commit a3ef12e24ad5b5633d0f1e5c22a5029a71906053 Author: Brent Perteet Date: Wed May 14 12:57:39 2025 -0500 initial check in based on SVN revision 575 diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..3346ad2 --- /dev/null +++ b/.cproject @@ -0,0 +1,776 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_3="NXP" property_4="LPC54113J256" property_count="5" version="100300"/> +<infoList vendor="NXP"> +<info chip="LPC54113J256" flash_driver="LPC5411x_256K.cfx" match_id="0x0" name="LPC54113J256" stub="crt_emu_cm3_gen"> +<chip> +<name>LPC54113J256</name> +<family>LPC5411x</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" driver="LPC5411x_256K.cfx" edited="true" id="PROGRAM_FLASH" location="0x0" size="0x40000"/> +<memoryInstance derived_from="RAM" edited="true" id="SRAM1" location="0x20010000" size="0x10000"/> +<memoryInstance derived_from="RAM" edited="true" id="SRAM0" location="0x20000000" size="0x10000"/> +<memoryInstance derived_from="RAM" edited="true" id="SRAMX" location="0x4000000" size="0x8000"/> +<memoryInstance derived_from="RAM" edited="true" id="SRAM2" location="0x20020000" size="0x8000"/> +</chip> +<processor> +<name gcc_name="cortex-m4">Cortex-M4</name> +<family>Cortex-M</family> +</processor> +</info> +</infoList> +</TargetConfig> + + + + + + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fbe3bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +build +.cache +Debug +Release +/source/Fonts/bmp/Application Files/MonoBitmapConverter_1_0_0_0/ChangeLog.txt.deploy +/source/Fonts/bmp/Application Files/MonoBitmapConverter_1_0_0_0/MonoBitmapConverter.application +/source/Fonts/bmp/Application Files/MonoBitmapConverter_1_0_0_0/MonoBitmapConverter.exe.config.deploy +/source/Fonts/bmp/Application Files/MonoBitmapConverter_1_0_0_0/MonoBitmapConverter.exe.deploy +/source/Fonts/bmp/Application Files/MonoBitmapConverter_1_0_0_0/MonoBitmapConverter.exe.manifest +/source/Fonts/bmp/MonoBitmapConverter.application +/source/Fonts/bmp/setup.exe +/*.launch diff --git a/.project b/.project new file mode 100644 index 0000000..5d9ce8a --- /dev/null +++ b/.project @@ -0,0 +1,26 @@ + + + TX_App + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..c430e45 --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000..2a04510 --- /dev/null +++ b/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,75 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false} +org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"} +org.eclipse.cdt.codan.checkers.localvarreturn=-Warning +org.eclipse.cdt.codan.checkers.localvarreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Returning the address of a local variable\\")"} +org.eclipse.cdt.codan.checkers.nocommentinside=-Error +org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"} +org.eclipse.cdt.codan.checkers.nolinecomment=-Error +org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"} +org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false} +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"} +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"} +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"} +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"} +org.eclipse.cdt.codan.internal.checkers.BlacklistProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.BlacklistProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function or method is blacklisted\\")",blacklist\=>()} +org.eclipse.cdt.codan.internal.checkers.CStyleCastProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.CStyleCastProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"C-Style cast instead of C++ cast\\")",checkMacro\=>true} +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false} +org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"} +org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true} +org.eclipse.cdt.codan.internal.checkers.CopyrightProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.CopyrightProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Lack of copyright information\\")",regex\=>".*Copyright.*"} +org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"} +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.FloatCompareProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.FloatCompareProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Direct float comparison\\")"} +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.GotoStatementProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.GotoStatementProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Goto statement used\\")"} +org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"} +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"} +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"} +org.eclipse.cdt.codan.internal.checkers.MagicNumberProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.MagicNumberProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Avoid magic numbers\\")",checkArray\=>true,checkOperatorParen\=>true,exceptions\=>(1,0,-1,2,1.0,0.0,-1.0)} +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"} +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.MissCaseProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.MissCaseProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing cases in switch\\")"} +org.eclipse.cdt.codan.internal.checkers.MissDefaultProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.MissDefaultProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing default in switch\\")",defaultWithAllEnums\=>false} +org.eclipse.cdt.codan.internal.checkers.MissReferenceProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.MissReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing reference return value in assignment operator\\")"} +org.eclipse.cdt.codan.internal.checkers.MissSelfCheckProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.MissSelfCheckProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing self check in assignment operator\\")"} +org.eclipse.cdt.codan.internal.checkers.MultipleDeclarationsProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.MultipleDeclarationsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Multiple variable declaration\\")"} +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.NoDiscardProblem=Warning +org.eclipse.cdt.codan.internal.checkers.NoDiscardProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return value not evaluated\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"} +org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"} +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"} +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"} +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"} +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"} +org.eclipse.cdt.codan.internal.checkers.ShallowCopyProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ShallowCopyProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Miss copy constructor or assignment operator\\")",onlynew\=>false} +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.StaticVariableInHeaderProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.StaticVariableInHeaderProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Static variable in header file\\")"} +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false} +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false} +org.eclipse.cdt.codan.internal.checkers.SymbolShadowingProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.SymbolShadowingProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol shadowing\\")",paramFuncParameters\=>true} +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")} +org.eclipse.cdt.codan.internal.checkers.UsingInHeaderProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.UsingInHeaderProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Using directive in header\\")"} +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.VirtualMethodCallProblem=-Error +org.eclipse.cdt.codan.internal.checkers.VirtualMethodCallProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Virtual method call in constructor/destructor\\")"} diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 0000000..39984cf --- /dev/null +++ b/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,194 @@ +doxygen/doxygen_new_line_after_brief=true +doxygen/doxygen_use_brief_tag=false +doxygen/doxygen_use_javadoc_tags=true +doxygen/doxygen_use_pre_tag=false +doxygen/doxygen_use_structural_commands=false +eclipse.preferences.version=1 +org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.cdt.core.formatter.alignment_for_assignment=16 +org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80 +org.eclipse.cdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.cdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=34 +org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain=18 +org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list=0 +org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16 +org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48 +org.eclipse.cdt.core.formatter.alignment_for_expression_list=0 +org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.cdt.core.formatter.alignment_for_lambda_expression=20 +org.eclipse.cdt.core.formatter.alignment_for_member_access=0 +org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain=16 +org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=next_line +org.eclipse.cdt.core.formatter.brace_position_for_block=next_line +org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=next_line +org.eclipse.cdt.core.formatter.brace_position_for_linkage_declaration=next_line +org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line +org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=next_line +org.eclipse.cdt.core.formatter.brace_position_for_switch=next_line +org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=next_line +org.eclipse.cdt.core.formatter.comment.line_up_line_comment_in_blocks_on_first_column=false +org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment=1 +org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column=true +org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.cdt.core.formatter.comment_formatter_off_tag=@formatter\:off +org.eclipse.cdt.core.formatter.comment_formatter_on_tag=@formatter\:on +org.eclipse.cdt.core.formatter.compact_else_if=true +org.eclipse.cdt.core.formatter.continuation_indentation=2 +org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.cdt.core.formatter.format_block_comment=true +org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.cdt.core.formatter.format_header_comment=true +org.eclipse.cdt.core.formatter.format_line_comment=true +org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false +org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces=0 +org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true +org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_linkage=false +org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=false +org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=false +org.eclipse.cdt.core.formatter.indent_empty_lines=false +org.eclipse.cdt.core.formatter.indent_label_compare_to_statements=true +org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.cdt.core.formatter.indentation.size=4 +org.eclipse.cdt.core.formatter.insert_new_line_after_colon_in_constructor_initializer_list=insert +org.eclipse.cdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=insert +org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert +org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert +org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert +org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_structured_binding_name_list=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert +org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert +org.eclipse.cdt.core.formatter.insert_space_after_lambda_return=insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_opening_structured_binding_name_list=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_pointer_in_declarator_list=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_pointer_in_method_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_closing_structured_binding_name_list=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_structured_binding_name_list=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_lambda_return=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_linkage_declaration=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.cdt.core.formatter.insert_space_before_opening_structured_binding_name_list=insert +org.eclipse.cdt.core.formatter.insert_space_before_pointer_in_declarator_list=insert +org.eclipse.cdt.core.formatter.insert_space_before_pointer_in_method_declaration=insert +org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.cdt.core.formatter.insert_space_before_ref_qualifier_in_structured_binding=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert +org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert +org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.cdt.core.formatter.join_wrapped_lines=true +org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.cdt.core.formatter.lineSplit=80 +org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.cdt.core.formatter.tabulation.char=tab +org.eclipse.cdt.core.formatter.tabulation.size=4 +org.eclipse.cdt.core.formatter.use_comment_formatter_tag=true +org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false diff --git a/.settings/org.eclipse.cdt.ui.prefs b/.settings/org.eclipse.cdt.ui.prefs new file mode 100644 index 0000000..48a50c7 --- /dev/null +++ b/.settings/org.eclipse.cdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +formatter_profile=org.eclipse.cdt.ui.default.allman_profile +formatter_settings_version=1 diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..b196c64 --- /dev/null +++ b/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a584167 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "files.associations": { + "main.h": "c", + "pin_mux.h": "c", + "fsl_debug_console.h": "c", + "board.h": "c", + "fsl_common.h": "c", + "clock_config.h": "c", + "utils.h": "c", + "ports.h": "c", + "mode.h": "c" + } +} \ No newline at end of file diff --git a/CMSIS/arm_common_tables.h b/CMSIS/arm_common_tables.h new file mode 100644 index 0000000..6a4337f --- /dev/null +++ b/CMSIS/arm_common_tables.h @@ -0,0 +1,378 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.h + * Description: Extern declaration for common tables + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024) + extern const uint16_t armBitRevTable[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) + extern const float32_t twiddleCoef_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) + extern const float32_t twiddleCoef_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) + extern const float32_t twiddleCoef_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) + extern const float32_t twiddleCoef_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) + extern const float32_t twiddleCoef_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) + extern const float32_t twiddleCoef_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) + extern const float32_t twiddleCoef_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) + extern const float32_t twiddleCoef_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) + extern const float32_t twiddleCoef_4096[8192]; + #define twiddleCoef twiddleCoef_4096 + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) + extern const q31_t twiddleCoef_16_q31[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) + extern const q31_t twiddleCoef_32_q31[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) + extern const q31_t twiddleCoef_64_q31[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) + extern const q31_t twiddleCoef_128_q31[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) + extern const q31_t twiddleCoef_256_q31[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) + extern const q31_t twiddleCoef_512_q31[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) + extern const q31_t twiddleCoef_1024_q31[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) + extern const q31_t twiddleCoef_2048_q31[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) + extern const q31_t twiddleCoef_4096_q31[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) + extern const q15_t twiddleCoef_16_q15[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) + extern const q15_t twiddleCoef_32_q15[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) + extern const q15_t twiddleCoef_64_q15[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) + extern const q15_t twiddleCoef_128_q15[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) + extern const q15_t twiddleCoef_256_q15[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) + extern const q15_t twiddleCoef_512_q15[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) + extern const q15_t twiddleCoef_1024_q15[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) + extern const q15_t twiddleCoef_2048_q15[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) + extern const q15_t twiddleCoef_4096_q15[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32) + extern const float32_t twiddleCoef_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64) + extern const float32_t twiddleCoef_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128) + extern const float32_t twiddleCoef_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256) + extern const float32_t twiddleCoef_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512) + extern const float32_t twiddleCoef_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024) + extern const float32_t twiddleCoef_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048) + extern const float32_t twiddleCoef_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096) + extern const float32_t twiddleCoef_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + /* floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16) + #define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) + extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32) + #define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) + extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64) + #define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128) + #define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) + extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256) + #define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) + extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512) + #define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) + extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024) + #define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) + extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048) + #define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) + extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096) + #define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* fixed-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16) + #define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32) + #define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64) + #define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128) + #define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256) + #define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512) + #define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024) + #define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048) + #define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096) + #define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32) + extern const float32_t realCoefA[8192]; + extern const float32_t realCoefB[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31) + extern const q31_t realCoefAQ31[8192]; + extern const q31_t realCoefBQ31[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15) + extern const q15_t realCoefAQ15[8192]; + extern const q15_t realCoefBQ15[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128) + extern const float32_t Weights_128[256]; + extern const float32_t cos_factors_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512) + extern const float32_t Weights_512[1024]; + extern const float32_t cos_factors_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048) + extern const float32_t Weights_2048[4096]; + extern const float32_t cos_factors_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192) + extern const float32_t Weights_8192[16384]; + extern const float32_t cos_factors_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128) + extern const q15_t WeightsQ15_128[256]; + extern const q15_t cos_factorsQ15_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512) + extern const q15_t WeightsQ15_512[1024]; + extern const q15_t cos_factorsQ15_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048) + extern const q15_t WeightsQ15_2048[4096]; + extern const q15_t cos_factorsQ15_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192) + extern const q15_t WeightsQ15_8192[16384]; + extern const q15_t cos_factorsQ15_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128) + extern const q31_t WeightsQ31_128[256]; + extern const q31_t cos_factorsQ31_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512) + extern const q31_t WeightsQ31_512[1024]; + extern const q31_t cos_factorsQ31_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048) + extern const q31_t WeightsQ31_2048[4096]; + extern const q31_t cos_factorsQ31_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192) + extern const q31_t WeightsQ31_8192[16384]; + extern const q31_t cos_factorsQ31_8192[8192]; + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */ + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES) + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15) + extern const q15_t armRecipTableQ15[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31) + extern const q31_t armRecipTableQ31[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + /* Tables for Fast Math Sine and Cosine */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32) + extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31) + extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15) + extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */ + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/CMSIS/arm_const_structs.h b/CMSIS/arm_const_structs.h new file mode 100644 index 0000000..80a3e8b --- /dev/null +++ b/CMSIS/arm_const_structs.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_const_structs.h + * Description: Constant structs that are initialized for user convenience. + * For example, some can be given as arguments to the arm_cfft_f32() function. + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/CMSIS/arm_math.h b/CMSIS/arm_math.h new file mode 100644 index 0000000..eb37f82 --- /dev/null +++ b/CMSIS/arm_math.h @@ -0,0 +1,7361 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.6.0 + * @date 18. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transform functions + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (Armv8-M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (Armv8-M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (Armv8-M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (Armv8-M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (Armv8-M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to rebuild libraries on MDK toolchain in the CMSIS\\DSP\\Projects\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional preprocessor macros detailed above. + * + * Preprocessor Macros + * ------------ + * + * Each library project have different preprocessor macros. + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_LOOPUNROLL: + * + * Define macro ARM_MATH_LOOPUNROLL to enable manual loop unrolling in DSP functions + * + * - ARM_MATH_NEON: + * + * Define macro ARM_MATH_NEON to enable Neon versions of the DSP functions. + * It is not enabled by default when Neon is available because performances are + * dependent on the compiler and target architecture. + * + * - ARM_MATH_NEON_EXPERIMENTAL: + * + * Define macro ARM_MATH_NEON_EXPERIMENTAL to enable experimental Neon versions of + * of some DSP functions. Experimental Neon versions currently do not have better + * performances than the scalar versions. + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |---------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP\\DSP_Lib_TestSuite | DSP_Lib test suite | + * |\b CMSIS\\DSP\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP\\Include | DSP_Lib include files | + * |\b CMSIS\\DSP\\Lib | DSP_Lib binaries | + * |\b CMSIS\\DSP\\Projects | Projects to rebuild DSP_Lib binaries | + * |\b CMSIS\\DSP\\Source | DSP_Lib source files | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to \ref arm_mat_init_f32(), \ref arm_mat_init_q31() and \ref arm_mat_init_q15() + * for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ + +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ + + +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" + #pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + + +/* Included for instrinsics definitions */ +#if !defined ( _MSC_VER ) +#include "cmsis_compiler.h" +#else +#include +#define __STATIC_FORCEINLINE static __forceinline +#define __ALIGNED(x) __declspec(align(x)) +#define LOW_OPTIMIZATION_ENTER +#define LOW_OPTIMIZATION_EXIT +#define IAR_ONLY_LOW_OPTIMIZATION_ENTER +#define IAR_ONLY_LOW_OPTIMIZATION_EXIT +#endif + +#include "string.h" +#include "math.h" +#include "float.h" + +/* evaluate ARM DSP feature */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + #define ARM_MATH_DSP 1 +#endif + +#if defined(__ARM_NEON) +#include +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Input matrix is singular and cannot be inverted */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + +/** + @brief definition to read/write two 16 bit values. + @deprecated + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __un(aligned) int32_t +#elif defined(_MSC_VER ) + #define __SIMD32_TYPE int32_t +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr)) +#define __SIMD64(addr) (*( int64_t **) & (addr)) + +/* SIMD replacement */ + + +/** + @brief Read 2 Q15 from Q15 pointer. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2 ( + q15_t * pQ15) +{ + q31_t val; + + memcpy (&val, pQ15, 4); + + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_ia ( + q15_t ** pQ15) +{ + q31_t val; + + memcpy (&val, *pQ15, 4); + *pQ15 += 2; + + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_da ( + q15_t ** pQ15) +{ + q31_t val; + + memcpy (&val, *pQ15, 4); + *pQ15 -= 2; + + return (val); +} + +/** + @brief Write 2 Q15 to Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2_ia ( + q15_t ** pQ15, + q31_t value) +{ + q31_t val = value; + + memcpy (*pQ15, &val, 4); + *pQ15 += 2; +} + +/** + @brief Write 2 Q15 to Q15 pointer. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2 ( + q15_t * pQ15, + q31_t value) +{ + q31_t val = value; + + memcpy (pQ15, &val, 4); +} + + +/** + @brief Read 4 Q7 from Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_ia ( + q7_t ** pQ7) +{ + q31_t val; + + memcpy (&val, *pQ7, 4); + *pQ7 += 4; + + return (val); +} + +/** + @brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_da ( + q7_t ** pQ7) +{ + q31_t val; + + memcpy (&val, *pQ7, 4); + *pQ7 -= 4; + + return (val); +} + +/** + @brief Write 4 Q7 to Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q7x4_ia ( + q7_t ** pQ7, + q31_t value) +{ + q31_t val = value; + + memcpy (*pQ7, &val, 4); + *pQ7 += 4; +} + +/* + +Normally those kind of definitions are in a compiler file +in Core or Core_A. + +But for MSVC compiler it is a bit special. The goal is very specific +to CMSIS-DSP and only to allow the use of this library from other +systems like Python or Matlab. + +MSVC is not going to be used to cross-compile to ARM. So, having a MSVC +compiler file in Core or Core_A would not make sense. + +*/ +#if defined ( _MSC_VER ) + __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#ifndef ARM_MATH_DSP + /** + * @brief definition to pack two 16 bit values. + */ + #define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) + #define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) +#endif + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + __STATIC_FORCEINLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + __STATIC_FORCEINLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + __STATIC_FORCEINLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y) ) ); + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + const q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1U); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + const q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + +#if defined(ARM_MATH_NEON) + +static inline float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t x) +{ + float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN)); + float32x4_t e = vrsqrteq_f32(x1); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + return vmulq_f32(x, e); +} + +static inline int16x8_t __arm_vec_sqrt_q15_neon(int16x8_t vec) +{ + float32x4_t tempF; + int32x4_t tempHI,tempLO; + + tempLO = vmovl_s16(vget_low_s16(vec)); + tempF = vcvtq_n_f32_s32(tempLO,15); + tempF = __arm_vec_sqrt_f32_neon(tempF); + tempLO = vcvtq_n_s32_f32(tempF,15); + + tempHI = vmovl_s16(vget_high_s16(vec)); + tempF = vcvtq_n_f32_s32(tempHI,15); + tempF = __arm_vec_sqrt_f32_neon(tempF); + tempHI = vcvtq_n_s32_f32(tempF,15); + + return(vcombine_s16(vqmovn_s32(tempLO),vqmovn_s32(tempHI))); +} + +static inline int32x4_t __arm_vec_sqrt_q31_neon(int32x4_t vec) +{ + float32x4_t temp; + + temp = vcvtq_n_f32_s32(vec,31); + temp = __arm_vec_sqrt_f32_neon(temp); + return(vcvtq_n_s32_f32(temp,31)); +} + +#endif + +/* + * @brief C custom defined intrinsic functions + */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 + */ + __STATIC_FORCEINLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 + */ + __STATIC_FORCEINLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 + */ + __STATIC_FORCEINLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 + */ + __STATIC_FORCEINLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 + */ + __STATIC_FORCEINLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 + */ + __STATIC_FORCEINLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX + */ + __STATIC_FORCEINLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX + */ + __STATIC_FORCEINLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX + */ + __STATIC_FORCEINLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX + */ + __STATIC_FORCEINLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX + */ + __STATIC_FORCEINLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX + */ + __STATIC_FORCEINLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD + */ + __STATIC_FORCEINLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB + */ + __STATIC_FORCEINLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD + */ + __STATIC_FORCEINLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX + */ + __STATIC_FORCEINLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX + */ + __STATIC_FORCEINLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD + */ + __STATIC_FORCEINLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX + */ + __STATIC_FORCEINLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD + */ + __STATIC_FORCEINLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD + */ + __STATIC_FORCEINLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 + */ + __STATIC_FORCEINLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA + */ + __STATIC_FORCEINLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter (fast version). + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns either + * ARM_MATH_SUCCESS if initialization was successful or + * ARM_MATH_ARGUMENT_ERROR if numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter (fast version). + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + const q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +arm_status arm_rfft_32_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_64_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_128_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_256_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_512_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_1024_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_2048_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_4096_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + + + void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + const float32_t *pTwiddle; /**< points to the twiddle factor table. */ + const float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + const float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + const q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + const q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + const q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + const q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + const q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + const q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + const float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + const q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + const q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + const q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + +/** + @brief Instance structure for floating-point FIR decimator. + */ +typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + +/** + @brief Processing function for floating-point FIR decimator. + @param[in] S points to an instance of the floating-point FIR decimator structure + @param[in] pSrc points to the block of input data + @param[out] pDst points to the block of output data + @param[in] blockSize number of samples to process + */ +void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + @brief Initialization function for the floating-point FIR decimator. + @param[in,out] S points to an instance of the floating-point FIR decimator structure + @param[in] numTaps number of coefficients in the filter + @param[in] M decimation factor + @param[in] pCoeffs points to the filter coefficients + @param[in] pState points to the state buffer + @param[in] blockSize number of input samples to process per call + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_LENGTH_ERROR : blockSize is not a multiple of M + */ +arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + +#if defined(ARM_MATH_NEON) +void arm_biquad_cascade_df2T_compute_coefs_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs); +#endif + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + const q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + const q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + +/** + @brief Correlation of Q15 sequences + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. +*/ +void arm_correlate_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + +/** + @brief Correlation of Q15 sequences. + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + */ +void arm_correlate_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence. + @param[in] srcALen length of the first input sequence. + @param[in] pSrcB points to the second input sequence. + @param[in] srcBLen length of the second input sequence. + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ +void arm_correlate_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + @brief Correlation of Q31 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void arm_correlate_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd
+   * 
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return processed output sample. + */ + __STATIC_FORCEINLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + +/** + @brief Process function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around rather than clip. + In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ +__STATIC_FORCEINLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + +/** + @brief Process function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ +__STATIC_FORCEINLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @return none + */ + __STATIC_FORCEINLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + +/** + @brief Clarke transform for Q31 version + @param[in] Ia input three-phase coordinate a + @param[in] Ib input three-phase coordinate b + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + +/** + @brief Inverse Clarke transform for Q31 version + @param[in] Ialpha input two-phase orthogonal vector axis alpha + @param[in] Ibeta input two-phase orthogonal vector axis beta + @param[out] pIa points to output three-phase coordinate a + @param[out] pIb points to output three-phase coordinate b + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + * + * The function implements the forward Park transform. + * + */ + __STATIC_FORCEINLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + +/** + @brief Park transform for Q31 version + @param[in] Ialpha input two-phase vector coordinate alpha + @param[in] Ibeta input two-phase vector coordinate beta + @param[out] pId points to output rotor reference frame d + @param[out] pIq points to output rotor reference frame q + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + +/** + @brief Inverse Park transform for Q31 version + @param[in] Id input coordinate of rotor reference frame d + @param[in] Iq input coordinate of rotor reference frame q + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + __STATIC_FORCEINLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1U); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + __STATIC_FORCEINLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + +/** + @brief Floating-point square root function. + @param[in] in input value + @param[out] pOut square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +__STATIC_FORCEINLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + *pOut = __sqrtf(in); + #else + *pOut = sqrtf(in); + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); + #else + *pOut = sqrtf(in); + #endif + +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + +/** + @brief Q31 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + +/** + @brief Q15 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @brief Vector Floating-point square root function. + * @param[in] pIn input vector. + * @param[out] pOut vector of square roots of input elements. + * @param[in] len length of input vector. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + void arm_vsqrt_f32( + float32_t * pIn, + float32_t * pOut, + uint16_t len); + + void arm_vsqrt_q31( + q31_t * pIn, + q31_t * pOut, + uint16_t len); + + void arm_vsqrt_q15( + q15_t * pIn, + q15_t * pOut, + uint16_t len); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t rOffset; + int32_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q15_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q7_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + const q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + const q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + const q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + const q15_t * pSrcCmplx, + const q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + const q31_t * pSrcCmplx, + const q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + const float32_t * pSrcCmplx, + const float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + const float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + const float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + const float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + const q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + const q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + const q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + const q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + const q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + const q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + const q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + const q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + const q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/CMSIS/cmsis_armcc.h b/CMSIS/cmsis_armcc.h new file mode 100644 index 0000000..59f173a --- /dev/null +++ b/CMSIS/cmsis_armcc.h @@ -0,0 +1,894 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.1.0 + * @date 08. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/CMSIS/cmsis_armclang.h b/CMSIS/cmsis_armclang.h new file mode 100644 index 0000000..e917f35 --- /dev/null +++ b/CMSIS/cmsis_armclang.h @@ -0,0 +1,1444 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.2.0 + * @date 08. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/CMSIS/cmsis_armclang_ltm.h b/CMSIS/cmsis_armclang_ltm.h new file mode 100644 index 0000000..feec324 --- /dev/null +++ b/CMSIS/cmsis_armclang_ltm.h @@ -0,0 +1,1891 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.2.0 + * @date 08. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2018-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/CMSIS/cmsis_compiler.h b/CMSIS/cmsis_compiler.h new file mode 100644 index 0000000..adbf296 --- /dev/null +++ b/CMSIS/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/CMSIS/cmsis_gcc.h b/CMSIS/cmsis_gcc.h new file mode 100644 index 0000000..3ddcc58 --- /dev/null +++ b/CMSIS/cmsis_gcc.h @@ -0,0 +1,2168 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.2.0 + * @date 08. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section(".vectors"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/CMSIS/cmsis_iccarm.h b/CMSIS/cmsis_iccarm.h new file mode 100644 index 0000000..12d68fd --- /dev/null +++ b/CMSIS/cmsis_iccarm.h @@ -0,0 +1,964 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.1.0 + * @date 08. May 2019 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2019 IAR Systems +// Copyright (c) 2017-2019 Arm Limited. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + +#ifndef __PROGRAM_START +#define __PROGRAM_START __iar_program_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP CSTACK$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT CSTACK$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __vector_table +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE @".intvec" +#endif + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/CMSIS/cmsis_version.h b/CMSIS/cmsis_version.h new file mode 100644 index 0000000..f2e2746 --- /dev/null +++ b/CMSIS/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.3 + * @date 24. June 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 3U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/CMSIS/core_cm4.h b/CMSIS/core_cm4.h new file mode 100644 index 0000000..12c023b --- /dev/null +++ b/CMSIS/core_cm4.h @@ -0,0 +1,2124 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/mpu_armv7.h b/CMSIS/mpu_armv7.h new file mode 100644 index 0000000..66ef59b --- /dev/null +++ b/CMSIS/mpu_armv7.h @@ -0,0 +1,272 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/LPC54114/drivers/fsl_power.c b/LPC54114/drivers/fsl_power.c new file mode 100644 index 0000000..4d35023 --- /dev/null +++ b/LPC54114/drivers/fsl_power.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016, NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "fsl_common.h" +#include "fsl_power.h" +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.power" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Empty file since implementation is in header file and power library */ diff --git a/LPC54114/drivers/fsl_power.h b/LPC54114/drivers/fsl_power.h new file mode 100644 index 0000000..6ab8f78 --- /dev/null +++ b/LPC54114/drivers/fsl_power.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016, NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_POWER_H_ +#define _FSL_POWER_H_ + +#include "fsl_common.h" + +/*! @addtogroup power */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief power driver version 2.0.0. */ +#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +#define MAKE_PD_BITS(reg, slot) (((reg) << 8) | (slot)) +#define PDRCFG0 0x0U +#define PDRCFG1 0x1U + +typedef enum pd_bits +{ + kPDRUNCFG_PD_FRO_EN = MAKE_PD_BITS(PDRCFG0, 4U), + kPDRUNCFG_PD_FLASH = MAKE_PD_BITS(PDRCFG0, 5U), + kPDRUNCFG_PD_TEMPS = MAKE_PD_BITS(PDRCFG0, 6U), + kPDRUNCFG_PD_BOD_RESET = MAKE_PD_BITS(PDRCFG0, 7U), + kPDRUNCFG_PD_BOD_INTR = MAKE_PD_BITS(PDRCFG0, 8U), + kPDRUNCFG_PD_ADC0 = MAKE_PD_BITS(PDRCFG0, 10U), + kPDRUNCFG_PD_VDDFLASH = MAKE_PD_BITS(PDRCFG0, 11U), + kPDRUNCFG_LP_VDDFLASH = MAKE_PD_BITS(PDRCFG0, 12U), + kPDRUNCFG_PD_RAM0 = MAKE_PD_BITS(PDRCFG0, 13U), + kPDRUNCFG_PD_RAM1 = MAKE_PD_BITS(PDRCFG0, 14U), + kPDRUNCFG_PD_RAM2 = MAKE_PD_BITS(PDRCFG0, 15U), + kPDRUNCFG_PD_RAMX = MAKE_PD_BITS(PDRCFG0, 16U), + kPDRUNCFG_PD_ROM = MAKE_PD_BITS(PDRCFG0, 17U), + kPDRUNCFG_PD_VDDHV_ENA = MAKE_PD_BITS(PDRCFG0, 18U), + kPDRUNCFG_PD_VD7_ENA = MAKE_PD_BITS(PDRCFG0, 19U), + kPDRUNCFG_PD_WDT_OSC = MAKE_PD_BITS(PDRCFG0, 20U), + kPDRUNCFG_PD_USB0_PHY = MAKE_PD_BITS(PDRCFG0, 21U), + kPDRUNCFG_PD_SYS_PLL0 = MAKE_PD_BITS(PDRCFG0, 22U), + kPDRUNCFG_PD_VREFP_SW = MAKE_PD_BITS(PDRCFG0, 23U), + kPDRUNCFG_PD_FLASH_BG = MAKE_PD_BITS(PDRCFG0, 25U), + + kPDRUNCFG_PD_ALT_FLASH_IBG = MAKE_PD_BITS(PDRCFG1, 28U), + kPDRUNCFG_SEL_ALT_FLASH_IBG = MAKE_PD_BITS(PDRCFG1, 29U), + + /* + This enum member has no practical meaning,it is used to avoid MISRA issue, + user should not trying to use it. + */ + kPDRUNCFG_ForceUnsigned = (int)0x80000000U +} pd_bit_t; + +/* Power mode configuration API parameter */ +typedef enum _power_mode_config +{ + kPmu_Sleep = 0U, + kPmu_Deep_Sleep = 1U, + kPmu_Deep_PowerDown = 2U, +} power_mode_cfg_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! +* @name Power Configuration +* @{ +*/ + +/*! + * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral + * + * @param en peripheral for which to enable the PDRUNCFG bit + * @return none + */ +static inline void POWER_EnablePD(pd_bit_t en) +{ + /* PDRUNCFGSET */ + SYSCON->PDRUNCFGSET[((uint32_t)en >> 8UL)] = (1UL << ((uint32_t)en & 0xffU)); +} + +/*! + * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral + * + * @param en peripheral for which to disable the PDRUNCFG bit + * @return none + */ +static inline void POWER_DisablePD(pd_bit_t en) +{ + /* PDRUNCFGCLR */ + SYSCON->PDRUNCFGCLR[((uint32_t)en >> 8UL)] = (1UL << ((uint32_t)en & 0xffU)); +} + +/*! + * @brief API to enable deep sleep bit in the ARM Core. + * + * @return none + */ +static inline void POWER_EnableDeepSleep(void) +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; +} + +/*! + * @brief API to disable deep sleep bit in the ARM Core. + * + * @return none + */ +static inline void POWER_DisableDeepSleep(void) +{ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; +} + +/*! + * @brief API to power down flash controller. + * + * @return none + */ +static inline void POWER_PowerDownFlash(void) +{ + /* note, we retain flash trim to make waking back up faster */ + SYSCON->PDRUNCFGSET[0] = + SYSCON_PDRUNCFG_LP_VDDFLASH_MASK | SYSCON_PDRUNCFG_PD_VDDHV_ENA_MASK | SYSCON_PDRUNCFG_PD_FLASH_BG_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* TURN OFF clock for Flash Controller (only needed for FLASH programming, will be turned on by ROM API) */ + CLOCK_DisableClock(kCLOCK_Flash); + + /* TURN OFF clock for Flash Accelerator */ + CLOCK_DisableClock(kCLOCK_Fmc); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief API to power up flash controller. + * + * @return none + */ +static inline void POWER_PowerUpFlash(void) +{ + SYSCON->PDRUNCFGCLR[0] = SYSCON_PDRUNCFG_LP_VDDFLASH_MASK | SYSCON_PDRUNCFG_PD_VDDHV_ENA_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* TURN ON clock for flash Accelerator */ + CLOCK_EnableClock(kCLOCK_Fmc); + + /* TURN ON clock for flash Controller */ + CLOCK_EnableClock(kCLOCK_Flash); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief Power Library API to enter different power mode. + * + * @param mode Power mode. + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep + * @return none + */ +void POWER_EnterPowerMode(power_mode_cfg_t mode, uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to enter sleep mode. + * + * @return none + */ +void POWER_EnterSleep(void); + +/*! + * @brief Power Library API to enter deep sleep mode. + * + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep + * @return none + */ +void POWER_EnterDeepSleep(uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to enter deep power down mode. + * + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep power down mode, + * but this is has no effect as the voltages are cut off. + * @return none + */ +void POWER_EnterDeepPowerDown(uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to choose normal regulation and set the voltage for the desired operating frequency. + * + * @param freq - The desired frequency at which the part would like to operate, + * note that the voltage and flash wait states should be set before changing frequency + * @return none + */ +void POWER_SetVoltageForFreq(uint32_t freq); + +/*! + * @brief Power Library API to choose low power regulation and set the voltage for the desired operating frequency. + * + * @param freq - The desired frequency at which the part would like to operate, + * note only 12MHz and 48Mhz are supported + * @return none + */ +void POWER_SetLowPowerVoltageForFreq(uint32_t freq); + +/*! + * @brief Power Library API to return the library version. + * + * @return version number of the power library + */ +uint32_t POWER_GetLibVersion(void); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +/*! @} */ + +#endif /* _FSL_POWER_H_ */ diff --git a/LPC54114/mcuxpresso/libpower_cm4_hardabi.a b/LPC54114/mcuxpresso/libpower_cm4_hardabi.a new file mode 100644 index 0000000..b478832 Binary files /dev/null and b/LPC54114/mcuxpresso/libpower_cm4_hardabi.a differ diff --git a/LPC54114/mcuxpresso/libpower_cm4_softabi.a b/LPC54114/mcuxpresso/libpower_cm4_softabi.a new file mode 100644 index 0000000..27a814a Binary files /dev/null and b/LPC54114/mcuxpresso/libpower_cm4_softabi.a differ diff --git a/board/board.c b/board/board.c new file mode 100644 index 0000000..f1bfd92 --- /dev/null +++ b/board/board.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "fsl_common.h" +#include "clock_config.h" +#include "board.h" +#include "fsl_debug_console.h" +#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED +#include "fsl_i2c.h" +#endif /* SDK_I2C_BASED_COMPONENT_USED */ +#if defined BOARD_USE_CODEC +#include "fsl_wm8904.h" +#endif +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Clock rate on the CLKIN pin */ +const uint32_t ExtClockIn = BOARD_EXTCLKINRATE; + +/******************************************************************************* + * Code + ******************************************************************************/ +/* Initialize debug console. */ +status_t BOARD_InitDebugConsole(void) +{ +#if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) + status_t result; + /* attach 12 MHz clock to FLEXCOMM0 (debug console) */ + CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); + RESET_PeripheralReset(BOARD_DEBUG_UART_RST); + result = DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, + BOARD_DEBUG_UART_CLK_FREQ); + assert(kStatus_Success == result); + return result; +#else + return kStatus_Success; +#endif +} + +status_t BOARD_InitDebugConsole_Core1(void) +{ +#if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) + status_t result; + /* attach 12 MHz clock to FLEXCOMM0 (debug console) */ + CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH_CORE1); + RESET_PeripheralReset(BOARD_DEBUG_UART_RST_CORE1); + result = DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE_CORE1, BOARD_DEBUG_UART_BAUDRATE_CORE1, + BOARD_DEBUG_UART_TYPE_CORE1, BOARD_DEBUG_UART_CLK_FREQ_CORE1); + assert(kStatus_Success == result); + return result; +#else + return kStatus_Success; +#endif +} + +#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED +void BOARD_I2C_Init(I2C_Type *base, uint32_t clkSrc_Hz) +{ + i2c_master_config_t i2cConfig = {0}; + + I2C_MasterGetDefaultConfig(&i2cConfig); + I2C_MasterInit(base, &i2cConfig, clkSrc_Hz); +} + +status_t BOARD_I2C_Send(I2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subaddressSize, + uint8_t *txBuff, + uint8_t txBuffSize) +{ + i2c_master_transfer_t masterXfer; + + /* Prepare transfer structure. */ + masterXfer.slaveAddress = deviceAddress; + masterXfer.direction = kI2C_Write; + masterXfer.subaddress = subAddress; + masterXfer.subaddressSize = subaddressSize; + masterXfer.data = txBuff; + masterXfer.dataSize = txBuffSize; + masterXfer.flags = kI2C_TransferDefaultFlag; + + return I2C_MasterTransferBlocking(base, &masterXfer); +} + +status_t BOARD_I2C_Receive(I2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subaddressSize, + uint8_t *rxBuff, + uint8_t rxBuffSize) +{ + i2c_master_transfer_t masterXfer; + + /* Prepare transfer structure. */ + masterXfer.slaveAddress = deviceAddress; + masterXfer.subaddress = subAddress; + masterXfer.subaddressSize = subaddressSize; + masterXfer.data = rxBuff; + masterXfer.dataSize = rxBuffSize; + masterXfer.direction = kI2C_Read; + masterXfer.flags = kI2C_TransferDefaultFlag; + + return I2C_MasterTransferBlocking(base, &masterXfer); +} + +void BOARD_Codec_I2C_Init(void) +{ + BOARD_I2C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ); +} + +status_t BOARD_Codec_I2C_Send( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize) +{ + return BOARD_I2C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff, + txBuffSize); +} + +status_t BOARD_Codec_I2C_Receive( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize) +{ + return BOARD_I2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize); +} +#endif /* SDK_I2C_BASED_COMPONENT_USED */ diff --git a/board/board.h b/board/board.h new file mode 100644 index 0000000..2a8a3da --- /dev/null +++ b/board/board.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include "clock_config.h" +#include "fsl_common.h" +#include "fsl_gpio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief The board name */ +#define BOARD_NAME "LPCXPRESSO54114" + +#define BOARD_EXTCLKINRATE (0) + +/*! @brief The UART to use for debug messages. */ +#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart +#define BOARD_DEBUG_UART_BASEADDR (uint32_t) USART0 +#define BOARD_DEBUG_UART_INSTANCE 0U +#define BOARD_DEBUG_UART_CLK_FREQ CLOCK_GetFlexCommClkFreq(0) +#define BOARD_DEBUG_UART_CLK_ATTACH kFRO12M_to_FLEXCOMM0 +#define BOARD_DEBUG_UART_RST kFC0_RST_SHIFT_RSTn +#define BOARD_UART_IRQ FLEXCOMM0_IRQn +#define BOARD_UART_IRQ_HANDLER FLEXCOMM0_IRQHandler + +#define BOARD_DEBUG_UART_TYPE_CORE1 kSerialPort_Uart +#define BOARD_DEBUG_UART_BASEADDR_CORE1 (uint32_t) USART2 +#define BOARD_DEBUG_UART_INSTANCE_CORE1 2U +#define BOARD_DEBUG_UART_CLK_FREQ_CORE1 CLOCK_GetFlexCommClkFreq(2) +#define BOARD_DEBUG_UART_CLK_ATTACH_CORE1 kFRO12M_to_FLEXCOMM2 +#define BOARD_DEBUG_UART_RST_CORE1 kFC2_RST_SHIFT_RSTn +#define BOARD_UART_IRQ_CORE1 FLEXCOMM2_IRQn +#define BOARD_UART_IRQ_HANDLER_CORE1 FLEXCOMM2_IRQHandler + +#define BOARD_DEBUG_SPI_CLK_FREQ 12000000 + +#ifndef BOARD_DEBUG_UART_BAUDRATE +#define BOARD_DEBUG_UART_BAUDRATE 115200 +#endif /* BOARD_DEBUG_UART_BAUDRATE */ + +#ifndef BOARD_DEBUG_UART_BAUDRATE_CORE1 +#define BOARD_DEBUG_UART_BAUDRATE_CORE1 115200 +#endif /* BOARD_DEBUG_UART_BAUDRATE_CORE1 */ + +#ifndef BOARD_LED_RED_GPIO +#define BOARD_LED_RED_GPIO GPIO +#endif +#define BOARD_LED_RED_GPIO_PORT 0U +#ifndef BOARD_LED_RED_GPIO_PIN +#define BOARD_LED_RED_GPIO_PIN 29U +#endif +#ifndef BOARD_LED_GREEN_GPIO +#define BOARD_LED_GREEN_GPIO GPIO +#endif +#define BOARD_LED_GREEN_GPIO_PORT 1U +#ifndef BOARD_LED_GREEN_GPIO_PIN +#define BOARD_LED_GREEN_GPIO_PIN 10U +#endif +#ifndef BOARD_LED_BLUE_GPIO +#define BOARD_LED_BLUE_GPIO GPIO +#endif +#define BOARD_LED_BLUE_GPIO_PORT 1U +#ifndef BOARD_LED_BLUE_GPIO_PIN +#define BOARD_LED_BLUE_GPIO_PIN 9U +#endif + +#ifndef BOARD_SW1_GPIO +#define BOARD_SW1_GPIO GPIO +#endif +#define BOARD_SW1_GPIO_PORT 0U +#ifndef BOARD_SW1_GPIO_PIN +#define BOARD_SW1_GPIO_PIN 24U +#endif +#define BOARD_SW1_NAME "SW1" +#define BOARD_SW3_IRQ PIN_INT0_IRQn +#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler + +#ifndef BOARD_SW2_GPIO +#define BOARD_SW2_GPIO GPIO +#endif +#define BOARD_SW2_GPIO_PORT 0U +#ifndef BOARD_SW2_GPIO_PIN +#define BOARD_SW2_GPIO_PIN 31U +#endif +#define BOARD_SW2_NAME "SW2" +#define BOARD_SW3_IRQ PIN_INT0_IRQn +#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler + +#ifndef BOARD_SW3_GPIO +#define BOARD_SW3_GPIO GPIO +#endif +#define BOARD_SW3_GPIO_PORT 0U +#ifndef BOARD_SW3_GPIO_PIN +#define BOARD_SW3_GPIO_PIN 4U +#endif +#define BOARD_SW3_NAME "SW3" +#define BOARD_SW3_IRQ PIN_INT0_IRQn +#define BOARD_SW3_IRQ_HANDLER PIN_INT0_IRQHandler +#define BOARD_SW3_GPIO_PININT_INDEX 0 + +#define BOARD_ARDUINO_INT_IRQ (GINT0_IRQn) +#define BOARD_ARDUINO_I2C_IRQ (FLEXCOMM4_IRQn) +#define BOARD_ARDUINO_I2C_INDEX (4) +/* Board led color mapping */ +#define LOGIC_LED_ON 0U +#define LOGIC_LED_OFF 1U + +#define LED_RED_INIT(output) \ + GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, BOARD_LED_RED_GPIO_PIN, \ + &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_RED */ +#define LED_RED_ON() \ + GPIO_PortClear(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \ + 1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn on target LED_RED */ +#define LED_RED_OFF() \ + GPIO_PortSet(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \ + 1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn off target LED_RED */ +#define LED_RED_TOGGLE() \ + GPIO_PortToggle(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \ + 1U << BOARD_LED_RED_GPIO_PIN) /*!< Toggle on target LED_RED */ + +#define LED_GREEN_INIT(output) \ + GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, BOARD_LED_GREEN_GPIO_PIN, \ + &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_GREEN */ +#define LED_GREEN_ON() \ + GPIO_PortClear(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \ + 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn on target LED_GREEN */ +#define LED_GREEN_OFF() \ + GPIO_PortSet(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \ + 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn off target LED_GREEN */ +#define LED_GREEN_TOGGLE() \ + GPIO_PortToggle(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \ + 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Toggle on target LED_GREEN */ + +#define LED_BLUE_INIT(output) \ + GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, BOARD_LED_BLUE_GPIO_PIN, \ + &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_BLUE */ +#define LED_BLUE_ON() \ + GPIO_PortClear(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \ + 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn on target LED_BLUE */ +#define LED_BLUE_OFF() \ + GPIO_PortSet(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \ + 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn off target LED_BLUE */ +#define LED_BLUE_TOGGLE() \ + GPIO_PortToggle(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \ + 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Toggle on target LED_BLUE */ + +#define BOARD_CODEC_I2C_BASEADDR I2C4 +#define BOARD_CODEC_I2C_INSTANCE 4U +#define BOARD_CODEC_I2C_CLOCK_FREQ 12000000 + +/* Display. */ +#define BOARD_LCD_DC_GPIO GPIO +#define BOARD_LCD_DC_GPIO_PORT 1U +#define BOARD_LCD_DC_GPIO_PIN 15U + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * API + ******************************************************************************/ + +status_t BOARD_InitDebugConsole(void); +status_t BOARD_InitDebugConsole_Core1(void); +#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED +void BOARD_I2C_Init(I2C_Type *base, uint32_t clkSrc_Hz); +status_t BOARD_I2C_Send(I2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subaddressSize, + uint8_t *txBuff, + uint8_t txBuffSize); +status_t BOARD_I2C_Receive(I2C_Type *base, + uint8_t deviceAddress, + uint32_t subAddress, + uint8_t subaddressSize, + uint8_t *rxBuff, + uint8_t rxBuffSize); +void BOARD_Codec_I2C_Init(void); +status_t BOARD_Codec_I2C_Send( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize); +status_t BOARD_Codec_I2C_Receive( + uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize); +#endif /* SDK_I2C_BASED_COMPONENT_USED */ +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _BOARD_H_ */ diff --git a/board/clock_config.c b/board/clock_config.c new file mode 100644 index 0000000..38487f2 --- /dev/null +++ b/board/clock_config.c @@ -0,0 +1,257 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to set up clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Setup voltage for the fastest of the clock outputs + * + * 3. Set up wait states of the flash. + * + * 4. Set up all dividers. + * + * 5. Set up all selectors to provide selected clocks. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v11.0 +processor: LPC54114J256 +package_id: LPC54114J256BD64 +mcu_data: ksdk2_0 +processor_version: 13.0.1 +board: LPCXpresso54114 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_power.h" +#include "fsl_clock.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL150M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: System_clock.outFreq, value: 12 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Set up FRO */ + POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ + /*!< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF48M +outputs: +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.MAINCLKSELA.sel, value: SYSCON.fro_hf} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF48M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Set up FRO */ + POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(48000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(48000000U); /*!< Set FLASH wait states for core */ + + CLOCK_SetupFROClocking(48000000U); /*!< Set up high frequency FRO output to selected frequency */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + /*!< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF96M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF96M +outputs: +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: SYSCON.MAINCLKSELA.sel, value: SYSCON.fro_hf} +sources: +- {id: SYSCON.fro_hf.outFreq, value: 96 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF96M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Set up FRO */ + POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ + + CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + /*!< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL150M +called_from_default_init: true +outputs: +- {id: PLL_clock.outFreq, value: 144 MHz} +- {id: System_clock.outFreq, value: 144 MHz} +settings: +- {id: PLL_Mode, value: Normal} +- {id: SYSCON.DIRECTO.sel, value: SYSCON.PLL} +- {id: SYSCON.MAINCLKSELA.sel, value: SYSCON.clk_in} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL_BYPASS} +- {id: SYSCON.M_MULT.scale, value: '48', locked: true} +- {id: SYSCON.N_DIV.scale, value: '8', locked: true} +- {id: SYSCON.PLL_BYPASS.sel, value: SYSCON.DIRECTO} +- {id: SYSCON.SYSPLLCLKSEL.sel, value: SYSCON.clk_in} +sources: +- {id: SYSCON.clk_in.outFreq, value: 24 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL150M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Set up FRO */ + POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(144000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(144000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + CLOCK_AttachClk(kEXT_CLK_to_SYS_PLL); /*!< Switch PLL clock source selector to EXT_CLK */ + const pll_setup_t pllSetup = { + .syspllctrl = SYSCON_SYSPLLCTRL_BANDSEL_MASK | SYSCON_SYSPLLCTRL_SELI(52U) | SYSCON_SYSPLLCTRL_SELP(25U) | SYSCON_SYSPLLCTRL_DIRECTO_MASK, + .syspllndec = SYSCON_SYSPLLNDEC_NDEC(44U), + .syspllpdec = SYSCON_SYSPLLPDEC_PDEC(2U), + .syspllssctrl = {(SYSCON_SYSPLLSSCTRL0_MDEC(32682U) | SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK),0x0U}, + .pllRate = 144000000U, + .flags = PLL_SETUPFLAG_POWERUP + }; + CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */ + + /* PLL input more than 20 MHz */ + /* SYSTICK is used for waiting for PLL stabilization */ + + CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 0U, true); /*!< Reset SysTick divider counter and halt it */ + CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 3U, false); /*!< Set SysTick divider to value 3 */ + SysTick->LOAD = 27999UL; /*!< Set SysTick count value */ + SysTick->VAL = 0UL; /*!< Reset current count value */ + SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; /*!< Enable SYSTICK */ + while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != SysTick_CTRL_COUNTFLAG_Msk){} /*!< Waiting for PLL stabilization */ + SysTick->CTRL = 0UL; /*!< Stop SYSTICK */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kSYS_PLL_to_MAIN_CLK); /*!< Switch MAIN_CLK to SYS_PLL */ + SYSCON->MAINCLKSELA = ((SYSCON->MAINCLKSELA & ~SYSCON_MAINCLKSELA_SEL_MASK) | SYSCON_MAINCLKSELA_SEL(1U)); /*!< Switch MAINCLKSELA to EXT_CLK even it is not used for MAINCLKSELB */ + /*!< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; +#endif +} + diff --git a/board/clock_config.h b/board/clock_config.h new file mode 100644 index 0000000..b89aa87 --- /dev/null +++ b/board/clock_config.h @@ -0,0 +1,228 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 12000000U /*!< Board xtal0 frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ + + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKFRO12M_ADC_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_ASYNCAPB_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_CLKOUT_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_DMIC_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM0_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM1_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM2_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM3_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM4_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM5_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM6_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOM7_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_FXCOMS_CLK32K_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_MASTER_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_PLL_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_SYSTICK_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_SYSTEM_CLOCK 12000000UL +#define BOARD_BOOTCLOCKFRO12M_TRACE_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_USB_CLOCK 0UL +#define BOARD_BOOTCLOCKFRO12M_WDT_CLOCK 0UL + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKFROHF48M_ADC_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_ASYNCAPB_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_CLKOUT_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_DMIC_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM0_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM1_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM2_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM3_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM4_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM5_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM6_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOM7_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_FXCOMS_CLK32K_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_MASTER_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_PLL_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_SYSTICK_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_SYSTEM_CLOCK 48000000UL +#define BOARD_BOOTCLOCKFROHF48M_TRACE_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_USB_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF48M_WDT_CLOCK 0UL + +/******************************************************************************* + * API for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF96M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKFROHF96M_ADC_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_ASYNCAPB_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_CLKOUT_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_DMIC_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM0_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM1_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM2_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM3_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM4_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM5_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM6_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOM7_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_FXCOMS_CLK32K_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_MASTER_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_PLL_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_SYSTICK_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_SYSTEM_CLOCK 96000000UL +#define BOARD_BOOTCLOCKFROHF96M_TRACE_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_USB_CLOCK 0UL +#define BOARD_BOOTCLOCKFROHF96M_WDT_CLOCK 0UL + +/******************************************************************************* + * API for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF96M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ + + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKPLL150M_ADC_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_ASYNCAPB_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_CLKOUT_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_DMIC_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM0_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM1_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM2_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM3_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM4_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM5_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM6_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOM7_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_FXCOMS_CLK32K_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_MASTER_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_PLL_CLOCK 144000000UL +#define BOARD_BOOTCLOCKPLL150M_SYSTICK_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_SYSTEM_CLOCK 144000000UL +#define BOARD_BOOTCLOCKPLL150M_TRACE_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_USB_CLOCK 0UL +#define BOARD_BOOTCLOCKPLL150M_WDT_CLOCK 0UL + +/******************************************************************************* + * API for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ + diff --git a/board/pin_mux.c b/board/pin_mux.c new file mode 100644 index 0000000..362977a --- /dev/null +++ b/board/pin_mux.c @@ -0,0 +1,954 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: LPC54114J256 +package_id: LPC54114J256BD64 +mcu_data: ksdk2_0 +processor_version: 13.0.1 +board: LPCXpresso54114 +pin_labels: +- {pin_num: '3', pin_signal: PIO0_25/FC4_RTS_SCL_SSEL1/FC6_CTS_SDA_SSEL0/CTIMER0_CAP2/CTIMER1_CAP1, label: 'J1[1]/JS4[1]/U10[7]/P0_25-FC4_SCLX', identifier: SFTKY4} +- {pin_num: '2', pin_signal: PIO0_24/FC1_CTS_SDA_SSEL0/CTIMER0_CAP1/CTIMER0_MAT0, label: 'J4[10]/JS2[1]/JS5[3]/U10[5]/U12[E6]/SW1/BRIDGE_SDA-WAKEUP', identifier: SFTKY3} +- {pin_num: '1', pin_signal: PIO0_23/FC1_RTS_SCL_SSEL1/CTIMER0_CAP0/UTICK_CAP1, label: 'J4[9]/JS3[1]/JS4[3]/U10[7]/U12[D6]/BRIDGE_SCL', identifier: RST_RF} +- {pin_num: '4', pin_signal: PIO0_26/FC4_CTS_SDA_SSEL0/CTIMER0_CAP3, label: 'J1[3]/JS5[1]/U10[5]/P0_26-FC4_SDAX', identifier: RF_BUSY} +- {pin_num: '7', pin_signal: PIO1_16/PDM0_DATA/CTIMER0_MAT0/CTIMER0_CAP0/FC7_RTS_SCL_SSEL1, label: 'J1[19]/P1_16-CT32B0_MAT0-GYRO_INT1', identifier: CTL_PSU} +- {pin_num: '10', pin_signal: PIO1_17/MCLK/UTICK_CAP3, label: 'J9[9]/P1_17-IR_LEARN_EN', identifier: E_STOP} +- {pin_num: '11', pin_signal: PIO0_29/FC1_RXD_SDA_MOSI/SCT0_OUT2/CTIMER0_MAT3/CTIMER0_CAP1/CTIMER0_MAT1/ADC0_0, label: 'J2[5]/D2[1]/P0_29-CT32B0_MAT3-RED', identifier: I_OUT1} +- {pin_num: '12', pin_signal: PIO0_30/FC1_TXD_SCL_MISO/SCT0_OUT3/CTIMER0_MAT2/CTIMER0_CAP2/ADC0_1, label: 'J9[2]/P0_30-ADC1', identifier: V_OUT1} +- {pin_num: '14', pin_signal: PIO1_0/PDM0_DATA/FC2_RTS_SCL_SSEL1/CTIMER3_MAT1/CTIMER0_CAP0/ADC0_3, label: 'J2[3]/P1_0-PDM0_DATA-CT32B3_MAT1', identifier: PSU_MON} +- {pin_num: '15', pin_signal: PIO1_1/SWO/SCT0_OUT4/FC5_SSEL2/FC4_TXD_SCL_MISO/ADC0_4, label: 'J1[15]/P1_1-FC5_SSEL2', identifier: VBAT_MON} +- {pin_num: '16', pin_signal: PIO1_2/MCLK/FC7_SSEL3/SCT0_OUT5/FC5_SSEL3/FC4_RXD_SDA_MOSI/ADC0_5, label: 'J9[7]/JS8[1]/U5[1]/P1_2-FC5_SSEL3', identifier: ID1} +- {pin_num: '17', pin_signal: PIO1_3/FC7_SSEL2/SCT0_OUT6/FC3_SCK/CTIMER0_CAP1/USB0_UP_LED/ADC0_6, label: 'J2[20]/P1_3-FC7_SSEL2-CT32B0_CAP1', identifier: ID2} +- {pin_num: '18', pin_signal: PIO1_4/PDM1_CLK/FC7_RTS_SCL_SSEL1/SCT0_OUT7/FC3_TXD_SCL_MISO/CTIMER0_MAT1/ADC0_7, label: 'J2[18]/J9[10]/P1_4-ADC7-PDM1_CLK-FC7_RTS-FC3_TXD', + identifier: V_CHK} +- {pin_num: '19', pin_signal: PIO1_5/PDM1_DATA/FC7_CTS_SDA_SSEL0/CTIMER1_CAP0/CTIMER1_MAT3/USB0_FRAME/ADC0_8, label: 'J2[16]/J9[12]/P1_5-ADC8-PDM1_DAT-FC7_CTS', identifier: TEMP} +- {pin_num: '27', pin_signal: PIO1_7/FC7_RXD_SDA_MOSI_DATA/CTIMER1_MAT2/CTIMER1_CAP2/ADC0_10, label: 'J1[10]/P1_7-FC7_RXD_SDA_MOSI_DATA', identifier: BAT_ID} +- {pin_num: '28', pin_signal: PIO1_8/FC7_TXD_SCL_MISO_WS/CTIMER1_MAT3/CTIMER1_CAP3/ADC0_11, label: 'J1[12]/J9[6]/P1_8-ADC11-FC7_TXD_SCL_MISO_FRAME', identifier: LCD_CD} +- {pin_num: '29', pin_signal: PIO1_9/FC3_RXD_SDA_MOSI/CTIMER0_CAP2/USB0_UP_LED, label: 'J9[5]/D2[3]/P1_9-BLUE_LED', identifier: SIG_EN} +- {pin_num: '30', pin_signal: PIO1_10/FC6_TXD_SCL_MISO_WS/SCT0_OUT4/FC1_SCK/USB0_FRAME, label: 'J9[8]/D2[4]/P1_10-SCT4-LED_GREEN', identifier: SD_EN} +- {pin_num: '31', pin_signal: PIO0_0/FC0_RXD_SDA_MOSI/FC3_CTS_SDA_SSEL0/CTIMER0_CAP0/SCT0_OUT3, label: 'U18[4]/TO_MUX_P0_0-ISP_RX', identifier: FC0_MOSI} +- {pin_num: '32', pin_signal: PIO0_1/FC0_TXD_SCL_MISO/FC3_RTS_SCL_SSEL1/CTIMER0_CAP1/SCT0_OUT1, label: 'U6[4]/U22[3]/P0_1-ISP_TX', identifier: FC0_MISO} +- {pin_num: '36', pin_signal: PIO0_2/FC0_CTS_SDA_SSEL0/FC2_SSEL3/CTIMER2_CAP1, label: 'J9[1]/P0_2-GPIO_SPI_CS', identifier: SFTKY1} +- {pin_num: '37', pin_signal: PIO0_3/FC0_RTS_SCL_SSEL1/FC2_SSEL2/CTIMER1_MAT3, label: 'J9[3]/P0_3-GPIO_SPI_CS', identifier: SFTKY2} +- {pin_num: '39', pin_signal: PIO0_5/FC6_RXD_SDA_MOSI_DATA/SCT0_OUT6/CTIMER0_MAT0, label: 'J1[20]/P0_5-FC6_RXD_SDA_MOSI_DATA', identifier: RXD} +- {pin_num: '40', pin_signal: PIO0_6/FC6_TXD_SCL_MISO_WS/CTIMER0_MAT1/UTICK_CAP0, label: 'J1[18]/P0_6-FC6_TXD_SCL_MISO_FRAME', identifier: TXD} +- {pin_num: '41', pin_signal: PIO0_7/FC6_SCK/SCT0_OUT0/CTIMER0_MAT2/CTIMER0_CAP2, label: 'J1[16]/P0_7-FC6_SCK', identifier: POT_CS} +- {pin_num: '42', pin_signal: PIO1_11/FC6_RTS_SCL_SSEL1/CTIMER1_CAP0/FC4_SCK/USB0_VBUS, label: 'J2[19]/P1_11-FC6_RTS_SSEL1-MAG_DRDY', identifier: RAMP_EN} +- {pin_num: '43', pin_signal: PIO0_8/FC2_RXD_SDA_MOSI/SCT0_OUT1/CTIMER0_MAT3, label: 'J2[15]/P0_8-FC2_RXD_SDA_MOSI', identifier: PWM_BAR} +- {pin_num: '44', pin_signal: PIO0_9/FC2_TXD_SCL_MISO/SCT0_OUT2/CTIMER3_CAP0/FC3_CTS_SDA_SSEL0, label: 'J2[13]/P0_9-FC2_TXD_SCL_MISO', identifier: PWM_CPU} +- {pin_num: '45', pin_signal: PIO0_10/FC2_SCK/SCT0_OUT3/CTIMER3_MAT0, label: 'J2[11]/P0_10-FC2_SCK-CT32B3_MAT0', identifier: CS_EEP} +- {pin_num: '46', pin_signal: PIO0_11/FC3_SCK/FC6_RXD_SDA_MOSI_DATA/CTIMER2_MAT1, label: 'J4[4]/U9[13]/BRIDGE_T_SCK', identifier: SCLK} +- {pin_num: '47', pin_signal: PIO0_12/FC3_RXD_SDA_MOSI/FC6_TXD_SCL_MISO_WS/CTIMER2_MAT3, label: 'J4[2]/U9[11]/BRIDGE_T_MOSI', identifier: SDATA} +- {pin_num: '48', pin_signal: PIO0_13/FC3_TXD_SCL_MISO/SCT0_OUT4/CTIMER2_MAT0, label: 'J4[3]/U15[4]/BRIDGE_T_MISO', identifier: SDIN} +- {pin_num: '49', pin_signal: PIO0_14/FC3_CTS_SDA_SSEL0/SCT0_OUT5/CTIMER2_MAT1/FC1_SCK, label: 'J2[12]/J4[1]/U9[14]/BRIDGE_T_SSEL-SPIFI_IO3', identifier: SFTKY0} +- {pin_num: '50', pin_signal: PIO0_15/FC3_RTS_SCL_SSEL1/SWO/CTIMER2_MAT2/FC4_SCK, label: 'J2[10]/JS30/U4[12]/TDO-SWO_TRGT-SPIFI_IO2', identifier: LCD_CS} +- {pin_num: '51', pin_signal: PIO1_12/FC5_RXD_SDA_MOSI/CTIMER1_MAT0/FC7_SCK/UTICK_CAP2, label: 'J2[9]/P1_12-CT32B1_MAT0-ACCl_INT1', identifier: SIG_RST} +- {pin_num: '54', pin_signal: PIO1_13/FC5_TXD_SCL_MISO/CTIMER1_MAT1/FC7_RXD_SDA_MOSI_DATA, label: 'J2[7]/P1_13-CT32B1_MAT1', identifier: SD_RST} +- {pin_num: '57', pin_signal: PIO1_14/FC2_RXD_SDA_MOSI/SCT0_OUT7/FC7_TXD_SCL_MISO_WS, label: 'J2[1]/P1_14-SCTO7', identifier: RAMP_RST} +- {pin_num: '58', pin_signal: PIO0_18/FC5_TXD_SCL_MISO/SCT0_OUT0/CTIMER0_MAT0, label: 'J1[11]/U5[2]/P0_18-FC5_TXD_SCL_MISO', identifier: WRITE} +- {pin_num: '59', pin_signal: PIO0_19/FC5_SCK/SCT0_OUT1/CTIMER0_MAT1, label: 'J1[9]/J2[8]/U5[6]/P0_19-FC5_SCK-SPIFI_CSn', identifier: PORT_LE} +- {pin_num: '60', pin_signal: PIO0_20/FC5_RXD_SDA_MOSI/FC0_SCK/CTIMER3_CAP0, label: 'J1[13]/U5[5]/P0_20-FC5_RXD_SDA_MOSI', identifier: FC0_SCK} +- {pin_num: '61', pin_signal: PIO0_21/CLKOUT/FC0_TXD_SCL_MISO/CTIMER3_MAT0, label: 'J2[2]/P0_21-CLKOUT-SPIFI_CLK', identifier: POT_CS2} +- {pin_num: '62', pin_signal: PIO1_15/PDM0_CLK/SCT0_OUT5/CTIMER1_CAP3/FC7_CTS_SDA_SSEL0, label: 'J1[17]/P1_15-SCTO5-FC7_CTS', identifier: ON_POLL} +- {pin_num: '63', pin_signal: PIO0_22/CLKIN/FC0_RXD_SDA_MOSI/CTIMER3_MAT3, label: 'J4[8]/P0_22-BRIDGE_GPIO', identifier: SYS_CLK} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_gpio.h" +#include "fsl_iocon.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm4, enableClock: 'true'} +- pin_list: + - {pin_num: '31', peripheral: FLEXCOMM0, signal: RXD_SDA_MOSI, pin_signal: PIO0_0/FC0_RXD_SDA_MOSI/FC3_CTS_SDA_SSEL0/CTIMER0_CAP0/SCT0_OUT3, mode: inactive, invert: disabled, + glitch_filter: disabled, slew_rate: standard, open_drain: disabled} + - {pin_num: '32', peripheral: FLEXCOMM0, signal: TXD_SCL_MISO, pin_signal: PIO0_1/FC0_TXD_SCL_MISO/FC3_RTS_SCL_SSEL1/CTIMER0_CAP1/SCT0_OUT1, mode: inactive, invert: disabled, + glitch_filter: disabled, slew_rate: standard, open_drain: disabled} + - {pin_num: '46', peripheral: FLEXCOMM3, signal: SCK, pin_signal: PIO0_11/FC3_SCK/FC6_RXD_SDA_MOSI_DATA/CTIMER2_MAT1, mode: pullUp, invert: disabled, glitch_filter: disabled, + slew_rate: standard, open_drain: disabled} + - {pin_num: '47', peripheral: FLEXCOMM3, signal: RXD_SDA_MOSI, pin_signal: PIO0_12/FC3_RXD_SDA_MOSI/FC6_TXD_SCL_MISO_WS/CTIMER2_MAT3, mode: pullUp, invert: disabled, + glitch_filter: disabled, slew_rate: standard, open_drain: disabled} + - {pin_num: '48', peripheral: FLEXCOMM3, signal: TXD_SCL_MISO, pin_signal: PIO0_13/FC3_TXD_SCL_MISO/SCT0_OUT4/CTIMER2_MAT0, mode: pullUp, invert: disabled, glitch_filter: disabled, + slew_rate: standard, open_drain: disabled} + - {pin_num: '11', peripheral: ADC0, signal: 'CH, 0', pin_signal: PIO0_29/FC1_RXD_SDA_MOSI/SCT0_OUT2/CTIMER0_MAT3/CTIMER0_CAP1/CTIMER0_MAT1/ADC0_0} + - {pin_num: '12', peripheral: ADC0, signal: 'CH, 1', pin_signal: PIO0_30/FC1_TXD_SCL_MISO/SCT0_OUT3/CTIMER0_MAT2/CTIMER0_CAP2/ADC0_1} + - {pin_num: '18', peripheral: ADC0, signal: 'CH, 7', pin_signal: PIO1_4/PDM1_CLK/FC7_RTS_SCL_SSEL1/SCT0_OUT7/FC3_TXD_SCL_MISO/CTIMER0_MAT1/ADC0_7} + - {pin_num: '17', peripheral: ADC0, signal: 'CH, 6', pin_signal: PIO1_3/FC7_SSEL2/SCT0_OUT6/FC3_SCK/CTIMER0_CAP1/USB0_UP_LED/ADC0_6} + - {pin_num: '16', peripheral: ADC0, signal: 'CH, 5', pin_signal: PIO1_2/MCLK/FC7_SSEL3/SCT0_OUT5/FC5_SSEL3/FC4_RXD_SDA_MOSI/ADC0_5} + - {pin_num: '15', peripheral: ADC0, signal: 'CH, 4', pin_signal: PIO1_1/SWO/SCT0_OUT4/FC5_SSEL2/FC4_TXD_SCL_MISO/ADC0_4} + - {pin_num: '14', peripheral: ADC0, signal: 'CH, 3', pin_signal: PIO1_0/PDM0_DATA/FC2_RTS_SCL_SSEL1/CTIMER3_MAT1/CTIMER0_CAP0/ADC0_3} + - {pin_num: '51', peripheral: GPIO, signal: 'PIO1, 12', pin_signal: PIO1_12/FC5_RXD_SDA_MOSI/CTIMER1_MAT0/FC7_SCK/UTICK_CAP2, direction: OUTPUT} + - {pin_num: '54', peripheral: GPIO, signal: 'PIO1, 13', pin_signal: PIO1_13/FC5_TXD_SCL_MISO/CTIMER1_MAT1/FC7_RXD_SDA_MOSI_DATA, direction: OUTPUT} + - {pin_num: '57', peripheral: GPIO, signal: 'PIO1, 14', pin_signal: PIO1_14/FC2_RXD_SDA_MOSI/SCT0_OUT7/FC7_TXD_SCL_MISO_WS, direction: OUTPUT} + - {pin_num: '62', peripheral: GPIO, signal: 'PIO1, 15', pin_signal: PIO1_15/PDM0_CLK/SCT0_OUT5/CTIMER1_CAP3/FC7_CTS_SDA_SSEL0, direction: INPUT} + - {pin_num: '7', peripheral: GPIO, signal: 'PIO1, 16', pin_signal: PIO1_16/PDM0_DATA/CTIMER0_MAT0/CTIMER0_CAP0/FC7_RTS_SCL_SSEL1, direction: OUTPUT, mode: pullDown} + - {pin_num: '60', peripheral: FLEXCOMM0, signal: SCK, pin_signal: PIO0_20/FC5_RXD_SDA_MOSI/FC0_SCK/CTIMER3_CAP0} + - {pin_num: '36', peripheral: GPIO, signal: 'PIO0, 2', pin_signal: PIO0_2/FC0_CTS_SDA_SSEL0/FC2_SSEL3/CTIMER2_CAP1, direction: INPUT} + - {pin_num: '37', peripheral: GPIO, signal: 'PIO0, 3', pin_signal: PIO0_3/FC0_RTS_SCL_SSEL1/FC2_SSEL2/CTIMER1_MAT3, direction: INPUT} + - {pin_num: '41', peripheral: GPIO, signal: 'PIO0, 7', pin_signal: PIO0_7/FC6_SCK/SCT0_OUT0/CTIMER0_MAT2/CTIMER0_CAP2, direction: OUTPUT, gpio_init_state: 'true'} + - {pin_num: '61', peripheral: GPIO, signal: 'PIO0, 21', pin_signal: PIO0_21/CLKOUT/FC0_TXD_SCL_MISO/CTIMER3_MAT0, direction: OUTPUT, gpio_init_state: 'true'} + - {pin_num: '52', peripheral: SWD, signal: SWCLK, pin_signal: PIO0_16/FC3_SSEL2/FC6_CTS_SDA_SSEL0/CTIMER3_MAT1/SWCLK} + - {pin_num: '53', peripheral: SWD, signal: SWDIO, pin_signal: PIO0_17/FC3_SSEL3/FC6_RTS_SCL_SSEL1/CTIMER3_MAT2/SWDIO} + - {pin_num: '28', peripheral: GPIO, signal: 'PIO1, 8', pin_signal: PIO1_8/FC7_TXD_SCL_MISO_WS/CTIMER1_MAT3/CTIMER1_CAP3/ADC0_11, direction: OUTPUT} + - {pin_num: '59', peripheral: GPIO, signal: 'PIO0, 19', pin_signal: PIO0_19/FC5_SCK/SCT0_OUT1/CTIMER0_MAT1, direction: OUTPUT} + - {pin_num: '2', peripheral: GPIO, signal: 'PIO0, 24', pin_signal: PIO0_24/FC1_CTS_SDA_SSEL0/CTIMER0_CAP1/CTIMER0_MAT0, direction: INPUT} + - {pin_num: '3', peripheral: GPIO, signal: 'PIO0, 25', pin_signal: PIO0_25/FC4_RTS_SCL_SSEL1/FC6_CTS_SDA_SSEL0/CTIMER0_CAP2/CTIMER1_CAP1, direction: INPUT} + - {pin_num: '49', peripheral: GPIO, signal: 'PIO0, 14', pin_signal: PIO0_14/FC3_CTS_SDA_SSEL0/SCT0_OUT5/CTIMER2_MAT1/FC1_SCK, direction: INPUT, mode: inactive} + - {pin_num: '19', peripheral: ADC0, signal: 'CH, 8', pin_signal: PIO1_5/PDM1_DATA/FC7_CTS_SDA_SSEL0/CTIMER1_CAP0/CTIMER1_MAT3/USB0_FRAME/ADC0_8} + - {pin_num: '4', peripheral: GPIO, signal: 'PIO0, 26', pin_signal: PIO0_26/FC4_CTS_SDA_SSEL0/CTIMER0_CAP3, direction: OUTPUT, i2c_filter: disabled} + - {pin_num: '10', peripheral: GPIO, signal: 'PIO1, 17', pin_signal: PIO1_17/MCLK/UTICK_CAP3, direction: OUTPUT} + - {pin_num: '27', peripheral: ADC0, signal: 'CH, 10', pin_signal: PIO1_7/FC7_RXD_SDA_MOSI_DATA/CTIMER1_MAT2/CTIMER1_CAP2/ADC0_10} + - {pin_num: '29', peripheral: GPIO, signal: 'PIO1, 9', pin_signal: PIO1_9/FC3_RXD_SDA_MOSI/CTIMER0_CAP2/USB0_UP_LED, direction: OUTPUT} + - {pin_num: '30', peripheral: GPIO, signal: 'PIO1, 10', pin_signal: PIO1_10/FC6_TXD_SCL_MISO_WS/SCT0_OUT4/FC1_SCK/USB0_FRAME, direction: OUTPUT} + - {pin_num: '39', peripheral: FLEXCOMM6, signal: RXD_SDA_MOSI_DATA, pin_signal: PIO0_5/FC6_RXD_SDA_MOSI_DATA/SCT0_OUT6/CTIMER0_MAT0} + - {pin_num: '40', peripheral: FLEXCOMM6, signal: TXD_SCL_MISO_WS, pin_signal: PIO0_6/FC6_TXD_SCL_MISO_WS/CTIMER0_MAT1/UTICK_CAP0, identifier: ''} + - {pin_num: '42', peripheral: GPIO, signal: 'PIO1, 11', pin_signal: PIO1_11/FC6_RTS_SCL_SSEL1/CTIMER1_CAP0/FC4_SCK/USB0_VBUS, direction: OUTPUT} + - {pin_num: '45', peripheral: GPIO, signal: 'PIO0, 10', pin_signal: PIO0_10/FC2_SCK/SCT0_OUT3/CTIMER3_MAT0, direction: OUTPUT} + - {pin_num: '58', peripheral: GPIO, signal: 'PIO0, 18', pin_signal: PIO0_18/FC5_TXD_SCL_MISO/SCT0_OUT0/CTIMER0_MAT0, direction: OUTPUT} + - {pin_num: '63', peripheral: SYSCON, signal: CLKIN, pin_signal: PIO0_22/CLKIN/FC0_RXD_SDA_MOSI/CTIMER3_MAT3} + - {pin_num: '50', peripheral: FLEXCOMM3, signal: RTS_SCL_SSEL1, pin_signal: PIO0_15/FC3_RTS_SCL_SSEL1/SWO/CTIMER2_MAT2/FC4_SCK, identifier: ''} + - {pin_num: '43', peripheral: SCT0, signal: 'OUT, 1', pin_signal: PIO0_8/FC2_RXD_SDA_MOSI/SCT0_OUT1/CTIMER0_MAT3} + - {pin_num: '44', peripheral: SCT0, signal: 'OUT, 2', pin_signal: PIO0_9/FC2_TXD_SCL_MISO/SCT0_OUT2/CTIMER3_CAP0/FC3_CTS_SDA_SSEL0} + - {pin_num: '1', peripheral: SCT0, signal: 'IN, 0', pin_signal: PIO0_23/FC1_RTS_SCL_SSEL1/CTIMER0_CAP0/UTICK_CAP1, identifier: ''} + - {pin_num: '5', peripheral: USB0, signal: USB_DP, pin_signal: USB0_DP} + - {pin_num: '6', peripheral: USB0, signal: USB_DM, pin_signal: USB0_DM} + - {pin_num: '26', peripheral: USB0, signal: USB_VBUS, pin_signal: PIO1_6/FC7_SCK/CTIMER1_CAP2/CTIMER1_MAT2/USB0_VBUS/ADC0_9, identifier: ''} + - {pin_num: '38', peripheral: GPIO, signal: 'PIO0, 4', pin_signal: PIO0_4/FC0_SCK/FC3_SSEL2/CTIMER0_CAP2, direction: OUTPUT} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +/* Function assigned for the Cortex-M4F */ +void BOARD_InitPins(void) +{ + /* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */ + CLOCK_EnableClock(kCLOCK_Iocon); + /* Enables the clock for the GPIO0 module */ + CLOCK_EnableClock(kCLOCK_Gpio0); + /* Enables the clock for the GPIO1 module */ + CLOCK_EnableClock(kCLOCK_Gpio1); + + gpio_pin_config_t SFTKY1_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_2 (pin 36) */ + GPIO_PinInit(BOARD_INITPINS_SFTKY1_GPIO, BOARD_INITPINS_SFTKY1_PORT, BOARD_INITPINS_SFTKY1_PIN, &SFTKY1_config); + + gpio_pin_config_t SFTKY2_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_3 (pin 37) */ + GPIO_PinInit(BOARD_INITPINS_SFTKY2_GPIO, BOARD_INITPINS_SFTKY2_PORT, BOARD_INITPINS_SFTKY2_PIN, &SFTKY2_config); + + gpio_pin_config_t gpio0_pin38_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_4 (pin 38) */ + GPIO_PinInit(GPIO, 0U, 4U, &gpio0_pin38_config); + + gpio_pin_config_t POT_CS_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PIO0_7 (pin 41) */ + GPIO_PinInit(BOARD_INITPINS_POT_CS_GPIO, BOARD_INITPINS_POT_CS_PORT, BOARD_INITPINS_POT_CS_PIN, &POT_CS_config); + + gpio_pin_config_t CS_EEP_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_10 (pin 45) */ + GPIO_PinInit(BOARD_INITPINS_CS_EEP_GPIO, BOARD_INITPINS_CS_EEP_PORT, BOARD_INITPINS_CS_EEP_PIN, &CS_EEP_config); + + gpio_pin_config_t SFTKY0_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_14 (pin 49) */ + GPIO_PinInit(BOARD_INITPINS_SFTKY0_GPIO, BOARD_INITPINS_SFTKY0_PORT, BOARD_INITPINS_SFTKY0_PIN, &SFTKY0_config); + + gpio_pin_config_t WRITE_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_18 (pin 58) */ + GPIO_PinInit(BOARD_INITPINS_WRITE_GPIO, BOARD_INITPINS_WRITE_PORT, BOARD_INITPINS_WRITE_PIN, &WRITE_config); + + gpio_pin_config_t PORT_LE_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_19 (pin 59) */ + GPIO_PinInit(BOARD_INITPINS_PORT_LE_GPIO, BOARD_INITPINS_PORT_LE_PORT, BOARD_INITPINS_PORT_LE_PIN, &PORT_LE_config); + + gpio_pin_config_t POT_CS2_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PIO0_21 (pin 61) */ + GPIO_PinInit(BOARD_INITPINS_POT_CS2_GPIO, BOARD_INITPINS_POT_CS2_PORT, BOARD_INITPINS_POT_CS2_PIN, &POT_CS2_config); + + gpio_pin_config_t SFTKY3_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_24 (pin 2) */ + GPIO_PinInit(BOARD_INITPINS_SFTKY3_GPIO, BOARD_INITPINS_SFTKY3_PORT, BOARD_INITPINS_SFTKY3_PIN, &SFTKY3_config); + + gpio_pin_config_t SFTKY4_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_25 (pin 3) */ + GPIO_PinInit(BOARD_INITPINS_SFTKY4_GPIO, BOARD_INITPINS_SFTKY4_PORT, BOARD_INITPINS_SFTKY4_PIN, &SFTKY4_config); + + gpio_pin_config_t RF_BUSY_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO0_26 (pin 4) */ + GPIO_PinInit(BOARD_INITPINS_RF_BUSY_GPIO, BOARD_INITPINS_RF_BUSY_PORT, BOARD_INITPINS_RF_BUSY_PIN, &RF_BUSY_config); + + gpio_pin_config_t LCD_CD_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_8 (pin 28) */ + GPIO_PinInit(BOARD_INITPINS_LCD_CD_GPIO, BOARD_INITPINS_LCD_CD_PORT, BOARD_INITPINS_LCD_CD_PIN, &LCD_CD_config); + + gpio_pin_config_t SIG_EN_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_9 (pin 29) */ + GPIO_PinInit(BOARD_INITPINS_SIG_EN_GPIO, BOARD_INITPINS_SIG_EN_PORT, BOARD_INITPINS_SIG_EN_PIN, &SIG_EN_config); + + gpio_pin_config_t SD_EN_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_10 (pin 30) */ + GPIO_PinInit(BOARD_INITPINS_SD_EN_GPIO, BOARD_INITPINS_SD_EN_PORT, BOARD_INITPINS_SD_EN_PIN, &SD_EN_config); + + gpio_pin_config_t RAMP_EN_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_11 (pin 42) */ + GPIO_PinInit(BOARD_INITPINS_RAMP_EN_GPIO, BOARD_INITPINS_RAMP_EN_PORT, BOARD_INITPINS_RAMP_EN_PIN, &RAMP_EN_config); + + gpio_pin_config_t SIG_RST_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_12 (pin 51) */ + GPIO_PinInit(BOARD_INITPINS_SIG_RST_GPIO, BOARD_INITPINS_SIG_RST_PORT, BOARD_INITPINS_SIG_RST_PIN, &SIG_RST_config); + + gpio_pin_config_t SD_RST_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_13 (pin 54) */ + GPIO_PinInit(BOARD_INITPINS_SD_RST_GPIO, BOARD_INITPINS_SD_RST_PORT, BOARD_INITPINS_SD_RST_PIN, &SD_RST_config); + + gpio_pin_config_t RAMP_RST_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_14 (pin 57) */ + GPIO_PinInit(BOARD_INITPINS_RAMP_RST_GPIO, BOARD_INITPINS_RAMP_RST_PORT, BOARD_INITPINS_RAMP_RST_PIN, &RAMP_RST_config); + + gpio_pin_config_t ON_POLL_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_15 (pin 62) */ + GPIO_PinInit(BOARD_INITPINS_ON_POLL_GPIO, BOARD_INITPINS_ON_POLL_PORT, BOARD_INITPINS_ON_POLL_PIN, &ON_POLL_config); + + gpio_pin_config_t CTL_PSU_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_16 (pin 7) */ + GPIO_PinInit(BOARD_INITPINS_CTL_PSU_GPIO, BOARD_INITPINS_CTL_PSU_PORT, BOARD_INITPINS_CTL_PSU_PIN, &CTL_PSU_config); + + gpio_pin_config_t E_STOP_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PIO1_17 (pin 10) */ + GPIO_PinInit(BOARD_INITPINS_E_STOP_GPIO, BOARD_INITPINS_E_STOP_PORT, BOARD_INITPINS_E_STOP_PIN, &E_STOP_config); + + const uint32_t FC0_MOSI = (/* Pin is configured as FC0_RXD_SDA_MOSI */ + IOCON_PIO_FUNC1 | + /* No addition pin function */ + IOCON_PIO_MODE_INACT | + /* Input function is not inverted */ + IOCON_PIO_INV_DI | + /* Enables digital function */ + IOCON_PIO_DIGITAL_EN | + /* Input filter disabled */ + IOCON_PIO_INPFILT_OFF | + /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_SLEW_STANDARD | + /* Open drain is disabled */ + IOCON_PIO_OPENDRAIN_DI); + /* PORT0 PIN0 (coords: 31) is configured as FC0_RXD_SDA_MOSI */ + IOCON_PinMuxSet(IOCON, BOARD_INITPINS_FC0_MOSI_PORT, BOARD_INITPINS_FC0_MOSI_PIN, FC0_MOSI); + + const uint32_t FC0_MISO = (/* Pin is configured as FC0_TXD_SCL_MISO */ + IOCON_PIO_FUNC1 | + /* No addition pin function */ + IOCON_PIO_MODE_INACT | + /* Input function is not inverted */ + IOCON_PIO_INV_DI | + /* Enables digital function */ + IOCON_PIO_DIGITAL_EN | + /* Input filter disabled */ + IOCON_PIO_INPFILT_OFF | + /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_SLEW_STANDARD | + /* Open drain is disabled */ + IOCON_PIO_OPENDRAIN_DI); + /* PORT0 PIN1 (coords: 32) is configured as FC0_TXD_SCL_MISO */ + IOCON_PinMuxSet(IOCON, BOARD_INITPINS_FC0_MISO_PORT, BOARD_INITPINS_FC0_MISO_PIN, FC0_MISO); + + IOCON->PIO[0][10] = ((IOCON->PIO[0][10] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT010 (pin 45) is configured as PIO0_10. */ + | IOCON_PIO_FUNC(PIO010_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO010_DIGIMODE_DIGITAL)); + + const uint32_t SCLK = (/* Pin is configured as FC3_SCK */ + IOCON_PIO_FUNC1 | + /* Selects pull-up function */ + IOCON_PIO_MODE_PULLUP | + /* Input function is not inverted */ + IOCON_PIO_INV_DI | + /* Enables digital function */ + IOCON_PIO_DIGITAL_EN | + /* Input filter disabled */ + IOCON_PIO_INPFILT_OFF | + /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_SLEW_STANDARD | + /* Open drain is disabled */ + IOCON_PIO_OPENDRAIN_DI); + /* PORT0 PIN11 (coords: 46) is configured as FC3_SCK */ + IOCON_PinMuxSet(IOCON, BOARD_INITPINS_SCLK_PORT, BOARD_INITPINS_SCLK_PIN, SCLK); + + const uint32_t SDATA = (/* Pin is configured as FC3_RXD_SDA_MOSI */ + IOCON_PIO_FUNC1 | + /* Selects pull-up function */ + IOCON_PIO_MODE_PULLUP | + /* Input function is not inverted */ + IOCON_PIO_INV_DI | + /* Enables digital function */ + IOCON_PIO_DIGITAL_EN | + /* Input filter disabled */ + IOCON_PIO_INPFILT_OFF | + /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_SLEW_STANDARD | + /* Open drain is disabled */ + IOCON_PIO_OPENDRAIN_DI); + /* PORT0 PIN12 (coords: 47) is configured as FC3_RXD_SDA_MOSI */ + IOCON_PinMuxSet(IOCON, BOARD_INITPINS_SDATA_PORT, BOARD_INITPINS_SDATA_PIN, SDATA); + + const uint32_t SDIN = (/* Pin is configured as FC3_TXD_SCL_MISO */ + IOCON_PIO_FUNC1 | + /* Selects pull-up function */ + IOCON_PIO_MODE_PULLUP | + /* Input function is not inverted */ + IOCON_PIO_INV_DI | + /* Enables digital function */ + IOCON_PIO_DIGITAL_EN | + /* Input filter disabled */ + IOCON_PIO_INPFILT_OFF | + /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_SLEW_STANDARD | + /* Open drain is disabled */ + IOCON_PIO_OPENDRAIN_DI); + /* PORT0 PIN13 (coords: 48) is configured as FC3_TXD_SCL_MISO */ + IOCON_PinMuxSet(IOCON, BOARD_INITPINS_SDIN_PORT, BOARD_INITPINS_SDIN_PIN, SDIN); + + IOCON->PIO[0][14] = ((IOCON->PIO[0][14] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT014 (pin 49) is configured as PIO0_14. */ + | IOCON_PIO_FUNC(PIO014_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO014_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO014_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][15] = ((IOCON->PIO[0][15] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT015 (pin 50) is configured as FC3_RTS_SCL_SSEL1. */ + | IOCON_PIO_FUNC(PIO015_FUNC_ALT1) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO015_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][16] = ((IOCON->PIO[0][16] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT016 (pin 52) is configured as SWCLK. */ + | IOCON_PIO_FUNC(PIO016_FUNC_ALT5) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO016_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][17] = ((IOCON->PIO[0][17] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT017 (pin 53) is configured as SWDIO. */ + | IOCON_PIO_FUNC(PIO017_FUNC_ALT5) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO017_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][18] = ((IOCON->PIO[0][18] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT018 (pin 58) is configured as PIO0_18. */ + | IOCON_PIO_FUNC(PIO018_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO018_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][19] = ((IOCON->PIO[0][19] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT019 (pin 59) is configured as PIO0_19. */ + | IOCON_PIO_FUNC(PIO019_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO019_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][2] = ((IOCON->PIO[0][2] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT02 (pin 36) is configured as PIO0_2. */ + | IOCON_PIO_FUNC(PIO02_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO02_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][20] = ((IOCON->PIO[0][20] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT020 (pin 60) is configured as FC0_SCK. */ + | IOCON_PIO_FUNC(PIO020_FUNC_ALT2) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO020_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][21] = ((IOCON->PIO[0][21] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT021 (pin 61) is configured as PIO0_21. */ + | IOCON_PIO_FUNC(PIO021_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO021_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][22] = ((IOCON->PIO[0][22] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT022 (pin 63) is configured as CLKIN. */ + | IOCON_PIO_FUNC(PIO022_FUNC_ALT1) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO022_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][24] = ((IOCON->PIO[0][24] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT024 (pin 2) is configured as PIO0_24. */ + | IOCON_PIO_FUNC(PIO024_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO024_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][25] = ((IOCON->PIO[0][25] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT025 (pin 3) is configured as PIO0_25. */ + | IOCON_PIO_FUNC(PIO025_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO025_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][26] = ((IOCON->PIO[0][26] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK | IOCON_PIO_I2CFILTER_MASK))) + + /* Selects pin function. + * : PORT026 (pin 4) is configured as PIO0_26. */ + | IOCON_PIO_FUNC(PIO026_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO026_DIGIMODE_DIGITAL) + + /* Configures I2C features for standard mode, fast mode, and Fast Mode Plus operation. + * : Disabled. + * I2C 50 ns glitch filter disabled. */ + | IOCON_PIO_I2CFILTER(PIO026_I2CFILTER_DISABLED)); + + IOCON->PIO[0][29] = ((IOCON->PIO[0][29] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT029 (pin 11) is configured as ADC0_0. */ + | IOCON_PIO_FUNC(PIO029_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO029_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO029_DIGIMODE_ANALOG)); + + IOCON->PIO[0][3] = ((IOCON->PIO[0][3] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT03 (pin 37) is configured as PIO0_3. */ + | IOCON_PIO_FUNC(PIO03_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO03_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][30] = ((IOCON->PIO[0][30] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT030 (pin 12) is configured as ADC0_1. */ + | IOCON_PIO_FUNC(PIO030_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO030_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO030_DIGIMODE_ANALOG)); + + IOCON->PIO[0][4] = ((IOCON->PIO[0][4] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT04 (pin 38) is configured as PIO0_4. */ + | IOCON_PIO_FUNC(PIO04_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO04_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][5] = ((IOCON->PIO[0][5] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT05 (pin 39) is configured as FC6_RXD_SDA_MOSI_DATA. */ + | IOCON_PIO_FUNC(PIO05_FUNC_ALT1) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO05_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][6] = ((IOCON->PIO[0][6] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT06 (pin 40) is configured as FC6_TXD_SCL_MISO_WS. */ + | IOCON_PIO_FUNC(PIO06_FUNC_ALT1) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO06_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][7] = ((IOCON->PIO[0][7] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT07 (pin 41) is configured as PIO0_7. */ + | IOCON_PIO_FUNC(PIO07_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO07_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][8] = ((IOCON->PIO[0][8] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT08 (pin 43) is configured as SCT0_OUT1. */ + | IOCON_PIO_FUNC(PIO08_FUNC_ALT2) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO08_DIGIMODE_DIGITAL)); + + IOCON->PIO[0][9] = ((IOCON->PIO[0][9] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT09 (pin 44) is configured as SCT0_OUT2. */ + | IOCON_PIO_FUNC(PIO09_FUNC_ALT2) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO09_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][0] = ((IOCON->PIO[1][0] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT10 (pin 14) is configured as ADC0_3. */ + | IOCON_PIO_FUNC(PIO10_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO10_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO10_DIGIMODE_ANALOG)); + + IOCON->PIO[1][1] = ((IOCON->PIO[1][1] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT11 (pin 15) is configured as ADC0_4. */ + | IOCON_PIO_FUNC(PIO11_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO11_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO11_DIGIMODE_ANALOG)); + + IOCON->PIO[1][10] = ((IOCON->PIO[1][10] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT110 (pin 30) is configured as PIO1_10. */ + | IOCON_PIO_FUNC(PIO110_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO110_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][11] = ((IOCON->PIO[1][11] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT111 (pin 42) is configured as PIO1_11. */ + | IOCON_PIO_FUNC(PIO111_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO111_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][12] = ((IOCON->PIO[1][12] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT112 (pin 51) is configured as PIO1_12. */ + | IOCON_PIO_FUNC(PIO112_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO112_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][13] = ((IOCON->PIO[1][13] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT113 (pin 54) is configured as PIO1_13. */ + | IOCON_PIO_FUNC(PIO113_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO113_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][14] = ((IOCON->PIO[1][14] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT114 (pin 57) is configured as PIO1_14. */ + | IOCON_PIO_FUNC(PIO114_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO114_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][15] = ((IOCON->PIO[1][15] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT115 (pin 62) is configured as PIO1_15. */ + | IOCON_PIO_FUNC(PIO115_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO115_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][16] = ((IOCON->PIO[1][16] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT116 (pin 7) is configured as PIO1_16. */ + | IOCON_PIO_FUNC(PIO116_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Pull-down. + * Pull-down resistor enabled. */ + | IOCON_PIO_MODE(PIO116_MODE_PULL_DOWN) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO116_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][17] = ((IOCON->PIO[1][17] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT117 (pin 10) is configured as PIO1_17. */ + | IOCON_PIO_FUNC(PIO117_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO117_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][2] = ((IOCON->PIO[1][2] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT12 (pin 16) is configured as ADC0_5. */ + | IOCON_PIO_FUNC(PIO12_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO12_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO12_DIGIMODE_ANALOG)); + + IOCON->PIO[1][3] = ((IOCON->PIO[1][3] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT13 (pin 17) is configured as ADC0_6. */ + | IOCON_PIO_FUNC(PIO13_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO13_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO13_DIGIMODE_ANALOG)); + + IOCON->PIO[1][4] = ((IOCON->PIO[1][4] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT14 (pin 18) is configured as ADC0_7. */ + | IOCON_PIO_FUNC(PIO14_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO14_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO14_DIGIMODE_ANALOG)); + + IOCON->PIO[1][5] = ((IOCON->PIO[1][5] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT15 (pin 19) is configured as ADC0_8. */ + | IOCON_PIO_FUNC(PIO15_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO15_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO15_DIGIMODE_ANALOG)); + + IOCON->PIO[1][6] = ((IOCON->PIO[1][6] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT16 (pin 26) is configured as USB0_VBUS. */ + | IOCON_PIO_FUNC(PIO16_FUNC_ALT7) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO16_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][7] = ((IOCON->PIO[1][7] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT17 (pin 27) is configured as ADC0_10. */ + | IOCON_PIO_FUNC(PIO17_FUNC_ALT0) + + /* Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO17_MODE_INACTIVE) + + /* Select Analog/Digital mode. + * : Analog mode. */ + | IOCON_PIO_DIGIMODE(PIO17_DIGIMODE_ANALOG)); + + IOCON->PIO[1][8] = ((IOCON->PIO[1][8] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT18 (pin 28) is configured as PIO1_8. */ + | IOCON_PIO_FUNC(PIO18_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO18_DIGIMODE_DIGITAL)); + + IOCON->PIO[1][9] = ((IOCON->PIO[1][9] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK))) + + /* Selects pin function. + * : PORT19 (pin 29) is configured as PIO1_9. */ + | IOCON_PIO_FUNC(PIO19_FUNC_ALT0) + + /* Select Analog/Digital mode. + * : Digital mode. */ + | IOCON_PIO_DIGIMODE(PIO19_DIGIMODE_DIGITAL)); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/board/pin_mux.h b/board/pin_mux.h new file mode 100644 index 0000000..ecf6adb --- /dev/null +++ b/board/pin_mux.h @@ -0,0 +1,786 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Enables digital function */ +#define IOCON_PIO_DIGITAL_EN 0x80u +/*! + * @brief Selects pin function 1 */ +#define IOCON_PIO_FUNC1 0x01u +/*! + * @brief Input filter disabled */ +#define IOCON_PIO_INPFILT_OFF 0x0100u +/*! + * @brief Input function is not inverted */ +#define IOCON_PIO_INV_DI 0x00u +/*! + * @brief No addition pin function */ +#define IOCON_PIO_MODE_INACT 0x00u +/*! + * @brief Selects pull-up function */ +#define IOCON_PIO_MODE_PULLUP 0x10u +/*! + * @brief Open drain is disabled */ +#define IOCON_PIO_OPENDRAIN_DI 0x00u +/*! + * @brief Standard mode, output slew rate control is enabled */ +#define IOCON_PIO_SLEW_STANDARD 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO010_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO010_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO014_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO014_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO014_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO015_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 1. */ +#define PIO015_FUNC_ALT1 0x01u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO016_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 5. */ +#define PIO016_FUNC_ALT5 0x05u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO017_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 5. */ +#define PIO017_FUNC_ALT5 0x05u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO018_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO018_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO019_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO019_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO020_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 2. */ +#define PIO020_FUNC_ALT2 0x02u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO021_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO021_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO022_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 1. */ +#define PIO022_FUNC_ALT1 0x01u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO024_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO024_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO025_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO025_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO026_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO026_FUNC_ALT0 0x00u +/*! + * @brief + * Configures I2C features for standard mode, fast mode, and Fast Mode Plus operation. + * : Disabled. + * I2C 50 ns glitch filter disabled. + */ +#define PIO026_I2CFILTER_DISABLED 0x01u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO029_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO029_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO029_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO02_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO02_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO030_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO030_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO030_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO03_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO03_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO04_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO04_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO05_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 1. */ +#define PIO05_FUNC_ALT1 0x01u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO06_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 1. */ +#define PIO06_FUNC_ALT1 0x01u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO07_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO07_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO08_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 2. */ +#define PIO08_FUNC_ALT2 0x02u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO09_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 2. */ +#define PIO09_FUNC_ALT2 0x02u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO10_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO10_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO10_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO110_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO110_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO111_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO111_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO112_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO112_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO113_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO113_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO114_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO114_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO115_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO115_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO116_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO116_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Pull-down. + * Pull-down resistor enabled. + */ +#define PIO116_MODE_PULL_DOWN 0x01u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO117_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO117_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO11_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO11_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO11_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO12_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO12_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO12_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO13_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO13_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO13_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO14_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO14_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO14_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO15_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO15_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO15_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO16_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 7. */ +#define PIO16_FUNC_ALT7 0x07u +/*! + * @brief Select Analog/Digital mode.: Analog mode. */ +#define PIO17_DIGIMODE_ANALOG 0x00u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO17_FUNC_ALT0 0x00u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO17_MODE_INACTIVE 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO18_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO18_FUNC_ALT0 0x00u +/*! + * @brief Select Analog/Digital mode.: Digital mode. */ +#define PIO19_DIGIMODE_DIGITAL 0x01u +/*! + * @brief Selects pin function.: Alternative connection 0. */ +#define PIO19_FUNC_ALT0 0x00u + +/*! @name PIO0_0 (number 31), U18[4]/TO_MUX_P0_0-ISP_RX + @{ */ +#define BOARD_INITPINS_FC0_MOSI_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_FC0_MOSI_PIN 0U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_FC0_MOSI_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_1 (number 32), U6[4]/U22[3]/P0_1-ISP_TX + @{ */ +#define BOARD_INITPINS_FC0_MISO_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_FC0_MISO_PIN 1U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_FC0_MISO_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_11 (number 46), J4[4]/U9[13]/BRIDGE_T_SCK + @{ */ +#define BOARD_INITPINS_SCLK_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SCLK_PIN 11U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SCLK_PIN_MASK (1U << 11U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_12 (number 47), J4[2]/U9[11]/BRIDGE_T_MOSI + @{ */ +#define BOARD_INITPINS_SDATA_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SDATA_PIN 12U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SDATA_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_13 (number 48), J4[3]/U15[4]/BRIDGE_T_MISO + @{ */ +#define BOARD_INITPINS_SDIN_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SDIN_PIN 13U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SDIN_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_29 (number 11), J2[5]/D2[1]/P0_29-CT32B0_MAT3-RED + @{ */ +#define BOARD_INITPINS_I_OUT1_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_I_OUT1_PIN 29U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_I_OUT1_PIN_MASK (1U << 29U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_30 (number 12), J9[2]/P0_30-ADC1 + @{ */ +#define BOARD_INITPINS_V_OUT1_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_V_OUT1_PIN 30U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_V_OUT1_PIN_MASK (1U << 30U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_4 (number 18), J2[18]/J9[10]/P1_4-ADC7-PDM1_CLK-FC7_RTS-FC3_TXD + @{ */ +#define BOARD_INITPINS_V_CHK_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_V_CHK_PIN 4U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_V_CHK_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_3 (number 17), J2[20]/P1_3-FC7_SSEL2-CT32B0_CAP1 + @{ */ +#define BOARD_INITPINS_ID2_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_ID2_PIN 3U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_ID2_PIN_MASK (1U << 3U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_2 (number 16), J9[7]/JS8[1]/U5[1]/P1_2-FC5_SSEL3 + @{ */ +#define BOARD_INITPINS_ID1_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_ID1_PIN 2U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_ID1_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_1 (number 15), J1[15]/P1_1-FC5_SSEL2 + @{ */ +#define BOARD_INITPINS_VBAT_MON_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_VBAT_MON_PIN 1U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_VBAT_MON_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_0 (number 14), J2[3]/P1_0-PDM0_DATA-CT32B3_MAT1 + @{ */ +#define BOARD_INITPINS_PSU_MON_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_PSU_MON_PIN 0U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_PSU_MON_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_12 (number 51), J2[9]/P1_12-CT32B1_MAT0-ACCl_INT1 + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SIG_RST_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SIG_RST_GPIO_PIN_MASK (1U << 12U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SIG_RST_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SIG_RST_PIN 12U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SIG_RST_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_13 (number 54), J2[7]/P1_13-CT32B1_MAT1 + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SD_RST_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SD_RST_GPIO_PIN_MASK (1U << 13U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SD_RST_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SD_RST_PIN 13U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SD_RST_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_14 (number 57), J2[1]/P1_14-SCTO7 + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_RAMP_RST_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_RAMP_RST_GPIO_PIN_MASK (1U << 14U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_RAMP_RST_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_RAMP_RST_PIN 14U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_RAMP_RST_PIN_MASK (1U << 14U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_15 (number 62), J1[17]/P1_15-SCTO5-FC7_CTS + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_ON_POLL_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_ON_POLL_GPIO_PIN_MASK (1U << 15U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_ON_POLL_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_ON_POLL_PIN 15U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_ON_POLL_PIN_MASK (1U << 15U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_16 (number 7), J1[19]/P1_16-CT32B0_MAT0-GYRO_INT1 + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_CTL_PSU_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_CTL_PSU_GPIO_PIN_MASK (1U << 16U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_CTL_PSU_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_CTL_PSU_PIN 16U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_CTL_PSU_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_20 (number 60), J1[13]/U5[5]/P0_20-FC5_RXD_SDA_MOSI + @{ */ +#define BOARD_INITPINS_FC0_SCK_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_FC0_SCK_PIN 20U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_FC0_SCK_PIN_MASK (1U << 20U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_2 (number 36), J9[1]/P0_2-GPIO_SPI_CS + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SFTKY1_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SFTKY1_GPIO_PIN_MASK (1U << 2U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SFTKY1_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SFTKY1_PIN 2U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SFTKY1_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_3 (number 37), J9[3]/P0_3-GPIO_SPI_CS + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SFTKY2_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SFTKY2_GPIO_PIN_MASK (1U << 3U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SFTKY2_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SFTKY2_PIN 3U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SFTKY2_PIN_MASK (1U << 3U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_7 (number 41), J1[16]/P0_7-FC6_SCK + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_POT_CS_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_POT_CS_GPIO_PIN_MASK (1U << 7U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_POT_CS_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_POT_CS_PIN 7U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_POT_CS_PIN_MASK (1U << 7U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_21 (number 61), J2[2]/P0_21-CLKOUT-SPIFI_CLK + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_POT_CS2_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_POT_CS2_GPIO_PIN_MASK (1U << 21U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_POT_CS2_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_POT_CS2_PIN 21U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_POT_CS2_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_16 (number 52), J2[4]/JS28/U4[4]/TCK-SWDCLK_TRGT-SPIFI_IO1 + @{ */ +#define BOARD_INITPINS_DEBUG_SWD_SWDCLK_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_DEBUG_SWD_SWDCLK_PIN 16U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_DEBUG_SWD_SWDCLK_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_17 (number 53), J2[6]/P1[2]/U2[5]/U14[4]/IF_TMS_SWDIO-SPIFI_IO0 + @{ */ +#define BOARD_INITPINS_DEBUG_SWD_SWDIO_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_DEBUG_SWD_SWDIO_PIN 17U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_DEBUG_SWD_SWDIO_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_8 (number 28), J1[12]/J9[6]/P1_8-ADC11-FC7_TXD_SCL_MISO_FRAME + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_LCD_CD_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_LCD_CD_GPIO_PIN_MASK (1U << 8U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_LCD_CD_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_LCD_CD_PIN 8U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_LCD_CD_PIN_MASK (1U << 8U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_19 (number 59), J1[9]/J2[8]/U5[6]/P0_19-FC5_SCK-SPIFI_CSn + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_PORT_LE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_PORT_LE_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_PORT_LE_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_PORT_LE_PIN 19U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_PORT_LE_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_24 (number 2), J4[10]/JS2[1]/JS5[3]/U10[5]/U12[E6]/SW1/BRIDGE_SDA-WAKEUP + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SFTKY3_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SFTKY3_GPIO_PIN_MASK (1U << 24U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SFTKY3_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SFTKY3_PIN 24U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SFTKY3_PIN_MASK (1U << 24U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_25 (number 3), J1[1]/JS4[1]/U10[7]/P0_25-FC4_SCLX + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SFTKY4_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SFTKY4_GPIO_PIN_MASK (1U << 25U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SFTKY4_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SFTKY4_PIN 25U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SFTKY4_PIN_MASK (1U << 25U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_14 (number 49), J2[12]/J4[1]/U9[14]/BRIDGE_T_SSEL-SPIFI_IO3 + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SFTKY0_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SFTKY0_GPIO_PIN_MASK (1U << 14U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SFTKY0_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SFTKY0_PIN 14U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SFTKY0_PIN_MASK (1U << 14U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_5 (number 19), J2[16]/J9[12]/P1_5-ADC8-PDM1_DAT-FC7_CTS + @{ */ +#define BOARD_INITPINS_TEMP_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_TEMP_PIN 5U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_TEMP_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_26 (number 4), J1[3]/JS5[1]/U10[5]/P0_26-FC4_SDAX + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_RF_BUSY_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_RF_BUSY_GPIO_PIN_MASK (1U << 26U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_RF_BUSY_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_RF_BUSY_PIN 26U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_RF_BUSY_PIN_MASK (1U << 26U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_17 (number 10), J9[9]/P1_17-IR_LEARN_EN + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_E_STOP_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_E_STOP_GPIO_PIN_MASK (1U << 17U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_E_STOP_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_E_STOP_PIN 17U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_E_STOP_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_7 (number 27), J1[10]/P1_7-FC7_RXD_SDA_MOSI_DATA + @{ */ +#define BOARD_INITPINS_BAT_ID_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_BAT_ID_PIN 7U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_BAT_ID_PIN_MASK (1U << 7U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_9 (number 29), J9[5]/D2[3]/P1_9-BLUE_LED + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SIG_EN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SIG_EN_GPIO_PIN_MASK (1U << 9U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SIG_EN_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SIG_EN_PIN 9U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SIG_EN_PIN_MASK (1U << 9U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_10 (number 30), J9[8]/D2[4]/P1_10-SCT4-LED_GREEN + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_SD_EN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_SD_EN_GPIO_PIN_MASK (1U << 10U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_SD_EN_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SD_EN_PIN 10U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SD_EN_PIN_MASK (1U << 10U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_5 (number 39), J1[20]/P0_5-FC6_RXD_SDA_MOSI_DATA + @{ */ +#define BOARD_INITPINS_RXD_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_RXD_PIN 5U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_RXD_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO1_11 (number 42), J2[19]/P1_11-FC6_RTS_SSEL1-MAG_DRDY + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_RAMP_EN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_RAMP_EN_GPIO_PIN_MASK (1U << 11U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_RAMP_EN_PORT 1U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_RAMP_EN_PIN 11U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_RAMP_EN_PIN_MASK (1U << 11U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_10 (number 45), J2[11]/P0_10-FC2_SCK-CT32B3_MAT0 + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_CS_EEP_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_CS_EEP_GPIO_PIN_MASK (1U << 10U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_CS_EEP_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_CS_EEP_PIN 10U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_CS_EEP_PIN_MASK (1U << 10U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_18 (number 58), J1[11]/U5[2]/P0_18-FC5_TXD_SCL_MISO + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_WRITE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_WRITE_GPIO_PIN_MASK (1U << 18U) /*!<@brief GPIO pin mask */ +#define BOARD_INITPINS_WRITE_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_WRITE_PIN 18U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_WRITE_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_22 (number 63), J4[8]/P0_22-BRIDGE_GPIO + @{ */ +#define BOARD_INITPINS_SYS_CLK_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_SYS_CLK_PIN 22U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_SYS_CLK_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_8 (number 43), J2[15]/P0_8-FC2_RXD_SDA_MOSI + @{ */ +#define BOARD_INITPINS_PWM_BAR_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_PWM_BAR_PIN 8U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_PWM_BAR_PIN_MASK (1U << 8U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PIO0_9 (number 44), J2[13]/P0_9-FC2_TXD_SCL_MISO + @{ */ +#define BOARD_INITPINS_PWM_CPU_PORT 0U /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_PWM_CPU_PIN 9U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_PWM_CPU_PIN_MASK (1U << 9U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name USB0_DP (number 5), J5[3]/U7[2]/USB_DP + @{ */ +/* @} */ + +/*! @name USB0_DM (number 6), J5[2]/U7[3]/USB_DM + @{ */ +/* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); /* Function assigned for the Cortex-M4F */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/component/lists/fsl_component_generic_list.c b/component/lists/fsl_component_generic_list.c new file mode 100644 index 0000000..6184631 --- /dev/null +++ b/component/lists/fsl_component_generic_list.c @@ -0,0 +1,493 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*! ********************************************************************************* +************************************************************************************* +* Include +************************************************************************************* +********************************************************************************** */ +#include "fsl_component_generic_list.h" + +#if defined(OSA_USED) +#include "fsl_os_abstraction.h" +#if (defined(USE_RTOS) && (USE_RTOS > 0U)) +#define LIST_ENTER_CRITICAL() \ + OSA_SR_ALLOC(); \ + OSA_ENTER_CRITICAL() +#define LIST_EXIT_CRITICAL() OSA_EXIT_CRITICAL() +#else +#define LIST_ENTER_CRITICAL() +#define LIST_EXIT_CRITICAL() +#endif +#else +#define LIST_ENTER_CRITICAL() uint32_t regPrimask = DisableGlobalIRQ(); +#define LIST_EXIT_CRITICAL() EnableGlobalIRQ(regPrimask); +#endif + +static list_status_t LIST_Error_Check(list_handle_t list, list_element_handle_t newElement) +{ + list_status_t listStatus = kLIST_Ok; +#if (defined(GENERIC_LIST_DUPLICATED_CHECKING) && (GENERIC_LIST_DUPLICATED_CHECKING > 0U)) + list_element_handle_t element = list->head; +#endif + if ((list->max != 0U) && (list->max == list->size)) + { + listStatus = kLIST_Full; /*List is full*/ + } +#if (defined(GENERIC_LIST_DUPLICATED_CHECKING) && (GENERIC_LIST_DUPLICATED_CHECKING > 0U)) + else + { + while (element != NULL) /*Scan list*/ + { + /* Determine if element is duplicated */ + if (element == newElement) + { + listStatus = kLIST_DuplicateError; + break; + } + element = element->next; + } + } +#endif + return listStatus; +} + +/*! ********************************************************************************* +************************************************************************************* +* Public functions +************************************************************************************* +********************************************************************************** */ +/*! ********************************************************************************* + * \brief Initialises the list descriptor. + * + * \param[in] list - LIST_ handle to init. + * max - Maximum number of elements in list. 0 for unlimited. + * + * \return void. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +void LIST_Init(list_handle_t list, uint32_t max) +{ + list->head = NULL; + list->tail = NULL; + list->max = (uint16_t)max; + list->size = 0; +} + +/*! ********************************************************************************* + * \brief Gets the list that contains the given element. + * + * \param[in] element - Handle of the element. + * + * \return NULL if element is orphan. + * Handle of the list the element is inserted into. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_handle_t LIST_GetList(list_element_handle_t element) +{ + return element->list; +} + +/*! ********************************************************************************* + * \brief Links element to the tail of the list. + * + * \param[in] list - ID of list to insert into. + * element - element to add + * + * \return kLIST_Full if list is full. + * kLIST_Ok if insertion was successful. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element) +{ + LIST_ENTER_CRITICAL(); + list_status_t listStatus = kLIST_Ok; + + listStatus = LIST_Error_Check(list, element); + if (listStatus == kLIST_Ok) /* Avoiding list status error */ + { + if (list->size == 0U) + { + list->head = element; + } + else + { + list->tail->next = element; + } +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) +#else + element->prev = list->tail; +#endif + element->list = list; + element->next = NULL; + list->tail = element; + list->size++; + } + + LIST_EXIT_CRITICAL(); + return listStatus; +} + +/*! ********************************************************************************* + * \brief Links element to the head of the list. + * + * \param[in] list - ID of list to insert into. + * element - element to add + * + * \return kLIST_Full if list is full. + * kLIST_Ok if insertion was successful. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element) +{ + LIST_ENTER_CRITICAL(); + list_status_t listStatus = kLIST_Ok; + + listStatus = LIST_Error_Check(list, element); + if (listStatus == kLIST_Ok) /* Avoiding list status error */ + { + /* Links element to the head of the list */ + if (list->size == 0U) + { + list->tail = element; + } +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) +#else + else + { + list->head->prev = element; + } + element->prev = NULL; +#endif + element->list = list; + element->next = list->head; + list->head = element; + list->size++; + } + + LIST_EXIT_CRITICAL(); + return listStatus; +} + +/*! ********************************************************************************* + * \brief Unlinks element from the head of the list. + * + * \param[in] list - ID of list to remove from. + * + * \return NULL if list is empty. + * ID of removed element(pointer) if removal was successful. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_element_handle_t LIST_RemoveHead(list_handle_t list) +{ + list_element_handle_t element; + + LIST_ENTER_CRITICAL(); + + if ((NULL == list) || (list->size == 0U)) + { + element = NULL; /*LIST_ is empty*/ + } + else + { + element = list->head; + list->size--; + if (list->size == 0U) + { + list->tail = NULL; + } +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) +#else + else + { + element->next->prev = NULL; + } +#endif + element->list = NULL; + list->head = element->next; /*Is NULL if element is head*/ + } + + LIST_EXIT_CRITICAL(); + return element; +} + +/*! ********************************************************************************* + * \brief Gets head element ID. + * + * \param[in] list - ID of list. + * + * \return NULL if list is empty. + * ID of head element if list is not empty. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_element_handle_t LIST_GetHead(list_handle_t list) +{ + return list->head; +} + +/*! ********************************************************************************* + * \brief Gets next element ID. + * + * \param[in] element - ID of the element. + * + * \return NULL if element is tail. + * ID of next element if exists. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_element_handle_t LIST_GetNext(list_element_handle_t element) +{ + return element->next; +} + +/*! ********************************************************************************* + * \brief Gets previous element ID. + * + * \param[in] element - ID of the element. + * + * \return NULL if element is head. + * ID of previous element if exists. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_element_handle_t LIST_GetPrev(list_element_handle_t element) +{ +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + return NULL; +#else + return element->prev; +#endif +} + +/*! ********************************************************************************* + * \brief Unlinks an element from its list. + * + * \param[in] element - ID of the element to remove. + * + * \return kLIST_OrphanElement if element is not part of any list. + * kLIST_Ok if removal was successful. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_status_t LIST_RemoveElement(list_element_handle_t element) +{ + list_status_t listStatus = kLIST_Ok; + LIST_ENTER_CRITICAL(); + + if (element->list == NULL) + { + listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/ + } + else + { +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + list_element_handle_t element_list = element->list->head; + while (NULL != element_list) + { + if (element->list->head == element) + { + element->list->head = element_list->next; + break; + } + if (element_list->next == element) + { + element_list->next = element->next; + break; + } + element_list = element_list->next; + } +#else + if (element->prev == NULL) /*Element is head or solo*/ + { + element->list->head = element->next; /*is null if solo*/ + } + if (element->next == NULL) /*Element is tail or solo*/ + { + element->list->tail = element->prev; /*is null if solo*/ + } + if (element->prev != NULL) /*Element is not head*/ + { + element->prev->next = element->next; + } + if (element->next != NULL) /*Element is not tail*/ + { + element->next->prev = element->prev; + } +#endif + element->list->size--; + element->list = NULL; + } + + LIST_EXIT_CRITICAL(); + return listStatus; +} + +/*! ********************************************************************************* + * \brief Links an element in the previous position relative to a given member + * of a list. + * + * \param[in] element - ID of a member of a list. + * newElement - new element to insert before the given member. + * + * \return kLIST_OrphanElement if element is not part of any list. + * kLIST_Full if list is full. + * kLIST_Ok if insertion was successful. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement) +{ + list_status_t listStatus = kLIST_Ok; + LIST_ENTER_CRITICAL(); + + if (element->list == NULL) + { + listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/ + } + else + { + listStatus = LIST_Error_Check(element->list, newElement); + if (listStatus == kLIST_Ok) + { +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + list_element_handle_t element_list = element->list->head; + while (NULL != element_list) + { + if ((element_list->next == element) || (element_list == element)) + { + if (element_list == element) + { + element->list->head = newElement; + } + else + { + element_list->next = newElement; + } + newElement->list = element->list; + newElement->next = element; + element->list->size++; + break; + } + element_list = element_list->next; + } + +#else + if (element->prev == NULL) /*Element is list head*/ + { + element->list->head = newElement; + } + else + { + element->prev->next = newElement; + } + newElement->list = element->list; + element->list->size++; + newElement->next = element; + newElement->prev = element->prev; + element->prev = newElement; +#endif + } + } + + LIST_EXIT_CRITICAL(); + return listStatus; +} + +/*! ********************************************************************************* + * \brief Gets the current size of a list. + * + * \param[in] list - ID of the list. + * + * \return Current size of the list. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +uint32_t LIST_GetSize(list_handle_t list) +{ + return list->size; +} + +/*! ********************************************************************************* + * \brief Gets the number of free places in the list. + * + * \param[in] list - ID of the list. + * + * \return Available size of the list. + * + * \pre + * + * \post + * + * \remarks + * + ********************************************************************************** */ +uint32_t LIST_GetAvailableSize(list_handle_t list) +{ + return ((uint32_t)list->max - (uint32_t)list->size); /*Gets the number of free places in the list*/ +} diff --git a/component/lists/fsl_component_generic_list.h b/component/lists/fsl_component_generic_list.h new file mode 100644 index 0000000..ccdc219 --- /dev/null +++ b/component/lists/fsl_component_generic_list.h @@ -0,0 +1,201 @@ +/* + * Copyright 2018-2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _GENERIC_LIST_H_ +#define _GENERIC_LIST_H_ + +#include "fsl_common.h" +/*! + * @addtogroup GenericList + * @{ + */ + +/********************************************************************************** +* Include +***********************************************************************************/ + +/********************************************************************************** +* Public macro definitions +***********************************************************************************/ +/*! @brief Definition to determine whether use list light. */ +#ifndef GENERIC_LIST_LIGHT +#define GENERIC_LIST_LIGHT (1) +#endif + +/*! @brief Definition to determine whether enable list duplicated checking. */ +#ifndef GENERIC_LIST_DUPLICATED_CHECKING +#define GENERIC_LIST_DUPLICATED_CHECKING (0) +#endif + +/********************************************************************************** +* Public type definitions +***********************************************************************************/ +/*! @brief The list status */ +typedef enum _list_status +{ + kLIST_Ok = kStatus_Success, /*!< Success */ + kLIST_DuplicateError = MAKE_STATUS(kStatusGroup_LIST, 1), /*!< Duplicate Error */ + kLIST_Full = MAKE_STATUS(kStatusGroup_LIST, 2), /*!< FULL */ + kLIST_Empty = MAKE_STATUS(kStatusGroup_LIST, 3), /*!< Empty */ + kLIST_OrphanElement = MAKE_STATUS(kStatusGroup_LIST, 4), /*!< Orphan Element */ + kLIST_NotSupport = MAKE_STATUS(kStatusGroup_LIST, 5), /*!< Not Support */ +} list_status_t; + +/*! @brief The list structure*/ +typedef struct list_label +{ + struct list_element_tag *head; /*!< list head */ + struct list_element_tag *tail; /*!< list tail */ + uint16_t size; /*!< list size */ + uint16_t max; /*!< list max number of elements */ +} list_label_t, *list_handle_t; +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) +/*! @brief The list element*/ +typedef struct list_element_tag +{ + struct list_element_tag *next; /*!< next list element */ + struct list_label *list; /*!< pointer to the list */ +} list_element_t, *list_element_handle_t; +#else +/*! @brief The list element*/ +typedef struct list_element_tag +{ + struct list_element_tag *next; /*!< next list element */ + struct list_element_tag *prev; /*!< previous list element */ + struct list_label *list; /*!< pointer to the list */ +} list_element_t, *list_element_handle_t; +#endif +/********************************************************************************** +* Public prototypes +***********************************************************************************/ +/********************************************************************************** + * API + **********************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ +/*! + * @brief Initialize the list. + * + * This function initialize the list. + * + * @param list - List handle to initialize. + * @param max - Maximum number of elements in list. 0 for unlimited. + */ +void LIST_Init(list_handle_t list, uint32_t max); + +/*! + * @brief Gets the list that contains the given element. + * + * + * @param element - Handle of the element. + * @retval NULL if element is orphan, Handle of the list the element is inserted into. + */ +list_handle_t LIST_GetList(list_element_handle_t element); + +/*! + * @brief Links element to the head of the list. + * + * @param list - Handle of the list. + * @param element - Handle of the element. + * @retval kLIST_Full if list is full, kLIST_Ok if insertion was successful. + */ +list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element); + +/*! + * @brief Links element to the tail of the list. + * + * @param list - Handle of the list. + * @param element - Handle of the element. + * @retval kLIST_Full if list is full, kLIST_Ok if insertion was successful. + */ +list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element); + +/*! + * @brief Unlinks element from the head of the list. + * + * @param list - Handle of the list. + * + * @retval NULL if list is empty, handle of removed element(pointer) if removal was successful. + */ +list_element_handle_t LIST_RemoveHead(list_handle_t list); + +/*! + * @brief Gets head element handle. + * + * @param list - Handle of the list. + * + * @retval NULL if list is empty, handle of removed element(pointer) if removal was successful. + */ +list_element_handle_t LIST_GetHead(list_handle_t list); + +/*! + * @brief Gets next element handle for given element handle. + * + * @param element - Handle of the element. + * + * @retval NULL if list is empty, handle of removed element(pointer) if removal was successful. + */ +list_element_handle_t LIST_GetNext(list_element_handle_t element); + +/*! + * @brief Gets previous element handle for given element handle. + * + * @param element - Handle of the element. + * + * @retval NULL if list is empty, handle of removed element(pointer) if removal was successful. + */ +list_element_handle_t LIST_GetPrev(list_element_handle_t element); + +/*! + * @brief Unlinks an element from its list. + * + * @param element - Handle of the element. + * + * @retval kLIST_OrphanElement if element is not part of any list. + * @retval kLIST_Ok if removal was successful. + */ +list_status_t LIST_RemoveElement(list_element_handle_t element); + +/*! + * @brief Links an element in the previous position relative to a given member of a list. + * + * @param element - Handle of the element. + * @param newElement - New element to insert before the given member. + * + * @retval kLIST_OrphanElement if element is not part of any list. + * @retval kLIST_Ok if removal was successful. + */ +list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement); + +/*! + * @brief Gets the current size of a list. + * + * @param list - Handle of the list. + * + * @retval Current size of the list. + */ +uint32_t LIST_GetSize(list_handle_t list); + +/*! + * @brief Gets the number of free places in the list. + * + * @param list - Handle of the list. + * + * @retval Available size of the list. + */ +uint32_t LIST_GetAvailableSize(list_handle_t list); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! @}*/ +#endif /*_GENERIC_LIST_H_*/ diff --git a/component/osa/fsl_os_abstraction.h b/component/osa/fsl_os_abstraction.h new file mode 100644 index 0000000..805a3bb --- /dev/null +++ b/component/osa/fsl_os_abstraction.h @@ -0,0 +1,863 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_OS_ABSTRACTION_H_ +#define _FSL_OS_ABSTRACTION_H_ + +#include "fsl_common.h" +#include "fsl_os_abstraction_config.h" +#include "fsl_component_generic_list.h" + +/*! + * @addtogroup osa_adapter + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Type for the Task Priority*/ +typedef uint16_t osa_task_priority_t; +/*! @brief Type for a task handler */ +typedef void *osa_task_handle_t; +/*! @brief Type for the parameter to be passed to the task at its creation */ +typedef void *osa_task_param_t; +/*! @brief Type for task pointer. Task prototype declaration */ +typedef void (*osa_task_ptr_t)(osa_task_param_t task_param); +/*! @brief Type for the semaphore handler */ +typedef void *osa_semaphore_handle_t; +/*! @brief Type for the mutex handler */ +typedef void *osa_mutex_handle_t; +/*! @brief Type for the event handler */ +typedef void *osa_event_handle_t; +/*! @brief Type for an event flags group, bit 32 is reserved. */ +typedef uint32_t osa_event_flags_t; +/*! @brief Message definition. */ +typedef void *osa_msg_handle_t; +/*! @brief Type for the message queue handler */ +typedef void *osa_msgq_handle_t; +/*! @brief Type for the Timer handler */ +typedef void *osa_timer_handle_t; +/*! @brief Type for the Timer callback function pointer. */ +typedef void (*osa_timer_fct_ptr_t)(void const *argument); +/*! @brief Thread Definition structure contains startup information of a thread.*/ +typedef struct osa_task_def_tag +{ + osa_task_ptr_t pthread; /*!< start address of thread function*/ + uint32_t tpriority; /*!< initial thread priority*/ + uint32_t instances; /*!< maximum number of instances of that thread function*/ + uint32_t stacksize; /*!< stack size requirements in bytes; 0 is default stack size*/ + uint32_t *tstack; /*!< stack pointer*/ + void *tlink; /*!< link pointer*/ + uint8_t *tname; /*!< name pointer*/ + uint8_t useFloat; /*!< is use float*/ +} osa_task_def_t; +/*! @brief Thread Link Definition structure .*/ +typedef struct osa_thread_link_tag +{ + uint8_t link[12]; /*!< link*/ + osa_task_handle_t osThreadId; /*!< thread id*/ + osa_task_def_t *osThreadDefHandle; /*!< pointer of thread define handle*/ + uint32_t *osThreadStackHandle; /*!< pointer of thread stack handle*/ +} osa_thread_link_t, *osa_thread_link_handle_t; + +/*! @brief Definition structure contains timer parameters.*/ +typedef struct osa_time_def_tag +{ + osa_timer_fct_ptr_t pfCallback; /* < start address of a timer function */ + void *argument; /* < argument of a timer function */ +} osa_time_def_t; + +/*! @brief Type for the timer definition*/ +typedef enum _osa_timer +{ + KOSA_TimerOnce = 0, /*!< one-shot timer*/ + KOSA_TimerPeriodic = 1 /*!< repeating timer*/ +} osa_timer_t; + +/*! @brief Defines the return status of OSA's functions */ +typedef enum _osa_status +{ + KOSA_StatusSuccess = kStatus_Success, /*!< Success */ + KOSA_StatusError = MAKE_STATUS(kStatusGroup_OSA, 1), /*!< Failed */ + KOSA_StatusTimeout = MAKE_STATUS(kStatusGroup_OSA, 2), /*!< Timeout occurs while waiting */ + KOSA_StatusIdle = MAKE_STATUS(kStatusGroup_OSA, 3), /*!< Used for bare metal only, the wait object is not ready + and timeout still not occur */ +} osa_status_t; + +#ifdef USE_RTOS +#undef USE_RTOS +#endif + +#if defined(FSL_RTOS_MQX) +#define USE_RTOS (1) +#elif defined(FSL_RTOS_FREE_RTOS) +#define USE_RTOS (1) +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) +#define OSA_TASK_HANDLE_SIZE (12U) +#else +#define OSA_TASK_HANDLE_SIZE (16U) +#endif +#define OSA_EVENT_HANDLE_SIZE (8U) +#define OSA_SEM_HANDLE_SIZE (4U) +#define OSA_MUTEX_HANDLE_SIZE (4U) +#define OSA_MSGQ_HANDLE_SIZE (4U) +#define OSA_MSG_HANDLE_SIZE (0U) +#elif defined(FSL_RTOS_UCOSII) +#define USE_RTOS (1) +#elif defined(FSL_RTOS_UCOSIII) +#define USE_RTOS (1) +#else +#define USE_RTOS (0) +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) +#define OSA_TASK_HANDLE_SIZE (24U) +#else +#define OSA_TASK_HANDLE_SIZE (28U) +#endif +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +#define OSA_EVENT_HANDLE_SIZE (20U) +#else +#define OSA_EVENT_HANDLE_SIZE (16U) +#endif /* FSL_OSA_TASK_ENABLE */ +#define OSA_SEM_HANDLE_SIZE (12U) +#define OSA_MUTEX_HANDLE_SIZE (12U) +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +#define OSA_MSGQ_HANDLE_SIZE (32U) +#else +#define OSA_MSGQ_HANDLE_SIZE (28U) +#endif /* FSL_OSA_TASK_ENABLE */ +#define OSA_MSG_HANDLE_SIZE (4U) +#endif + +/*! @brief Priority setting for OSA. */ +#ifndef OSA_PRIORITY_IDLE +#define OSA_PRIORITY_IDLE (6) +#endif + +#ifndef OSA_PRIORITY_LOW +#define OSA_PRIORITY_LOW (5) +#endif + +#ifndef OSA_PRIORITY_BELOW_NORMAL +#define OSA_PRIORITY_BELOW_NORMAL (4) +#endif + +#ifndef OSA_PRIORITY_NORMAL +#define OSA_PRIORITY_NORMAL (3) +#endif + +#ifndef OSA_PRIORITY_ABOVE_NORMAL +#define OSA_PRIORITY_ABOVE_NORMAL (2) +#endif + +#ifndef OSA_PRIORITY_HIGH +#define OSA_PRIORITY_HIGH (1) +#endif + +#ifndef OSA_PRIORITY_REAL_TIME +#define OSA_PRIORITY_REAL_TIME (0) +#endif + +#ifndef OSA_TASK_PRIORITY_MAX +#define OSA_TASK_PRIORITY_MAX (0) +#endif + +#ifndef OSA_TASK_PRIORITY_MIN +#define OSA_TASK_PRIORITY_MIN (15) +#endif + +#define SIZE_IN_UINT32_UNITS(size) (((size) + sizeof(uint32_t) - 1) / sizeof(uint32_t)) + +/*! @brief Constant to pass as timeout value in order to wait indefinitely. */ +#define osaWaitForever_c ((uint32_t)(-1)) +#define osaEventFlagsAll_c ((osa_event_flags_t)(0x00FFFFFF)) +#define osThreadStackArray(name) osThread_##name##_stack +#define osThreadStackDef(name, stacksize, instances) \ + const uint32_t osThreadStackArray(name)[SIZE_IN_UINT32_UNITS(stacksize) * (instances)]; + +/* ==== Thread Management ==== */ + +/* Create a Thread Definition with function, priority, and stack requirements. + * \param name name of the thread function. + * \param priority initial priority of the thread function. + * \param instances number of possible thread instances. + * \param stackSz stack size (in bytes) requirements for the thread function. + * \param useFloat + */ +#if defined(FSL_RTOS_MQX) +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ + osa_thread_link_t osThreadLink_##name[instances] = {0}; \ + osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \ + (name), (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \ + (uint8_t *)#name, (useFloat)} +#elif defined(FSL_RTOS_UCOSII) +#if gTaskMultipleInstancesManagement_c +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ + osa_thread_link_t osThreadLink_##name[instances] = {0}; \ + osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \ + (name), (priority), (instances), (stackSz), osThreadStackArray(name), osThreadLink_##name, \ + (uint8_t *)#name, (useFloat)} +#else +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ + osThreadStackDef(name, stackSz, instances) osa_task_def_t os_thread_def_##name = { \ + (name), (priority), (instances), (stackSz), osThreadStackArray(name), NULL, (uint8_t *)#name, (useFloat)} +#endif +#else +#define OSA_TASK_DEFINE(name, priority, instances, stackSz, useFloat) \ + const osa_task_def_t os_thread_def_##name = {(name), (priority), (instances), (stackSz), \ + NULL, NULL, (uint8_t *)#name, (useFloat)} +#endif +/* Access a Thread defintion. + * \param name name of the thread definition object. + */ +#define OSA_TASK(name) (const osa_task_def_t *)&os_thread_def_##name + +#define OSA_TASK_PROTO(name) externosa_task_def_t os_thread_def_##name +/* ==== Timer Management ==== + * Define a Timer object. + * \param name name of the timer object. + * \param function name of the timer call back function. + */ + +#define OSA_TIMER_DEF(name, function) osa_time_def_t os_timer_def_##name = {(function), NULL} + +/* Access a Timer definition. + * \param name name of the timer object. + */ +#define OSA_TIMER(name) &os_timer_def_##name + +/* ==== Buffer Definition ==== */ + +/*! + * @brief Defines the semaphore handle + * + * This macro is used to define a 4 byte aligned semaphore handle. + * Then use "(osa_semaphore_handle_t)name" to get the semaphore handle. + * + * The macro should be global and could be optional. You could also define semaphore handle by yourself. + * + * This is an example, + * @code + * OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle); + * @endcode + * + * @param name The name string of the semaphore handle. + */ +#define OSA_SEMAPHORE_HANDLE_DEFINE(name) \ + uint32_t name[(OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] + +/*! + * @brief Defines the mutex handle + * + * This macro is used to define a 4 byte aligned mutex handle. + * Then use "(osa_mutex_handle_t)name" to get the mutex handle. + * + * The macro should be global and could be optional. You could also define mutex handle by yourself. + * + * This is an example, + * @code + * OSA_MUTEX_HANDLE_DEFINE(mutexHandle); + * @endcode + * + * @param name The name string of the mutex handle. + */ +#define OSA_MUTEX_HANDLE_DEFINE(name) uint32_t name[(OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] + +/*! + * @brief Defines the event handle + * + * This macro is used to define a 4 byte aligned event handle. + * Then use "(osa_event_handle_t)name" to get the event handle. + * + * The macro should be global and could be optional. You could also define event handle by yourself. + * + * This is an example, + * @code + * OSA_EVENT_HANDLE_DEFINE(eventHandle); + * @endcode + * + * @param name The name string of the event handle. + */ +#define OSA_EVENT_HANDLE_DEFINE(name) uint32_t name[(OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] + +/*! + * @brief Defines the message queue handle + * + * This macro is used to define a 4 byte aligned message queue handle. + * Then use "(osa_msgq_handle_t)name" to get the message queue handle. + * + * The macro should be global and could be optional. You could also define message queue handle by yourself. + * + * This is an example, + * @code + * OSA_MSGQ_HANDLE_DEFINE(msgqHandle, 3, sizeof(msgStruct)); + * @endcode + * + * @param name The name string of the message queue handle. + * @param numberOfMsgs Number of messages. + * @param msgSize Message size. + * + */ +#if defined(FSL_RTOS_FREE_RTOS) +/*< Macro For FREE_RTOS*/ +#define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \ + uint32_t name[(OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] +#else +/*< Macro For BARE_MATEL*/ +#define OSA_MSGQ_HANDLE_DEFINE(name, numberOfMsgs, msgSize) \ + uint32_t name[((OSA_MSGQ_HANDLE_SIZE + numberOfMsgs * msgSize) + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] +#endif + +/*! + * @brief Defines the TASK handle + * + * This macro is used to define a 4 byte aligned TASK handle. + * Then use "(osa_task_handle_t)name" to get the TASK handle. + * + * The macro should be global and could be optional. You could also define TASK handle by yourself. + * + * This is an example, + * @code + * OSA_TASK_HANDLE_DEFINE(taskHandle); + * @endcode + * + * @param name The name string of the TASK handle. + */ +#define OSA_TASK_HANDLE_DEFINE(name) uint32_t name[(OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)] + +#if defined(FSL_RTOS_FREE_RTOS) +#include "fsl_os_abstraction_free_rtos.h" +#else +#include "fsl_os_abstraction_bm.h" +#endif + +extern const uint8_t gUseRtos_c; + +/* + * alloc the temporary memory to store the status + */ +#define OSA_SR_ALLOC() uint32_t osaCurrentSr; +/* + * Enter critical mode + */ +#define OSA_ENTER_CRITICAL() OSA_EnterCritical(&osaCurrentSr) +/* + * Exit critical mode and retore the previous mode + */ +#define OSA_EXIT_CRITICAL() OSA_ExitCritical(osaCurrentSr) + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Reserves the requested amount of memory in bytes. + * + * The function is used to reserve the requested amount of memory in bytes and initializes it to 0. + * + * @param length Amount of bytes to reserve. + * + * @return Pointer to the reserved memory. NULL if memory can't be allocated. + */ +void *OSA_MemoryAllocate(uint32_t length); + +/*! + * @brief Frees the memory previously reserved. + * + * The function is used to free the memory block previously reserved. + * + * @param p Pointer to the start of the memory block previously reserved. + * + */ +void OSA_MemoryFree(void *p); + +/*! + * @brief Enter critical with nesting mode. + * + * @param sr Store current status and return to caller. + */ +void OSA_EnterCritical(uint32_t *sr); + +/*! + * @brief Exit critical with nesting mode. + * + * @param sr Previous status to restore. + */ +void OSA_ExitCritical(uint32_t sr); + +/*! + * @name Task management + * @{ + */ + +/*! + * @brief Creates a task. + * + * This function is used to create task based on the resources defined + * by the macro OSA_TASK_DEFINE. + * + * Example below shows how to use this API to create the task handle. + * @code + * OSA_TASK_HANDLE_DEFINE(taskHandle); + * OSA_TASK_DEFINE( Job1, OSA_PRIORITY_HIGH, 1, 800, 0); + * OSA_TaskCreate((osa_task_handle_t)taskHandle, OSA_TASK(Job1), (osa_task_param_t)NULL); + * @endcode + * + * @param taskHandle Pointer to a memory space of size OSA_TASK_HANDLE_SIZE allocated by the caller, task handle. + * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. + * You can define the handle in the following two ways: + * #OSA_TASK_HANDLE_DEFINE(taskHandle); + * or + * uint32_t taskHandle[((OSA_TASK_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * @param thread_def pointer to theosa_task_def_t structure which defines the task. + * @param task_param Pointer to be passed to the task when it is created. + * @retval KOSA_StatusSuccess The task is successfully created. + * @retval KOSA_StatusError The task can not be created. + */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, + const osa_task_def_t *thread_def, + osa_task_param_t task_param); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! + * @brief Gets the handler of active task. + * + * @return Handler to current active task. + */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_task_handle_t OSA_TaskGetCurrentHandle(void); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! + * @brief Puts the active task to the end of scheduler's queue. + * + * When a task calls this function, it gives up the CPU and puts itself to the + * end of a task ready list. + * + * @retval KOSA_StatusSuccess The function is called successfully. + * @retval KOSA_StatusError Error occurs with this function. + */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskYield(void); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! + * @brief Gets the priority of a task. + * + * @param taskHandle The handler of the task whose priority is received. + * + * @return Task's priority. + */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! + * @brief Sets the priority of a task. + * + * @param taskHandle The handler of the task whose priority is set. + * @param taskPriority The priority to set. + * + * @retval KOSA_StatusSuccess Task's priority is set successfully. + * @retval KOSA_StatusError Task's priority can not be set. + */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! + * @brief Destroys a previously created task. + * + * @param taskHandle The handler of the task to destroy. + * + * @retval KOSA_StatusSuccess The task was successfully destroyed. + * @retval KOSA_StatusError Task destruction failed or invalid parameter. + */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! + * @brief Creates a semaphore with a given value. + * + * This function creates a semaphore and sets the value to the parameter + * initValue. + * + * Example below shows how to use this API to create the semaphore handle. + * @code + * OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle); + * OSA_SemaphoreCreate((osa_semaphore_handle_t)semaphoreHandle, 0xff); + * @endcode + * + * @param semaphoreHandle Pointer to a memory space of size OSA_SEM_HANDLE_SIZE allocated by the caller. + * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. + * You can define the handle in the following two ways: + * #OSA_SEMAPHORE_HANDLE_DEFINE(semaphoreHandle); + * or + * uint32_t semaphoreHandle[((OSA_SEM_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * @param initValue Initial value the semaphore will be set to. + * + * @retval KOSA_StatusSuccess the new semaphore if the semaphore is created successfully. + * @retval KOSA_StatusError if the semaphore can not be created. + */ +osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue); + +/*! + * @brief Destroys a previously created semaphore. + * + * @param semaphoreHandle The semaphore handle. + * The macro SEMAPHORE_HANDLE_BUFFER_GET is used to get the semaphore buffer pointer, + * and should not be used before the macro SEMAPHORE_HANDLE_BUFFER_DEFINE is used. + * + * @retval KOSA_StatusSuccess The semaphore is successfully destroyed. + * @retval KOSA_StatusError The semaphore can not be destroyed. + */ +osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle); + +/*! + * @brief Pending a semaphore with timeout. + * + * This function checks the semaphore's counting value. If it is positive, + * decreases it and returns KOSA_StatusSuccess. Otherwise, a timeout is used + * to wait. + * + * @param semaphoreHandle The semaphore handle. + * @param millisec The maximum number of milliseconds to wait if semaphore is not + * positive. Pass osaWaitForever_c to wait indefinitely, pass 0 + * will return KOSA_StatusTimeout immediately. + * + * @retval KOSA_StatusSuccess The semaphore is received. + * @retval KOSA_StatusTimeout The semaphore is not received within the specified 'timeout'. + * @retval KOSA_StatusError An incorrect parameter was passed. + */ +osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec); + +/*! + * @brief Signals for someone waiting on the semaphore to wake up. + * + * Wakes up one task that is waiting on the semaphore. If no task is waiting, increases + * the semaphore's counting value. + * + * @param semaphoreHandle The semaphore handle to signal. + * + * @retval KOSA_StatusSuccess The semaphore is successfully signaled. + * @retval KOSA_StatusError The object can not be signaled or invalid parameter. + * + */ +osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle); + +/*! + * @brief Create an unlocked mutex. + * + * This function creates a non-recursive mutex and sets it to unlocked status. + * + * Example below shows how to use this API to create the mutex handle. + * @code + * OSA_MUTEX_HANDLE_DEFINE(mutexHandle); + * OSA_MutexCreate((osa_mutex_handle_t)mutexHandle); + * @endcode + * + * @param mutexHandle Pointer to a memory space of size OSA_MUTEX_HANDLE_SIZE allocated by the caller. + * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. + * You can define the handle in the following two ways: + * #OSA_MUTEX_HANDLE_DEFINE(mutexHandle); + * or + * uint32_t mutexHandle[((OSA_MUTEX_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * @retval KOSA_StatusSuccess the new mutex if the mutex is created successfully. + * @retval KOSA_StatusError if the mutex can not be created. + */ +osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle); + +/*! + * @brief Waits for a mutex and locks it. + * + * This function checks the mutex's status. If it is unlocked, locks it and returns the + * KOSA_StatusSuccess. Otherwise, waits for a timeout in milliseconds to lock. + * + * @param mutexHandle The mutex handle. + * @param millisec The maximum number of milliseconds to wait for the mutex. + * If the mutex is locked, Pass the value osaWaitForever_c will + * wait indefinitely, pass 0 will return KOSA_StatusTimeout + * immediately. + * + * @retval KOSA_StatusSuccess The mutex is locked successfully. + * @retval KOSA_StatusTimeout Timeout occurred. + * @retval KOSA_StatusError Incorrect parameter was passed. + * + * @note This is non-recursive mutex, a task can not try to lock the mutex it has locked. + */ +osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec); + +/*! + * @brief Unlocks a previously locked mutex. + * + * @param mutexHandle The mutex handle. + * + * @retval KOSA_StatusSuccess The mutex is successfully unlocked. + * @retval KOSA_StatusError The mutex can not be unlocked or invalid parameter. + */ +osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle); + +/*! + * @brief Destroys a previously created mutex. + * + * @param mutexHandle The mutex handle. + * + * @retval KOSA_StatusSuccess The mutex is successfully destroyed. + * @retval KOSA_StatusError The mutex can not be destroyed. + * + */ +osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle); + +/*! + * @brief Initializes an event object with all flags cleared. + * + * This function creates an event object and set its clear mode. If autoClear + * is 1, when a task gets the event flags, these flags will be + * cleared automatically. Otherwise these flags must + * be cleared manually. + * + * Example below shows how to use this API to create the event handle. + * @code + * OSA_EVENT_HANDLE_DEFINE(eventHandle); + * OSA_EventCreate((osa_event_handle_t)eventHandle, 0); + * @endcode + * + * @param eventHandle Pointer to a memory space of size OSA_EVENT_HANDLE_SIZE allocated by the caller. + * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. + * You can define the handle in the following two ways: + * #OSA_EVENT_HANDLE_DEFINE(eventHandle); + * or + * uint32_t eventHandle[((OSA_EVENT_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * @param autoClear 1 The event is auto-clear. + * 0 The event manual-clear + * @retval KOSA_StatusSuccess the new event if the event is created successfully. + * @retval KOSA_StatusError if the event can not be created. + */ +osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear); + +/*! + * @brief Sets one or more event flags. + * + * Sets specified flags of an event object. + * + * @param eventHandle The event handle. + * @param flagsToSet Flags to be set. + * + * @retval KOSA_StatusSuccess The flags were successfully set. + * @retval KOSA_StatusError An incorrect parameter was passed. + */ +osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet); + +/*! + * @brief Clears one or more flags. + * + * Clears specified flags of an event object. + * + * @param eventHandle The event handle. + * @param flagsToClear Flags to be clear. + * + * @retval KOSA_StatusSuccess The flags were successfully cleared. + * @retval KOSA_StatusError An incorrect parameter was passed. + */ +osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear); + +/*! + * @brief Get event's flags. + * + * Get specified flags of an event object. + * + * @param eventHandle The event handle. + * The macro EVENT_HANDLE_BUFFER_GET is used to get the event buffer pointer, + * and should not be used before the macro EVENT_HANDLE_BUFFER_DEFINE is used. + * @param flagsMask The flags user want to get are specified by this parameter. + * @param pFlagsOfEvent The event flags are obtained by this parameter. + * + * @retval KOSA_StatusSuccess The event flags were successfully got. + * @retval KOSA_StatusError An incorrect parameter was passed. + */ +osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, + osa_event_flags_t flagsMask, + osa_event_flags_t *pFlagsOfEvent); + +/*! + * @brief Waits for specified event flags to be set. + * + * This function waits for a combination of flags to be set in an event object. + * Applications can wait for any/all bits to be set. Also this function could + * obtain the flags who wakeup the waiting task. + * + * @param eventHandle The event handle. + * @param flagsToWait Flags that to wait. + * @param waitAll Wait all flags or any flag to be set. + * @param millisec The maximum number of milliseconds to wait for the event. + * If the wait condition is not met, pass osaWaitForever_c will + * wait indefinitely, pass 0 will return KOSA_StatusTimeout + * immediately. + * @param pSetFlags Flags that wakeup the waiting task are obtained by this parameter. + * + * @retval KOSA_StatusSuccess The wait condition met and function returns successfully. + * @retval KOSA_StatusTimeout Has not met wait condition within timeout. + * @retval KOSA_StatusError An incorrect parameter was passed. + + * + * @note Please pay attention to the flags bit width, FreeRTOS uses the most + * significant 8 bis as control bits, so do not wait these bits while using + * FreeRTOS. + * + */ +osa_status_t OSA_EventWait(osa_event_handle_t eventHandle, + osa_event_flags_t flagsToWait, + uint8_t waitAll, + uint32_t millisec, + osa_event_flags_t *pSetFlags); + +/*! + * @brief Destroys a previously created event object. + * + * @param eventHandle The event handle. + * + * @retval KOSA_StatusSuccess The event is successfully destroyed. + * @retval KOSA_StatusError Event destruction failed. + */ +osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle); + +/*! + * @brief Initializes a message queue. + * + * This function allocates memory for and initializes a message queue. Message queue elements are hardcoded as void*. + * + * Example below shows how to use this API to create the massage queue handle. + * @code + * OSA_MSGQ_HANDLE_DEFINE(msgqHandle); + * OSA_MsgQCreate((osa_msgq_handle_t)msgqHandle, 5U, sizeof(msg)); + * @endcode + * + * @param msgqHandle Pointer to a memory space of size #(OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize) on bare-matel + * and #(OSA_MSGQ_HANDLE_SIZE) on FreeRTOS allocated by the caller, message queue handle. + * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. + * You can define the handle in the following two ways: + * #OSA_MSGQ_HANDLE_DEFINE(msgqHandle); + * or + * For bm: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + msgNo*msgSize + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * For freertos: uint32_t msgqHandle[((OSA_MSGQ_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * @param msgNo :number of messages the message queue should accommodate. + * @param msgSize :size of a single message structure. + * + * @retval KOSA_StatusSuccess Message queue successfully Create. + * @retval KOSA_StatusError Message queue create failure. + */ +osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize); + +/*! + * @brief Puts a message at the end of the queue. + * + * This function puts a message to the end of the message queue. If the queue + * is full, this function returns the KOSA_StatusError; + * + * @param msgqHandle Message Queue handler. + * @param pMessage Pointer to the message to be put into the queue. + * + * @retval KOSA_StatusSuccess Message successfully put into the queue. + * @retval KOSA_StatusError The queue was full or an invalid parameter was passed. + */ +osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage); + +/*! + * @brief Reads and remove a message at the head of the queue. + * + * This function gets a message from the head of the message queue. If the + * queue is empty, timeout is used to wait. + * + * @param msgqHandle Message Queue handler. + * @param pMessage Pointer to a memory to save the message. + * @param millisec The number of milliseconds to wait for a message. If the + * queue is empty, pass osaWaitForever_c will wait indefinitely, + * pass 0 will return KOSA_StatusTimeout immediately. + * + * @retval KOSA_StatusSuccess Message successfully obtained from the queue. + * @retval KOSA_StatusTimeout The queue remains empty after timeout. + * @retval KOSA_StatusError Invalid parameter. + */ +osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec); + +/*! + * @brief Get the available message + * + * This function is used to get the available message. + * + * @param msgqHandle Message Queue handler. + * + * @return Available message count + */ +int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle); + +/*! + * @brief Destroys a previously created queue. + * + * @param msgqHandle Message Queue handler. + * + * @retval KOSA_StatusSuccess The queue was successfully destroyed. + * @retval KOSA_StatusError Message queue destruction failed. + */ +osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle); + +/*! + * @brief Enable all interrupts. + */ +void OSA_InterruptEnable(void); + +/*! + * @brief Disable all interrupts. + */ +void OSA_InterruptDisable(void); + +/*! + * @brief Enable all interrupts using PRIMASK. + */ +void OSA_EnableIRQGlobal(void); + +/*! + * @brief Disable all interrupts using PRIMASK. + */ +void OSA_DisableIRQGlobal(void); + +/*! + * @brief Delays execution for a number of milliseconds. + * + * @param millisec The time in milliseconds to wait. + */ +void OSA_TimeDelay(uint32_t millisec); + +/*! + * @brief This function gets current time in milliseconds. + * + * @retval current time in milliseconds + */ +uint32_t OSA_TimeGetMsec(void); + +/*! + * @brief Installs the interrupt handler. + * + * @param IRQNumber IRQ number of the interrupt. + * @param handler The interrupt handler to install. + */ +void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void)); + +/*! @}*/ +#ifdef __cplusplus +} +#endif +/*! @}*/ +#endif diff --git a/component/osa/fsl_os_abstraction_bm.c b/component/osa/fsl_os_abstraction_bm.c new file mode 100644 index 0000000..bac5ec5 --- /dev/null +++ b/component/osa/fsl_os_abstraction_bm.c @@ -0,0 +1,1323 @@ +/*! + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * + * + * This is the source file for the OS Abstraction layer for MQXLite. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*! ********************************************************************************* +************************************************************************************* +* Include +************************************************************************************* +********************************************************************************** */ +#include "fsl_component_generic_list.h" +#include "fsl_os_abstraction.h" +#include "fsl_os_abstraction_bm.h" +#include + +/*! ********************************************************************************* +************************************************************************************* +* Private macros +************************************************************************************* +********************************************************************************** */ + +/* Weak function. */ +#if defined(__GNUC__) +#define __WEAK_FUNC __attribute__((weak)) +#elif defined(__ICCARM__) +#define __WEAK_FUNC __weak +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +#define __WEAK_FUNC __attribute__((weak)) +#endif + +#ifdef DEBUG_ASSERT +#define OS_ASSERT(condition) \ + if (!(condition)) \ + while (1) \ + ; +#else +#define OS_ASSERT(condition) (void)(condition); +#endif + +/************************************************************************************ +************************************************************************************* +* Private type definitions +************************************************************************************* +************************************************************************************/ + +/*! @brief Type for an semaphore */ +typedef struct Semaphore +{ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ + volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout on this object */ + volatile uint8_t semCount; /*!< The count value of the object */ + +} semaphore_t; + +/*! @brief Type for a mutex */ +typedef struct Mutex +{ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ + volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout on this mutex */ + volatile uint8_t isLocked; /*!< Is the object locked or not */ +} mutex_t; + +#define gIdleTaskPriority_c ((task_priority_t)0) +#define gInvalidTaskPriority_c ((task_priority_t)-1) + +/*! @brief Type for a task handler, returned by the OSA_TaskCreate function */ +typedef void (*task_t)(task_param_t param); +/*! @brief Task control block for bare metal. */ +typedef struct TaskControlBlock +{ + list_element_t link; + osa_task_ptr_t p_func; /*!< Task's entry */ + osa_task_priority_t priority; /*!< Task's priority */ + osa_task_param_t param; /*!< Task's parameter */ + uint8_t haveToRun; /*!< Task was signaled */ +} task_control_block_t; + +/*! @brief Type for a task pointer */ +typedef task_control_block_t *task_handler_t; + +/*! @brief Type for a task stack */ +typedef uint32_t task_stack_t; + +/*! @brief Type for an event object */ +typedef struct Event +{ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ + volatile event_flags_t flags; /*!< The flags status */ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + task_handler_t waitingTask; /*!< Handler to the waiting task */ +#endif + uint8_t autoClear; /*!< Auto clear or manual clear */ + volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout on this event */ +} event_t; + +/*! @brief Type for a message queue */ +typedef struct MsgQueue +{ + volatile uint8_t isWaiting; /*!< Is any task waiting for a timeout */ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ + uint32_t size; /*!< The size(byte) of a single message */ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + task_handler_t waitingTask; /*!< Handler to the waiting task */ +#endif + uint8_t *queueMem; /*!< Points to the queue memory */ + uint16_t number; /*!< The number of messages in the queue */ + uint16_t max; /*!< The max number of queue messages */ + uint16_t head; /*!< Index of the next message to be read */ + uint16_t tail; /*!< Index of the next place to write to */ +} msg_queue_t; + +/*! @brief Type for a message queue handler */ +typedef msg_queue_t *msg_queue_handler_t; + +/*! @brief State structure for bm osa manager. */ +typedef struct _osa_state +{ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + list_label_t taskList; + task_handler_t curTaskHandler; +#endif + volatile uint32_t interruptDisableCount; + volatile uint32_t tickCounter; +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + OSA_TASK_HANDLE_DEFINE(mainTaskHandle); +#endif +} osa_state_t; + +/*! ********************************************************************************* +************************************************************************************* +* Private prototypes +************************************************************************************* +********************************************************************************** */ +__WEAK_FUNC void main_task(osa_task_param_t arg); +__WEAK_FUNC void main_task(osa_task_param_t arg) +{ +} +__WEAK_FUNC void OSA_TimeInit(void); +__WEAK_FUNC uint32_t OSA_TimeDiff(uint32_t time_start, uint32_t time_end); +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_Init(void); +#endif /* FSL_OSA_TASK_ENABLE */ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +void OSA_Start(void); +#endif /* FSL_OSA_TASK_ENABLE */ + +/*! ********************************************************************************* +************************************************************************************* +* Public memory declarations +************************************************************************************* +********************************************************************************** */ +const uint8_t gUseRtos_c = USE_RTOS; /* USE_RTOS = 0 for BareMetal and 1 for OS */ + +/*! ********************************************************************************* +************************************************************************************* +* Private memory declarations +************************************************************************************* +********************************************************************************** */ +static osa_state_t s_osaState; + +/*! ********************************************************************************* +************************************************************************************* +* Public functions +************************************************************************************* +********************************************************************************** */ +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MemoryAllocate + * Description : Reserves the requested amount of memory in bytes. + * + *END**************************************************************************/ +void *OSA_MemoryAllocate(uint32_t length) +{ + void *p = (void *)malloc(length); + + if (NULL != p) + { + (void)memset(p, 0, length); + } + + return p; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MemoryFree + * Description : Frees the memory previously reserved. + * + *END**************************************************************************/ +void OSA_MemoryFree(void *p) +{ + free(p); +} + +void OSA_EnterCritical(uint32_t *sr) +{ + *sr = DisableGlobalIRQ(); +} + +void OSA_ExitCritical(uint32_t sr) +{ + EnableGlobalIRQ(sr); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EnableIRQGlobal + * Description : Disable system interrupt. + * + *END**************************************************************************/ +void OSA_EnableIRQGlobal(void) +{ + if (s_osaState.interruptDisableCount > 0U) + { + s_osaState.interruptDisableCount--; + + if (0U == s_osaState.interruptDisableCount) + { + __enable_irq(); + } + /* call core API to enable the global interrupt*/ + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_DisableIRQGlobal + * Description : Disable system interrupt + * This function will disable the global interrupt by calling the core API + * + *END**************************************************************************/ +void OSA_DisableIRQGlobal(void) +{ + /* call core API to disable the global interrupt*/ + __disable_irq(); + + /* update counter*/ + s_osaState.interruptDisableCount++; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskGetCurrentHandle + * Description : This function is used to get current active task's handler. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_task_handle_t OSA_TaskGetCurrentHandle(void) +{ + return (osa_task_handle_t)s_osaState.curTaskHandler; +} +#endif +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EXT_TaskYield + * Description : When a task calls this function, it will give up CPU and put + * itself to the tail of ready list. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskYield(void) +{ + return KOSA_StatusSuccess; +} +#endif +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskGetPriority + * Description : This function returns task's priority by task handler. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle) +{ + assert(taskHandle); + task_handler_t handler = (task_handler_t)taskHandle; + return handler->priority; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskSetPriority + * Description : This function sets task's priority by task handler. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority) +{ + assert(taskHandle); + list_element_handle_t list_element; + task_control_block_t *tcb = NULL; +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + task_control_block_t *preTcb = NULL; +#endif + task_control_block_t *ptaskStruct = (task_control_block_t *)taskHandle; + uint32_t regPrimask; + + ptaskStruct->priority = taskPriority; + (void)LIST_RemoveElement(&ptaskStruct->link); + /* Insert task control block into the task list. */ + list_element = LIST_GetHead(&s_osaState.taskList); + while (NULL != list_element) + { + tcb = (task_control_block_t *)(void *)list_element; + if (ptaskStruct->priority <= tcb->priority) + { +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + if (preTcb == NULL) + { + (&tcb->link)->list->head = (struct list_element_tag *)(void *)ptaskStruct; + } + else + { + (&preTcb->link)->next = (struct list_element_tag *)(void *)ptaskStruct; + } + (&ptaskStruct->link)->list = (&tcb->link)->list; + (&ptaskStruct->link)->next = (struct list_element_tag *)(void *)tcb; + (&ptaskStruct->link)->list->size++; +#else + (void)LIST_AddPrevElement(&tcb->link, &ptaskStruct->link); +#endif + break; + } +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + preTcb = tcb; +#endif + list_element = LIST_GetNext(list_element); + } + if (ptaskStruct->priority > tcb->priority) + { + OSA_EnterCritical(®Primask); + (void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t)(void *)&(ptaskStruct->link)); + OSA_ExitCritical(regPrimask); + } + + return KOSA_StatusSuccess; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskCreate + * Description : This function is used to create a task and make it ready. + * Param[in] : threadDef - Definition of the thread. + * task_param - Parameter to pass to the new thread. + * Return Thread handle of the new thread, or NULL if failed. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, const osa_task_def_t *thread_def, osa_task_param_t task_param) +{ + list_element_handle_t list_element; + + task_control_block_t *tcb = NULL; +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + task_control_block_t *preTcb = NULL; +#endif + list_status_t listStatus; + + task_control_block_t *ptaskStruct = (task_control_block_t *)taskHandle; + uint32_t regPrimask; + assert(sizeof(task_control_block_t) == OSA_TASK_HANDLE_SIZE); + assert(taskHandle); + + ptaskStruct->p_func = thread_def->pthread; + ptaskStruct->haveToRun = 1U; + ptaskStruct->priority = (uint16_t)PRIORITY_OSA_TO_RTOS(thread_def->tpriority); + ptaskStruct->param = task_param; + + list_element = LIST_GetHead(&s_osaState.taskList); + while (NULL != list_element) + { + tcb = (task_control_block_t *)(void *)list_element; + if (ptaskStruct->priority <= tcb->priority) + { + OSA_EnterCritical(®Primask); +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + if (preTcb == NULL) + { + (&tcb->link)->list->head = (struct list_element_tag *)(void *)ptaskStruct; + } + else + { + (&preTcb->link)->next = (struct list_element_tag *)(void *)ptaskStruct; + } + (&ptaskStruct->link)->list = (&tcb->link)->list; + (&ptaskStruct->link)->next = (struct list_element_tag *)(void *)tcb; + (&ptaskStruct->link)->list->size++; + OSA_ExitCritical(regPrimask); + return KOSA_StatusSuccess; +#else + listStatus = LIST_AddPrevElement(&tcb->link, &ptaskStruct->link); + OSA_ExitCritical(regPrimask); + if (listStatus == (list_status_t)kLIST_DuplicateError) + { + return KOSA_StatusError; + } + break; +#endif + } +#if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U)) + preTcb = tcb; +#endif + list_element = LIST_GetNext(list_element); + } + + if ((NULL == tcb) || (ptaskStruct->priority > tcb->priority)) + { + OSA_EnterCritical(®Primask); + listStatus = LIST_AddTail(&s_osaState.taskList, (list_element_handle_t)(void *)&(ptaskStruct->link)); + (void)listStatus; + assert(listStatus == kLIST_Ok); + OSA_ExitCritical(regPrimask); + } + + return KOSA_StatusSuccess; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskDestroy + * Description : This function destroy a task. + * Param[in] :taskHandle - Thread handle. + * Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle) +{ + uint32_t regPrimask; + assert(taskHandle); + + OSA_EnterCritical(®Primask); + (void)LIST_RemoveElement(taskHandle); + OSA_ExitCritical(regPrimask); + return KOSA_StatusSuccess; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TimeInit + * Description : This function initializes the timer used in BM OSA, the + * functions such as OSA_TimeDelay, OSA_TimeGetMsec, and the timeout are all + * based on this timer. + * + *END**************************************************************************/ +__WEAK_FUNC void OSA_TimeInit(void) +{ +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk); + SysTick->LOAD = (uint32_t)(SystemCoreClock / 1000U - 1U); + SysTick->VAL = 0; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; +#endif +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TimeDiff + * Description : This function gets the difference between two time stamp, + * time overflow is considered. + * + *END**************************************************************************/ +__WEAK_FUNC uint32_t OSA_TimeDiff(uint32_t time_start, uint32_t time_end) +{ + if (time_end >= time_start) + { + return time_end - time_start; + } + else + { + return FSL_OSA_TIME_RANGE - time_start + time_end + 1UL; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA__TimeDelay + * Description : This function is used to suspend the active thread for the given number of milliseconds. + * + *END**************************************************************************/ +void OSA_TimeDelay(uint32_t millisec) +{ +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + uint32_t currTime, timeStart; + + timeStart = OSA_TimeGetMsec(); + + do + { + currTime = OSA_TimeGetMsec(); /* Get current time stamp */ + } while (millisec >= OSA_TimeDiff(timeStart, currTime)); +#endif +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TimeGetMsec + * Description : This function gets current time in milliseconds. + * + *END**************************************************************************/ +__WEAK_FUNC uint32_t OSA_TimeGetMsec(void) +{ +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + return s_osaState.tickCounter; +#else + return 0; +#endif +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaphoreCreate + * Description : This function is used to create a semaphore. + * Return : Semaphore handle of the new semaphore, or NULL if failed. + * + *END**************************************************************************/ + +osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue) +{ + semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle; + assert(sizeof(semaphore_t) == OSA_SEM_HANDLE_SIZE); + assert(semaphoreHandle); + + pSemStruct->semCount = (uint8_t)initValue; + pSemStruct->isWaiting = 0U; + pSemStruct->time_start = 0U; + pSemStruct->timeout = 0U; + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaphoreDestroy + * Description : This function is used to destroy a semaphore. + * Return : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError. + * + *END**************************************************************************/ +osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle) +{ + assert(semaphoreHandle); + semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle; + + /* Destroy semaphoreHandle's data */ + (void)memset(pSemStruct, 0, sizeof(semaphore_t)); + + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaphoreWait + * Description : This function checks the semaphore's counting value, if it is + * positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout + * will be used for wait. The parameter timeout indicates how long should wait + * in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will + * return KOSA_StatusTimeout immediately if semaphore is not positive. + * This function returns KOSA_StatusSuccess if the semaphore is received, returns + * KOSA_StatusTimeout if the semaphore is not received within the specified + * 'timeout', returns KOSA_StatusError if any errors occur during waiting. + * + *END**************************************************************************/ +osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec) +{ + semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle; + uint32_t regPrimask; + assert(semaphoreHandle); +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + uint32_t currentTime; +#endif + /* Check the sem count first. Deal with timeout only if not already set */ + + if (0U != pSemStruct->semCount) + { + OSA_EnterCritical(®Primask); + pSemStruct->semCount--; + pSemStruct->isWaiting = 0U; + OSA_ExitCritical(regPrimask); + return KOSA_StatusSuccess; + } + else + { + if (0U == millisec) + { + /* If timeout is 0 and semaphore is not available, return kStatus_OSA_Timeout. */ + return KOSA_StatusTimeout; + } +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + else if (0U != pSemStruct->isWaiting) + { + /* Check for timeout */ + currentTime = OSA_TimeGetMsec(); + if (pSemStruct->timeout < OSA_TimeDiff(pSemStruct->time_start, currentTime)) + { + OSA_EnterCritical(®Primask); + pSemStruct->isWaiting = 0U; + OSA_ExitCritical(regPrimask); + return KOSA_StatusTimeout; + } + } + else if (millisec != osaWaitForever_c) /* If don't wait forever, start the timer */ + { + /* Start the timeout counter */ + OSA_EnterCritical(®Primask); + pSemStruct->isWaiting = 1U; + OSA_ExitCritical(regPrimask); + pSemStruct->time_start = OSA_TimeGetMsec(); + pSemStruct->timeout = millisec; + } +#endif + else + { + ; + } + } + + return KOSA_StatusIdle; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaphorePost + * Description : This function is used to wake up one task that wating on the + * semaphore. If no task is waiting, increase the semaphore. The function returns + * KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns + * KOSA_StatusError. + * + *END**************************************************************************/ +osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle) +{ + semaphore_t *pSemStruct = (semaphore_t *)semaphoreHandle; + uint32_t regPrimask; + assert(semaphoreHandle); + + /* The max value is 0xFF */ + if (0xFFU == pSemStruct->semCount) + { + return KOSA_StatusError; + } + OSA_EnterCritical(®Primask); + ++pSemStruct->semCount; + OSA_ExitCritical(regPrimask); + + return KOSA_StatusSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexCreate + * Description : This function is used to create a mutex. + * Return : Mutex handle of the new mutex, or NULL if failed. + * + *END**************************************************************************/ +osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle) +{ + mutex_t *pMutexStruct = (mutex_t *)mutexHandle; + assert(sizeof(mutex_t) == OSA_MUTEX_HANDLE_SIZE); + assert(mutexHandle); + + pMutexStruct->isLocked = 0U; + pMutexStruct->isWaiting = 0U; + pMutexStruct->time_start = 0u; + pMutexStruct->timeout = 0u; + return KOSA_StatusSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexLock + * Description : This function checks the mutex's status, if it is unlocked, + * lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex. + * MQX does not support timeout to wait for a mutex. + * This function returns KOSA_StatusSuccess if the mutex is obtained, returns + * KOSA_StatusError if any errors occur during waiting. If the mutex has been + * locked, pass 0 as timeout will return KOSA_StatusTimeout immediately. + * + *END**************************************************************************/ +osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec) +{ +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + uint32_t currentTime; +#endif + mutex_t *pMutexStruct = (mutex_t *)mutexHandle; + uint32_t regPrimask; + + /* Always check first. Deal with timeout only if not available. */ + if (0U == pMutexStruct->isLocked) + { + /* Get the lock and return success */ + OSA_EnterCritical(®Primask); + pMutexStruct->isLocked = 1U; + pMutexStruct->isWaiting = 0U; + OSA_ExitCritical(regPrimask); + return KOSA_StatusSuccess; + } + else + { + if (0U == millisec) + { + /* If timeout is 0 and mutex is not available, return kStatus_OSA_Timeout. */ + return KOSA_StatusTimeout; + } +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + else if (pMutexStruct->isWaiting != 0U) + { + /* Check for timeout */ + currentTime = OSA_TimeGetMsec(); + if (pMutexStruct->timeout < OSA_TimeDiff(pMutexStruct->time_start, currentTime)) + { + OSA_EnterCritical(®Primask); + pMutexStruct->isWaiting = 0U; + OSA_ExitCritical(regPrimask); + return KOSA_StatusTimeout; + } + } + else if (millisec != osaWaitForever_c) /* If dont't wait forever, start timer. */ + { + /* Start the timeout counter */ + OSA_EnterCritical(®Primask); + pMutexStruct->isWaiting = 1U; + OSA_ExitCritical(regPrimask); + pMutexStruct->time_start = OSA_TimeGetMsec(); + pMutexStruct->timeout = millisec; + } +#endif + else + { + ; + } + } + + return KOSA_StatusIdle; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexUnlock + * Description : This function is used to unlock a mutex. + * + *END**************************************************************************/ +osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle) +{ + mutex_t *pMutexStruct = (mutex_t *)mutexHandle; + uint32_t regPrimask; + assert(mutexHandle); + + OSA_EnterCritical(®Primask); + pMutexStruct->isLocked = 0U; + OSA_ExitCritical(regPrimask); + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexDestroy + * Description : This function is used to destroy a mutex. + * Return : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError. + * + *END**************************************************************************/ +osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle) +{ + assert(mutexHandle); + mutex_t *pMutexStruct = (mutex_t *)mutexHandle; + + /* Destory mutexHandle's data */ + (void)memset(pMutexStruct, 0, sizeof(mutex_t)); + + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventCreate + * Description : This function is used to create a event object. + * Return : Event handle of the new event, or NULL if failed. + * + *END**************************************************************************/ +osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear) +{ + event_t *pEventStruct = eventHandle; + assert(sizeof(event_t) == OSA_EVENT_HANDLE_SIZE); + assert(eventHandle); + + pEventStruct->isWaiting = 0U; + pEventStruct->flags = 0; + pEventStruct->autoClear = autoClear; + pEventStruct->time_start = 0u; + pEventStruct->timeout = 0u; +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + pEventStruct->waitingTask = NULL; +#endif + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventSet + * Description : Set one or more event flags of an event object. + * Return : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed. + * + *END**************************************************************************/ +osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet) +{ + event_t *pEventStruct; + uint32_t regPrimask; + pEventStruct = (event_t *)eventHandle; + /* Set flags ensuring atomic operation */ + OSA_EnterCritical(®Primask); + pEventStruct->flags |= flagsToSet; +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + if (pEventStruct->waitingTask != NULL) + { + pEventStruct->waitingTask->haveToRun = 1U; + } +#endif + OSA_ExitCritical(regPrimask); + + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventClear + * Description : Clear one or more event flags of an event object. + * Return :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed. + * + *END**************************************************************************/ +osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear) +{ + event_t *pEventStruct; + uint32_t regPrimask; + pEventStruct = (event_t *)eventHandle; + /* Clear flags ensuring atomic operation */ + OSA_EnterCritical(®Primask); + pEventStruct->flags &= ~flagsToClear; + if (0U != pEventStruct->flags) + { +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + if (NULL != pEventStruct->waitingTask) + { + pEventStruct->waitingTask->haveToRun = 1U; + } +#endif + } + OSA_ExitCritical(regPrimask); + + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventGet + * Description : This function is used to get event's flags that specified by prameter + * flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So + * you should pass the parameter 0xffffffff to specify you want to get all. + * Return :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed. + * + *END**************************************************************************/ +osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent) +{ + event_t *pEventStruct; + pEventStruct = (event_t *)eventHandle; + OSA_SR_ALLOC(); + + if (NULL == pFlagsOfEvent) + { + return KOSA_StatusError; + } + + OSA_ENTER_CRITICAL(); + *pFlagsOfEvent = pEventStruct->flags & flagsMask; + OSA_EXIT_CRITICAL(); + + return KOSA_StatusSuccess; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventWait + * Description : This function checks the event's status, if it meets the wait + * condition, return KOSA_StatusSuccess, otherwise, timeout will be used for + * wait. The parameter timeout indicates how long should wait in milliseconds. + * Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value + * KOSA_StatusTimeout immediately if wait condition is not met. The event flags + * will be cleared if the event is auto clear mode. Flags that wakeup waiting + * task could be obtained from the parameter setFlags. + * This function returns KOSA_StatusSuccess if wait condition is met, returns + * KOSA_StatusTimeout if wait condition is not met within the specified + * 'timeout', returns KOSA_StatusError if any errors occur during waiting. + * + *END**************************************************************************/ +osa_status_t OSA_EventWait(osa_event_handle_t eventHandle, + osa_event_flags_t flagsToWait, + uint8_t waitAll, + uint32_t millisec, + osa_event_flags_t *pSetFlags) +{ + event_t *pEventStruct; + uint32_t regPrimask; +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + uint32_t currentTime; +#endif + osa_status_t retVal = KOSA_StatusIdle; + if (NULL == pSetFlags) + { + return KOSA_StatusError; + } + + pEventStruct = (event_t *)eventHandle; + + OSA_EnterCritical(®Primask); +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +#if (TASK_MAX_NUM > 0) + pEventStruct->waitingTask = OSA_TaskGetCurrentHandle(); +#endif +#endif + + *pSetFlags = pEventStruct->flags & flagsToWait; + + /* Check the event flag first, if does not meet wait condition, deal with timeout. */ + if (((0U == waitAll) && (0U != *pSetFlags)) || (*pSetFlags == flagsToWait)) + { + pEventStruct->isWaiting = 0U; + if (1U == pEventStruct->autoClear) + { + pEventStruct->flags &= ~flagsToWait; + } + retVal = KOSA_StatusSuccess; + } + else + { + if (0U == millisec) + { + /* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */ + retVal = KOSA_StatusTimeout; + } +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + else if (0U != pEventStruct->isWaiting) + { + /* Check for timeout */ + currentTime = OSA_TimeGetMsec(); + if (pEventStruct->timeout < OSA_TimeDiff(pEventStruct->time_start, currentTime)) + { + pEventStruct->isWaiting = 0U; + retVal = KOSA_StatusTimeout; + } + } + else if (millisec != osaWaitForever_c) /* If no timeout, don't start the timer */ + { + /* Start the timeout counter */ + pEventStruct->isWaiting = 1U; + pEventStruct->time_start = OSA_TimeGetMsec(); + pEventStruct->timeout = millisec; + } +#endif + else + { +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + pEventStruct->waitingTask->haveToRun = 0U; +#endif + } + } + + OSA_ExitCritical(regPrimask); + + return retVal; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventDestroy + * Description : This function is used to destroy a event object. Return + * KOSA_StatusSuccess if the event object is destroyed successfully, otherwise + * return KOSA_StatusError. + * + *END**************************************************************************/ +osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle) +{ + assert(eventHandle); + event_t *pEventStruct = (event_t *)eventHandle; + + /* Destroy eventHandle's data */ + (void)memset(pEventStruct, 0, sizeof(event_t)); + + return KOSA_StatusSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQCreate + * Description : This function is used to create a message queue. + * Return : the handle to the message queue if create successfully, otherwise + * return NULL. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize) +{ + msg_queue_t *pMsgQStruct = msgqHandle; + assert(sizeof(msg_queue_t) == OSA_MSGQ_HANDLE_SIZE); + assert(msgqHandle); + + pMsgQStruct->max = (uint16_t)msgNo; + pMsgQStruct->number = 0; + pMsgQStruct->head = 0; + pMsgQStruct->tail = 0; + pMsgQStruct->size = msgSize; + pMsgQStruct->queueMem = (uint8_t *)((uint8_t *)msgqHandle + sizeof(msg_queue_t)); + return KOSA_StatusSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQPut + * Description : This function is used to put a message to a message queue. + * Return : KOSA_StatusSuccess if the message is put successfully, otherwise return KOSA_StatusError. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage) +{ + assert(msgqHandle); + msg_queue_t *pQueue; + osa_status_t status = KOSA_StatusSuccess; + uint32_t regPrimask; + + uint8_t *pMsgArray; + + pQueue = (msg_queue_t *)msgqHandle; + + if (NULL == pQueue->queueMem) + { + return KOSA_StatusError; + } + + OSA_EnterCritical(®Primask); + if (pQueue->number >= pQueue->max) + { + status = KOSA_StatusError; + } + else + { + pMsgArray = &pQueue->queueMem[pQueue->tail]; + for (uint32_t i = 0; i < pQueue->size; i++) + { + pMsgArray[i] = *((uint8_t *)pMessage + i); + } + + pQueue->number++; + pQueue->tail += (uint16_t)pQueue->size; + + if (pQueue->tail >= (pQueue->max * pQueue->size)) + { + pQueue->tail = 0; + } +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + if (NULL != pQueue->waitingTask) + { + pQueue->waitingTask->haveToRun = 1U; + } +#endif + } + OSA_ExitCritical(regPrimask); + return status; +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQGet + * Description : This function checks the queue's status, if it is not empty, + * get message from it and return KOSA_StatusSuccess, otherwise, timeout will + * be used for wait. The parameter timeout indicates how long should wait in + * milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will return + * KOSA_StatusTimeout immediately if queue is empty. + * This function returns KOSA_StatusSuccess if message is got successfully, + * returns KOSA_StatusTimeout if message queue is empty within the specified + * 'timeout', returns KOSA_StatusError if any errors occur during waiting. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec) +{ + assert(msgqHandle); + msg_queue_t *pQueue; + osa_status_t status = KOSA_StatusSuccess; + uint32_t regPrimask; + + uint8_t *pMsgArray; + +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + uint32_t currentTime; +#endif + + pQueue = (msg_queue_t *)msgqHandle; + + if (NULL == pQueue->queueMem) + { + return KOSA_StatusError; + } + +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + pQueue->waitingTask = OSA_TaskGetCurrentHandle(); +#endif + + OSA_EnterCritical(®Primask); + if (0U != pQueue->number) + { + pMsgArray = (uint8_t *)pMessage; + for (uint32_t i = 0; i < pQueue->size; i++) + { + pMsgArray[i] = pQueue->queueMem[pQueue->head + i]; + } + + pQueue->number--; + pQueue->head += (uint16_t)pQueue->size; + pQueue->isWaiting = 0U; + + if (pQueue->head >= (pQueue->max * pQueue->size)) + { + pQueue->head = 0; + } + status = KOSA_StatusSuccess; + } + else + { + if (0U == millisec) + { + /* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */ + status = KOSA_StatusTimeout; + } +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + else if (0U != pQueue->isWaiting) + { + /* Check for timeout */ + status = KOSA_StatusIdle; /* Before a timeout, the status should be idle. */ + currentTime = OSA_TimeGetMsec(); + if (pQueue->timeout < OSA_TimeDiff(pQueue->time_start, currentTime)) + { + pQueue->isWaiting = 0U; + status = KOSA_StatusTimeout; + } + } + else if (millisec != osaWaitForever_c) /* If no timeout, don't start the timer */ + { + /* Start the timeout counter */ + pQueue->isWaiting = 1U; + pQueue->time_start = OSA_TimeGetMsec(); + pQueue->timeout = millisec; + status = KOSA_StatusIdle; + } +#endif + else + { +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) + pQueue->waitingTask->haveToRun = 0U; +#endif + status = KOSA_StatusIdle; + } + } + OSA_ExitCritical(regPrimask); + + return status; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQAvailableMsgs + * Description : This function is used to get the available message. + * Return : Available message count + * + *END**************************************************************************/ +int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle) +{ + assert(msgqHandle); + msg_queue_t *pQueue = (msg_queue_t *)msgqHandle; + + return (int)pQueue->number; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EXT_MsgQDestroy + * Description : This function is used to destroy the message queue. + * Return : KOSA_StatusSuccess if the message queue is destroyed successfully, otherwise return KOSA_StatusError. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle) +{ + assert(msgqHandle); + msg_queue_t *pQueue = (msg_queue_t *)msgqHandle; + + /* Destory msgqHandle's data */ + /* OSA_MsgQGet() & OSA_MsgQPut() will check queueMem, if NULL will return an error. */ + (void)memset(pQueue, 0, sizeof(msg_queue_t)); + + return KOSA_StatusSuccess; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_InterruptEnable + * Description : self explanatory. + * + *END**************************************************************************/ +void OSA_InterruptEnable(void) +{ + OSA_EnableIRQGlobal(); +} +/*FUNCTION********************************************************************** + * + * Function Name : OSA_InterruptDisable + * Description : self explanatory. + * + *END**************************************************************************/ +void OSA_InterruptDisable(void) +{ + OSA_DisableIRQGlobal(); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_InstallIntHandler + * Description : This function is used to install interrupt handler. + * + *END**************************************************************************/ +void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void)) +{ +#if defined(__IAR_SYSTEMS_ICC__) + _Pragma("diag_suppress = Pm138") +#endif +#if defined(ENABLE_RAM_VECTOR_TABLE) + (void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t) * (uint32_t *)&handler); +#endif /* ENABLE_RAM_VECTOR_TABLE. */ +#if defined(__IAR_SYSTEMS_ICC__) + _Pragma("diag_remark = PM138") +#endif +} + +/*! ********************************************************************************* +************************************************************************************* +* Private functions +************************************************************************************* +********************************************************************************** */ +#if ((defined(FSL_OSA_TASK_ENABLE)) && (FSL_OSA_TASK_ENABLE > 0U)) + +static OSA_TASK_DEFINE(main_task, gMainThreadPriority_c, 1, gMainThreadStackSize_c, 0); + +int main(void) +{ + extern void BOARD_InitHardware(void); + (void)OSA_Init(); + /* Initialize MCU clock */ + BOARD_InitHardware(); +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) + OSA_TimeInit(); +#endif + (void)OSA_TaskCreate((osa_task_handle_t)s_osaState.mainTaskHandle, OSA_TASK(main_task), NULL); + OSA_Start(); + + return 0; +} +#endif /* FSL_OSA_TASK_ENABLE */ + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_Init + * Description : This function is used to setup the basic services, it should + * be called first in function main. Return kStatus_OSA_Success if services + * are initialized successfully, otherwise return kStatus_OSA_Error. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +osa_status_t OSA_Init(void) +{ + LIST_Init((&s_osaState.taskList), 0); + return KOSA_StatusSuccess; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_Start + * Description : This function is used to start RTOS scheduler. + * + *END**************************************************************************/ +#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U)) +void OSA_Start(void) +{ + list_element_handle_t list_element; + task_control_block_t *tcb; + + for (;;) + { + list_element = LIST_GetHead(&s_osaState.taskList); + while (NULL != list_element) + { + tcb = (task_control_block_t *)(void *)list_element; + s_osaState.curTaskHandler = (osa_task_handle_t)tcb; + if (0U != tcb->haveToRun) + { + if (NULL != tcb->p_func) + { + tcb->p_func(tcb->param); + } + list_element = LIST_GetHead(&s_osaState.taskList); + } + else + { + list_element = LIST_GetNext(list_element); + } + } + } +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : SysTick_Handler + * Description : This ISR of the SYSTICK timer. + * + *END**************************************************************************/ +#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE) +void SysTick_Handler(void); +void SysTick_Handler(void) +{ + s_osaState.tickCounter++; +} +#endif diff --git a/component/osa/fsl_os_abstraction_bm.h b/component/osa/fsl_os_abstraction_bm.h new file mode 100644 index 0000000..84a5bd1 --- /dev/null +++ b/component/osa/fsl_os_abstraction_bm.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#if !defined(__FSL_OS_ABSTRACTION_BM_H__) +#define __FSL_OS_ABSTRACTION_BM_H__ + +/*! + * @addtogroup os_abstraction_bm + * @{ + */ + +/******************************************************************************* + * Declarations + ******************************************************************************/ +/*! @brief Bare Metal does not use timer. */ +#ifndef FSL_OSA_BM_TIMER_NONE +#define FSL_OSA_BM_TIMER_NONE 0U +#endif + +/*! @brief Bare Metal uses SYSTICK as timer. */ +#ifndef FSL_OSA_BM_TIMER_SYSTICK +#define FSL_OSA_BM_TIMER_SYSTICK 1U +#endif + +/*! @brief Configure what timer is used in Bare Metal. */ +#ifndef FSL_OSA_BM_TIMER_CONFIG +#define FSL_OSA_BM_TIMER_CONFIG FSL_OSA_BM_TIMER_NONE +#endif + +/*! @brief Type for task parameter */ +typedef void *task_param_t; + +/*! @brief Type for an event flags group, bit 32 is reserved */ +typedef uint32_t event_flags_t; + +/*! @brief Constant to pass as timeout value in order to wait indefinitely. */ +#define OSA_WAIT_FOREVER 0xFFFFFFFFU + +/*! @brief How many tasks can the bare metal support. */ +#ifndef TASK_MAX_NUM +#define TASK_MAX_NUM 7 +#endif + +/*! @brief OSA's time range in millisecond, OSA time wraps if exceeds this value. */ +#define FSL_OSA_TIME_RANGE 0xFFFFFFFFU + +/*! @brief The default interrupt handler installed in vector table. */ +#define OSA_DEFAULT_INT_HANDLER ((osa_int_handler_t)(&DefaultISR)) + +/*! @brief The default interrupt handler installed in vector table. */ +extern void DefaultISR(void); + +/*! + * @name Thread management + * @{ + */ + +/*! + * @brief To provide unified priority for upper layer, OSA layer makes conversation. + */ +#define PRIORITY_OSA_TO_RTOS(osa_prio) (osa_prio) +#define PRIORITY_RTOS_TO_OSA(rtos_prio) (rtos_prio) + +/*! @}*/ +/*! @}*/ +#endif /* __FSL_OS_ABSTRACTION_BM_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/component/osa/fsl_os_abstraction_config.h b/component/osa/fsl_os_abstraction_config.h new file mode 100644 index 0000000..85aa37b --- /dev/null +++ b/component/osa/fsl_os_abstraction_config.h @@ -0,0 +1,40 @@ +/*! + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_OS_ABSTRACTION_CONFIG_H_ +#define _FSL_OS_ABSTRACTION_CONFIG_H_ + +#ifndef gMainThreadStackSize_c +#define gMainThreadStackSize_c 1024 +#endif + +#ifndef gMainThreadPriority_c +#define gMainThreadPriority_c 7 +#endif + +#ifndef gTaskMultipleInstancesManagement_c +#define gTaskMultipleInstancesManagement_c 0 +#endif + +/*! @brief Definition to determine whether enable OSA's TASK module. */ +#ifndef OSA_USED +#ifndef FSL_OSA_TASK_ENABLE +#define FSL_OSA_TASK_ENABLE 0U +#endif +#else +#if defined(FSL_OSA_TASK_ENABLE) +#undef FSL_OSA_TASK_ENABLE +#endif +#define FSL_OSA_TASK_ENABLE 1U +#endif /* OSA_USED */ + +#ifndef FSL_OSA_MAIN_FUNC_ENABLE +#define FSL_OSA_MAIN_FUNC_ENABLE 1U +#endif + +#endif /* _FSL_OS_ABSTRACTION_CONFIG_H_ */ diff --git a/component/uart/fsl_adapter_uart.h b/component/uart/fsl_adapter_uart.h new file mode 100644 index 0000000..f97c00e --- /dev/null +++ b/component/uart/fsl_adapter_uart.h @@ -0,0 +1,558 @@ +/* + * Copyright 2018-2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __HAL_UART_ADAPTER_H__ +#define __HAL_UART_ADAPTER_H__ + +#include "fsl_common.h" +#if defined(FSL_RTOS_FREE_RTOS) +#include "FreeRTOS.h" +#endif + +/*! + * @addtogroup UART_Adapter + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable) */ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +#define UART_ADAPTER_NON_BLOCKING_MODE (1U) +#else +#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE +#define UART_ADAPTER_NON_BLOCKING_MODE (0U) +#else +#define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE +#endif +#endif + +#if defined(__GIC_PRIO_BITS) +#ifndef HAL_UART_ISR_PRIORITY +#define HAL_UART_ISR_PRIORITY (25U) +#endif +#else +#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) +#ifndef HAL_UART_ISR_PRIORITY +#define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) +#endif +#else +/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc. + * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum + * priority is 3 (2^2 - 1). So, the default value is 3. + */ +#ifndef HAL_UART_ISR_PRIORITY +#define HAL_UART_ISR_PRIORITY (3U) +#endif +#endif +#endif + +#ifndef HAL_UART_ADAPTER_LOWPOWER +#define HAL_UART_ADAPTER_LOWPOWER (0U) +#endif /* HAL_UART_ADAPTER_LOWPOWER */ + +#ifndef HAL_UART_ADAPTER_FIFO +#define HAL_UART_ADAPTER_FIFO (0U) +#endif /* HAL_UART_ADAPTER_FIFO */ + +/*! @brief Definition of uart adapter handle size. */ +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) +#define HAL_UART_HANDLE_SIZE (92U + HAL_UART_ADAPTER_LOWPOWER * 16U) +#define HAL_UART_BLOCK_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U) +#else +#define HAL_UART_HANDLE_SIZE (8U + HAL_UART_ADAPTER_LOWPOWER * 16U) +#endif + +/*! + * @brief Defines the uart handle + * + * This macro is used to define a 4 byte aligned uart handle. + * Then use "(hal_uart_handle_t)name" to get the uart handle. + * + * The macro should be global and could be optional. You could also define uart handle by yourself. + * + * This is an example, + * @code + * UART_HANDLE_DEFINE(uartHandle); + * @endcode + * + * @param name The name string of the uart handle. + */ +#define UART_HANDLE_DEFINE(name) uint32_t name[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))] + +/*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */ +#ifndef HAL_UART_TRANSFER_MODE +#define HAL_UART_TRANSFER_MODE (0U) +#endif + +/*! @brief The handle of uart adapter. */ +typedef void *hal_uart_handle_t; + +/*! @brief UART status */ +typedef enum _hal_uart_status +{ + kStatus_HAL_UartSuccess = kStatus_Success, /*!< Successfully */ + kStatus_HAL_UartTxBusy = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */ + kStatus_HAL_UartRxBusy = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */ + kStatus_HAL_UartTxIdle = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */ + kStatus_HAL_UartRxIdle = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */ + kStatus_HAL_UartBaudrateNotSupport = + MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */ + kStatus_HAL_UartProtocolError = MAKE_STATUS( + kStatusGroup_HAL_UART, + 6), /*!< Error occurs for Noise, Framing, Parity, etc. + For transactional transfer, The up layer needs to abort the transfer and then starts again */ + kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */ +} hal_uart_status_t; + +/*! @brief UART parity mode. */ +typedef enum _hal_uart_parity_mode +{ + kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */ + kHAL_UartParityEven = 0x2U, /*!< Parity even enabled */ + kHAL_UartParityOdd = 0x3U, /*!< Parity odd enabled */ +} hal_uart_parity_mode_t; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) +/*! @brief UART Block Mode. */ +typedef enum _hal_uart_block_mode +{ + kHAL_UartNonBlockMode = 0x0U, /*!< Uart NonBlock Mode */ + kHAL_UartBlockMode = 0x1U, /*!< Uart Block Mode */ +} hal_uart_block_mode_t; +#endif /* UART_ADAPTER_NON_BLOCKING_MODE */ + +/*! @brief UART stop bit count. */ +typedef enum _hal_uart_stop_bit_count +{ + kHAL_UartOneStopBit = 0U, /*!< One stop bit */ + kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */ +} hal_uart_stop_bit_count_t; + +/*! @brief UART configuration structure. */ +typedef struct _hal_uart_config +{ + uint32_t srcClock_Hz; /*!< Source clock */ + uint32_t baudRate_Bps; /*!< Baud rate */ + hal_uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ + uint8_t enableRx; /*!< Enable RX */ + uint8_t enableTx; /*!< Enable TX */ + uint8_t enableRxRTS; /*!< Enable RX RTS */ + uint8_t enableTxCTS; /*!< Enable TX CTS */ + uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the + SOC corresponding RM. + Invalid instance value will cause initialization failure. */ +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + hal_uart_block_mode_t mode; /*!< Uart block mode */ +#endif /* UART_ADAPTER_NON_BLOCKING_MODE */ +#if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u)) + uint8_t txFifoWatermark; + uint8_t rxFifoWatermark; +#endif +} hal_uart_config_t; + +/*! @brief UART transfer callback function. */ +typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam); + +/*! @brief UART transfer structure. */ +typedef struct _hal_uart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} hal_uart_transfer_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes a UART instance with the UART handle and the user configuration structure. + * + * This function configures the UART module with user-defined settings. The user can configure the configuration + * structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by + * the caller. Example below shows how to use this API to configure the UART. + * @code + * UART_HANDLE_DEFINE(g_UartHandle); + * hal_uart_config_t config; + * config.srcClock_Hz = 48000000; + * config.baudRate_Bps = 115200U; + * config.parityMode = kHAL_UartParityDisabled; + * config.stopBitCount = kHAL_UartOneStopBit; + * config.enableRx = 1; + * config.enableTx = 1; + * config.enableRxRTS = 0; + * config.enableTxCTS = 0; + * config.instance = 0; + * HAL_UartInit((hal_uart_handle_t)g_UartHandle, &config); + * @endcode + * + * @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller. + * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. + * You can define the handle in the following two ways: + * #UART_HANDLE_DEFINE(handle); + * or + * uint32_t handle[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; + * @param config Pointer to user-defined configuration structure. + * @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_HAL_UartSuccess UART initialization succeed + */ +hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *config); + +/*! + * @brief Deinitializes a UART instance. + * + * This function waits for TX complete, disables TX and RX, and disables the UART clock. + * + * @param handle UART handle pointer. + * @retval kStatus_HAL_UartSuccess UART de-initialization succeed + */ +hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle); + +/*! @}*/ + +/*! + * @name Blocking bus Operations + * @{ + */ + +/*! + * @brief Reads RX data register using a blocking method. + * + * This function polls the RX register, waits for the RX register to be full or for RX FIFO to + * have data, and reads data from the RX register. + * + * @note The function #HAL_UartReceiveBlocking and the function HAL_UartTransferReceiveNonBlocking + * cannot be used at the same time. + * And, the function HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function. + * + * @param handle UART handle pointer. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_HAL_UartError An error occurred while receiving data. + * @retval kStatus_HAL_UartParityError A parity error occurred while receiving data. + * @retval kStatus_HAL_UartSuccess Successfully received all data. + */ +hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length); + +/*! + * @brief Writes to the TX register using a blocking method. + * + * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO + * to have room and writes data to the TX buffer. + * + * @note The function #HAL_UartSendBlocking and the function HAL_UartTransferSendNonBlocking + * cannot be used at the same time. + * And, the function HAL_UartTransferAbortSend cannot be used to abort the transmission of this function. + * + * @param handle UART handle pointer. + * @param data Start address of the data to write. + * @param length Size of the data to write. + * @retval kStatus_HAL_UartSuccess Successfully sent all data. + */ +hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length); + +/*! @}*/ + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + +/*! + * @name Transactional + * @note The transactional API and the functional API cannot be used at the same time. The macro + * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the + * functional API with non-blocking mode will be used. Otherwise, transactional API will be used. + * @{ + */ + +/*! + * @brief Installs a callback and callback parameter. + * + * This function is used to install the callback and callback parameter for UART module. + * When any status of the UART changed, the driver will notify the upper layer by the installed callback + * function. And the status is also passed as status parameter when the callback is called. + * + * @param handle UART handle pointer. + * @param callback The callback function. + * @param callbackParam The parameter of the callback function. + * @retval kStatus_HAL_UartSuccess Successfully install the callback. + */ +hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle, + hal_uart_transfer_callback_t callback, + void *callbackParam); + +/*! + * @brief Receives a buffer of data using an interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be received. + * The receive request is saved by the UART driver. + * When the new data arrives, the receive request is serviced first. + * When all data is received, the UART driver notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle. + * + * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking + * cannot be used at the same time. + * + * @param handle UART handle pointer. + * @param transfer UART transfer structure, see #hal_uart_transfer_t. + * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue. + * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished. + * @retval kStatus_HAL_UartError An error occurred. + */ +hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in the ISR, the UART driver calls the callback + * function and passes the @ref kStatus_UART_TxIdle as status parameter. + * + * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking + * cannot be used at the same time. + * + * @param handle UART handle pointer. + * @param transfer UART transfer structure. See #hal_uart_transfer_t. + * @retval kStatus_HAL_UartSuccess Successfully start the data transmission. + * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet. + * @retval kStatus_HAL_UartError An error occurred. + */ +hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer); + +/*! + * @brief Gets the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param handle UART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_HAL_UartError An error occurred. + * @retval kStatus_Success Get successfully through the parameter \p count. + */ +hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count); + +/*! + * @brief Gets the number of bytes written to the UART TX register. + * + * This function gets the number of bytes written to the UART TX + * register by using the interrupt method. + * + * @param handle UART handle pointer. + * @param count Send bytes count. + * @retval kStatus_HAL_UartError An error occurred. + * @retval kStatus_Success Get successfully through the parameter \p count. + */ +hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know + * how many bytes are not received yet. + * + * @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of + * the function #HAL_UartReceiveBlocking. + * + * @param handle UART handle pointer. + * @retval kStatus_Success Get successfully abort the receiving. + */ +hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle); + +/*! + * @brief Aborts the interrupt-driven data sending. + * + * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out + * how many bytes are not sent out. + * + * @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of + * the function #HAL_UartSendBlocking. + * + * @param handle UART handle pointer. + * @retval kStatus_Success Get successfully abort the sending. + */ +hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle); + +/*! @}*/ + +#else + +/*! + * @name Functional API with non-blocking mode. + * @note The functional API and the transactional API cannot be used at the same time. The macro + * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the + * functional API with non-blocking mode will be used. Otherwise, transactional API will be used. + * @{ + */ + +/*! + * @brief Installs a callback and callback parameter. + * + * This function is used to install the callback and callback parameter for UART module. + * When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback + * function. And the status is also passed as status parameter when the callback is called. + * + * @param handle UART handle pointer. + * @param callback The callback function. + * @param callbackParam The parameter of the callback function. + * @retval kStatus_HAL_UartSuccess Successfully install the callback. + */ +hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle, + hal_uart_transfer_callback_t callback, + void *callbackParam); + +/*! + * @brief Receives a buffer of data using an interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be received. + * The receive request is saved by the UART adapter. + * When the new data arrives, the receive request is serviced first. + * When all data is received, the UART adapter notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle. + * + * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking + * cannot be used at the same time. + * + * @param handle UART handle pointer. + * @param data Start address of the data to write. + * @param length Size of the data to write. + * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue. + * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished. + * @retval kStatus_HAL_UartError An error occurred. + */ +hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in the ISR, the UART driver calls the callback + * function and passes the @ref kStatus_UART_TxIdle as status parameter. + * + * @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking + * cannot be used at the same time. + * + * @param handle UART handle pointer. + * @param data Start address of the data to write. + * @param length Size of the data to write. + * @retval kStatus_HAL_UartSuccess Successfully start the data transmission. + * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet. + * @retval kStatus_HAL_UartError An error occurred. + */ +hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length); + +/*! + * @brief Gets the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param handle UART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_HAL_UartError An error occurred. + * @retval kStatus_Success Get successfully through the parameter \p count. + */ +hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount); + +/*! + * @brief Gets the number of bytes written to the UART TX register. + * + * This function gets the number of bytes written to the UART TX + * register by using the interrupt method. + * + * @param handle UART handle pointer. + * @param count Send bytes count. + * @retval kStatus_HAL_UartError An error occurred. + * @retval kStatus_Success Get successfully through the parameter \p count. + */ +hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know + * how many bytes are not received yet. + * + * @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of + * the function #HAL_UartReceiveBlocking. + * + * @param handle UART handle pointer. + * @retval kStatus_Success Get successfully abort the receiving. + */ +hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle); + +/*! + * @brief Aborts the interrupt-driven data sending. + * + * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out + * how many bytes are not sent out. + * + * @note The function #HAL_UartAbortSend cannot be used to abort the transmission of + * the function #HAL_UartSendBlocking. + * + * @param handle UART handle pointer. + * @retval kStatus_Success Get successfully abort the sending. + */ +hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle); + +/*! @}*/ + +#endif +#endif + +/*! + * @brief Prepares to enter low power consumption. + * + * This function is used to prepare to enter low power consumption. + * + * @param handle UART handle pointer. + * @retval kStatus_HAL_UartSuccess Successful operation. + * @retval kStatus_HAL_UartError An error occurred. + */ +hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle); + +/*! + * @brief Restores from low power consumption. + * + * This function is used to restore from low power consumption. + * + * @param handle UART handle pointer. + * @retval kStatus_HAL_UartSuccess Successful operation. + * @retval kStatus_HAL_UartError An error occurred. + */ +hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle); + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) +/*! + * @brief UART IRQ handle function. + * + * This function handles the UART transmit and receive IRQ request. + * + * @param handle UART handle pointer. + */ +void HAL_UartIsrFunction(hal_uart_handle_t handle); +#endif + +#if defined(__cplusplus) +} +#endif +/*! @}*/ +#endif /* __HAL_UART_ADAPTER_H__ */ diff --git a/component/uart/fsl_adapter_usart.c b/component/uart/fsl_adapter_usart.c new file mode 100644 index 0000000..8e1354e --- /dev/null +++ b/component/uart/fsl_adapter_usart.c @@ -0,0 +1,643 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_usart.h" +#include "fsl_flexcomm.h" + +#include "fsl_adapter_uart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#ifndef NDEBUG +#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U)) +#undef assert +#define assert(n) +#endif +#endif + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) +/*! @brief uart RX state structure. */ +typedef struct _hal_uart_receive_state +{ + volatile uint8_t *buffer; + volatile uint32_t bufferLength; + volatile uint32_t bufferSofar; +} hal_uart_receive_state_t; + +/*! @brief uart TX state structure. */ +typedef struct _hal_uart_send_state +{ + volatile uint8_t *buffer; + volatile uint32_t bufferLength; + volatile uint32_t bufferSofar; +} hal_uart_send_state_t; +#endif +/*! @brief uart state structure. */ +typedef struct _hal_uart_state +{ +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + hal_uart_transfer_callback_t callback; + void *callbackParam; +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + usart_handle_t hardwareHandle; +#endif + hal_uart_receive_state_t rx; + hal_uart_send_state_t tx; +#endif + uint8_t instance; +} hal_uart_state_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +static USART_Type *const s_UsartAdapterBase[] = USART_BASE_PTRS; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) +/* Array of USART IRQ number. */ +static const IRQn_Type s_UsartIRQ[] = USART_IRQS; +#endif + +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) +static hal_uart_status_t HAL_UartGetStatus(status_t status) +{ + hal_uart_status_t uartStatus = kStatus_HAL_UartError; + switch (status) + { + case kStatus_Success: + uartStatus = kStatus_HAL_UartSuccess; + break; + case kStatus_USART_TxBusy: + uartStatus = kStatus_HAL_UartTxBusy; + break; + case kStatus_USART_RxBusy: + uartStatus = kStatus_HAL_UartRxBusy; + break; + case kStatus_USART_TxIdle: + uartStatus = kStatus_HAL_UartTxIdle; + break; + case kStatus_USART_RxIdle: + uartStatus = kStatus_HAL_UartRxIdle; + break; + case kStatus_USART_BaudrateNotSupport: + uartStatus = kStatus_HAL_UartBaudrateNotSupport; + break; + case kStatus_USART_NoiseError: + case kStatus_USART_FramingError: + case kStatus_USART_ParityError: + uartStatus = kStatus_HAL_UartProtocolError; + break; + default: + /* This comments for MISRA C-2012 Rule 16.4 */ + break; + } + return uartStatus; +} +#else +static hal_uart_status_t HAL_UartGetStatus(status_t status) +{ + if (kStatus_Success == status) + { + return kStatus_HAL_UartSuccess; + } + else + { + return kStatus_HAL_UartError; + } +} +#endif + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) +static void HAL_UartCallback(USART_Type *base, usart_handle_t *handle, status_t status, void *callbackParam) +{ + hal_uart_state_t *uartHandle; + hal_uart_status_t uartStatus = HAL_UartGetStatus(status); + assert(callbackParam); + + uartHandle = (hal_uart_state_t *)callbackParam; + + if (kStatus_HAL_UartProtocolError == uartStatus) + { + if (0U != uartHandle->hardwareHandle.rxDataSize) + { + uartStatus = kStatus_HAL_UartError; + } + } + + if (NULL != uartHandle->callback) + { + uartHandle->callback(uartHandle, uartStatus, uartHandle->callbackParam); + } +} + +#else +static void HAL_UartInterruptHandle(USART_Type *base, void *handle) +{ + hal_uart_state_t *uartHandle = (hal_uart_state_t *)handle; + uint32_t status; + uint8_t instance; + + if (NULL == uartHandle) + { + return; + } + instance = uartHandle->instance; + + status = USART_GetStatusFlags(s_UsartAdapterBase[instance]); + + /* Receive data register full */ + if ((0U != (USART_FIFOSTAT_RXNOTEMPTY_MASK & status)) && + (0U != (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_RXLVL_MASK))) + { + if (NULL != uartHandle->rx.buffer) + { + uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = USART_ReadByte(s_UsartAdapterBase[instance]); + if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength) + { + USART_DisableInterrupts(s_UsartAdapterBase[instance], + USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK); + uartHandle->rx.buffer = NULL; + if (NULL != uartHandle->callback) + { + uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam); + } + } + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((0U != (USART_FIFOSTAT_TXNOTFULL_MASK & status)) && + (0U != (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_TXLVL_MASK))) + { + if (NULL != uartHandle->tx.buffer) + { + USART_WriteByte(s_UsartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]); + if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength) + { + USART_DisableInterrupts(s_UsartAdapterBase[instance], USART_FIFOINTENCLR_TXLVL_MASK); + uartHandle->tx.buffer = NULL; + if (NULL != uartHandle->callback) + { + uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam); + } + } + } + } + +#if 1 + USART_ClearStatusFlags(s_UsartAdapterBase[instance], status); +#endif +} + +static void HAL_UartInterruptHandle_Wapper(void *base, void *handle) +{ + HAL_UartInterruptHandle((USART_Type *)base, handle); +} +#endif + +#endif + +hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *config) +{ + hal_uart_state_t *uartHandle; + usart_config_t usartConfig; + status_t status; + assert(handle); + assert(config); + assert(config->instance < (sizeof(s_UsartAdapterBase) / sizeof(USART_Type *))); + assert(s_UsartAdapterBase[config->instance]); + assert(HAL_UART_HANDLE_SIZE >= sizeof(hal_uart_state_t)); + + USART_GetDefaultConfig(&usartConfig); + usartConfig.baudRate_Bps = config->baudRate_Bps; + + if (kHAL_UartParityEven == config->parityMode) + { + usartConfig.parityMode = kUSART_ParityEven; + } + else if (kHAL_UartParityOdd == config->parityMode) + { + usartConfig.parityMode = kUSART_ParityOdd; + } + else + { + usartConfig.parityMode = kUSART_ParityDisabled; + } + + if (kHAL_UartTwoStopBit == config->stopBitCount) + { + usartConfig.stopBitCount = kUSART_TwoStopBit; + } + else + { + usartConfig.stopBitCount = kUSART_OneStopBit; + } + usartConfig.enableRx = (bool)config->enableRx; + usartConfig.enableTx = (bool)config->enableTx; + usartConfig.txWatermark = kUSART_TxFifo0; + usartConfig.rxWatermark = kUSART_RxFifo1; + + status = USART_Init(s_UsartAdapterBase[config->instance], &usartConfig, config->srcClock_Hz); + + if (kStatus_Success != status) + { + return HAL_UartGetStatus(status); + } + + uartHandle = (hal_uart_state_t *)handle; + uartHandle->instance = config->instance; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + USART_TransferCreateHandle(s_UsartAdapterBase[config->instance], &uartHandle->hardwareHandle, + (usart_transfer_callback_t)HAL_UartCallback, handle); +#else + /* Enable interrupt in NVIC. */ + FLEXCOMM_SetIRQHandler(s_UsartAdapterBase[config->instance], HAL_UartInterruptHandle_Wapper, handle); + NVIC_SetPriority((IRQn_Type)s_UsartIRQ[config->instance], HAL_UART_ISR_PRIORITY); + (void)EnableIRQ(s_UsartIRQ[config->instance]); +#endif + +#endif + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + + USART_Deinit(s_UsartAdapterBase[uartHandle->instance]); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(data); + assert(length); + + uartHandle = (hal_uart_state_t *)handle; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + if (NULL != uartHandle->rx.buffer) + { + return kStatus_HAL_UartRxBusy; + } +#endif + + status = USART_ReadBlocking(s_UsartAdapterBase[uartHandle->instance], data, length); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(data); + assert(length); + + uartHandle = (hal_uart_state_t *)handle; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + if (NULL != uartHandle->tx.buffer) + { + return kStatus_HAL_UartTxBusy; + } +#endif + + (void)USART_WriteBlocking(s_UsartAdapterBase[uartHandle->instance], data, length); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle) +{ + assert(handle); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle) +{ + assert(handle); + + return kStatus_HAL_UartSuccess; +} + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + +hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle, + hal_uart_transfer_callback_t callback, + void *callbackParam) +{ + hal_uart_state_t *uartHandle; + + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + uartHandle->callbackParam = callbackParam; + uartHandle->callback = callback; + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(transfer); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = USART_TransferReceiveNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, + (usart_transfer_t *)transfer, NULL); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(transfer); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = USART_TransferSendNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, + (usart_transfer_t *)transfer); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(count); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = + USART_TransferGetReceiveCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(count); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = USART_TransferGetSendCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + USART_TransferAbortReceive(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + USART_TransferAbortSend(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); + + return kStatus_HAL_UartSuccess; +} + +#else + +/* None transactional API with non-blocking mode. */ +hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle, + hal_uart_transfer_callback_t callback, + void *callbackParam) +{ + hal_uart_state_t *uartHandle; + + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + uartHandle->callbackParam = callbackParam; + uartHandle->callback = callback; + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(data); + assert(length); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->rx.buffer) + { + return kStatus_HAL_UartRxBusy; + } + + uartHandle->rx.bufferLength = length; + uartHandle->rx.bufferSofar = 0; + uartHandle->rx.buffer = data; + USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_RXLVL_MASK); + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(data); + assert(length); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->tx.buffer) + { + return kStatus_HAL_UartTxBusy; + } + uartHandle->tx.bufferLength = length; + uartHandle->tx.bufferSofar = 0; + uartHandle->tx.buffer = (volatile uint8_t *)data; + USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_TXLVL_MASK); + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(reCount); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->rx.buffer) + { + *reCount = uartHandle->rx.bufferSofar; + return kStatus_HAL_UartSuccess; + } + return kStatus_HAL_UartError; +} + +hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(seCount); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->tx.buffer) + { + *seCount = uartHandle->tx.bufferSofar; + return kStatus_HAL_UartSuccess; + } + return kStatus_HAL_UartError; +} + +hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->rx.buffer) + { + USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance], + USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK); + uartHandle->rx.buffer = NULL; + } + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->tx.buffer) + { + USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENCLR_TXLVL_MASK); + uartHandle->tx.buffer = NULL; + } + + return kStatus_HAL_UartSuccess; +} + +#endif + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + +void HAL_UartIsrFunction(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + +#if 0 + DisableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif + USART_TransferHandleIRQ(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); +#if 0 + NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY); + EnableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif +} + +#else + +void HAL_UartIsrFunction(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + +#if 0 + DisableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif + HAL_UartInterruptHandle(s_UsartAdapterBase[uartHandle->instance], (void *)uartHandle); +#if 0 + NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY); + EnableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif +} + +#endif + +#endif diff --git a/device/LPC54114_cm4.h b/device/LPC54114_cm4.h new file mode 100644 index 0000000..49df4b1 --- /dev/null +++ b/device/LPC54114_cm4.h @@ -0,0 +1,12100 @@ +/* +** ################################################################### +** Processors: LPC54114J256BD64_cm4 +** LPC54114J256UK49_cm4 +** +** Compilers: GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** Keil ARM C/C++ Compiler +** MCUXpresso Compiler +** +** Reference manual: LPC5411x User manual Rev. 1.1 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b200304 +** +** Abstract: +** CMSIS Peripheral Access Layer for LPC54114_cm4 +** +** Copyright 1997-2016 Freescale Semiconductor, Inc. +** Copyright 2016-2020 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54114_cm4.h + * @version 1.0 + * @date 2016-04-29 + * @brief CMSIS Peripheral Access Layer for LPC54114_cm4 + * + * CMSIS Peripheral Access Layer for LPC54114_cm4 + */ + +#ifndef _LPC54114_CM4_H_ +#define _LPC54114_CM4_H_ /**< Symbol preventing repeated inclusion */ + +/** Memory map major version (memory maps with equal major version number are + * compatible) */ +#define MCU_MEM_MAP_VERSION 0x0100U +/** Memory map minor version */ +#define MCU_MEM_MAP_VERSION_MINOR 0x0000U + + +/* ---------------------------------------------------------------------------- + -- Interrupt vector numbers + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Interrupt_vector_numbers Interrupt vector numbers + * @{ + */ + +/** Interrupt Number Definitions */ +#define NUMBER_OF_INT_VECTORS 56 /**< Number of interrupts in the Vector table */ + +typedef enum IRQn { + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M4 SV Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /**< Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M4 System Tick Interrupt */ + + /* Device specific interrupts */ + WDT_BOD_IRQn = 0, /**< Windowed watchdog timer, Brownout detect */ + DMA0_IRQn = 1, /**< DMA controller */ + GINT0_IRQn = 2, /**< GPIO group 0 */ + GINT1_IRQn = 3, /**< GPIO group 1 */ + PIN_INT0_IRQn = 4, /**< Pin interrupt 0 or pattern match engine slice 0 */ + PIN_INT1_IRQn = 5, /**< Pin interrupt 1or pattern match engine slice 1 */ + PIN_INT2_IRQn = 6, /**< Pin interrupt 2 or pattern match engine slice 2 */ + PIN_INT3_IRQn = 7, /**< Pin interrupt 3 or pattern match engine slice 3 */ + UTICK0_IRQn = 8, /**< Micro-tick Timer */ + MRT0_IRQn = 9, /**< Multi-rate timer */ + CTIMER0_IRQn = 10, /**< Standard counter/timer CTIMER0 */ + CTIMER1_IRQn = 11, /**< Standard counter/timer CTIMER1 */ + SCT0_IRQn = 12, /**< SCTimer/PWM */ + CTIMER3_IRQn = 13, /**< Standard counter/timer CTIMER3 */ + FLEXCOMM0_IRQn = 14, /**< Flexcomm Interface 0 (USART, SPI, I2C) */ + FLEXCOMM1_IRQn = 15, /**< Flexcomm Interface 1 (USART, SPI, I2C) */ + FLEXCOMM2_IRQn = 16, /**< Flexcomm Interface 2 (USART, SPI, I2C) */ + FLEXCOMM3_IRQn = 17, /**< Flexcomm Interface 3 (USART, SPI, I2C) */ + FLEXCOMM4_IRQn = 18, /**< Flexcomm Interface 4 (USART, SPI, I2C) */ + FLEXCOMM5_IRQn = 19, /**< Flexcomm Interface 5 (USART, SPI, I2C) */ + FLEXCOMM6_IRQn = 20, /**< Flexcomm Interface 6 (USART, SPI, I2C, I2S) */ + FLEXCOMM7_IRQn = 21, /**< Flexcomm Interface 7 (USART, SPI, I2C, I2S) */ + ADC0_SEQA_IRQn = 22, /**< ADC0 sequence A completion. */ + ADC0_SEQB_IRQn = 23, /**< ADC0 sequence B completion. */ + ADC0_THCMP_IRQn = 24, /**< ADC0 threshold compare and error. */ + DMIC0_IRQn = 25, /**< Digital microphone and DMIC subsystem */ + HWVAD0_IRQn = 26, /**< Hardware Voice Activity Detector */ + USB0_NEEDCLK_IRQn = 27, /**< USB Activity Wake-up Interrupt */ + USB0_IRQn = 28, /**< USB device */ + RTC_IRQn = 29, /**< RTC alarm and wake-up interrupts */ + IOH_IRQn = 30, /**< IOH */ + MAILBOX_IRQn = 31, /**< Mailbox interrupt (present on selected devices) */ + PIN_INT4_IRQn = 32, /**< Pin interrupt 4 or pattern match engine slice 4 int */ + PIN_INT5_IRQn = 33, /**< Pin interrupt 5 or pattern match engine slice 5 int */ + PIN_INT6_IRQn = 34, /**< Pin interrupt 6 or pattern match engine slice 6 int */ + PIN_INT7_IRQn = 35, /**< Pin interrupt 7 or pattern match engine slice 7 int */ + CTIMER2_IRQn = 36, /**< Standard counter/timer CTIMER2 */ + CTIMER4_IRQn = 37, /**< Standard counter/timer CTIMER4 */ + Reserved54_IRQn = 38, /**< Reserved interrupt */ + SPIFI0_IRQn = 39 /**< SPI flash interface */ +} IRQn_Type; + +/*! + * @} + */ /* end of group Interrupt_vector_numbers */ + + +/* ---------------------------------------------------------------------------- + -- Cortex M4 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M4 Core Configuration + * @{ + */ + +#define __MPU_PRESENT 1 /**< Defines if an MPU is present or not */ +#define __NVIC_PRIO_BITS 3 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ +#define __FPU_PRESENT 1 /**< Defines if an FPU is present or not */ + +#include "core_cm4.h" /* Core Peripheral Access Layer */ +#include "system_LPC54114_cm4.h" /* Device specific configuration file */ + +/*! + * @} + */ /* end of group Cortex_Core_Configuration */ + + +/* ---------------------------------------------------------------------------- + -- Device Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Peripheral_access_layer Device Peripheral Access Layer + * @{ + */ + + +/* +** Start of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #else + #pragma push + #pragma anon_unions + #endif +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=extended +#else + #error Not supported compiler type +#endif + +/* ---------------------------------------------------------------------------- + -- ADC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer + * @{ + */ + +/** ADC - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls., offset: 0x0 */ + __IO uint32_t INSEL; /**< Input Select. Allows selection of the temperature sensor as an alternate input to ADC channel 0., offset: 0x4 */ + __IO uint32_t SEQ_CTRL[2]; /**< ADC Conversion Sequence-n control register: Controls triggering and channel selection for conversion sequence-n. Also specifies interrupt mode for sequence-n., array offset: 0x8, array step: 0x4 */ + __I uint32_t SEQ_GDAT[2]; /**< ADC Sequence-n Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-n., array offset: 0x10, array step: 0x4 */ + uint8_t RESERVED_0[8]; + __I uint32_t DAT[12]; /**< ADC Channel 0 Data register. This register contains the result of the most recent conversion completed on channel 0., array offset: 0x20, array step: 0x4 */ + __IO uint32_t THR0_LOW; /**< ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x50 */ + __IO uint32_t THR1_LOW; /**< ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x54 */ + __IO uint32_t THR0_HIGH; /**< ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x58 */ + __IO uint32_t THR1_HIGH; /**< ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x5C */ + __IO uint32_t CHAN_THRSEL; /**< ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel, offset: 0x60 */ + __IO uint32_t INTEN; /**< ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated., offset: 0x64 */ + __IO uint32_t FLAGS; /**< ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers)., offset: 0x68 */ + __IO uint32_t STARTUP; /**< ADC Startup register., offset: 0x6C */ + __IO uint32_t CALIB; /**< ADC Calibration register., offset: 0x70 */ +} ADC_Type; + +/* ---------------------------------------------------------------------------- + -- ADC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Register_Masks ADC Register Masks + * @{ + */ + +/*! @name CTRL - ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls. */ +/*! @{ */ +#define ADC_CTRL_CLKDIV_MASK (0xFFU) +#define ADC_CTRL_CLKDIV_SHIFT (0U) +/*! CLKDIV - In synchronous mode only, the system clock is divided by this value plus one to produce + * the clock for the ADC converter, which should be less than or equal to 72 MHz. Typically, + * software should program the smallest value in this field that yields this maximum clock rate or + * slightly less, but in certain cases (such as a high-impedance analog source) a slower clock may + * be desirable. This field is ignored in the asynchronous operating mode. + */ +#define ADC_CTRL_CLKDIV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_CLKDIV_SHIFT)) & ADC_CTRL_CLKDIV_MASK) +#define ADC_CTRL_ASYNMODE_MASK (0x100U) +#define ADC_CTRL_ASYNMODE_SHIFT (8U) +/*! ASYNMODE - Select clock mode. + * 0b0..Synchronous mode. The ADC clock is derived from the system clock based on the divide value selected in + * the CLKDIV field. The ADC clock will be started in a controlled fashion in response to a trigger to + * eliminate any uncertainty in the launching of an ADC conversion in response to any synchronous (on-chip) trigger. + * In Synchronous mode with the SYNCBYPASS bit (in a sequence control register) set, sampling of the ADC + * input and start of conversion will initiate 2 system clocks after the leading edge of a (synchronous) trigger + * pulse. + * 0b1..Asynchronous mode. The ADC clock is based on the output of the ADC clock divider ADCCLKSEL in the SYSCON block. + */ +#define ADC_CTRL_ASYNMODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_ASYNMODE_SHIFT)) & ADC_CTRL_ASYNMODE_MASK) +#define ADC_CTRL_RESOL_MASK (0x600U) +#define ADC_CTRL_RESOL_SHIFT (9U) +/*! RESOL - The number of bits of ADC resolution. Accuracy can be reduced to achieve higher + * conversion rates. A single conversion (including one conversion in a burst or sequence) requires the + * selected number of bits of resolution plus 3 ADC clocks. This field must only be altered when + * the ADC is fully idle. Changing it during any kind of ADC operation may have unpredictable + * results. ADC clock frequencies for various resolutions must not exceed: - 5x the system clock rate + * for 12-bit resolution - 4.3x the system clock rate for 10-bit resolution - 3.6x the system + * clock for 8-bit resolution - 3x the bus clock rate for 6-bit resolution + * 0b00..6-bit resolution. An ADC conversion requires 9 ADC clocks, plus any clocks specified by the TSAMP field. + * 0b01..8-bit resolution. An ADC conversion requires 11 ADC clocks, plus any clocks specified by the TSAMP field. + * 0b10..10-bit resolution. An ADC conversion requires 13 ADC clocks, plus any clocks specified by the TSAMP field. + * 0b11..12-bit resolution. An ADC conversion requires 15 ADC clocks, plus any clocks specified by the TSAMP field. + */ +#define ADC_CTRL_RESOL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_SHIFT)) & ADC_CTRL_RESOL_MASK) +#define ADC_CTRL_BYPASSCAL_MASK (0x800U) +#define ADC_CTRL_BYPASSCAL_SHIFT (11U) +/*! BYPASSCAL - Bypass Calibration. This bit may be set to avoid the need to calibrate if offset + * error is not a concern in the application. + * 0b0..Calibrate. The stored calibration value will be applied to the ADC during conversions to compensated for + * offset error. A calibration cycle must be performed each time the chip is powered-up. Re-calibration may + * be warranted periodically - especially if operating conditions have changed. + * 0b1..Bypass calibration. Calibration is not utilized. Less time is required when enabling the ADC - + * particularly following chip power-up. Attempts to launch a calibration cycle are blocked when this bit is set. + */ +#define ADC_CTRL_BYPASSCAL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_BYPASSCAL_SHIFT)) & ADC_CTRL_BYPASSCAL_MASK) +#define ADC_CTRL_TSAMP_MASK (0x7000U) +#define ADC_CTRL_TSAMP_SHIFT (12U) +/*! TSAMP - Sample Time. The default sampling period (TSAMP = '000') at the start of each conversion + * is 2.5 ADC clock periods. Depending on a variety of factors, including operating conditions + * and the output impedance of the analog source, longer sampling times may be required. See + * Section 28.7.10. The TSAMP field specifies the number of additional ADC clock cycles, from zero to + * seven, by which the sample period will be extended. The total conversion time will increase by + * the same number of clocks. 000 - The sample period will be the default 2.5 ADC clocks. A + * complete conversion with 12-bits of accuracy will require 15 clocks. 001- The sample period will + * be extended by one ADC clock to a total of 3.5 clock periods. A complete 12-bit conversion will + * require 16 clocks. 010 - The sample period will be extended by two clocks to 4.5 ADC clock + * cycles. A complete 12-bit conversion will require 17 ADC clocks. 111 - The sample period will be + * extended by seven clocks to 9.5 ADC clock cycles. A complete 12-bit conversion will require + * 22 ADC clocks. + */ +#define ADC_CTRL_TSAMP(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_TSAMP_SHIFT)) & ADC_CTRL_TSAMP_MASK) +/*! @} */ + +/*! @name INSEL - Input Select. Allows selection of the temperature sensor as an alternate input to ADC channel 0. */ +/*! @{ */ +#define ADC_INSEL_SEL_MASK (0x3U) +#define ADC_INSEL_SEL_SHIFT (0U) +/*! SEL - Selects the input source for channel 0. All other values are reserved. + * 0b00..ADC0_IN0 function. + * 0b11..Internal temperature sensor. + */ +#define ADC_INSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_INSEL_SEL_SHIFT)) & ADC_INSEL_SEL_MASK) +/*! @} */ + +/*! @name SEQ_CTRL - ADC Conversion Sequence-n control register: Controls triggering and channel selection for conversion sequence-n. Also specifies interrupt mode for sequence-n. */ +/*! @{ */ +#define ADC_SEQ_CTRL_CHANNELS_MASK (0xFFFU) +#define ADC_SEQ_CTRL_CHANNELS_SHIFT (0U) +/*! CHANNELS - Selects which one or more of the ADC channels will be sampled and converted when this + * sequence is launched. A 1 in any bit of this field will cause the corresponding channel to be + * included in the conversion sequence, where bit 0 corresponds to channel 0, bit 1 to channel 1 + * and so forth. When this conversion sequence is triggered, either by a hardware trigger or via + * software command, ADC conversions will be performed on each enabled channel, in sequence, + * beginning with the lowest-ordered channel. This field can ONLY be changed while SEQA_ENA (bit 31) + * is LOW. It is allowed to change this field and set bit 31 in the same write. + */ +#define ADC_SEQ_CTRL_CHANNELS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_CHANNELS_SHIFT)) & ADC_SEQ_CTRL_CHANNELS_MASK) +#define ADC_SEQ_CTRL_TRIGGER_MASK (0x3F000U) +#define ADC_SEQ_CTRL_TRIGGER_SHIFT (12U) +/*! TRIGGER - Selects which of the available hardware trigger sources will cause this conversion + * sequence to be initiated. Program the trigger input number in this field. See Table 476. In order + * to avoid generating a spurious trigger, it is recommended writing to this field only when + * SEQA_ENA (bit 31) is low. It is safe to change this field and set bit 31 in the same write. + */ +#define ADC_SEQ_CTRL_TRIGGER(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGGER_SHIFT)) & ADC_SEQ_CTRL_TRIGGER_MASK) +#define ADC_SEQ_CTRL_TRIGPOL_MASK (0x40000U) +#define ADC_SEQ_CTRL_TRIGPOL_SHIFT (18U) +/*! TRIGPOL - Select the polarity of the selected input trigger for this conversion sequence. In + * order to avoid generating a spurious trigger, it is recommended writing to this field only when + * SEQA_ENA (bit 31) is low. It is safe to change this field and set bit 31 in the same write. + * 0b0..Negative edge. A negative edge launches the conversion sequence on the selected trigger input. + * 0b1..Positive edge. A positive edge launches the conversion sequence on the selected trigger input. + */ +#define ADC_SEQ_CTRL_TRIGPOL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGPOL_SHIFT)) & ADC_SEQ_CTRL_TRIGPOL_MASK) +#define ADC_SEQ_CTRL_SYNCBYPASS_MASK (0x80000U) +#define ADC_SEQ_CTRL_SYNCBYPASS_SHIFT (19U) +/*! SYNCBYPASS - Setting this bit allows the hardware trigger input to bypass synchronization + * flip-flop stages and therefore shorten the time between the trigger input signal and the start of a + * conversion. There are slightly different criteria for whether or not this bit can be set + * depending on the clock operating mode: Synchronous mode (the ASYNMODE in the CTRL register = 0): + * Synchronization may be bypassed (this bit may be set) if the selected trigger source is already + * synchronous with the main system clock (eg. coming from an on-chip, system-clock-based timer). + * Whether this bit is set or not, a trigger pulse must be maintained for at least one system + * clock period. Asynchronous mode (the ASYNMODE in the CTRL register = 1): Synchronization may be + * bypassed (this bit may be set) if it is certain that the duration of a trigger input pulse + * will be at least one cycle of the ADC clock (regardless of whether the trigger comes from and + * on-chip or off-chip source). If this bit is NOT set, the trigger pulse must at least be + * maintained for one system clock period. + * 0b0..Enable trigger synchronization. The hardware trigger bypass is not enabled. + * 0b1..Bypass trigger synchronization. The hardware trigger bypass is enabled. + */ +#define ADC_SEQ_CTRL_SYNCBYPASS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SYNCBYPASS_SHIFT)) & ADC_SEQ_CTRL_SYNCBYPASS_MASK) +#define ADC_SEQ_CTRL_START_MASK (0x4000000U) +#define ADC_SEQ_CTRL_START_SHIFT (26U) +/*! START - Writing a 1 to this field will launch one pass through this conversion sequence. The + * behavior will be identical to a sequence triggered by a hardware trigger. Do not write 1 to this + * bit if the BURST bit is set. This bit is only set to a 1 momentarily when written to launch a + * conversion sequence. It will consequently always read back as a zero. + */ +#define ADC_SEQ_CTRL_START(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_SHIFT)) & ADC_SEQ_CTRL_START_MASK) +#define ADC_SEQ_CTRL_BURST_MASK (0x8000000U) +#define ADC_SEQ_CTRL_BURST_SHIFT (27U) +/*! BURST - Writing a 1 to this bit will cause this conversion sequence to be continuously cycled + * through. Other sequence A triggers will be ignored while this bit is set. Repeated conversions + * can be halted by clearing this bit. The sequence currently in progress will be completed before + * conversions are terminated. Note that a new sequence could begin just before BURST is cleared. + */ +#define ADC_SEQ_CTRL_BURST(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_BURST_SHIFT)) & ADC_SEQ_CTRL_BURST_MASK) +#define ADC_SEQ_CTRL_SINGLESTEP_MASK (0x10000000U) +#define ADC_SEQ_CTRL_SINGLESTEP_SHIFT (28U) +/*! SINGLESTEP - When this bit is set, a hardware trigger or a write to the START bit will launch a + * single conversion on the next channel in the sequence instead of the default response of + * launching an entire sequence of conversions. Once all of the channels comprising a sequence have + * been converted, a subsequent trigger will repeat the sequence beginning with the first enabled + * channel. Interrupt generation will still occur either after each individual conversion or at + * the end of the entire sequence, depending on the state of the MODE bit. + */ +#define ADC_SEQ_CTRL_SINGLESTEP(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SINGLESTEP_SHIFT)) & ADC_SEQ_CTRL_SINGLESTEP_MASK) +#define ADC_SEQ_CTRL_LOWPRIO_MASK (0x20000000U) +#define ADC_SEQ_CTRL_LOWPRIO_SHIFT (29U) +/*! LOWPRIO - Set priority for sequence A. + * 0b0..Low priority. Any B trigger which occurs while an A conversion sequence is active will be ignored and lost. + * 0b1..High priority. Setting this bit to a 1 will permit any enabled B sequence trigger (including a B sequence + * software start) to immediately interrupt sequence A and launch a B sequence in it's place. The conversion + * currently in progress will be terminated. The A sequence that was interrupted will automatically resume + * after the B sequence completes. The channel whose conversion was terminated will be re-sampled and the + * conversion sequence will resume from that point. + */ +#define ADC_SEQ_CTRL_LOWPRIO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_LOWPRIO_SHIFT)) & ADC_SEQ_CTRL_LOWPRIO_MASK) +#define ADC_SEQ_CTRL_MODE_MASK (0x40000000U) +#define ADC_SEQ_CTRL_MODE_SHIFT (30U) +/*! MODE - Indicates whether the primary method for retrieving conversion results for this sequence + * will be accomplished via reading the global data register (SEQA_GDAT) at the end of each + * conversion, or the individual channel result registers at the end of the entire sequence. Impacts + * when conversion-complete interrupt/DMA trigger for sequence-A will be generated and which + * overrun conditions contribute to an overrun interrupt as described below. + * 0b0..End of conversion. The sequence A interrupt/DMA trigger will be set at the end of each individual ADC + * conversion performed under sequence A. This flag will mirror the DATAVALID bit in the SEQA_GDAT register. The + * OVERRUN bit in the SEQA_GDAT register will contribute to generation of an overrun interrupt/DMA trigger + * if enabled. + * 0b1..End of sequence. The sequence A interrupt/DMA trigger will be set when the entire set of sequence-A + * conversions completes. This flag will need to be explicitly cleared by software or by the DMA-clear signal in + * this mode. The OVERRUN bit in the SEQA_GDAT register will NOT contribute to generation of an overrun + * interrupt/DMA trigger since it is assumed this register may not be utilized in this mode. + */ +#define ADC_SEQ_CTRL_MODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_MODE_SHIFT)) & ADC_SEQ_CTRL_MODE_MASK) +#define ADC_SEQ_CTRL_SEQ_ENA_MASK (0x80000000U) +#define ADC_SEQ_CTRL_SEQ_ENA_SHIFT (31U) +/*! SEQ_ENA - Sequence Enable. In order to avoid spuriously triggering the sequence, care should be + * taken to only set the SEQn_ENA bit when the selected trigger input is in its INACTIVE state + * (as defined by the TRIGPOL bit). If this condition is not met, the sequence will be triggered + * immediately upon being enabled. In order to avoid spuriously triggering the sequence, care + * should be taken to only set the SEQn_ENA bit when the selected trigger input is in its INACTIVE + * state (as defined by the TRIGPOL bit). If this condition is not met, the sequence will be + * triggered immediately upon being enabled. + * 0b0..Disabled. Sequence n is disabled. Sequence n triggers are ignored. If this bit is cleared while sequence + * n is in progress, the sequence will be halted at the end of the current conversion. After the sequence is + * re-enabled, a new trigger will be required to restart the sequence beginning with the next enabled channel. + * 0b1..Enabled. Sequence n is enabled. + */ +#define ADC_SEQ_CTRL_SEQ_ENA(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SEQ_ENA_SHIFT)) & ADC_SEQ_CTRL_SEQ_ENA_MASK) +/*! @} */ + +/* The count of ADC_SEQ_CTRL */ +#define ADC_SEQ_CTRL_COUNT (2U) + +/*! @name SEQ_GDAT - ADC Sequence-n Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-n. */ +/*! @{ */ +#define ADC_SEQ_GDAT_RESULT_MASK (0xFFF0U) +#define ADC_SEQ_GDAT_RESULT_SHIFT (4U) +/*! RESULT - This field contains the 12-bit ADC conversion result from the most recent conversion + * performed under conversion sequence associated with this register. The result is a binary + * fraction representing the voltage on the currently-selected input channel as it falls within the + * range of VREFP to VREFN. Zero in the field indicates that the voltage on the input pin was less + * than, equal to, or close to that on VREFN, while 0xFFF indicates that the voltage on the input + * was close to, equal to, or greater than that on VREFP. DATAVALID = 1 indicates that this + * result has not yet been read. + */ +#define ADC_SEQ_GDAT_RESULT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_RESULT_SHIFT)) & ADC_SEQ_GDAT_RESULT_MASK) +#define ADC_SEQ_GDAT_THCMPRANGE_MASK (0x30000U) +#define ADC_SEQ_GDAT_THCMPRANGE_SHIFT (16U) +/*! THCMPRANGE - Indicates whether the result of the last conversion performed was above, below or + * within the range established by the designated threshold comparison registers (THRn_LOW and + * THRn_HIGH). + */ +#define ADC_SEQ_GDAT_THCMPRANGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPRANGE_SHIFT)) & ADC_SEQ_GDAT_THCMPRANGE_MASK) +#define ADC_SEQ_GDAT_THCMPCROSS_MASK (0xC0000U) +#define ADC_SEQ_GDAT_THCMPCROSS_SHIFT (18U) +/*! THCMPCROSS - Indicates whether the result of the last conversion performed represented a + * crossing of the threshold level established by the designated LOW threshold comparison register + * (THRn_LOW) and, if so, in what direction the crossing occurred. + */ +#define ADC_SEQ_GDAT_THCMPCROSS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPCROSS_SHIFT)) & ADC_SEQ_GDAT_THCMPCROSS_MASK) +#define ADC_SEQ_GDAT_CHN_MASK (0x3C000000U) +#define ADC_SEQ_GDAT_CHN_SHIFT (26U) +/*! CHN - These bits contain the channel from which the RESULT bits were converted (e.g. 0000 + * identifies channel 0, 0001 channel 1, etc.). + */ +#define ADC_SEQ_GDAT_CHN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_CHN_SHIFT)) & ADC_SEQ_GDAT_CHN_MASK) +#define ADC_SEQ_GDAT_OVERRUN_MASK (0x40000000U) +#define ADC_SEQ_GDAT_OVERRUN_SHIFT (30U) +/*! OVERRUN - This bit is set if a new conversion result is loaded into the RESULT field before a + * previous result has been read - i.e. while the DATAVALID bit is set. This bit is cleared, along + * with the DATAVALID bit, whenever this register is read. This bit will contribute to an overrun + * interrupt/DMA trigger if the MODE bit (in SEQAA_CTRL) for the corresponding sequence is set + * to '0' (and if the overrun interrupt is enabled). + */ +#define ADC_SEQ_GDAT_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_OVERRUN_SHIFT)) & ADC_SEQ_GDAT_OVERRUN_MASK) +#define ADC_SEQ_GDAT_DATAVALID_MASK (0x80000000U) +#define ADC_SEQ_GDAT_DATAVALID_SHIFT (31U) +/*! DATAVALID - This bit is set to '1' at the end of each conversion when a new result is loaded + * into the RESULT field. It is cleared whenever this register is read. This bit will cause a + * conversion-complete interrupt for the corresponding sequence if the MODE bit (in SEQA_CTRL) for that + * sequence is set to 0 (and if the interrupt is enabled). + */ +#define ADC_SEQ_GDAT_DATAVALID(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_DATAVALID_SHIFT)) & ADC_SEQ_GDAT_DATAVALID_MASK) +/*! @} */ + +/* The count of ADC_SEQ_GDAT */ +#define ADC_SEQ_GDAT_COUNT (2U) + +/*! @name DAT - ADC Channel 0 Data register. This register contains the result of the most recent conversion completed on channel 0. */ +/*! @{ */ +#define ADC_DAT_RESULT_MASK (0xFFF0U) +#define ADC_DAT_RESULT_SHIFT (4U) +/*! RESULT - This field contains the 12-bit ADC conversion result from the last conversion performed + * on this channel. This will be a binary fraction representing the voltage on the AD0[n] pin, + * as it falls within the range of VREFP to VREFN. Zero in the field indicates that the voltage on + * the input pin was less than, equal to, or close to that on VREFN, while 0xFFF indicates that + * the voltage on the input was close to, equal to, or greater than that on VREFP. + */ +#define ADC_DAT_RESULT(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_RESULT_SHIFT)) & ADC_DAT_RESULT_MASK) +#define ADC_DAT_THCMPRANGE_MASK (0x30000U) +#define ADC_DAT_THCMPRANGE_SHIFT (16U) +/*! THCMPRANGE - Threshold Range Comparison result. 0x0 = In Range: The last completed conversion + * was greater than or equal to the value programmed into the designated LOW threshold register + * (THRn_LOW) but less than or equal to the value programmed into the designated HIGH threshold + * register (THRn_HIGH). 0x1 = Below Range: The last completed conversion on was less than the value + * programmed into the designated LOW threshold register (THRn_LOW). 0x2 = Above Range: The last + * completed conversion was greater than the value programmed into the designated HIGH threshold + * register (THRn_HIGH). 0x3 = Reserved. + */ +#define ADC_DAT_THCMPRANGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPRANGE_SHIFT)) & ADC_DAT_THCMPRANGE_MASK) +#define ADC_DAT_THCMPCROSS_MASK (0xC0000U) +#define ADC_DAT_THCMPCROSS_SHIFT (18U) +/*! THCMPCROSS - Threshold Crossing Comparison result. 0x0 = No threshold Crossing detected: The + * most recent completed conversion on this channel had the same relationship (above or below) to + * the threshold value established by the designated LOW threshold register (THRn_LOW) as did the + * previous conversion on this channel. 0x1 = Reserved. 0x2 = Downward Threshold Crossing + * Detected. Indicates that a threshold crossing in the downward direction has occurred - i.e. the + * previous sample on this channel was above the threshold value established by the designated LOW + * threshold register (THRn_LOW) and the current sample is below that threshold. 0x3 = Upward + * Threshold Crossing Detected. Indicates that a threshold crossing in the upward direction has occurred + * - i.e. the previous sample on this channel was below the threshold value established by the + * designated LOW threshold register (THRn_LOW) and the current sample is above that threshold. + */ +#define ADC_DAT_THCMPCROSS(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPCROSS_SHIFT)) & ADC_DAT_THCMPCROSS_MASK) +#define ADC_DAT_CHANNEL_MASK (0x3C000000U) +#define ADC_DAT_CHANNEL_SHIFT (26U) +/*! CHANNEL - This field is hard-coded to contain the channel number that this particular register + * relates to (i.e. this field will contain 0b0000 for the DAT0 register, 0b0001 for the DAT1 + * register, etc) + */ +#define ADC_DAT_CHANNEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_CHANNEL_SHIFT)) & ADC_DAT_CHANNEL_MASK) +#define ADC_DAT_OVERRUN_MASK (0x40000000U) +#define ADC_DAT_OVERRUN_SHIFT (30U) +/*! OVERRUN - This bit will be set to a 1 if a new conversion on this channel completes and + * overwrites the previous contents of the RESULT field before it has been read - i.e. while the DONE bit + * is set. This bit is cleared, along with the DONE bit, whenever this register is read or when + * the data related to this channel is read from either of the global SEQn_GDAT registers. This + * bit (in any of the 12 registers) will cause an overrun interrupt/DMA trigger to be asserted if + * the overrun interrupt is enabled. While it is allowed to include the same channels in both + * conversion sequences, doing so may cause erratic behavior of the DONE and OVERRUN bits in the + * data registers associated with any of the channels that are shared between the two sequences. Any + * erratic OVERRUN behavior will also affect overrun interrupt generation, if enabled. + */ +#define ADC_DAT_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_OVERRUN_SHIFT)) & ADC_DAT_OVERRUN_MASK) +#define ADC_DAT_DATAVALID_MASK (0x80000000U) +#define ADC_DAT_DATAVALID_SHIFT (31U) +/*! DATAVALID - This bit is set to 1 when an ADC conversion on this channel completes. This bit is + * cleared whenever this register is read or when the data related to this channel is read from + * either of the global SEQn_GDAT registers. While it is allowed to include the same channels in + * both conversion sequences, doing so may cause erratic behavior of the DONE and OVERRUN bits in + * the data registers associated with any of the channels that are shared between the two + * sequences. Any erratic OVERRUN behavior will also affect overrun interrupt generation, if enabled. + */ +#define ADC_DAT_DATAVALID(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_DATAVALID_SHIFT)) & ADC_DAT_DATAVALID_MASK) +/*! @} */ + +/* The count of ADC_DAT */ +#define ADC_DAT_COUNT (12U) + +/*! @name THR0_LOW - ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */ +/*! @{ */ +#define ADC_THR0_LOW_THRLOW_MASK (0xFFF0U) +#define ADC_THR0_LOW_THRLOW_SHIFT (4U) +/*! THRLOW - Low threshold value against which ADC results will be compared + */ +#define ADC_THR0_LOW_THRLOW(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR0_LOW_THRLOW_SHIFT)) & ADC_THR0_LOW_THRLOW_MASK) +/*! @} */ + +/*! @name THR1_LOW - ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */ +/*! @{ */ +#define ADC_THR1_LOW_THRLOW_MASK (0xFFF0U) +#define ADC_THR1_LOW_THRLOW_SHIFT (4U) +/*! THRLOW - Low threshold value against which ADC results will be compared + */ +#define ADC_THR1_LOW_THRLOW(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR1_LOW_THRLOW_SHIFT)) & ADC_THR1_LOW_THRLOW_MASK) +/*! @} */ + +/*! @name THR0_HIGH - ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */ +/*! @{ */ +#define ADC_THR0_HIGH_THRHIGH_MASK (0xFFF0U) +#define ADC_THR0_HIGH_THRHIGH_SHIFT (4U) +/*! THRHIGH - High threshold value against which ADC results will be compared + */ +#define ADC_THR0_HIGH_THRHIGH(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR0_HIGH_THRHIGH_SHIFT)) & ADC_THR0_HIGH_THRHIGH_MASK) +/*! @} */ + +/*! @name THR1_HIGH - ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */ +/*! @{ */ +#define ADC_THR1_HIGH_THRHIGH_MASK (0xFFF0U) +#define ADC_THR1_HIGH_THRHIGH_SHIFT (4U) +/*! THRHIGH - High threshold value against which ADC results will be compared + */ +#define ADC_THR1_HIGH_THRHIGH(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR1_HIGH_THRHIGH_SHIFT)) & ADC_THR1_HIGH_THRHIGH_MASK) +/*! @} */ + +/*! @name CHAN_THRSEL - ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel */ +/*! @{ */ +#define ADC_CHAN_THRSEL_CH0_THRSEL_MASK (0x1U) +#define ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT (0U) +/*! CH0_THRSEL - Threshold select for channel 0. + * 0b0..Threshold 0. Results for this channel will be compared against the threshold levels indicated in the THR0_LOW and THR0_HIGH registers. + * 0b1..Threshold 1. Results for this channel will be compared against the threshold levels indicated in the THR1_LOW and THR1_HIGH registers. + */ +#define ADC_CHAN_THRSEL_CH0_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH0_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH1_THRSEL_MASK (0x2U) +#define ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT (1U) +/*! CH1_THRSEL - Threshold select for channel 1. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH1_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH1_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH2_THRSEL_MASK (0x4U) +#define ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT (2U) +/*! CH2_THRSEL - Threshold select for channel 2. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH2_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH2_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH3_THRSEL_MASK (0x8U) +#define ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT (3U) +/*! CH3_THRSEL - Threshold select for channel 3. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH3_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH3_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH4_THRSEL_MASK (0x10U) +#define ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT (4U) +/*! CH4_THRSEL - Threshold select for channel 4. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH4_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH4_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH5_THRSEL_MASK (0x20U) +#define ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT (5U) +/*! CH5_THRSEL - Threshold select for channel 5. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH5_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH5_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH6_THRSEL_MASK (0x40U) +#define ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT (6U) +/*! CH6_THRSEL - Threshold select for channel 6. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH6_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH6_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH7_THRSEL_MASK (0x80U) +#define ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT (7U) +/*! CH7_THRSEL - Threshold select for channel 7. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH7_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH7_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH8_THRSEL_MASK (0x100U) +#define ADC_CHAN_THRSEL_CH8_THRSEL_SHIFT (8U) +/*! CH8_THRSEL - Threshold select for channel 8. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH8_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH8_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH8_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH9_THRSEL_MASK (0x200U) +#define ADC_CHAN_THRSEL_CH9_THRSEL_SHIFT (9U) +/*! CH9_THRSEL - Threshold select for channel 9. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH9_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH9_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH9_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH10_THRSEL_MASK (0x400U) +#define ADC_CHAN_THRSEL_CH10_THRSEL_SHIFT (10U) +/*! CH10_THRSEL - Threshold select for channel 10. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH10_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH10_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH10_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH11_THRSEL_MASK (0x800U) +#define ADC_CHAN_THRSEL_CH11_THRSEL_SHIFT (11U) +/*! CH11_THRSEL - Threshold select for channel 11. See description for channel 0. + */ +#define ADC_CHAN_THRSEL_CH11_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH11_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH11_THRSEL_MASK) +/*! @} */ + +/*! @name INTEN - ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated. */ +/*! @{ */ +#define ADC_INTEN_SEQA_INTEN_MASK (0x1U) +#define ADC_INTEN_SEQA_INTEN_SHIFT (0U) +/*! SEQA_INTEN - Sequence A interrupt enable. + * 0b0..Disabled. The sequence A interrupt/DMA trigger is disabled. + * 0b1..Enabled. The sequence A interrupt/DMA trigger is enabled and will be asserted either upon completion of + * each individual conversion performed as part of sequence A, or upon completion of the entire A sequence of + * conversions, depending on the MODE bit in the SEQA_CTRL register. + */ +#define ADC_INTEN_SEQA_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQA_INTEN_SHIFT)) & ADC_INTEN_SEQA_INTEN_MASK) +#define ADC_INTEN_SEQB_INTEN_MASK (0x2U) +#define ADC_INTEN_SEQB_INTEN_SHIFT (1U) +/*! SEQB_INTEN - Sequence B interrupt enable. + * 0b0..Disabled. The sequence B interrupt/DMA trigger is disabled. + * 0b1..Enabled. The sequence B interrupt/DMA trigger is enabled and will be asserted either upon completion of + * each individual conversion performed as part of sequence B, or upon completion of the entire B sequence of + * conversions, depending on the MODE bit in the SEQB_CTRL register. + */ +#define ADC_INTEN_SEQB_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQB_INTEN_SHIFT)) & ADC_INTEN_SEQB_INTEN_MASK) +#define ADC_INTEN_OVR_INTEN_MASK (0x4U) +#define ADC_INTEN_OVR_INTEN_SHIFT (2U) +/*! OVR_INTEN - Overrun interrupt enable. + * 0b0..Disabled. The overrun interrupt is disabled. + * 0b1..Enabled. The overrun interrupt is enabled. Detection of an overrun condition on any of the 12 channel + * data registers will cause an overrun interrupt/DMA trigger. In addition, if the MODE bit for a particular + * sequence is 0, then an overrun in the global data register for that sequence will also cause this + * interrupt/DMA trigger to be asserted. + */ +#define ADC_INTEN_OVR_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_OVR_INTEN_SHIFT)) & ADC_INTEN_OVR_INTEN_MASK) +#define ADC_INTEN_ADCMPINTEN0_MASK (0x18U) +#define ADC_INTEN_ADCMPINTEN0_SHIFT (3U) +/*! ADCMPINTEN0 - Threshold comparison interrupt enable for channel 0. + * 0b00..Disabled. + * 0b01..Outside threshold. + * 0b10..Crossing threshold. + * 0b11..Reserved + */ +#define ADC_INTEN_ADCMPINTEN0(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN0_SHIFT)) & ADC_INTEN_ADCMPINTEN0_MASK) +#define ADC_INTEN_ADCMPINTEN1_MASK (0x60U) +#define ADC_INTEN_ADCMPINTEN1_SHIFT (5U) +/*! ADCMPINTEN1 - Channel 1 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN1(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN1_SHIFT)) & ADC_INTEN_ADCMPINTEN1_MASK) +#define ADC_INTEN_ADCMPINTEN2_MASK (0x180U) +#define ADC_INTEN_ADCMPINTEN2_SHIFT (7U) +/*! ADCMPINTEN2 - Channel 2 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN2(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN2_SHIFT)) & ADC_INTEN_ADCMPINTEN2_MASK) +#define ADC_INTEN_ADCMPINTEN3_MASK (0x600U) +#define ADC_INTEN_ADCMPINTEN3_SHIFT (9U) +/*! ADCMPINTEN3 - Channel 3 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN3(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN3_SHIFT)) & ADC_INTEN_ADCMPINTEN3_MASK) +#define ADC_INTEN_ADCMPINTEN4_MASK (0x1800U) +#define ADC_INTEN_ADCMPINTEN4_SHIFT (11U) +/*! ADCMPINTEN4 - Channel 4 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN4(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN4_SHIFT)) & ADC_INTEN_ADCMPINTEN4_MASK) +#define ADC_INTEN_ADCMPINTEN5_MASK (0x6000U) +#define ADC_INTEN_ADCMPINTEN5_SHIFT (13U) +/*! ADCMPINTEN5 - Channel 5 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN5(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN5_SHIFT)) & ADC_INTEN_ADCMPINTEN5_MASK) +#define ADC_INTEN_ADCMPINTEN6_MASK (0x18000U) +#define ADC_INTEN_ADCMPINTEN6_SHIFT (15U) +/*! ADCMPINTEN6 - Channel 6 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN6(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN6_SHIFT)) & ADC_INTEN_ADCMPINTEN6_MASK) +#define ADC_INTEN_ADCMPINTEN7_MASK (0x60000U) +#define ADC_INTEN_ADCMPINTEN7_SHIFT (17U) +/*! ADCMPINTEN7 - Channel 7 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN7(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN7_SHIFT)) & ADC_INTEN_ADCMPINTEN7_MASK) +#define ADC_INTEN_ADCMPINTEN8_MASK (0x180000U) +#define ADC_INTEN_ADCMPINTEN8_SHIFT (19U) +/*! ADCMPINTEN8 - Channel 8 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN8(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN8_SHIFT)) & ADC_INTEN_ADCMPINTEN8_MASK) +#define ADC_INTEN_ADCMPINTEN9_MASK (0x600000U) +#define ADC_INTEN_ADCMPINTEN9_SHIFT (21U) +/*! ADCMPINTEN9 - Channel 9 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN9(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN9_SHIFT)) & ADC_INTEN_ADCMPINTEN9_MASK) +#define ADC_INTEN_ADCMPINTEN10_MASK (0x1800000U) +#define ADC_INTEN_ADCMPINTEN10_SHIFT (23U) +/*! ADCMPINTEN10 - Channel 10 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN10(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN10_SHIFT)) & ADC_INTEN_ADCMPINTEN10_MASK) +#define ADC_INTEN_ADCMPINTEN11_MASK (0x6000000U) +#define ADC_INTEN_ADCMPINTEN11_SHIFT (25U) +/*! ADCMPINTEN11 - Channel 21 threshold comparison interrupt enable. See description for channel 0. + */ +#define ADC_INTEN_ADCMPINTEN11(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN11_SHIFT)) & ADC_INTEN_ADCMPINTEN11_MASK) +/*! @} */ + +/*! @name FLAGS - ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers). */ +/*! @{ */ +#define ADC_FLAGS_THCMP0_MASK (0x1U) +#define ADC_FLAGS_THCMP0_SHIFT (0U) +/*! THCMP0 - Threshold comparison event on Channel 0. Set to 1 upon either an out-of-range result or + * a threshold-crossing result if enabled to do so in the INTEN register. This bit is cleared by + * writing a 1. + */ +#define ADC_FLAGS_THCMP0(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP0_SHIFT)) & ADC_FLAGS_THCMP0_MASK) +#define ADC_FLAGS_THCMP1_MASK (0x2U) +#define ADC_FLAGS_THCMP1_SHIFT (1U) +/*! THCMP1 - Threshold comparison event on Channel 1. See description for channel 0. + */ +#define ADC_FLAGS_THCMP1(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP1_SHIFT)) & ADC_FLAGS_THCMP1_MASK) +#define ADC_FLAGS_THCMP2_MASK (0x4U) +#define ADC_FLAGS_THCMP2_SHIFT (2U) +/*! THCMP2 - Threshold comparison event on Channel 2. See description for channel 0. + */ +#define ADC_FLAGS_THCMP2(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP2_SHIFT)) & ADC_FLAGS_THCMP2_MASK) +#define ADC_FLAGS_THCMP3_MASK (0x8U) +#define ADC_FLAGS_THCMP3_SHIFT (3U) +/*! THCMP3 - Threshold comparison event on Channel 3. See description for channel 0. + */ +#define ADC_FLAGS_THCMP3(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP3_SHIFT)) & ADC_FLAGS_THCMP3_MASK) +#define ADC_FLAGS_THCMP4_MASK (0x10U) +#define ADC_FLAGS_THCMP4_SHIFT (4U) +/*! THCMP4 - Threshold comparison event on Channel 4. See description for channel 0. + */ +#define ADC_FLAGS_THCMP4(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP4_SHIFT)) & ADC_FLAGS_THCMP4_MASK) +#define ADC_FLAGS_THCMP5_MASK (0x20U) +#define ADC_FLAGS_THCMP5_SHIFT (5U) +/*! THCMP5 - Threshold comparison event on Channel 5. See description for channel 0. + */ +#define ADC_FLAGS_THCMP5(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP5_SHIFT)) & ADC_FLAGS_THCMP5_MASK) +#define ADC_FLAGS_THCMP6_MASK (0x40U) +#define ADC_FLAGS_THCMP6_SHIFT (6U) +/*! THCMP6 - Threshold comparison event on Channel 6. See description for channel 0. + */ +#define ADC_FLAGS_THCMP6(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP6_SHIFT)) & ADC_FLAGS_THCMP6_MASK) +#define ADC_FLAGS_THCMP7_MASK (0x80U) +#define ADC_FLAGS_THCMP7_SHIFT (7U) +/*! THCMP7 - Threshold comparison event on Channel 7. See description for channel 0. + */ +#define ADC_FLAGS_THCMP7(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP7_SHIFT)) & ADC_FLAGS_THCMP7_MASK) +#define ADC_FLAGS_THCMP8_MASK (0x100U) +#define ADC_FLAGS_THCMP8_SHIFT (8U) +/*! THCMP8 - Threshold comparison event on Channel 8. See description for channel 0. + */ +#define ADC_FLAGS_THCMP8(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP8_SHIFT)) & ADC_FLAGS_THCMP8_MASK) +#define ADC_FLAGS_THCMP9_MASK (0x200U) +#define ADC_FLAGS_THCMP9_SHIFT (9U) +/*! THCMP9 - Threshold comparison event on Channel 9. See description for channel 0. + */ +#define ADC_FLAGS_THCMP9(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP9_SHIFT)) & ADC_FLAGS_THCMP9_MASK) +#define ADC_FLAGS_THCMP10_MASK (0x400U) +#define ADC_FLAGS_THCMP10_SHIFT (10U) +/*! THCMP10 - Threshold comparison event on Channel 10. See description for channel 0. + */ +#define ADC_FLAGS_THCMP10(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP10_SHIFT)) & ADC_FLAGS_THCMP10_MASK) +#define ADC_FLAGS_THCMP11_MASK (0x800U) +#define ADC_FLAGS_THCMP11_SHIFT (11U) +/*! THCMP11 - Threshold comparison event on Channel 11. See description for channel 0. + */ +#define ADC_FLAGS_THCMP11(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP11_SHIFT)) & ADC_FLAGS_THCMP11_MASK) +#define ADC_FLAGS_OVERRUN0_MASK (0x1000U) +#define ADC_FLAGS_OVERRUN0_SHIFT (12U) +/*! OVERRUN0 - Mirrors the OVERRRUN status flag from the result register for ADC channel 0 + */ +#define ADC_FLAGS_OVERRUN0(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN0_SHIFT)) & ADC_FLAGS_OVERRUN0_MASK) +#define ADC_FLAGS_OVERRUN1_MASK (0x2000U) +#define ADC_FLAGS_OVERRUN1_SHIFT (13U) +/*! OVERRUN1 - Mirrors the OVERRRUN status flag from the result register for ADC channel 1 + */ +#define ADC_FLAGS_OVERRUN1(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN1_SHIFT)) & ADC_FLAGS_OVERRUN1_MASK) +#define ADC_FLAGS_OVERRUN2_MASK (0x4000U) +#define ADC_FLAGS_OVERRUN2_SHIFT (14U) +/*! OVERRUN2 - Mirrors the OVERRRUN status flag from the result register for ADC channel 2 + */ +#define ADC_FLAGS_OVERRUN2(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN2_SHIFT)) & ADC_FLAGS_OVERRUN2_MASK) +#define ADC_FLAGS_OVERRUN3_MASK (0x8000U) +#define ADC_FLAGS_OVERRUN3_SHIFT (15U) +/*! OVERRUN3 - Mirrors the OVERRRUN status flag from the result register for ADC channel 3 + */ +#define ADC_FLAGS_OVERRUN3(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN3_SHIFT)) & ADC_FLAGS_OVERRUN3_MASK) +#define ADC_FLAGS_OVERRUN4_MASK (0x10000U) +#define ADC_FLAGS_OVERRUN4_SHIFT (16U) +/*! OVERRUN4 - Mirrors the OVERRRUN status flag from the result register for ADC channel 4 + */ +#define ADC_FLAGS_OVERRUN4(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN4_SHIFT)) & ADC_FLAGS_OVERRUN4_MASK) +#define ADC_FLAGS_OVERRUN5_MASK (0x20000U) +#define ADC_FLAGS_OVERRUN5_SHIFT (17U) +/*! OVERRUN5 - Mirrors the OVERRRUN status flag from the result register for ADC channel 5 + */ +#define ADC_FLAGS_OVERRUN5(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN5_SHIFT)) & ADC_FLAGS_OVERRUN5_MASK) +#define ADC_FLAGS_OVERRUN6_MASK (0x40000U) +#define ADC_FLAGS_OVERRUN6_SHIFT (18U) +/*! OVERRUN6 - Mirrors the OVERRRUN status flag from the result register for ADC channel 6 + */ +#define ADC_FLAGS_OVERRUN6(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN6_SHIFT)) & ADC_FLAGS_OVERRUN6_MASK) +#define ADC_FLAGS_OVERRUN7_MASK (0x80000U) +#define ADC_FLAGS_OVERRUN7_SHIFT (19U) +/*! OVERRUN7 - Mirrors the OVERRRUN status flag from the result register for ADC channel 7 + */ +#define ADC_FLAGS_OVERRUN7(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN7_SHIFT)) & ADC_FLAGS_OVERRUN7_MASK) +#define ADC_FLAGS_OVERRUN8_MASK (0x100000U) +#define ADC_FLAGS_OVERRUN8_SHIFT (20U) +/*! OVERRUN8 - Mirrors the OVERRRUN status flag from the result register for ADC channel 8 + */ +#define ADC_FLAGS_OVERRUN8(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN8_SHIFT)) & ADC_FLAGS_OVERRUN8_MASK) +#define ADC_FLAGS_OVERRUN9_MASK (0x200000U) +#define ADC_FLAGS_OVERRUN9_SHIFT (21U) +/*! OVERRUN9 - Mirrors the OVERRRUN status flag from the result register for ADC channel 9 + */ +#define ADC_FLAGS_OVERRUN9(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN9_SHIFT)) & ADC_FLAGS_OVERRUN9_MASK) +#define ADC_FLAGS_OVERRUN10_MASK (0x400000U) +#define ADC_FLAGS_OVERRUN10_SHIFT (22U) +/*! OVERRUN10 - Mirrors the OVERRRUN status flag from the result register for ADC channel 10 + */ +#define ADC_FLAGS_OVERRUN10(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN10_SHIFT)) & ADC_FLAGS_OVERRUN10_MASK) +#define ADC_FLAGS_OVERRUN11_MASK (0x800000U) +#define ADC_FLAGS_OVERRUN11_SHIFT (23U) +/*! OVERRUN11 - Mirrors the OVERRRUN status flag from the result register for ADC channel 11 + */ +#define ADC_FLAGS_OVERRUN11(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN11_SHIFT)) & ADC_FLAGS_OVERRUN11_MASK) +#define ADC_FLAGS_SEQA_OVR_MASK (0x1000000U) +#define ADC_FLAGS_SEQA_OVR_SHIFT (24U) +/*! SEQA_OVR - Mirrors the global OVERRUN status flag in the SEQA_GDAT register + */ +#define ADC_FLAGS_SEQA_OVR(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_OVR_SHIFT)) & ADC_FLAGS_SEQA_OVR_MASK) +#define ADC_FLAGS_SEQB_OVR_MASK (0x2000000U) +#define ADC_FLAGS_SEQB_OVR_SHIFT (25U) +/*! SEQB_OVR - Mirrors the global OVERRUN status flag in the SEQB_GDAT register + */ +#define ADC_FLAGS_SEQB_OVR(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQB_OVR_SHIFT)) & ADC_FLAGS_SEQB_OVR_MASK) +#define ADC_FLAGS_SEQA_INT_MASK (0x10000000U) +#define ADC_FLAGS_SEQA_INT_SHIFT (28U) +/*! SEQA_INT - Sequence A interrupt/DMA trigger. If the MODE bit in the SEQA_CTRL register is 0, + * this flag will mirror the DATAVALID bit in the sequence A global data register (SEQA_GDAT), which + * is set at the end of every ADC conversion performed as part of sequence A. It will be cleared + * automatically when the SEQA_GDAT register is read. If the MODE bit in the SEQA_CTRL register + * is 1, this flag will be set upon completion of an entire A sequence. In this case it must be + * cleared by writing a 1 to this SEQA_INT bit. This interrupt must be enabled in the INTEN + * register. + */ +#define ADC_FLAGS_SEQA_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_INT_SHIFT)) & ADC_FLAGS_SEQA_INT_MASK) +#define ADC_FLAGS_SEQB_INT_MASK (0x20000000U) +#define ADC_FLAGS_SEQB_INT_SHIFT (29U) +/*! SEQB_INT - Sequence A interrupt/DMA trigger. If the MODE bit in the SEQB_CTRL register is 0, + * this flag will mirror the DATAVALID bit in the sequence A global data register (SEQB_GDAT), which + * is set at the end of every ADC conversion performed as part of sequence B. It will be cleared + * automatically when the SEQB_GDAT register is read. If the MODE bit in the SEQB_CTRL register + * is 1, this flag will be set upon completion of an entire B sequence. In this case it must be + * cleared by writing a 1 to this SEQB_INT bit. This interrupt must be enabled in the INTEN + * register. + */ +#define ADC_FLAGS_SEQB_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQB_INT_SHIFT)) & ADC_FLAGS_SEQB_INT_MASK) +#define ADC_FLAGS_THCMP_INT_MASK (0x40000000U) +#define ADC_FLAGS_THCMP_INT_SHIFT (30U) +/*! THCMP_INT - Threshold Comparison Interrupt. This bit will be set if any of the THCMP flags in + * the lower bits of this register are set to 1 (due to an enabled out-of-range or + * threshold-crossing event on any channel). Each type of threshold comparison interrupt on each channel must be + * individually enabled in the INTEN register to cause this interrupt. This bit will be cleared + * when all of the individual threshold flags are cleared via writing 1s to those bits. + */ +#define ADC_FLAGS_THCMP_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP_INT_SHIFT)) & ADC_FLAGS_THCMP_INT_MASK) +#define ADC_FLAGS_OVR_INT_MASK (0x80000000U) +#define ADC_FLAGS_OVR_INT_SHIFT (31U) +/*! OVR_INT - Overrun Interrupt flag. Any overrun bit in any of the individual channel data + * registers will cause this interrupt. In addition, if the MODE bit in either of the SEQn_CTRL registers + * is 0 then the OVERRUN bit in the corresponding SEQn_GDAT register will also cause this + * interrupt. This interrupt must be enabled in the INTEN register. This bit will be cleared when all + * of the individual overrun bits have been cleared via reading the corresponding data registers. + */ +#define ADC_FLAGS_OVR_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVR_INT_SHIFT)) & ADC_FLAGS_OVR_INT_MASK) +/*! @} */ + +/*! @name STARTUP - ADC Startup register. */ +/*! @{ */ +#define ADC_STARTUP_ADC_ENA_MASK (0x1U) +#define ADC_STARTUP_ADC_ENA_SHIFT (0U) +/*! ADC_ENA - ADC Enable bit. This bit can only be set to a 1 by software. It is cleared + * automatically whenever the ADC is powered down. This bit must not be set until at least 10 microseconds + * after the ADC is powered up (typically by altering a system-level ADC power control bit). + */ +#define ADC_STARTUP_ADC_ENA(x) (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_ENA_SHIFT)) & ADC_STARTUP_ADC_ENA_MASK) +#define ADC_STARTUP_ADC_INIT_MASK (0x2U) +#define ADC_STARTUP_ADC_INIT_SHIFT (1U) +/*! ADC_INIT - ADC Initialization. After enabling the ADC (setting the ADC_ENA bit), the API routine + * will EITHER set this bit or the CALIB bit in the CALIB register, depending on whether or not + * calibration is required. Setting this bit will launch the 'dummy' conversion cycle that is + * required if a calibration is not performed. It will also reload the stored calibration value from + * a previous calibration unless the BYPASSCAL bit is set. This bit should only be set AFTER the + * ADC_ENA bit is set and after the CALIREQD bit is tested to determine whether a calibration or + * an ADC dummy conversion cycle is required. It should not be set during the same write that + * sets the ADC_ENA bit. This bit can only be set to a '1' by software. It is cleared automatically + * when the 'dummy' conversion cycle completes. + */ +#define ADC_STARTUP_ADC_INIT(x) (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_INIT_SHIFT)) & ADC_STARTUP_ADC_INIT_MASK) +/*! @} */ + +/*! @name CALIB - ADC Calibration register. */ +/*! @{ */ +#define ADC_CALIB_CALIB_MASK (0x1U) +#define ADC_CALIB_CALIB_SHIFT (0U) +/*! CALIB - Calibration request. Setting this bit will launch an ADC calibration cycle. This bit can + * only be set to a '1' by software. It is cleared automatically when the calibration cycle + * completes. + */ +#define ADC_CALIB_CALIB(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALIB_SHIFT)) & ADC_CALIB_CALIB_MASK) +#define ADC_CALIB_CALREQD_MASK (0x2U) +#define ADC_CALIB_CALREQD_SHIFT (1U) +/*! CALREQD - Calibration required. This read-only bit indicates if calibration is required when + * enabling the ADC. CALREQD will be '1' if no calibration has been run since the chip was + * powered-up and if the BYPASSCAL bit in the CTRL register is low. Software will test this bit to + * determine whether to initiate a calibration cycle or whether to set the ADC_INIT bit (in the STARTUP + * register) to launch the ADC initialization process which includes a 'dummy' conversion cycle. + * Note: A 'dummy' conversion cycle requires approximately 6 ADC clocks as opposed to 81 clocks + * required for calibration. + */ +#define ADC_CALIB_CALREQD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALREQD_SHIFT)) & ADC_CALIB_CALREQD_MASK) +#define ADC_CALIB_CALVALUE_MASK (0x1FCU) +#define ADC_CALIB_CALVALUE_SHIFT (2U) +/*! CALVALUE - Calibration Value. This read-only field displays the calibration value established + * during last calibration cycle. This value is not typically of any use to the user. + */ +#define ADC_CALIB_CALVALUE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALVALUE_SHIFT)) & ADC_CALIB_CALVALUE_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group ADC_Register_Masks */ + + +/* ADC - Peripheral instance base addresses */ +/** Peripheral ADC0 base address */ +#define ADC0_BASE (0x400A0000u) +/** Peripheral ADC0 base pointer */ +#define ADC0 ((ADC_Type *)ADC0_BASE) +/** Array initializer of ADC peripheral base addresses */ +#define ADC_BASE_ADDRS { ADC0_BASE } +/** Array initializer of ADC peripheral base pointers */ +#define ADC_BASE_PTRS { ADC0 } +/** Interrupt vectors for the ADC peripheral type */ +#define ADC_SEQ_IRQS { ADC0_SEQA_IRQn, ADC0_SEQB_IRQn } +#define ADC_THCMP_IRQS { ADC0_THCMP_IRQn } + +/*! + * @} + */ /* end of group ADC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- ASYNC_SYSCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ASYNC_SYSCON_Peripheral_Access_Layer ASYNC_SYSCON Peripheral Access Layer + * @{ + */ + +/** ASYNC_SYSCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t ASYNCPRESETCTRL; /**< Async peripheral reset control, offset: 0x0 */ + __O uint32_t ASYNCPRESETCTRLSET; /**< Set bits in ASYNCPRESETCTRL, offset: 0x4 */ + __O uint32_t ASYNCPRESETCTRLCLR; /**< Clear bits in ASYNCPRESETCTRL, offset: 0x8 */ + uint8_t RESERVED_0[4]; + __IO uint32_t ASYNCAPBCLKCTRL; /**< Async peripheral clock control, offset: 0x10 */ + __O uint32_t ASYNCAPBCLKCTRLSET; /**< Set bits in ASYNCAPBCLKCTRL, offset: 0x14 */ + __O uint32_t ASYNCAPBCLKCTRLCLR; /**< Clear bits in ASYNCAPBCLKCTRL, offset: 0x18 */ + uint8_t RESERVED_1[4]; + __IO uint32_t ASYNCAPBCLKSELA; /**< Async APB clock source select A, offset: 0x20 */ +} ASYNC_SYSCON_Type; + +/* ---------------------------------------------------------------------------- + -- ASYNC_SYSCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ASYNC_SYSCON_Register_Masks ASYNC_SYSCON Register Masks + * @{ + */ + +/*! @name ASYNCPRESETCTRL - Async peripheral reset control */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER3_MASK (0x2000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER3_SHIFT (13U) +/*! CTIMER3 - Standard counter/timer CTIMER3 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER3(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER3_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER3_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER4_MASK (0x4000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER4_SHIFT (14U) +/*! CTIMER4 - Standard counter/timer CTIMER4 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER4(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER4_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CTIMER4_MASK) +/*! @} */ + +/*! @name ASYNCPRESETCTRLSET - Set bits in ASYNCPRESETCTRL */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_SHIFT (0U) +/*! ARST_SET - Writing ones to this register sets the corresponding bit or bits in the + * ASYNCPRESETCTRL register, if they are implemented. Bits that do not correspond to defined bits in + * ASYNCPRESETCTRL are reserved and only zeroes should be written to them. + */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_MASK) +/*! @} */ + +/*! @name ASYNCPRESETCTRLCLR - Clear bits in ASYNCPRESETCTRL */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_SHIFT (0U) +/*! ARST_CLR - Writing ones to this register clears the corresponding bit or bits in the + * ASYNCPRESETCTRL register, if they are implemented. Bits that do not correspond to defined bits in + * ASYNCPRESETCTRL are reserved and only zeroes should be written to them. + */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_MASK) +/*! @} */ + +/*! @name ASYNCAPBCLKCTRL - Async peripheral clock control */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER3_MASK (0x2000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER3_SHIFT (13U) +/*! CTIMER3 - Controls the clock for CTIMER3. 0 = Disable; 1 = Enable. + */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER3(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER3_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER3_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER4_MASK (0x4000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER4_SHIFT (14U) +/*! CTIMER4 - Controls the clock for CTIMER4. 0 = Disable; 1 = Enable. + */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER4(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER4_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CTIMER4_MASK) +/*! @} */ + +/*! @name ASYNCAPBCLKCTRLSET - Set bits in ASYNCAPBCLKCTRL */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_SHIFT (0U) +/*! ACLK_SET - Writing ones to this register sets the corresponding bit or bits in the + * ASYNCAPBCLKCTRL register, if they are implemented. Bits that do not correspond to defined bits in + * ASYNCPRESETCTRL are reserved and only zeroes should be written to them. + */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_MASK) +/*! @} */ + +/*! @name ASYNCAPBCLKCTRLCLR - Clear bits in ASYNCAPBCLKCTRL */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_SHIFT (0U) +/*! ACLK_CLR - Writing ones to this register clears the corresponding bit or bits in the + * ASYNCAPBCLKCTRL register, if they are implemented. Bits that do not correspond to defined bits in + * ASYNCAPBCLKCTRL are reserved and only zeroes should be written to them. + */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_MASK) +/*! @} */ + +/*! @name ASYNCAPBCLKSELA - Async APB clock source select A */ +/*! @{ */ +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK (0x3U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT (0U) +/*! SEL - Clock source for asynchronous clock source selector A + * 0b00..Main clock + * 0b01..FRO 12 MHz + * 0b10..Reserved setting + * 0b11..Reserved setting + */ +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group ASYNC_SYSCON_Register_Masks */ + + +/* ASYNC_SYSCON - Peripheral instance base addresses */ +/** Peripheral ASYNC_SYSCON base address */ +#define ASYNC_SYSCON_BASE (0x40040000u) +/** Peripheral ASYNC_SYSCON base pointer */ +#define ASYNC_SYSCON ((ASYNC_SYSCON_Type *)ASYNC_SYSCON_BASE) +/** Array initializer of ASYNC_SYSCON peripheral base addresses */ +#define ASYNC_SYSCON_BASE_ADDRS { ASYNC_SYSCON_BASE } +/** Array initializer of ASYNC_SYSCON peripheral base pointers */ +#define ASYNC_SYSCON_BASE_PTRS { ASYNC_SYSCON } + +/*! + * @} + */ /* end of group ASYNC_SYSCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CRC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Peripheral_Access_Layer CRC Peripheral Access Layer + * @{ + */ + +/** CRC - Register Layout Typedef */ +typedef struct { + __IO uint32_t MODE; /**< CRC mode register, offset: 0x0 */ + __IO uint32_t SEED; /**< CRC seed register, offset: 0x4 */ + union { /* offset: 0x8 */ + __I uint32_t SUM; /**< CRC checksum register, offset: 0x8 */ + __O uint32_t WR_DATA; /**< CRC data register, offset: 0x8 */ + }; +} CRC_Type; + +/* ---------------------------------------------------------------------------- + -- CRC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Register_Masks CRC Register Masks + * @{ + */ + +/*! @name MODE - CRC mode register */ +/*! @{ */ +#define CRC_MODE_CRC_POLY_MASK (0x3U) +#define CRC_MODE_CRC_POLY_SHIFT (0U) +/*! CRC_POLY - CRC polynomial: 1X = CRC-32 polynomial 01 = CRC-16 polynomial 00 = CRC-CCITT polynomial + */ +#define CRC_MODE_CRC_POLY(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CRC_POLY_SHIFT)) & CRC_MODE_CRC_POLY_MASK) +#define CRC_MODE_BIT_RVS_WR_MASK (0x4U) +#define CRC_MODE_BIT_RVS_WR_SHIFT (2U) +/*! BIT_RVS_WR - Data bit order: 1 = Bit order reverse for CRC_WR_DATA (per byte) 0 = No bit order reverse for CRC_WR_DATA (per byte) + */ +#define CRC_MODE_BIT_RVS_WR(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_BIT_RVS_WR_SHIFT)) & CRC_MODE_BIT_RVS_WR_MASK) +#define CRC_MODE_CMPL_WR_MASK (0x8U) +#define CRC_MODE_CMPL_WR_SHIFT (3U) +/*! CMPL_WR - Data complement: 1 = 1's complement for CRC_WR_DATA 0 = No 1's complement for CRC_WR_DATA + */ +#define CRC_MODE_CMPL_WR(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CMPL_WR_SHIFT)) & CRC_MODE_CMPL_WR_MASK) +#define CRC_MODE_BIT_RVS_SUM_MASK (0x10U) +#define CRC_MODE_BIT_RVS_SUM_SHIFT (4U) +/*! BIT_RVS_SUM - CRC sum bit order: 1 = Bit order reverse for CRC_SUM 0 = No bit order reverse for CRC_SUM + */ +#define CRC_MODE_BIT_RVS_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_BIT_RVS_SUM_SHIFT)) & CRC_MODE_BIT_RVS_SUM_MASK) +#define CRC_MODE_CMPL_SUM_MASK (0x20U) +#define CRC_MODE_CMPL_SUM_SHIFT (5U) +/*! CMPL_SUM - CRC sum complement: 1 = 1's complement for CRC_SUM 0 = No 1's complement for CRC_SUM + */ +#define CRC_MODE_CMPL_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CMPL_SUM_SHIFT)) & CRC_MODE_CMPL_SUM_MASK) +/*! @} */ + +/*! @name SEED - CRC seed register */ +/*! @{ */ +#define CRC_SEED_CRC_SEED_MASK (0xFFFFFFFFU) +#define CRC_SEED_CRC_SEED_SHIFT (0U) +/*! CRC_SEED - A write access to this register will load CRC seed value to CRC_SUM register with + * selected bit order and 1's complement pre-processes. A write access to this register will + * overrule the CRC calculation in progresses. + */ +#define CRC_SEED_CRC_SEED(x) (((uint32_t)(((uint32_t)(x)) << CRC_SEED_CRC_SEED_SHIFT)) & CRC_SEED_CRC_SEED_MASK) +/*! @} */ + +/*! @name SUM - CRC checksum register */ +/*! @{ */ +#define CRC_SUM_CRC_SUM_MASK (0xFFFFFFFFU) +#define CRC_SUM_CRC_SUM_SHIFT (0U) +/*! CRC_SUM - The most recent CRC sum can be read through this register with selected bit order and 1's complement post-processes. + */ +#define CRC_SUM_CRC_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_SUM_CRC_SUM_SHIFT)) & CRC_SUM_CRC_SUM_MASK) +/*! @} */ + +/*! @name WR_DATA - CRC data register */ +/*! @{ */ +#define CRC_WR_DATA_CRC_WR_DATA_MASK (0xFFFFFFFFU) +#define CRC_WR_DATA_CRC_WR_DATA_SHIFT (0U) +/*! CRC_WR_DATA - Data written to this register will be taken to perform CRC calculation with + * selected bit order and 1's complement pre-process. Any write size 8, 16 or 32-bit are allowed and + * accept back-to-back transactions. + */ +#define CRC_WR_DATA_CRC_WR_DATA(x) (((uint32_t)(((uint32_t)(x)) << CRC_WR_DATA_CRC_WR_DATA_SHIFT)) & CRC_WR_DATA_CRC_WR_DATA_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group CRC_Register_Masks */ + + +/* CRC - Peripheral instance base addresses */ +/** Peripheral CRC_ENGINE base address */ +#define CRC_ENGINE_BASE (0x40095000u) +/** Peripheral CRC_ENGINE base pointer */ +#define CRC_ENGINE ((CRC_Type *)CRC_ENGINE_BASE) +/** Array initializer of CRC peripheral base addresses */ +#define CRC_BASE_ADDRS { CRC_ENGINE_BASE } +/** Array initializer of CRC peripheral base pointers */ +#define CRC_BASE_PTRS { CRC_ENGINE } + +/*! + * @} + */ /* end of group CRC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CTIMER Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CTIMER_Peripheral_Access_Layer CTIMER Peripheral Access Layer + * @{ + */ + +/** CTIMER - Register Layout Typedef */ +typedef struct { + __IO uint32_t IR; /**< Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending., offset: 0x0 */ + __IO uint32_t TCR; /**< Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR., offset: 0x4 */ + __IO uint32_t TC; /**< Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR., offset: 0x8 */ + __IO uint32_t PR; /**< Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC., offset: 0xC */ + __IO uint32_t PC; /**< Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface., offset: 0x10 */ + __IO uint32_t MCR; /**< Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs., offset: 0x14 */ + __IO uint32_t MR[4]; /**< Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC., array offset: 0x18, array step: 0x4 */ + __IO uint32_t CCR; /**< Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place., offset: 0x28 */ + __I uint32_t CR[4]; /**< Capture Register . CR is loaded with the value of TC when there is an event on the CAPn. input., array offset: 0x2C, array step: 0x4 */ + __IO uint32_t EMR; /**< External Match Register. The EMR controls the match function and the external match pins., offset: 0x3C */ + uint8_t RESERVED_0[48]; + __IO uint32_t CTCR; /**< Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting., offset: 0x70 */ + __IO uint32_t PWMC; /**< PWM Control Register. The PWMCON enables PWM mode for the external match pins., offset: 0x74 */ +} CTIMER_Type; + +/* ---------------------------------------------------------------------------- + -- CTIMER Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CTIMER_Register_Masks CTIMER Register Masks + * @{ + */ + +/*! @name IR - Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */ +/*! @{ */ +#define CTIMER_IR_MR0INT_MASK (0x1U) +#define CTIMER_IR_MR0INT_SHIFT (0U) +/*! MR0INT - Interrupt flag for match channel 0. + */ +#define CTIMER_IR_MR0INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR0INT_SHIFT)) & CTIMER_IR_MR0INT_MASK) +#define CTIMER_IR_MR1INT_MASK (0x2U) +#define CTIMER_IR_MR1INT_SHIFT (1U) +/*! MR1INT - Interrupt flag for match channel 1. + */ +#define CTIMER_IR_MR1INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR1INT_SHIFT)) & CTIMER_IR_MR1INT_MASK) +#define CTIMER_IR_MR2INT_MASK (0x4U) +#define CTIMER_IR_MR2INT_SHIFT (2U) +/*! MR2INT - Interrupt flag for match channel 2. + */ +#define CTIMER_IR_MR2INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR2INT_SHIFT)) & CTIMER_IR_MR2INT_MASK) +#define CTIMER_IR_MR3INT_MASK (0x8U) +#define CTIMER_IR_MR3INT_SHIFT (3U) +/*! MR3INT - Interrupt flag for match channel 3. + */ +#define CTIMER_IR_MR3INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR3INT_SHIFT)) & CTIMER_IR_MR3INT_MASK) +#define CTIMER_IR_CR0INT_MASK (0x10U) +#define CTIMER_IR_CR0INT_SHIFT (4U) +/*! CR0INT - Interrupt flag for capture channel 0 event. + */ +#define CTIMER_IR_CR0INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR0INT_SHIFT)) & CTIMER_IR_CR0INT_MASK) +#define CTIMER_IR_CR1INT_MASK (0x20U) +#define CTIMER_IR_CR1INT_SHIFT (5U) +/*! CR1INT - Interrupt flag for capture channel 1 event. + */ +#define CTIMER_IR_CR1INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR1INT_SHIFT)) & CTIMER_IR_CR1INT_MASK) +#define CTIMER_IR_CR2INT_MASK (0x40U) +#define CTIMER_IR_CR2INT_SHIFT (6U) +/*! CR2INT - Interrupt flag for capture channel 2 event. + */ +#define CTIMER_IR_CR2INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR2INT_SHIFT)) & CTIMER_IR_CR2INT_MASK) +#define CTIMER_IR_CR3INT_MASK (0x80U) +#define CTIMER_IR_CR3INT_SHIFT (7U) +/*! CR3INT - Interrupt flag for capture channel 3 event. + */ +#define CTIMER_IR_CR3INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR3INT_SHIFT)) & CTIMER_IR_CR3INT_MASK) +/*! @} */ + +/*! @name TCR - Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */ +/*! @{ */ +#define CTIMER_TCR_CEN_MASK (0x1U) +#define CTIMER_TCR_CEN_SHIFT (0U) +/*! CEN - Counter enable. + * 0b0..Disabled.The counters are disabled. + * 0b1..Enabled. The Timer Counter and Prescale Counter are enabled. + */ +#define CTIMER_TCR_CEN(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CEN_SHIFT)) & CTIMER_TCR_CEN_MASK) +#define CTIMER_TCR_CRST_MASK (0x2U) +#define CTIMER_TCR_CRST_SHIFT (1U) +/*! CRST - Counter reset. + * 0b0..Disabled. Do nothing. + * 0b1..Enabled. The Timer Counter and the Prescale Counter are synchronously reset on the next positive edge of + * the APB bus clock. The counters remain reset until TCR[1] is returned to zero. + */ +#define CTIMER_TCR_CRST(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CRST_SHIFT)) & CTIMER_TCR_CRST_MASK) +/*! @} */ + +/*! @name TC - Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR. */ +/*! @{ */ +#define CTIMER_TC_TCVAL_MASK (0xFFFFFFFFU) +#define CTIMER_TC_TCVAL_SHIFT (0U) +/*! TCVAL - Timer counter value. + */ +#define CTIMER_TC_TCVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TC_TCVAL_SHIFT)) & CTIMER_TC_TCVAL_MASK) +/*! @} */ + +/*! @name PR - Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC. */ +/*! @{ */ +#define CTIMER_PR_PRVAL_MASK (0xFFFFFFFFU) +#define CTIMER_PR_PRVAL_SHIFT (0U) +/*! PRVAL - Prescale counter value. + */ +#define CTIMER_PR_PRVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PR_PRVAL_SHIFT)) & CTIMER_PR_PRVAL_MASK) +/*! @} */ + +/*! @name PC - Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */ +/*! @{ */ +#define CTIMER_PC_PCVAL_MASK (0xFFFFFFFFU) +#define CTIMER_PC_PCVAL_SHIFT (0U) +/*! PCVAL - Prescale counter value. + */ +#define CTIMER_PC_PCVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PC_PCVAL_SHIFT)) & CTIMER_PC_PCVAL_MASK) +/*! @} */ + +/*! @name MCR - Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */ +/*! @{ */ +#define CTIMER_MCR_MR0I_MASK (0x1U) +#define CTIMER_MCR_MR0I_SHIFT (0U) +/*! MR0I - Interrupt on MR0: an interrupt is generated when MR0 matches the value in the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR0I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0I_SHIFT)) & CTIMER_MCR_MR0I_MASK) +#define CTIMER_MCR_MR0R_MASK (0x2U) +#define CTIMER_MCR_MR0R_SHIFT (1U) +/*! MR0R - Reset on MR0: the TC will be reset if MR0 matches it. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR0R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0R_SHIFT)) & CTIMER_MCR_MR0R_MASK) +#define CTIMER_MCR_MR0S_MASK (0x4U) +#define CTIMER_MCR_MR0S_SHIFT (2U) +/*! MR0S - Stop on MR0: the TC and PC will be stopped and TCR[0] will be set to 0 if MR0 matches the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR0S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0S_SHIFT)) & CTIMER_MCR_MR0S_MASK) +#define CTIMER_MCR_MR1I_MASK (0x8U) +#define CTIMER_MCR_MR1I_SHIFT (3U) +/*! MR1I - Interrupt on MR1: an interrupt is generated when MR1 matches the value in the TC. 0 = + * disabled. 1 = enabled. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR1I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1I_SHIFT)) & CTIMER_MCR_MR1I_MASK) +#define CTIMER_MCR_MR1R_MASK (0x10U) +#define CTIMER_MCR_MR1R_SHIFT (4U) +/*! MR1R - Reset on MR1: the TC will be reset if MR1 matches it. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR1R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1R_SHIFT)) & CTIMER_MCR_MR1R_MASK) +#define CTIMER_MCR_MR1S_MASK (0x20U) +#define CTIMER_MCR_MR1S_SHIFT (5U) +/*! MR1S - Stop on MR1: the TC and PC will be stopped and TCR[0] will be set to 0 if MR1 matches the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR1S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1S_SHIFT)) & CTIMER_MCR_MR1S_MASK) +#define CTIMER_MCR_MR2I_MASK (0x40U) +#define CTIMER_MCR_MR2I_SHIFT (6U) +/*! MR2I - Interrupt on MR2: an interrupt is generated when MR2 matches the value in the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR2I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2I_SHIFT)) & CTIMER_MCR_MR2I_MASK) +#define CTIMER_MCR_MR2R_MASK (0x80U) +#define CTIMER_MCR_MR2R_SHIFT (7U) +/*! MR2R - Reset on MR2: the TC will be reset if MR2 matches it. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR2R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2R_SHIFT)) & CTIMER_MCR_MR2R_MASK) +#define CTIMER_MCR_MR2S_MASK (0x100U) +#define CTIMER_MCR_MR2S_SHIFT (8U) +/*! MR2S - Stop on MR2: the TC and PC will be stopped and TCR[0] will be set to 0 if MR2 matches the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR2S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2S_SHIFT)) & CTIMER_MCR_MR2S_MASK) +#define CTIMER_MCR_MR3I_MASK (0x200U) +#define CTIMER_MCR_MR3I_SHIFT (9U) +/*! MR3I - Interrupt on MR3: an interrupt is generated when MR3 matches the value in the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR3I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3I_SHIFT)) & CTIMER_MCR_MR3I_MASK) +#define CTIMER_MCR_MR3R_MASK (0x400U) +#define CTIMER_MCR_MR3R_SHIFT (10U) +/*! MR3R - Reset on MR3: the TC will be reset if MR3 matches it. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR3R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3R_SHIFT)) & CTIMER_MCR_MR3R_MASK) +#define CTIMER_MCR_MR3S_MASK (0x800U) +#define CTIMER_MCR_MR3S_SHIFT (11U) +/*! MR3S - Stop on MR3: the TC and PC will be stopped and TCR[0] will be set to 0 if MR3 matches the TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_MCR_MR3S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3S_SHIFT)) & CTIMER_MCR_MR3S_MASK) +/*! @} */ + +/*! @name MR - Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */ +/*! @{ */ +#define CTIMER_MR_MATCH_MASK (0xFFFFFFFFU) +#define CTIMER_MR_MATCH_SHIFT (0U) +/*! MATCH - Timer counter match value. + */ +#define CTIMER_MR_MATCH(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MR_MATCH_SHIFT)) & CTIMER_MR_MATCH_MASK) +/*! @} */ + +/* The count of CTIMER_MR */ +#define CTIMER_MR_COUNT (4U) + +/*! @name CCR - Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */ +/*! @{ */ +#define CTIMER_CCR_CAP0RE_MASK (0x1U) +#define CTIMER_CCR_CAP0RE_SHIFT (0U) +/*! CAP0RE - Rising edge of capture channel 0: a sequence of 0 then 1 causes CR0 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP0RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0RE_SHIFT)) & CTIMER_CCR_CAP0RE_MASK) +#define CTIMER_CCR_CAP0FE_MASK (0x2U) +#define CTIMER_CCR_CAP0FE_SHIFT (1U) +/*! CAP0FE - Falling edge of capture channel 0: a sequence of 1 then 0 causes CR0 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP0FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0FE_SHIFT)) & CTIMER_CCR_CAP0FE_MASK) +#define CTIMER_CCR_CAP0I_MASK (0x4U) +#define CTIMER_CCR_CAP0I_SHIFT (2U) +/*! CAP0I - Generate interrupt on channel 0 capture event: a CR0 load generates an interrupt. + */ +#define CTIMER_CCR_CAP0I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0I_SHIFT)) & CTIMER_CCR_CAP0I_MASK) +#define CTIMER_CCR_CAP1RE_MASK (0x8U) +#define CTIMER_CCR_CAP1RE_SHIFT (3U) +/*! CAP1RE - Rising edge of capture channel 1: a sequence of 0 then 1 causes CR1 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP1RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1RE_SHIFT)) & CTIMER_CCR_CAP1RE_MASK) +#define CTIMER_CCR_CAP1FE_MASK (0x10U) +#define CTIMER_CCR_CAP1FE_SHIFT (4U) +/*! CAP1FE - Falling edge of capture channel 1: a sequence of 1 then 0 causes CR1 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP1FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1FE_SHIFT)) & CTIMER_CCR_CAP1FE_MASK) +#define CTIMER_CCR_CAP1I_MASK (0x20U) +#define CTIMER_CCR_CAP1I_SHIFT (5U) +/*! CAP1I - Generate interrupt on channel 1 capture event: a CR1 load generates an interrupt. + */ +#define CTIMER_CCR_CAP1I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1I_SHIFT)) & CTIMER_CCR_CAP1I_MASK) +#define CTIMER_CCR_CAP2RE_MASK (0x40U) +#define CTIMER_CCR_CAP2RE_SHIFT (6U) +/*! CAP2RE - Rising edge of capture channel 2: a sequence of 0 then 1 causes CR2 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP2RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2RE_SHIFT)) & CTIMER_CCR_CAP2RE_MASK) +#define CTIMER_CCR_CAP2FE_MASK (0x80U) +#define CTIMER_CCR_CAP2FE_SHIFT (7U) +/*! CAP2FE - Falling edge of capture channel 2: a sequence of 1 then 0 causes CR2 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP2FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2FE_SHIFT)) & CTIMER_CCR_CAP2FE_MASK) +#define CTIMER_CCR_CAP2I_MASK (0x100U) +#define CTIMER_CCR_CAP2I_SHIFT (8U) +/*! CAP2I - Generate interrupt on channel 2 capture event: a CR2 load generates an interrupt. + */ +#define CTIMER_CCR_CAP2I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2I_SHIFT)) & CTIMER_CCR_CAP2I_MASK) +#define CTIMER_CCR_CAP3RE_MASK (0x200U) +#define CTIMER_CCR_CAP3RE_SHIFT (9U) +/*! CAP3RE - Rising edge of capture channel 3: a sequence of 0 then 1 causes CR3 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP3RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3RE_SHIFT)) & CTIMER_CCR_CAP3RE_MASK) +#define CTIMER_CCR_CAP3FE_MASK (0x400U) +#define CTIMER_CCR_CAP3FE_SHIFT (10U) +/*! CAP3FE - Falling edge of capture channel 3: a sequence of 1 then 0 causes CR3 to be loaded with + * the contents of TC. 0 = disabled. 1 = enabled. + */ +#define CTIMER_CCR_CAP3FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3FE_SHIFT)) & CTIMER_CCR_CAP3FE_MASK) +#define CTIMER_CCR_CAP3I_MASK (0x800U) +#define CTIMER_CCR_CAP3I_SHIFT (11U) +/*! CAP3I - Generate interrupt on channel 3 capture event: a CR3 load generates an interrupt. + */ +#define CTIMER_CCR_CAP3I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3I_SHIFT)) & CTIMER_CCR_CAP3I_MASK) +/*! @} */ + +/*! @name CR - Capture Register . CR is loaded with the value of TC when there is an event on the CAPn. input. */ +/*! @{ */ +#define CTIMER_CR_CAP_MASK (0xFFFFFFFFU) +#define CTIMER_CR_CAP_SHIFT (0U) +/*! CAP - Timer counter capture value. + */ +#define CTIMER_CR_CAP(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CR_CAP_SHIFT)) & CTIMER_CR_CAP_MASK) +/*! @} */ + +/* The count of CTIMER_CR */ +#define CTIMER_CR_COUNT (4U) + +/*! @name EMR - External Match Register. The EMR controls the match function and the external match pins. */ +/*! @{ */ +#define CTIMER_EMR_EM0_MASK (0x1U) +#define CTIMER_EMR_EM0_SHIFT (0U) +/*! EM0 - External Match 0. This bit reflects the state of output MAT0, whether or not this output + * is connected to a pin. When a match occurs between the TC and MR0, this bit can either toggle, + * go LOW, go HIGH, or do nothing, as selected by EMR[5:4]. This bit is driven to the MAT pins if + * the match function is selected via IOCON. 0 = LOW. 1 = HIGH. + */ +#define CTIMER_EMR_EM0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM0_SHIFT)) & CTIMER_EMR_EM0_MASK) +#define CTIMER_EMR_EM1_MASK (0x2U) +#define CTIMER_EMR_EM1_SHIFT (1U) +/*! EM1 - External Match 1. This bit reflects the state of output MAT1, whether or not this output + * is connected to a pin. When a match occurs between the TC and MR1, this bit can either toggle, + * go LOW, go HIGH, or do nothing, as selected by EMR[7:6]. This bit is driven to the MAT pins if + * the match function is selected via IOCON. 0 = LOW. 1 = HIGH. + */ +#define CTIMER_EMR_EM1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM1_SHIFT)) & CTIMER_EMR_EM1_MASK) +#define CTIMER_EMR_EM2_MASK (0x4U) +#define CTIMER_EMR_EM2_SHIFT (2U) +/*! EM2 - External Match 2. This bit reflects the state of output MAT2, whether or not this output + * is connected to a pin. When a match occurs between the TC and MR2, this bit can either toggle, + * go LOW, go HIGH, or do nothing, as selected by EMR[9:8]. This bit is driven to the MAT pins if + * the match function is selected via IOCON. 0 = LOW. 1 = HIGH. + */ +#define CTIMER_EMR_EM2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM2_SHIFT)) & CTIMER_EMR_EM2_MASK) +#define CTIMER_EMR_EM3_MASK (0x8U) +#define CTIMER_EMR_EM3_SHIFT (3U) +/*! EM3 - External Match 3. This bit reflects the state of output MAT3, whether or not this output + * is connected to a pin. When a match occurs between the TC and MR3, this bit can either toggle, + * go LOW, go HIGH, or do nothing, as selected by MR[11:10]. This bit is driven to the MAT pins + * if the match function is selected via IOCON. 0 = LOW. 1 = HIGH. + */ +#define CTIMER_EMR_EM3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM3_SHIFT)) & CTIMER_EMR_EM3_MASK) +#define CTIMER_EMR_EMC0_MASK (0x30U) +#define CTIMER_EMR_EMC0_SHIFT (4U) +/*! EMC0 - External Match Control 0. Determines the functionality of External Match 0. + * 0b00..Do Nothing. + * 0b01..Clear. Clear the corresponding External Match bit/output to 0 (MAT0 pin is LOW if pinned out). + * 0b10..Set. Set the corresponding External Match bit/output to 1 (MAT0 pin is HIGH if pinned out). + * 0b11..Toggle. Toggle the corresponding External Match bit/output. + */ +#define CTIMER_EMR_EMC0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC0_SHIFT)) & CTIMER_EMR_EMC0_MASK) +#define CTIMER_EMR_EMC1_MASK (0xC0U) +#define CTIMER_EMR_EMC1_SHIFT (6U) +/*! EMC1 - External Match Control 1. Determines the functionality of External Match 1. + * 0b00..Do Nothing. + * 0b01..Clear. Clear the corresponding External Match bit/output to 0 (MAT1 pin is LOW if pinned out). + * 0b10..Set. Set the corresponding External Match bit/output to 1 (MAT1 pin is HIGH if pinned out). + * 0b11..Toggle. Toggle the corresponding External Match bit/output. + */ +#define CTIMER_EMR_EMC1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC1_SHIFT)) & CTIMER_EMR_EMC1_MASK) +#define CTIMER_EMR_EMC2_MASK (0x300U) +#define CTIMER_EMR_EMC2_SHIFT (8U) +/*! EMC2 - External Match Control 2. Determines the functionality of External Match 2. + * 0b00..Do Nothing. + * 0b01..Clear. Clear the corresponding External Match bit/output to 0 (MAT2 pin is LOW if pinned out). + * 0b10..Set. Set the corresponding External Match bit/output to 1 (MAT2 pin is HIGH if pinned out). + * 0b11..Toggle. Toggle the corresponding External Match bit/output. + */ +#define CTIMER_EMR_EMC2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC2_SHIFT)) & CTIMER_EMR_EMC2_MASK) +#define CTIMER_EMR_EMC3_MASK (0xC00U) +#define CTIMER_EMR_EMC3_SHIFT (10U) +/*! EMC3 - External Match Control 3. Determines the functionality of External Match 3. + * 0b00..Do Nothing. + * 0b01..Clear. Clear the corresponding External Match bit/output to 0 (MAT3 pin is LOW if pinned out). + * 0b10..Set. Set the corresponding External Match bit/output to 1 (MAT3 pin is HIGH if pinned out). + * 0b11..Toggle. Toggle the corresponding External Match bit/output. + */ +#define CTIMER_EMR_EMC3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC3_SHIFT)) & CTIMER_EMR_EMC3_MASK) +/*! @} */ + +/*! @name CTCR - Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */ +/*! @{ */ +#define CTIMER_CTCR_CTMODE_MASK (0x3U) +#define CTIMER_CTCR_CTMODE_SHIFT (0U) +/*! CTMODE - Counter/Timer Mode This field selects which rising APB bus clock edges can increment + * Timer's Prescale Counter (PC), or clear PC and increment Timer Counter (TC). Timer Mode: the TC + * is incremented when the Prescale Counter matches the Prescale Register. + * 0b00..Timer Mode. Incremented every rising APB bus clock edge. + * 0b01..Counter Mode rising edge. TC is incremented on rising edges on the CAP input selected by bits 3:2. + * 0b10..Counter Mode falling edge. TC is incremented on falling edges on the CAP input selected by bits 3:2. + * 0b11..Counter Mode dual edge. TC is incremented on both edges on the CAP input selected by bits 3:2. + */ +#define CTIMER_CTCR_CTMODE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CTMODE_SHIFT)) & CTIMER_CTCR_CTMODE_MASK) +#define CTIMER_CTCR_CINSEL_MASK (0xCU) +#define CTIMER_CTCR_CINSEL_SHIFT (2U) +/*! CINSEL - Count Input Select When bits 1:0 in this register are not 00, these bits select which + * CAP pin is sampled for clocking. Note: If Counter mode is selected for a particular CAPn input + * in the CTCR, the 3 bits for that input in the Capture Control Register (CCR) must be + * programmed as 000. However, capture and/or interrupt can be selected for the other 3 CAPn inputs in the + * same timer. + * 0b00..Channel 0. CAPn.0 for CTIMERn + * 0b01..Channel 1. CAPn.1 for CTIMERn + * 0b10..Channel 2. CAPn.2 for CTIMERn + * 0b11..Channel 3. CAPn.3 for CTIMERn + */ +#define CTIMER_CTCR_CINSEL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CINSEL_SHIFT)) & CTIMER_CTCR_CINSEL_MASK) +#define CTIMER_CTCR_ENCC_MASK (0x10U) +#define CTIMER_CTCR_ENCC_SHIFT (4U) +/*! ENCC - Setting this bit to 1 enables clearing of the timer and the prescaler when the + * capture-edge event specified in bits 7:5 occurs. + */ +#define CTIMER_CTCR_ENCC(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_ENCC_SHIFT)) & CTIMER_CTCR_ENCC_MASK) +#define CTIMER_CTCR_SELCC_MASK (0xE0U) +#define CTIMER_CTCR_SELCC_SHIFT (5U) +/*! SELCC - Edge select. When bit 4 is 1, these bits select which capture input edge will cause the + * timer and prescaler to be cleared. These bits have no effect when bit 4 is low. Values 0x2 to + * 0x3 and 0x6 to 0x7 are reserved. + * 0b000..Channel 0 Rising Edge. Rising edge of the signal on capture channel 0 clears the timer (if bit 4 is set). + * 0b001..Channel 0 Falling Edge. Falling edge of the signal on capture channel 0 clears the timer (if bit 4 is set). + * 0b010..Channel 1 Rising Edge. Rising edge of the signal on capture channel 1 clears the timer (if bit 4 is set). + * 0b011..Channel 1 Falling Edge. Falling edge of the signal on capture channel 1 clears the timer (if bit 4 is set). + * 0b100..Channel 2 Rising Edge. Rising edge of the signal on capture channel 2 clears the timer (if bit 4 is set). + * 0b101..Channel 2 Falling Edge. Falling edge of the signal on capture channel 2 clears the timer (if bit 4 is set). + */ +#define CTIMER_CTCR_SELCC(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_SELCC_SHIFT)) & CTIMER_CTCR_SELCC_MASK) +/*! @} */ + +/*! @name PWMC - PWM Control Register. The PWMCON enables PWM mode for the external match pins. */ +/*! @{ */ +#define CTIMER_PWMC_PWMEN0_MASK (0x1U) +#define CTIMER_PWMC_PWMEN0_SHIFT (0U) +/*! PWMEN0 - PWM mode enable for channel0. + * 0b0..Match. CTIMERn_MAT0 is controlled by EM0. + * 0b1..PWM. PWM mode is enabled for CTIMERn_MAT0. + */ +#define CTIMER_PWMC_PWMEN0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN0_SHIFT)) & CTIMER_PWMC_PWMEN0_MASK) +#define CTIMER_PWMC_PWMEN1_MASK (0x2U) +#define CTIMER_PWMC_PWMEN1_SHIFT (1U) +/*! PWMEN1 - PWM mode enable for channel1. + * 0b0..Match. CTIMERn_MAT01 is controlled by EM1. + * 0b1..PWM. PWM mode is enabled for CTIMERn_MAT1. + */ +#define CTIMER_PWMC_PWMEN1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN1_SHIFT)) & CTIMER_PWMC_PWMEN1_MASK) +#define CTIMER_PWMC_PWMEN2_MASK (0x4U) +#define CTIMER_PWMC_PWMEN2_SHIFT (2U) +/*! PWMEN2 - PWM mode enable for channel2. + * 0b0..Match. CTIMERn_MAT2 is controlled by EM2. + * 0b1..PWM. PWM mode is enabled for CTIMERn_MAT2. + */ +#define CTIMER_PWMC_PWMEN2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN2_SHIFT)) & CTIMER_PWMC_PWMEN2_MASK) +#define CTIMER_PWMC_PWMEN3_MASK (0x8U) +#define CTIMER_PWMC_PWMEN3_SHIFT (3U) +/*! PWMEN3 - PWM mode enable for channel3. Note: It is recommended to use match channel 3 to set the PWM cycle. + * 0b0..Match. CTIMERn_MAT3 is controlled by EM3. + * 0b1..PWM. PWM mode is enabled for CT132Bn_MAT3. + */ +#define CTIMER_PWMC_PWMEN3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN3_SHIFT)) & CTIMER_PWMC_PWMEN3_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group CTIMER_Register_Masks */ + + +/* CTIMER - Peripheral instance base addresses */ +/** Peripheral CTIMER0 base address */ +#define CTIMER0_BASE (0x40008000u) +/** Peripheral CTIMER0 base pointer */ +#define CTIMER0 ((CTIMER_Type *)CTIMER0_BASE) +/** Peripheral CTIMER1 base address */ +#define CTIMER1_BASE (0x40009000u) +/** Peripheral CTIMER1 base pointer */ +#define CTIMER1 ((CTIMER_Type *)CTIMER1_BASE) +/** Peripheral CTIMER2 base address */ +#define CTIMER2_BASE (0x40028000u) +/** Peripheral CTIMER2 base pointer */ +#define CTIMER2 ((CTIMER_Type *)CTIMER2_BASE) +/** Peripheral CTIMER3 base address */ +#define CTIMER3_BASE (0x40048000u) +/** Peripheral CTIMER3 base pointer */ +#define CTIMER3 ((CTIMER_Type *)CTIMER3_BASE) +/** Peripheral CTIMER4 base address */ +#define CTIMER4_BASE (0x40049000u) +/** Peripheral CTIMER4 base pointer */ +#define CTIMER4 ((CTIMER_Type *)CTIMER4_BASE) +/** Array initializer of CTIMER peripheral base addresses */ +#define CTIMER_BASE_ADDRS { CTIMER0_BASE, CTIMER1_BASE, CTIMER2_BASE, CTIMER3_BASE, CTIMER4_BASE } +/** Array initializer of CTIMER peripheral base pointers */ +#define CTIMER_BASE_PTRS { CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4 } +/** Interrupt vectors for the CTIMER peripheral type */ +#define CTIMER_IRQS { CTIMER0_IRQn, CTIMER1_IRQn, CTIMER2_IRQn, CTIMER3_IRQn, CTIMER4_IRQn } + +/*! + * @} + */ /* end of group CTIMER_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer + * @{ + */ + +/** DMA - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< DMA control., offset: 0x0 */ + __I uint32_t INTSTAT; /**< Interrupt status., offset: 0x4 */ + __IO uint32_t SRAMBASE; /**< SRAM address of the channel configuration table., offset: 0x8 */ + uint8_t RESERVED_0[20]; + struct { /* offset: 0x20, array step: 0x5C */ + __IO uint32_t ENABLESET; /**< Channel Enable read and Set for all DMA channels., array offset: 0x20, array step: 0x5C */ + uint8_t RESERVED_0[4]; + __O uint32_t ENABLECLR; /**< Channel Enable Clear for all DMA channels., array offset: 0x28, array step: 0x5C */ + uint8_t RESERVED_1[4]; + __I uint32_t ACTIVE; /**< Channel Active status for all DMA channels., array offset: 0x30, array step: 0x5C */ + uint8_t RESERVED_2[4]; + __I uint32_t BUSY; /**< Channel Busy status for all DMA channels., array offset: 0x38, array step: 0x5C */ + uint8_t RESERVED_3[4]; + __IO uint32_t ERRINT; /**< Error Interrupt status for all DMA channels., array offset: 0x40, array step: 0x5C */ + uint8_t RESERVED_4[4]; + __IO uint32_t INTENSET; /**< Interrupt Enable read and Set for all DMA channels., array offset: 0x48, array step: 0x5C */ + uint8_t RESERVED_5[4]; + __O uint32_t INTENCLR; /**< Interrupt Enable Clear for all DMA channels., array offset: 0x50, array step: 0x5C */ + uint8_t RESERVED_6[4]; + __IO uint32_t INTA; /**< Interrupt A status for all DMA channels., array offset: 0x58, array step: 0x5C */ + uint8_t RESERVED_7[4]; + __IO uint32_t INTB; /**< Interrupt B status for all DMA channels., array offset: 0x60, array step: 0x5C */ + uint8_t RESERVED_8[4]; + __O uint32_t SETVALID; /**< Set ValidPending control bits for all DMA channels., array offset: 0x68, array step: 0x5C */ + uint8_t RESERVED_9[4]; + __O uint32_t SETTRIG; /**< Set Trigger control bits for all DMA channels., array offset: 0x70, array step: 0x5C */ + uint8_t RESERVED_10[4]; + __O uint32_t ABORT; /**< Channel Abort control for all DMA channels., array offset: 0x78, array step: 0x5C */ + } COMMON[1]; + uint8_t RESERVED_1[900]; + struct { /* offset: 0x400, array step: 0x10 */ + __IO uint32_t CFG; /**< Configuration register for DMA channel ., array offset: 0x400, array step: 0x10 */ + __I uint32_t CTLSTAT; /**< Control and status register for DMA channel ., array offset: 0x404, array step: 0x10 */ + __IO uint32_t XFERCFG; /**< Transfer configuration register for DMA channel ., array offset: 0x408, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } CHANNEL[20]; +} DMA_Type; + +/* ---------------------------------------------------------------------------- + -- DMA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Register_Masks DMA Register Masks + * @{ + */ + +/*! @name CTRL - DMA control. */ +/*! @{ */ +#define DMA_CTRL_ENABLE_MASK (0x1U) +#define DMA_CTRL_ENABLE_SHIFT (0U) +/*! ENABLE - DMA controller master enable. + * 0b0..Disabled. The DMA controller is disabled. This clears any triggers that were asserted at the point when + * disabled, but does not prevent re-triggering when the DMA controller is re-enabled. + * 0b1..Enabled. The DMA controller is enabled. + */ +#define DMA_CTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CTRL_ENABLE_SHIFT)) & DMA_CTRL_ENABLE_MASK) +/*! @} */ + +/*! @name INTSTAT - Interrupt status. */ +/*! @{ */ +#define DMA_INTSTAT_ACTIVEINT_MASK (0x2U) +#define DMA_INTSTAT_ACTIVEINT_SHIFT (1U) +/*! ACTIVEINT - Summarizes whether any enabled interrupts (other than error interrupts) are pending. + * 0b0..Not pending. No enabled interrupts are pending. + * 0b1..Pending. At least one enabled interrupt is pending. + */ +#define DMA_INTSTAT_ACTIVEINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEINT_SHIFT)) & DMA_INTSTAT_ACTIVEINT_MASK) +#define DMA_INTSTAT_ACTIVEERRINT_MASK (0x4U) +#define DMA_INTSTAT_ACTIVEERRINT_SHIFT (2U) +/*! ACTIVEERRINT - Summarizes whether any error interrupts are pending. + * 0b0..Not pending. No error interrupts are pending. + * 0b1..Pending. At least one error interrupt is pending. + */ +#define DMA_INTSTAT_ACTIVEERRINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEERRINT_SHIFT)) & DMA_INTSTAT_ACTIVEERRINT_MASK) +/*! @} */ + +/*! @name SRAMBASE - SRAM address of the channel configuration table. */ +/*! @{ */ +#define DMA_SRAMBASE_OFFSET_MASK (0xFFFFFE00U) +#define DMA_SRAMBASE_OFFSET_SHIFT (9U) +/*! OFFSET - Address bits 31:9 of the beginning of the DMA descriptor table. For 18 channels, the + * table must begin on a 512 byte boundary. + */ +#define DMA_SRAMBASE_OFFSET(x) (((uint32_t)(((uint32_t)(x)) << DMA_SRAMBASE_OFFSET_SHIFT)) & DMA_SRAMBASE_OFFSET_MASK) +/*! @} */ + +/*! @name COMMON_ENABLESET - Channel Enable read and Set for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_ENABLESET_ENA_MASK (0xFFFFFFFFU) +#define DMA_COMMON_ENABLESET_ENA_SHIFT (0U) +/*! ENA - Enable for DMA channels. Bit n enables or disables DMA channel n. The number of bits = + * number of DMA channels in this device. Other bits are reserved. 0 = disabled. 1 = enabled. + */ +#define DMA_COMMON_ENABLESET_ENA(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLESET_ENA_SHIFT)) & DMA_COMMON_ENABLESET_ENA_MASK) +/*! @} */ + +/* The count of DMA_COMMON_ENABLESET */ +#define DMA_COMMON_ENABLESET_COUNT (1U) + +/*! @name COMMON_ENABLECLR - Channel Enable Clear for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_ENABLECLR_CLR_MASK (0xFFFFFFFFU) +#define DMA_COMMON_ENABLECLR_CLR_SHIFT (0U) +/*! CLR - Writing ones to this register clears the corresponding bits in ENABLESET0. Bit n clears + * the channel enable bit n. The number of bits = number of DMA channels in this device. Other bits + * are reserved. + */ +#define DMA_COMMON_ENABLECLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLECLR_CLR_SHIFT)) & DMA_COMMON_ENABLECLR_CLR_MASK) +/*! @} */ + +/* The count of DMA_COMMON_ENABLECLR */ +#define DMA_COMMON_ENABLECLR_COUNT (1U) + +/*! @name COMMON_ACTIVE - Channel Active status for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_ACTIVE_ACT_MASK (0xFFFFFFFFU) +#define DMA_COMMON_ACTIVE_ACT_SHIFT (0U) +/*! ACT - Active flag for DMA channel n. Bit n corresponds to DMA channel n. The number of bits = + * number of DMA channels in this device. Other bits are reserved. 0 = not active. 1 = active. + */ +#define DMA_COMMON_ACTIVE_ACT(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ACTIVE_ACT_SHIFT)) & DMA_COMMON_ACTIVE_ACT_MASK) +/*! @} */ + +/* The count of DMA_COMMON_ACTIVE */ +#define DMA_COMMON_ACTIVE_COUNT (1U) + +/*! @name COMMON_BUSY - Channel Busy status for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_BUSY_BSY_MASK (0xFFFFFFFFU) +#define DMA_COMMON_BUSY_BSY_SHIFT (0U) +/*! BSY - Busy flag for DMA channel n. Bit n corresponds to DMA channel n. The number of bits = + * number of DMA channels in this device. Other bits are reserved. 0 = not busy. 1 = busy. + */ +#define DMA_COMMON_BUSY_BSY(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_BUSY_BSY_SHIFT)) & DMA_COMMON_BUSY_BSY_MASK) +/*! @} */ + +/* The count of DMA_COMMON_BUSY */ +#define DMA_COMMON_BUSY_COUNT (1U) + +/*! @name COMMON_ERRINT - Error Interrupt status for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_ERRINT_ERR_MASK (0xFFFFFFFFU) +#define DMA_COMMON_ERRINT_ERR_SHIFT (0U) +/*! ERR - Error Interrupt flag for DMA channel n. Bit n corresponds to DMA channel n. The number of + * bits = number of DMA channels in this device. Other bits are reserved. 0 = error interrupt is + * not active. 1 = error interrupt is active. + */ +#define DMA_COMMON_ERRINT_ERR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ERRINT_ERR_SHIFT)) & DMA_COMMON_ERRINT_ERR_MASK) +/*! @} */ + +/* The count of DMA_COMMON_ERRINT */ +#define DMA_COMMON_ERRINT_COUNT (1U) + +/*! @name COMMON_INTENSET - Interrupt Enable read and Set for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_INTENSET_INTEN_MASK (0xFFFFFFFFU) +#define DMA_COMMON_INTENSET_INTEN_SHIFT (0U) +/*! INTEN - Interrupt Enable read and set for DMA channel n. Bit n corresponds to DMA channel n. The + * number of bits = number of DMA channels in this device. Other bits are reserved. 0 = + * interrupt for DMA channel is disabled. 1 = interrupt for DMA channel is enabled. + */ +#define DMA_COMMON_INTENSET_INTEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENSET_INTEN_SHIFT)) & DMA_COMMON_INTENSET_INTEN_MASK) +/*! @} */ + +/* The count of DMA_COMMON_INTENSET */ +#define DMA_COMMON_INTENSET_COUNT (1U) + +/*! @name COMMON_INTENCLR - Interrupt Enable Clear for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_INTENCLR_CLR_MASK (0xFFFFFFFFU) +#define DMA_COMMON_INTENCLR_CLR_SHIFT (0U) +/*! CLR - Writing ones to this register clears corresponding bits in the INTENSET0. Bit n + * corresponds to DMA channel n. The number of bits = number of DMA channels in this device. Other bits are + * reserved. + */ +#define DMA_COMMON_INTENCLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENCLR_CLR_SHIFT)) & DMA_COMMON_INTENCLR_CLR_MASK) +/*! @} */ + +/* The count of DMA_COMMON_INTENCLR */ +#define DMA_COMMON_INTENCLR_COUNT (1U) + +/*! @name COMMON_INTA - Interrupt A status for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_INTA_IA_MASK (0xFFFFFFFFU) +#define DMA_COMMON_INTA_IA_SHIFT (0U) +/*! IA - Interrupt A status for DMA channel n. Bit n corresponds to DMA channel n. The number of + * bits = number of DMA channels in this device. Other bits are reserved. 0 = the DMA channel + * interrupt A is not active. 1 = the DMA channel interrupt A is active. + */ +#define DMA_COMMON_INTA_IA(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTA_IA_SHIFT)) & DMA_COMMON_INTA_IA_MASK) +/*! @} */ + +/* The count of DMA_COMMON_INTA */ +#define DMA_COMMON_INTA_COUNT (1U) + +/*! @name COMMON_INTB - Interrupt B status for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_INTB_IB_MASK (0xFFFFFFFFU) +#define DMA_COMMON_INTB_IB_SHIFT (0U) +/*! IB - Interrupt B status for DMA channel n. Bit n corresponds to DMA channel n. The number of + * bits = number of DMA channels in this device. Other bits are reserved. 0 = the DMA channel + * interrupt B is not active. 1 = the DMA channel interrupt B is active. + */ +#define DMA_COMMON_INTB_IB(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTB_IB_SHIFT)) & DMA_COMMON_INTB_IB_MASK) +/*! @} */ + +/* The count of DMA_COMMON_INTB */ +#define DMA_COMMON_INTB_COUNT (1U) + +/*! @name COMMON_SETVALID - Set ValidPending control bits for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_SETVALID_SV_MASK (0xFFFFFFFFU) +#define DMA_COMMON_SETVALID_SV_SHIFT (0U) +/*! SV - SETVALID control for DMA channel n. Bit n corresponds to DMA channel n. The number of bits + * = number of DMA channels in this device. Other bits are reserved. 0 = no effect. 1 = sets the + * VALIDPENDING control bit for DMA channel n + */ +#define DMA_COMMON_SETVALID_SV(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETVALID_SV_SHIFT)) & DMA_COMMON_SETVALID_SV_MASK) +/*! @} */ + +/* The count of DMA_COMMON_SETVALID */ +#define DMA_COMMON_SETVALID_COUNT (1U) + +/*! @name COMMON_SETTRIG - Set Trigger control bits for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_SETTRIG_TRIG_MASK (0xFFFFFFFFU) +#define DMA_COMMON_SETTRIG_TRIG_SHIFT (0U) +/*! TRIG - Set Trigger control bit for DMA channel 0. Bit n corresponds to DMA channel n. The number + * of bits = number of DMA channels in this device. Other bits are reserved. 0 = no effect. 1 = + * sets the TRIG bit for DMA channel n. + */ +#define DMA_COMMON_SETTRIG_TRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETTRIG_TRIG_SHIFT)) & DMA_COMMON_SETTRIG_TRIG_MASK) +/*! @} */ + +/* The count of DMA_COMMON_SETTRIG */ +#define DMA_COMMON_SETTRIG_COUNT (1U) + +/*! @name COMMON_ABORT - Channel Abort control for all DMA channels. */ +/*! @{ */ +#define DMA_COMMON_ABORT_ABORTCTRL_MASK (0xFFFFFFFFU) +#define DMA_COMMON_ABORT_ABORTCTRL_SHIFT (0U) +/*! ABORTCTRL - Abort control for DMA channel 0. Bit n corresponds to DMA channel n. 0 = no effect. + * 1 = aborts DMA operations on channel n. + */ +#define DMA_COMMON_ABORT_ABORTCTRL(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ABORT_ABORTCTRL_SHIFT)) & DMA_COMMON_ABORT_ABORTCTRL_MASK) +/*! @} */ + +/* The count of DMA_COMMON_ABORT */ +#define DMA_COMMON_ABORT_COUNT (1U) + +/*! @name CHANNEL_CFG - Configuration register for DMA channel . */ +/*! @{ */ +#define DMA_CHANNEL_CFG_PERIPHREQEN_MASK (0x1U) +#define DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT (0U) +/*! PERIPHREQEN - Peripheral request Enable. If a DMA channel is used to perform a memory-to-memory + * move, any peripheral DMA request associated with that channel can be disabled to prevent any + * interaction between the peripheral and the DMA controller. + * 0b0..Disabled. Peripheral DMA requests are disabled. + * 0b1..Enabled. Peripheral DMA requests are enabled. + */ +#define DMA_CHANNEL_CFG_PERIPHREQEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT)) & DMA_CHANNEL_CFG_PERIPHREQEN_MASK) +#define DMA_CHANNEL_CFG_HWTRIGEN_MASK (0x2U) +#define DMA_CHANNEL_CFG_HWTRIGEN_SHIFT (1U) +/*! HWTRIGEN - Hardware Triggering Enable for this channel. + * 0b0..Disabled. Hardware triggering is not used. + * 0b1..Enabled. Use hardware triggering. + */ +#define DMA_CHANNEL_CFG_HWTRIGEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_HWTRIGEN_SHIFT)) & DMA_CHANNEL_CFG_HWTRIGEN_MASK) +#define DMA_CHANNEL_CFG_TRIGPOL_MASK (0x10U) +#define DMA_CHANNEL_CFG_TRIGPOL_SHIFT (4U) +/*! TRIGPOL - Trigger Polarity. Selects the polarity of a hardware trigger for this channel. + * 0b0..Active low - falling edge. Hardware trigger is active low or falling edge triggered, based on TRIGTYPE. + * 0b1..Active high - rising edge. Hardware trigger is active high or rising edge triggered, based on TRIGTYPE. + */ +#define DMA_CHANNEL_CFG_TRIGPOL(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGPOL_SHIFT)) & DMA_CHANNEL_CFG_TRIGPOL_MASK) +#define DMA_CHANNEL_CFG_TRIGTYPE_MASK (0x20U) +#define DMA_CHANNEL_CFG_TRIGTYPE_SHIFT (5U) +/*! TRIGTYPE - Trigger Type. Selects hardware trigger as edge triggered or level triggered. + * 0b0..Edge. Hardware trigger is edge triggered. Transfers will be initiated and completed, as specified for a single trigger. + * 0b1..Level. Hardware trigger is level triggered. Note that when level triggering without burst (BURSTPOWER = + * 0) is selected, only hardware triggers should be used on that channel. Transfers continue as long as the + * trigger level is asserted. Once the trigger is de-asserted, the transfer will be paused until the trigger + * is, again, asserted. However, the transfer will not be paused until any remaining transfers within the + * current BURSTPOWER length are completed. + */ +#define DMA_CHANNEL_CFG_TRIGTYPE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGTYPE_SHIFT)) & DMA_CHANNEL_CFG_TRIGTYPE_MASK) +#define DMA_CHANNEL_CFG_TRIGBURST_MASK (0x40U) +#define DMA_CHANNEL_CFG_TRIGBURST_SHIFT (6U) +/*! TRIGBURST - Trigger Burst. Selects whether hardware triggers cause a single or burst transfer. + * 0b0..Single transfer. Hardware trigger causes a single transfer. + * 0b1..Burst transfer. When the trigger for this channel is set to edge triggered, a hardware trigger causes a + * burst transfer, as defined by BURSTPOWER. When the trigger for this channel is set to level triggered, a + * hardware trigger causes transfers to continue as long as the trigger is asserted, unless the transfer is + * complete. + */ +#define DMA_CHANNEL_CFG_TRIGBURST(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGBURST_SHIFT)) & DMA_CHANNEL_CFG_TRIGBURST_MASK) +#define DMA_CHANNEL_CFG_BURSTPOWER_MASK (0xF00U) +#define DMA_CHANNEL_CFG_BURSTPOWER_SHIFT (8U) +/*! BURSTPOWER - Burst Power is used in two ways. It always selects the address wrap size when + * SRCBURSTWRAP and/or DSTBURSTWRAP modes are selected (see descriptions elsewhere in this register). + * When the TRIGBURST field elsewhere in this register = 1, Burst Power selects how many + * transfers are performed for each DMA trigger. This can be used, for example, with peripherals that + * contain a FIFO that can initiate a DMA operation when the FIFO reaches a certain level. 0000: + * Burst size = 1 (20). 0001: Burst size = 2 (21). 0010: Burst size = 4 (22). 1010: Burst size = + * 1024 (210). This corresponds to the maximum supported transfer count. others: not supported. The + * total transfer length as defined in the XFERCOUNT bits in the XFERCFG register must be an even + * multiple of the burst size. + */ +#define DMA_CHANNEL_CFG_BURSTPOWER(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_BURSTPOWER_SHIFT)) & DMA_CHANNEL_CFG_BURSTPOWER_MASK) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK (0x4000U) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT (14U) +/*! SRCBURSTWRAP - Source Burst Wrap. When enabled, the source data address for the DMA is + * 'wrapped', meaning that the source address range for each burst will be the same. As an example, this + * could be used to read several sequential registers from a peripheral for each DMA burst, + * reading the same registers again for each burst. + * 0b0..Disabled. Source burst wrapping is not enabled for this DMA channel. + * 0b1..Enabled. Source burst wrapping is enabled for this DMA channel. + */ +#define DMA_CHANNEL_CFG_SRCBURSTWRAP(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK (0x8000U) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT (15U) +/*! DSTBURSTWRAP - Destination Burst Wrap. When enabled, the destination data address for the DMA is + * 'wrapped', meaning that the destination address range for each burst will be the same. As an + * example, this could be used to write several sequential registers to a peripheral for each DMA + * burst, writing the same registers again for each burst. + * 0b0..Disabled. Destination burst wrapping is not enabled for this DMA channel. + * 0b1..Enabled. Destination burst wrapping is enabled for this DMA channel. + */ +#define DMA_CHANNEL_CFG_DSTBURSTWRAP(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK) +#define DMA_CHANNEL_CFG_CHPRIORITY_MASK (0x70000U) +#define DMA_CHANNEL_CFG_CHPRIORITY_SHIFT (16U) +/*! CHPRIORITY - Priority of this channel when multiple DMA requests are pending. Eight priority + * levels are supported: 0x0 = highest priority. 0x7 = lowest priority. + */ +#define DMA_CHANNEL_CFG_CHPRIORITY(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_CHPRIORITY_SHIFT)) & DMA_CHANNEL_CFG_CHPRIORITY_MASK) +/*! @} */ + +/* The count of DMA_CHANNEL_CFG */ +#define DMA_CHANNEL_CFG_COUNT (20U) + +/*! @name CHANNEL_CTLSTAT - Control and status register for DMA channel . */ +/*! @{ */ +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK (0x1U) +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT (0U) +/*! VALIDPENDING - Valid pending flag for this channel. This bit is set when a 1 is written to the + * corresponding bit in the related SETVALID register when CFGVALID = 1 for the same channel. + * 0b0..No effect. No effect on DMA operation. + * 0b1..Valid pending. + */ +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT)) & DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK) +#define DMA_CHANNEL_CTLSTAT_TRIG_MASK (0x4U) +#define DMA_CHANNEL_CTLSTAT_TRIG_SHIFT (2U) +/*! TRIG - Trigger flag. Indicates that the trigger for this channel is currently set. This bit is + * cleared at the end of an entire transfer or upon reload when CLRTRIG = 1. + * 0b0..Not triggered. The trigger for this DMA channel is not set. DMA operations will not be carried out. + * 0b1..Triggered. The trigger for this DMA channel is set. DMA operations will be carried out. + */ +#define DMA_CHANNEL_CTLSTAT_TRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_TRIG_SHIFT)) & DMA_CHANNEL_CTLSTAT_TRIG_MASK) +/*! @} */ + +/* The count of DMA_CHANNEL_CTLSTAT */ +#define DMA_CHANNEL_CTLSTAT_COUNT (20U) + +/*! @name CHANNEL_XFERCFG - Transfer configuration register for DMA channel . */ +/*! @{ */ +#define DMA_CHANNEL_XFERCFG_CFGVALID_MASK (0x1U) +#define DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT (0U) +/*! CFGVALID - Configuration Valid flag. This bit indicates whether the current channel descriptor + * is valid and can potentially be acted upon, if all other activation criteria are fulfilled. + * 0b0..Not valid. The channel descriptor is not considered valid until validated by an associated SETVALID0 setting. + * 0b1..Valid. The current channel descriptor is considered valid. + */ +#define DMA_CHANNEL_XFERCFG_CFGVALID(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT)) & DMA_CHANNEL_XFERCFG_CFGVALID_MASK) +#define DMA_CHANNEL_XFERCFG_RELOAD_MASK (0x2U) +#define DMA_CHANNEL_XFERCFG_RELOAD_SHIFT (1U) +/*! RELOAD - Indicates whether the channel's control structure will be reloaded when the current + * descriptor is exhausted. Reloading allows ping-pong and linked transfers. + * 0b0..Disabled. Do not reload the channels' control structure when the current descriptor is exhausted. + * 0b1..Enabled. Reload the channels' control structure when the current descriptor is exhausted. + */ +#define DMA_CHANNEL_XFERCFG_RELOAD(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_RELOAD_SHIFT)) & DMA_CHANNEL_XFERCFG_RELOAD_MASK) +#define DMA_CHANNEL_XFERCFG_SWTRIG_MASK (0x4U) +#define DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT (2U) +/*! SWTRIG - Software Trigger. + * 0b0..Not set. When written by software, the trigger for this channel is not set. A new trigger, as defined by + * the HWTRIGEN, TRIGPOL, and TRIGTYPE will be needed to start the channel. + * 0b1..Set. When written by software, the trigger for this channel is set immediately. This feature should not + * be used with level triggering when TRIGBURST = 0. + */ +#define DMA_CHANNEL_XFERCFG_SWTRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_SWTRIG_MASK) +#define DMA_CHANNEL_XFERCFG_CLRTRIG_MASK (0x8U) +#define DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT (3U) +/*! CLRTRIG - Clear Trigger. + * 0b0..Not cleared. The trigger is not cleared when this descriptor is exhausted. If there is a reload, the next descriptor will be started. + * 0b1..Cleared. The trigger is cleared when this descriptor is exhausted + */ +#define DMA_CHANNEL_XFERCFG_CLRTRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_CLRTRIG_MASK) +#define DMA_CHANNEL_XFERCFG_SETINTA_MASK (0x10U) +#define DMA_CHANNEL_XFERCFG_SETINTA_SHIFT (4U) +/*! SETINTA - Set Interrupt flag A for this channel. There is no hardware distinction between + * interrupt A and B. They can be used by software to assist with more complex descriptor usage. By + * convention, interrupt A may be used when only one interrupt flag is needed. + * 0b0..No effect. + * 0b1..Set. The INTA flag for this channel will be set when the current descriptor is exhausted. + */ +#define DMA_CHANNEL_XFERCFG_SETINTA(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTA_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTA_MASK) +#define DMA_CHANNEL_XFERCFG_SETINTB_MASK (0x20U) +#define DMA_CHANNEL_XFERCFG_SETINTB_SHIFT (5U) +/*! SETINTB - Set Interrupt flag B for this channel. There is no hardware distinction between + * interrupt A and B. They can be used by software to assist with more complex descriptor usage. By + * convention, interrupt A may be used when only one interrupt flag is needed. + * 0b0..No effect. + * 0b1..Set. The INTB flag for this channel will be set when the current descriptor is exhausted. + */ +#define DMA_CHANNEL_XFERCFG_SETINTB(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTB_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTB_MASK) +#define DMA_CHANNEL_XFERCFG_WIDTH_MASK (0x300U) +#define DMA_CHANNEL_XFERCFG_WIDTH_SHIFT (8U) +/*! WIDTH - Transfer width used for this DMA channel. + * 0b00..8-bit. 8-bit transfers are performed (8-bit source reads and destination writes). + * 0b01..16-bit. 6-bit transfers are performed (16-bit source reads and destination writes). + * 0b10..32-bit. 32-bit transfers are performed (32-bit source reads and destination writes). + * 0b11..Reserved. Reserved setting, do not use. + */ +#define DMA_CHANNEL_XFERCFG_WIDTH(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_WIDTH_SHIFT)) & DMA_CHANNEL_XFERCFG_WIDTH_MASK) +#define DMA_CHANNEL_XFERCFG_SRCINC_MASK (0x3000U) +#define DMA_CHANNEL_XFERCFG_SRCINC_SHIFT (12U) +/*! SRCINC - Determines whether the source address is incremented for each DMA transfer. + * 0b00..No increment. The source address is not incremented for each transfer. This is the usual case when the source is a peripheral device. + * 0b01..1 x width. The source address is incremented by the amount specified by Width for each transfer. This is + * the usual case when the source is memory. + * 0b10..2 x width. The source address is incremented by 2 times the amount specified by Width for each transfer. + * 0b11..4 x width. The source address is incremented by 4 times the amount specified by Width for each transfer. + */ +#define DMA_CHANNEL_XFERCFG_SRCINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SRCINC_SHIFT)) & DMA_CHANNEL_XFERCFG_SRCINC_MASK) +#define DMA_CHANNEL_XFERCFG_DSTINC_MASK (0xC000U) +#define DMA_CHANNEL_XFERCFG_DSTINC_SHIFT (14U) +/*! DSTINC - Determines whether the destination address is incremented for each DMA transfer. + * 0b00..No increment. The destination address is not incremented for each transfer. This is the usual case when + * the destination is a peripheral device. + * 0b01..1 x width. The destination address is incremented by the amount specified by Width for each transfer. + * This is the usual case when the destination is memory. + * 0b10..2 x width. The destination address is incremented by 2 times the amount specified by Width for each transfer. + * 0b11..4 x width. The destination address is incremented by 4 times the amount specified by Width for each transfer. + */ +#define DMA_CHANNEL_XFERCFG_DSTINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_DSTINC_SHIFT)) & DMA_CHANNEL_XFERCFG_DSTINC_MASK) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK (0x3FF0000U) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT (16U) +/*! XFERCOUNT - Total number of transfers to be performed, minus 1 encoded. The number of bytes + * transferred is: (XFERCOUNT + 1) x data width (as defined by the WIDTH field). The DMA controller + * uses this bit field during transfer to count down. Hence, it cannot be used by software to read + * back the size of the transfer, for instance, in an interrupt handler. 0x0 = a total of 1 + * transfer will be performed. 0x1 = a total of 2 transfers will be performed. 0x3FF = a total of + * 1,024 transfers will be performed. + */ +#define DMA_CHANNEL_XFERCFG_XFERCOUNT(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT)) & DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK) +/*! @} */ + +/* The count of DMA_CHANNEL_XFERCFG */ +#define DMA_CHANNEL_XFERCFG_COUNT (20U) + + +/*! + * @} + */ /* end of group DMA_Register_Masks */ + + +/* DMA - Peripheral instance base addresses */ +/** Peripheral DMA0 base address */ +#define DMA0_BASE (0x40082000u) +/** Peripheral DMA0 base pointer */ +#define DMA0 ((DMA_Type *)DMA0_BASE) +/** Array initializer of DMA peripheral base addresses */ +#define DMA_BASE_ADDRS { DMA0_BASE } +/** Array initializer of DMA peripheral base pointers */ +#define DMA_BASE_PTRS { DMA0 } +/** Interrupt vectors for the DMA peripheral type */ +#define DMA_IRQS { DMA0_IRQn } + +/*! + * @} + */ /* end of group DMA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMIC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMIC_Peripheral_Access_Layer DMIC Peripheral Access Layer + * @{ + */ + +/** DMIC - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x100 */ + __IO uint32_t OSR; /**< Oversample Rate register 0, array offset: 0x0, array step: 0x100 */ + __IO uint32_t DIVHFCLK; /**< DMIC Clock Register 0, array offset: 0x4, array step: 0x100 */ + __IO uint32_t PREAC2FSCOEF; /**< Pre-Emphasis Filter Coefficient for 2 FS register, array offset: 0x8, array step: 0x100 */ + __IO uint32_t PREAC4FSCOEF; /**< Pre-Emphasis Filter Coefficient for 4 FS register, array offset: 0xC, array step: 0x100 */ + __IO uint32_t GAINSHIFT; /**< Decimator Gain Shift register, array offset: 0x10, array step: 0x100 */ + uint8_t RESERVED_0[108]; + __IO uint32_t FIFO_CTRL; /**< FIFO Control register 0, array offset: 0x80, array step: 0x100 */ + __IO uint32_t FIFO_STATUS; /**< FIFO Status register 0, array offset: 0x84, array step: 0x100 */ + __IO uint32_t FIFO_DATA; /**< FIFO Data Register 0, array offset: 0x88, array step: 0x100 */ + __IO uint32_t PHY_CTRL; /**< PDM Source Configuration register 0, array offset: 0x8C, array step: 0x100 */ + __IO uint32_t DC_CTRL; /**< DC Control register 0, array offset: 0x90, array step: 0x100 */ + uint8_t RESERVED_1[108]; + } CHANNEL[2]; + uint8_t RESERVED_0[3328]; + __IO uint32_t CHANEN; /**< Channel Enable register, offset: 0xF00 */ + uint8_t RESERVED_1[8]; + __IO uint32_t IOCFG; /**< I/O Configuration register, offset: 0xF0C */ + __IO uint32_t USE2FS; /**< Use 2FS register, offset: 0xF10 */ + uint8_t RESERVED_2[108]; + __IO uint32_t HWVADGAIN; /**< HWVAD input gain register, offset: 0xF80 */ + __IO uint32_t HWVADHPFS; /**< HWVAD filter control register, offset: 0xF84 */ + __IO uint32_t HWVADST10; /**< HWVAD control register, offset: 0xF88 */ + __IO uint32_t HWVADRSTT; /**< HWVAD filter reset register, offset: 0xF8C */ + __IO uint32_t HWVADTHGN; /**< HWVAD noise estimator gain register, offset: 0xF90 */ + __IO uint32_t HWVADTHGS; /**< HWVAD signal estimator gain register, offset: 0xF94 */ + __I uint32_t HWVADLOWZ; /**< HWVAD noise envelope estimator register, offset: 0xF98 */ + uint8_t RESERVED_3[96]; + __I uint32_t ID; /**< Module Identification register, offset: 0xFFC */ +} DMIC_Type; + +/* ---------------------------------------------------------------------------- + -- DMIC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMIC_Register_Masks DMIC Register Masks + * @{ + */ + +/*! @name CHANNEL_OSR - Oversample Rate register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_OSR_OSR_MASK (0xFFU) +#define DMIC_CHANNEL_OSR_OSR_SHIFT (0U) +/*! OSR - Selects the oversample rate for the related input channel. + */ +#define DMIC_CHANNEL_OSR_OSR(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_OSR_OSR_SHIFT)) & DMIC_CHANNEL_OSR_OSR_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_OSR */ +#define DMIC_CHANNEL_OSR_COUNT (2U) + +/*! @name CHANNEL_DIVHFCLK - DMIC Clock Register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_DIVHFCLK_PDMDIV_MASK (0xFU) +#define DMIC_CHANNEL_DIVHFCLK_PDMDIV_SHIFT (0U) +/*! PDMDIV - PDM clock divider value. 0 = divide by 1 1 = divide by 2 2 = divide by 3 3 = divide by + * 4 4 = divide by 6 5 = divide by 8 6 = divide by 12 7 = divide by 16 8 = divide by 24 9 = + * divide by 32 10 = divide by 48 11 = divide by 64 12 = divide by 96 13 = divide by 128 others = + * reserved. + */ +#define DMIC_CHANNEL_DIVHFCLK_PDMDIV(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DIVHFCLK_PDMDIV_SHIFT)) & DMIC_CHANNEL_DIVHFCLK_PDMDIV_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_DIVHFCLK */ +#define DMIC_CHANNEL_DIVHFCLK_COUNT (2U) + +/*! @name CHANNEL_PREAC2FSCOEF - Pre-Emphasis Filter Coefficient for 2 FS register */ +/*! @{ */ +#define DMIC_CHANNEL_PREAC2FSCOEF_COMP_MASK (0x3U) +#define DMIC_CHANNEL_PREAC2FSCOEF_COMP_SHIFT (0U) +/*! COMP - Pre-emphasis filer coefficient for 2 FS mode. 0 = Compensation = 0 1 = Compensation = 16 + * 2 = Compensation = 15 3 = Compensation = 13 + */ +#define DMIC_CHANNEL_PREAC2FSCOEF_COMP(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PREAC2FSCOEF_COMP_SHIFT)) & DMIC_CHANNEL_PREAC2FSCOEF_COMP_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_PREAC2FSCOEF */ +#define DMIC_CHANNEL_PREAC2FSCOEF_COUNT (2U) + +/*! @name CHANNEL_PREAC4FSCOEF - Pre-Emphasis Filter Coefficient for 4 FS register */ +/*! @{ */ +#define DMIC_CHANNEL_PREAC4FSCOEF_COMP_MASK (0x3U) +#define DMIC_CHANNEL_PREAC4FSCOEF_COMP_SHIFT (0U) +/*! COMP - Pre-emphasis filer coefficient for 4 FS mode. 0 = Compensation = 0 1 = Compensation = 16 + * 2 = Compensation = 15 3 = Compensation = 13 + */ +#define DMIC_CHANNEL_PREAC4FSCOEF_COMP(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PREAC4FSCOEF_COMP_SHIFT)) & DMIC_CHANNEL_PREAC4FSCOEF_COMP_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_PREAC4FSCOEF */ +#define DMIC_CHANNEL_PREAC4FSCOEF_COUNT (2U) + +/*! @name CHANNEL_GAINSHIFT - Decimator Gain Shift register */ +/*! @{ */ +#define DMIC_CHANNEL_GAINSHIFT_GAIN_MASK (0x3FU) +#define DMIC_CHANNEL_GAINSHIFT_GAIN_SHIFT (0U) +/*! GAIN - Gain control, as a positive or negative (two's complement) number of bits to shift. + */ +#define DMIC_CHANNEL_GAINSHIFT_GAIN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_GAINSHIFT_GAIN_SHIFT)) & DMIC_CHANNEL_GAINSHIFT_GAIN_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_GAINSHIFT */ +#define DMIC_CHANNEL_GAINSHIFT_COUNT (2U) + +/*! @name CHANNEL_FIFO_CTRL - FIFO Control register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_FIFO_CTRL_ENABLE_MASK (0x1U) +#define DMIC_CHANNEL_FIFO_CTRL_ENABLE_SHIFT (0U) +/*! ENABLE - FIFO enable. + * 0b0..FIFO is not enabled. Enabling a DMIC channel with the FIFO disabled could be useful while data is being + * streamed to the I2S, or in order to avoid a filter settling delay when a channel is re-enabled after a + * period when the data was not needed. + * 0b1..FIFO is enabled. The FIFO must be enabled in order for the CPU or DMA to read data from the DMIC via the FIFODATA register. + */ +#define DMIC_CHANNEL_FIFO_CTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_ENABLE_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_ENABLE_MASK) +#define DMIC_CHANNEL_FIFO_CTRL_RESETN_MASK (0x2U) +#define DMIC_CHANNEL_FIFO_CTRL_RESETN_SHIFT (1U) +/*! RESETN - FIFO reset. + * 0b0..Reset the FIFO. + * 0b1..Normal operation + */ +#define DMIC_CHANNEL_FIFO_CTRL_RESETN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_RESETN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_RESETN_MASK) +#define DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK (0x4U) +#define DMIC_CHANNEL_FIFO_CTRL_INTEN_SHIFT (2U) +/*! INTEN - Interrupt enable. + * 0b0..FIFO level interrupts are not enabled. + * 0b1..FIFO level interrupts are enabled. + */ +#define DMIC_CHANNEL_FIFO_CTRL_INTEN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_INTEN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK) +#define DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK (0x8U) +#define DMIC_CHANNEL_FIFO_CTRL_DMAEN_SHIFT (3U) +/*! DMAEN - DMA enable + * 0b0..DMA requests are not enabled. + * 0b1..DMA requests based on FIFO level are enabled. + */ +#define DMIC_CHANNEL_FIFO_CTRL_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_DMAEN_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK) +#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_MASK (0x1F0000U) +#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_SHIFT (16U) +/*! TRIGLVL - FIFO trigger level. Selects the data trigger level for interrupt or DMA operation. If + * enabled to do so, the FIFO level can wake up the device just enough to perform DMA, then + * return to the reduced power mode See Section 4.5.66 'Hardware Wake-up control register'. 0 = + * trigger when the FIFO has received one entry (is no longer empty). 1 = trigger when the FIFO has + * received two entries. 15 = trigger when the FIFO has received 16 entries (has become full). + */ +#define DMIC_CHANNEL_FIFO_CTRL_TRIGLVL(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_SHIFT)) & DMIC_CHANNEL_FIFO_CTRL_TRIGLVL_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_FIFO_CTRL */ +#define DMIC_CHANNEL_FIFO_CTRL_COUNT (2U) + +/*! @name CHANNEL_FIFO_STATUS - FIFO Status register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_FIFO_STATUS_INT_MASK (0x1U) +#define DMIC_CHANNEL_FIFO_STATUS_INT_SHIFT (0U) +/*! INT - Interrupt flag. Asserted when FIFO data reaches the level specified in the FIFOCTRL + * register. Writing a one to this bit clears the flag. Remark: note that the bus clock to the DMIC + * subsystem must be running in order for an interrupt to occur. + */ +#define DMIC_CHANNEL_FIFO_STATUS_INT(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_INT_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_INT_MASK) +#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN_MASK (0x2U) +#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN_SHIFT (1U) +/*! OVERRUN - Overrun flag. Indicates that a FIFO overflow has occurred at some point. Writing a one + * to this bit clears the flag. This flag does not cause an interrupt. + */ +#define DMIC_CHANNEL_FIFO_STATUS_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_OVERRUN_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_OVERRUN_MASK) +#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_MASK (0x4U) +#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_SHIFT (2U) +/*! UNDERRUN - Underrun flag. Indicates that a FIFO underflow has occurred at some point. Writing a one to this bit clears the flag. + */ +#define DMIC_CHANNEL_FIFO_STATUS_UNDERRUN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_SHIFT)) & DMIC_CHANNEL_FIFO_STATUS_UNDERRUN_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_FIFO_STATUS */ +#define DMIC_CHANNEL_FIFO_STATUS_COUNT (2U) + +/*! @name CHANNEL_FIFO_DATA - FIFO Data Register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_FIFO_DATA_DATA_MASK (0xFFFFFFU) +#define DMIC_CHANNEL_FIFO_DATA_DATA_SHIFT (0U) +/*! DATA - Data from the top of the input filter FIFO. + */ +#define DMIC_CHANNEL_FIFO_DATA_DATA(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_FIFO_DATA_DATA_SHIFT)) & DMIC_CHANNEL_FIFO_DATA_DATA_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_FIFO_DATA */ +#define DMIC_CHANNEL_FIFO_DATA_COUNT (2U) + +/*! @name CHANNEL_PHY_CTRL - PDM Source Configuration register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL_MASK (0x1U) +#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL_SHIFT (0U) +/*! PHY_FALL - Capture PDM_DATA + * 0b0..Capture PDM_DATA on the rising edge of PDM_CLK. + * 0b1..Capture PDM_DATA on the falling edge of PDM_CLK. + */ +#define DMIC_CHANNEL_PHY_CTRL_PHY_FALL(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PHY_CTRL_PHY_FALL_SHIFT)) & DMIC_CHANNEL_PHY_CTRL_PHY_FALL_MASK) +#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF_MASK (0x2U) +#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF_SHIFT (1U) +/*! PHY_HALF - Half rate sampling + * 0b0..Standard half rate sampling. The clock to the DMIC is sent at the same rate as the decimator is providing. + * 0b1..Use half rate sampling. The clock to the DMIC is sent at half the rate as the decimator is providing. + */ +#define DMIC_CHANNEL_PHY_CTRL_PHY_HALF(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_PHY_CTRL_PHY_HALF_SHIFT)) & DMIC_CHANNEL_PHY_CTRL_PHY_HALF_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_PHY_CTRL */ +#define DMIC_CHANNEL_PHY_CTRL_COUNT (2U) + +/*! @name CHANNEL_DC_CTRL - DC Control register 0 */ +/*! @{ */ +#define DMIC_CHANNEL_DC_CTRL_DCPOLE_MASK (0x3U) +#define DMIC_CHANNEL_DC_CTRL_DCPOLE_SHIFT (0U) +/*! DCPOLE - DC block filter + * 0b00..Flat response, no filter. + * 0b01..155 Hz. + * 0b10..78 Hz. + * 0b11..39 Hz + */ +#define DMIC_CHANNEL_DC_CTRL_DCPOLE(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_DCPOLE_SHIFT)) & DMIC_CHANNEL_DC_CTRL_DCPOLE_MASK) +#define DMIC_CHANNEL_DC_CTRL_DCGAIN_MASK (0xF0U) +#define DMIC_CHANNEL_DC_CTRL_DCGAIN_SHIFT (4U) +/*! DCGAIN - Fine gain adjustment in the form of a number of bits to downshift. + */ +#define DMIC_CHANNEL_DC_CTRL_DCGAIN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_DCGAIN_SHIFT)) & DMIC_CHANNEL_DC_CTRL_DCGAIN_MASK) +#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_MASK (0x100U) +#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_SHIFT (8U) +/*! SATURATEAT16BIT - Selects 16-bit saturation. + * 0b0..Results roll over if out range and do not saturate. + * 0b1..If the result overflows, it saturates at 0xFFFF for positive overflow and 0x8000 for negative overflow. + */ +#define DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_SHIFT)) & DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT_MASK) +/*! @} */ + +/* The count of DMIC_CHANNEL_DC_CTRL */ +#define DMIC_CHANNEL_DC_CTRL_COUNT (2U) + +/*! @name CHANEN - Channel Enable register */ +/*! @{ */ +#define DMIC_CHANEN_EN_CH0_MASK (0x1U) +#define DMIC_CHANEN_EN_CH0_SHIFT (0U) +/*! EN_CH0 - Enable channel 0. When 1, PDM channel 0 is enabled. + */ +#define DMIC_CHANEN_EN_CH0(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANEN_EN_CH0_SHIFT)) & DMIC_CHANEN_EN_CH0_MASK) +#define DMIC_CHANEN_EN_CH1_MASK (0x2U) +#define DMIC_CHANEN_EN_CH1_SHIFT (1U) +/*! EN_CH1 - Enable channel 1. When 1, PDM channel 1 is enabled. + */ +#define DMIC_CHANEN_EN_CH1(x) (((uint32_t)(((uint32_t)(x)) << DMIC_CHANEN_EN_CH1_SHIFT)) & DMIC_CHANEN_EN_CH1_MASK) +/*! @} */ + +/*! @name IOCFG - I/O Configuration register */ +/*! @{ */ +#define DMIC_IOCFG_CLK_BYPASS0_MASK (0x1U) +#define DMIC_IOCFG_CLK_BYPASS0_SHIFT (0U) +/*! CLK_BYPASS0 - Bypass CLK0. When 1, PDM_DATA1 becomes the clock for PDM channel 0. This provides + * for the possibility of an external codec taking over the PDM bus. + */ +#define DMIC_IOCFG_CLK_BYPASS0(x) (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_CLK_BYPASS0_SHIFT)) & DMIC_IOCFG_CLK_BYPASS0_MASK) +#define DMIC_IOCFG_CLK_BYPASS1_MASK (0x2U) +#define DMIC_IOCFG_CLK_BYPASS1_SHIFT (1U) +/*! CLK_BYPASS1 - Bypass CLK1. When 1, PDM_DATA1 becomes the clock for PDM channel 1. This provides + * for the possibility of an external codec taking over the PDM bus. + */ +#define DMIC_IOCFG_CLK_BYPASS1(x) (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_CLK_BYPASS1_SHIFT)) & DMIC_IOCFG_CLK_BYPASS1_MASK) +#define DMIC_IOCFG_STEREO_DATA0_MASK (0x4U) +#define DMIC_IOCFG_STEREO_DATA0_SHIFT (2U) +/*! STEREO_DATA0 - Stereo PDM select. When 1, PDM_DATA0 is routed to both PDM channels in a + * configuration that supports a single stereo digital microphone. + */ +#define DMIC_IOCFG_STEREO_DATA0(x) (((uint32_t)(((uint32_t)(x)) << DMIC_IOCFG_STEREO_DATA0_SHIFT)) & DMIC_IOCFG_STEREO_DATA0_MASK) +/*! @} */ + +/*! @name USE2FS - Use 2FS register */ +/*! @{ */ +#define DMIC_USE2FS_USE2FS_MASK (0x1U) +#define DMIC_USE2FS_USE2FS_SHIFT (0U) +/*! USE2FS - Use 2FS register + * 0b0..Use 1FS output for PCM data. + * 0b1..Use 2FS output for PCM data. + */ +#define DMIC_USE2FS_USE2FS(x) (((uint32_t)(((uint32_t)(x)) << DMIC_USE2FS_USE2FS_SHIFT)) & DMIC_USE2FS_USE2FS_MASK) +/*! @} */ + +/*! @name HWVADGAIN - HWVAD input gain register */ +/*! @{ */ +#define DMIC_HWVADGAIN_INPUTGAIN_MASK (0xFU) +#define DMIC_HWVADGAIN_INPUTGAIN_SHIFT (0U) +/*! INPUTGAIN - Shift value for input bits 0x00 -10 bits 0x01 -8 bits 0x02 -6 bits 0x03 -4 bits 0x04 + * -2 bits 0x05 0 bits (default) 0x06 +2 bits 0x07 +4 bits 0x08 +6 bits 0x09 +8 bits 0x0A +10 + * bits 0x0B +12 bits 0x0C +14 bits 0x0D to 0x0F Reserved. + */ +#define DMIC_HWVADGAIN_INPUTGAIN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADGAIN_INPUTGAIN_SHIFT)) & DMIC_HWVADGAIN_INPUTGAIN_MASK) +/*! @} */ + +/*! @name HWVADHPFS - HWVAD filter control register */ +/*! @{ */ +#define DMIC_HWVADHPFS_HPFS_MASK (0x3U) +#define DMIC_HWVADHPFS_HPFS_SHIFT (0U) +/*! HPFS - High pass filter + * 0b00..First filter by-pass. + * 0b01..High pass filter with -3dB cut-off at 1750Hz. + * 0b10..High pass filter with -3dB cut-off at 215Hz. + * 0b11..Reserved. + */ +#define DMIC_HWVADHPFS_HPFS(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADHPFS_HPFS_SHIFT)) & DMIC_HWVADHPFS_HPFS_MASK) +/*! @} */ + +/*! @name HWVADST10 - HWVAD control register */ +/*! @{ */ +#define DMIC_HWVADST10_ST10_MASK (0x1U) +#define DMIC_HWVADST10_ST10_SHIFT (0U) +/*! ST10 - Stage 0 + * 0b0..Normal operation, waiting for HWVAD trigger event (stage 0). + * 0b1..Reset internal interrupt flag by writing a '1' pulse. + */ +#define DMIC_HWVADST10_ST10(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADST10_ST10_SHIFT)) & DMIC_HWVADST10_ST10_MASK) +/*! @} */ + +/*! @name HWVADRSTT - HWVAD filter reset register */ +/*! @{ */ +#define DMIC_HWVADRSTT_RSTT_MASK (0x1U) +#define DMIC_HWVADRSTT_RSTT_SHIFT (0U) +/*! RSTT - Writing a 1 resets all filter values + */ +#define DMIC_HWVADRSTT_RSTT(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADRSTT_RSTT_SHIFT)) & DMIC_HWVADRSTT_RSTT_MASK) +/*! @} */ + +/*! @name HWVADTHGN - HWVAD noise estimator gain register */ +/*! @{ */ +#define DMIC_HWVADTHGN_THGN_MASK (0xFU) +#define DMIC_HWVADTHGN_THGN_SHIFT (0U) +/*! THGN - Gain value for the noise estimator. Values 0 to 14. 0 corresponds to a gain of 1. + */ +#define DMIC_HWVADTHGN_THGN(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADTHGN_THGN_SHIFT)) & DMIC_HWVADTHGN_THGN_MASK) +/*! @} */ + +/*! @name HWVADTHGS - HWVAD signal estimator gain register */ +/*! @{ */ +#define DMIC_HWVADTHGS_THGS_MASK (0xFU) +#define DMIC_HWVADTHGS_THGS_SHIFT (0U) +/*! THGS - Gain value for the signal estimator. Values 0 to 14. 0 corresponds to a gain of 1. + */ +#define DMIC_HWVADTHGS_THGS(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADTHGS_THGS_SHIFT)) & DMIC_HWVADTHGS_THGS_MASK) +/*! @} */ + +/*! @name HWVADLOWZ - HWVAD noise envelope estimator register */ +/*! @{ */ +#define DMIC_HWVADLOWZ_LOWZ_MASK (0xFFFFU) +#define DMIC_HWVADLOWZ_LOWZ_SHIFT (0U) +/*! LOWZ - Noise envelope estimator value. + */ +#define DMIC_HWVADLOWZ_LOWZ(x) (((uint32_t)(((uint32_t)(x)) << DMIC_HWVADLOWZ_LOWZ_SHIFT)) & DMIC_HWVADLOWZ_LOWZ_MASK) +/*! @} */ + +/*! @name ID - Module Identification register */ +/*! @{ */ +#define DMIC_ID_ID_MASK (0xFFFFFFFFU) +#define DMIC_ID_ID_SHIFT (0U) +/*! ID - Indicates module ID and the number of channels in this DMIC interface. + */ +#define DMIC_ID_ID(x) (((uint32_t)(((uint32_t)(x)) << DMIC_ID_ID_SHIFT)) & DMIC_ID_ID_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group DMIC_Register_Masks */ + + +/* DMIC - Peripheral instance base addresses */ +/** Peripheral DMIC0 base address */ +#define DMIC0_BASE (0x40090000u) +/** Peripheral DMIC0 base pointer */ +#define DMIC0 ((DMIC_Type *)DMIC0_BASE) +/** Array initializer of DMIC peripheral base addresses */ +#define DMIC_BASE_ADDRS { DMIC0_BASE } +/** Array initializer of DMIC peripheral base pointers */ +#define DMIC_BASE_PTRS { DMIC0 } +/** Interrupt vectors for the DMIC peripheral type */ +#define DMIC_IRQS { DMIC0_IRQn } +#define DMIC_HWVAD_IRQS { HWVAD0_IRQn } + +/*! + * @} + */ /* end of group DMIC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FLEXCOMM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FLEXCOMM_Peripheral_Access_Layer FLEXCOMM Peripheral Access Layer + * @{ + */ + +/** FLEXCOMM - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[4088]; + __IO uint32_t PSELID; /**< Peripheral Select and Flexcomm ID register., offset: 0xFF8 */ + __I uint32_t PID; /**< Peripheral identification register., offset: 0xFFC */ +} FLEXCOMM_Type; + +/* ---------------------------------------------------------------------------- + -- FLEXCOMM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FLEXCOMM_Register_Masks FLEXCOMM Register Masks + * @{ + */ + +/*! @name PSELID - Peripheral Select and Flexcomm ID register. */ +/*! @{ */ +#define FLEXCOMM_PSELID_PERSEL_MASK (0x7U) +#define FLEXCOMM_PSELID_PERSEL_SHIFT (0U) +/*! PERSEL - Peripheral Select. This field is writable by software. + * 0b000..No peripheral selected. + * 0b001..USART function selected. + * 0b010..SPI function selected. + * 0b011..I2C function selected. + * 0b100..I2S transmit function selected. + * 0b101..I2S receive function selected. + * 0b110..Reserved + * 0b111..Reserved + */ +#define FLEXCOMM_PSELID_PERSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_PERSEL_SHIFT)) & FLEXCOMM_PSELID_PERSEL_MASK) +#define FLEXCOMM_PSELID_LOCK_MASK (0x8U) +#define FLEXCOMM_PSELID_LOCK_SHIFT (3U) +/*! LOCK - Lock the peripheral select. This field is writable by software. + * 0b0..Peripheral select can be changed by software. + * 0b1..Peripheral select is locked and cannot be changed until this Flexcomm or the entire device is reset. + */ +#define FLEXCOMM_PSELID_LOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_LOCK_SHIFT)) & FLEXCOMM_PSELID_LOCK_MASK) +#define FLEXCOMM_PSELID_USARTPRESENT_MASK (0x10U) +#define FLEXCOMM_PSELID_USARTPRESENT_SHIFT (4U) +/*! USARTPRESENT - USART present indicator. This field is Read-only. + * 0b0..This Flexcomm does not include the USART function. + * 0b1..This Flexcomm includes the USART function. + */ +#define FLEXCOMM_PSELID_USARTPRESENT(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_USARTPRESENT_SHIFT)) & FLEXCOMM_PSELID_USARTPRESENT_MASK) +#define FLEXCOMM_PSELID_SPIPRESENT_MASK (0x20U) +#define FLEXCOMM_PSELID_SPIPRESENT_SHIFT (5U) +/*! SPIPRESENT - SPI present indicator. This field is Read-only. + * 0b0..This Flexcomm does not include the SPI function. + * 0b1..This Flexcomm includes the SPI function. + */ +#define FLEXCOMM_PSELID_SPIPRESENT(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_SPIPRESENT_SHIFT)) & FLEXCOMM_PSELID_SPIPRESENT_MASK) +#define FLEXCOMM_PSELID_I2CPRESENT_MASK (0x40U) +#define FLEXCOMM_PSELID_I2CPRESENT_SHIFT (6U) +/*! I2CPRESENT - I2C present indicator. This field is Read-only. + * 0b0..This Flexcomm does not include the I2C function. + * 0b1..This Flexcomm includes the I2C function. + */ +#define FLEXCOMM_PSELID_I2CPRESENT(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_I2CPRESENT_SHIFT)) & FLEXCOMM_PSELID_I2CPRESENT_MASK) +#define FLEXCOMM_PSELID_I2SPRESENT_MASK (0x80U) +#define FLEXCOMM_PSELID_I2SPRESENT_SHIFT (7U) +/*! I2SPRESENT - I 2S present indicator. This field is Read-only. + * 0b0..This Flexcomm does not include the I2S function. + * 0b1..This Flexcomm includes the I2S function. + */ +#define FLEXCOMM_PSELID_I2SPRESENT(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_I2SPRESENT_SHIFT)) & FLEXCOMM_PSELID_I2SPRESENT_MASK) +#define FLEXCOMM_PSELID_ID_MASK (0xFFFFF000U) +#define FLEXCOMM_PSELID_ID_SHIFT (12U) +/*! ID - Flexcomm ID. + */ +#define FLEXCOMM_PSELID_ID(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PSELID_ID_SHIFT)) & FLEXCOMM_PSELID_ID_MASK) +/*! @} */ + +/*! @name PID - Peripheral identification register. */ +/*! @{ */ +#define FLEXCOMM_PID_Minor_Rev_MASK (0xF00U) +#define FLEXCOMM_PID_Minor_Rev_SHIFT (8U) +/*! Minor_Rev - Minor revision of module implementation. + */ +#define FLEXCOMM_PID_Minor_Rev(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_Minor_Rev_SHIFT)) & FLEXCOMM_PID_Minor_Rev_MASK) +#define FLEXCOMM_PID_Major_Rev_MASK (0xF000U) +#define FLEXCOMM_PID_Major_Rev_SHIFT (12U) +/*! Major_Rev - Major revision of module implementation. + */ +#define FLEXCOMM_PID_Major_Rev(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_Major_Rev_SHIFT)) & FLEXCOMM_PID_Major_Rev_MASK) +#define FLEXCOMM_PID_ID_MASK (0xFFFF0000U) +#define FLEXCOMM_PID_ID_SHIFT (16U) +/*! ID - Module identifier for the selected function. + */ +#define FLEXCOMM_PID_ID(x) (((uint32_t)(((uint32_t)(x)) << FLEXCOMM_PID_ID_SHIFT)) & FLEXCOMM_PID_ID_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group FLEXCOMM_Register_Masks */ + + +/* FLEXCOMM - Peripheral instance base addresses */ +/** Peripheral FLEXCOMM0 base address */ +#define FLEXCOMM0_BASE (0x40086000u) +/** Peripheral FLEXCOMM0 base pointer */ +#define FLEXCOMM0 ((FLEXCOMM_Type *)FLEXCOMM0_BASE) +/** Peripheral FLEXCOMM1 base address */ +#define FLEXCOMM1_BASE (0x40087000u) +/** Peripheral FLEXCOMM1 base pointer */ +#define FLEXCOMM1 ((FLEXCOMM_Type *)FLEXCOMM1_BASE) +/** Peripheral FLEXCOMM2 base address */ +#define FLEXCOMM2_BASE (0x40088000u) +/** Peripheral FLEXCOMM2 base pointer */ +#define FLEXCOMM2 ((FLEXCOMM_Type *)FLEXCOMM2_BASE) +/** Peripheral FLEXCOMM3 base address */ +#define FLEXCOMM3_BASE (0x40089000u) +/** Peripheral FLEXCOMM3 base pointer */ +#define FLEXCOMM3 ((FLEXCOMM_Type *)FLEXCOMM3_BASE) +/** Peripheral FLEXCOMM4 base address */ +#define FLEXCOMM4_BASE (0x4008A000u) +/** Peripheral FLEXCOMM4 base pointer */ +#define FLEXCOMM4 ((FLEXCOMM_Type *)FLEXCOMM4_BASE) +/** Peripheral FLEXCOMM5 base address */ +#define FLEXCOMM5_BASE (0x40096000u) +/** Peripheral FLEXCOMM5 base pointer */ +#define FLEXCOMM5 ((FLEXCOMM_Type *)FLEXCOMM5_BASE) +/** Peripheral FLEXCOMM6 base address */ +#define FLEXCOMM6_BASE (0x40097000u) +/** Peripheral FLEXCOMM6 base pointer */ +#define FLEXCOMM6 ((FLEXCOMM_Type *)FLEXCOMM6_BASE) +/** Peripheral FLEXCOMM7 base address */ +#define FLEXCOMM7_BASE (0x40098000u) +/** Peripheral FLEXCOMM7 base pointer */ +#define FLEXCOMM7 ((FLEXCOMM_Type *)FLEXCOMM7_BASE) +/** Array initializer of FLEXCOMM peripheral base addresses */ +#define FLEXCOMM_BASE_ADDRS { FLEXCOMM0_BASE, FLEXCOMM1_BASE, FLEXCOMM2_BASE, FLEXCOMM3_BASE, FLEXCOMM4_BASE, FLEXCOMM5_BASE, FLEXCOMM6_BASE, FLEXCOMM7_BASE } +/** Array initializer of FLEXCOMM peripheral base pointers */ +#define FLEXCOMM_BASE_PTRS { FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7 } +/** Interrupt vectors for the FLEXCOMM peripheral type */ +#define FLEXCOMM_IRQS { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn, FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM4_IRQn, FLEXCOMM5_IRQn, FLEXCOMM6_IRQn, FLEXCOMM7_IRQn } + +/*! + * @} + */ /* end of group FLEXCOMM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GINT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GINT_Peripheral_Access_Layer GINT Peripheral Access Layer + * @{ + */ + +/** GINT - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< GPIO grouped interrupt control register, offset: 0x0 */ + uint8_t RESERVED_0[28]; + __IO uint32_t PORT_POL[2]; /**< GPIO grouped interrupt port 0 polarity register, array offset: 0x20, array step: 0x4 */ + uint8_t RESERVED_1[24]; + __IO uint32_t PORT_ENA[2]; /**< GPIO grouped interrupt port 0 enable register, array offset: 0x40, array step: 0x4 */ +} GINT_Type; + +/* ---------------------------------------------------------------------------- + -- GINT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GINT_Register_Masks GINT Register Masks + * @{ + */ + +/*! @name CTRL - GPIO grouped interrupt control register */ +/*! @{ */ +#define GINT_CTRL_INT_MASK (0x1U) +#define GINT_CTRL_INT_SHIFT (0U) +/*! INT - Group interrupt status. This bit is cleared by writing a one to it. Writing zero has no effect. + * 0b0..No request. No interrupt request is pending. + * 0b1..Request active. Interrupt request is active. + */ +#define GINT_CTRL_INT(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_INT_SHIFT)) & GINT_CTRL_INT_MASK) +#define GINT_CTRL_COMB_MASK (0x2U) +#define GINT_CTRL_COMB_SHIFT (1U) +/*! COMB - Combine enabled inputs for group interrupt + * 0b0..Or. OR functionality: A grouped interrupt is generated when any one of the enabled inputs is active (based on its programmed polarity). + * 0b1..And. AND functionality: An interrupt is generated when all enabled bits are active (based on their programmed polarity). + */ +#define GINT_CTRL_COMB(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_COMB_SHIFT)) & GINT_CTRL_COMB_MASK) +#define GINT_CTRL_TRIG_MASK (0x4U) +#define GINT_CTRL_TRIG_SHIFT (2U) +/*! TRIG - Group interrupt trigger + * 0b0..Edge-triggered. + * 0b1..Level-triggered. + */ +#define GINT_CTRL_TRIG(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_TRIG_SHIFT)) & GINT_CTRL_TRIG_MASK) +/*! @} */ + +/*! @name PORT_POL - GPIO grouped interrupt port 0 polarity register */ +/*! @{ */ +#define GINT_PORT_POL_POL_MASK (0xFFFFFFFFU) +#define GINT_PORT_POL_POL_SHIFT (0U) +/*! POL - Configure pin polarity of port m pins for group interrupt. Bit n corresponds to pin PIOm_n + * of port m. 0 = the pin is active LOW. If the level on this pin is LOW, the pin contributes to + * the group interrupt. 1 = the pin is active HIGH. If the level on this pin is HIGH, the pin + * contributes to the group interrupt. + */ +#define GINT_PORT_POL_POL(x) (((uint32_t)(((uint32_t)(x)) << GINT_PORT_POL_POL_SHIFT)) & GINT_PORT_POL_POL_MASK) +/*! @} */ + +/* The count of GINT_PORT_POL */ +#define GINT_PORT_POL_COUNT (2U) + +/*! @name PORT_ENA - GPIO grouped interrupt port 0 enable register */ +/*! @{ */ +#define GINT_PORT_ENA_ENA_MASK (0xFFFFFFFFU) +#define GINT_PORT_ENA_ENA_SHIFT (0U) +/*! ENA - Enable port 0 pin for group interrupt. Bit n corresponds to pin Pm_n of port m. 0 = the + * port 0 pin is disabled and does not contribute to the grouped interrupt. 1 = the port 0 pin is + * enabled and contributes to the grouped interrupt. + */ +#define GINT_PORT_ENA_ENA(x) (((uint32_t)(((uint32_t)(x)) << GINT_PORT_ENA_ENA_SHIFT)) & GINT_PORT_ENA_ENA_MASK) +/*! @} */ + +/* The count of GINT_PORT_ENA */ +#define GINT_PORT_ENA_COUNT (2U) + + +/*! + * @} + */ /* end of group GINT_Register_Masks */ + + +/* GINT - Peripheral instance base addresses */ +/** Peripheral GINT0 base address */ +#define GINT0_BASE (0x40002000u) +/** Peripheral GINT0 base pointer */ +#define GINT0 ((GINT_Type *)GINT0_BASE) +/** Peripheral GINT1 base address */ +#define GINT1_BASE (0x40003000u) +/** Peripheral GINT1 base pointer */ +#define GINT1 ((GINT_Type *)GINT1_BASE) +/** Array initializer of GINT peripheral base addresses */ +#define GINT_BASE_ADDRS { GINT0_BASE, GINT1_BASE } +/** Array initializer of GINT peripheral base pointers */ +#define GINT_BASE_PTRS { GINT0, GINT1 } +/** Interrupt vectors for the GINT peripheral type */ +#define GINT_IRQS { GINT0_IRQn, GINT1_IRQn } + +/*! + * @} + */ /* end of group GINT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GPIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer + * @{ + */ + +/** GPIO - Register Layout Typedef */ +typedef struct { + __IO uint8_t B[2][32]; /**< Byte pin registers for all port 0 and 1 GPIO pins, array offset: 0x0, array step: index*0x20, index2*0x1 */ + uint8_t RESERVED_0[4032]; + __IO uint32_t W[2][32]; /**< Word pin registers for all port 0 and 1 GPIO pins, array offset: 0x1000, array step: index*0x80, index2*0x4 */ + uint8_t RESERVED_1[3840]; + __IO uint32_t DIR[2]; /**< Direction registers, array offset: 0x2000, array step: 0x4 */ + uint8_t RESERVED_2[120]; + __IO uint32_t MASK[2]; /**< Mask register, array offset: 0x2080, array step: 0x4 */ + uint8_t RESERVED_3[120]; + __IO uint32_t PIN[2]; /**< Port pin register, array offset: 0x2100, array step: 0x4 */ + uint8_t RESERVED_4[120]; + __IO uint32_t MPIN[2]; /**< Masked port register, array offset: 0x2180, array step: 0x4 */ + uint8_t RESERVED_5[120]; + __IO uint32_t SET[2]; /**< Write: Set register for port Read: output bits for port, array offset: 0x2200, array step: 0x4 */ + uint8_t RESERVED_6[120]; + __O uint32_t CLR[2]; /**< Clear port, array offset: 0x2280, array step: 0x4 */ + uint8_t RESERVED_7[120]; + __O uint32_t NOT[2]; /**< Toggle port, array offset: 0x2300, array step: 0x4 */ + uint8_t RESERVED_8[120]; + __O uint32_t DIRSET[2]; /**< Set pin direction bits for port, array offset: 0x2380, array step: 0x4 */ + uint8_t RESERVED_9[120]; + __O uint32_t DIRCLR[2]; /**< Clear pin direction bits for port, array offset: 0x2400, array step: 0x4 */ + uint8_t RESERVED_10[120]; + __O uint32_t DIRNOT[2]; /**< Toggle pin direction bits for port, array offset: 0x2480, array step: 0x4 */ +} GPIO_Type; + +/* ---------------------------------------------------------------------------- + -- GPIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Register_Masks GPIO Register Masks + * @{ + */ + +/*! @name B - Byte pin registers for all port 0 and 1 GPIO pins */ +/*! @{ */ +#define GPIO_B_PBYTE_MASK (0x1U) +#define GPIO_B_PBYTE_SHIFT (0U) +/*! PBYTE - Read: state of the pin PIOm_n, regardless of direction, masking, or alternate function, + * except that pins configured as analog I/O always read as 0. One register for each port pin. + * Supported pins depends on the specific device and package. Write: loads the pin's output bit. + * One register for each port pin. Supported pins depends on the specific device and package. + */ +#define GPIO_B_PBYTE(x) (((uint8_t)(((uint8_t)(x)) << GPIO_B_PBYTE_SHIFT)) & GPIO_B_PBYTE_MASK) +/*! @} */ + +/* The count of GPIO_B */ +#define GPIO_B_COUNT (2U) + +/* The count of GPIO_B */ +#define GPIO_B_COUNT2 (32U) + +/*! @name W - Word pin registers for all port 0 and 1 GPIO pins */ +/*! @{ */ +#define GPIO_W_PWORD_MASK (0xFFFFFFFFU) +#define GPIO_W_PWORD_SHIFT (0U) +/*! PWORD - Read 0: pin PIOm_n is LOW. Write 0: clear output bit. Read 0xFFFF FFFF: pin PIOm_n is + * HIGH. Write any value 0x0000 0001 to 0xFFFF FFFF: set output bit. Only 0 or 0xFFFF FFFF can be + * read. Writing any value other than 0 will set the output bit. One register for each port pin. + * Supported pins depends on the specific device and package. + */ +#define GPIO_W_PWORD(x) (((uint32_t)(((uint32_t)(x)) << GPIO_W_PWORD_SHIFT)) & GPIO_W_PWORD_MASK) +/*! @} */ + +/* The count of GPIO_W */ +#define GPIO_W_COUNT (2U) + +/* The count of GPIO_W */ +#define GPIO_W_COUNT2 (32U) + +/*! @name DIR - Direction registers */ +/*! @{ */ +#define GPIO_DIR_DIRP_MASK (0xFFFFFFFFU) +#define GPIO_DIR_DIRP_SHIFT (0U) +/*! DIRP - Selects pin direction for pin PIOm_n (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported + * pins depends on the specific device and package. 0 = input. 1 = output. + */ +#define GPIO_DIR_DIRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_SHIFT)) & GPIO_DIR_DIRP_MASK) +/*! @} */ + +/* The count of GPIO_DIR */ +#define GPIO_DIR_COUNT (2U) + +/*! @name MASK - Mask register */ +/*! @{ */ +#define GPIO_MASK_MASKP_MASK (0xFFFFFFFFU) +#define GPIO_MASK_MASKP_SHIFT (0U) +/*! MASKP - Controls which bits corresponding to PIOm_n are active in the MPORT register (bit 0 = + * PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on the specific device and package. 0 = + * Read MPORT: pin state; write MPORT: load output bit. 1 = Read MPORT: 0; write MPORT: output bit + * not affected. + */ +#define GPIO_MASK_MASKP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_SHIFT)) & GPIO_MASK_MASKP_MASK) +/*! @} */ + +/* The count of GPIO_MASK */ +#define GPIO_MASK_COUNT (2U) + +/*! @name PIN - Port pin register */ +/*! @{ */ +#define GPIO_PIN_PORT_MASK (0xFFFFFFFFU) +#define GPIO_PIN_PORT_SHIFT (0U) +/*! PORT - Reads pin states or loads output bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported + * pins depends on the specific device and package. 0 = Read: pin is low; write: clear output bit. + * 1 = Read: pin is high; write: set output bit. + */ +#define GPIO_PIN_PORT(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_SHIFT)) & GPIO_PIN_PORT_MASK) +/*! @} */ + +/* The count of GPIO_PIN */ +#define GPIO_PIN_COUNT (2U) + +/*! @name MPIN - Masked port register */ +/*! @{ */ +#define GPIO_MPIN_MPORTP_MASK (0xFFFFFFFFU) +#define GPIO_MPIN_MPORTP_SHIFT (0U) +/*! MPORTP - Masked port register (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on + * the specific device and package. 0 = Read: pin is LOW and/or the corresponding bit in the MASK + * register is 1; write: clear output bit if the corresponding bit in the MASK register is 0. 1 + * = Read: pin is HIGH and the corresponding bit in the MASK register is 0; write: set output bit + * if the corresponding bit in the MASK register is 0. + */ +#define GPIO_MPIN_MPORTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORTP_SHIFT)) & GPIO_MPIN_MPORTP_MASK) +/*! @} */ + +/* The count of GPIO_MPIN */ +#define GPIO_MPIN_COUNT (2U) + +/*! @name SET - Write: Set register for port Read: output bits for port */ +/*! @{ */ +#define GPIO_SET_SETP_MASK (0xFFFFFFFFU) +#define GPIO_SET_SETP_SHIFT (0U) +/*! SETP - Read or set output bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on + * the specific device and package. 0 = Read: output bit: write: no operation. 1 = Read: output + * bit; write: set output bit. + */ +#define GPIO_SET_SETP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_SHIFT)) & GPIO_SET_SETP_MASK) +/*! @} */ + +/* The count of GPIO_SET */ +#define GPIO_SET_COUNT (2U) + +/*! @name CLR - Clear port */ +/*! @{ */ +#define GPIO_CLR_CLRP_MASK (0xFFFFFFFFU) +#define GPIO_CLR_CLRP_SHIFT (0U) +/*! CLRP - Clear output bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on the + * specific device and package. 0 = No operation. 1 = Clear output bit. + */ +#define GPIO_CLR_CLRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_SHIFT)) & GPIO_CLR_CLRP_MASK) +/*! @} */ + +/* The count of GPIO_CLR */ +#define GPIO_CLR_COUNT (2U) + +/*! @name NOT - Toggle port */ +/*! @{ */ +#define GPIO_NOT_NOTP_MASK (0xFFFFFFFFU) +#define GPIO_NOT_NOTP_SHIFT (0U) +/*! NOTP - Toggle output bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on the + * specific device and package. 0 = no operation. 1 = Toggle output bit. + */ +#define GPIO_NOT_NOTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_SHIFT)) & GPIO_NOT_NOTP_MASK) +/*! @} */ + +/* The count of GPIO_NOT */ +#define GPIO_NOT_COUNT (2U) + +/*! @name DIRSET - Set pin direction bits for port */ +/*! @{ */ +#define GPIO_DIRSET_DIRSETP_MASK (0x1FFFFFFFU) +#define GPIO_DIRSET_DIRSETP_SHIFT (0U) +/*! DIRSETP - Set direction bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on + * the specific device and package. 0 = No operation. 1 = Set direction bit. + */ +#define GPIO_DIRSET_DIRSETP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_SHIFT)) & GPIO_DIRSET_DIRSETP_MASK) +/*! @} */ + +/* The count of GPIO_DIRSET */ +#define GPIO_DIRSET_COUNT (2U) + +/*! @name DIRCLR - Clear pin direction bits for port */ +/*! @{ */ +#define GPIO_DIRCLR_DIRCLRP_MASK (0x1FFFFFFFU) +#define GPIO_DIRCLR_DIRCLRP_SHIFT (0U) +/*! DIRCLRP - Clear direction bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends on + * the specific device and package. 0 = No operation. 1 = Clear direction bit. + */ +#define GPIO_DIRCLR_DIRCLRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_SHIFT)) & GPIO_DIRCLR_DIRCLRP_MASK) +/*! @} */ + +/* The count of GPIO_DIRCLR */ +#define GPIO_DIRCLR_COUNT (2U) + +/*! @name DIRNOT - Toggle pin direction bits for port */ +/*! @{ */ +#define GPIO_DIRNOT_DIRNOTP_MASK (0x1FFFFFFFU) +#define GPIO_DIRNOT_DIRNOTP_SHIFT (0U) +/*! DIRNOTP - Toggle direction bits (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins depends + * on the specific device and package. 0 = no operation. 1 = Toggle direction bit. + */ +#define GPIO_DIRNOT_DIRNOTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_SHIFT)) & GPIO_DIRNOT_DIRNOTP_MASK) +/*! @} */ + +/* The count of GPIO_DIRNOT */ +#define GPIO_DIRNOT_COUNT (2U) + + +/*! + * @} + */ /* end of group GPIO_Register_Masks */ + + +/* GPIO - Peripheral instance base addresses */ +/** Peripheral GPIO base address */ +#define GPIO_BASE (0x4008C000u) +/** Peripheral GPIO base pointer */ +#define GPIO ((GPIO_Type *)GPIO_BASE) +/** Array initializer of GPIO peripheral base addresses */ +#define GPIO_BASE_ADDRS { GPIO_BASE } +/** Array initializer of GPIO peripheral base pointers */ +#define GPIO_BASE_PTRS { GPIO } + +/*! + * @} + */ /* end of group GPIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2C Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer + * @{ + */ + +/** I2C - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[2048]; + __IO uint32_t CFG; /**< Configuration for shared functions., offset: 0x800 */ + __IO uint32_t STAT; /**< Status register for Master, Slave, and Monitor functions., offset: 0x804 */ + __IO uint32_t INTENSET; /**< Interrupt Enable Set and read register., offset: 0x808 */ + __O uint32_t INTENCLR; /**< Interrupt Enable Clear register., offset: 0x80C */ + __IO uint32_t TIMEOUT; /**< Time-out value register., offset: 0x810 */ + __IO uint32_t CLKDIV; /**< Clock pre-divider for the entire I2C interface. This determines what time increments are used for the MSTTIME register, and controls some timing of the Slave function., offset: 0x814 */ + __I uint32_t INTSTAT; /**< Interrupt Status register for Master, Slave, and Monitor functions., offset: 0x818 */ + uint8_t RESERVED_1[4]; + __IO uint32_t MSTCTL; /**< Master control register., offset: 0x820 */ + __IO uint32_t MSTTIME; /**< Master timing configuration., offset: 0x824 */ + __IO uint32_t MSTDAT; /**< Combined Master receiver and transmitter data register., offset: 0x828 */ + uint8_t RESERVED_2[20]; + __IO uint32_t SLVCTL; /**< Slave control register., offset: 0x840 */ + __IO uint32_t SLVDAT; /**< Combined Slave receiver and transmitter data register., offset: 0x844 */ + __IO uint32_t SLVADR[4]; /**< Slave address register., array offset: 0x848, array step: 0x4 */ + __IO uint32_t SLVQUAL0; /**< Slave Qualification for address 0., offset: 0x858 */ + uint8_t RESERVED_3[36]; + __I uint32_t MONRXDAT; /**< Monitor receiver data register., offset: 0x880 */ +} I2C_Type; + +/* ---------------------------------------------------------------------------- + -- I2C Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Register_Masks I2C Register Masks + * @{ + */ + +/*! @name CFG - Configuration for shared functions. */ +/*! @{ */ +#define I2C_CFG_MSTEN_MASK (0x1U) +#define I2C_CFG_MSTEN_SHIFT (0U) +/*! MSTEN - Master Enable. When disabled, configurations settings for the Master function are not + * changed, but the Master function is internally reset. + * 0b0..Disabled. The I2C Master function is disabled. + * 0b1..Enabled. The I2C Master function is enabled. + */ +#define I2C_CFG_MSTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MSTEN_SHIFT)) & I2C_CFG_MSTEN_MASK) +#define I2C_CFG_SLVEN_MASK (0x2U) +#define I2C_CFG_SLVEN_SHIFT (1U) +/*! SLVEN - Slave Enable. When disabled, configurations settings for the Slave function are not + * changed, but the Slave function is internally reset. + * 0b0..Disabled. The I2C slave function is disabled. + * 0b1..Enabled. The I2C slave function is enabled. + */ +#define I2C_CFG_SLVEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_SLVEN_SHIFT)) & I2C_CFG_SLVEN_MASK) +#define I2C_CFG_MONEN_MASK (0x4U) +#define I2C_CFG_MONEN_SHIFT (2U) +/*! MONEN - Monitor Enable. When disabled, configurations settings for the Monitor function are not + * changed, but the Monitor function is internally reset. + * 0b0..Disabled. The I2C Monitor function is disabled. + * 0b1..Enabled. The I2C Monitor function is enabled. + */ +#define I2C_CFG_MONEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONEN_SHIFT)) & I2C_CFG_MONEN_MASK) +#define I2C_CFG_TIMEOUTEN_MASK (0x8U) +#define I2C_CFG_TIMEOUTEN_SHIFT (3U) +/*! TIMEOUTEN - I2C bus Time-out Enable. When disabled, the time-out function is internally reset. + * 0b0..Disabled. Time-out function is disabled. + * 0b1..Enabled. Time-out function is enabled. Both types of time-out flags will be generated and will cause + * interrupts if they are enabled. Typically, only one time-out will be used in a system. + */ +#define I2C_CFG_TIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_TIMEOUTEN_SHIFT)) & I2C_CFG_TIMEOUTEN_MASK) +#define I2C_CFG_MONCLKSTR_MASK (0x10U) +#define I2C_CFG_MONCLKSTR_SHIFT (4U) +/*! MONCLKSTR - Monitor function Clock Stretching. + * 0b0..Disabled. The Monitor function will not perform clock stretching. Software or DMA may not always be able + * to read data provided by the Monitor function before it is overwritten. This mode may be used when + * non-invasive monitoring is critical. + * 0b1..Enabled. The Monitor function will perform clock stretching in order to ensure that software or DMA can + * read all incoming data supplied by the Monitor function. + */ +#define I2C_CFG_MONCLKSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONCLKSTR_SHIFT)) & I2C_CFG_MONCLKSTR_MASK) +#define I2C_CFG_HSCAPABLE_MASK (0x20U) +#define I2C_CFG_HSCAPABLE_SHIFT (5U) +/*! HSCAPABLE - High-speed mode Capable enable. Since High Speed mode alters the way I2C pins drive + * and filter, as well as the timing for certain I2C signalling, enabling High-speed mode applies + * to all functions: Master, Slave, and Monitor. + * 0b0..Fast-mode plus. The I 2C interface will support Standard-mode, Fast-mode, and Fast-mode Plus, to the + * extent that the pin electronics support these modes. Any changes that need to be made to the pin controls, + * such as changing the drive strength or filtering, must be made by software via the IOCON register associated + * with each I2C pin, + * 0b1..High-speed. In addition to Standard-mode, Fast-mode, and Fast-mode Plus, the I 2C interface will support + * High-speed mode to the extent that the pin electronics support these modes. See Section 25.7.2.2 for more + * information. + */ +#define I2C_CFG_HSCAPABLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_HSCAPABLE_SHIFT)) & I2C_CFG_HSCAPABLE_MASK) +/*! @} */ + +/*! @name STAT - Status register for Master, Slave, and Monitor functions. */ +/*! @{ */ +#define I2C_STAT_MSTPENDING_MASK (0x1U) +#define I2C_STAT_MSTPENDING_SHIFT (0U) +/*! MSTPENDING - Master Pending. Indicates that the Master is waiting to continue communication on + * the I2C-bus (pending) or is idle. When the master is pending, the MSTSTATE bits indicate what + * type of software service if any the master expects. This flag will cause an interrupt when set + * if, enabled via the INTENSET register. The MSTPENDING flag is not set when the DMA is handling + * an event (if the MSTDMA bit in the MSTCTL register is set). If the master is in the idle + * state, and no communication is needed, mask this interrupt. + * 0b0..In progress. Communication is in progress and the Master function is busy and cannot currently accept a command. + * 0b1..Pending. The Master function needs software service or is in the idle state. If the master is not in the + * idle state, it is waiting to receive or transmit data or the NACK bit. + */ +#define I2C_STAT_MSTPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTPENDING_SHIFT)) & I2C_STAT_MSTPENDING_MASK) +#define I2C_STAT_MSTSTATE_MASK (0xEU) +#define I2C_STAT_MSTSTATE_SHIFT (1U) +/*! MSTSTATE - Master State code. The master state code reflects the master state when the + * MSTPENDING bit is set, that is the master is pending or in the idle state. Each value of this field + * indicates a specific required service for the Master function. All other values are reserved. See + * Table 400 for details of state values and appropriate responses. + * 0b000..Idle. The Master function is available to be used for a new transaction. + * 0b001..Receive ready. Received data available (Master Receiver mode). Address plus Read was previously sent and Acknowledged by slave. + * 0b010..Transmit ready. Data can be transmitted (Master Transmitter mode). Address plus Write was previously sent and Acknowledged by slave. + * 0b011..NACK Address. Slave NACKed address. + * 0b100..NACK Data. Slave NACKed transmitted data. + */ +#define I2C_STAT_MSTSTATE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTATE_SHIFT)) & I2C_STAT_MSTSTATE_MASK) +#define I2C_STAT_MSTARBLOSS_MASK (0x10U) +#define I2C_STAT_MSTARBLOSS_SHIFT (4U) +/*! MSTARBLOSS - Master Arbitration Loss flag. This flag can be cleared by software writing a 1 to + * this bit. It is also cleared automatically a 1 is written to MSTCONTINUE. + * 0b0..No Arbitration Loss has occurred. + * 0b1..Arbitration loss. The Master function has experienced an Arbitration Loss. At this point, the Master + * function has already stopped driving the bus and gone to an idle state. Software can respond by doing nothing, + * or by sending a Start in order to attempt to gain control of the bus when it next becomes idle. + */ +#define I2C_STAT_MSTARBLOSS(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTARBLOSS_SHIFT)) & I2C_STAT_MSTARBLOSS_MASK) +#define I2C_STAT_MSTSTSTPERR_MASK (0x40U) +#define I2C_STAT_MSTSTSTPERR_SHIFT (6U) +/*! MSTSTSTPERR - Master Start/Stop Error flag. This flag can be cleared by software writing a 1 to + * this bit. It is also cleared automatically a 1 is written to MSTCONTINUE. + * 0b0..No Start/Stop Error has occurred. + * 0b1..The Master function has experienced a Start/Stop Error. A Start or Stop was detected at a time when it is + * not allowed by the I2C specification. The Master interface has stopped driving the bus and gone to an + * idle state, no action is required. A request for a Start could be made, or software could attempt to insure + * that the bus has not stalled. + */ +#define I2C_STAT_MSTSTSTPERR(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTSTPERR_SHIFT)) & I2C_STAT_MSTSTSTPERR_MASK) +#define I2C_STAT_SLVPENDING_MASK (0x100U) +#define I2C_STAT_SLVPENDING_SHIFT (8U) +/*! SLVPENDING - Slave Pending. Indicates that the Slave function is waiting to continue + * communication on the I2C-bus and needs software service. This flag will cause an interrupt when set if + * enabled via INTENSET. The SLVPENDING flag is not set when the DMA is handling an event (if the + * SLVDMA bit in the SLVCTL register is set). The SLVPENDING flag is read-only and is + * automatically cleared when a 1 is written to the SLVCONTINUE bit in the SLVCTL register. The point in time + * when SlvPending is set depends on whether the I2C interface is in HSCAPABLE mode. See Section + * 25.7.2.2.2. When the I2C interface is configured to be HSCAPABLE, HS master codes are + * detected automatically. Due to the requirements of the HS I2C specification, slave addresses must + * also be detected automatically, since the address must be acknowledged before the clock can be + * stretched. + * 0b0..In progress. The Slave function does not currently need service. + * 0b1..Pending. The Slave function needs service. Information on what is needed can be found in the adjacent SLVSTATE field. + */ +#define I2C_STAT_SLVPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVPENDING_SHIFT)) & I2C_STAT_SLVPENDING_MASK) +#define I2C_STAT_SLVSTATE_MASK (0x600U) +#define I2C_STAT_SLVSTATE_SHIFT (9U) +/*! SLVSTATE - Slave State code. Each value of this field indicates a specific required service for + * the Slave function. All other values are reserved. See Table 401 for state values and actions. + * note that the occurrence of some states and how they are handled are affected by DMA mode and + * Automatic Operation modes. + * 0b00..Slave address. Address plus R/W received. At least one of the four slave addresses has been matched by hardware. + * 0b01..Slave receive. Received data is available (Slave Receiver mode). + * 0b10..Slave transmit. Data can be transmitted (Slave Transmitter mode). + */ +#define I2C_STAT_SLVSTATE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSTATE_SHIFT)) & I2C_STAT_SLVSTATE_MASK) +#define I2C_STAT_SLVNOTSTR_MASK (0x800U) +#define I2C_STAT_SLVNOTSTR_SHIFT (11U) +/*! SLVNOTSTR - Slave Not Stretching. Indicates when the slave function is stretching the I2C clock. + * This is needed in order to gracefully invoke Deep Sleep or Power-down modes during slave + * operation. This read-only flag reflects the slave function status in real time. + * 0b0..Stretching. The slave function is currently stretching the I2C bus clock. Deep-Sleep or Power-down mode cannot be entered at this time. + * 0b1..Not stretching. The slave function is not currently stretching the I 2C bus clock. Deep-sleep or + * Power-down mode could be entered at this time. + */ +#define I2C_STAT_SLVNOTSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVNOTSTR_SHIFT)) & I2C_STAT_SLVNOTSTR_MASK) +#define I2C_STAT_SLVIDX_MASK (0x3000U) +#define I2C_STAT_SLVIDX_SHIFT (12U) +/*! SLVIDX - Slave address match Index. This field is valid when the I2C slave function has been + * selected by receiving an address that matches one of the slave addresses defined by any enabled + * slave address registers, and provides an identification of the address that was matched. It is + * possible that more than one address could be matched, but only one match can be reported here. + * 0b00..Address 0. Slave address 0 was matched. + * 0b01..Address 1. Slave address 1 was matched. + * 0b10..Address 2. Slave address 2 was matched. + * 0b11..Address 3. Slave address 3 was matched. + */ +#define I2C_STAT_SLVIDX(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVIDX_SHIFT)) & I2C_STAT_SLVIDX_MASK) +#define I2C_STAT_SLVSEL_MASK (0x4000U) +#define I2C_STAT_SLVSEL_SHIFT (14U) +/*! SLVSEL - Slave selected flag. SLVSEL is set after an address match when software tells the Slave + * function to acknowledge the address, or when the address has been automatically acknowledged. + * It is cleared when another address cycle presents an address that does not match an enabled + * address on the Slave function, when slave software decides to NACK a matched address, when + * there is a Stop detected on the bus, when the master NACKs slave data, and in some combinations of + * Automatic Operation. SLVSEL is not cleared if software NACKs data. + * 0b0..Not selected. The Slave function is not currently selected. + * 0b1..Selected. The Slave function is currently selected. + */ +#define I2C_STAT_SLVSEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSEL_SHIFT)) & I2C_STAT_SLVSEL_MASK) +#define I2C_STAT_SLVDESEL_MASK (0x8000U) +#define I2C_STAT_SLVDESEL_SHIFT (15U) +/*! SLVDESEL - Slave Deselected flag. This flag will cause an interrupt when set if enabled via + * INTENSET. This flag can be cleared by writing a 1 to this bit. + * 0b0..Not deselected. The Slave function has not become deselected. This does not mean that it is currently + * selected. That information can be found in the SLVSEL flag. + * 0b1..Deselected. The Slave function has become deselected. This is specifically caused by the SLVSEL flag + * changing from 1 to 0. See the description of SLVSEL for details on when that event occurs. + */ +#define I2C_STAT_SLVDESEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVDESEL_SHIFT)) & I2C_STAT_SLVDESEL_MASK) +#define I2C_STAT_MONRDY_MASK (0x10000U) +#define I2C_STAT_MONRDY_SHIFT (16U) +/*! MONRDY - Monitor Ready. This flag is cleared when the MONRXDAT register is read. + * 0b0..No data. The Monitor function does not currently have data available. + * 0b1..Data waiting. The Monitor function has data waiting to be read. + */ +#define I2C_STAT_MONRDY(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONRDY_SHIFT)) & I2C_STAT_MONRDY_MASK) +#define I2C_STAT_MONOV_MASK (0x20000U) +#define I2C_STAT_MONOV_SHIFT (17U) +/*! MONOV - Monitor Overflow flag. + * 0b0..No overrun. Monitor data has not overrun. + * 0b1..Overrun. A Monitor data overrun has occurred. This can only happen when Monitor clock stretching not + * enabled via the MONCLKSTR bit in the CFG register. Writing 1 to this bit clears the flag. + */ +#define I2C_STAT_MONOV(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONOV_SHIFT)) & I2C_STAT_MONOV_MASK) +#define I2C_STAT_MONACTIVE_MASK (0x40000U) +#define I2C_STAT_MONACTIVE_SHIFT (18U) +/*! MONACTIVE - Monitor Active flag. Indicates when the Monitor function considers the I 2C bus to + * be active. Active is defined here as when some Master is on the bus: a bus Start has occurred + * more recently than a bus Stop. + * 0b0..Inactive. The Monitor function considers the I2C bus to be inactive. + * 0b1..Active. The Monitor function considers the I2C bus to be active. + */ +#define I2C_STAT_MONACTIVE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONACTIVE_SHIFT)) & I2C_STAT_MONACTIVE_MASK) +#define I2C_STAT_MONIDLE_MASK (0x80000U) +#define I2C_STAT_MONIDLE_SHIFT (19U) +/*! MONIDLE - Monitor Idle flag. This flag is set when the Monitor function sees the I2C bus change + * from active to inactive. This can be used by software to decide when to process data + * accumulated by the Monitor function. This flag will cause an interrupt when set if enabled via the + * INTENSET register. The flag can be cleared by writing a 1 to this bit. + * 0b0..Not idle. The I2C bus is not idle, or this flag has been cleared by software. + * 0b1..Idle. The I2C bus has gone idle at least once since the last time this flag was cleared by software. + */ +#define I2C_STAT_MONIDLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONIDLE_SHIFT)) & I2C_STAT_MONIDLE_MASK) +#define I2C_STAT_EVENTTIMEOUT_MASK (0x1000000U) +#define I2C_STAT_EVENTTIMEOUT_SHIFT (24U) +/*! EVENTTIMEOUT - Event Time-out Interrupt flag. Indicates when the time between events has been + * longer than the time specified by the TIMEOUT register. Events include Start, Stop, and clock + * edges. The flag is cleared by writing a 1 to this bit. No time-out is created when the I2C-bus + * is idle. + * 0b0..No time-out. I2C bus events have not caused a time-out. + * 0b1..Event time-out. The time between I2C bus events has been longer than the time specified by the TIMEOUT register. + */ +#define I2C_STAT_EVENTTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_EVENTTIMEOUT_SHIFT)) & I2C_STAT_EVENTTIMEOUT_MASK) +#define I2C_STAT_SCLTIMEOUT_MASK (0x2000000U) +#define I2C_STAT_SCLTIMEOUT_SHIFT (25U) +/*! SCLTIMEOUT - SCL Time-out Interrupt flag. Indicates when SCL has remained low longer than the + * time specific by the TIMEOUT register. The flag is cleared by writing a 1 to this bit. + * 0b0..No time-out. SCL low time has not caused a time-out. + * 0b1..Time-out. SCL low time has caused a time-out. + */ +#define I2C_STAT_SCLTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SCLTIMEOUT_SHIFT)) & I2C_STAT_SCLTIMEOUT_MASK) +/*! @} */ + +/*! @name INTENSET - Interrupt Enable Set and read register. */ +/*! @{ */ +#define I2C_INTENSET_MSTPENDINGEN_MASK (0x1U) +#define I2C_INTENSET_MSTPENDINGEN_SHIFT (0U) +/*! MSTPENDINGEN - Master Pending interrupt Enable. + * 0b0..Disabled. The MstPending interrupt is disabled. + * 0b1..Enabled. The MstPending interrupt is enabled. + */ +#define I2C_INTENSET_MSTPENDINGEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTPENDINGEN_SHIFT)) & I2C_INTENSET_MSTPENDINGEN_MASK) +#define I2C_INTENSET_MSTARBLOSSEN_MASK (0x10U) +#define I2C_INTENSET_MSTARBLOSSEN_SHIFT (4U) +/*! MSTARBLOSSEN - Master Arbitration Loss interrupt Enable. + * 0b0..Disabled. The MstArbLoss interrupt is disabled. + * 0b1..Enabled. The MstArbLoss interrupt is enabled. + */ +#define I2C_INTENSET_MSTARBLOSSEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTARBLOSSEN_SHIFT)) & I2C_INTENSET_MSTARBLOSSEN_MASK) +#define I2C_INTENSET_MSTSTSTPERREN_MASK (0x40U) +#define I2C_INTENSET_MSTSTSTPERREN_SHIFT (6U) +/*! MSTSTSTPERREN - Master Start/Stop Error interrupt Enable. + * 0b0..Disabled. The MstStStpErr interrupt is disabled. + * 0b1..Enabled. The MstStStpErr interrupt is enabled. + */ +#define I2C_INTENSET_MSTSTSTPERREN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTSTSTPERREN_SHIFT)) & I2C_INTENSET_MSTSTSTPERREN_MASK) +#define I2C_INTENSET_SLVPENDINGEN_MASK (0x100U) +#define I2C_INTENSET_SLVPENDINGEN_SHIFT (8U) +/*! SLVPENDINGEN - Slave Pending interrupt Enable. + * 0b0..Disabled. The SlvPending interrupt is disabled. + * 0b1..Enabled. The SlvPending interrupt is enabled. + */ +#define I2C_INTENSET_SLVPENDINGEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVPENDINGEN_SHIFT)) & I2C_INTENSET_SLVPENDINGEN_MASK) +#define I2C_INTENSET_SLVNOTSTREN_MASK (0x800U) +#define I2C_INTENSET_SLVNOTSTREN_SHIFT (11U) +/*! SLVNOTSTREN - Slave Not Stretching interrupt Enable. + * 0b0..Disabled. The SlvNotStr interrupt is disabled. + * 0b1..Enabled. The SlvNotStr interrupt is enabled. + */ +#define I2C_INTENSET_SLVNOTSTREN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVNOTSTREN_SHIFT)) & I2C_INTENSET_SLVNOTSTREN_MASK) +#define I2C_INTENSET_SLVDESELEN_MASK (0x8000U) +#define I2C_INTENSET_SLVDESELEN_SHIFT (15U) +/*! SLVDESELEN - Slave Deselect interrupt Enable. + * 0b0..Disabled. The SlvDeSel interrupt is disabled. + * 0b1..Enabled. The SlvDeSel interrupt is enabled. + */ +#define I2C_INTENSET_SLVDESELEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVDESELEN_SHIFT)) & I2C_INTENSET_SLVDESELEN_MASK) +#define I2C_INTENSET_MONRDYEN_MASK (0x10000U) +#define I2C_INTENSET_MONRDYEN_SHIFT (16U) +/*! MONRDYEN - Monitor data Ready interrupt Enable. + * 0b0..Disabled. The MonRdy interrupt is disabled. + * 0b1..Enabled. The MonRdy interrupt is enabled. + */ +#define I2C_INTENSET_MONRDYEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONRDYEN_SHIFT)) & I2C_INTENSET_MONRDYEN_MASK) +#define I2C_INTENSET_MONOVEN_MASK (0x20000U) +#define I2C_INTENSET_MONOVEN_SHIFT (17U) +/*! MONOVEN - Monitor Overrun interrupt Enable. + * 0b0..Disabled. The MonOv interrupt is disabled. + * 0b1..Enabled. The MonOv interrupt is enabled. + */ +#define I2C_INTENSET_MONOVEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONOVEN_SHIFT)) & I2C_INTENSET_MONOVEN_MASK) +#define I2C_INTENSET_MONIDLEEN_MASK (0x80000U) +#define I2C_INTENSET_MONIDLEEN_SHIFT (19U) +/*! MONIDLEEN - Monitor Idle interrupt Enable. + * 0b0..Disabled. The MonIdle interrupt is disabled. + * 0b1..Enabled. The MonIdle interrupt is enabled. + */ +#define I2C_INTENSET_MONIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONIDLEEN_SHIFT)) & I2C_INTENSET_MONIDLEEN_MASK) +#define I2C_INTENSET_EVENTTIMEOUTEN_MASK (0x1000000U) +#define I2C_INTENSET_EVENTTIMEOUTEN_SHIFT (24U) +/*! EVENTTIMEOUTEN - Event time-out interrupt Enable. + * 0b0..Disabled. The Event time-out interrupt is disabled. + * 0b1..Enabled. The Event time-out interrupt is enabled. + */ +#define I2C_INTENSET_EVENTTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_EVENTTIMEOUTEN_SHIFT)) & I2C_INTENSET_EVENTTIMEOUTEN_MASK) +#define I2C_INTENSET_SCLTIMEOUTEN_MASK (0x2000000U) +#define I2C_INTENSET_SCLTIMEOUTEN_SHIFT (25U) +/*! SCLTIMEOUTEN - SCL time-out interrupt Enable. + * 0b0..Disabled. The SCL time-out interrupt is disabled. + * 0b1..Enabled. The SCL time-out interrupt is enabled. + */ +#define I2C_INTENSET_SCLTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SCLTIMEOUTEN_SHIFT)) & I2C_INTENSET_SCLTIMEOUTEN_MASK) +/*! @} */ + +/*! @name INTENCLR - Interrupt Enable Clear register. */ +/*! @{ */ +#define I2C_INTENCLR_MSTPENDINGCLR_MASK (0x1U) +#define I2C_INTENCLR_MSTPENDINGCLR_SHIFT (0U) +/*! MSTPENDINGCLR - Master Pending interrupt clear. Writing 1 to this bit clears the corresponding + * bit in the INTENSET register if implemented. + */ +#define I2C_INTENCLR_MSTPENDINGCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTPENDINGCLR_SHIFT)) & I2C_INTENCLR_MSTPENDINGCLR_MASK) +#define I2C_INTENCLR_MSTARBLOSSCLR_MASK (0x10U) +#define I2C_INTENCLR_MSTARBLOSSCLR_SHIFT (4U) +/*! MSTARBLOSSCLR - Master Arbitration Loss interrupt clear. + */ +#define I2C_INTENCLR_MSTARBLOSSCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTARBLOSSCLR_SHIFT)) & I2C_INTENCLR_MSTARBLOSSCLR_MASK) +#define I2C_INTENCLR_MSTSTSTPERRCLR_MASK (0x40U) +#define I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT (6U) +/*! MSTSTSTPERRCLR - Master Start/Stop Error interrupt clear. + */ +#define I2C_INTENCLR_MSTSTSTPERRCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT)) & I2C_INTENCLR_MSTSTSTPERRCLR_MASK) +#define I2C_INTENCLR_SLVPENDINGCLR_MASK (0x100U) +#define I2C_INTENCLR_SLVPENDINGCLR_SHIFT (8U) +/*! SLVPENDINGCLR - Slave Pending interrupt clear. + */ +#define I2C_INTENCLR_SLVPENDINGCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVPENDINGCLR_SHIFT)) & I2C_INTENCLR_SLVPENDINGCLR_MASK) +#define I2C_INTENCLR_SLVNOTSTRCLR_MASK (0x800U) +#define I2C_INTENCLR_SLVNOTSTRCLR_SHIFT (11U) +/*! SLVNOTSTRCLR - Slave Not Stretching interrupt clear. + */ +#define I2C_INTENCLR_SLVNOTSTRCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVNOTSTRCLR_SHIFT)) & I2C_INTENCLR_SLVNOTSTRCLR_MASK) +#define I2C_INTENCLR_SLVDESELCLR_MASK (0x8000U) +#define I2C_INTENCLR_SLVDESELCLR_SHIFT (15U) +/*! SLVDESELCLR - Slave Deselect interrupt clear. + */ +#define I2C_INTENCLR_SLVDESELCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVDESELCLR_SHIFT)) & I2C_INTENCLR_SLVDESELCLR_MASK) +#define I2C_INTENCLR_MONRDYCLR_MASK (0x10000U) +#define I2C_INTENCLR_MONRDYCLR_SHIFT (16U) +/*! MONRDYCLR - Monitor data Ready interrupt clear. + */ +#define I2C_INTENCLR_MONRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONRDYCLR_SHIFT)) & I2C_INTENCLR_MONRDYCLR_MASK) +#define I2C_INTENCLR_MONOVCLR_MASK (0x20000U) +#define I2C_INTENCLR_MONOVCLR_SHIFT (17U) +/*! MONOVCLR - Monitor Overrun interrupt clear. + */ +#define I2C_INTENCLR_MONOVCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONOVCLR_SHIFT)) & I2C_INTENCLR_MONOVCLR_MASK) +#define I2C_INTENCLR_MONIDLECLR_MASK (0x80000U) +#define I2C_INTENCLR_MONIDLECLR_SHIFT (19U) +/*! MONIDLECLR - Monitor Idle interrupt clear. + */ +#define I2C_INTENCLR_MONIDLECLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONIDLECLR_SHIFT)) & I2C_INTENCLR_MONIDLECLR_MASK) +#define I2C_INTENCLR_EVENTTIMEOUTCLR_MASK (0x1000000U) +#define I2C_INTENCLR_EVENTTIMEOUTCLR_SHIFT (24U) +/*! EVENTTIMEOUTCLR - Event time-out interrupt clear. + */ +#define I2C_INTENCLR_EVENTTIMEOUTCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_EVENTTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_EVENTTIMEOUTCLR_MASK) +#define I2C_INTENCLR_SCLTIMEOUTCLR_MASK (0x2000000U) +#define I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT (25U) +/*! SCLTIMEOUTCLR - SCL time-out interrupt clear. + */ +#define I2C_INTENCLR_SCLTIMEOUTCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_SCLTIMEOUTCLR_MASK) +/*! @} */ + +/*! @name TIMEOUT - Time-out value register. */ +/*! @{ */ +#define I2C_TIMEOUT_TOMIN_MASK (0xFU) +#define I2C_TIMEOUT_TOMIN_SHIFT (0U) +/*! TOMIN - Time-out time value, bottom four bits. These are hard-wired to 0xF. This gives a minimum + * time-out of 16 I2C function clocks and also a time-out resolution of 16 I2C function clocks. + */ +#define I2C_TIMEOUT_TOMIN(x) (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TOMIN_SHIFT)) & I2C_TIMEOUT_TOMIN_MASK) +#define I2C_TIMEOUT_TO_MASK (0xFFF0U) +#define I2C_TIMEOUT_TO_SHIFT (4U) +/*! TO - Time-out time value. Specifies the time-out interval value in increments of 16 I 2C + * function clocks, as defined by the CLKDIV register. To change this value while I2C is in operation, + * disable all time-outs, write a new value to TIMEOUT, then re-enable time-outs. 0x000 = A + * time-out will occur after 16 counts of the I2C function clock. 0x001 = A time-out will occur after + * 32 counts of the I2C function clock. 0xFFF = A time-out will occur after 65,536 counts of the + * I2C function clock. + */ +#define I2C_TIMEOUT_TO(x) (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TO_SHIFT)) & I2C_TIMEOUT_TO_MASK) +/*! @} */ + +/*! @name CLKDIV - Clock pre-divider for the entire I2C interface. This determines what time increments are used for the MSTTIME register, and controls some timing of the Slave function. */ +/*! @{ */ +#define I2C_CLKDIV_DIVVAL_MASK (0xFFFFU) +#define I2C_CLKDIV_DIVVAL_SHIFT (0U) +/*! DIVVAL - This field controls how the Flexcomm clock (FCLK) is used by the I2C functions that + * need an internal clock in order to operate. 0x0000 = FCLK is used directly by the I2C. 0x0001 = + * FCLK is divided by 2 before use. 0x0002 = FCLK is divided by 3 before use. 0xFFFF = FCLK is + * divided by 65,536 before use. + */ +#define I2C_CLKDIV_DIVVAL(x) (((uint32_t)(((uint32_t)(x)) << I2C_CLKDIV_DIVVAL_SHIFT)) & I2C_CLKDIV_DIVVAL_MASK) +/*! @} */ + +/*! @name INTSTAT - Interrupt Status register for Master, Slave, and Monitor functions. */ +/*! @{ */ +#define I2C_INTSTAT_MSTPENDING_MASK (0x1U) +#define I2C_INTSTAT_MSTPENDING_SHIFT (0U) +/*! MSTPENDING - Master Pending. + */ +#define I2C_INTSTAT_MSTPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTPENDING_SHIFT)) & I2C_INTSTAT_MSTPENDING_MASK) +#define I2C_INTSTAT_MSTARBLOSS_MASK (0x10U) +#define I2C_INTSTAT_MSTARBLOSS_SHIFT (4U) +/*! MSTARBLOSS - Master Arbitration Loss flag. + */ +#define I2C_INTSTAT_MSTARBLOSS(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTARBLOSS_SHIFT)) & I2C_INTSTAT_MSTARBLOSS_MASK) +#define I2C_INTSTAT_MSTSTSTPERR_MASK (0x40U) +#define I2C_INTSTAT_MSTSTSTPERR_SHIFT (6U) +/*! MSTSTSTPERR - Master Start/Stop Error flag. + */ +#define I2C_INTSTAT_MSTSTSTPERR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTSTSTPERR_SHIFT)) & I2C_INTSTAT_MSTSTSTPERR_MASK) +#define I2C_INTSTAT_SLVPENDING_MASK (0x100U) +#define I2C_INTSTAT_SLVPENDING_SHIFT (8U) +/*! SLVPENDING - Slave Pending. + */ +#define I2C_INTSTAT_SLVPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVPENDING_SHIFT)) & I2C_INTSTAT_SLVPENDING_MASK) +#define I2C_INTSTAT_SLVNOTSTR_MASK (0x800U) +#define I2C_INTSTAT_SLVNOTSTR_SHIFT (11U) +/*! SLVNOTSTR - Slave Not Stretching status. + */ +#define I2C_INTSTAT_SLVNOTSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVNOTSTR_SHIFT)) & I2C_INTSTAT_SLVNOTSTR_MASK) +#define I2C_INTSTAT_SLVDESEL_MASK (0x8000U) +#define I2C_INTSTAT_SLVDESEL_SHIFT (15U) +/*! SLVDESEL - Slave Deselected flag. + */ +#define I2C_INTSTAT_SLVDESEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVDESEL_SHIFT)) & I2C_INTSTAT_SLVDESEL_MASK) +#define I2C_INTSTAT_MONRDY_MASK (0x10000U) +#define I2C_INTSTAT_MONRDY_SHIFT (16U) +/*! MONRDY - Monitor Ready. + */ +#define I2C_INTSTAT_MONRDY(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONRDY_SHIFT)) & I2C_INTSTAT_MONRDY_MASK) +#define I2C_INTSTAT_MONOV_MASK (0x20000U) +#define I2C_INTSTAT_MONOV_SHIFT (17U) +/*! MONOV - Monitor Overflow flag. + */ +#define I2C_INTSTAT_MONOV(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONOV_SHIFT)) & I2C_INTSTAT_MONOV_MASK) +#define I2C_INTSTAT_MONIDLE_MASK (0x80000U) +#define I2C_INTSTAT_MONIDLE_SHIFT (19U) +/*! MONIDLE - Monitor Idle flag. + */ +#define I2C_INTSTAT_MONIDLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONIDLE_SHIFT)) & I2C_INTSTAT_MONIDLE_MASK) +#define I2C_INTSTAT_EVENTTIMEOUT_MASK (0x1000000U) +#define I2C_INTSTAT_EVENTTIMEOUT_SHIFT (24U) +/*! EVENTTIMEOUT - Event time-out Interrupt flag. + */ +#define I2C_INTSTAT_EVENTTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_EVENTTIMEOUT_SHIFT)) & I2C_INTSTAT_EVENTTIMEOUT_MASK) +#define I2C_INTSTAT_SCLTIMEOUT_MASK (0x2000000U) +#define I2C_INTSTAT_SCLTIMEOUT_SHIFT (25U) +/*! SCLTIMEOUT - SCL time-out Interrupt flag. + */ +#define I2C_INTSTAT_SCLTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SCLTIMEOUT_SHIFT)) & I2C_INTSTAT_SCLTIMEOUT_MASK) +/*! @} */ + +/*! @name MSTCTL - Master control register. */ +/*! @{ */ +#define I2C_MSTCTL_MSTCONTINUE_MASK (0x1U) +#define I2C_MSTCTL_MSTCONTINUE_SHIFT (0U) +/*! MSTCONTINUE - Master Continue. This bit is write-only. + * 0b0..No effect. + * 0b1..Continue. Informs the Master function to continue to the next operation. This must done after writing + * transmit data, reading received data, or any other housekeeping related to the next bus operation. + */ +#define I2C_MSTCTL_MSTCONTINUE(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTCONTINUE_SHIFT)) & I2C_MSTCTL_MSTCONTINUE_MASK) +#define I2C_MSTCTL_MSTSTART_MASK (0x2U) +#define I2C_MSTCTL_MSTSTART_SHIFT (1U) +/*! MSTSTART - Master Start control. This bit is write-only. + * 0b0..No effect. + * 0b1..Start. A Start will be generated on the I2C bus at the next allowed time. + */ +#define I2C_MSTCTL_MSTSTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTART_SHIFT)) & I2C_MSTCTL_MSTSTART_MASK) +#define I2C_MSTCTL_MSTSTOP_MASK (0x4U) +#define I2C_MSTCTL_MSTSTOP_SHIFT (2U) +/*! MSTSTOP - Master Stop control. This bit is write-only. + * 0b0..No effect. + * 0b1..Stop. A Stop will be generated on the I2C bus at the next allowed time, preceded by a NACK to the slave + * if the master is receiving data from the slave (Master Receiver mode). + */ +#define I2C_MSTCTL_MSTSTOP(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTOP_SHIFT)) & I2C_MSTCTL_MSTSTOP_MASK) +#define I2C_MSTCTL_MSTDMA_MASK (0x8U) +#define I2C_MSTCTL_MSTDMA_SHIFT (3U) +/*! MSTDMA - Master DMA enable. Data operations of the I2C can be performed with DMA. Protocol type + * operations such as Start, address, Stop, and address match must always be done with software, + * typically via an interrupt. Address acknowledgement must also be done by software except when + * the I2C is configured to be HSCAPABLE (and address acknowledgement is handled entirely by + * hardware) or when Automatic Operation is enabled. When a DMA data transfer is complete, MSTDMA + * must be cleared prior to beginning the next operation, typically a Start or Stop.This bit is + * read/write. + * 0b0..Disable. No DMA requests are generated for master operation. + * 0b1..Enable. A DMA request is generated for I2C master data operations. When this I2C master is generating + * Acknowledge bits in Master Receiver mode, the acknowledge is generated automatically. + */ +#define I2C_MSTCTL_MSTDMA(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTDMA_SHIFT)) & I2C_MSTCTL_MSTDMA_MASK) +/*! @} */ + +/*! @name MSTTIME - Master timing configuration. */ +/*! @{ */ +#define I2C_MSTTIME_MSTSCLLOW_MASK (0x7U) +#define I2C_MSTTIME_MSTSCLLOW_SHIFT (0U) +/*! MSTSCLLOW - Master SCL Low time. Specifies the minimum low time that will be asserted by this + * master on SCL. Other devices on the bus (masters or slaves) could lengthen this time. This + * corresponds to the parameter t LOW in the I2C bus specification. I2C bus specification parameters + * tBUF and tSU;STA have the same values and are also controlled by MSTSCLLOW. + * 0b000..2 clocks. Minimum SCL low time is 2 clocks of the I2C clock pre-divider. + * 0b001..3 clocks. Minimum SCL low time is 3 clocks of the I2C clock pre-divider. + * 0b010..4 clocks. Minimum SCL low time is 4 clocks of the I2C clock pre-divider. + * 0b011..5 clocks. Minimum SCL low time is 5 clocks of the I2C clock pre-divider. + * 0b100..6 clocks. Minimum SCL low time is 6 clocks of the I2C clock pre-divider. + * 0b101..7 clocks. Minimum SCL low time is 7 clocks of the I2C clock pre-divider. + * 0b110..8 clocks. Minimum SCL low time is 8 clocks of the I2C clock pre-divider. + * 0b111..9 clocks. Minimum SCL low time is 9 clocks of the I2C clock pre-divider. + */ +#define I2C_MSTTIME_MSTSCLLOW(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLLOW_SHIFT)) & I2C_MSTTIME_MSTSCLLOW_MASK) +#define I2C_MSTTIME_MSTSCLHIGH_MASK (0x70U) +#define I2C_MSTTIME_MSTSCLHIGH_SHIFT (4U) +/*! MSTSCLHIGH - Master SCL High time. Specifies the minimum high time that will be asserted by this + * master on SCL. Other masters in a multi-master system could shorten this time. This + * corresponds to the parameter tHIGH in the I2C bus specification. I2C bus specification parameters + * tSU;STO and tHD;STA have the same values and are also controlled by MSTSCLHIGH. + * 0b000..2 clocks. Minimum SCL high time is 2 clock of the I2C clock pre-divider. + * 0b001..3 clocks. Minimum SCL high time is 3 clocks of the I2C clock pre-divider . + * 0b010..4 clocks. Minimum SCL high time is 4 clock of the I2C clock pre-divider. + * 0b011..5 clocks. Minimum SCL high time is 5 clock of the I2C clock pre-divider. + * 0b100..6 clocks. Minimum SCL high time is 6 clock of the I2C clock pre-divider. + * 0b101..7 clocks. Minimum SCL high time is 7 clock of the I2C clock pre-divider. + * 0b110..8 clocks. Minimum SCL high time is 8 clock of the I2C clock pre-divider. + * 0b111..9 clocks. Minimum SCL high time is 9 clocks of the I2C clock pre-divider. + */ +#define I2C_MSTTIME_MSTSCLHIGH(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLHIGH_SHIFT)) & I2C_MSTTIME_MSTSCLHIGH_MASK) +/*! @} */ + +/*! @name MSTDAT - Combined Master receiver and transmitter data register. */ +/*! @{ */ +#define I2C_MSTDAT_DATA_MASK (0xFFU) +#define I2C_MSTDAT_DATA_SHIFT (0U) +/*! DATA - Master function data register. Read: read the most recently received data for the Master + * function. Write: transmit data using the Master function. + */ +#define I2C_MSTDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTDAT_DATA_SHIFT)) & I2C_MSTDAT_DATA_MASK) +/*! @} */ + +/*! @name SLVCTL - Slave control register. */ +/*! @{ */ +#define I2C_SLVCTL_SLVCONTINUE_MASK (0x1U) +#define I2C_SLVCTL_SLVCONTINUE_SHIFT (0U) +/*! SLVCONTINUE - Slave Continue. + * 0b0..No effect. + * 0b1..Continue. Informs the Slave function to continue to the next operation, by clearing the SLVPENDING flag + * in the STAT register. This must be done after writing transmit data, reading received data, or any other + * housekeeping related to the next bus operation. Automatic Operation has different requirements. SLVCONTINUE + * should not be set unless SLVPENDING = 1. + */ +#define I2C_SLVCTL_SLVCONTINUE(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVCONTINUE_SHIFT)) & I2C_SLVCTL_SLVCONTINUE_MASK) +#define I2C_SLVCTL_SLVNACK_MASK (0x2U) +#define I2C_SLVCTL_SLVNACK_SHIFT (1U) +/*! SLVNACK - Slave NACK. + * 0b0..No effect. + * 0b1..NACK. Causes the Slave function to NACK the master when the slave is receiving data from the master (Slave Receiver mode). + */ +#define I2C_SLVCTL_SLVNACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVNACK_SHIFT)) & I2C_SLVCTL_SLVNACK_MASK) +#define I2C_SLVCTL_SLVDMA_MASK (0x8U) +#define I2C_SLVCTL_SLVDMA_SHIFT (3U) +/*! SLVDMA - Slave DMA enable. + * 0b0..Disabled. No DMA requests are issued for Slave mode operation. + * 0b1..Enabled. DMA requests are issued for I2C slave data transmission and reception. + */ +#define I2C_SLVCTL_SLVDMA(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVDMA_SHIFT)) & I2C_SLVCTL_SLVDMA_MASK) +#define I2C_SLVCTL_AUTOACK_MASK (0x100U) +#define I2C_SLVCTL_AUTOACK_SHIFT (8U) +/*! AUTOACK - Automatic Acknowledge.When this bit is set, it will cause an I2C header which matches + * SLVADR0 and the direction set by AUTOMATCHREAD to be ACKed immediately; this is used with DMA + * to allow processing of the data without intervention. If this bit is clear and a header + * matches SLVADR0, the behavior is controlled by AUTONACK in the SLVADR0 register: allowing NACK or + * interrupt. + * 0b0..Normal, non-automatic operation. If AUTONACK = 0, an SlvPending interrupt is generated when a matching + * address is received. If AUTONACK = 1, received addresses are NACKed (ignored). + * 0b1..A header with matching SLVADR0 and matching direction as set by AUTOMATCHREAD will be ACKed immediately, + * allowing the master to move on to the data bytes. If the address matches SLVADR0, but the direction does + * not match AUTOMATCHREAD, the behavior will depend on the AUTONACK bit in the SLVADR0 register: if AUTONACK + * is set, then it will be Nacked; else if AUTONACK is clear, then a SlvPending interrupt is generated. + */ +#define I2C_SLVCTL_AUTOACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_AUTOACK_SHIFT)) & I2C_SLVCTL_AUTOACK_MASK) +#define I2C_SLVCTL_AUTOMATCHREAD_MASK (0x200U) +#define I2C_SLVCTL_AUTOMATCHREAD_SHIFT (9U) +/*! AUTOMATCHREAD - When AUTOACK is set, this bit controls whether it matches a read or write + * request on the next header with an address matching SLVADR0. Since DMA needs to be configured to + * match the transfer direction, the direction needs to be specified. This bit allows a direction to + * be chosen for the next operation. + * 0b0..The expected next operation in Automatic Mode is an I2C write. + * 0b1..The expected next operation in Automatic Mode is an I2C read. + */ +#define I2C_SLVCTL_AUTOMATCHREAD(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_AUTOMATCHREAD_SHIFT)) & I2C_SLVCTL_AUTOMATCHREAD_MASK) +/*! @} */ + +/*! @name SLVDAT - Combined Slave receiver and transmitter data register. */ +/*! @{ */ +#define I2C_SLVDAT_DATA_MASK (0xFFU) +#define I2C_SLVDAT_DATA_SHIFT (0U) +/*! DATA - Slave function data register. Read: read the most recently received data for the Slave + * function. Write: transmit data using the Slave function. + */ +#define I2C_SLVDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVDAT_DATA_SHIFT)) & I2C_SLVDAT_DATA_MASK) +/*! @} */ + +/*! @name SLVADR - Slave address register. */ +/*! @{ */ +#define I2C_SLVADR_SADISABLE_MASK (0x1U) +#define I2C_SLVADR_SADISABLE_SHIFT (0U) +/*! SADISABLE - Slave Address n Disable. + * 0b0..Enabled. Slave Address n is enabled. + * 0b1..Ignored Slave Address n is ignored. + */ +#define I2C_SLVADR_SADISABLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SADISABLE_SHIFT)) & I2C_SLVADR_SADISABLE_MASK) +#define I2C_SLVADR_SLVADR_MASK (0xFEU) +#define I2C_SLVADR_SLVADR_SHIFT (1U) +/*! SLVADR - Slave Address. Seven bit slave address that is compared to received addresses if enabled. + */ +#define I2C_SLVADR_SLVADR(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SLVADR_SHIFT)) & I2C_SLVADR_SLVADR_MASK) +#define I2C_SLVADR_AUTONACK_MASK (0x8000U) +#define I2C_SLVADR_AUTONACK_SHIFT (15U) +/*! AUTONACK - Automatic NACK operation. Used in conjunction with AUTOACK and AUTOMATCHREAD, allows + * software to ignore I2C traffic while handling previous I2C data or other operations. + * 0b0..Normal operation, matching I2C addresses are not ignored. + * 0b1..Automatic-only mode. All incoming addresses are ignored (NACKed), unless AUTOACK is set, it matches + * SLVADRn, and AUTOMATCHREAD matches the direction. + */ +#define I2C_SLVADR_AUTONACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_AUTONACK_SHIFT)) & I2C_SLVADR_AUTONACK_MASK) +/*! @} */ + +/* The count of I2C_SLVADR */ +#define I2C_SLVADR_COUNT (4U) + +/*! @name SLVQUAL0 - Slave Qualification for address 0. */ +/*! @{ */ +#define I2C_SLVQUAL0_QUALMODE0_MASK (0x1U) +#define I2C_SLVQUAL0_QUALMODE0_SHIFT (0U) +/*! QUALMODE0 - Qualify mode for slave address 0. + * 0b0..Mask. The SLVQUAL0 field is used as a logical mask for matching address 0. + * 0b1..Extend. The SLVQUAL0 field is used to extend address 0 matching in a range of addresses. + */ +#define I2C_SLVQUAL0_QUALMODE0(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_QUALMODE0_SHIFT)) & I2C_SLVQUAL0_QUALMODE0_MASK) +#define I2C_SLVQUAL0_SLVQUAL0_MASK (0xFEU) +#define I2C_SLVQUAL0_SLVQUAL0_SHIFT (1U) +/*! SLVQUAL0 - Slave address Qualifier for address 0. A value of 0 causes the address in SLVADR0 to + * be used as-is, assuming that it is enabled. If QUALMODE0 = 0, any bit in this field which is + * set to 1 will cause an automatic match of the corresponding bit of the received address when it + * is compared to the SLVADR0 register. If QUALMODE0 = 1, an address range is matched for + * address 0. This range extends from the value defined by SLVADR0 to the address defined by SLVQUAL0 + * (address matches when SLVADR0[7:1] <= received address <= SLVQUAL0[7:1]). + */ +#define I2C_SLVQUAL0_SLVQUAL0(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_SLVQUAL0_SHIFT)) & I2C_SLVQUAL0_SLVQUAL0_MASK) +/*! @} */ + +/*! @name MONRXDAT - Monitor receiver data register. */ +/*! @{ */ +#define I2C_MONRXDAT_MONRXDAT_MASK (0xFFU) +#define I2C_MONRXDAT_MONRXDAT_SHIFT (0U) +/*! MONRXDAT - Monitor function Receiver Data. This reflects every data byte that passes on the I2C pins. + */ +#define I2C_MONRXDAT_MONRXDAT(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRXDAT_SHIFT)) & I2C_MONRXDAT_MONRXDAT_MASK) +#define I2C_MONRXDAT_MONSTART_MASK (0x100U) +#define I2C_MONRXDAT_MONSTART_SHIFT (8U) +/*! MONSTART - Monitor Received Start. + * 0b0..No start detected. The Monitor function has not detected a Start event on the I2C bus. + * 0b1..Start detected. The Monitor function has detected a Start event on the I2C bus. + */ +#define I2C_MONRXDAT_MONSTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONSTART_SHIFT)) & I2C_MONRXDAT_MONSTART_MASK) +#define I2C_MONRXDAT_MONRESTART_MASK (0x200U) +#define I2C_MONRXDAT_MONRESTART_SHIFT (9U) +/*! MONRESTART - Monitor Received Repeated Start. + * 0b0..No repeated start detected. The Monitor function has not detected a Repeated Start event on the I2C bus. + * 0b1..Repeated start detected. The Monitor function has detected a Repeated Start event on the I2C bus. + */ +#define I2C_MONRXDAT_MONRESTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRESTART_SHIFT)) & I2C_MONRXDAT_MONRESTART_MASK) +#define I2C_MONRXDAT_MONNACK_MASK (0x400U) +#define I2C_MONRXDAT_MONNACK_SHIFT (10U) +/*! MONNACK - Monitor Received NACK. + * 0b0..Acknowledged. The data currently being provided by the Monitor function was acknowledged by at least one master or slave receiver. + * 0b1..Not acknowledged. The data currently being provided by the Monitor function was not acknowledged by any receiver. + */ +#define I2C_MONRXDAT_MONNACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONNACK_SHIFT)) & I2C_MONRXDAT_MONNACK_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group I2C_Register_Masks */ + + +/* I2C - Peripheral instance base addresses */ +/** Peripheral I2C0 base address */ +#define I2C0_BASE (0x40086000u) +/** Peripheral I2C0 base pointer */ +#define I2C0 ((I2C_Type *)I2C0_BASE) +/** Peripheral I2C1 base address */ +#define I2C1_BASE (0x40087000u) +/** Peripheral I2C1 base pointer */ +#define I2C1 ((I2C_Type *)I2C1_BASE) +/** Peripheral I2C2 base address */ +#define I2C2_BASE (0x40088000u) +/** Peripheral I2C2 base pointer */ +#define I2C2 ((I2C_Type *)I2C2_BASE) +/** Peripheral I2C3 base address */ +#define I2C3_BASE (0x40089000u) +/** Peripheral I2C3 base pointer */ +#define I2C3 ((I2C_Type *)I2C3_BASE) +/** Peripheral I2C4 base address */ +#define I2C4_BASE (0x4008A000u) +/** Peripheral I2C4 base pointer */ +#define I2C4 ((I2C_Type *)I2C4_BASE) +/** Peripheral I2C5 base address */ +#define I2C5_BASE (0x40096000u) +/** Peripheral I2C5 base pointer */ +#define I2C5 ((I2C_Type *)I2C5_BASE) +/** Peripheral I2C6 base address */ +#define I2C6_BASE (0x40097000u) +/** Peripheral I2C6 base pointer */ +#define I2C6 ((I2C_Type *)I2C6_BASE) +/** Peripheral I2C7 base address */ +#define I2C7_BASE (0x40098000u) +/** Peripheral I2C7 base pointer */ +#define I2C7 ((I2C_Type *)I2C7_BASE) +/** Array initializer of I2C peripheral base addresses */ +#define I2C_BASE_ADDRS { I2C0_BASE, I2C1_BASE, I2C2_BASE, I2C3_BASE, I2C4_BASE, I2C5_BASE, I2C6_BASE, I2C7_BASE } +/** Array initializer of I2C peripheral base pointers */ +#define I2C_BASE_PTRS { I2C0, I2C1, I2C2, I2C3, I2C4, I2C5, I2C6, I2C7 } +/** Interrupt vectors for the I2C peripheral type */ +#define I2C_IRQS { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn, FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM4_IRQn, FLEXCOMM5_IRQn, FLEXCOMM6_IRQn, FLEXCOMM7_IRQn } + +/*! + * @} + */ /* end of group I2C_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2S Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Peripheral_Access_Layer I2S Peripheral Access Layer + * @{ + */ + +/** I2S - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[3072]; + __IO uint32_t CFG1; /**< Configuration register 1 for the primary channel pair., offset: 0xC00 */ + __IO uint32_t CFG2; /**< Configuration register 2 for the primary channel pair., offset: 0xC04 */ + __IO uint32_t STAT; /**< Status register for the primary channel pair., offset: 0xC08 */ + uint8_t RESERVED_1[16]; + __IO uint32_t DIV; /**< Clock divider, used by all channel pairs., offset: 0xC1C */ + uint8_t RESERVED_2[480]; + __IO uint32_t FIFOCFG; /**< FIFO configuration and enable register., offset: 0xE00 */ + __IO uint32_t FIFOSTAT; /**< FIFO status register., offset: 0xE04 */ + __IO uint32_t FIFOTRIG; /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */ + uint8_t RESERVED_3[4]; + __IO uint32_t FIFOINTENSET; /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */ + __IO uint32_t FIFOINTENCLR; /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */ + __I uint32_t FIFOINTSTAT; /**< FIFO interrupt status register., offset: 0xE18 */ + uint8_t RESERVED_4[4]; + __O uint32_t FIFOWR; /**< FIFO write data., offset: 0xE20 */ + __O uint32_t FIFOWR48H; /**< FIFO write data for upper data bits. May only be used if the I2S is configured for 2x 24-bit data and not using DMA., offset: 0xE24 */ + uint8_t RESERVED_5[8]; + __I uint32_t FIFORD; /**< FIFO read data., offset: 0xE30 */ + __I uint32_t FIFORD48H; /**< FIFO read data for upper data bits. May only be used if the I2S is configured for 2x 24-bit data and not using DMA., offset: 0xE34 */ + uint8_t RESERVED_6[8]; + __I uint32_t FIFORDNOPOP; /**< FIFO data read with no FIFO pop., offset: 0xE40 */ + __I uint32_t FIFORD48HNOPOP; /**< FIFO data read for upper data bits with no FIFO pop. May only be used if the I2S is configured for 2x 24-bit data and not using DMA., offset: 0xE44 */ +} I2S_Type; + +/* ---------------------------------------------------------------------------- + -- I2S Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Register_Masks I2S Register Masks + * @{ + */ + +/*! @name CFG1 - Configuration register 1 for the primary channel pair. */ +/*! @{ */ +#define I2S_CFG1_MAINENABLE_MASK (0x1U) +#define I2S_CFG1_MAINENABLE_SHIFT (0U) +/*! MAINENABLE - Main enable for I 2S function in this Flexcomm + * 0b0..All I 2S channel pairs in this Flexcomm are disabled and the internal state machines, counters, and flags + * are reset. No other channel pairs can be enabled. + * 0b1..This I 2S channel pair is enabled. Other channel pairs in this Flexcomm may be enabled in their individual PAIRENABLE bits. + */ +#define I2S_CFG1_MAINENABLE(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_MAINENABLE_SHIFT)) & I2S_CFG1_MAINENABLE_MASK) +#define I2S_CFG1_DATAPAUSE_MASK (0x2U) +#define I2S_CFG1_DATAPAUSE_SHIFT (1U) +/*! DATAPAUSE - Data flow Pause. Allows pausing data flow between the I2S serializer/deserializer + * and the FIFO. This could be done in order to change streams, or while restarting after a data + * underflow or overflow. When paused, FIFO operations can be done without corrupting data that is + * in the process of being sent or received. Once a data pause has been requested, the interface + * may need to complete sending data that was in progress before interrupting the flow of data. + * Software must check that the pause is actually in effect before taking action. This is done by + * monitoring the DATAPAUSED flag in the STAT register. When DATAPAUSE is cleared, data transfer + * will resume at the beginning of the next frame. + * 0b0..Normal operation, or resuming normal operation at the next frame if the I2S has already been paused. + * 0b1..A pause in the data flow is being requested. It is in effect when DATAPAUSED in STAT = 1. + */ +#define I2S_CFG1_DATAPAUSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_DATAPAUSE_SHIFT)) & I2S_CFG1_DATAPAUSE_MASK) +#define I2S_CFG1_PAIRCOUNT_MASK (0xCU) +#define I2S_CFG1_PAIRCOUNT_SHIFT (2U) +/*! PAIRCOUNT - Provides the number of I2S channel pairs in this Flexcomm This is a read-only field + * whose value may be different in other Flexcomms. 00 = there is 1 I2S channel pair in this + * Flexcomm. 01 = there are 2 I2S channel pairs in this Flexcomm. 10 = there are 3 I2S channel pairs + * in this Flexcomm. 11 = there are 4 I2S channel pairs in this Flexcomm. + * 0b00..1 I2S channel pairs in this flexcomm + * 0b01..2 I2S channel pairs in this flexcomm + * 0b10..3 I2S channel pairs in this flexcomm + * 0b11..4 I2S channel pairs in this flexcomm + */ +#define I2S_CFG1_PAIRCOUNT(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_PAIRCOUNT_SHIFT)) & I2S_CFG1_PAIRCOUNT_MASK) +#define I2S_CFG1_MSTSLVCFG_MASK (0x30U) +#define I2S_CFG1_MSTSLVCFG_SHIFT (4U) +/*! MSTSLVCFG - Master / slave configuration selection, determining how SCK and WS are used by all channel pairs in this Flexcomm. + * 0b00..Normal slave mode, the default mode. SCK and WS are received from a master and used to transmit or receive data. + * 0b01..WS synchronized master. WS is received from another master and used to synchronize the generation of + * SCK, when divided from the Flexcomm function clock. + * 0b10..Master using an existing SCK. SCK is received and used directly to generate WS, as well as transmitting or receiving data. + * 0b11..Normal master mode. SCK and WS are generated so they can be sent to one or more slave devices. + */ +#define I2S_CFG1_MSTSLVCFG(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_MSTSLVCFG_SHIFT)) & I2S_CFG1_MSTSLVCFG_MASK) +#define I2S_CFG1_MODE_MASK (0xC0U) +#define I2S_CFG1_MODE_SHIFT (6U) +/*! MODE - Selects the basic I2S operating mode. Other configurations modify this to obtain all + * supported cases. See Formats and modes for examples. + * 0b00..I2S mode a.k.a. 'classic' mode. WS has a 50% duty cycle, with (for each enabled channel pair) one piece + * of left channel data occurring during the first phase, and one pieces of right channel data occurring + * during the second phase. In this mode, the data region begins one clock after the leading WS edge for the + * frame. For a 50% WS duty cycle, FRAMELEN must define an even number of I2S clocks for the frame. If + * FRAMELEN defines an odd number of clocks per frame, the extra clock will occur on the right. + * 0b01..DSP mode where WS has a 50% duty cycle. See remark for mode 0. + * 0b10..DSP mode where WS has a one clock long pulse at the beginning of each data frame. + * 0b11..DSP mode where WS has a one data slot long pulse at the beginning of each data frame. + */ +#define I2S_CFG1_MODE(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_MODE_SHIFT)) & I2S_CFG1_MODE_MASK) +#define I2S_CFG1_RIGHTLOW_MASK (0x100U) +#define I2S_CFG1_RIGHTLOW_SHIFT (8U) +/*! RIGHTLOW - Right channel data is in the Low portion of FIFO data. Essentially, this swaps left + * and right channel data as it is transferred to or from the FIFO. This bit is not used if the + * data width is greater than 24 bits or if PDMDATA = 1. Note that if the ONECHANNEL field (bit 10 + * of this register) = 1, the one channel to be used is the nominally the left channel. POSITION + * can still place that data in the frame where right channel data is normally located. if all + * enabled channel pairs have ONECHANNEL = 1, then RIGHTLOW = 1 is not allowed. + * 0b0..The right channel is taken from the high part of the FIFO data. For example, when data is 16 bits, FIFO + * bits 31:16 are used for the right channel. + * 0b1..The right channel is taken from the low part of the FIFO data. For example, when data is 16 bits, FIFO + * bits 15:0 are used for the right channel. + */ +#define I2S_CFG1_RIGHTLOW(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_RIGHTLOW_SHIFT)) & I2S_CFG1_RIGHTLOW_MASK) +#define I2S_CFG1_LEFTJUST_MASK (0x200U) +#define I2S_CFG1_LEFTJUST_SHIFT (9U) +/*! LEFTJUST - Left Justify data. + * 0b0..Data is transferred between the FIFO and the I2S serializer/deserializer right justified, i.e. starting + * from bit 0 and continuing to the position defined by DATALEN. This would correspond to right justified data + * in the stream on the data bus. + * 0b1..Data is transferred between the FIFO and the I2S serializer/deserializer left justified, i.e. starting + * from the MSB of the FIFO entry and continuing for the number of bits defined by DATALEN. This would + * correspond to left justified data in the stream on the data bus. + */ +#define I2S_CFG1_LEFTJUST(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_LEFTJUST_SHIFT)) & I2S_CFG1_LEFTJUST_MASK) +#define I2S_CFG1_ONECHANNEL_MASK (0x400U) +#define I2S_CFG1_ONECHANNEL_SHIFT (10U) +/*! ONECHANNEL - Single channel mode. Applies to both transmit and receive. This configuration bit + * applies only to the first I2S channel pair. Other channel pairs may select this mode + * independently in their separate CFG1 registers. + * 0b0..I2S data for this channel pair is treated as left and right channels. + * 0b1..I2S data for this channel pair is treated as a single channel, functionally the left channel for this + * pair. In mode 0 only, the right side of the frame begins at POSITION = 0x100. This is because mode 0 makes a + * clear distinction between the left and right sides of the frame. When ONECHANNEL = 1, the single channel + * of data may be placed on the right by setting POSITION to 0x100 + the data position within the right side + * (e.g. 0x108 would place data starting at the 8th clock after the middle of the frame). In other modes, data + * for the single channel of data is placed at the clock defined by POSITION. + */ +#define I2S_CFG1_ONECHANNEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_ONECHANNEL_SHIFT)) & I2S_CFG1_ONECHANNEL_MASK) +#define I2S_CFG1_PDMDATA_MASK (0x800U) +#define I2S_CFG1_PDMDATA_SHIFT (11U) +/*! PDMDATA - PDM Data selection. This bit controls the data source for I2S transmit, and cannot be + * set in Rx mode. This bit only has an effect if the device the Flexcomm resides in includes a + * D-Mic subsystem. For the LPC5411x, this bit applies only to Flexcomm 7. + * 0b0..Normal operation, data is transferred to or from the Flexcomm FIFO. + * 0b1..The data source is the D-Mic subsystem. When PDMDATA = 1, only the primary channel pair can be used in + * this Flexcomm. If ONECHANNEL = 1, only the PDM left data is used. the WS rate must match the Fs (sample + * rate) of the D-Mic decimator. A rate mismatch will at some point cause the I2S to overrun or underrun. + */ +#define I2S_CFG1_PDMDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_PDMDATA_SHIFT)) & I2S_CFG1_PDMDATA_MASK) +#define I2S_CFG1_SCK_POL_MASK (0x1000U) +#define I2S_CFG1_SCK_POL_SHIFT (12U) +/*! SCK_POL - SCK polarity. + * 0b0..Data is launched on SCK falling edges and sampled on SCK rising edges (standard for I2S). + * 0b1..Data is launched on SCK rising edges and sampled on SCK falling edges. + */ +#define I2S_CFG1_SCK_POL(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_SCK_POL_SHIFT)) & I2S_CFG1_SCK_POL_MASK) +#define I2S_CFG1_WS_POL_MASK (0x2000U) +#define I2S_CFG1_WS_POL_SHIFT (13U) +/*! WS_POL - WS polarity. + * 0b0..Data frames begin at a falling edge of WS (standard for classic I2S). + * 0b1..WS is inverted, resulting in a data frame beginning at a rising edge of WS (standard for most 'non-classic' variations of I2S). + */ +#define I2S_CFG1_WS_POL(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_WS_POL_SHIFT)) & I2S_CFG1_WS_POL_MASK) +#define I2S_CFG1_DATALEN_MASK (0x1F0000U) +#define I2S_CFG1_DATALEN_SHIFT (16U) +/*! DATALEN - Data Length, minus 1 encoded, defines the number of data bits to be transmitted or + * received for all I2S channel pairs in this Flexcomm. Note that data is only driven to or received + * from SDA for the number of bits defined by DATALEN. DATALEN is also used in these ways by the + * I2S: Determines the size of data transfers between the FIFO and the I2S + * serializer/deserializer. See FIFO buffer configurations and usage In mode 1, 2, and 3, determines the location of + * right data following left data in the frame. In mode 3 (where WS has a one data slot long pulse + * at the beginning of each data frame) determines the duration of the WS pulse. Values: 0x00 to + * 0x02 = not supported 0x03 = data is 4 bits in length 0x04 = data is 5 bits in length 0x1F = + * data is 32 bits in length + */ +#define I2S_CFG1_DATALEN(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG1_DATALEN_SHIFT)) & I2S_CFG1_DATALEN_MASK) +/*! @} */ + +/*! @name CFG2 - Configuration register 2 for the primary channel pair. */ +/*! @{ */ +#define I2S_CFG2_FRAMELEN_MASK (0x1FFU) +#define I2S_CFG2_FRAMELEN_SHIFT (0U) +/*! FRAMELEN - Frame Length, minus 1 encoded, defines the number of clocks and data bits in the + * frames that this channel pair participates in. See Frame format. 0x000 to 0x002 = not supported + * 0x003 = frame is 4 bits in total length 0x004 = frame is 5 bits in total length 0x1FF = frame is + * 512 bits in total length if FRAMELEN is an defines an odd length frame (e.g. 33 clocks) in + * mode 0 or 1, the extra clock appears in the right half. When MODE = 3, FRAMELEN must be larger + * than DATALEN in order for the WS pulse to be generated correctly. + */ +#define I2S_CFG2_FRAMELEN(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG2_FRAMELEN_SHIFT)) & I2S_CFG2_FRAMELEN_MASK) +#define I2S_CFG2_POSITION_MASK (0x1FF0000U) +#define I2S_CFG2_POSITION_SHIFT (16U) +/*! POSITION - Data Position. Defines the location within the frame of the data for this channel + * pair. POSITION + DATALEN must be less than FRAMELEN. See Frame format. When MODE = 0, POSITION + * defines the location of data in both the left phase and right phase, starting one clock after + * the WS edge. In other modes, POSITION defines the location of data within the entire frame. + * ONECHANNEL = 1 while MODE = 0 is a special case, see the description of ONECHANNEL. The + * combination of DATALEN and the POSITION fields of all channel pairs must be made such that the channels + * do not overlap within the frame. 0x000 = data begins at bit position 0 (the first bit + * position) within the frame or WS phase. 0x001 = data begins at bit position 1 within the frame or WS + * phase. 0x002 = data begins at bit position 2 within the frame or WS phase. + */ +#define I2S_CFG2_POSITION(x) (((uint32_t)(((uint32_t)(x)) << I2S_CFG2_POSITION_SHIFT)) & I2S_CFG2_POSITION_MASK) +/*! @} */ + +/*! @name STAT - Status register for the primary channel pair. */ +/*! @{ */ +#define I2S_STAT_BUSY_MASK (0x1U) +#define I2S_STAT_BUSY_SHIFT (0U) +/*! BUSY - Busy status for the primary channel pair. Other BUSY flags may be found in the STAT register for each channel pair. + * 0b0..The transmitter/receiver for channel pair is currently idle. + * 0b1..The transmitter/receiver for channel pair is currently processing data. + */ +#define I2S_STAT_BUSY(x) (((uint32_t)(((uint32_t)(x)) << I2S_STAT_BUSY_SHIFT)) & I2S_STAT_BUSY_MASK) +#define I2S_STAT_SLVFRMERR_MASK (0x2U) +#define I2S_STAT_SLVFRMERR_SHIFT (1U) +/*! SLVFRMERR - Slave Frame Error flag. This applies when at least one channel pair is operating as + * a slave. An error indicates that the incoming WS signal did not transition as expected due to + * a mismatch between FRAMELEN and the actual incoming I2S stream. + * 0b0..No error has been recorded. + * 0b1..An error has been recorded for some channel pair that is operating in slave mode. ERROR is cleared by writing a 1 to this bit position. + */ +#define I2S_STAT_SLVFRMERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_STAT_SLVFRMERR_SHIFT)) & I2S_STAT_SLVFRMERR_MASK) +#define I2S_STAT_LR_MASK (0x4U) +#define I2S_STAT_LR_SHIFT (2U) +/*! LR - Left/Right indication. This flag is considered to be a debugging aid and is not expected to + * be used by an I2S driver. Valid when one channel pair is busy. Indicates left or right data + * being processed for the currently busy channel pair. + * 0b0..Left channel. + * 0b1..Right channel. + */ +#define I2S_STAT_LR(x) (((uint32_t)(((uint32_t)(x)) << I2S_STAT_LR_SHIFT)) & I2S_STAT_LR_MASK) +#define I2S_STAT_DATAPAUSED_MASK (0x8U) +#define I2S_STAT_DATAPAUSED_SHIFT (3U) +/*! DATAPAUSED - Data Paused status flag. Applies to all I2S channels + * 0b0..Data is not currently paused. A data pause may have been requested but is not yet in force, waiting for + * an allowed pause point. Refer to the description of the DATAPAUSE control bit in the CFG1 register. + * 0b1..A data pause has been requested and is now in force. + */ +#define I2S_STAT_DATAPAUSED(x) (((uint32_t)(((uint32_t)(x)) << I2S_STAT_DATAPAUSED_SHIFT)) & I2S_STAT_DATAPAUSED_MASK) +/*! @} */ + +/*! @name DIV - Clock divider, used by all channel pairs. */ +/*! @{ */ +#define I2S_DIV_DIV_MASK (0xFFFU) +#define I2S_DIV_DIV_SHIFT (0U) +/*! DIV - This field controls how this I2S block uses the Flexcomm function clock. 0x000 = The + * Flexcomm function clock is used directly. 0x001 = The Flexcomm function clock is divided by 2. + * 0x002 = The Flexcomm function clock is divided by 3. 0xFFF = The Flexcomm function clock is + * divided by 4,096. + */ +#define I2S_DIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_DIV_DIV_SHIFT)) & I2S_DIV_DIV_MASK) +/*! @} */ + +/*! @name FIFOCFG - FIFO configuration and enable register. */ +/*! @{ */ +#define I2S_FIFOCFG_ENABLETX_MASK (0x1U) +#define I2S_FIFOCFG_ENABLETX_SHIFT (0U) +/*! ENABLETX - Enable the transmit FIFO. + * 0b0..The transmit FIFO is not enabled. + * 0b1..The transmit FIFO is enabled. + */ +#define I2S_FIFOCFG_ENABLETX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_ENABLETX_SHIFT)) & I2S_FIFOCFG_ENABLETX_MASK) +#define I2S_FIFOCFG_ENABLERX_MASK (0x2U) +#define I2S_FIFOCFG_ENABLERX_SHIFT (1U) +/*! ENABLERX - Enable the receive FIFO. + * 0b0..The receive FIFO is not enabled. + * 0b1..The receive FIFO is enabled. + */ +#define I2S_FIFOCFG_ENABLERX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_ENABLERX_SHIFT)) & I2S_FIFOCFG_ENABLERX_MASK) +#define I2S_FIFOCFG_TXI2SSE0_MASK (0x4U) +#define I2S_FIFOCFG_TXI2SSE0_SHIFT (2U) +/*! TXI2SSE0 - Transmit I2S empty 0. Determines the value sent by the I2S in transmit mode if the TX + * FIFO becomes empty. This value is sent repeatedly until the I2S is paused, the error is + * cleared, new data is provided, and the I2S is un-paused. + * 0b0..If the TX FIFO becomes empty, the last value is sent. This setting may be used when the data length is 24 + * bits or less, or when MONO = 1 for this channel pair. + * 0b1..If the TX FIFO becomes empty, 0 is sent. Use if the data length is greater than 24 bits or if zero fill is preferred. + */ +#define I2S_FIFOCFG_TXI2SSE0(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_TXI2SSE0_SHIFT)) & I2S_FIFOCFG_TXI2SSE0_MASK) +#define I2S_FIFOCFG_PACK48_MASK (0x8U) +#define I2S_FIFOCFG_PACK48_SHIFT (3U) +/*! PACK48 - Packing format for 48-bit data. This relates to how data is entered into or taken from the FIFO by software or DMA. + * 0b0..48-bit I2S FIFO entries are handled as all 24-bit values. + * 0b1..48-bit I2S FIFO entries are handled as alternating 32-bit and 16-bit values. + */ +#define I2S_FIFOCFG_PACK48(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_PACK48_SHIFT)) & I2S_FIFOCFG_PACK48_MASK) +#define I2S_FIFOCFG_SIZE_MASK (0x30U) +#define I2S_FIFOCFG_SIZE_SHIFT (4U) +/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = FIFO is configured as 16 + * entries of 8 bits. 0x1, 0x2, 0x3 = not applicable to USART. + */ +#define I2S_FIFOCFG_SIZE(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_SIZE_SHIFT)) & I2S_FIFOCFG_SIZE_MASK) +#define I2S_FIFOCFG_DMATX_MASK (0x1000U) +#define I2S_FIFOCFG_DMATX_SHIFT (12U) +/*! DMATX - DMA configuration for transmit. + * 0b0..DMA is not used for the transmit function. + * 0b1..Trigger DMA for the transmit function if the FIFO is not full. Generally, data interrupts would be disabled if DMA is enabled. + */ +#define I2S_FIFOCFG_DMATX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_DMATX_SHIFT)) & I2S_FIFOCFG_DMATX_MASK) +#define I2S_FIFOCFG_DMARX_MASK (0x2000U) +#define I2S_FIFOCFG_DMARX_SHIFT (13U) +/*! DMARX - DMA configuration for receive. + * 0b0..DMA is not used for the receive function. + * 0b1..Trigger DMA for the receive function if the FIFO is not empty. Generally, data interrupts would be disabled if DMA is enabled. + */ +#define I2S_FIFOCFG_DMARX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_DMARX_SHIFT)) & I2S_FIFOCFG_DMARX_MASK) +#define I2S_FIFOCFG_WAKETX_MASK (0x4000U) +#define I2S_FIFOCFG_WAKETX_SHIFT (14U) +/*! WAKETX - Wake-up for transmit FIFO level. This allows the device to be woken from reduced power + * modes (up to power-down, as long as the peripheral function works in that power mode) without + * enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The + * CPU will remain stopped until woken by another cause, such as DMA completion. See Hardware + * Wake-up control register. + * 0b0..Only enabled interrupts will wake up the device form reduced power modes. + * 0b1..A device wake-up for DMA will occur if the transmit FIFO level reaches the value specified by TXLVL in + * FIFOTRIG, even when the TXLVL interrupt is not enabled. + */ +#define I2S_FIFOCFG_WAKETX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_WAKETX_SHIFT)) & I2S_FIFOCFG_WAKETX_MASK) +#define I2S_FIFOCFG_WAKERX_MASK (0x8000U) +#define I2S_FIFOCFG_WAKERX_SHIFT (15U) +/*! WAKERX - Wake-up for receive FIFO level. This allows the device to be woken from reduced power + * modes (up to power-down, as long as the peripheral function works in that power mode) without + * enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The + * CPU will remain stopped until woken by another cause, such as DMA completion. See Hardware + * Wake-up control register. + * 0b0..Only enabled interrupts will wake up the device form reduced power modes. + * 0b1..A device wake-up for DMA will occur if the receive FIFO level reaches the value specified by RXLVL in + * FIFOTRIG, even when the RXLVL interrupt is not enabled. + */ +#define I2S_FIFOCFG_WAKERX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_WAKERX_SHIFT)) & I2S_FIFOCFG_WAKERX_MASK) +#define I2S_FIFOCFG_EMPTYTX_MASK (0x10000U) +#define I2S_FIFOCFG_EMPTYTX_SHIFT (16U) +/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied. + */ +#define I2S_FIFOCFG_EMPTYTX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_EMPTYTX_SHIFT)) & I2S_FIFOCFG_EMPTYTX_MASK) +#define I2S_FIFOCFG_EMPTYRX_MASK (0x20000U) +#define I2S_FIFOCFG_EMPTYRX_SHIFT (17U) +/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied. + */ +#define I2S_FIFOCFG_EMPTYRX(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_EMPTYRX_SHIFT)) & I2S_FIFOCFG_EMPTYRX_MASK) +#define I2S_FIFOCFG_POPDBG_MASK (0x40000U) +#define I2S_FIFOCFG_POPDBG_SHIFT (18U) +/*! POPDBG - Pop FIFO for debug reads. + * 0b0..Debug reads of the FIFO do not pop the FIFO. + * 0b1..A debug read will cause the FIFO to pop. + */ +#define I2S_FIFOCFG_POPDBG(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_POPDBG_SHIFT)) & I2S_FIFOCFG_POPDBG_MASK) +/*! @} */ + +/*! @name FIFOSTAT - FIFO status register. */ +/*! @{ */ +#define I2S_FIFOSTAT_TXERR_MASK (0x1U) +#define I2S_FIFOSTAT_TXERR_SHIFT (0U) +/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow + * caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is + * needed. Cleared by writing a 1 to this bit. + */ +#define I2S_FIFOSTAT_TXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_TXERR_SHIFT)) & I2S_FIFOSTAT_TXERR_MASK) +#define I2S_FIFOSTAT_RXERR_MASK (0x2U) +#define I2S_FIFOSTAT_RXERR_SHIFT (1U) +/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA + * not emptying the FIFO fast enough. Cleared by writing a 1 to this bit. + */ +#define I2S_FIFOSTAT_RXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_RXERR_SHIFT)) & I2S_FIFOSTAT_RXERR_MASK) +#define I2S_FIFOSTAT_PERINT_MASK (0x8U) +#define I2S_FIFOSTAT_PERINT_SHIFT (3U) +/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted + * an interrupt. The details can be found by reading the peripheral's STAT register. + */ +#define I2S_FIFOSTAT_PERINT(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_PERINT_SHIFT)) & I2S_FIFOSTAT_PERINT_MASK) +#define I2S_FIFOSTAT_TXEMPTY_MASK (0x10U) +#define I2S_FIFOSTAT_TXEMPTY_SHIFT (4U) +/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data. + */ +#define I2S_FIFOSTAT_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_TXEMPTY_SHIFT)) & I2S_FIFOSTAT_TXEMPTY_MASK) +#define I2S_FIFOSTAT_TXNOTFULL_MASK (0x20U) +#define I2S_FIFOSTAT_TXNOTFULL_SHIFT (5U) +/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be + * written. When 0, the transmit FIFO is full and another write would cause it to overflow. + */ +#define I2S_FIFOSTAT_TXNOTFULL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_TXNOTFULL_SHIFT)) & I2S_FIFOSTAT_TXNOTFULL_MASK) +#define I2S_FIFOSTAT_RXNOTEMPTY_MASK (0x40U) +#define I2S_FIFOSTAT_RXNOTEMPTY_SHIFT (6U) +/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty. + */ +#define I2S_FIFOSTAT_RXNOTEMPTY(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_RXNOTEMPTY_SHIFT)) & I2S_FIFOSTAT_RXNOTEMPTY_MASK) +#define I2S_FIFOSTAT_RXFULL_MASK (0x80U) +#define I2S_FIFOSTAT_RXFULL_SHIFT (7U) +/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to + * prevent the peripheral from causing an overflow. + */ +#define I2S_FIFOSTAT_RXFULL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_RXFULL_SHIFT)) & I2S_FIFOSTAT_RXFULL_MASK) +#define I2S_FIFOSTAT_TXLVL_MASK (0x1F00U) +#define I2S_FIFOSTAT_TXLVL_SHIFT (8U) +/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY + * and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at + * the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be + * 0. + */ +#define I2S_FIFOSTAT_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_TXLVL_SHIFT)) & I2S_FIFOSTAT_TXLVL_MASK) +#define I2S_FIFOSTAT_RXLVL_MASK (0x1F0000U) +#define I2S_FIFOSTAT_RXLVL_SHIFT (16U) +/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and + * RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the + * point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be + * 1. + */ +#define I2S_FIFOSTAT_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOSTAT_RXLVL_SHIFT)) & I2S_FIFOSTAT_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */ +/*! @{ */ +#define I2S_FIFOTRIG_TXLVLENA_MASK (0x1U) +#define I2S_FIFOTRIG_TXLVLENA_SHIFT (0U) +/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled + * in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set. + * 0b0..Transmit FIFO level does not generate a FIFO level trigger. + * 0b1..An trigger will be generated if the transmit FIFO level reaches the value specified by the TXLVL field in this register. + */ +#define I2S_FIFOTRIG_TXLVLENA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOTRIG_TXLVLENA_SHIFT)) & I2S_FIFOTRIG_TXLVLENA_MASK) +#define I2S_FIFOTRIG_RXLVLENA_MASK (0x2U) +#define I2S_FIFOTRIG_RXLVLENA_SHIFT (1U) +/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled + * in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set. + * 0b0..Receive FIFO level does not generate a FIFO level trigger. + * 0b1..An trigger will be generated if the receive FIFO level reaches the value specified by the RXLVL field in this register. + */ +#define I2S_FIFOTRIG_RXLVLENA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOTRIG_RXLVLENA_SHIFT)) & I2S_FIFOTRIG_RXLVLENA_MASK) +#define I2S_FIFOTRIG_TXLVL_MASK (0xF00U) +#define I2S_FIFOTRIG_TXLVL_SHIFT (8U) +/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. If enabled + * to do so, the FIFO level can wake up the device just enough to perform DMA, then return to + * the reduced power mode. See Hardware Wake-up control register. 0 = trigger when the TX FIFO + * becomes empty. 1 = trigger when the TX FIFO level decreases to one entry. 15 = trigger when the TX + * FIFO level decreases to 15 entries (is no longer full). + */ +#define I2S_FIFOTRIG_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOTRIG_TXLVL_SHIFT)) & I2S_FIFOTRIG_TXLVL_MASK) +#define I2S_FIFOTRIG_RXLVL_MASK (0xF0000U) +#define I2S_FIFOTRIG_RXLVL_SHIFT (16U) +/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data + * is received. This field is used only when RXLVLENA = 1. If enabled to do so, the FIFO level + * can wake up the device just enough to perform DMA, then return to the reduced power mode. See + * Hardware Wake-up control register. 0 = trigger when the RX FIFO has received one entry (is no + * longer empty). 1 = trigger when the RX FIFO has received two entries. 15 = trigger when the RX + * FIFO has received 16 entries (has become full). + */ +#define I2S_FIFOTRIG_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOTRIG_RXLVL_SHIFT)) & I2S_FIFOTRIG_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */ +/*! @{ */ +#define I2S_FIFOINTENSET_TXERR_MASK (0x1U) +#define I2S_FIFOINTENSET_TXERR_SHIFT (0U) +/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR flag in the FIFOSTAT register. + * 0b0..No interrupt will be generated for a transmit error. + * 0b1..An interrupt will be generated when a transmit error occurs. + */ +#define I2S_FIFOINTENSET_TXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENSET_TXERR_SHIFT)) & I2S_FIFOINTENSET_TXERR_MASK) +#define I2S_FIFOINTENSET_RXERR_MASK (0x2U) +#define I2S_FIFOINTENSET_RXERR_SHIFT (1U) +/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR flag in the FIFOSTAT register. + * 0b0..No interrupt will be generated for a receive error. + * 0b1..An interrupt will be generated when a receive error occurs. + */ +#define I2S_FIFOINTENSET_RXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENSET_RXERR_SHIFT)) & I2S_FIFOINTENSET_RXERR_MASK) +#define I2S_FIFOINTENSET_TXLVL_MASK (0x4U) +#define I2S_FIFOINTENSET_TXLVL_SHIFT (2U) +/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level + * specified by the TXLVL field in the FIFOTRIG register. + * 0b0..No interrupt will be generated based on the TX FIFO level. + * 0b1..If TXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when the TX FIFO level decreases + * to the level specified by TXLVL in the FIFOTRIG register. + */ +#define I2S_FIFOINTENSET_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENSET_TXLVL_SHIFT)) & I2S_FIFOINTENSET_TXLVL_MASK) +#define I2S_FIFOINTENSET_RXLVL_MASK (0x8U) +#define I2S_FIFOINTENSET_RXLVL_SHIFT (3U) +/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level + * specified by the TXLVL field in the FIFOTRIG register. + * 0b0..No interrupt will be generated based on the RX FIFO level. + * 0b1..If RXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when the when the RX FIFO level + * increases to the level specified by RXLVL in the FIFOTRIG register. + */ +#define I2S_FIFOINTENSET_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENSET_RXLVL_SHIFT)) & I2S_FIFOINTENSET_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */ +/*! @{ */ +#define I2S_FIFOINTENCLR_TXERR_MASK (0x1U) +#define I2S_FIFOINTENCLR_TXERR_SHIFT (0U) +/*! TXERR - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define I2S_FIFOINTENCLR_TXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENCLR_TXERR_SHIFT)) & I2S_FIFOINTENCLR_TXERR_MASK) +#define I2S_FIFOINTENCLR_RXERR_MASK (0x2U) +#define I2S_FIFOINTENCLR_RXERR_SHIFT (1U) +/*! RXERR - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define I2S_FIFOINTENCLR_RXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENCLR_RXERR_SHIFT)) & I2S_FIFOINTENCLR_RXERR_MASK) +#define I2S_FIFOINTENCLR_TXLVL_MASK (0x4U) +#define I2S_FIFOINTENCLR_TXLVL_SHIFT (2U) +/*! TXLVL - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define I2S_FIFOINTENCLR_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENCLR_TXLVL_SHIFT)) & I2S_FIFOINTENCLR_TXLVL_MASK) +#define I2S_FIFOINTENCLR_RXLVL_MASK (0x8U) +#define I2S_FIFOINTENCLR_RXLVL_SHIFT (3U) +/*! RXLVL - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define I2S_FIFOINTENCLR_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTENCLR_RXLVL_SHIFT)) & I2S_FIFOINTENCLR_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTSTAT - FIFO interrupt status register. */ +/*! @{ */ +#define I2S_FIFOINTSTAT_TXERR_MASK (0x1U) +#define I2S_FIFOINTSTAT_TXERR_SHIFT (0U) +/*! TXERR - TX FIFO error. + */ +#define I2S_FIFOINTSTAT_TXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTSTAT_TXERR_SHIFT)) & I2S_FIFOINTSTAT_TXERR_MASK) +#define I2S_FIFOINTSTAT_RXERR_MASK (0x2U) +#define I2S_FIFOINTSTAT_RXERR_SHIFT (1U) +/*! RXERR - RX FIFO error. + */ +#define I2S_FIFOINTSTAT_RXERR(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTSTAT_RXERR_SHIFT)) & I2S_FIFOINTSTAT_RXERR_MASK) +#define I2S_FIFOINTSTAT_TXLVL_MASK (0x4U) +#define I2S_FIFOINTSTAT_TXLVL_SHIFT (2U) +/*! TXLVL - Transmit FIFO level interrupt. + */ +#define I2S_FIFOINTSTAT_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTSTAT_TXLVL_SHIFT)) & I2S_FIFOINTSTAT_TXLVL_MASK) +#define I2S_FIFOINTSTAT_RXLVL_MASK (0x8U) +#define I2S_FIFOINTSTAT_RXLVL_SHIFT (3U) +/*! RXLVL - Receive FIFO level interrupt. + */ +#define I2S_FIFOINTSTAT_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTSTAT_RXLVL_SHIFT)) & I2S_FIFOINTSTAT_RXLVL_MASK) +#define I2S_FIFOINTSTAT_PERINT_MASK (0x10U) +#define I2S_FIFOINTSTAT_PERINT_SHIFT (4U) +/*! PERINT - Peripheral interrupt. + */ +#define I2S_FIFOINTSTAT_PERINT(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOINTSTAT_PERINT_SHIFT)) & I2S_FIFOINTSTAT_PERINT_MASK) +/*! @} */ + +/*! @name FIFOWR - FIFO write data. */ +/*! @{ */ +#define I2S_FIFOWR_TXDATA_MASK (0xFFFFFFFFU) +#define I2S_FIFOWR_TXDATA_SHIFT (0U) +/*! TXDATA - Transmit data to the FIFO. The number of bits used depends on configuration details. + */ +#define I2S_FIFOWR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOWR_TXDATA_SHIFT)) & I2S_FIFOWR_TXDATA_MASK) +/*! @} */ + +/*! @name FIFOWR48H - FIFO write data for upper data bits. May only be used if the I2S is configured for 2x 24-bit data and not using DMA. */ +/*! @{ */ +#define I2S_FIFOWR48H_TXDATA_MASK (0xFFFFFFU) +#define I2S_FIFOWR48H_TXDATA_SHIFT (0U) +/*! TXDATA - Transmit data to the FIFO. Whether this register is used and the number of bits used depends on configuration details. + */ +#define I2S_FIFOWR48H_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOWR48H_TXDATA_SHIFT)) & I2S_FIFOWR48H_TXDATA_MASK) +/*! @} */ + +/*! @name FIFORD - FIFO read data. */ +/*! @{ */ +#define I2S_FIFORD_RXDATA_MASK (0xFFFFFFFFU) +#define I2S_FIFORD_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. The number of bits used depends on configuration details. + */ +#define I2S_FIFORD_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFORD_RXDATA_SHIFT)) & I2S_FIFORD_RXDATA_MASK) +/*! @} */ + +/*! @name FIFORD48H - FIFO read data for upper data bits. May only be used if the I2S is configured for 2x 24-bit data and not using DMA. */ +/*! @{ */ +#define I2S_FIFORD48H_RXDATA_MASK (0xFFFFFFU) +#define I2S_FIFORD48H_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. Whether this register is used and the number of bits used depends on configuration details. + */ +#define I2S_FIFORD48H_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFORD48H_RXDATA_SHIFT)) & I2S_FIFORD48H_RXDATA_MASK) +/*! @} */ + +/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. */ +/*! @{ */ +#define I2S_FIFORDNOPOP_RXDATA_MASK (0xFFFFFFFFU) +#define I2S_FIFORDNOPOP_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. + */ +#define I2S_FIFORDNOPOP_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFORDNOPOP_RXDATA_SHIFT)) & I2S_FIFORDNOPOP_RXDATA_MASK) +/*! @} */ + +/*! @name FIFORD48HNOPOP - FIFO data read for upper data bits with no FIFO pop. May only be used if the I2S is configured for 2x 24-bit data and not using DMA. */ +/*! @{ */ +#define I2S_FIFORD48HNOPOP_RXDATA_MASK (0xFFFFFFU) +#define I2S_FIFORD48HNOPOP_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. Whether this register is used and the number of bits used depends on configuration details. + */ +#define I2S_FIFORD48HNOPOP_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFORD48HNOPOP_RXDATA_SHIFT)) & I2S_FIFORD48HNOPOP_RXDATA_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group I2S_Register_Masks */ + + +/* I2S - Peripheral instance base addresses */ +/** Peripheral I2S0 base address */ +#define I2S0_BASE (0x40097000u) +/** Peripheral I2S0 base pointer */ +#define I2S0 ((I2S_Type *)I2S0_BASE) +/** Peripheral I2S1 base address */ +#define I2S1_BASE (0x40098000u) +/** Peripheral I2S1 base pointer */ +#define I2S1 ((I2S_Type *)I2S1_BASE) +/** Array initializer of I2S peripheral base addresses */ +#define I2S_BASE_ADDRS { I2S0_BASE, I2S1_BASE } +/** Array initializer of I2S peripheral base pointers */ +#define I2S_BASE_PTRS { I2S0, I2S1 } +/** Interrupt vectors for the I2S peripheral type */ +#define I2S_IRQS { FLEXCOMM6_IRQn, FLEXCOMM7_IRQn } + +/*! + * @} + */ /* end of group I2S_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- INPUTMUX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup INPUTMUX_Peripheral_Access_Layer INPUTMUX Peripheral Access Layer + * @{ + */ + +/** INPUTMUX - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[192]; + __IO uint32_t PINTSEL[8]; /**< Pin interrupt select register, array offset: 0xC0, array step: 0x4 */ + __IO uint32_t DMA_ITRIG_INMUX[22]; /**< Trigger select register for DMA channel, array offset: 0xE0, array step: 0x4 */ + uint8_t RESERVED_1[40]; + __IO uint32_t DMA_OTRIG_INMUX[4]; /**< DMA output trigger selection to become DMA trigger, array offset: 0x160, array step: 0x4 */ + uint8_t RESERVED_2[16]; + __IO uint32_t FREQMEAS_REF; /**< Selection for frequency measurement reference clock, offset: 0x180 */ + __IO uint32_t FREQMEAS_TARGET; /**< Selection for frequency measurement target clock, offset: 0x184 */ +} INPUTMUX_Type; + +/* ---------------------------------------------------------------------------- + -- INPUTMUX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup INPUTMUX_Register_Masks INPUTMUX Register Masks + * @{ + */ + +/*! @name PINTSEL - Pin interrupt select register */ +/*! @{ */ +#define INPUTMUX_PINTSEL_INTPIN_MASK (0xFFU) +#define INPUTMUX_PINTSEL_INTPIN_SHIFT (0U) +/*! INTPIN - Pin number select for pin interrupt or pattern match engine input. (PIO0_0 to PIO1_31 correspond to numbers 0 to 63). + */ +#define INPUTMUX_PINTSEL_INTPIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_PINTSEL_INTPIN_SHIFT)) & INPUTMUX_PINTSEL_INTPIN_MASK) +/*! @} */ + +/* The count of INPUTMUX_PINTSEL */ +#define INPUTMUX_PINTSEL_COUNT (8U) + +/*! @name DMA_ITRIG_INMUX - Trigger select register for DMA channel */ +/*! @{ */ +#define INPUTMUX_DMA_ITRIG_INMUX_INP_MASK (0x1FU) +#define INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT (0U) +/*! INP - Trigger input number (decimal value) for DMA channel n (n = 0 to 21). 0 = ADC0 Sequence A + * interrupt 1 = ADC0 Sequence B interrupt 2 = SCT0 DMA request 0 3 = SCT0 DMA request 1 4 = + * Timer CTIMER0 Match 0 5 = Timer CTIMER0 Match 1 6 = Timer CTIMER1 Match 0 7 = Timer CTIMER2 Match + * 0 8 = Timer CTIMER2 Match 1 9 = Timer CTIMER3 Match 0 10 = Timer CTIMER4 Match 0 11 = Timer + * CTIMER4 Match 1 12 = Pin interrupt 0 13 = Pin interrupt 1 14 = Pin interrupt 2 15 = Pin + * interrupt 3 16 = DMA output trigger mux 0 17 = DMA output trigger mux 1 18 = DMA output trigger mux 2 + * 19 = DMA output trigger mux 3 + */ +#define INPUTMUX_DMA_ITRIG_INMUX_INP(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_ITRIG_INMUX_INP_MASK) +/*! @} */ + +/* The count of INPUTMUX_DMA_ITRIG_INMUX */ +#define INPUTMUX_DMA_ITRIG_INMUX_COUNT (22U) + +/*! @name DMA_OTRIG_INMUX - DMA output trigger selection to become DMA trigger */ +/*! @{ */ +#define INPUTMUX_DMA_OTRIG_INMUX_INP_MASK (0x1FU) +#define INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT (0U) +/*! INP - DMA trigger output number (decimal value) for DMA channel n (n = 0 to 19). + */ +#define INPUTMUX_DMA_OTRIG_INMUX_INP(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_OTRIG_INMUX_INP_MASK) +/*! @} */ + +/* The count of INPUTMUX_DMA_OTRIG_INMUX */ +#define INPUTMUX_DMA_OTRIG_INMUX_COUNT (4U) + +/*! @name FREQMEAS_REF - Selection for frequency measurement reference clock */ +/*! @{ */ +#define INPUTMUX_FREQMEAS_REF_CLKIN_MASK (0x1FU) +#define INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT (0U) +/*! CLKIN - Clock source number (decimal value) for frequency measure function target clock: 0 = + * CLK_IN 1 = FRO 12 MHz oscillator 2 = Watchdog oscillator 3 = 32 kHz RTC oscillator 4 = Main clock + * (see Section 4.5.23) 5 = PIO0_4 6 = PIO0_20 7 = PIO0_24 8 = PIO1_4 + */ +#define INPUTMUX_FREQMEAS_REF_CLKIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_REF_CLKIN_MASK) +/*! @} */ + +/*! @name FREQMEAS_TARGET - Selection for frequency measurement target clock */ +/*! @{ */ +#define INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK (0x1FU) +#define INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT (0U) +/*! CLKIN - Clock source number (decimal value) for frequency measure function target clock: 0 = + * CLK_IN 1 = FRO 12 MHz oscillator 2 = Watchdog oscillator 3 = 32 kHz RTC oscillator 4 = Main clock + * (see Section 4.5.23) 5 = PIO0_4 6 = PIO0_20 7 = PIO0_24 8 = PIO1_4 + */ +#define INPUTMUX_FREQMEAS_TARGET_CLKIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group INPUTMUX_Register_Masks */ + + +/* INPUTMUX - Peripheral instance base addresses */ +/** Peripheral INPUTMUX base address */ +#define INPUTMUX_BASE (0x40005000u) +/** Peripheral INPUTMUX base pointer */ +#define INPUTMUX ((INPUTMUX_Type *)INPUTMUX_BASE) +/** Array initializer of INPUTMUX peripheral base addresses */ +#define INPUTMUX_BASE_ADDRS { INPUTMUX_BASE } +/** Array initializer of INPUTMUX peripheral base pointers */ +#define INPUTMUX_BASE_PTRS { INPUTMUX } + +/*! + * @} + */ /* end of group INPUTMUX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- IOCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup IOCON_Peripheral_Access_Layer IOCON Peripheral Access Layer + * @{ + */ + +/** IOCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t PIO[2][32]; /**< Digital I/O control for port 0 pins PIO0_0..Digital I/O control for port 1 pins PIO1_31, array offset: 0x0, array step: index*0x80, index2*0x4 */ +} IOCON_Type; + +/* ---------------------------------------------------------------------------- + -- IOCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup IOCON_Register_Masks IOCON Register Masks + * @{ + */ + +/*! @name PIO - Digital I/O control for port 0 pins PIO0_0..Digital I/O control for port 1 pins PIO1_31 */ +/*! @{ */ +#define IOCON_PIO_FUNC_MASK (0x7U) +#define IOCON_PIO_FUNC_SHIFT (0U) +/*! FUNC - Selects pin function. + * 0b000..Alternative connection 0. + * 0b001..Alternative connection 1. + * 0b010..Alternative connection 2. + * 0b011..Alternative connection 3. + * 0b100..Alternative connection 4. + * 0b101..Alternative connection 5. + * 0b110..Alternative connection 6. + * 0b111..Alternative connection 7. + */ +#define IOCON_PIO_FUNC(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FUNC_SHIFT)) & IOCON_PIO_FUNC_MASK) +#define IOCON_PIO_MODE_MASK (0x18U) +#define IOCON_PIO_MODE_SHIFT (3U) +/*! MODE - Selects function mode (on-chip pull-up/pull-down resistor control). + * 0b00..Inactive. Inactive (no pull-down/pull-up resistor enabled). + * 0b01..Pull-down. Pull-down resistor enabled. + * 0b10..Pull-up. Pull-up resistor enabled. + * 0b11..Repeater. Repeater mode. + */ +#define IOCON_PIO_MODE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_MODE_SHIFT)) & IOCON_PIO_MODE_MASK) +#define IOCON_PIO_I2CSLEW_MASK (0x20U) +#define IOCON_PIO_I2CSLEW_SHIFT (5U) +/*! I2CSLEW - Controls slew rate of I2C pad. + * 0b0..I2C mode. + * 0b1..GPIO mode. + */ +#define IOCON_PIO_I2CSLEW(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CSLEW_SHIFT)) & IOCON_PIO_I2CSLEW_MASK) +#define IOCON_PIO_INVERT_MASK (0x40U) +#define IOCON_PIO_INVERT_SHIFT (6U) +/*! INVERT - Input polarity. + * 0b0..Disabled. Input function is not inverted. + * 0b1..Enabled. Input is function inverted. + */ +#define IOCON_PIO_INVERT(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_INVERT_SHIFT)) & IOCON_PIO_INVERT_MASK) +#define IOCON_PIO_DIGIMODE_MASK (0x80U) +#define IOCON_PIO_DIGIMODE_SHIFT (7U) +/*! DIGIMODE - Select Analog/Digital mode. + * 0b0..Analog mode. + * 0b1..Digital mode. + */ +#define IOCON_PIO_DIGIMODE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DIGIMODE_SHIFT)) & IOCON_PIO_DIGIMODE_MASK) +#define IOCON_PIO_FILTEROFF_MASK (0x100U) +#define IOCON_PIO_FILTEROFF_SHIFT (8U) +/*! FILTEROFF - Controls input glitch filter. + * 0b0..Filter enabled. Noise pulses below approximately 10 ns are filtered out. + * 0b1..Filter disabled. No input filtering is done. + */ +#define IOCON_PIO_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FILTEROFF_SHIFT)) & IOCON_PIO_FILTEROFF_MASK) +#define IOCON_PIO_I2CDRIVE_MASK (0x200U) +#define IOCON_PIO_I2CDRIVE_SHIFT (9U) +/*! I2CDRIVE - Controls the current sink capability of the pin. + * 0b0..Low drive. Output drive sink is 4 mA. This is sufficient for standard and fast mode I2C. + * 0b1..High drive. Output drive sink is 20 mA. This is needed for Fast Mode Plus I 2C. Refer to the appropriate + * specific device data sheet for details. + */ +#define IOCON_PIO_I2CDRIVE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CDRIVE_SHIFT)) & IOCON_PIO_I2CDRIVE_MASK) +#define IOCON_PIO_SLEW_MASK (0x200U) +#define IOCON_PIO_SLEW_SHIFT (9U) +/*! SLEW - Driver slew rate. + * 0b0..Standard mode, output slew rate control is enabled. More outputs can be switched simultaneously. + * 0b1..Fast mode, slew rate control is disabled. Refer to the appropriate specific device data sheet for details. + */ +#define IOCON_PIO_SLEW(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW_SHIFT)) & IOCON_PIO_SLEW_MASK) +#define IOCON_PIO_I2CFILTER_MASK (0x400U) +#define IOCON_PIO_I2CFILTER_SHIFT (10U) +/*! I2CFILTER - Configures I2C features for standard mode, fast mode, and Fast Mode Plus operation. + * 0b0..Enabled. I2C 50 ns glitch filter enabled. + * 0b1..Disabled. I2C 50 ns glitch filter disabled. + */ +#define IOCON_PIO_I2CFILTER(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CFILTER_SHIFT)) & IOCON_PIO_I2CFILTER_MASK) +#define IOCON_PIO_OD_MASK (0x400U) +#define IOCON_PIO_OD_SHIFT (10U) +/*! OD - Controls open-drain mode. + * 0b0..Normal. Normal push-pull output + * 0b1..Open-drain. Simulated open-drain output (high drive disabled). + */ +#define IOCON_PIO_OD(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_OD_SHIFT)) & IOCON_PIO_OD_MASK) +/*! @} */ + +/* The count of IOCON_PIO */ +#define IOCON_PIO_COUNT (2U) + +/* The count of IOCON_PIO */ +#define IOCON_PIO_COUNT2 (32U) + + +/*! + * @} + */ /* end of group IOCON_Register_Masks */ + + +/* IOCON - Peripheral instance base addresses */ +/** Peripheral IOCON base address */ +#define IOCON_BASE (0x40001000u) +/** Peripheral IOCON base pointer */ +#define IOCON ((IOCON_Type *)IOCON_BASE) +/** Array initializer of IOCON peripheral base addresses */ +#define IOCON_BASE_ADDRS { IOCON_BASE } +/** Array initializer of IOCON peripheral base pointers */ +#define IOCON_BASE_PTRS { IOCON } + +/*! + * @} + */ /* end of group IOCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MAILBOX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MAILBOX_Peripheral_Access_Layer MAILBOX Peripheral Access Layer + * @{ + */ + +/** MAILBOX - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x10 */ + __IO uint32_t IRQ; /**< Interrupt request register for the Cortex-M0+ CPU., array offset: 0x0, array step: 0x10 */ + __O uint32_t IRQSET; /**< Set bits in IRQ0, array offset: 0x4, array step: 0x10 */ + __O uint32_t IRQCLR; /**< Clear bits in IRQ0, array offset: 0x8, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } MBOXIRQ[2]; + uint8_t RESERVED_0[216]; + __IO uint32_t MUTEX; /**< Mutual exclusion register[1], offset: 0xF8 */ +} MAILBOX_Type; + +/* ---------------------------------------------------------------------------- + -- MAILBOX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MAILBOX_Register_Masks MAILBOX Register Masks + * @{ + */ + +/*! @name MBOXIRQ_IRQ - Interrupt request register for the Cortex-M0+ CPU. */ +/*! @{ */ +#define MAILBOX_MBOXIRQ_IRQ_INTREQ_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQ_INTREQ_SHIFT (0U) +/*! INTREQ - If any bit is set, an interrupt request is sent to the Cortex-M0+ interrupt controller. + */ +#define MAILBOX_MBOXIRQ_IRQ_INTREQ(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQ_INTREQ_SHIFT)) & MAILBOX_MBOXIRQ_IRQ_INTREQ_MASK) +/*! @} */ + +/* The count of MAILBOX_MBOXIRQ_IRQ */ +#define MAILBOX_MBOXIRQ_IRQ_COUNT (2U) + +/*! @name MBOXIRQ_IRQSET - Set bits in IRQ0 */ +/*! @{ */ +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET_SHIFT (0U) +/*! INTREQSET - Writing 1 sets the corresponding bit in the IRQ0 register. + */ +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQSET_INTREQSET_SHIFT)) & MAILBOX_MBOXIRQ_IRQSET_INTREQSET_MASK) +/*! @} */ + +/* The count of MAILBOX_MBOXIRQ_IRQSET */ +#define MAILBOX_MBOXIRQ_IRQSET_COUNT (2U) + +/*! @name MBOXIRQ_IRQCLR - Clear bits in IRQ0 */ +/*! @{ */ +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_SHIFT (0U) +/*! INTREQCLR - Writing 1 clears the corresponding bit in the IRQ0 register. + */ +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_SHIFT)) & MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_MASK) +/*! @} */ + +/* The count of MAILBOX_MBOXIRQ_IRQCLR */ +#define MAILBOX_MBOXIRQ_IRQCLR_COUNT (2U) + +/*! @name MUTEX - Mutual exclusion register[1] */ +/*! @{ */ +#define MAILBOX_MUTEX_EX_MASK (0x1U) +#define MAILBOX_MUTEX_EX_SHIFT (0U) +/*! EX - Cleared when read, set when written. See usage description above. + */ +#define MAILBOX_MUTEX_EX(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MUTEX_EX_SHIFT)) & MAILBOX_MUTEX_EX_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group MAILBOX_Register_Masks */ + + +/* MAILBOX - Peripheral instance base addresses */ +/** Peripheral MAILBOX base address */ +#define MAILBOX_BASE (0x4008B000u) +/** Peripheral MAILBOX base pointer */ +#define MAILBOX ((MAILBOX_Type *)MAILBOX_BASE) +/** Array initializer of MAILBOX peripheral base addresses */ +#define MAILBOX_BASE_ADDRS { MAILBOX_BASE } +/** Array initializer of MAILBOX peripheral base pointers */ +#define MAILBOX_BASE_PTRS { MAILBOX } +/** Interrupt vectors for the MAILBOX peripheral type */ +#define MAILBOX_IRQS { MAILBOX_IRQn } + +/*! + * @} + */ /* end of group MAILBOX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MRT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MRT_Peripheral_Access_Layer MRT Peripheral Access Layer + * @{ + */ + +/** MRT - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x10 */ + __IO uint32_t INTVAL; /**< MRT Time interval value register. This value is loaded into the TIMER register., array offset: 0x0, array step: 0x10 */ + __I uint32_t TIMER; /**< MRT Timer register. This register reads the value of the down-counter., array offset: 0x4, array step: 0x10 */ + __IO uint32_t CTRL; /**< MRT Control register. This register controls the MRT modes., array offset: 0x8, array step: 0x10 */ + __IO uint32_t STAT; /**< MRT Status register., array offset: 0xC, array step: 0x10 */ + } CHANNEL[4]; + uint8_t RESERVED_0[176]; + __IO uint32_t MODCFG; /**< Module Configuration register. This register provides information about this particular MRT instance, and allows choosing an overall mode for the idle channel feature., offset: 0xF0 */ + __I uint32_t IDLE_CH; /**< Idle channel register. This register returns the number of the first idle channel., offset: 0xF4 */ + __IO uint32_t IRQ_FLAG; /**< Global interrupt flag register, offset: 0xF8 */ +} MRT_Type; + +/* ---------------------------------------------------------------------------- + -- MRT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MRT_Register_Masks MRT Register Masks + * @{ + */ + +/*! @name CHANNEL_INTVAL - MRT Time interval value register. This value is loaded into the TIMER register. */ +/*! @{ */ +#define MRT_CHANNEL_INTVAL_IVALUE_MASK (0xFFFFFFU) +#define MRT_CHANNEL_INTVAL_IVALUE_SHIFT (0U) +/*! IVALUE - Time interval load value. This value is loaded into the TIMERn register and the MRT + * channel n starts counting down from IVALUE -1. If the timer is idle, writing a non-zero value to + * this bit field starts the timer immediately. If the timer is running, writing a zero to this + * bit field does the following: If LOAD = 1, the timer stops immediately. If LOAD = 0, the timer + * stops at the end of the time interval. + */ +#define MRT_CHANNEL_INTVAL_IVALUE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_INTVAL_IVALUE_SHIFT)) & MRT_CHANNEL_INTVAL_IVALUE_MASK) +#define MRT_CHANNEL_INTVAL_LOAD_MASK (0x80000000U) +#define MRT_CHANNEL_INTVAL_LOAD_SHIFT (31U) +/*! LOAD - Determines how the timer interval value IVALUE -1 is loaded into the TIMERn register. + * This bit is write-only. Reading this bit always returns 0. + * 0b0..No force load. The load from the INTVALn register to the TIMERn register is processed at the end of the + * time interval if the repeat mode is selected. + * 0b1..Force load. The INTVALn interval value IVALUE -1 is immediately loaded into the TIMERn register while TIMERn is running. + */ +#define MRT_CHANNEL_INTVAL_LOAD(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_INTVAL_LOAD_SHIFT)) & MRT_CHANNEL_INTVAL_LOAD_MASK) +/*! @} */ + +/* The count of MRT_CHANNEL_INTVAL */ +#define MRT_CHANNEL_INTVAL_COUNT (4U) + +/*! @name CHANNEL_TIMER - MRT Timer register. This register reads the value of the down-counter. */ +/*! @{ */ +#define MRT_CHANNEL_TIMER_VALUE_MASK (0xFFFFFFU) +#define MRT_CHANNEL_TIMER_VALUE_SHIFT (0U) +/*! VALUE - Holds the current timer value of the down-counter. The initial value of the TIMERn + * register is loaded as IVALUE - 1 from the INTVALn register either at the end of the time interval + * or immediately in the following cases: INTVALn register is updated in the idle state. INTVALn + * register is updated with LOAD = 1. When the timer is in idle state, reading this bit fields + * returns -1 (0x00FF FFFF). + */ +#define MRT_CHANNEL_TIMER_VALUE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_TIMER_VALUE_SHIFT)) & MRT_CHANNEL_TIMER_VALUE_MASK) +/*! @} */ + +/* The count of MRT_CHANNEL_TIMER */ +#define MRT_CHANNEL_TIMER_COUNT (4U) + +/*! @name CHANNEL_CTRL - MRT Control register. This register controls the MRT modes. */ +/*! @{ */ +#define MRT_CHANNEL_CTRL_INTEN_MASK (0x1U) +#define MRT_CHANNEL_CTRL_INTEN_SHIFT (0U) +/*! INTEN - Enable the TIMERn interrupt. + * 0b0..Disabled. TIMERn interrupt is disabled. + * 0b1..Enabled. TIMERn interrupt is enabled. + */ +#define MRT_CHANNEL_CTRL_INTEN(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_CTRL_INTEN_SHIFT)) & MRT_CHANNEL_CTRL_INTEN_MASK) +#define MRT_CHANNEL_CTRL_MODE_MASK (0x6U) +#define MRT_CHANNEL_CTRL_MODE_SHIFT (1U) +/*! MODE - Selects timer mode. + * 0b00..Repeat interrupt mode. + * 0b01..One-shot interrupt mode. + * 0b10..One-shot stall mode. + * 0b11..Reserved. + */ +#define MRT_CHANNEL_CTRL_MODE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_CTRL_MODE_SHIFT)) & MRT_CHANNEL_CTRL_MODE_MASK) +/*! @} */ + +/* The count of MRT_CHANNEL_CTRL */ +#define MRT_CHANNEL_CTRL_COUNT (4U) + +/*! @name CHANNEL_STAT - MRT Status register. */ +/*! @{ */ +#define MRT_CHANNEL_STAT_INTFLAG_MASK (0x1U) +#define MRT_CHANNEL_STAT_INTFLAG_SHIFT (0U) +/*! INTFLAG - Monitors the interrupt flag. + * 0b0..No pending interrupt. Writing a zero is equivalent to no operation. + * 0b1..Pending interrupt. The interrupt is pending because TIMERn has reached the end of the time interval. If + * the INTEN bit in the CONTROLn is also set to 1, the interrupt for timer channel n and the global interrupt + * are raised. Writing a 1 to this bit clears the interrupt request. + */ +#define MRT_CHANNEL_STAT_INTFLAG(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_INTFLAG_SHIFT)) & MRT_CHANNEL_STAT_INTFLAG_MASK) +#define MRT_CHANNEL_STAT_RUN_MASK (0x2U) +#define MRT_CHANNEL_STAT_RUN_SHIFT (1U) +/*! RUN - Indicates the state of TIMERn. This bit is read-only. + * 0b0..Idle state. TIMERn is stopped. + * 0b1..Running. TIMERn is running. + */ +#define MRT_CHANNEL_STAT_RUN(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_RUN_SHIFT)) & MRT_CHANNEL_STAT_RUN_MASK) +#define MRT_CHANNEL_STAT_INUSE_MASK (0x4U) +#define MRT_CHANNEL_STAT_INUSE_SHIFT (2U) +/*! INUSE - Channel In Use flag. Operating details depend on the MULTITASK bit in the MODCFG + * register, and affects the use of IDLE_CH. See Idle channel register for details of the two operating + * modes. + * 0b0..This channel is not in use. + * 0b1..This channel is in use. + */ +#define MRT_CHANNEL_STAT_INUSE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_INUSE_SHIFT)) & MRT_CHANNEL_STAT_INUSE_MASK) +/*! @} */ + +/* The count of MRT_CHANNEL_STAT */ +#define MRT_CHANNEL_STAT_COUNT (4U) + +/*! @name MODCFG - Module Configuration register. This register provides information about this particular MRT instance, and allows choosing an overall mode for the idle channel feature. */ +/*! @{ */ +#define MRT_MODCFG_NOC_MASK (0xFU) +#define MRT_MODCFG_NOC_SHIFT (0U) +/*! NOC - Identifies the number of channels in this MRT.(4 channels on this device.) + */ +#define MRT_MODCFG_NOC(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_NOC_SHIFT)) & MRT_MODCFG_NOC_MASK) +#define MRT_MODCFG_NOB_MASK (0x1F0U) +#define MRT_MODCFG_NOB_SHIFT (4U) +/*! NOB - Identifies the number of timer bits in this MRT. (24 bits wide on this device.) + */ +#define MRT_MODCFG_NOB(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_NOB_SHIFT)) & MRT_MODCFG_NOB_MASK) +#define MRT_MODCFG_MULTITASK_MASK (0x80000000U) +#define MRT_MODCFG_MULTITASK_SHIFT (31U) +/*! MULTITASK - Selects the operating mode for the INUSE flags and the IDLE_CH register. + * 0b0..Hardware status mode. In this mode, the INUSE(n) flags for all channels are reset. + * 0b1..Multi-task mode. + */ +#define MRT_MODCFG_MULTITASK(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_MULTITASK_SHIFT)) & MRT_MODCFG_MULTITASK_MASK) +/*! @} */ + +/*! @name IDLE_CH - Idle channel register. This register returns the number of the first idle channel. */ +/*! @{ */ +#define MRT_IDLE_CH_CHAN_MASK (0xF0U) +#define MRT_IDLE_CH_CHAN_SHIFT (4U) +/*! CHAN - Idle channel. Reading the CHAN bits, returns the lowest idle timer channel. The number is + * positioned such that it can be used as an offset from the MRT base address in order to access + * the registers for the allocated channel. If all timer channels are running, CHAN = 0xF. See + * text above for more details. + */ +#define MRT_IDLE_CH_CHAN(x) (((uint32_t)(((uint32_t)(x)) << MRT_IDLE_CH_CHAN_SHIFT)) & MRT_IDLE_CH_CHAN_MASK) +/*! @} */ + +/*! @name IRQ_FLAG - Global interrupt flag register */ +/*! @{ */ +#define MRT_IRQ_FLAG_GFLAG0_MASK (0x1U) +#define MRT_IRQ_FLAG_GFLAG0_SHIFT (0U) +/*! GFLAG0 - Monitors the interrupt flag of TIMER0. + * 0b0..No pending interrupt. Writing a zero is equivalent to no operation. + * 0b1..Pending interrupt. The interrupt is pending because TIMER0 has reached the end of the time interval. If + * the INTEN bit in the CONTROL0 register is also set to 1, the interrupt for timer channel 0 and the global + * interrupt are raised. Writing a 1 to this bit clears the interrupt request. + */ +#define MRT_IRQ_FLAG_GFLAG0(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG0_SHIFT)) & MRT_IRQ_FLAG_GFLAG0_MASK) +#define MRT_IRQ_FLAG_GFLAG1_MASK (0x2U) +#define MRT_IRQ_FLAG_GFLAG1_SHIFT (1U) +/*! GFLAG1 - Monitors the interrupt flag of TIMER1. See description of channel 0. + */ +#define MRT_IRQ_FLAG_GFLAG1(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG1_SHIFT)) & MRT_IRQ_FLAG_GFLAG1_MASK) +#define MRT_IRQ_FLAG_GFLAG2_MASK (0x4U) +#define MRT_IRQ_FLAG_GFLAG2_SHIFT (2U) +/*! GFLAG2 - Monitors the interrupt flag of TIMER2. See description of channel 0. + */ +#define MRT_IRQ_FLAG_GFLAG2(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG2_SHIFT)) & MRT_IRQ_FLAG_GFLAG2_MASK) +#define MRT_IRQ_FLAG_GFLAG3_MASK (0x8U) +#define MRT_IRQ_FLAG_GFLAG3_SHIFT (3U) +/*! GFLAG3 - Monitors the interrupt flag of TIMER3. See description of channel 0. + */ +#define MRT_IRQ_FLAG_GFLAG3(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG3_SHIFT)) & MRT_IRQ_FLAG_GFLAG3_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group MRT_Register_Masks */ + + +/* MRT - Peripheral instance base addresses */ +/** Peripheral MRT0 base address */ +#define MRT0_BASE (0x4000D000u) +/** Peripheral MRT0 base pointer */ +#define MRT0 ((MRT_Type *)MRT0_BASE) +/** Array initializer of MRT peripheral base addresses */ +#define MRT_BASE_ADDRS { MRT0_BASE } +/** Array initializer of MRT peripheral base pointers */ +#define MRT_BASE_PTRS { MRT0 } +/** Interrupt vectors for the MRT peripheral type */ +#define MRT_IRQS { MRT0_IRQn } + +/*! + * @} + */ /* end of group MRT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PINT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PINT_Peripheral_Access_Layer PINT Peripheral Access Layer + * @{ + */ + +/** PINT - Register Layout Typedef */ +typedef struct { + __IO uint32_t ISEL; /**< Pin Interrupt Mode register, offset: 0x0 */ + __IO uint32_t IENR; /**< Pin interrupt level or rising edge interrupt enable register, offset: 0x4 */ + __O uint32_t SIENR; /**< Pin interrupt level or rising edge interrupt set register, offset: 0x8 */ + __O uint32_t CIENR; /**< Pin interrupt level (rising edge interrupt) clear register, offset: 0xC */ + __IO uint32_t IENF; /**< Pin interrupt active level or falling edge interrupt enable register, offset: 0x10 */ + __O uint32_t SIENF; /**< Pin interrupt active level or falling edge interrupt set register, offset: 0x14 */ + __O uint32_t CIENF; /**< Pin interrupt active level or falling edge interrupt clear register, offset: 0x18 */ + __IO uint32_t RISE; /**< Pin interrupt rising edge register, offset: 0x1C */ + __IO uint32_t FALL; /**< Pin interrupt falling edge register, offset: 0x20 */ + __IO uint32_t IST; /**< Pin interrupt status register, offset: 0x24 */ + __IO uint32_t PMCTRL; /**< Pattern match interrupt control register, offset: 0x28 */ + __IO uint32_t PMSRC; /**< Pattern match interrupt bit-slice source register, offset: 0x2C */ + __IO uint32_t PMCFG; /**< Pattern match interrupt bit slice configuration register, offset: 0x30 */ +} PINT_Type; + +/* ---------------------------------------------------------------------------- + -- PINT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PINT_Register_Masks PINT Register Masks + * @{ + */ + +/*! @name ISEL - Pin Interrupt Mode register */ +/*! @{ */ +#define PINT_ISEL_PMODE_MASK (0xFFU) +#define PINT_ISEL_PMODE_SHIFT (0U) +/*! PMODE - Selects the interrupt mode for each pin interrupt. Bit n configures the pin interrupt + * selected in PINTSELn. 0 = Edge sensitive 1 = Level sensitive + */ +#define PINT_ISEL_PMODE(x) (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_SHIFT)) & PINT_ISEL_PMODE_MASK) +/*! @} */ + +/*! @name IENR - Pin interrupt level or rising edge interrupt enable register */ +/*! @{ */ +#define PINT_IENR_ENRL_MASK (0xFFU) +#define PINT_IENR_ENRL_SHIFT (0U) +/*! ENRL - Enables the rising edge or level interrupt for each pin interrupt. Bit n configures the + * pin interrupt selected in PINTSELn. 0 = Disable rising edge or level interrupt. 1 = Enable + * rising edge or level interrupt. + */ +#define PINT_IENR_ENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_SHIFT)) & PINT_IENR_ENRL_MASK) +/*! @} */ + +/*! @name SIENR - Pin interrupt level or rising edge interrupt set register */ +/*! @{ */ +#define PINT_SIENR_SETENRL_MASK (0xFFU) +#define PINT_SIENR_SETENRL_SHIFT (0U) +/*! SETENRL - Ones written to this address set bits in the IENR, thus enabling interrupts. Bit n + * sets bit n in the IENR register. 0 = No operation. 1 = Enable rising edge or level interrupt. + */ +#define PINT_SIENR_SETENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_SHIFT)) & PINT_SIENR_SETENRL_MASK) +/*! @} */ + +/*! @name CIENR - Pin interrupt level (rising edge interrupt) clear register */ +/*! @{ */ +#define PINT_CIENR_CENRL_MASK (0xFFU) +#define PINT_CIENR_CENRL_SHIFT (0U) +/*! CENRL - Ones written to this address clear bits in the IENR, thus disabling the interrupts. Bit + * n clears bit n in the IENR register. 0 = No operation. 1 = Disable rising edge or level + * interrupt. + */ +#define PINT_CIENR_CENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CENRL_SHIFT)) & PINT_CIENR_CENRL_MASK) +/*! @} */ + +/*! @name IENF - Pin interrupt active level or falling edge interrupt enable register */ +/*! @{ */ +#define PINT_IENF_ENAF_MASK (0xFFU) +#define PINT_IENF_ENAF_SHIFT (0U) +/*! ENAF - Enables the falling edge or configures the active level interrupt for each pin interrupt. + * Bit n configures the pin interrupt selected in PINTSELn. 0 = Disable falling edge interrupt + * or set active interrupt level LOW. 1 = Enable falling edge interrupt enabled or set active + * interrupt level HIGH. + */ +#define PINT_IENF_ENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_SHIFT)) & PINT_IENF_ENAF_MASK) +/*! @} */ + +/*! @name SIENF - Pin interrupt active level or falling edge interrupt set register */ +/*! @{ */ +#define PINT_SIENF_SETENAF_MASK (0xFFU) +#define PINT_SIENF_SETENAF_SHIFT (0U) +/*! SETENAF - Ones written to this address set bits in the IENF, thus enabling interrupts. Bit n + * sets bit n in the IENF register. 0 = No operation. 1 = Select HIGH-active interrupt or enable + * falling edge interrupt. + */ +#define PINT_SIENF_SETENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_SHIFT)) & PINT_SIENF_SETENAF_MASK) +/*! @} */ + +/*! @name CIENF - Pin interrupt active level or falling edge interrupt clear register */ +/*! @{ */ +#define PINT_CIENF_CENAF_MASK (0xFFU) +#define PINT_CIENF_CENAF_SHIFT (0U) +/*! CENAF - Ones written to this address clears bits in the IENF, thus disabling interrupts. Bit n + * clears bit n in the IENF register. 0 = No operation. 1 = LOW-active interrupt selected or + * falling edge interrupt disabled. + */ +#define PINT_CIENF_CENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CENAF_SHIFT)) & PINT_CIENF_CENAF_MASK) +/*! @} */ + +/*! @name RISE - Pin interrupt rising edge register */ +/*! @{ */ +#define PINT_RISE_RDET_MASK (0xFFU) +#define PINT_RISE_RDET_SHIFT (0U) +/*! RDET - Rising edge detect. Bit n detects the rising edge of the pin selected in PINTSELn. Read + * 0: No rising edge has been detected on this pin since Reset or the last time a one was written + * to this bit. Write 0: no operation. Read 1: a rising edge has been detected since Reset or the + * last time a one was written to this bit. Write 1: clear rising edge detection for this pin. + */ +#define PINT_RISE_RDET(x) (((uint32_t)(((uint32_t)(x)) << PINT_RISE_RDET_SHIFT)) & PINT_RISE_RDET_MASK) +/*! @} */ + +/*! @name FALL - Pin interrupt falling edge register */ +/*! @{ */ +#define PINT_FALL_FDET_MASK (0xFFU) +#define PINT_FALL_FDET_SHIFT (0U) +/*! FDET - Falling edge detect. Bit n detects the falling edge of the pin selected in PINTSELn. Read + * 0: No falling edge has been detected on this pin since Reset or the last time a one was + * written to this bit. Write 0: no operation. Read 1: a falling edge has been detected since Reset or + * the last time a one was written to this bit. Write 1: clear falling edge detection for this + * pin. + */ +#define PINT_FALL_FDET(x) (((uint32_t)(((uint32_t)(x)) << PINT_FALL_FDET_SHIFT)) & PINT_FALL_FDET_MASK) +/*! @} */ + +/*! @name IST - Pin interrupt status register */ +/*! @{ */ +#define PINT_IST_PSTAT_MASK (0xFFU) +#define PINT_IST_PSTAT_SHIFT (0U) +/*! PSTAT - Pin interrupt status. Bit n returns the status, clears the edge interrupt, or inverts + * the active level of the pin selected in PINTSELn. Read 0: interrupt is not being requested for + * this interrupt pin. Write 0: no operation. Read 1: interrupt is being requested for this + * interrupt pin. Write 1 (edge-sensitive): clear rising- and falling-edge detection for this pin. + * Write 1 (level-sensitive): switch the active level for this pin (in the IENF register). + */ +#define PINT_IST_PSTAT(x) (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_SHIFT)) & PINT_IST_PSTAT_MASK) +/*! @} */ + +/*! @name PMCTRL - Pattern match interrupt control register */ +/*! @{ */ +#define PINT_PMCTRL_SEL_PMATCH_MASK (0x1U) +#define PINT_PMCTRL_SEL_PMATCH_SHIFT (0U) +/*! SEL_PMATCH - Specifies whether the 8 pin interrupts are controlled by the pin interrupt function or by the pattern match function. + * 0b0..Pin interrupt. Interrupts are driven in response to the standard pin interrupt function. + * 0b1..Pattern match. Interrupts are driven in response to pattern matches. + */ +#define PINT_PMCTRL_SEL_PMATCH(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_SEL_PMATCH_SHIFT)) & PINT_PMCTRL_SEL_PMATCH_MASK) +#define PINT_PMCTRL_ENA_RXEV_MASK (0x2U) +#define PINT_PMCTRL_ENA_RXEV_SHIFT (1U) +/*! ENA_RXEV - Enables the RXEV output to the CPU and/or to a GPIO output when the specified boolean expression evaluates to true. + * 0b0..Disabled. RXEV output to the CPU is disabled. + * 0b1..Enabled. RXEV output to the CPU is enabled. + */ +#define PINT_PMCTRL_ENA_RXEV(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_ENA_RXEV_SHIFT)) & PINT_PMCTRL_ENA_RXEV_MASK) +#define PINT_PMCTRL_PMAT_MASK (0xFF000000U) +#define PINT_PMCTRL_PMAT_SHIFT (24U) +/*! PMAT - This field displays the current state of pattern matches. A 1 in any bit of this field + * indicates that the corresponding product term is matched by the current state of the appropriate + * inputs. + */ +#define PINT_PMCTRL_PMAT(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_PMAT_SHIFT)) & PINT_PMCTRL_PMAT_MASK) +/*! @} */ + +/*! @name PMSRC - Pattern match interrupt bit-slice source register */ +/*! @{ */ +#define PINT_PMSRC_SRC0_MASK (0x700U) +#define PINT_PMSRC_SRC0_SHIFT (8U) +/*! SRC0 - Selects the input source for bit slice 0 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 0. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 0. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 0. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 0. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 0. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 0. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 0. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 0. + */ +#define PINT_PMSRC_SRC0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC0_SHIFT)) & PINT_PMSRC_SRC0_MASK) +#define PINT_PMSRC_SRC1_MASK (0x3800U) +#define PINT_PMSRC_SRC1_SHIFT (11U) +/*! SRC1 - Selects the input source for bit slice 1 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 1. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 1. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 1. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 1. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 1. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 1. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 1. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 1. + */ +#define PINT_PMSRC_SRC1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC1_SHIFT)) & PINT_PMSRC_SRC1_MASK) +#define PINT_PMSRC_SRC2_MASK (0x1C000U) +#define PINT_PMSRC_SRC2_SHIFT (14U) +/*! SRC2 - Selects the input source for bit slice 2 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 2. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 2. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 2. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 2. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 2. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 2. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 2. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 2. + */ +#define PINT_PMSRC_SRC2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC2_SHIFT)) & PINT_PMSRC_SRC2_MASK) +#define PINT_PMSRC_SRC3_MASK (0xE0000U) +#define PINT_PMSRC_SRC3_SHIFT (17U) +/*! SRC3 - Selects the input source for bit slice 3 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 3. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 3. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 3. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 3. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 3. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 3. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 3. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 3. + */ +#define PINT_PMSRC_SRC3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC3_SHIFT)) & PINT_PMSRC_SRC3_MASK) +#define PINT_PMSRC_SRC4_MASK (0x700000U) +#define PINT_PMSRC_SRC4_SHIFT (20U) +/*! SRC4 - Selects the input source for bit slice 4 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 4. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 4. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 4. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 4. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 4. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 4. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 4. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 4. + */ +#define PINT_PMSRC_SRC4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC4_SHIFT)) & PINT_PMSRC_SRC4_MASK) +#define PINT_PMSRC_SRC5_MASK (0x3800000U) +#define PINT_PMSRC_SRC5_SHIFT (23U) +/*! SRC5 - Selects the input source for bit slice 5 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 5. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 5. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 5. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 5. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 5. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 5. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 5. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 5. + */ +#define PINT_PMSRC_SRC5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC5_SHIFT)) & PINT_PMSRC_SRC5_MASK) +#define PINT_PMSRC_SRC6_MASK (0x1C000000U) +#define PINT_PMSRC_SRC6_SHIFT (26U) +/*! SRC6 - Selects the input source for bit slice 6 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 6. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 6. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 6. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 6. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 6. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 6. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 6. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 6. + */ +#define PINT_PMSRC_SRC6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC6_SHIFT)) & PINT_PMSRC_SRC6_MASK) +#define PINT_PMSRC_SRC7_MASK (0xE0000000U) +#define PINT_PMSRC_SRC7_SHIFT (29U) +/*! SRC7 - Selects the input source for bit slice 7 + * 0b000..Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit slice 7. + * 0b001..Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit slice 7. + * 0b010..Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit slice 7. + * 0b011..Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit slice 7. + * 0b100..Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit slice 7. + * 0b101..Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit slice 7. + * 0b110..Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit slice 7. + * 0b111..Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit slice 7. + */ +#define PINT_PMSRC_SRC7(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC7_SHIFT)) & PINT_PMSRC_SRC7_MASK) +/*! @} */ + +/*! @name PMCFG - Pattern match interrupt bit slice configuration register */ +/*! @{ */ +#define PINT_PMCFG_PROD_ENDPTS0_MASK (0x1U) +#define PINT_PMCFG_PROD_ENDPTS0_SHIFT (0U) +/*! PROD_ENDPTS0 - Determines whether slice 0 is an endpoint. + * 0b0..No effect. Slice 0 is not an endpoint. + * 0b1..endpoint. Slice 0 is the endpoint of a product term (minterm). Pin interrupt 0 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS0_SHIFT)) & PINT_PMCFG_PROD_ENDPTS0_MASK) +#define PINT_PMCFG_PROD_ENDPTS1_MASK (0x2U) +#define PINT_PMCFG_PROD_ENDPTS1_SHIFT (1U) +/*! PROD_ENDPTS1 - Determines whether slice 1 is an endpoint. + * 0b0..No effect. Slice 1 is not an endpoint. + * 0b1..endpoint. Slice 1 is the endpoint of a product term (minterm). Pin interrupt 1 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS1_SHIFT)) & PINT_PMCFG_PROD_ENDPTS1_MASK) +#define PINT_PMCFG_PROD_ENDPTS2_MASK (0x4U) +#define PINT_PMCFG_PROD_ENDPTS2_SHIFT (2U) +/*! PROD_ENDPTS2 - Determines whether slice 2 is an endpoint. + * 0b0..No effect. Slice 2 is not an endpoint. + * 0b1..endpoint. Slice 2 is the endpoint of a product term (minterm). Pin interrupt 2 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS2_SHIFT)) & PINT_PMCFG_PROD_ENDPTS2_MASK) +#define PINT_PMCFG_PROD_ENDPTS3_MASK (0x8U) +#define PINT_PMCFG_PROD_ENDPTS3_SHIFT (3U) +/*! PROD_ENDPTS3 - Determines whether slice 3 is an endpoint. + * 0b0..No effect. Slice 3 is not an endpoint. + * 0b1..endpoint. Slice 3 is the endpoint of a product term (minterm). Pin interrupt 3 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS3_SHIFT)) & PINT_PMCFG_PROD_ENDPTS3_MASK) +#define PINT_PMCFG_PROD_ENDPTS4_MASK (0x10U) +#define PINT_PMCFG_PROD_ENDPTS4_SHIFT (4U) +/*! PROD_ENDPTS4 - Determines whether slice 4 is an endpoint. + * 0b0..No effect. Slice 4 is not an endpoint. + * 0b1..endpoint. Slice 4 is the endpoint of a product term (minterm). Pin interrupt 4 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS4_SHIFT)) & PINT_PMCFG_PROD_ENDPTS4_MASK) +#define PINT_PMCFG_PROD_ENDPTS5_MASK (0x20U) +#define PINT_PMCFG_PROD_ENDPTS5_SHIFT (5U) +/*! PROD_ENDPTS5 - Determines whether slice 5 is an endpoint. + * 0b0..No effect. Slice 5 is not an endpoint. + * 0b1..endpoint. Slice 5 is the endpoint of a product term (minterm). Pin interrupt 5 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS5_SHIFT)) & PINT_PMCFG_PROD_ENDPTS5_MASK) +#define PINT_PMCFG_PROD_ENDPTS6_MASK (0x40U) +#define PINT_PMCFG_PROD_ENDPTS6_SHIFT (6U) +/*! PROD_ENDPTS6 - Determines whether slice 6 is an endpoint. + * 0b0..No effect. Slice 6 is not an endpoint. + * 0b1..endpoint. Slice 6 is the endpoint of a product term (minterm). Pin interrupt 6 in the NVIC is raised if the minterm evaluates as true. + */ +#define PINT_PMCFG_PROD_ENDPTS6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS6_SHIFT)) & PINT_PMCFG_PROD_ENDPTS6_MASK) +#define PINT_PMCFG_CFG0_MASK (0x700U) +#define PINT_PMCFG_CFG0_SHIFT (8U) +/*! CFG0 - Specifies the match contribution condition for bit slice 0. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG0_SHIFT)) & PINT_PMCFG_CFG0_MASK) +#define PINT_PMCFG_CFG1_MASK (0x3800U) +#define PINT_PMCFG_CFG1_SHIFT (11U) +/*! CFG1 - Specifies the match contribution condition for bit slice 1. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG1_SHIFT)) & PINT_PMCFG_CFG1_MASK) +#define PINT_PMCFG_CFG2_MASK (0x1C000U) +#define PINT_PMCFG_CFG2_SHIFT (14U) +/*! CFG2 - Specifies the match contribution condition for bit slice 2. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG2_SHIFT)) & PINT_PMCFG_CFG2_MASK) +#define PINT_PMCFG_CFG3_MASK (0xE0000U) +#define PINT_PMCFG_CFG3_SHIFT (17U) +/*! CFG3 - Specifies the match contribution condition for bit slice 3. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG3_SHIFT)) & PINT_PMCFG_CFG3_MASK) +#define PINT_PMCFG_CFG4_MASK (0x700000U) +#define PINT_PMCFG_CFG4_SHIFT (20U) +/*! CFG4 - Specifies the match contribution condition for bit slice 4. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG4_SHIFT)) & PINT_PMCFG_CFG4_MASK) +#define PINT_PMCFG_CFG5_MASK (0x3800000U) +#define PINT_PMCFG_CFG5_SHIFT (23U) +/*! CFG5 - Specifies the match contribution condition for bit slice 5. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG5_SHIFT)) & PINT_PMCFG_CFG5_MASK) +#define PINT_PMCFG_CFG6_MASK (0x1C000000U) +#define PINT_PMCFG_CFG6_SHIFT (26U) +/*! CFG6 - Specifies the match contribution condition for bit slice 6. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG6_SHIFT)) & PINT_PMCFG_CFG6_MASK) +#define PINT_PMCFG_CFG7_MASK (0xE0000000U) +#define PINT_PMCFG_CFG7_SHIFT (29U) +/*! CFG7 - Specifies the match contribution condition for bit slice 7. + * 0b000..Constant HIGH. This bit slice always contributes to a product term match. + * 0b001..Sticky rising edge. Match occurs if a rising edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b010..Sticky falling edge. Match occurs if a falling edge on the specified input has occurred since the last + * time the edge detection for this bit slice was cleared. This bit is only cleared when the PMCFG or the + * PMSRC registers are written to. + * 0b011..Sticky rising or falling edge. Match occurs if either a rising or falling edge on the specified input + * has occurred since the last time the edge detection for this bit slice was cleared. This bit is only + * cleared when the PMCFG or the PMSRC registers are written to. + * 0b100..High level. Match (for this bit slice) occurs when there is a high level on the input specified for this bit slice in the PMSRC register. + * 0b101..Low level. Match occurs when there is a low level on the specified input. + * 0b110..Constant 0. This bit slice never contributes to a match (should be used to disable any unused bit slices). + * 0b111..Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when either a rising or + * falling edge is first detected on the specified input (this is a non-sticky version of value 0x3) . This bit + * is cleared after one clock cycle. + */ +#define PINT_PMCFG_CFG7(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG7_SHIFT)) & PINT_PMCFG_CFG7_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group PINT_Register_Masks */ + + +/* PINT - Peripheral instance base addresses */ +/** Peripheral PINT base address */ +#define PINT_BASE (0x40004000u) +/** Peripheral PINT base pointer */ +#define PINT ((PINT_Type *)PINT_BASE) +/** Array initializer of PINT peripheral base addresses */ +#define PINT_BASE_ADDRS { PINT_BASE } +/** Array initializer of PINT peripheral base pointers */ +#define PINT_BASE_PTRS { PINT } +/** Interrupt vectors for the PINT peripheral type */ +#define PINT_IRQS { PIN_INT0_IRQn, PIN_INT1_IRQn, PIN_INT2_IRQn, PIN_INT3_IRQn, PIN_INT4_IRQn, PIN_INT5_IRQn, PIN_INT6_IRQn, PIN_INT7_IRQn } + +/*! + * @} + */ /* end of group PINT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer + * @{ + */ + +/** RTC - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< RTC control register, offset: 0x0 */ + __IO uint32_t MATCH; /**< RTC match register, offset: 0x4 */ + __IO uint32_t COUNT; /**< RTC counter register, offset: 0x8 */ + __IO uint32_t WAKE; /**< High-resolution/wake-up timer control register, offset: 0xC */ +} RTC_Type; + +/* ---------------------------------------------------------------------------- + -- RTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Register_Masks RTC Register Masks + * @{ + */ + +/*! @name CTRL - RTC control register */ +/*! @{ */ +#define RTC_CTRL_SWRESET_MASK (0x1U) +#define RTC_CTRL_SWRESET_SHIFT (0U) +/*! SWRESET - Software reset control + * 0b0..Not in reset. The RTC is not held in reset. This bit must be cleared prior to configuring or initiating any operation of the RTC. + * 0b1..In reset. The RTC is held in reset. All register bits within the RTC will be forced to their reset value + * except the OFD bit. This bit must be cleared before writing to any register in the RTC - including writes + * to set any of the other bits within this register. Do not attempt to write to any bits of this register at + * the same time that the reset bit is being cleared. + */ +#define RTC_CTRL_SWRESET(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_SWRESET_SHIFT)) & RTC_CTRL_SWRESET_MASK) +#define RTC_CTRL_ALARM1HZ_MASK (0x4U) +#define RTC_CTRL_ALARM1HZ_SHIFT (2U) +/*! ALARM1HZ - RTC 1 Hz timer alarm flag status. + * 0b0..No match. No match has occurred on the 1 Hz RTC timer. Writing a 0 has no effect. + * 0b1..Match. A match condition has occurred on the 1 Hz RTC timer. This flag generates an RTC alarm interrupt + * request RTC_ALARM which can also wake up the part from any low power mode. Writing a 1 clears this bit. + */ +#define RTC_CTRL_ALARM1HZ(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARM1HZ_SHIFT)) & RTC_CTRL_ALARM1HZ_MASK) +#define RTC_CTRL_WAKE1KHZ_MASK (0x8U) +#define RTC_CTRL_WAKE1KHZ_SHIFT (3U) +/*! WAKE1KHZ - RTC 1 kHz timer wake-up flag status. + * 0b0..Run. The RTC 1 kHz timer is running. Writing a 0 has no effect. + * 0b1..Time-out. The 1 kHz high-resolution/wake-up timer has timed out. This flag generates an RTC wake-up + * interrupt request RTC-WAKE which can also wake up the part from any low power mode. Writing a 1 clears this bit. + */ +#define RTC_CTRL_WAKE1KHZ(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKE1KHZ_SHIFT)) & RTC_CTRL_WAKE1KHZ_MASK) +#define RTC_CTRL_ALARMDPD_EN_MASK (0x10U) +#define RTC_CTRL_ALARMDPD_EN_SHIFT (4U) +/*! ALARMDPD_EN - RTC 1 Hz timer alarm enable for Deep power-down. + * 0b0..Disable. A match on the 1 Hz RTC timer will not bring the part out of Deep power-down mode. + * 0b1..Enable. A match on the 1 Hz RTC timer bring the part out of Deep power-down mode. + */ +#define RTC_CTRL_ALARMDPD_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARMDPD_EN_SHIFT)) & RTC_CTRL_ALARMDPD_EN_MASK) +#define RTC_CTRL_WAKEDPD_EN_MASK (0x20U) +#define RTC_CTRL_WAKEDPD_EN_SHIFT (5U) +/*! WAKEDPD_EN - RTC 1 kHz timer wake-up enable for Deep power-down. + * 0b0..Disable. A match on the 1 kHz RTC timer will not bring the part out of Deep power-down mode. + * 0b1..Enable. A match on the 1 kHz RTC timer bring the part out of Deep power-down mode. + */ +#define RTC_CTRL_WAKEDPD_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKEDPD_EN_SHIFT)) & RTC_CTRL_WAKEDPD_EN_MASK) +#define RTC_CTRL_RTC1KHZ_EN_MASK (0x40U) +#define RTC_CTRL_RTC1KHZ_EN_SHIFT (6U) +/*! RTC1KHZ_EN - RTC 1 kHz clock enable. This bit can be set to 0 to conserve power if the 1 kHz + * timer is not used. This bit has no effect when the RTC is disabled (bit 7 of this register is 0). + * 0b0..Disable. A match on the 1 kHz RTC timer will not bring the part out of Deep power-down mode. + * 0b1..Enable. The 1 kHz RTC timer is enabled. + */ +#define RTC_CTRL_RTC1KHZ_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC1KHZ_EN_SHIFT)) & RTC_CTRL_RTC1KHZ_EN_MASK) +#define RTC_CTRL_RTC_EN_MASK (0x80U) +#define RTC_CTRL_RTC_EN_SHIFT (7U) +/*! RTC_EN - RTC enable. + * 0b0..Disable. The RTC 1 Hz and 1 kHz clocks are shut down and the RTC operation is disabled. This bit should + * be 0 when writing to load a value in the RTC counter register. + * 0b1..Enable. The 1 Hz RTC clock is running and RTC operation is enabled. This bit must be set to initiate + * operation of the RTC. The first clock to the RTC counter occurs 1 s after this bit is set. To also enable the + * high-resolution, 1 kHz clock, set bit 6 in this register. + */ +#define RTC_CTRL_RTC_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_EN_SHIFT)) & RTC_CTRL_RTC_EN_MASK) +#define RTC_CTRL_RTC_OSC_PD_MASK (0x100U) +#define RTC_CTRL_RTC_OSC_PD_SHIFT (8U) +/*! RTC_OSC_PD - RTC oscillator power-down control. + * 0b0..See RTC_OSC_BYPASS + * 0b1..RTC oscillator is powered-down. + */ +#define RTC_CTRL_RTC_OSC_PD(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_OSC_PD_SHIFT)) & RTC_CTRL_RTC_OSC_PD_MASK) +#define RTC_CTRL_RTC_OSC_BYPASS_MASK (0x200U) +#define RTC_CTRL_RTC_OSC_BYPASS_SHIFT (9U) +/*! RTC_OSC_BYPASS - RTC oscillator bypass control. + * 0b0..RTC oscillator is in normal crystal oscillation mode. + * 0b1..RTC oscillator is bypassed. RTCXIN may be driven by an external clock. + */ +#define RTC_CTRL_RTC_OSC_BYPASS(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_OSC_BYPASS_SHIFT)) & RTC_CTRL_RTC_OSC_BYPASS_MASK) +/*! @} */ + +/*! @name MATCH - RTC match register */ +/*! @{ */ +#define RTC_MATCH_MATVAL_MASK (0xFFFFFFFFU) +#define RTC_MATCH_MATVAL_SHIFT (0U) +/*! MATVAL - Contains the match value against which the 1 Hz RTC timer will be compared to set the + * alarm flag RTC_ALARM and generate an alarm interrupt/wake-up if enabled. + */ +#define RTC_MATCH_MATVAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_MATCH_MATVAL_SHIFT)) & RTC_MATCH_MATVAL_MASK) +/*! @} */ + +/*! @name COUNT - RTC counter register */ +/*! @{ */ +#define RTC_COUNT_VAL_MASK (0xFFFFFFFFU) +#define RTC_COUNT_VAL_SHIFT (0U) +/*! VAL - A read reflects the current value of the main, 1 Hz RTC timer. A write loads a new initial + * value into the timer. The RTC counter will count up continuously at a 1 Hz rate once the RTC + * Software Reset is removed (by clearing bit 0 of the CTRL register). Only write to this + * register when the RTC_EN bit in the RTC CTRL Register is 0. The counter increments one second after + * the RTC_EN bit is set. + */ +#define RTC_COUNT_VAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_COUNT_VAL_SHIFT)) & RTC_COUNT_VAL_MASK) +/*! @} */ + +/*! @name WAKE - High-resolution/wake-up timer control register */ +/*! @{ */ +#define RTC_WAKE_VAL_MASK (0xFFFFU) +#define RTC_WAKE_VAL_SHIFT (0U) +/*! VAL - A read reflects the current value of the high-resolution/wake-up timer. A write pre-loads + * a start count value into the wake-up timer and initializes a count-down sequence. Do not write + * to this register while counting is in progress. + */ +#define RTC_WAKE_VAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAKE_VAL_SHIFT)) & RTC_WAKE_VAL_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group RTC_Register_Masks */ + + +/* RTC - Peripheral instance base addresses */ +/** Peripheral RTC base address */ +#define RTC_BASE (0x4002C000u) +/** Peripheral RTC base pointer */ +#define RTC ((RTC_Type *)RTC_BASE) +/** Array initializer of RTC peripheral base addresses */ +#define RTC_BASE_ADDRS { RTC_BASE } +/** Array initializer of RTC peripheral base pointers */ +#define RTC_BASE_PTRS { RTC } +/** Interrupt vectors for the RTC peripheral type */ +#define RTC_IRQS { RTC_IRQn } + +/*! + * @} + */ /* end of group RTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SCT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SCT_Peripheral_Access_Layer SCT Peripheral Access Layer + * @{ + */ + +/** SCT - Register Layout Typedef */ +typedef struct { + __IO uint32_t CONFIG; /**< SCT configuration register, offset: 0x0 */ + union { /* offset: 0x4 */ + struct { /* offset: 0x4 */ + __IO uint16_t CTRLL; /**< SCT_CTRLL register, offset: 0x4 */ + __IO uint16_t CTRLH; /**< SCT_CTRLH register, offset: 0x6 */ + } CTRL_ACCESS16BIT; + __IO uint32_t CTRL; /**< SCT control register, offset: 0x4 */ + }; + union { /* offset: 0x8 */ + struct { /* offset: 0x8 */ + __IO uint16_t LIMITL; /**< SCT_LIMITL register, offset: 0x8 */ + __IO uint16_t LIMITH; /**< SCT_LIMITH register, offset: 0xA */ + } LIMIT_ACCESS16BIT; + __IO uint32_t LIMIT; /**< SCT limit event select register, offset: 0x8 */ + }; + union { /* offset: 0xC */ + struct { /* offset: 0xC */ + __IO uint16_t HALTL; /**< SCT_HALTL register, offset: 0xC */ + __IO uint16_t HALTH; /**< SCT_HALTH register, offset: 0xE */ + } HALT_ACCESS16BIT; + __IO uint32_t HALT; /**< SCT halt event select register, offset: 0xC */ + }; + union { /* offset: 0x10 */ + struct { /* offset: 0x10 */ + __IO uint16_t STOPL; /**< SCT_STOPL register, offset: 0x10 */ + __IO uint16_t STOPH; /**< SCT_STOPH register, offset: 0x12 */ + } STOP_ACCESS16BIT; + __IO uint32_t STOP; /**< SCT stop event select register, offset: 0x10 */ + }; + union { /* offset: 0x14 */ + struct { /* offset: 0x14 */ + __IO uint16_t STARTL; /**< SCT_STARTL register, offset: 0x14 */ + __IO uint16_t STARTH; /**< SCT_STARTH register, offset: 0x16 */ + } START_ACCESS16BIT; + __IO uint32_t START; /**< SCT start event select register, offset: 0x14 */ + }; + uint8_t RESERVED_0[40]; + union { /* offset: 0x40 */ + struct { /* offset: 0x40 */ + __IO uint16_t COUNTL; /**< SCT_COUNTL register, offset: 0x40 */ + __IO uint16_t COUNTH; /**< SCT_COUNTH register, offset: 0x42 */ + } COUNT_ACCESS16BIT; + __IO uint32_t COUNT; /**< SCT counter register, offset: 0x40 */ + }; + union { /* offset: 0x44 */ + struct { /* offset: 0x44 */ + __IO uint16_t STATEL; /**< SCT_STATEL register, offset: 0x44 */ + __IO uint16_t STATEH; /**< SCT_STATEH register, offset: 0x46 */ + } STATE_ACCESS16BIT; + __IO uint32_t STATE; /**< SCT state register, offset: 0x44 */ + }; + __I uint32_t INPUT; /**< SCT input register, offset: 0x48 */ + union { /* offset: 0x4C */ + struct { /* offset: 0x4C */ + __IO uint16_t REGMODEL; /**< SCT_REGMODEL register, offset: 0x4C */ + __IO uint16_t REGMODEH; /**< SCT_REGMODEH register, offset: 0x4E */ + } REGMODE_ACCESS16BIT; + __IO uint32_t REGMODE; /**< SCT match/capture mode register, offset: 0x4C */ + }; + __IO uint32_t OUTPUT; /**< SCT output register, offset: 0x50 */ + __IO uint32_t OUTPUTDIRCTRL; /**< SCT output counter direction control register, offset: 0x54 */ + __IO uint32_t RES; /**< SCT conflict resolution register, offset: 0x58 */ + __IO uint32_t DMAREQ0; /**< SCT DMA request 0 register, offset: 0x5C */ + __IO uint32_t DMAREQ1; /**< SCT DMA request 1 register, offset: 0x60 */ + uint8_t RESERVED_1[140]; + __IO uint32_t EVEN; /**< SCT event interrupt enable register, offset: 0xF0 */ + __IO uint32_t EVFLAG; /**< SCT event flag register, offset: 0xF4 */ + __IO uint32_t CONEN; /**< SCT conflict interrupt enable register, offset: 0xF8 */ + __IO uint32_t CONFLAG; /**< SCT conflict flag register, offset: 0xFC */ + union { /* offset: 0x100 */ + union { /* offset: 0x100, array step: 0x4 */ + struct { /* offset: 0x100, array step: 0x4 */ + __IO uint16_t CAPL; /**< SCT_CAPL register, array offset: 0x100, array step: 0x4 */ + __IO uint16_t CAPH; /**< SCT_CAPH register, array offset: 0x102, array step: 0x4 */ + } CAP_ACCESS16BIT[10]; + __IO uint32_t CAP[10]; /**< SCT capture register of capture channel, array offset: 0x100, array step: 0x4 */ + }; + union { /* offset: 0x100, array step: 0x4 */ + struct { /* offset: 0x100, array step: 0x4 */ + __IO uint16_t MATCHL; /**< SCT_MATCHL register, array offset: 0x100, array step: 0x4 */ + __IO uint16_t MATCHH; /**< SCT_MATCHH register, array offset: 0x102, array step: 0x4 */ + } MATCH_ACCESS16BIT[10]; + __IO uint32_t MATCH[10]; /**< SCT match value register of match channels, array offset: 0x100, array step: 0x4 */ + }; + }; + uint8_t RESERVED_2[216]; + union { /* offset: 0x200 */ + union { /* offset: 0x200, array step: 0x4 */ + struct { /* offset: 0x200, array step: 0x4 */ + __IO uint16_t CAPCTRLL; /**< SCT_CAPCTRLL register, array offset: 0x200, array step: 0x4 */ + __IO uint16_t CAPCTRLH; /**< SCT_CAPCTRLH register, array offset: 0x202, array step: 0x4 */ + } CAPCTRL_ACCESS16BIT[10]; + __IO uint32_t CAPCTRL[10]; /**< SCT capture control register, array offset: 0x200, array step: 0x4 */ + }; + union { /* offset: 0x200, array step: 0x4 */ + struct { /* offset: 0x200, array step: 0x4 */ + __IO uint16_t MATCHRELL; /**< SCT_MATCHRELL register, array offset: 0x200, array step: 0x4 */ + __IO uint16_t MATCHRELH; /**< SCT_MATCHRELH register, array offset: 0x202, array step: 0x4 */ + } MATCHREL_ACCESS16BIT[10]; + __IO uint32_t MATCHREL[10]; /**< SCT match reload value register, array offset: 0x200, array step: 0x4 */ + }; + }; + uint8_t RESERVED_3[216]; + struct { /* offset: 0x300, array step: 0x8 */ + __IO uint32_t STATE; /**< SCT event state register 0, array offset: 0x300, array step: 0x8 */ + __IO uint32_t CTRL; /**< SCT event control register 0, array offset: 0x304, array step: 0x8 */ + } EV[10]; + uint8_t RESERVED_4[432]; + struct { /* offset: 0x500, array step: 0x8 */ + __IO uint32_t SET; /**< SCT output 0 set register, array offset: 0x500, array step: 0x8 */ + __IO uint32_t CLR; /**< SCT output 0 clear register, array offset: 0x504, array step: 0x8 */ + } OUT[8]; +} SCT_Type; + +/* ---------------------------------------------------------------------------- + -- SCT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SCT_Register_Masks SCT Register Masks + * @{ + */ + +/*! @name CONFIG - SCT configuration register */ +/*! @{ */ +#define SCT_CONFIG_UNIFY_MASK (0x1U) +#define SCT_CONFIG_UNIFY_SHIFT (0U) +/*! UNIFY - SCT operation + * 0b0..The SCT operates as two 16-bit counters named COUNTER_L and COUNTER_H. + * 0b1..The SCT operates as a unified 32-bit counter. + */ +#define SCT_CONFIG_UNIFY(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_UNIFY_SHIFT)) & SCT_CONFIG_UNIFY_MASK) +#define SCT_CONFIG_CLKMODE_MASK (0x6U) +#define SCT_CONFIG_CLKMODE_SHIFT (1U) +/*! CLKMODE - SCT clock mode + * 0b00..System Clock Mode. The system clock clocks the entire SCT module including the counter(s) and counter prescalers. + * 0b01..Sampled System Clock Mode. The system clock clocks the SCT module, but the counter and prescalers are + * only enabled to count when the designated edge is detected on the input selected by the CKSEL field. The + * minimum pulse width on the selected clock-gate input is 1 bus clock period. This mode is the + * high-performance, sampled-clock mode. + * 0b10..SCT Input Clock Mode. The input/edge selected by the CKSEL field clocks the SCT module, including the + * counters and prescalers, after first being synchronized to the system clock. The minimum pulse width on the + * clock input is 1 bus clock period. This mode is the low-power, sampled-clock mode. + * 0b11..Asynchronous Mode. The entire SCT module is clocked directly by the input/edge selected by the CKSEL + * field. In this mode, the SCT outputs are switched synchronously to the SCT input clock - not the system + * clock. The input clock rate must be at least half the system clock rate and can be the same or faster than + * the system clock. + */ +#define SCT_CONFIG_CLKMODE(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_CLKMODE_SHIFT)) & SCT_CONFIG_CLKMODE_MASK) +#define SCT_CONFIG_CKSEL_MASK (0x78U) +#define SCT_CONFIG_CKSEL_SHIFT (3U) +/*! CKSEL - SCT clock select. The specific functionality of the designated input/edge is dependent + * on the CLKMODE bit selection in this register. + * 0b0000..Rising edges on input 0. + * 0b0001..Falling edges on input 0. + * 0b0010..Rising edges on input 1. + * 0b0011..Falling edges on input 1. + * 0b0100..Rising edges on input 2. + * 0b0101..Falling edges on input 2. + * 0b0110..Rising edges on input 3. + * 0b0111..Falling edges on input 3. + * 0b1000..Rising edges on input 4. + * 0b1001..Falling edges on input 4. + * 0b1010..Rising edges on input 5. + * 0b1011..Falling edges on input 5. + * 0b1100..Rising edges on input 6. + * 0b1101..Falling edges on input 6. + * 0b1110..Rising edges on input 7. + * 0b1111..Falling edges on input 7. + */ +#define SCT_CONFIG_CKSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_CKSEL_SHIFT)) & SCT_CONFIG_CKSEL_MASK) +#define SCT_CONFIG_NORELOAD_L_MASK (0x80U) +#define SCT_CONFIG_NORELOAD_L_SHIFT (7U) +/*! NORELOAD_L - A 1 in this bit prevents the lower match registers from being reloaded from their + * respective reload registers. Setting this bit eliminates the need to write to the reload + * registers MATCHREL if the match values are fixed. Software can write to set or clear this bit at any + * time. This bit applies to both the higher and lower registers when the UNIFY bit is set. + */ +#define SCT_CONFIG_NORELOAD_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_NORELOAD_L_SHIFT)) & SCT_CONFIG_NORELOAD_L_MASK) +#define SCT_CONFIG_NORELOAD_H_MASK (0x100U) +#define SCT_CONFIG_NORELOAD_H_SHIFT (8U) +/*! NORELOAD_H - A 1 in this bit prevents the higher match registers from being reloaded from their + * respective reload registers. Setting this bit eliminates the need to write to the reload + * registers MATCHREL if the match values are fixed. Software can write to set or clear this bit at + * any time. This bit is not used when the UNIFY bit is set. + */ +#define SCT_CONFIG_NORELOAD_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_NORELOAD_H_SHIFT)) & SCT_CONFIG_NORELOAD_H_MASK) +#define SCT_CONFIG_INSYNC_MASK (0x1E00U) +#define SCT_CONFIG_INSYNC_SHIFT (9U) +/*! INSYNC - Synchronization for input N (bit 9 = input 0, bit 10 = input 1,, bit 12 = input 3); all + * other bits are reserved. A 1 in one of these bits subjects the corresponding input to + * synchronization to the SCT clock, before it is used to create an event. If an input is known to + * already be synchronous to the SCT clock, this bit may be set to 0 for faster input response. (Note: + * The SCT clock is the system clock for CKMODEs 0-2. It is the selected, asynchronous SCT input + * clock for CKMODE3). Note that the INSYNC field only affects inputs used for event generation. + * It does not apply to the clock input specified in the CKSEL field. + */ +#define SCT_CONFIG_INSYNC(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_INSYNC_SHIFT)) & SCT_CONFIG_INSYNC_MASK) +#define SCT_CONFIG_AUTOLIMIT_L_MASK (0x20000U) +#define SCT_CONFIG_AUTOLIMIT_L_SHIFT (17U) +/*! AUTOLIMIT_L - A one in this bit causes a match on match register 0 to be treated as a de-facto + * LIMIT condition without the need to define an associated event. As with any LIMIT event, this + * automatic limit causes the counter to be cleared to zero in unidirectional mode or to change + * the direction of count in bi-directional mode. Software can write to set or clear this bit at + * any time. This bit applies to both the higher and lower registers when the UNIFY bit is set. + */ +#define SCT_CONFIG_AUTOLIMIT_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_AUTOLIMIT_L_SHIFT)) & SCT_CONFIG_AUTOLIMIT_L_MASK) +#define SCT_CONFIG_AUTOLIMIT_H_MASK (0x40000U) +#define SCT_CONFIG_AUTOLIMIT_H_SHIFT (18U) +/*! AUTOLIMIT_H - A one in this bit will cause a match on match register 0 to be treated as a + * de-facto LIMIT condition without the need to define an associated event. As with any LIMIT event, + * this automatic limit causes the counter to be cleared to zero in unidirectional mode or to + * change the direction of count in bi-directional mode. Software can write to set or clear this bit + * at any time. This bit is not used when the UNIFY bit is set. + */ +#define SCT_CONFIG_AUTOLIMIT_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_AUTOLIMIT_H_SHIFT)) & SCT_CONFIG_AUTOLIMIT_H_MASK) +/*! @} */ + +/*! @name CTRLL - SCT_CTRLL register */ +/*! @{ */ +#define SCT_CTRLL_DOWN_L_MASK (0x1U) +#define SCT_CTRLL_DOWN_L_SHIFT (0U) +/*! DOWN_L - This bit is 1 when the L or unified counter is counting down. Hardware sets this bit + * when the counter is counting up, counter limit occurs, and BIDIR = 1.Hardware clears this bit + * when the counter is counting down and a limit condition occurs or when the counter reaches 0. + */ +#define SCT_CTRLL_DOWN_L(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLL_DOWN_L_SHIFT)) & SCT_CTRLL_DOWN_L_MASK) +#define SCT_CTRLL_STOP_L_MASK (0x2U) +#define SCT_CTRLL_STOP_L_SHIFT (1U) +/*! STOP_L - When this bit is 1 and HALT is 0, the L or unified counter does not run, but I/O events + * related to the counter can occur. If a designated start event occurs, this bit is cleared and + * counting resumes. + */ +#define SCT_CTRLL_STOP_L(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLL_STOP_L_SHIFT)) & SCT_CTRLL_STOP_L_MASK) +#define SCT_CTRLL_HALT_L_MASK (0x4U) +#define SCT_CTRLL_HALT_L_SHIFT (2U) +/*! HALT_L - When this bit is 1, the L or unified counter does not run and no events can occur. A + * reset sets this bit. When the HALT_L bit is one, the STOP_L bit is cleared. It is possible to + * remove the halt condition while keeping the SCT in the stop condition (not running) with a + * single write to this register to simultaneously clear the HALT bit and set the STOP bit. Once set, + * only software can clear this bit to restore counter operation. This bit is set on reset. + */ +#define SCT_CTRLL_HALT_L(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLL_HALT_L_SHIFT)) & SCT_CTRLL_HALT_L_MASK) +#define SCT_CTRLL_CLRCTR_L_MASK (0x8U) +#define SCT_CTRLL_CLRCTR_L_SHIFT (3U) +/*! CLRCTR_L - Writing a 1 to this bit clears the L or unified counter. This bit always reads as 0. + */ +#define SCT_CTRLL_CLRCTR_L(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLL_CLRCTR_L_SHIFT)) & SCT_CTRLL_CLRCTR_L_MASK) +#define SCT_CTRLL_BIDIR_L_MASK (0x10U) +#define SCT_CTRLL_BIDIR_L_SHIFT (4U) +/*! BIDIR_L - L or unified counter direction select + * 0b0..Up. The counter counts up to a limit condition, then is cleared to zero. + * 0b1..Up-down. The counter counts up to a limit, then counts down to a limit condition or to 0. + */ +#define SCT_CTRLL_BIDIR_L(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLL_BIDIR_L_SHIFT)) & SCT_CTRLL_BIDIR_L_MASK) +#define SCT_CTRLL_PRE_L_MASK (0x1FE0U) +#define SCT_CTRLL_PRE_L_SHIFT (5U) +/*! PRE_L - Specifies the factor by which the SCT clock is prescaled to produce the L or unified + * counter clock. The counter clock is clocked at the rate of the SCT clock divided by PRE_L+1. + * Clear the counter (by writing a 1 to the CLRCTR bit) whenever changing the PRE value. + */ +#define SCT_CTRLL_PRE_L(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLL_PRE_L_SHIFT)) & SCT_CTRLL_PRE_L_MASK) +/*! @} */ + +/*! @name CTRLH - SCT_CTRLH register */ +/*! @{ */ +#define SCT_CTRLH_DOWN_H_MASK (0x1U) +#define SCT_CTRLH_DOWN_H_SHIFT (0U) +/*! DOWN_H - This bit is 1 when the H counter is counting down. Hardware sets this bit when the + * counter is counting, a counter limit condition occurs, and BIDIR is 1. Hardware clears this bit + * when the counter is counting down and a limit condition occurs or when the counter reaches 0. + */ +#define SCT_CTRLH_DOWN_H(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLH_DOWN_H_SHIFT)) & SCT_CTRLH_DOWN_H_MASK) +#define SCT_CTRLH_STOP_H_MASK (0x2U) +#define SCT_CTRLH_STOP_H_SHIFT (1U) +/*! STOP_H - When this bit is 1 and HALT is 0, the H counter does not, run but I/O events related to + * the counter can occur. If such an event matches the mask in the Start register, this bit is + * cleared and counting resumes. + */ +#define SCT_CTRLH_STOP_H(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLH_STOP_H_SHIFT)) & SCT_CTRLH_STOP_H_MASK) +#define SCT_CTRLH_HALT_H_MASK (0x4U) +#define SCT_CTRLH_HALT_H_SHIFT (2U) +/*! HALT_H - When this bit is 1, the H counter does not run and no events can occur. A reset sets + * this bit. When the HALT_H bit is one, the STOP_H bit is cleared. It is possible to remove the + * halt condition while keeping the SCT in the stop condition (not running) with a single write to + * this register to simultaneously clear the HALT bit and set the STOP bit. Once set, this bit + * can only be cleared by software to restore counter operation. This bit is set on reset. + */ +#define SCT_CTRLH_HALT_H(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLH_HALT_H_SHIFT)) & SCT_CTRLH_HALT_H_MASK) +#define SCT_CTRLH_CLRCTR_H_MASK (0x8U) +#define SCT_CTRLH_CLRCTR_H_SHIFT (3U) +/*! CLRCTR_H - Writing a 1 to this bit clears the H counter. This bit always reads as 0. + */ +#define SCT_CTRLH_CLRCTR_H(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLH_CLRCTR_H_SHIFT)) & SCT_CTRLH_CLRCTR_H_MASK) +#define SCT_CTRLH_BIDIR_H_MASK (0x10U) +#define SCT_CTRLH_BIDIR_H_SHIFT (4U) +/*! BIDIR_H - Direction select + * 0b0..The H counter counts up to its limit condition, then is cleared to zero. + * 0b1..The H counter counts up to its limit, then counts down to a limit condition or to 0. + */ +#define SCT_CTRLH_BIDIR_H(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLH_BIDIR_H_SHIFT)) & SCT_CTRLH_BIDIR_H_MASK) +#define SCT_CTRLH_PRE_H_MASK (0x1FE0U) +#define SCT_CTRLH_PRE_H_SHIFT (5U) +/*! PRE_H - Specifies the factor by which the SCT clock is prescaled to produce the H counter clock. + * The counter clock is clocked at the rate of the SCT clock divided by PRELH+1. Clear the + * counter (by writing a 1 to the CLRCTR bit) whenever changing the PRE value. + */ +#define SCT_CTRLH_PRE_H(x) (((uint16_t)(((uint16_t)(x)) << SCT_CTRLH_PRE_H_SHIFT)) & SCT_CTRLH_PRE_H_MASK) +/*! @} */ + +/*! @name CTRL - SCT control register */ +/*! @{ */ +#define SCT_CTRL_DOWN_L_MASK (0x1U) +#define SCT_CTRL_DOWN_L_SHIFT (0U) +/*! DOWN_L - This bit is 1 when the L or unified counter is counting down. Hardware sets this bit + * when the counter is counting up, counter limit occurs, and BIDIR = 1.Hardware clears this bit + * when the counter is counting down and a limit condition occurs or when the counter reaches 0. + */ +#define SCT_CTRL_DOWN_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_DOWN_L_SHIFT)) & SCT_CTRL_DOWN_L_MASK) +#define SCT_CTRL_STOP_L_MASK (0x2U) +#define SCT_CTRL_STOP_L_SHIFT (1U) +/*! STOP_L - When this bit is 1 and HALT is 0, the L or unified counter does not run, but I/O events + * related to the counter can occur. If a designated start event occurs, this bit is cleared and + * counting resumes. + */ +#define SCT_CTRL_STOP_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_STOP_L_SHIFT)) & SCT_CTRL_STOP_L_MASK) +#define SCT_CTRL_HALT_L_MASK (0x4U) +#define SCT_CTRL_HALT_L_SHIFT (2U) +/*! HALT_L - When this bit is 1, the L or unified counter does not run and no events can occur. A + * reset sets this bit. When the HALT_L bit is one, the STOP_L bit is cleared. It is possible to + * remove the halt condition while keeping the SCT in the stop condition (not running) with a + * single write to this register to simultaneously clear the HALT bit and set the STOP bit. Once set, + * only software can clear this bit to restore counter operation. This bit is set on reset. + */ +#define SCT_CTRL_HALT_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_HALT_L_SHIFT)) & SCT_CTRL_HALT_L_MASK) +#define SCT_CTRL_CLRCTR_L_MASK (0x8U) +#define SCT_CTRL_CLRCTR_L_SHIFT (3U) +/*! CLRCTR_L - Writing a 1 to this bit clears the L or unified counter. This bit always reads as 0. + */ +#define SCT_CTRL_CLRCTR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_CLRCTR_L_SHIFT)) & SCT_CTRL_CLRCTR_L_MASK) +#define SCT_CTRL_BIDIR_L_MASK (0x10U) +#define SCT_CTRL_BIDIR_L_SHIFT (4U) +/*! BIDIR_L - L or unified counter direction select + * 0b0..Up. The counter counts up to a limit condition, then is cleared to zero. + * 0b1..Up-down. The counter counts up to a limit, then counts down to a limit condition or to 0. + */ +#define SCT_CTRL_BIDIR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_BIDIR_L_SHIFT)) & SCT_CTRL_BIDIR_L_MASK) +#define SCT_CTRL_PRE_L_MASK (0x1FE0U) +#define SCT_CTRL_PRE_L_SHIFT (5U) +/*! PRE_L - Specifies the factor by which the SCT clock is prescaled to produce the L or unified + * counter clock. The counter clock is clocked at the rate of the SCT clock divided by PRE_L+1. + * Clear the counter (by writing a 1 to the CLRCTR bit) whenever changing the PRE value. + */ +#define SCT_CTRL_PRE_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_PRE_L_SHIFT)) & SCT_CTRL_PRE_L_MASK) +#define SCT_CTRL_DOWN_H_MASK (0x10000U) +#define SCT_CTRL_DOWN_H_SHIFT (16U) +/*! DOWN_H - This bit is 1 when the H counter is counting down. Hardware sets this bit when the + * counter is counting, a counter limit condition occurs, and BIDIR is 1. Hardware clears this bit + * when the counter is counting down and a limit condition occurs or when the counter reaches 0. + */ +#define SCT_CTRL_DOWN_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_DOWN_H_SHIFT)) & SCT_CTRL_DOWN_H_MASK) +#define SCT_CTRL_STOP_H_MASK (0x20000U) +#define SCT_CTRL_STOP_H_SHIFT (17U) +/*! STOP_H - When this bit is 1 and HALT is 0, the H counter does not, run but I/O events related to + * the counter can occur. If such an event matches the mask in the Start register, this bit is + * cleared and counting resumes. + */ +#define SCT_CTRL_STOP_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_STOP_H_SHIFT)) & SCT_CTRL_STOP_H_MASK) +#define SCT_CTRL_HALT_H_MASK (0x40000U) +#define SCT_CTRL_HALT_H_SHIFT (18U) +/*! HALT_H - When this bit is 1, the H counter does not run and no events can occur. A reset sets + * this bit. When the HALT_H bit is one, the STOP_H bit is cleared. It is possible to remove the + * halt condition while keeping the SCT in the stop condition (not running) with a single write to + * this register to simultaneously clear the HALT bit and set the STOP bit. Once set, this bit + * can only be cleared by software to restore counter operation. This bit is set on reset. + */ +#define SCT_CTRL_HALT_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_HALT_H_SHIFT)) & SCT_CTRL_HALT_H_MASK) +#define SCT_CTRL_CLRCTR_H_MASK (0x80000U) +#define SCT_CTRL_CLRCTR_H_SHIFT (19U) +/*! CLRCTR_H - Writing a 1 to this bit clears the H counter. This bit always reads as 0. + */ +#define SCT_CTRL_CLRCTR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_CLRCTR_H_SHIFT)) & SCT_CTRL_CLRCTR_H_MASK) +#define SCT_CTRL_BIDIR_H_MASK (0x100000U) +#define SCT_CTRL_BIDIR_H_SHIFT (20U) +/*! BIDIR_H - Direction select + * 0b0..The H counter counts up to its limit condition, then is cleared to zero. + * 0b1..The H counter counts up to its limit, then counts down to a limit condition or to 0. + */ +#define SCT_CTRL_BIDIR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_BIDIR_H_SHIFT)) & SCT_CTRL_BIDIR_H_MASK) +#define SCT_CTRL_PRE_H_MASK (0x1FE00000U) +#define SCT_CTRL_PRE_H_SHIFT (21U) +/*! PRE_H - Specifies the factor by which the SCT clock is prescaled to produce the H counter clock. + * The counter clock is clocked at the rate of the SCT clock divided by PRELH+1. Clear the + * counter (by writing a 1 to the CLRCTR bit) whenever changing the PRE value. + */ +#define SCT_CTRL_PRE_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_PRE_H_SHIFT)) & SCT_CTRL_PRE_H_MASK) +/*! @} */ + +/*! @name LIMITL - SCT_LIMITL register */ +/*! @{ */ +#define SCT_LIMITL_LIMITL_MASK (0xFFFFU) +#define SCT_LIMITL_LIMITL_SHIFT (0U) +#define SCT_LIMITL_LIMITL(x) (((uint16_t)(((uint16_t)(x)) << SCT_LIMITL_LIMITL_SHIFT)) & SCT_LIMITL_LIMITL_MASK) +/*! @} */ + +/*! @name LIMITH - SCT_LIMITH register */ +/*! @{ */ +#define SCT_LIMITH_LIMITH_MASK (0xFFFFU) +#define SCT_LIMITH_LIMITH_SHIFT (0U) +#define SCT_LIMITH_LIMITH(x) (((uint16_t)(((uint16_t)(x)) << SCT_LIMITH_LIMITH_SHIFT)) & SCT_LIMITH_LIMITH_MASK) +/*! @} */ + +/*! @name LIMIT - SCT limit event select register */ +/*! @{ */ +#define SCT_LIMIT_LIMMSK_L_MASK (0xFFFFU) +#define SCT_LIMIT_LIMMSK_L_SHIFT (0U) +/*! LIMMSK_L - If bit n is one, event n is used as a counter limit for the L or unified counter + * (event 0 = bit 0, event 1 = bit 1, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_LIMIT_LIMMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_LIMIT_LIMMSK_L_SHIFT)) & SCT_LIMIT_LIMMSK_L_MASK) +#define SCT_LIMIT_LIMMSK_H_MASK (0xFFFF0000U) +#define SCT_LIMIT_LIMMSK_H_SHIFT (16U) +/*! LIMMSK_H - If bit n is one, event n is used as a counter limit for the H counter (event 0 = bit + * 16, event 1 = bit 17, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_LIMIT_LIMMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_LIMIT_LIMMSK_H_SHIFT)) & SCT_LIMIT_LIMMSK_H_MASK) +/*! @} */ + +/*! @name HALTL - SCT_HALTL register */ +/*! @{ */ +#define SCT_HALTL_HALTL_MASK (0xFFFFU) +#define SCT_HALTL_HALTL_SHIFT (0U) +#define SCT_HALTL_HALTL(x) (((uint16_t)(((uint16_t)(x)) << SCT_HALTL_HALTL_SHIFT)) & SCT_HALTL_HALTL_MASK) +/*! @} */ + +/*! @name HALTH - SCT_HALTH register */ +/*! @{ */ +#define SCT_HALTH_HALTH_MASK (0xFFFFU) +#define SCT_HALTH_HALTH_SHIFT (0U) +#define SCT_HALTH_HALTH(x) (((uint16_t)(((uint16_t)(x)) << SCT_HALTH_HALTH_SHIFT)) & SCT_HALTH_HALTH_MASK) +/*! @} */ + +/*! @name HALT - SCT halt event select register */ +/*! @{ */ +#define SCT_HALT_HALTMSK_L_MASK (0xFFFFU) +#define SCT_HALT_HALTMSK_L_SHIFT (0U) +/*! HALTMSK_L - If bit n is one, event n sets the HALT_L bit in the CTRL register (event 0 = bit 0, + * event 1 = bit 1, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_HALT_HALTMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_HALT_HALTMSK_L_SHIFT)) & SCT_HALT_HALTMSK_L_MASK) +#define SCT_HALT_HALTMSK_H_MASK (0xFFFF0000U) +#define SCT_HALT_HALTMSK_H_SHIFT (16U) +/*! HALTMSK_H - If bit n is one, event n sets the HALT_H bit in the CTRL register (event 0 = bit 16, + * event 1 = bit 17, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_HALT_HALTMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_HALT_HALTMSK_H_SHIFT)) & SCT_HALT_HALTMSK_H_MASK) +/*! @} */ + +/*! @name STOPL - SCT_STOPL register */ +/*! @{ */ +#define SCT_STOPL_STOPL_MASK (0xFFFFU) +#define SCT_STOPL_STOPL_SHIFT (0U) +#define SCT_STOPL_STOPL(x) (((uint16_t)(((uint16_t)(x)) << SCT_STOPL_STOPL_SHIFT)) & SCT_STOPL_STOPL_MASK) +/*! @} */ + +/*! @name STOPH - SCT_STOPH register */ +/*! @{ */ +#define SCT_STOPH_STOPH_MASK (0xFFFFU) +#define SCT_STOPH_STOPH_SHIFT (0U) +#define SCT_STOPH_STOPH(x) (((uint16_t)(((uint16_t)(x)) << SCT_STOPH_STOPH_SHIFT)) & SCT_STOPH_STOPH_MASK) +/*! @} */ + +/*! @name STOP - SCT stop event select register */ +/*! @{ */ +#define SCT_STOP_STOPMSK_L_MASK (0xFFFFU) +#define SCT_STOP_STOPMSK_L_SHIFT (0U) +/*! STOPMSK_L - If bit n is one, event n sets the STOP_L bit in the CTRL register (event 0 = bit 0, + * event 1 = bit 1, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_STOP_STOPMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_STOP_STOPMSK_L_SHIFT)) & SCT_STOP_STOPMSK_L_MASK) +#define SCT_STOP_STOPMSK_H_MASK (0xFFFF0000U) +#define SCT_STOP_STOPMSK_H_SHIFT (16U) +/*! STOPMSK_H - If bit n is one, event n sets the STOP_H bit in the CTRL register (event 0 = bit 16, + * event 1 = bit 17, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_STOP_STOPMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_STOP_STOPMSK_H_SHIFT)) & SCT_STOP_STOPMSK_H_MASK) +/*! @} */ + +/*! @name STARTL - SCT_STARTL register */ +/*! @{ */ +#define SCT_STARTL_STARTL_MASK (0xFFFFU) +#define SCT_STARTL_STARTL_SHIFT (0U) +#define SCT_STARTL_STARTL(x) (((uint16_t)(((uint16_t)(x)) << SCT_STARTL_STARTL_SHIFT)) & SCT_STARTL_STARTL_MASK) +/*! @} */ + +/*! @name STARTH - SCT_STARTH register */ +/*! @{ */ +#define SCT_STARTH_STARTH_MASK (0xFFFFU) +#define SCT_STARTH_STARTH_SHIFT (0U) +#define SCT_STARTH_STARTH(x) (((uint16_t)(((uint16_t)(x)) << SCT_STARTH_STARTH_SHIFT)) & SCT_STARTH_STARTH_MASK) +/*! @} */ + +/*! @name START - SCT start event select register */ +/*! @{ */ +#define SCT_START_STARTMSK_L_MASK (0xFFFFU) +#define SCT_START_STARTMSK_L_SHIFT (0U) +/*! STARTMSK_L - If bit n is one, event n clears the STOP_L bit in the CTRL register (event 0 = bit + * 0, event 1 = bit 1, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_START_STARTMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_START_STARTMSK_L_SHIFT)) & SCT_START_STARTMSK_L_MASK) +#define SCT_START_STARTMSK_H_MASK (0xFFFF0000U) +#define SCT_START_STARTMSK_H_SHIFT (16U) +/*! STARTMSK_H - If bit n is one, event n clears the STOP_H bit in the CTRL register (event 0 = bit + * 16, event 1 = bit 17, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_START_STARTMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_START_STARTMSK_H_SHIFT)) & SCT_START_STARTMSK_H_MASK) +/*! @} */ + +/*! @name COUNTL - SCT_COUNTL register */ +/*! @{ */ +#define SCT_COUNTL_COUNTL_MASK (0xFFFFU) +#define SCT_COUNTL_COUNTL_SHIFT (0U) +#define SCT_COUNTL_COUNTL(x) (((uint16_t)(((uint16_t)(x)) << SCT_COUNTL_COUNTL_SHIFT)) & SCT_COUNTL_COUNTL_MASK) +/*! @} */ + +/*! @name COUNTH - SCT_COUNTH register */ +/*! @{ */ +#define SCT_COUNTH_COUNTH_MASK (0xFFFFU) +#define SCT_COUNTH_COUNTH_SHIFT (0U) +#define SCT_COUNTH_COUNTH(x) (((uint16_t)(((uint16_t)(x)) << SCT_COUNTH_COUNTH_SHIFT)) & SCT_COUNTH_COUNTH_MASK) +/*! @} */ + +/*! @name COUNT - SCT counter register */ +/*! @{ */ +#define SCT_COUNT_CTR_L_MASK (0xFFFFU) +#define SCT_COUNT_CTR_L_SHIFT (0U) +/*! CTR_L - When UNIFY = 0, read or write the 16-bit L counter value. When UNIFY = 1, read or write + * the lower 16 bits of the 32-bit unified counter. + */ +#define SCT_COUNT_CTR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_COUNT_CTR_L_SHIFT)) & SCT_COUNT_CTR_L_MASK) +#define SCT_COUNT_CTR_H_MASK (0xFFFF0000U) +#define SCT_COUNT_CTR_H_SHIFT (16U) +/*! CTR_H - When UNIFY = 0, read or write the 16-bit H counter value. When UNIFY = 1, read or write + * the upper 16 bits of the 32-bit unified counter. + */ +#define SCT_COUNT_CTR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_COUNT_CTR_H_SHIFT)) & SCT_COUNT_CTR_H_MASK) +/*! @} */ + +/*! @name STATEL - SCT_STATEL register */ +/*! @{ */ +#define SCT_STATEL_STATEL_MASK (0xFFFFU) +#define SCT_STATEL_STATEL_SHIFT (0U) +#define SCT_STATEL_STATEL(x) (((uint16_t)(((uint16_t)(x)) << SCT_STATEL_STATEL_SHIFT)) & SCT_STATEL_STATEL_MASK) +/*! @} */ + +/*! @name STATEH - SCT_STATEH register */ +/*! @{ */ +#define SCT_STATEH_STATEH_MASK (0xFFFFU) +#define SCT_STATEH_STATEH_SHIFT (0U) +#define SCT_STATEH_STATEH(x) (((uint16_t)(((uint16_t)(x)) << SCT_STATEH_STATEH_SHIFT)) & SCT_STATEH_STATEH_MASK) +/*! @} */ + +/*! @name STATE - SCT state register */ +/*! @{ */ +#define SCT_STATE_STATE_L_MASK (0x1FU) +#define SCT_STATE_STATE_L_SHIFT (0U) +/*! STATE_L - State variable. + */ +#define SCT_STATE_STATE_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_STATE_STATE_L_SHIFT)) & SCT_STATE_STATE_L_MASK) +#define SCT_STATE_STATE_H_MASK (0x1F0000U) +#define SCT_STATE_STATE_H_SHIFT (16U) +/*! STATE_H - State variable. + */ +#define SCT_STATE_STATE_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_STATE_STATE_H_SHIFT)) & SCT_STATE_STATE_H_MASK) +/*! @} */ + +/*! @name INPUT - SCT input register */ +/*! @{ */ +#define SCT_INPUT_AIN0_MASK (0x1U) +#define SCT_INPUT_AIN0_SHIFT (0U) +/*! AIN0 - Input 0 state. Input 0 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN0(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN0_SHIFT)) & SCT_INPUT_AIN0_MASK) +#define SCT_INPUT_AIN1_MASK (0x2U) +#define SCT_INPUT_AIN1_SHIFT (1U) +/*! AIN1 - Input 1 state. Input 1 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN1(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN1_SHIFT)) & SCT_INPUT_AIN1_MASK) +#define SCT_INPUT_AIN2_MASK (0x4U) +#define SCT_INPUT_AIN2_SHIFT (2U) +/*! AIN2 - Input 2 state. Input 2 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN2(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN2_SHIFT)) & SCT_INPUT_AIN2_MASK) +#define SCT_INPUT_AIN3_MASK (0x8U) +#define SCT_INPUT_AIN3_SHIFT (3U) +/*! AIN3 - Input 3 state. Input 3 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN3(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN3_SHIFT)) & SCT_INPUT_AIN3_MASK) +#define SCT_INPUT_AIN4_MASK (0x10U) +#define SCT_INPUT_AIN4_SHIFT (4U) +/*! AIN4 - Input 4 state. Input 4 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN4(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN4_SHIFT)) & SCT_INPUT_AIN4_MASK) +#define SCT_INPUT_AIN5_MASK (0x20U) +#define SCT_INPUT_AIN5_SHIFT (5U) +/*! AIN5 - Input 5 state. Input 5 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN5(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN5_SHIFT)) & SCT_INPUT_AIN5_MASK) +#define SCT_INPUT_AIN6_MASK (0x40U) +#define SCT_INPUT_AIN6_SHIFT (6U) +/*! AIN6 - Input 6 state. Input 6 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN6(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN6_SHIFT)) & SCT_INPUT_AIN6_MASK) +#define SCT_INPUT_AIN7_MASK (0x80U) +#define SCT_INPUT_AIN7_SHIFT (7U) +/*! AIN7 - Input 7 state. Input 7 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN7(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN7_SHIFT)) & SCT_INPUT_AIN7_MASK) +#define SCT_INPUT_AIN8_MASK (0x100U) +#define SCT_INPUT_AIN8_SHIFT (8U) +/*! AIN8 - Input 8 state. Input 8 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN8(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN8_SHIFT)) & SCT_INPUT_AIN8_MASK) +#define SCT_INPUT_AIN9_MASK (0x200U) +#define SCT_INPUT_AIN9_SHIFT (9U) +/*! AIN9 - Input 9 state. Input 9 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN9(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN9_SHIFT)) & SCT_INPUT_AIN9_MASK) +#define SCT_INPUT_AIN10_MASK (0x400U) +#define SCT_INPUT_AIN10_SHIFT (10U) +/*! AIN10 - Input 10 state. Input 10 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN10(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN10_SHIFT)) & SCT_INPUT_AIN10_MASK) +#define SCT_INPUT_AIN11_MASK (0x800U) +#define SCT_INPUT_AIN11_SHIFT (11U) +/*! AIN11 - Input 11 state. Input 11 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN11(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN11_SHIFT)) & SCT_INPUT_AIN11_MASK) +#define SCT_INPUT_AIN12_MASK (0x1000U) +#define SCT_INPUT_AIN12_SHIFT (12U) +/*! AIN12 - Input 12 state. Input 12 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN12(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN12_SHIFT)) & SCT_INPUT_AIN12_MASK) +#define SCT_INPUT_AIN13_MASK (0x2000U) +#define SCT_INPUT_AIN13_SHIFT (13U) +/*! AIN13 - Input 13 state. Input 13 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN13(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN13_SHIFT)) & SCT_INPUT_AIN13_MASK) +#define SCT_INPUT_AIN14_MASK (0x4000U) +#define SCT_INPUT_AIN14_SHIFT (14U) +/*! AIN14 - Input 14 state. Input 14 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN14(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN14_SHIFT)) & SCT_INPUT_AIN14_MASK) +#define SCT_INPUT_AIN15_MASK (0x8000U) +#define SCT_INPUT_AIN15_SHIFT (15U) +/*! AIN15 - Input 15 state. Input 15 state on the last SCT clock edge. + */ +#define SCT_INPUT_AIN15(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN15_SHIFT)) & SCT_INPUT_AIN15_MASK) +#define SCT_INPUT_SIN0_MASK (0x10000U) +#define SCT_INPUT_SIN0_SHIFT (16U) +/*! SIN0 - Input 0 state. Input 0 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN0(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN0_SHIFT)) & SCT_INPUT_SIN0_MASK) +#define SCT_INPUT_SIN1_MASK (0x20000U) +#define SCT_INPUT_SIN1_SHIFT (17U) +/*! SIN1 - Input 1 state. Input 1 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN1(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN1_SHIFT)) & SCT_INPUT_SIN1_MASK) +#define SCT_INPUT_SIN2_MASK (0x40000U) +#define SCT_INPUT_SIN2_SHIFT (18U) +/*! SIN2 - Input 2 state. Input 2 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN2(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN2_SHIFT)) & SCT_INPUT_SIN2_MASK) +#define SCT_INPUT_SIN3_MASK (0x80000U) +#define SCT_INPUT_SIN3_SHIFT (19U) +/*! SIN3 - Input 3 state. Input 3 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN3(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN3_SHIFT)) & SCT_INPUT_SIN3_MASK) +#define SCT_INPUT_SIN4_MASK (0x100000U) +#define SCT_INPUT_SIN4_SHIFT (20U) +/*! SIN4 - Input 4 state. Input 4 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN4(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN4_SHIFT)) & SCT_INPUT_SIN4_MASK) +#define SCT_INPUT_SIN5_MASK (0x200000U) +#define SCT_INPUT_SIN5_SHIFT (21U) +/*! SIN5 - Input 5 state. Input 5 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN5(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN5_SHIFT)) & SCT_INPUT_SIN5_MASK) +#define SCT_INPUT_SIN6_MASK (0x400000U) +#define SCT_INPUT_SIN6_SHIFT (22U) +/*! SIN6 - Input 6 state. Input 6 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN6(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN6_SHIFT)) & SCT_INPUT_SIN6_MASK) +#define SCT_INPUT_SIN7_MASK (0x800000U) +#define SCT_INPUT_SIN7_SHIFT (23U) +/*! SIN7 - Input 7 state. Input 7 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN7(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN7_SHIFT)) & SCT_INPUT_SIN7_MASK) +#define SCT_INPUT_SIN8_MASK (0x1000000U) +#define SCT_INPUT_SIN8_SHIFT (24U) +/*! SIN8 - Input 8 state. Input 8 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN8(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN8_SHIFT)) & SCT_INPUT_SIN8_MASK) +#define SCT_INPUT_SIN9_MASK (0x2000000U) +#define SCT_INPUT_SIN9_SHIFT (25U) +/*! SIN9 - Input 9 state. Input 9 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN9(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN9_SHIFT)) & SCT_INPUT_SIN9_MASK) +#define SCT_INPUT_SIN10_MASK (0x4000000U) +#define SCT_INPUT_SIN10_SHIFT (26U) +/*! SIN10 - Input 10 state. Input 10 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN10(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN10_SHIFT)) & SCT_INPUT_SIN10_MASK) +#define SCT_INPUT_SIN11_MASK (0x8000000U) +#define SCT_INPUT_SIN11_SHIFT (27U) +/*! SIN11 - Input 11 state. Input 11 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN11(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN11_SHIFT)) & SCT_INPUT_SIN11_MASK) +#define SCT_INPUT_SIN12_MASK (0x10000000U) +#define SCT_INPUT_SIN12_SHIFT (28U) +/*! SIN12 - Input 12 state. Input 12 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN12(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN12_SHIFT)) & SCT_INPUT_SIN12_MASK) +#define SCT_INPUT_SIN13_MASK (0x20000000U) +#define SCT_INPUT_SIN13_SHIFT (29U) +/*! SIN13 - Input 13 state. Input 13 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN13(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN13_SHIFT)) & SCT_INPUT_SIN13_MASK) +#define SCT_INPUT_SIN14_MASK (0x40000000U) +#define SCT_INPUT_SIN14_SHIFT (30U) +/*! SIN14 - Input 14 state. Input 14 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN14(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN14_SHIFT)) & SCT_INPUT_SIN14_MASK) +#define SCT_INPUT_SIN15_MASK (0x80000000U) +#define SCT_INPUT_SIN15_SHIFT (31U) +/*! SIN15 - Input 15 state. Input 15 state following the synchronization specified by INSYNC. + */ +#define SCT_INPUT_SIN15(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN15_SHIFT)) & SCT_INPUT_SIN15_MASK) +/*! @} */ + +/*! @name REGMODEL - SCT_REGMODEL register */ +/*! @{ */ +#define SCT_REGMODEL_REGMODEL_MASK (0xFFFFU) +#define SCT_REGMODEL_REGMODEL_SHIFT (0U) +#define SCT_REGMODEL_REGMODEL(x) (((uint16_t)(((uint16_t)(x)) << SCT_REGMODEL_REGMODEL_SHIFT)) & SCT_REGMODEL_REGMODEL_MASK) +/*! @} */ + +/*! @name REGMODEH - SCT_REGMODEH register */ +/*! @{ */ +#define SCT_REGMODEH_REGMODEH_MASK (0xFFFFU) +#define SCT_REGMODEH_REGMODEH_SHIFT (0U) +#define SCT_REGMODEH_REGMODEH(x) (((uint16_t)(((uint16_t)(x)) << SCT_REGMODEH_REGMODEH_SHIFT)) & SCT_REGMODEH_REGMODEH_MASK) +/*! @} */ + +/*! @name REGMODE - SCT match/capture mode register */ +/*! @{ */ +#define SCT_REGMODE_REGMOD_L_MASK (0xFFFFU) +#define SCT_REGMODE_REGMOD_L_SHIFT (0U) +/*! REGMOD_L - Each bit controls one match/capture register (register 0 = bit 0, register 1 = bit 1, + * etc.). The number of bits = number of match/captures in this SCT. 0 = register operates as + * match register. 1 = register operates as capture register. + */ +#define SCT_REGMODE_REGMOD_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_REGMODE_REGMOD_L_SHIFT)) & SCT_REGMODE_REGMOD_L_MASK) +#define SCT_REGMODE_REGMOD_H_MASK (0xFFFF0000U) +#define SCT_REGMODE_REGMOD_H_SHIFT (16U) +/*! REGMOD_H - Each bit controls one match/capture register (register 0 = bit 16, register 1 = bit + * 17, etc.). The number of bits = number of match/captures in this SCT. 0 = register operates as + * match registers. 1 = register operates as capture registers. + */ +#define SCT_REGMODE_REGMOD_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_REGMODE_REGMOD_H_SHIFT)) & SCT_REGMODE_REGMOD_H_MASK) +/*! @} */ + +/*! @name OUTPUT - SCT output register */ +/*! @{ */ +#define SCT_OUTPUT_OUT_MASK (0xFFFFU) +#define SCT_OUTPUT_OUT_SHIFT (0U) +/*! OUT - Writing a 1 to bit n forces the corresponding output HIGH. Writing a 0 forces the + * corresponding output LOW (output 0 = bit 0, output 1 = bit 1, etc.). The number of bits = number of + * outputs in this SCT. + */ +#define SCT_OUTPUT_OUT(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUT_OUT_SHIFT)) & SCT_OUTPUT_OUT_MASK) +/*! @} */ + +/*! @name OUTPUTDIRCTRL - SCT output counter direction control register */ +/*! @{ */ +#define SCT_OUTPUTDIRCTRL_SETCLR0_MASK (0x3U) +#define SCT_OUTPUTDIRCTRL_SETCLR0_SHIFT (0U) +/*! SETCLR0 - Set/clear operation on output 0. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR0(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR0_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR0_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR1_MASK (0xCU) +#define SCT_OUTPUTDIRCTRL_SETCLR1_SHIFT (2U) +/*! SETCLR1 - Set/clear operation on output 1. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR1(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR1_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR1_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR2_MASK (0x30U) +#define SCT_OUTPUTDIRCTRL_SETCLR2_SHIFT (4U) +/*! SETCLR2 - Set/clear operation on output 2. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR2(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR2_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR2_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR3_MASK (0xC0U) +#define SCT_OUTPUTDIRCTRL_SETCLR3_SHIFT (6U) +/*! SETCLR3 - Set/clear operation on output 3. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR3(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR3_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR3_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR4_MASK (0x300U) +#define SCT_OUTPUTDIRCTRL_SETCLR4_SHIFT (8U) +/*! SETCLR4 - Set/clear operation on output 4. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR4(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR4_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR4_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR5_MASK (0xC00U) +#define SCT_OUTPUTDIRCTRL_SETCLR5_SHIFT (10U) +/*! SETCLR5 - Set/clear operation on output 5. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR5(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR5_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR5_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR6_MASK (0x3000U) +#define SCT_OUTPUTDIRCTRL_SETCLR6_SHIFT (12U) +/*! SETCLR6 - Set/clear operation on output 6. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR6(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR6_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR6_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR7_MASK (0xC000U) +#define SCT_OUTPUTDIRCTRL_SETCLR7_SHIFT (14U) +/*! SETCLR7 - Set/clear operation on output 7. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR7(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR7_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR7_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR8_MASK (0x30000U) +#define SCT_OUTPUTDIRCTRL_SETCLR8_SHIFT (16U) +/*! SETCLR8 - Set/clear operation on output 8. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR8(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR8_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR8_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR9_MASK (0xC0000U) +#define SCT_OUTPUTDIRCTRL_SETCLR9_SHIFT (18U) +/*! SETCLR9 - Set/clear operation on output 9. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR9(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR9_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR9_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR10_MASK (0x300000U) +#define SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT (20U) +/*! SETCLR10 - Set/clear operation on output 10. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR10(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR10_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR11_MASK (0xC00000U) +#define SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT (22U) +/*! SETCLR11 - Set/clear operation on output 11. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR11(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR11_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR12_MASK (0x3000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT (24U) +/*! SETCLR12 - Set/clear operation on output 12. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR12(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR12_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR13_MASK (0xC000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT (26U) +/*! SETCLR13 - Set/clear operation on output 13. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR13(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR13_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR14_MASK (0x30000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT (28U) +/*! SETCLR14 - Set/clear operation on output 14. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR14(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR14_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR15_MASK (0xC0000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT (30U) +/*! SETCLR15 - Set/clear operation on output 15. Value 0x3 is reserved. Do not program this value. + * 0b00..Set and clear do not depend on the direction of any counter. + * 0b01..Set and clear are reversed when counter L or the unified counter is counting down. + * 0b10..Set and clear are reversed when counter H is counting down. Do not use if UNIFY = 1. + */ +#define SCT_OUTPUTDIRCTRL_SETCLR15(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR15_MASK) +/*! @} */ + +/*! @name RES - SCT conflict resolution register */ +/*! @{ */ +#define SCT_RES_O0RES_MASK (0x3U) +#define SCT_RES_O0RES_SHIFT (0U) +/*! O0RES - Effect of simultaneous set and clear on output 0. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR0 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR0 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O0RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O0RES_SHIFT)) & SCT_RES_O0RES_MASK) +#define SCT_RES_O1RES_MASK (0xCU) +#define SCT_RES_O1RES_SHIFT (2U) +/*! O1RES - Effect of simultaneous set and clear on output 1. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR1 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR1 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O1RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O1RES_SHIFT)) & SCT_RES_O1RES_MASK) +#define SCT_RES_O2RES_MASK (0x30U) +#define SCT_RES_O2RES_SHIFT (4U) +/*! O2RES - Effect of simultaneous set and clear on output 2. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR2 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output n (or set based on the SETCLR2 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O2RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O2RES_SHIFT)) & SCT_RES_O2RES_MASK) +#define SCT_RES_O3RES_MASK (0xC0U) +#define SCT_RES_O3RES_SHIFT (6U) +/*! O3RES - Effect of simultaneous set and clear on output 3. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR3 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR3 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O3RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O3RES_SHIFT)) & SCT_RES_O3RES_MASK) +#define SCT_RES_O4RES_MASK (0x300U) +#define SCT_RES_O4RES_SHIFT (8U) +/*! O4RES - Effect of simultaneous set and clear on output 4. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR4 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR4 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O4RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O4RES_SHIFT)) & SCT_RES_O4RES_MASK) +#define SCT_RES_O5RES_MASK (0xC00U) +#define SCT_RES_O5RES_SHIFT (10U) +/*! O5RES - Effect of simultaneous set and clear on output 5. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR5 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR5 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O5RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O5RES_SHIFT)) & SCT_RES_O5RES_MASK) +#define SCT_RES_O6RES_MASK (0x3000U) +#define SCT_RES_O6RES_SHIFT (12U) +/*! O6RES - Effect of simultaneous set and clear on output 6. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR6 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR6 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O6RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O6RES_SHIFT)) & SCT_RES_O6RES_MASK) +#define SCT_RES_O7RES_MASK (0xC000U) +#define SCT_RES_O7RES_SHIFT (14U) +/*! O7RES - Effect of simultaneous set and clear on output 7. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR7 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output n (or set based on the SETCLR7 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O7RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O7RES_SHIFT)) & SCT_RES_O7RES_MASK) +#define SCT_RES_O8RES_MASK (0x30000U) +#define SCT_RES_O8RES_SHIFT (16U) +/*! O8RES - Effect of simultaneous set and clear on output 8. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR8 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR8 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O8RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O8RES_SHIFT)) & SCT_RES_O8RES_MASK) +#define SCT_RES_O9RES_MASK (0xC0000U) +#define SCT_RES_O9RES_SHIFT (18U) +/*! O9RES - Effect of simultaneous set and clear on output 9. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR9 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR9 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O9RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O9RES_SHIFT)) & SCT_RES_O9RES_MASK) +#define SCT_RES_O10RES_MASK (0x300000U) +#define SCT_RES_O10RES_SHIFT (20U) +/*! O10RES - Effect of simultaneous set and clear on output 10. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR10 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR10 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O10RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O10RES_SHIFT)) & SCT_RES_O10RES_MASK) +#define SCT_RES_O11RES_MASK (0xC00000U) +#define SCT_RES_O11RES_SHIFT (22U) +/*! O11RES - Effect of simultaneous set and clear on output 11. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR11 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR11 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O11RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O11RES_SHIFT)) & SCT_RES_O11RES_MASK) +#define SCT_RES_O12RES_MASK (0x3000000U) +#define SCT_RES_O12RES_SHIFT (24U) +/*! O12RES - Effect of simultaneous set and clear on output 12. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR12 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR12 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O12RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O12RES_SHIFT)) & SCT_RES_O12RES_MASK) +#define SCT_RES_O13RES_MASK (0xC000000U) +#define SCT_RES_O13RES_SHIFT (26U) +/*! O13RES - Effect of simultaneous set and clear on output 13. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR13 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR13 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O13RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O13RES_SHIFT)) & SCT_RES_O13RES_MASK) +#define SCT_RES_O14RES_MASK (0x30000000U) +#define SCT_RES_O14RES_SHIFT (28U) +/*! O14RES - Effect of simultaneous set and clear on output 14. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR14 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR14 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O14RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O14RES_SHIFT)) & SCT_RES_O14RES_MASK) +#define SCT_RES_O15RES_MASK (0xC0000000U) +#define SCT_RES_O15RES_SHIFT (30U) +/*! O15RES - Effect of simultaneous set and clear on output 15. + * 0b00..No change. + * 0b01..Set output (or clear based on the SETCLR15 field in the OUTPUTDIRCTRL register). + * 0b10..Clear output (or set based on the SETCLR15 field). + * 0b11..Toggle output. + */ +#define SCT_RES_O15RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O15RES_SHIFT)) & SCT_RES_O15RES_MASK) +/*! @} */ + +/*! @name DMAREQ0 - SCT DMA request 0 register */ +/*! @{ */ +#define SCT_DMAREQ0_DEV_0_MASK (0xFFFFU) +#define SCT_DMAREQ0_DEV_0_SHIFT (0U) +/*! DEV_0 - If bit n is one, event n triggers DMA request 0 (event 0 = bit 0, event 1 = bit 1, + * etc.). The number of bits = number of events in this SCT. + */ +#define SCT_DMAREQ0_DEV_0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMAREQ0_DEV_0_SHIFT)) & SCT_DMAREQ0_DEV_0_MASK) +#define SCT_DMAREQ0_DRL0_MASK (0x40000000U) +#define SCT_DMAREQ0_DRL0_SHIFT (30U) +/*! DRL0 - A 1 in this bit triggers DMA request 0 when it loads the MATCH_L/Unified registers from the RELOAD_L/Unified registers. + */ +#define SCT_DMAREQ0_DRL0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMAREQ0_DRL0_SHIFT)) & SCT_DMAREQ0_DRL0_MASK) +#define SCT_DMAREQ0_DRQ0_MASK (0x80000000U) +#define SCT_DMAREQ0_DRQ0_SHIFT (31U) +/*! DRQ0 - This read-only bit indicates the state of DMA Request 0. Note that if the related DMA + * channel is enabled and properly set up, it is unlikely that software will see this flag, it will + * be cleared rapidly by the DMA service. The flag remaining set could point to an issue with DMA + * setup. + */ +#define SCT_DMAREQ0_DRQ0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMAREQ0_DRQ0_SHIFT)) & SCT_DMAREQ0_DRQ0_MASK) +/*! @} */ + +/*! @name DMAREQ1 - SCT DMA request 1 register */ +/*! @{ */ +#define SCT_DMAREQ1_DEV_1_MASK (0xFFFFU) +#define SCT_DMAREQ1_DEV_1_SHIFT (0U) +/*! DEV_1 - If bit n is one, event n triggers DMA request 1 (event 0 = bit 0, event 1 = bit 1, + * etc.). The number of bits = number of events in this SCT. + */ +#define SCT_DMAREQ1_DEV_1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMAREQ1_DEV_1_SHIFT)) & SCT_DMAREQ1_DEV_1_MASK) +#define SCT_DMAREQ1_DRL1_MASK (0x40000000U) +#define SCT_DMAREQ1_DRL1_SHIFT (30U) +/*! DRL1 - A 1 in this bit triggers DMA request 1 when it loads the Match L/Unified registers from the Reload L/Unified registers. + */ +#define SCT_DMAREQ1_DRL1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMAREQ1_DRL1_SHIFT)) & SCT_DMAREQ1_DRL1_MASK) +#define SCT_DMAREQ1_DRQ1_MASK (0x80000000U) +#define SCT_DMAREQ1_DRQ1_SHIFT (31U) +/*! DRQ1 - This read-only bit indicates the state of DMA Request 1. Note that if the related DMA + * channel is enabled and properly set up, it is unlikely that software will see this flag, it will + * be cleared rapidly by the DMA service. The flag remaining set could point to an issue with DMA + * setup. + */ +#define SCT_DMAREQ1_DRQ1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMAREQ1_DRQ1_SHIFT)) & SCT_DMAREQ1_DRQ1_MASK) +/*! @} */ + +/*! @name EVEN - SCT event interrupt enable register */ +/*! @{ */ +#define SCT_EVEN_IEN_MASK (0xFFFFU) +#define SCT_EVEN_IEN_SHIFT (0U) +/*! IEN - The SCT requests an interrupt when bit n of this register and the event flag register are + * both one (event 0 = bit 0, event 1 = bit 1, etc.). The number of bits = number of events in + * this SCT. + */ +#define SCT_EVEN_IEN(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVEN_IEN_SHIFT)) & SCT_EVEN_IEN_MASK) +/*! @} */ + +/*! @name EVFLAG - SCT event flag register */ +/*! @{ */ +#define SCT_EVFLAG_FLAG_MASK (0xFFFFU) +#define SCT_EVFLAG_FLAG_SHIFT (0U) +/*! FLAG - Bit n is one if event n has occurred since reset or a 1 was last written to this bit + * (event 0 = bit 0, event 1 = bit 1, etc.). The number of bits = number of events in this SCT. + */ +#define SCT_EVFLAG_FLAG(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVFLAG_FLAG_SHIFT)) & SCT_EVFLAG_FLAG_MASK) +/*! @} */ + +/*! @name CONEN - SCT conflict interrupt enable register */ +/*! @{ */ +#define SCT_CONEN_NCEN_MASK (0xFFFFU) +#define SCT_CONEN_NCEN_SHIFT (0U) +/*! NCEN - The SCT requests an interrupt when bit n of this register and the SCT conflict flag + * register are both one (output 0 = bit 0, output 1 = bit 1, etc.). The number of bits = number of + * outputs in this SCT. + */ +#define SCT_CONEN_NCEN(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONEN_NCEN_SHIFT)) & SCT_CONEN_NCEN_MASK) +/*! @} */ + +/*! @name CONFLAG - SCT conflict flag register */ +/*! @{ */ +#define SCT_CONFLAG_NCFLAG_MASK (0xFFFFU) +#define SCT_CONFLAG_NCFLAG_SHIFT (0U) +/*! NCFLAG - Bit n is one if a no-change conflict event occurred on output n since reset or a 1 was + * last written to this bit (output 0 = bit 0, output 1 = bit 1, etc.). The number of bits = + * number of outputs in this SCT. + */ +#define SCT_CONFLAG_NCFLAG(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_NCFLAG_SHIFT)) & SCT_CONFLAG_NCFLAG_MASK) +#define SCT_CONFLAG_BUSERRL_MASK (0x40000000U) +#define SCT_CONFLAG_BUSERRL_SHIFT (30U) +/*! BUSERRL - The most recent bus error from this SCT involved writing CTR L/Unified, STATE + * L/Unified, MATCH L/Unified, or the Output register when the L/U counter was not halted. A word write + * to certain L and H registers can be half successful and half unsuccessful. + */ +#define SCT_CONFLAG_BUSERRL(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_BUSERRL_SHIFT)) & SCT_CONFLAG_BUSERRL_MASK) +#define SCT_CONFLAG_BUSERRH_MASK (0x80000000U) +#define SCT_CONFLAG_BUSERRH_SHIFT (31U) +/*! BUSERRH - The most recent bus error from this SCT involved writing CTR H, STATE H, MATCH H, or + * the Output register when the H counter was not halted. + */ +#define SCT_CONFLAG_BUSERRH(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_BUSERRH_SHIFT)) & SCT_CONFLAG_BUSERRH_MASK) +/*! @} */ + +/*! @name CAPL - SCT_CAPL register */ +/*! @{ */ +#define SCT_CAPL_CAPL_MASK (0xFFFFU) +#define SCT_CAPL_CAPL_SHIFT (0U) +#define SCT_CAPL_CAPL(x) (((uint16_t)(((uint16_t)(x)) << SCT_CAPL_CAPL_SHIFT)) & SCT_CAPL_CAPL_MASK) +/*! @} */ + +/* The count of SCT_CAPL */ +#define SCT_CAPL_COUNT (10U) + +/*! @name CAPH - SCT_CAPH register */ +/*! @{ */ +#define SCT_CAPH_CAPH_MASK (0xFFFFU) +#define SCT_CAPH_CAPH_SHIFT (0U) +#define SCT_CAPH_CAPH(x) (((uint16_t)(((uint16_t)(x)) << SCT_CAPH_CAPH_SHIFT)) & SCT_CAPH_CAPH_MASK) +/*! @} */ + +/* The count of SCT_CAPH */ +#define SCT_CAPH_COUNT (10U) + +/*! @name CAP - SCT capture register of capture channel */ +/*! @{ */ +#define SCT_CAP_CAPn_L_MASK (0xFFFFU) +#define SCT_CAP_CAPn_L_SHIFT (0U) +/*! CAPn_L - When UNIFY = 0, read the 16-bit counter value at which this register was last captured. + * When UNIFY = 1, read the lower 16 bits of the 32-bit value at which this register was last + * captured. + */ +#define SCT_CAP_CAPn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CAP_CAPn_L_SHIFT)) & SCT_CAP_CAPn_L_MASK) +#define SCT_CAP_CAPn_H_MASK (0xFFFF0000U) +#define SCT_CAP_CAPn_H_SHIFT (16U) +/*! CAPn_H - When UNIFY = 0, read the 16-bit counter value at which this register was last captured. + * When UNIFY = 1, read the upper 16 bits of the 32-bit value at which this register was last + * captured. + */ +#define SCT_CAP_CAPn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CAP_CAPn_H_SHIFT)) & SCT_CAP_CAPn_H_MASK) +/*! @} */ + +/* The count of SCT_CAP */ +#define SCT_CAP_COUNT (10U) + +/*! @name MATCHL - SCT_MATCHL register */ +/*! @{ */ +#define SCT_MATCHL_MATCHL_MASK (0xFFFFU) +#define SCT_MATCHL_MATCHL_SHIFT (0U) +#define SCT_MATCHL_MATCHL(x) (((uint16_t)(((uint16_t)(x)) << SCT_MATCHL_MATCHL_SHIFT)) & SCT_MATCHL_MATCHL_MASK) +/*! @} */ + +/* The count of SCT_MATCHL */ +#define SCT_MATCHL_COUNT (10U) + +/*! @name MATCHH - SCT_MATCHH register */ +/*! @{ */ +#define SCT_MATCHH_MATCHH_MASK (0xFFFFU) +#define SCT_MATCHH_MATCHH_SHIFT (0U) +#define SCT_MATCHH_MATCHH(x) (((uint16_t)(((uint16_t)(x)) << SCT_MATCHH_MATCHH_SHIFT)) & SCT_MATCHH_MATCHH_MASK) +/*! @} */ + +/* The count of SCT_MATCHH */ +#define SCT_MATCHH_COUNT (10U) + +/*! @name MATCH - SCT match value register of match channels */ +/*! @{ */ +#define SCT_MATCH_MATCHn_L_MASK (0xFFFFU) +#define SCT_MATCH_MATCHn_L_SHIFT (0U) +/*! MATCHn_L - When UNIFY = 0, read or write the 16-bit value to be compared to the L counter. When + * UNIFY = 1, read or write the lower 16 bits of the 32-bit value to be compared to the unified + * counter. + */ +#define SCT_MATCH_MATCHn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_MATCH_MATCHn_L_SHIFT)) & SCT_MATCH_MATCHn_L_MASK) +#define SCT_MATCH_MATCHn_H_MASK (0xFFFF0000U) +#define SCT_MATCH_MATCHn_H_SHIFT (16U) +/*! MATCHn_H - When UNIFY = 0, read or write the 16-bit value to be compared to the H counter. When + * UNIFY = 1, read or write the upper 16 bits of the 32-bit value to be compared to the unified + * counter. + */ +#define SCT_MATCH_MATCHn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_MATCH_MATCHn_H_SHIFT)) & SCT_MATCH_MATCHn_H_MASK) +/*! @} */ + +/* The count of SCT_MATCH */ +#define SCT_MATCH_COUNT (10U) + +/*! @name CAPCTRLL - SCT_CAPCTRLL register */ +/*! @{ */ +#define SCT_CAPCTRLL_CAPCTRLL_MASK (0xFFFFU) +#define SCT_CAPCTRLL_CAPCTRLL_SHIFT (0U) +#define SCT_CAPCTRLL_CAPCTRLL(x) (((uint16_t)(((uint16_t)(x)) << SCT_CAPCTRLL_CAPCTRLL_SHIFT)) & SCT_CAPCTRLL_CAPCTRLL_MASK) +/*! @} */ + +/* The count of SCT_CAPCTRLL */ +#define SCT_CAPCTRLL_COUNT (10U) + +/*! @name CAPCTRLH - SCT_CAPCTRLH register */ +/*! @{ */ +#define SCT_CAPCTRLH_CAPCTRLH_MASK (0xFFFFU) +#define SCT_CAPCTRLH_CAPCTRLH_SHIFT (0U) +#define SCT_CAPCTRLH_CAPCTRLH(x) (((uint16_t)(((uint16_t)(x)) << SCT_CAPCTRLH_CAPCTRLH_SHIFT)) & SCT_CAPCTRLH_CAPCTRLH_MASK) +/*! @} */ + +/* The count of SCT_CAPCTRLH */ +#define SCT_CAPCTRLH_COUNT (10U) + +/*! @name CAPCTRL - SCT capture control register */ +/*! @{ */ +#define SCT_CAPCTRL_CAPCONn_L_MASK (0xFFFFU) +#define SCT_CAPCTRL_CAPCONn_L_SHIFT (0U) +/*! CAPCONn_L - If bit m is one, event m causes the CAPn_L (UNIFY = 0) or the CAPn (UNIFY = 1) + * register to be loaded (event 0 = bit 0, event 1 = bit 1, etc.). The number of bits = number of + * match/captures in this SCT. + */ +#define SCT_CAPCTRL_CAPCONn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CAPCTRL_CAPCONn_L_SHIFT)) & SCT_CAPCTRL_CAPCONn_L_MASK) +#define SCT_CAPCTRL_CAPCONn_H_MASK (0xFFFF0000U) +#define SCT_CAPCTRL_CAPCONn_H_SHIFT (16U) +/*! CAPCONn_H - If bit m is one, event m causes the CAPn_H (UNIFY = 0) register to be loaded (event + * 0 = bit 16, event 1 = bit 17, etc.). The number of bits = number of match/captures in this SCT. + */ +#define SCT_CAPCTRL_CAPCONn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CAPCTRL_CAPCONn_H_SHIFT)) & SCT_CAPCTRL_CAPCONn_H_MASK) +/*! @} */ + +/* The count of SCT_CAPCTRL */ +#define SCT_CAPCTRL_COUNT (10U) + +/*! @name MATCHRELL - SCT_MATCHRELL register */ +/*! @{ */ +#define SCT_MATCHRELL_MATCHRELL_MASK (0xFFFFU) +#define SCT_MATCHRELL_MATCHRELL_SHIFT (0U) +#define SCT_MATCHRELL_MATCHRELL(x) (((uint16_t)(((uint16_t)(x)) << SCT_MATCHRELL_MATCHRELL_SHIFT)) & SCT_MATCHRELL_MATCHRELL_MASK) +/*! @} */ + +/* The count of SCT_MATCHRELL */ +#define SCT_MATCHRELL_COUNT (10U) + +/*! @name MATCHRELH - SCT_MATCHRELH register */ +/*! @{ */ +#define SCT_MATCHRELH_MATCHRELH_MASK (0xFFFFU) +#define SCT_MATCHRELH_MATCHRELH_SHIFT (0U) +#define SCT_MATCHRELH_MATCHRELH(x) (((uint16_t)(((uint16_t)(x)) << SCT_MATCHRELH_MATCHRELH_SHIFT)) & SCT_MATCHRELH_MATCHRELH_MASK) +/*! @} */ + +/* The count of SCT_MATCHRELH */ +#define SCT_MATCHRELH_COUNT (10U) + +/*! @name MATCHREL - SCT match reload value register */ +/*! @{ */ +#define SCT_MATCHREL_RELOADn_L_MASK (0xFFFFU) +#define SCT_MATCHREL_RELOADn_L_SHIFT (0U) +/*! RELOADn_L - When UNIFY = 0, specifies the 16-bit value to be loaded into the MATCHn_L register. + * When UNIFY = 1, specifies the lower 16 bits of the 32-bit value to be loaded into the MATCHn + * register. + */ +#define SCT_MATCHREL_RELOADn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_MATCHREL_RELOADn_L_SHIFT)) & SCT_MATCHREL_RELOADn_L_MASK) +#define SCT_MATCHREL_RELOADn_H_MASK (0xFFFF0000U) +#define SCT_MATCHREL_RELOADn_H_SHIFT (16U) +/*! RELOADn_H - When UNIFY = 0, specifies the 16-bit to be loaded into the MATCHn_H register. When + * UNIFY = 1, specifies the upper 16 bits of the 32-bit value to be loaded into the MATCHn + * register. + */ +#define SCT_MATCHREL_RELOADn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_MATCHREL_RELOADn_H_SHIFT)) & SCT_MATCHREL_RELOADn_H_MASK) +/*! @} */ + +/* The count of SCT_MATCHREL */ +#define SCT_MATCHREL_COUNT (10U) + +/*! @name EV_STATE - SCT event state register 0 */ +/*! @{ */ +#define SCT_EV_STATE_STATEMSKn_MASK (0xFFFFU) +#define SCT_EV_STATE_STATEMSKn_SHIFT (0U) +/*! STATEMSKn - If bit m is one, event n happens in state m of the counter selected by the HEVENT + * bit (n = event number, m = state number; state 0 = bit 0, state 1= bit 1, etc.). The number of + * bits = number of states in this SCT. + */ +#define SCT_EV_STATE_STATEMSKn(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_STATE_STATEMSKn_SHIFT)) & SCT_EV_STATE_STATEMSKn_MASK) +/*! @} */ + +/* The count of SCT_EV_STATE */ +#define SCT_EV_STATE_COUNT (10U) + +/*! @name EV_CTRL - SCT event control register 0 */ +/*! @{ */ +#define SCT_EV_CTRL_MATCHSEL_MASK (0xFU) +#define SCT_EV_CTRL_MATCHSEL_SHIFT (0U) +/*! MATCHSEL - Selects the Match register associated with this event (if any). A match can occur + * only when the counter selected by the HEVENT bit is running. + */ +#define SCT_EV_CTRL_MATCHSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_MATCHSEL_SHIFT)) & SCT_EV_CTRL_MATCHSEL_MASK) +#define SCT_EV_CTRL_HEVENT_MASK (0x10U) +#define SCT_EV_CTRL_HEVENT_SHIFT (4U) +/*! HEVENT - Select L/H counter. Do not set this bit if UNIFY = 1. + * 0b0..Selects the L state and the L match register selected by MATCHSEL. + * 0b1..Selects the H state and the H match register selected by MATCHSEL. + */ +#define SCT_EV_CTRL_HEVENT(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_HEVENT_SHIFT)) & SCT_EV_CTRL_HEVENT_MASK) +#define SCT_EV_CTRL_OUTSEL_MASK (0x20U) +#define SCT_EV_CTRL_OUTSEL_SHIFT (5U) +/*! OUTSEL - Input/output select + * 0b0..Selects the inputs selected by IOSEL. + * 0b1..Selects the outputs selected by IOSEL. + */ +#define SCT_EV_CTRL_OUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_OUTSEL_SHIFT)) & SCT_EV_CTRL_OUTSEL_MASK) +#define SCT_EV_CTRL_IOSEL_MASK (0x3C0U) +#define SCT_EV_CTRL_IOSEL_SHIFT (6U) +/*! IOSEL - Selects the input or output signal number associated with this event (if any). Do not + * select an input in this register if CKMODE is 1x. In this case the clock input is an implicit + * ingredient of every event. + */ +#define SCT_EV_CTRL_IOSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_IOSEL_SHIFT)) & SCT_EV_CTRL_IOSEL_MASK) +#define SCT_EV_CTRL_IOCOND_MASK (0xC00U) +#define SCT_EV_CTRL_IOCOND_SHIFT (10U) +/*! IOCOND - Selects the I/O condition for event n. (The detection of edges on outputs lag the + * conditions that switch the outputs by one SCT clock). In order to guarantee proper edge/state + * detection, an input must have a minimum pulse width of at least one SCT clock period . + * 0b00..LOW + * 0b01..Rise + * 0b10..Fall + * 0b11..HIGH + */ +#define SCT_EV_CTRL_IOCOND(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_IOCOND_SHIFT)) & SCT_EV_CTRL_IOCOND_MASK) +#define SCT_EV_CTRL_COMBMODE_MASK (0x3000U) +#define SCT_EV_CTRL_COMBMODE_SHIFT (12U) +/*! COMBMODE - Selects how the specified match and I/O condition are used and combined. + * 0b00..OR. The event occurs when either the specified match or I/O condition occurs. + * 0b01..MATCH. Uses the specified match only. + * 0b10..IO. Uses the specified I/O condition only. + * 0b11..AND. The event occurs when the specified match and I/O condition occur simultaneously. + */ +#define SCT_EV_CTRL_COMBMODE(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_COMBMODE_SHIFT)) & SCT_EV_CTRL_COMBMODE_MASK) +#define SCT_EV_CTRL_STATELD_MASK (0x4000U) +#define SCT_EV_CTRL_STATELD_SHIFT (14U) +/*! STATELD - This bit controls how the STATEV value modifies the state selected by HEVENT when this + * event is the highest-numbered event occurring for that state. + * 0b0..STATEV value is added into STATE (the carry-out is ignored). + * 0b1..STATEV value is loaded into STATE. + */ +#define SCT_EV_CTRL_STATELD(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_STATELD_SHIFT)) & SCT_EV_CTRL_STATELD_MASK) +#define SCT_EV_CTRL_STATEV_MASK (0xF8000U) +#define SCT_EV_CTRL_STATEV_SHIFT (15U) +/*! STATEV - This value is loaded into or added to the state selected by HEVENT, depending on + * STATELD, when this event is the highest-numbered event occurring for that state. If STATELD and + * STATEV are both zero, there is no change to the STATE value. + */ +#define SCT_EV_CTRL_STATEV(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_STATEV_SHIFT)) & SCT_EV_CTRL_STATEV_MASK) +#define SCT_EV_CTRL_MATCHMEM_MASK (0x100000U) +#define SCT_EV_CTRL_MATCHMEM_SHIFT (20U) +/*! MATCHMEM - If this bit is one and the COMBMODE field specifies a match component to the + * triggering of this event, then a match is considered to be active whenever the counter value is + * GREATER THAN OR EQUAL TO the value specified in the match register when counting up, LESS THEN OR + * EQUAL TO the match value when counting down. If this bit is zero, a match is only be active + * during the cycle when the counter is equal to the match value. + */ +#define SCT_EV_CTRL_MATCHMEM(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_MATCHMEM_SHIFT)) & SCT_EV_CTRL_MATCHMEM_MASK) +#define SCT_EV_CTRL_DIRECTION_MASK (0x600000U) +#define SCT_EV_CTRL_DIRECTION_SHIFT (21U) +/*! DIRECTION - Direction qualifier for event generation. This field only applies when the counters + * are operating in BIDIR mode. If BIDIR = 0, the SCT ignores this field. Value 0x3 is reserved. + * 0b00..Direction independent. This event is triggered regardless of the count direction. + * 0b01..Counting up. This event is triggered only during up-counting when BIDIR = 1. + * 0b10..Counting down. This event is triggered only during down-counting when BIDIR = 1. + */ +#define SCT_EV_CTRL_DIRECTION(x) (((uint32_t)(((uint32_t)(x)) << SCT_EV_CTRL_DIRECTION_SHIFT)) & SCT_EV_CTRL_DIRECTION_MASK) +/*! @} */ + +/* The count of SCT_EV_CTRL */ +#define SCT_EV_CTRL_COUNT (10U) + +/*! @name OUT_SET - SCT output 0 set register */ +/*! @{ */ +#define SCT_OUT_SET_SET_MASK (0xFFFFU) +#define SCT_OUT_SET_SET_SHIFT (0U) +/*! SET - A 1 in bit m selects event m to set output n (or clear it if SETCLRn = 0x1 or 0x2) output + * 0 = bit 0, output 1 = bit 1, etc. The number of bits = number of events in this SCT. When the + * counter is used in bi-directional mode, it is possible to reverse the action specified by the + * output set and clear registers when counting down, See the OUTPUTCTRL register. + */ +#define SCT_OUT_SET_SET(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUT_SET_SET_SHIFT)) & SCT_OUT_SET_SET_MASK) +/*! @} */ + +/* The count of SCT_OUT_SET */ +#define SCT_OUT_SET_COUNT (8U) + +/*! @name OUT_CLR - SCT output 0 clear register */ +/*! @{ */ +#define SCT_OUT_CLR_CLR_MASK (0xFFFFU) +#define SCT_OUT_CLR_CLR_SHIFT (0U) +/*! CLR - A 1 in bit m selects event m to clear output n (or set it if SETCLRn = 0x1 or 0x2) event 0 + * = bit 0, event 1 = bit 1, etc. The number of bits = number of events in this SCT. When the + * counter is used in bi-directional mode, it is possible to reverse the action specified by the + * output set and clear registers when counting down, See the OUTPUTCTRL register. + */ +#define SCT_OUT_CLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUT_CLR_CLR_SHIFT)) & SCT_OUT_CLR_CLR_MASK) +/*! @} */ + +/* The count of SCT_OUT_CLR */ +#define SCT_OUT_CLR_COUNT (8U) + + +/*! + * @} + */ /* end of group SCT_Register_Masks */ + + +/* SCT - Peripheral instance base addresses */ +/** Peripheral SCT0 base address */ +#define SCT0_BASE (0x40085000u) +/** Peripheral SCT0 base pointer */ +#define SCT0 ((SCT_Type *)SCT0_BASE) +/** Array initializer of SCT peripheral base addresses */ +#define SCT_BASE_ADDRS { SCT0_BASE } +/** Array initializer of SCT peripheral base pointers */ +#define SCT_BASE_PTRS { SCT0 } +/** Interrupt vectors for the SCT peripheral type */ +#define SCT_IRQS { SCT0_IRQn } + +/*! + * @} + */ /* end of group SCT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer + * @{ + */ + +/** SPI - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[1024]; + __IO uint32_t CFG; /**< SPI Configuration register, offset: 0x400 */ + __IO uint32_t DLY; /**< SPI Delay register, offset: 0x404 */ + __IO uint32_t STAT; /**< SPI Status. Some status flags can be cleared by writing a 1 to that bit position., offset: 0x408 */ + __IO uint32_t INTENSET; /**< SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0x40C */ + __O uint32_t INTENCLR; /**< SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared., offset: 0x410 */ + uint8_t RESERVED_1[16]; + __IO uint32_t DIV; /**< SPI clock Divider, offset: 0x424 */ + __I uint32_t INTSTAT; /**< SPI Interrupt Status, offset: 0x428 */ + uint8_t RESERVED_2[2516]; + __IO uint32_t FIFOCFG; /**< FIFO configuration and enable register., offset: 0xE00 */ + __IO uint32_t FIFOSTAT; /**< FIFO status register., offset: 0xE04 */ + __IO uint32_t FIFOTRIG; /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */ + uint8_t RESERVED_3[4]; + __IO uint32_t FIFOINTENSET; /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */ + __IO uint32_t FIFOINTENCLR; /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */ + __I uint32_t FIFOINTSTAT; /**< FIFO interrupt status register., offset: 0xE18 */ + uint8_t RESERVED_4[4]; + __IO uint32_t FIFOWR; /**< FIFO write data., offset: 0xE20 */ + uint8_t RESERVED_5[12]; + __I uint32_t FIFORD; /**< FIFO read data., offset: 0xE30 */ + uint8_t RESERVED_6[12]; + __I uint32_t FIFORDNOPOP; /**< FIFO data read with no FIFO pop., offset: 0xE40 */ +} SPI_Type; + +/* ---------------------------------------------------------------------------- + -- SPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Register_Masks SPI Register Masks + * @{ + */ + +/*! @name CFG - SPI Configuration register */ +/*! @{ */ +#define SPI_CFG_ENABLE_MASK (0x1U) +#define SPI_CFG_ENABLE_SHIFT (0U) +/*! ENABLE - SPI enable. + * 0b0..Disabled. The SPI is disabled and the internal state machine and counters are reset. + * 0b1..Enabled. The SPI is enabled for operation. + */ +#define SPI_CFG_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_ENABLE_SHIFT)) & SPI_CFG_ENABLE_MASK) +#define SPI_CFG_MASTER_MASK (0x4U) +#define SPI_CFG_MASTER_SHIFT (2U) +/*! MASTER - Master mode select. + * 0b0..Slave mode. The SPI will operate in slave mode. SCK, MOSI, and the SSEL signals are inputs, MISO is an output. + * 0b1..Master mode. The SPI will operate in master mode. SCK, MOSI, and the SSEL signals are outputs, MISO is an input. + */ +#define SPI_CFG_MASTER(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_MASTER_SHIFT)) & SPI_CFG_MASTER_MASK) +#define SPI_CFG_LSBF_MASK (0x8U) +#define SPI_CFG_LSBF_SHIFT (3U) +/*! LSBF - LSB First mode enable. + * 0b0..Standard. Data is transmitted and received in standard MSB first order. + * 0b1..Reverse. Data is transmitted and received in reverse order (LSB first). + */ +#define SPI_CFG_LSBF(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LSBF_SHIFT)) & SPI_CFG_LSBF_MASK) +#define SPI_CFG_CPHA_MASK (0x10U) +#define SPI_CFG_CPHA_SHIFT (4U) +/*! CPHA - Clock Phase select. + * 0b0..Change. The SPI captures serial data on the first clock transition of the transfer (when the clock + * changes away from the rest state). Data is changed on the following edge. + * 0b1..Capture. The SPI changes serial data on the first clock transition of the transfer (when the clock + * changes away from the rest state). Data is captured on the following edge. + */ +#define SPI_CFG_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPHA_SHIFT)) & SPI_CFG_CPHA_MASK) +#define SPI_CFG_CPOL_MASK (0x20U) +#define SPI_CFG_CPOL_SHIFT (5U) +/*! CPOL - Clock Polarity select. + * 0b0..Low. The rest state of the clock (between transfers) is low. + * 0b1..High. The rest state of the clock (between transfers) is high. + */ +#define SPI_CFG_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPOL_SHIFT)) & SPI_CFG_CPOL_MASK) +#define SPI_CFG_LOOP_MASK (0x80U) +#define SPI_CFG_LOOP_SHIFT (7U) +/*! LOOP - Loopback mode enable. Loopback mode applies only to Master mode, and connects transmit + * and receive data connected together to allow simple software testing. + * 0b0..Disabled. + * 0b1..Enabled. + */ +#define SPI_CFG_LOOP(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LOOP_SHIFT)) & SPI_CFG_LOOP_MASK) +#define SPI_CFG_SPOL0_MASK (0x100U) +#define SPI_CFG_SPOL0_SHIFT (8U) +/*! SPOL0 - SSEL0 Polarity select. + * 0b0..Low. The SSEL0 pin is active low. + * 0b1..High. The SSEL0 pin is active high. + */ +#define SPI_CFG_SPOL0(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL0_SHIFT)) & SPI_CFG_SPOL0_MASK) +#define SPI_CFG_SPOL1_MASK (0x200U) +#define SPI_CFG_SPOL1_SHIFT (9U) +/*! SPOL1 - SSEL1 Polarity select. + * 0b0..Low. The SSEL1 pin is active low. + * 0b1..High. The SSEL1 pin is active high. + */ +#define SPI_CFG_SPOL1(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL1_SHIFT)) & SPI_CFG_SPOL1_MASK) +#define SPI_CFG_SPOL2_MASK (0x400U) +#define SPI_CFG_SPOL2_SHIFT (10U) +/*! SPOL2 - SSEL2 Polarity select. + * 0b0..Low. The SSEL2 pin is active low. + * 0b1..High. The SSEL2 pin is active high. + */ +#define SPI_CFG_SPOL2(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL2_SHIFT)) & SPI_CFG_SPOL2_MASK) +#define SPI_CFG_SPOL3_MASK (0x800U) +#define SPI_CFG_SPOL3_SHIFT (11U) +/*! SPOL3 - SSEL3 Polarity select. + * 0b0..Low. The SSEL3 pin is active low. + * 0b1..High. The SSEL3 pin is active high. + */ +#define SPI_CFG_SPOL3(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL3_SHIFT)) & SPI_CFG_SPOL3_MASK) +/*! @} */ + +/*! @name DLY - SPI Delay register */ +/*! @{ */ +#define SPI_DLY_PRE_DELAY_MASK (0xFU) +#define SPI_DLY_PRE_DELAY_SHIFT (0U) +/*! PRE_DELAY - Controls the amount of time between SSEL assertion and the beginning of a data + * transfer. There is always one SPI clock time between SSEL assertion and the first clock edge. This + * is not considered part of the pre-delay. 0x0 = No additional time is inserted. 0x1 = 1 SPI + * clock time is inserted. 0x2 = 2 SPI clock times are inserted. 0xF = 15 SPI clock times are + * inserted. + */ +#define SPI_DLY_PRE_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_PRE_DELAY_SHIFT)) & SPI_DLY_PRE_DELAY_MASK) +#define SPI_DLY_POST_DELAY_MASK (0xF0U) +#define SPI_DLY_POST_DELAY_SHIFT (4U) +/*! POST_DELAY - Controls the amount of time between the end of a data transfer and SSEL + * deassertion. 0x0 = No additional time is inserted. 0x1 = 1 SPI clock time is inserted. 0x2 = 2 SPI clock + * times are inserted. 0xF = 15 SPI clock times are inserted. + */ +#define SPI_DLY_POST_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_POST_DELAY_SHIFT)) & SPI_DLY_POST_DELAY_MASK) +#define SPI_DLY_FRAME_DELAY_MASK (0xF00U) +#define SPI_DLY_FRAME_DELAY_SHIFT (8U) +/*! FRAME_DELAY - If the EOF flag is set, controls the minimum amount of time between the current + * frame and the next frame (or SSEL deassertion if EOT). 0x0 = No additional time is inserted. 0x1 + * = 1 SPI clock time is inserted. 0x2 = 2 SPI clock times are inserted. 0xF = 15 SPI clock + * times are inserted. + */ +#define SPI_DLY_FRAME_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_FRAME_DELAY_SHIFT)) & SPI_DLY_FRAME_DELAY_MASK) +#define SPI_DLY_TRANSFER_DELAY_MASK (0xF000U) +#define SPI_DLY_TRANSFER_DELAY_SHIFT (12U) +/*! TRANSFER_DELAY - Controls the minimum amount of time that the SSEL is deasserted between + * transfers. 0x0 = The minimum time that SSEL is deasserted is 1 SPI clock time. (Zero added time.) 0x1 + * = The minimum time that SSEL is deasserted is 2 SPI clock times. 0x2 = The minimum time that + * SSEL is deasserted is 3 SPI clock times. 0xF = The minimum time that SSEL is deasserted is 16 + * SPI clock times. + */ +#define SPI_DLY_TRANSFER_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_TRANSFER_DELAY_SHIFT)) & SPI_DLY_TRANSFER_DELAY_MASK) +/*! @} */ + +/*! @name STAT - SPI Status. Some status flags can be cleared by writing a 1 to that bit position. */ +/*! @{ */ +#define SPI_STAT_SSA_MASK (0x10U) +#define SPI_STAT_SSA_SHIFT (4U) +/*! SSA - Slave Select Assert. This flag is set whenever any slave select transitions from + * deasserted to asserted, in both master and slave modes. This allows determining when the SPI + * transmit/receive functions become busy, and allows waking up the device from reduced power modes when a + * slave mode access begins. This flag is cleared by software. + */ +#define SPI_STAT_SSA(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSA_SHIFT)) & SPI_STAT_SSA_MASK) +#define SPI_STAT_SSD_MASK (0x20U) +#define SPI_STAT_SSD_SHIFT (5U) +/*! SSD - Slave Select Deassert. This flag is set whenever any asserted slave selects transition to + * deasserted, in both master and slave modes. This allows determining when the SPI + * transmit/receive functions become idle. This flag is cleared by software. + */ +#define SPI_STAT_SSD(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSD_SHIFT)) & SPI_STAT_SSD_MASK) +#define SPI_STAT_STALLED_MASK (0x40U) +#define SPI_STAT_STALLED_SHIFT (6U) +/*! STALLED - Stalled status flag. This indicates whether the SPI is currently in a stall condition. + */ +#define SPI_STAT_STALLED(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_STALLED_SHIFT)) & SPI_STAT_STALLED_MASK) +#define SPI_STAT_ENDTRANSFER_MASK (0x80U) +#define SPI_STAT_ENDTRANSFER_SHIFT (7U) +/*! ENDTRANSFER - End Transfer control bit. Software can set this bit to force an end to the current + * transfer when the transmitter finishes any activity already in progress, as if the EOT flag + * had been set prior to the last transmission. This capability is included to support cases where + * it is not known when transmit data is written that it will be the end of a transfer. The bit + * is cleared when the transmitter becomes idle as the transfer comes to an end. Forcing an end + * of transfer in this manner causes any specified FRAME_DELAY and TRANSFER_DELAY to be inserted. + */ +#define SPI_STAT_ENDTRANSFER(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_ENDTRANSFER_SHIFT)) & SPI_STAT_ENDTRANSFER_MASK) +#define SPI_STAT_MSTIDLE_MASK (0x100U) +#define SPI_STAT_MSTIDLE_SHIFT (8U) +/*! MSTIDLE - Master idle status flag. This bit is 1 whenever the SPI master function is fully idle. + * This means that the transmit holding register is empty and the transmitter is not in the + * process of sending data. + */ +#define SPI_STAT_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_MSTIDLE_SHIFT)) & SPI_STAT_MSTIDLE_MASK) +/*! @} */ + +/*! @name INTENSET - SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +/*! @{ */ +#define SPI_INTENSET_SSAEN_MASK (0x10U) +#define SPI_INTENSET_SSAEN_SHIFT (4U) +/*! SSAEN - Slave select assert interrupt enable. Determines whether an interrupt occurs when the Slave Select is asserted. + * 0b0..Disabled. No interrupt will be generated when any Slave Select transitions from deasserted to asserted. + * 0b1..Enabled. An interrupt will be generated when any Slave Select transitions from deasserted to asserted. + */ +#define SPI_INTENSET_SSAEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSAEN_SHIFT)) & SPI_INTENSET_SSAEN_MASK) +#define SPI_INTENSET_SSDEN_MASK (0x20U) +#define SPI_INTENSET_SSDEN_SHIFT (5U) +/*! SSDEN - Slave select deassert interrupt enable. Determines whether an interrupt occurs when the Slave Select is deasserted. + * 0b0..Disabled. No interrupt will be generated when all asserted Slave Selects transition to deasserted. + * 0b1..Enabled. An interrupt will be generated when all asserted Slave Selects transition to deasserted. + */ +#define SPI_INTENSET_SSDEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSDEN_SHIFT)) & SPI_INTENSET_SSDEN_MASK) +#define SPI_INTENSET_MSTIDLEEN_MASK (0x100U) +#define SPI_INTENSET_MSTIDLEEN_SHIFT (8U) +/*! MSTIDLEEN - Master idle interrupt enable. + * 0b0..No interrupt will be generated when the SPI master function is idle. + * 0b1..An interrupt will be generated when the SPI master function is fully idle. + */ +#define SPI_INTENSET_MSTIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_MSTIDLEEN_SHIFT)) & SPI_INTENSET_MSTIDLEEN_MASK) +/*! @} */ + +/*! @name INTENCLR - SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared. */ +/*! @{ */ +#define SPI_INTENCLR_SSAEN_MASK (0x10U) +#define SPI_INTENCLR_SSAEN_SHIFT (4U) +/*! SSAEN - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define SPI_INTENCLR_SSAEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSAEN_SHIFT)) & SPI_INTENCLR_SSAEN_MASK) +#define SPI_INTENCLR_SSDEN_MASK (0x20U) +#define SPI_INTENCLR_SSDEN_SHIFT (5U) +/*! SSDEN - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define SPI_INTENCLR_SSDEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSDEN_SHIFT)) & SPI_INTENCLR_SSDEN_MASK) +#define SPI_INTENCLR_MSTIDLE_MASK (0x100U) +#define SPI_INTENCLR_MSTIDLE_SHIFT (8U) +/*! MSTIDLE - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define SPI_INTENCLR_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_MSTIDLE_SHIFT)) & SPI_INTENCLR_MSTIDLE_MASK) +/*! @} */ + +/*! @name DIV - SPI clock Divider */ +/*! @{ */ +#define SPI_DIV_DIVVAL_MASK (0xFFFFU) +#define SPI_DIV_DIVVAL_SHIFT (0U) +/*! DIVVAL - Rate divider value. Specifies how the Flexcomm clock (FCLK) is divided to produce the + * SPI clock rate in master mode. DIVVAL is -1 encoded such that the value 0 results in FCLK/1, + * the value 1 results in FCLK/2, up to the maximum possible divide value of 0xFFFF, which results + * in FCLK/65536. + */ +#define SPI_DIV_DIVVAL(x) (((uint32_t)(((uint32_t)(x)) << SPI_DIV_DIVVAL_SHIFT)) & SPI_DIV_DIVVAL_MASK) +/*! @} */ + +/*! @name INTSTAT - SPI Interrupt Status */ +/*! @{ */ +#define SPI_INTSTAT_SSA_MASK (0x10U) +#define SPI_INTSTAT_SSA_SHIFT (4U) +/*! SSA - Slave Select Assert. + */ +#define SPI_INTSTAT_SSA(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSA_SHIFT)) & SPI_INTSTAT_SSA_MASK) +#define SPI_INTSTAT_SSD_MASK (0x20U) +#define SPI_INTSTAT_SSD_SHIFT (5U) +/*! SSD - Slave Select Deassert. + */ +#define SPI_INTSTAT_SSD(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSD_SHIFT)) & SPI_INTSTAT_SSD_MASK) +#define SPI_INTSTAT_MSTIDLE_MASK (0x100U) +#define SPI_INTSTAT_MSTIDLE_SHIFT (8U) +/*! MSTIDLE - Master Idle status flag. + */ +#define SPI_INTSTAT_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_MSTIDLE_SHIFT)) & SPI_INTSTAT_MSTIDLE_MASK) +/*! @} */ + +/*! @name FIFOCFG - FIFO configuration and enable register. */ +/*! @{ */ +#define SPI_FIFOCFG_ENABLETX_MASK (0x1U) +#define SPI_FIFOCFG_ENABLETX_SHIFT (0U) +/*! ENABLETX - Enable the transmit FIFO. + * 0b0..The transmit FIFO is not enabled. + * 0b1..The transmit FIFO is enabled. + */ +#define SPI_FIFOCFG_ENABLETX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_ENABLETX_SHIFT)) & SPI_FIFOCFG_ENABLETX_MASK) +#define SPI_FIFOCFG_ENABLERX_MASK (0x2U) +#define SPI_FIFOCFG_ENABLERX_SHIFT (1U) +/*! ENABLERX - Enable the receive FIFO. + * 0b0..The receive FIFO is not enabled. + * 0b1..The receive FIFO is enabled. + */ +#define SPI_FIFOCFG_ENABLERX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_ENABLERX_SHIFT)) & SPI_FIFOCFG_ENABLERX_MASK) +#define SPI_FIFOCFG_SIZE_MASK (0x30U) +#define SPI_FIFOCFG_SIZE_SHIFT (4U) +/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = FIFO is configured as 16 + * entries of 8 bits. 0x1, 0x2, 0x3 = not applicable to USART. + */ +#define SPI_FIFOCFG_SIZE(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_SIZE_SHIFT)) & SPI_FIFOCFG_SIZE_MASK) +#define SPI_FIFOCFG_DMATX_MASK (0x1000U) +#define SPI_FIFOCFG_DMATX_SHIFT (12U) +/*! DMATX - DMA configuration for transmit. + * 0b0..DMA is not used for the transmit function. + * 0b1..Trigger DMA for the transmit function if the FIFO is not full. Generally, data interrupts would be disabled if DMA is enabled. + */ +#define SPI_FIFOCFG_DMATX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_DMATX_SHIFT)) & SPI_FIFOCFG_DMATX_MASK) +#define SPI_FIFOCFG_DMARX_MASK (0x2000U) +#define SPI_FIFOCFG_DMARX_SHIFT (13U) +/*! DMARX - DMA configuration for receive. + * 0b0..DMA is not used for the receive function. + * 0b1..Trigger DMA for the receive function if the FIFO is not empty. Generally, data interrupts would be disabled if DMA is enabled. + */ +#define SPI_FIFOCFG_DMARX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_DMARX_SHIFT)) & SPI_FIFOCFG_DMARX_MASK) +#define SPI_FIFOCFG_WAKETX_MASK (0x4000U) +#define SPI_FIFOCFG_WAKETX_SHIFT (14U) +/*! WAKETX - Wake-up for transmit FIFO level. This allows the device to be woken from reduced power + * modes (up to power-down, as long as the peripheral function works in that power mode) without + * enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The + * CPU will remain stopped until woken by another cause, such as DMA completion. See Hardware + * Wake-up control register. + * 0b0..Only enabled interrupts will wake up the device form reduced power modes. + * 0b1..A device wake-up for DMA will occur if the transmit FIFO level reaches the value specified by TXLVL in + * FIFOTRIG, even when the TXLVL interrupt is not enabled. + */ +#define SPI_FIFOCFG_WAKETX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_WAKETX_SHIFT)) & SPI_FIFOCFG_WAKETX_MASK) +#define SPI_FIFOCFG_WAKERX_MASK (0x8000U) +#define SPI_FIFOCFG_WAKERX_SHIFT (15U) +/*! WAKERX - Wake-up for receive FIFO level. This allows the device to be woken from reduced power + * modes (up to power-down, as long as the peripheral function works in that power mode) without + * enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The + * CPU will remain stopped until woken by another cause, such as DMA completion. See Hardware + * Wake-up control register. + * 0b0..Only enabled interrupts will wake up the device form reduced power modes. + * 0b1..A device wake-up for DMA will occur if the receive FIFO level reaches the value specified by RXLVL in + * FIFOTRIG, even when the RXLVL interrupt is not enabled. + */ +#define SPI_FIFOCFG_WAKERX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_WAKERX_SHIFT)) & SPI_FIFOCFG_WAKERX_MASK) +#define SPI_FIFOCFG_EMPTYTX_MASK (0x10000U) +#define SPI_FIFOCFG_EMPTYTX_SHIFT (16U) +/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied. + */ +#define SPI_FIFOCFG_EMPTYTX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_EMPTYTX_SHIFT)) & SPI_FIFOCFG_EMPTYTX_MASK) +#define SPI_FIFOCFG_EMPTYRX_MASK (0x20000U) +#define SPI_FIFOCFG_EMPTYRX_SHIFT (17U) +/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied. + */ +#define SPI_FIFOCFG_EMPTYRX(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOCFG_EMPTYRX_SHIFT)) & SPI_FIFOCFG_EMPTYRX_MASK) +/*! @} */ + +/*! @name FIFOSTAT - FIFO status register. */ +/*! @{ */ +#define SPI_FIFOSTAT_TXERR_MASK (0x1U) +#define SPI_FIFOSTAT_TXERR_SHIFT (0U) +/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow + * caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is + * needed. Cleared by writing a 1 to this bit. + */ +#define SPI_FIFOSTAT_TXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXERR_SHIFT)) & SPI_FIFOSTAT_TXERR_MASK) +#define SPI_FIFOSTAT_RXERR_MASK (0x2U) +#define SPI_FIFOSTAT_RXERR_SHIFT (1U) +/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA + * not emptying the FIFO fast enough. Cleared by writing a 1 to this bit. + */ +#define SPI_FIFOSTAT_RXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXERR_SHIFT)) & SPI_FIFOSTAT_RXERR_MASK) +#define SPI_FIFOSTAT_PERINT_MASK (0x8U) +#define SPI_FIFOSTAT_PERINT_SHIFT (3U) +/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted + * an interrupt. The details can be found by reading the peripheral's STAT register. + */ +#define SPI_FIFOSTAT_PERINT(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_PERINT_SHIFT)) & SPI_FIFOSTAT_PERINT_MASK) +#define SPI_FIFOSTAT_TXEMPTY_MASK (0x10U) +#define SPI_FIFOSTAT_TXEMPTY_SHIFT (4U) +/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data. + */ +#define SPI_FIFOSTAT_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXEMPTY_SHIFT)) & SPI_FIFOSTAT_TXEMPTY_MASK) +#define SPI_FIFOSTAT_TXNOTFULL_MASK (0x20U) +#define SPI_FIFOSTAT_TXNOTFULL_SHIFT (5U) +/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be + * written. When 0, the transmit FIFO is full and another write would cause it to overflow. + */ +#define SPI_FIFOSTAT_TXNOTFULL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXNOTFULL_SHIFT)) & SPI_FIFOSTAT_TXNOTFULL_MASK) +#define SPI_FIFOSTAT_RXNOTEMPTY_MASK (0x40U) +#define SPI_FIFOSTAT_RXNOTEMPTY_SHIFT (6U) +/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty. + */ +#define SPI_FIFOSTAT_RXNOTEMPTY(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXNOTEMPTY_SHIFT)) & SPI_FIFOSTAT_RXNOTEMPTY_MASK) +#define SPI_FIFOSTAT_RXFULL_MASK (0x80U) +#define SPI_FIFOSTAT_RXFULL_SHIFT (7U) +/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to + * prevent the peripheral from causing an overflow. + */ +#define SPI_FIFOSTAT_RXFULL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXFULL_SHIFT)) & SPI_FIFOSTAT_RXFULL_MASK) +#define SPI_FIFOSTAT_TXLVL_MASK (0x1F00U) +#define SPI_FIFOSTAT_TXLVL_SHIFT (8U) +/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY + * and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at + * the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be + * 0. + */ +#define SPI_FIFOSTAT_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_TXLVL_SHIFT)) & SPI_FIFOSTAT_TXLVL_MASK) +#define SPI_FIFOSTAT_RXLVL_MASK (0x1F0000U) +#define SPI_FIFOSTAT_RXLVL_SHIFT (16U) +/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and + * RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the + * point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be + * 1. + */ +#define SPI_FIFOSTAT_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOSTAT_RXLVL_SHIFT)) & SPI_FIFOSTAT_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */ +/*! @{ */ +#define SPI_FIFOTRIG_TXLVLENA_MASK (0x1U) +#define SPI_FIFOTRIG_TXLVLENA_SHIFT (0U) +/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled + * in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set. + * 0b0..Transmit FIFO level does not generate a FIFO level trigger. + * 0b1..An trigger will be generated if the transmit FIFO level reaches the value specified by the TXLVL field in this register. + */ +#define SPI_FIFOTRIG_TXLVLENA(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_TXLVLENA_SHIFT)) & SPI_FIFOTRIG_TXLVLENA_MASK) +#define SPI_FIFOTRIG_RXLVLENA_MASK (0x2U) +#define SPI_FIFOTRIG_RXLVLENA_SHIFT (1U) +/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled + * in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set. + * 0b0..Receive FIFO level does not generate a FIFO level trigger. + * 0b1..An trigger will be generated if the receive FIFO level reaches the value specified by the RXLVL field in this register. + */ +#define SPI_FIFOTRIG_RXLVLENA(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_RXLVLENA_SHIFT)) & SPI_FIFOTRIG_RXLVLENA_MASK) +#define SPI_FIFOTRIG_TXLVL_MASK (0xF00U) +#define SPI_FIFOTRIG_TXLVL_SHIFT (8U) +/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. If enabled + * to do so, the FIFO level can wake up the device just enough to perform DMA, then return to + * the reduced power mode. See Hardware Wake-up control register. 0 = trigger when the TX FIFO + * becomes empty. 1 = trigger when the TX FIFO level decreases to one entry. 15 = trigger when the TX + * FIFO level decreases to 15 entries (is no longer full). + */ +#define SPI_FIFOTRIG_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_TXLVL_SHIFT)) & SPI_FIFOTRIG_TXLVL_MASK) +#define SPI_FIFOTRIG_RXLVL_MASK (0xF0000U) +#define SPI_FIFOTRIG_RXLVL_SHIFT (16U) +/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data + * is received. This field is used only when RXLVLENA = 1. If enabled to do so, the FIFO level + * can wake up the device just enough to perform DMA, then return to the reduced power mode. See + * Hardware Wake-up control register. 0 = trigger when the RX FIFO has received one entry (is no + * longer empty). 1 = trigger when the RX FIFO has received two entries. 15 = trigger when the RX + * FIFO has received 16 entries (has become full). + */ +#define SPI_FIFOTRIG_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOTRIG_RXLVL_SHIFT)) & SPI_FIFOTRIG_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */ +/*! @{ */ +#define SPI_FIFOINTENSET_TXERR_MASK (0x1U) +#define SPI_FIFOINTENSET_TXERR_SHIFT (0U) +/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR flag in the FIFOSTAT register. + * 0b0..No interrupt will be generated for a transmit error. + * 0b1..An interrupt will be generated when a transmit error occurs. + */ +#define SPI_FIFOINTENSET_TXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_TXERR_SHIFT)) & SPI_FIFOINTENSET_TXERR_MASK) +#define SPI_FIFOINTENSET_RXERR_MASK (0x2U) +#define SPI_FIFOINTENSET_RXERR_SHIFT (1U) +/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR flag in the FIFOSTAT register. + * 0b0..No interrupt will be generated for a receive error. + * 0b1..An interrupt will be generated when a receive error occurs. + */ +#define SPI_FIFOINTENSET_RXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_RXERR_SHIFT)) & SPI_FIFOINTENSET_RXERR_MASK) +#define SPI_FIFOINTENSET_TXLVL_MASK (0x4U) +#define SPI_FIFOINTENSET_TXLVL_SHIFT (2U) +/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level + * specified by the TXLVL field in the FIFOTRIG register. + * 0b0..No interrupt will be generated based on the TX FIFO level. + * 0b1..If TXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when the TX FIFO level decreases + * to the level specified by TXLVL in the FIFOTRIG register. + */ +#define SPI_FIFOINTENSET_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_TXLVL_SHIFT)) & SPI_FIFOINTENSET_TXLVL_MASK) +#define SPI_FIFOINTENSET_RXLVL_MASK (0x8U) +#define SPI_FIFOINTENSET_RXLVL_SHIFT (3U) +/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level + * specified by the TXLVL field in the FIFOTRIG register. + * 0b0..No interrupt will be generated based on the RX FIFO level. + * 0b1..If RXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when the when the RX FIFO level + * increases to the level specified by RXLVL in the FIFOTRIG register. + */ +#define SPI_FIFOINTENSET_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENSET_RXLVL_SHIFT)) & SPI_FIFOINTENSET_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */ +/*! @{ */ +#define SPI_FIFOINTENCLR_TXERR_MASK (0x1U) +#define SPI_FIFOINTENCLR_TXERR_SHIFT (0U) +/*! TXERR - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define SPI_FIFOINTENCLR_TXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_TXERR_SHIFT)) & SPI_FIFOINTENCLR_TXERR_MASK) +#define SPI_FIFOINTENCLR_RXERR_MASK (0x2U) +#define SPI_FIFOINTENCLR_RXERR_SHIFT (1U) +/*! RXERR - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define SPI_FIFOINTENCLR_RXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_RXERR_SHIFT)) & SPI_FIFOINTENCLR_RXERR_MASK) +#define SPI_FIFOINTENCLR_TXLVL_MASK (0x4U) +#define SPI_FIFOINTENCLR_TXLVL_SHIFT (2U) +/*! TXLVL - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define SPI_FIFOINTENCLR_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_TXLVL_SHIFT)) & SPI_FIFOINTENCLR_TXLVL_MASK) +#define SPI_FIFOINTENCLR_RXLVL_MASK (0x8U) +#define SPI_FIFOINTENCLR_RXLVL_SHIFT (3U) +/*! RXLVL - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define SPI_FIFOINTENCLR_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTENCLR_RXLVL_SHIFT)) & SPI_FIFOINTENCLR_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTSTAT - FIFO interrupt status register. */ +/*! @{ */ +#define SPI_FIFOINTSTAT_TXERR_MASK (0x1U) +#define SPI_FIFOINTSTAT_TXERR_SHIFT (0U) +/*! TXERR - TX FIFO error. + */ +#define SPI_FIFOINTSTAT_TXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_TXERR_SHIFT)) & SPI_FIFOINTSTAT_TXERR_MASK) +#define SPI_FIFOINTSTAT_RXERR_MASK (0x2U) +#define SPI_FIFOINTSTAT_RXERR_SHIFT (1U) +/*! RXERR - RX FIFO error. + */ +#define SPI_FIFOINTSTAT_RXERR(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_RXERR_SHIFT)) & SPI_FIFOINTSTAT_RXERR_MASK) +#define SPI_FIFOINTSTAT_TXLVL_MASK (0x4U) +#define SPI_FIFOINTSTAT_TXLVL_SHIFT (2U) +/*! TXLVL - Transmit FIFO level interrupt. + */ +#define SPI_FIFOINTSTAT_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_TXLVL_SHIFT)) & SPI_FIFOINTSTAT_TXLVL_MASK) +#define SPI_FIFOINTSTAT_RXLVL_MASK (0x8U) +#define SPI_FIFOINTSTAT_RXLVL_SHIFT (3U) +/*! RXLVL - Receive FIFO level interrupt. + */ +#define SPI_FIFOINTSTAT_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_RXLVL_SHIFT)) & SPI_FIFOINTSTAT_RXLVL_MASK) +#define SPI_FIFOINTSTAT_PERINT_MASK (0x10U) +#define SPI_FIFOINTSTAT_PERINT_SHIFT (4U) +/*! PERINT - Peripheral interrupt. + */ +#define SPI_FIFOINTSTAT_PERINT(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOINTSTAT_PERINT_SHIFT)) & SPI_FIFOINTSTAT_PERINT_MASK) +/*! @} */ + +/*! @name FIFOWR - FIFO write data. */ +/*! @{ */ +#define SPI_FIFOWR_TXDATA_MASK (0xFFFFU) +#define SPI_FIFOWR_TXDATA_SHIFT (0U) +/*! TXDATA - Transmit data to the FIFO. + */ +#define SPI_FIFOWR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXDATA_SHIFT)) & SPI_FIFOWR_TXDATA_MASK) +#define SPI_FIFOWR_TXSSEL0_N_MASK (0x10000U) +#define SPI_FIFOWR_TXSSEL0_N_SHIFT (16U) +/*! TXSSEL0_N - Transmit slave select. This field asserts SSEL0 in master mode. The output on the pin is active LOW by default. + * 0b0..SSEL0 asserted. + * 0b1..SSEL0 not asserted. + */ +#define SPI_FIFOWR_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL0_N_SHIFT)) & SPI_FIFOWR_TXSSEL0_N_MASK) +#define SPI_FIFOWR_TXSSEL1_N_MASK (0x20000U) +#define SPI_FIFOWR_TXSSEL1_N_SHIFT (17U) +/*! TXSSEL1_N - Transmit slave select. This field asserts SSEL1 in master mode. The output on the pin is active LOW by default. + * 0b0..SSEL1 asserted. + * 0b1..SSEL1 not asserted. + */ +#define SPI_FIFOWR_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL1_N_SHIFT)) & SPI_FIFOWR_TXSSEL1_N_MASK) +#define SPI_FIFOWR_TXSSEL2_N_MASK (0x40000U) +#define SPI_FIFOWR_TXSSEL2_N_SHIFT (18U) +/*! TXSSEL2_N - Transmit slave select. This field asserts SSEL2 in master mode. The output on the pin is active LOW by default. + * 0b0..SSEL2 asserted. + * 0b1..SSEL2 not asserted. + */ +#define SPI_FIFOWR_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL2_N_SHIFT)) & SPI_FIFOWR_TXSSEL2_N_MASK) +#define SPI_FIFOWR_TXSSEL3_N_MASK (0x80000U) +#define SPI_FIFOWR_TXSSEL3_N_SHIFT (19U) +/*! TXSSEL3_N - Transmit slave select. This field asserts SSEL3 in master mode. The output on the pin is active LOW by default. + * 0b0..SSEL3 asserted. + * 0b1..SSEL3 not asserted. + */ +#define SPI_FIFOWR_TXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_TXSSEL3_N_SHIFT)) & SPI_FIFOWR_TXSSEL3_N_MASK) +#define SPI_FIFOWR_EOT_MASK (0x100000U) +#define SPI_FIFOWR_EOT_SHIFT (20U) +/*! EOT - End of transfer. The asserted SSEL will be deasserted at the end of a transfer and remain + * so far at least the time specified by the Transfer_delay value in the DLY register. + * 0b0..SSEL not deasserted. This piece of data is not treated as the end of a transfer. SSEL will not be deasserted at the end of this data. + * 0b1..SSEL deasserted. This piece of data is treated as the end of a transfer. SSEL will be deasserted at the end of this piece of data. + */ +#define SPI_FIFOWR_EOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_EOT_SHIFT)) & SPI_FIFOWR_EOT_MASK) +#define SPI_FIFOWR_EOF_MASK (0x200000U) +#define SPI_FIFOWR_EOF_SHIFT (21U) +/*! EOF - End of frame. Between frames, a delay may be inserted, as defined by the Frame_delay value + * in the DLY register. The end of a frame may not be particularly meaningful if the Frame_delay + * value = 0. This control can be used as part of the support for frame lengths greater than 16 + * bits. + * 0b0..Data not EOF. This piece of data transmitted is not treated as the end of a frame. + * 0b1..Data EOF. This piece of data is treated as the end of a frame, causing the Frame_delay time to be + * inserted before subsequent data is transmitted. + */ +#define SPI_FIFOWR_EOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_EOF_SHIFT)) & SPI_FIFOWR_EOF_MASK) +#define SPI_FIFOWR_RXIGNORE_MASK (0x400000U) +#define SPI_FIFOWR_RXIGNORE_SHIFT (22U) +/*! RXIGNORE - Receive Ignore. This allows data to be transmitted using the SPI without the need to + * read unneeded data from the receiver. Setting this bit simplifies the transmit process and can + * be used with the DMA. + * 0b0..Read received data. Received data must be read in order to allow transmission to progress. SPI transmit + * will halt when the receive data FIFO is full. In slave mode, an overrun error will occur if received data + * is not read before new data is received. + * 0b1..Ignore received data. Received data is ignored, allowing transmission without reading unneeded received + * data. No receiver flags are generated. + */ +#define SPI_FIFOWR_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_RXIGNORE_SHIFT)) & SPI_FIFOWR_RXIGNORE_MASK) +#define SPI_FIFOWR_LEN_MASK (0xF000000U) +#define SPI_FIFOWR_LEN_SHIFT (24U) +/*! LEN - Data Length. Specifies the data length from 4 to 16 bits. Note that transfer lengths + * greater than 16 bits are supported by implementing multiple sequential transmits. 0x0-2 = Reserved. + * 0x3 = Data transfer is 4 bits in length. 0x4 = Data transfer is 5 bits in length. 0xF = Data + * transfer is 16 bits in length. + */ +#define SPI_FIFOWR_LEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFOWR_LEN_SHIFT)) & SPI_FIFOWR_LEN_MASK) +/*! @} */ + +/*! @name FIFORD - FIFO read data. */ +/*! @{ */ +#define SPI_FIFORD_RXDATA_MASK (0xFFFFU) +#define SPI_FIFORD_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. + */ +#define SPI_FIFORD_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXDATA_SHIFT)) & SPI_FIFORD_RXDATA_MASK) +#define SPI_FIFORD_RXSSEL0_N_MASK (0x10000U) +#define SPI_FIFORD_RXSSEL0_N_SHIFT (16U) +/*! RXSSEL0_N - Slave Select for receive. This field allows the state of the SSEL0 pin to be saved + * along with received data. The value will reflect the SSEL0 pin for both master and slave + * operation. A zero indicates that a slave select is active. The actual polarity of each slave select + * pin is configured by the related SPOL bit in CFG. + */ +#define SPI_FIFORD_RXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL0_N_SHIFT)) & SPI_FIFORD_RXSSEL0_N_MASK) +#define SPI_FIFORD_RXSSEL1_N_MASK (0x20000U) +#define SPI_FIFORD_RXSSEL1_N_SHIFT (17U) +/*! RXSSEL1_N - Slave Select for receive. This field allows the state of the SSEL1 pin to be saved + * along with received data. The value will reflect the SSEL1 pin for both master and slave + * operation. A zero indicates that a slave select is active. The actual polarity of each slave select + * pin is configured by the related SPOL bit in CFG. + */ +#define SPI_FIFORD_RXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL1_N_SHIFT)) & SPI_FIFORD_RXSSEL1_N_MASK) +#define SPI_FIFORD_RXSSEL2_N_MASK (0x40000U) +#define SPI_FIFORD_RXSSEL2_N_SHIFT (18U) +/*! RXSSEL2_N - Slave Select for receive. This field allows the state of the SSEL2 pin to be saved + * along with received data. The value will reflect the SSEL2 pin for both master and slave + * operation. A zero indicates that a slave select is active. The actual polarity of each slave select + * pin is configured by the related SPOL bit in CFG. + */ +#define SPI_FIFORD_RXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL2_N_SHIFT)) & SPI_FIFORD_RXSSEL2_N_MASK) +#define SPI_FIFORD_RXSSEL3_N_MASK (0x80000U) +#define SPI_FIFORD_RXSSEL3_N_SHIFT (19U) +/*! RXSSEL3_N - Slave Select for receive. This field allows the state of the SSEL3 pin to be saved + * along with received data. The value will reflect the SSEL3 pin for both master and slave + * operation. A zero indicates that a slave select is active. The actual polarity of each slave select + * pin is configured by the related SPOL bit in CFG. + */ +#define SPI_FIFORD_RXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_RXSSEL3_N_SHIFT)) & SPI_FIFORD_RXSSEL3_N_MASK) +#define SPI_FIFORD_SOT_MASK (0x100000U) +#define SPI_FIFORD_SOT_SHIFT (20U) +/*! SOT - Start of Transfer flag. This flag will be 1 if this is the first data after the SSELs went + * from deasserted to asserted (i.e., any previous transfer has ended). This information can be + * used to identify the first piece of data in cases where the transfer length is greater than 16 + * bits. + */ +#define SPI_FIFORD_SOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORD_SOT_SHIFT)) & SPI_FIFORD_SOT_MASK) +/*! @} */ + +/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. */ +/*! @{ */ +#define SPI_FIFORDNOPOP_RXDATA_MASK (0xFFFFU) +#define SPI_FIFORDNOPOP_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. + */ +#define SPI_FIFORDNOPOP_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXDATA_SHIFT)) & SPI_FIFORDNOPOP_RXDATA_MASK) +#define SPI_FIFORDNOPOP_RXSSEL0_N_MASK (0x10000U) +#define SPI_FIFORDNOPOP_RXSSEL0_N_SHIFT (16U) +/*! RXSSEL0_N - Slave Select for receive. + */ +#define SPI_FIFORDNOPOP_RXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL0_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL0_N_MASK) +#define SPI_FIFORDNOPOP_RXSSEL1_N_MASK (0x20000U) +#define SPI_FIFORDNOPOP_RXSSEL1_N_SHIFT (17U) +/*! RXSSEL1_N - Slave Select for receive. + */ +#define SPI_FIFORDNOPOP_RXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL1_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL1_N_MASK) +#define SPI_FIFORDNOPOP_RXSSEL2_N_MASK (0x40000U) +#define SPI_FIFORDNOPOP_RXSSEL2_N_SHIFT (18U) +/*! RXSSEL2_N - Slave Select for receive. + */ +#define SPI_FIFORDNOPOP_RXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL2_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL2_N_MASK) +#define SPI_FIFORDNOPOP_RXSSEL3_N_MASK (0x80000U) +#define SPI_FIFORDNOPOP_RXSSEL3_N_SHIFT (19U) +/*! RXSSEL3_N - Slave Select for receive. + */ +#define SPI_FIFORDNOPOP_RXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_RXSSEL3_N_SHIFT)) & SPI_FIFORDNOPOP_RXSSEL3_N_MASK) +#define SPI_FIFORDNOPOP_SOT_MASK (0x100000U) +#define SPI_FIFORDNOPOP_SOT_SHIFT (20U) +/*! SOT - Start of transfer flag. + */ +#define SPI_FIFORDNOPOP_SOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_FIFORDNOPOP_SOT_SHIFT)) & SPI_FIFORDNOPOP_SOT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SPI_Register_Masks */ + + +/* SPI - Peripheral instance base addresses */ +/** Peripheral SPI0 base address */ +#define SPI0_BASE (0x40086000u) +/** Peripheral SPI0 base pointer */ +#define SPI0 ((SPI_Type *)SPI0_BASE) +/** Peripheral SPI1 base address */ +#define SPI1_BASE (0x40087000u) +/** Peripheral SPI1 base pointer */ +#define SPI1 ((SPI_Type *)SPI1_BASE) +/** Peripheral SPI2 base address */ +#define SPI2_BASE (0x40088000u) +/** Peripheral SPI2 base pointer */ +#define SPI2 ((SPI_Type *)SPI2_BASE) +/** Peripheral SPI3 base address */ +#define SPI3_BASE (0x40089000u) +/** Peripheral SPI3 base pointer */ +#define SPI3 ((SPI_Type *)SPI3_BASE) +/** Peripheral SPI4 base address */ +#define SPI4_BASE (0x4008A000u) +/** Peripheral SPI4 base pointer */ +#define SPI4 ((SPI_Type *)SPI4_BASE) +/** Peripheral SPI5 base address */ +#define SPI5_BASE (0x40096000u) +/** Peripheral SPI5 base pointer */ +#define SPI5 ((SPI_Type *)SPI5_BASE) +/** Peripheral SPI6 base address */ +#define SPI6_BASE (0x40097000u) +/** Peripheral SPI6 base pointer */ +#define SPI6 ((SPI_Type *)SPI6_BASE) +/** Peripheral SPI7 base address */ +#define SPI7_BASE (0x40098000u) +/** Peripheral SPI7 base pointer */ +#define SPI7 ((SPI_Type *)SPI7_BASE) +/** Array initializer of SPI peripheral base addresses */ +#define SPI_BASE_ADDRS { SPI0_BASE, SPI1_BASE, SPI2_BASE, SPI3_BASE, SPI4_BASE, SPI5_BASE, SPI6_BASE, SPI7_BASE } +/** Array initializer of SPI peripheral base pointers */ +#define SPI_BASE_PTRS { SPI0, SPI1, SPI2, SPI3, SPI4, SPI5, SPI6, SPI7 } +/** Interrupt vectors for the SPI peripheral type */ +#define SPI_IRQS { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn, FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM4_IRQn, FLEXCOMM5_IRQn, FLEXCOMM6_IRQn, FLEXCOMM7_IRQn } + +/*! + * @} + */ /* end of group SPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPIFI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPIFI_Peripheral_Access_Layer SPIFI Peripheral Access Layer + * @{ + */ + +/** SPIFI - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< SPIFI control register, offset: 0x0 */ + __IO uint32_t CMD; /**< SPIFI command register, offset: 0x4 */ + __IO uint32_t ADDR; /**< SPIFI address register, offset: 0x8 */ + __IO uint32_t IDATA; /**< SPIFI intermediate data register, offset: 0xC */ + __IO uint32_t CLIMIT; /**< SPIFI limit register, offset: 0x10 */ + __IO uint32_t DATA; /**< SPIFI data register, offset: 0x14 */ + __IO uint32_t MCMD; /**< SPIFI memory command register, offset: 0x18 */ + __IO uint32_t STAT; /**< SPIFI status register, offset: 0x1C */ +} SPIFI_Type; + +/* ---------------------------------------------------------------------------- + -- SPIFI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPIFI_Register_Masks SPIFI Register Masks + * @{ + */ + +/*! @name CTRL - SPIFI control register */ +/*! @{ */ +#define SPIFI_CTRL_TIMEOUT_MASK (0xFFFFU) +#define SPIFI_CTRL_TIMEOUT_SHIFT (0U) +/*! TIMEOUT - This field contains the number of serial clock periods without the processor reading + * data in memory mode, which will cause the SPIFI hardware to terminate the command by driving + * the CS pin high and negating the CMD bit in the Status register. (This allows the flash memory + * to enter a lower-power state.) If the processor reads data from the flash region after a + * time-out, the command in the Memory Command Register is issued again. + */ +#define SPIFI_CTRL_TIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_TIMEOUT_SHIFT)) & SPIFI_CTRL_TIMEOUT_MASK) +#define SPIFI_CTRL_CSHIGH_MASK (0xF0000U) +#define SPIFI_CTRL_CSHIGH_SHIFT (16U) +/*! CSHIGH - This field controls the minimum CS high time, expressed as a number of serial clock periods minus one. + */ +#define SPIFI_CTRL_CSHIGH(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_CSHIGH_SHIFT)) & SPIFI_CTRL_CSHIGH_MASK) +#define SPIFI_CTRL_D_PRFTCH_DIS_MASK (0x200000U) +#define SPIFI_CTRL_D_PRFTCH_DIS_SHIFT (21U) +/*! D_PRFTCH_DIS - This bit allows conditioning of memory mode prefetches based on the AHB HPROT + * (instruction/data) access information. A 1 in this register means that the SPIFI will not attempt + * a speculative prefetch when it encounters data accesses. + */ +#define SPIFI_CTRL_D_PRFTCH_DIS(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_D_PRFTCH_DIS_SHIFT)) & SPIFI_CTRL_D_PRFTCH_DIS_MASK) +#define SPIFI_CTRL_INTEN_MASK (0x400000U) +#define SPIFI_CTRL_INTEN_SHIFT (22U) +/*! INTEN - If this bit is 1 when a command ends, the SPIFI will assert its interrupt request + * output. See INTRQ in the status register for further details. + */ +#define SPIFI_CTRL_INTEN(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_INTEN_SHIFT)) & SPIFI_CTRL_INTEN_MASK) +#define SPIFI_CTRL_MODE3_MASK (0x800000U) +#define SPIFI_CTRL_MODE3_SHIFT (23U) +/*! MODE3 - SPI Mode 3 select. + * 0b0..SCK LOW. The SPIFI drives SCK low after the rising edge at which the last bit of each command is + * captured, and keeps it low while CS is HIGH. + * 0b1..SCK HIGH. the SPIFI keeps SCK high after the rising edge for the last bit of each command and while CS is + * HIGH, and drives it low after it drives CS LOW. (Known serial flash devices can handle either mode, but + * some devices may require a particular mode for proper operation.) MODE3, RFCLK, and FBCLK should not all be + * 1, because in this case there is no final falling edge on SCK on which to sample the last data bit of the + * frame. + */ +#define SPIFI_CTRL_MODE3(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_MODE3_SHIFT)) & SPIFI_CTRL_MODE3_MASK) +#define SPIFI_CTRL_PRFTCH_DIS_MASK (0x8000000U) +#define SPIFI_CTRL_PRFTCH_DIS_SHIFT (27U) +/*! PRFTCH_DIS - Cache prefetching enable. The SPIFI includes an internal cache. A 1 in this bit disables prefetching of cache lines. + * 0b0..Enable. Cache prefetching enabled. + * 0b1..Disable. Disables prefetching of cache lines. + */ +#define SPIFI_CTRL_PRFTCH_DIS(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_PRFTCH_DIS_SHIFT)) & SPIFI_CTRL_PRFTCH_DIS_MASK) +#define SPIFI_CTRL_DUAL_MASK (0x10000000U) +#define SPIFI_CTRL_DUAL_SHIFT (28U) +/*! DUAL - Select dual protocol. + * 0b0..Quad protocol. This protocol uses IO3:0. + * 0b1..Dual protocol. This protocol uses IO1:0. + */ +#define SPIFI_CTRL_DUAL(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_DUAL_SHIFT)) & SPIFI_CTRL_DUAL_MASK) +#define SPIFI_CTRL_RFCLK_MASK (0x20000000U) +#define SPIFI_CTRL_RFCLK_SHIFT (29U) +/*! RFCLK - Select active clock edge for input data. + * 0b0..Rising edge. Read data is sampled on rising edges on the clock, as in classic SPI operation. + * 0b1..Falling edge. Read data is sampled on falling edges of the clock, allowing a full serial clock of of time + * in order to maximize the serial clock frequency. MODE3, RFCLK, and FBCLK should not all be 1, because in + * this case there is no final falling edge on SCK on which to sample the last data bit of the frame. + */ +#define SPIFI_CTRL_RFCLK(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_RFCLK_SHIFT)) & SPIFI_CTRL_RFCLK_MASK) +#define SPIFI_CTRL_FBCLK_MASK (0x40000000U) +#define SPIFI_CTRL_FBCLK_SHIFT (30U) +/*! FBCLK - Feedback clock select. + * 0b0..Internal clock. The SPIFI samples read data using an internal clock. + * 0b1..Feedback clock. Read data is sampled using a feedback clock from the SCK pin. This allows slightly more + * time for each received bit. MODE3, RFCLK, and FBCLK should not all be 1, because in this case there is no + * final falling edge on SCK on which to sample the last data bit of the frame. + */ +#define SPIFI_CTRL_FBCLK(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_FBCLK_SHIFT)) & SPIFI_CTRL_FBCLK_MASK) +#define SPIFI_CTRL_DMAEN_MASK (0x80000000U) +#define SPIFI_CTRL_DMAEN_SHIFT (31U) +/*! DMAEN - A 1 in this bit enables the DMA Request output from the SPIFI. Set this bit only when a + * DMA channel is used to transfer data in peripheral mode. Do not set this bit when a DMA + * channel is used for memory-to-memory transfers from the SPIFI memory area. DMAEN should only be used + * in Command mode. + */ +#define SPIFI_CTRL_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CTRL_DMAEN_SHIFT)) & SPIFI_CTRL_DMAEN_MASK) +/*! @} */ + +/*! @name CMD - SPIFI command register */ +/*! @{ */ +#define SPIFI_CMD_DATALEN_MASK (0x3FFFU) +#define SPIFI_CMD_DATALEN_SHIFT (0U) +/*! DATALEN - Except when the POLL bit in this register is 1, this field controls how many data + * bytes are in the command. 0 indicates that the command does not contain a data field. + */ +#define SPIFI_CMD_DATALEN(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_DATALEN_SHIFT)) & SPIFI_CMD_DATALEN_MASK) +#define SPIFI_CMD_POLL_MASK (0x4000U) +#define SPIFI_CMD_POLL_SHIFT (14U) +/*! POLL - This bit should be written as 1 only with an opcode that a) contains an input data field, + * and b) causes the serial flash device to return byte status repetitively (e.g., a Read Status + * command). When this bit is 1, the SPIFI hardware continues to read bytes until the test + * specified by the DATALEN field is met. The hardware tests the bit in each status byte selected by + * DATALEN bits 2:0, until a bit is found that is equal to DATALEN bit 3. When the test succeeds, + * the SPIFI captures the byte that meets this test so that it can be read from the Data + * Register, and terminates the command by raising CS. The end-of-command interrupt can be enabled to + * inform software when this occurs + */ +#define SPIFI_CMD_POLL(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_POLL_SHIFT)) & SPIFI_CMD_POLL_MASK) +#define SPIFI_CMD_DOUT_MASK (0x8000U) +#define SPIFI_CMD_DOUT_SHIFT (15U) +/*! DOUT - If the DATALEN field is not zero, this bit controls the direction of the data: + * 0b0..Input from serial flash. + * 0b1..Output to serial flash. + */ +#define SPIFI_CMD_DOUT(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_DOUT_SHIFT)) & SPIFI_CMD_DOUT_MASK) +#define SPIFI_CMD_INTLEN_MASK (0x70000U) +#define SPIFI_CMD_INTLEN_SHIFT (16U) +/*! INTLEN - This field controls how many intermediate bytes precede the data. (Each such byte may + * require 8 or 2 SCK cycles, depending on whether the intermediate field is in serial, 2-bit, or + * 4-bit format.) Intermediate bytes are output by the SPIFI, and include post-address control + * information, dummy and delay bytes. See the description of the Intermediate Data register for + * the contents of such bytes. + */ +#define SPIFI_CMD_INTLEN(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_INTLEN_SHIFT)) & SPIFI_CMD_INTLEN_MASK) +#define SPIFI_CMD_FIELDFORM_MASK (0x180000U) +#define SPIFI_CMD_FIELDFORM_SHIFT (19U) +/*! FIELDFORM - This field controls how the fields of the command are sent. + * 0b00..All serial. All fields of the command are serial. + * 0b01..Quad/dual data. Data field is quad/dual, other fields are serial. + * 0b10..Serial opcode. Opcode field is serial. Other fields are quad/dual. + * 0b11..All quad/dual. All fields of the command are in quad/dual format. + */ +#define SPIFI_CMD_FIELDFORM(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_FIELDFORM_SHIFT)) & SPIFI_CMD_FIELDFORM_MASK) +#define SPIFI_CMD_FRAMEFORM_MASK (0xE00000U) +#define SPIFI_CMD_FRAMEFORM_SHIFT (21U) +/*! FRAMEFORM - This field controls the opcode and address fields. + * 0b000..Reserved. + * 0b001..Opcode. Opcode only, no address. + * 0b010..Opcode one byte. Opcode, least significant byte of address. + * 0b011..Opcode two bytes. Opcode, two least significant bytes of address. + * 0b100..Opcode three bytes. Opcode, three least significant bytes of address. + * 0b101..Opcode four bytes. Opcode, 4 bytes of address. + * 0b110..No opcode three bytes. No opcode, 3 least significant bytes of address. + * 0b111..No opcode four bytes. No opcode, 4 bytes of address. + */ +#define SPIFI_CMD_FRAMEFORM(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_FRAMEFORM_SHIFT)) & SPIFI_CMD_FRAMEFORM_MASK) +#define SPIFI_CMD_OPCODE_MASK (0xFF000000U) +#define SPIFI_CMD_OPCODE_SHIFT (24U) +/*! OPCODE - The opcode of the command (not used for some FRAMEFORM values). + */ +#define SPIFI_CMD_OPCODE(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CMD_OPCODE_SHIFT)) & SPIFI_CMD_OPCODE_MASK) +/*! @} */ + +/*! @name ADDR - SPIFI address register */ +/*! @{ */ +#define SPIFI_ADDR_ADDRESS_MASK (0xFFFFFFFFU) +#define SPIFI_ADDR_ADDRESS_SHIFT (0U) +/*! ADDRESS - Address. + */ +#define SPIFI_ADDR_ADDRESS(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_ADDR_ADDRESS_SHIFT)) & SPIFI_ADDR_ADDRESS_MASK) +/*! @} */ + +/*! @name IDATA - SPIFI intermediate data register */ +/*! @{ */ +#define SPIFI_IDATA_IDATA_MASK (0xFFFFFFFFU) +#define SPIFI_IDATA_IDATA_SHIFT (0U) +/*! IDATA - Value of intermediate bytes. + */ +#define SPIFI_IDATA_IDATA(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_IDATA_IDATA_SHIFT)) & SPIFI_IDATA_IDATA_MASK) +/*! @} */ + +/*! @name CLIMIT - SPIFI limit register */ +/*! @{ */ +#define SPIFI_CLIMIT_CLIMIT_MASK (0xFFFFFFFFU) +#define SPIFI_CLIMIT_CLIMIT_SHIFT (0U) +/*! CLIMIT - Zero-based upper limit of cacheable memory + */ +#define SPIFI_CLIMIT_CLIMIT(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_CLIMIT_CLIMIT_SHIFT)) & SPIFI_CLIMIT_CLIMIT_MASK) +/*! @} */ + +/*! @name DATA - SPIFI data register */ +/*! @{ */ +#define SPIFI_DATA_DATA_MASK (0xFFFFFFFFU) +#define SPIFI_DATA_DATA_SHIFT (0U) +/*! DATA - Input or output data + */ +#define SPIFI_DATA_DATA(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_DATA_DATA_SHIFT)) & SPIFI_DATA_DATA_MASK) +/*! @} */ + +/*! @name MCMD - SPIFI memory command register */ +/*! @{ */ +#define SPIFI_MCMD_POLL_MASK (0x4000U) +#define SPIFI_MCMD_POLL_SHIFT (14U) +/*! POLL - This bit should be written as 0. + */ +#define SPIFI_MCMD_POLL(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_POLL_SHIFT)) & SPIFI_MCMD_POLL_MASK) +#define SPIFI_MCMD_DOUT_MASK (0x8000U) +#define SPIFI_MCMD_DOUT_SHIFT (15U) +/*! DOUT - This bit should be written as 0. + */ +#define SPIFI_MCMD_DOUT(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_DOUT_SHIFT)) & SPIFI_MCMD_DOUT_MASK) +#define SPIFI_MCMD_INTLEN_MASK (0x70000U) +#define SPIFI_MCMD_INTLEN_SHIFT (16U) +/*! INTLEN - This field controls how many intermediate bytes precede the data. (Each such byte may + * require 8 or 2 SCK cycles, depending on whether the intermediate field is in serial, 2-bit, or + * 4-bit format.) Intermediate bytes are output by the SPIFI, and include post-address control + * information, dummy and delay bytes. See the description of the Intermediate Data register for + * the contents of such bytes. + */ +#define SPIFI_MCMD_INTLEN(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_INTLEN_SHIFT)) & SPIFI_MCMD_INTLEN_MASK) +#define SPIFI_MCMD_FIELDFORM_MASK (0x180000U) +#define SPIFI_MCMD_FIELDFORM_SHIFT (19U) +/*! FIELDFORM - This field controls how the fields of the command are sent. + * 0b00..All serial. All fields of the command are serial. + * 0b01..Quad/dual data. Data field is quad/dual, other fields are serial. + * 0b10..Serial opcode. Opcode field is serial. Other fields are quad/dual. + * 0b11..All quad/dual. All fields of the command are in quad/dual format. + */ +#define SPIFI_MCMD_FIELDFORM(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_FIELDFORM_SHIFT)) & SPIFI_MCMD_FIELDFORM_MASK) +#define SPIFI_MCMD_FRAMEFORM_MASK (0xE00000U) +#define SPIFI_MCMD_FRAMEFORM_SHIFT (21U) +/*! FRAMEFORM - This field controls the opcode and address fields. + * 0b000..Reserved. + * 0b001..Opcode. Opcode only, no address. + * 0b010..Opcode one byte. Opcode, least-significant byte of address. + * 0b011..Opcode two bytes. Opcode, 2 least-significant bytes of address. + * 0b100..Opcode three bytes. Opcode, 3 least-significant bytes of address. + * 0b101..Opcode four bytes. Opcode, 4 bytes of address. + * 0b110..No opcode three bytes. No opcode, 3 least-significant bytes of address. + * 0b111..No opcode, 4 bytes of address. + */ +#define SPIFI_MCMD_FRAMEFORM(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_FRAMEFORM_SHIFT)) & SPIFI_MCMD_FRAMEFORM_MASK) +#define SPIFI_MCMD_OPCODE_MASK (0xFF000000U) +#define SPIFI_MCMD_OPCODE_SHIFT (24U) +/*! OPCODE - The opcode of the command (not used for some FRAMEFORM values). + */ +#define SPIFI_MCMD_OPCODE(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_MCMD_OPCODE_SHIFT)) & SPIFI_MCMD_OPCODE_MASK) +/*! @} */ + +/*! @name STAT - SPIFI status register */ +/*! @{ */ +#define SPIFI_STAT_MCINIT_MASK (0x1U) +#define SPIFI_STAT_MCINIT_SHIFT (0U) +/*! MCINIT - This bit is set when software successfully writes the Memory Command register, and is + * cleared by Reset or by writing a 1 to the RESET bit in this register. + */ +#define SPIFI_STAT_MCINIT(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_MCINIT_SHIFT)) & SPIFI_STAT_MCINIT_MASK) +#define SPIFI_STAT_CMD_MASK (0x2U) +#define SPIFI_STAT_CMD_SHIFT (1U) +/*! CMD - This bit is 1 when the Command register is written. It is cleared by a hardware reset, a + * write to the RESET bit in this register, or the deassertion of CS which indicates that the + * command has completed communication with the SPI Flash. + */ +#define SPIFI_STAT_CMD(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_CMD_SHIFT)) & SPIFI_STAT_CMD_MASK) +#define SPIFI_STAT_RESET_MASK (0x10U) +#define SPIFI_STAT_RESET_SHIFT (4U) +/*! RESET - Write a 1 to this bit to abort a current command or memory mode. This bit is cleared + * when the hardware is ready for a new command to be written to the Command register. + */ +#define SPIFI_STAT_RESET(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_RESET_SHIFT)) & SPIFI_STAT_RESET_MASK) +#define SPIFI_STAT_INTRQ_MASK (0x20U) +#define SPIFI_STAT_INTRQ_SHIFT (5U) +/*! INTRQ - This bit reflects the SPIFI interrupt request. Write a 1 to this bit to clear it. This + * bit is set when a CMD was previously 1 and has been cleared due to the deassertion of CS. + */ +#define SPIFI_STAT_INTRQ(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_INTRQ_SHIFT)) & SPIFI_STAT_INTRQ_MASK) +#define SPIFI_STAT_VERSION_MASK (0xFF000000U) +#define SPIFI_STAT_VERSION_SHIFT (24U) +/*! VERSION - - + */ +#define SPIFI_STAT_VERSION(x) (((uint32_t)(((uint32_t)(x)) << SPIFI_STAT_VERSION_SHIFT)) & SPIFI_STAT_VERSION_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SPIFI_Register_Masks */ + + +/* SPIFI - Peripheral instance base addresses */ +/** Peripheral SPIFI0 base address */ +#define SPIFI0_BASE (0x40080000u) +/** Peripheral SPIFI0 base pointer */ +#define SPIFI0 ((SPIFI_Type *)SPIFI0_BASE) +/** Array initializer of SPIFI peripheral base addresses */ +#define SPIFI_BASE_ADDRS { SPIFI0_BASE } +/** Array initializer of SPIFI peripheral base pointers */ +#define SPIFI_BASE_PTRS { SPIFI0 } +/** Interrupt vectors for the SPIFI peripheral type */ +#define SPIFI_IRQS { SPIFI0_IRQn } + +/*! + * @} + */ /* end of group SPIFI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SYSCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSCON_Peripheral_Access_Layer SYSCON Peripheral Access Layer + * @{ + */ + +/** SYSCON - Register Layout Typedef */ +typedef struct { + uint32_t SYSMEMREMAP; /**< System Remap register, offset: 0x0 */ + uint8_t RESERVED_0[12]; + __IO uint32_t AHBMATPRIO; /**< AHB multilayer matrix priority control, offset: 0x10 */ + uint8_t RESERVED_1[44]; + __IO uint32_t SYSTCKCAL; /**< System tick counter calibration, offset: 0x40 */ + uint8_t RESERVED_2[4]; + __IO uint32_t NMISRC; /**< NMI Source Select, offset: 0x48 */ + __IO uint32_t ASYNCAPBCTRL; /**< Asynchronous APB Control, offset: 0x4C */ + uint8_t RESERVED_3[112]; + __I uint32_t PIOPORCAP[2]; /**< POR captured value of port n, array offset: 0xC0, array step: 0x4 */ + uint8_t RESERVED_4[8]; + __I uint32_t PIORESCAP[2]; /**< Reset captured value of port n, array offset: 0xD0, array step: 0x4 */ + uint8_t RESERVED_5[40]; + __IO uint32_t PRESETCTRL[2]; /**< Peripheral reset control n, array offset: 0x100, array step: 0x4 */ + uint8_t RESERVED_6[24]; + __O uint32_t PRESETCTRLSET[2]; /**< Set bits in PRESETCTRLn, array offset: 0x120, array step: 0x4 */ + uint8_t RESERVED_7[24]; + __O uint32_t PRESETCTRLCLR[2]; /**< Clear bits in PRESETCTRLn, array offset: 0x140, array step: 0x4 */ + uint8_t RESERVED_8[168]; + __IO uint32_t SYSRSTSTAT; /**< System reset status register, offset: 0x1F0 */ + uint8_t RESERVED_9[12]; + __IO uint32_t AHBCLKCTRL[2]; /**< AHB Clock control n, array offset: 0x200, array step: 0x4 */ + uint8_t RESERVED_10[24]; + __O uint32_t AHBCLKCTRLSET[2]; /**< Set bits in AHBCLKCTRLn, array offset: 0x220, array step: 0x4 */ + uint8_t RESERVED_11[24]; + __O uint32_t AHBCLKCTRLCLR[2]; /**< Clear bits in AHBCLKCTRLn, array offset: 0x240, array step: 0x4 */ + uint8_t RESERVED_12[56]; + __IO uint32_t MAINCLKSELA; /**< Main clock source select A, offset: 0x280 */ + __IO uint32_t MAINCLKSELB; /**< Main clock source select B, offset: 0x284 */ + __IO uint32_t CLKOUTSELA; /**< CLKOUT clock source select A, offset: 0x288 */ + uint8_t RESERVED_13[4]; + __IO uint32_t SYSPLLCLKSEL; /**< PLL clock source select, offset: 0x290 */ + uint8_t RESERVED_14[12]; + __IO uint32_t SPIFICLKSEL; /**< SPIFI clock source select, offset: 0x2A0 */ + __IO uint32_t ADCCLKSEL; /**< ADC clock source select, offset: 0x2A4 */ + __IO uint32_t USBCLKSEL; /**< USB clock source select, offset: 0x2A8 */ + uint8_t RESERVED_15[4]; + __IO uint32_t FXCOMCLKSEL[8]; /**< Flexcomm 0 clock source select, array offset: 0x2B0, array step: 0x4 */ + uint8_t RESERVED_16[16]; + __IO uint32_t MCLKCLKSEL; /**< MCLK clock source select, offset: 0x2E0 */ + uint8_t RESERVED_17[4]; + __IO uint32_t FRGCLKSEL; /**< Fractional Rate Generator clock source select, offset: 0x2E8 */ + __IO uint32_t DMICCLKSEL; /**< Digital microphone (D-Mic) subsystem clock select, offset: 0x2EC */ + uint8_t RESERVED_18[16]; + __IO uint32_t SYSTICKCLKDIV; /**< SYSTICK clock divider, offset: 0x300 */ + __IO uint32_t TRACECLKDIV; /**< Trace clock divider, offset: 0x304 */ + uint8_t RESERVED_19[120]; + __IO uint32_t AHBCLKDIV; /**< AHB clock divider, offset: 0x380 */ + __IO uint32_t CLKOUTDIV; /**< CLKOUT clock divider, offset: 0x384 */ + uint8_t RESERVED_20[8]; + __IO uint32_t SPIFICLKDIV; /**< SPIFI clock divider, offset: 0x390 */ + __IO uint32_t ADCCLKDIV; /**< ADC clock divider, offset: 0x394 */ + __IO uint32_t USBCLKDIV; /**< USB clock divider, offset: 0x398 */ + uint8_t RESERVED_21[4]; + __IO uint32_t FRGCTRL; /**< Fractional rate divider, offset: 0x3A0 */ + uint8_t RESERVED_22[4]; + __IO uint32_t DMICCLKDIV; /**< DMIC clock divider, offset: 0x3A8 */ + __IO uint32_t MCLKDIV; /**< I2S MCLK clock divider, offset: 0x3AC */ + uint8_t RESERVED_23[80]; + __IO uint32_t FLASHCFG; /**< Flash wait states configuration, offset: 0x400 */ + uint8_t RESERVED_24[8]; + __IO uint32_t USBCLKCTRL; /**< USB clock control, offset: 0x40C */ + __IO uint32_t USBCLKSTAT; /**< USB clock status, offset: 0x410 */ + uint8_t RESERVED_25[4]; + __IO uint32_t FREQMECTRL; /**< Frequency measure register, offset: 0x418 */ + uint8_t RESERVED_26[4]; + __IO uint32_t MCLKIO; /**< MCLK input/output control, offset: 0x420 */ + uint8_t RESERVED_27[220]; + __IO uint32_t FROCTRL; /**< FRO oscillator control, offset: 0x500 */ + uint8_t RESERVED_28[4]; + __IO uint32_t WDTOSCCTRL; /**< Watchdog oscillator control, offset: 0x508 */ + __IO uint32_t RTCOSCCTRL; /**< RTC oscillator 32 kHz output control, offset: 0x50C */ + uint8_t RESERVED_29[112]; + __IO uint32_t SYSPLLCTRL; /**< PLL control, offset: 0x580 */ + __I uint32_t SYSPLLSTAT; /**< PLL status, offset: 0x584 */ + __IO uint32_t SYSPLLNDEC; /**< PLL N decoder, offset: 0x588 */ + __IO uint32_t SYSPLLPDEC; /**< PLL P decoder, offset: 0x58C */ + __IO uint32_t SYSPLLSSCTRL0; /**< PLL spread spectrum control 0, offset: 0x590 */ + __IO uint32_t SYSPLLSSCTRL1; /**< PLL spread spectrum control 1, offset: 0x594 */ + uint8_t RESERVED_30[104]; + __IO uint32_t PDSLEEPCFG[2]; /**< Sleep configuration register n, array offset: 0x600, array step: 0x4 */ + uint8_t RESERVED_31[8]; + __IO uint32_t PDRUNCFG[2]; /**< Power configuration register n, array offset: 0x610, array step: 0x4 */ + uint8_t RESERVED_32[8]; + __O uint32_t PDRUNCFGSET[2]; /**< Set bits in PDRUNCFGn, array offset: 0x620, array step: 0x4 */ + uint8_t RESERVED_33[8]; + __O uint32_t PDRUNCFGCLR[2]; /**< Clear bits in PDRUNCFGn, array offset: 0x630, array step: 0x4 */ + uint8_t RESERVED_34[72]; + __IO uint32_t STARTERP[2]; /**< Start logic n wake-up enable register, array offset: 0x680, array step: 0x4 */ + uint8_t RESERVED_35[24]; + __O uint32_t STARTERSET[2]; /**< Set bits in STARTERn, array offset: 0x6A0, array step: 0x4 */ + uint8_t RESERVED_36[24]; + __O uint32_t STARTERCLR[2]; /**< Clear bits in STARTERn, array offset: 0x6C0, array step: 0x4 */ + uint8_t RESERVED_37[184]; + __IO uint32_t HWWAKE; /**< Configures special cases of hardware wake-up, offset: 0x780 */ + uint8_t RESERVED_38[124]; + __IO uint32_t CPUCTRL; /**< CPU Control for multiple processors, offset: 0x800 */ + __IO uint32_t CPBOOT; /**< Coprocessor Boot Address, offset: 0x804 */ + __IO uint32_t CPSTACK; /**< Coprocessor Stack Address, offset: 0x808 */ + __I uint32_t CPSTAT; /**< Coprocessor Status, offset: 0x80C */ + uint8_t RESERVED_39[1524]; + __IO uint32_t AUTOCGOR; /**< Auto Clock-Gate Override Register, offset: 0xE04 */ + uint8_t RESERVED_40[492]; + __I uint32_t JTAGIDCODE; /**< JTAG ID code register, offset: 0xFF4 */ + __I uint32_t DEVICE_ID0; /**< Part ID register, offset: 0xFF8 */ + __I uint32_t DEVICE_ID1; /**< Boot ROM and die revision register, offset: 0xFFC */ + uint8_t RESERVED_41[127044]; + __IO uint32_t BODCTRL; /**< Brown-Out Detect control, offset: 0x20044 */ +} SYSCON_Type; + +/* ---------------------------------------------------------------------------- + -- SYSCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSCON_Register_Masks SYSCON Register Masks + * @{ + */ + +/*! @name AHBMATPRIO - AHB multilayer matrix priority control */ +/*! @{ */ +#define SYSCON_AHBMATPRIO_PRI_ICODE_MASK (0x3U) +#define SYSCON_AHBMATPRIO_PRI_ICODE_SHIFT (0U) +/*! PRI_ICODE - Cortex-M4 I-Code bus priority. Should typically be lower than PRI_DCODE for best operation. + */ +#define SYSCON_AHBMATPRIO_PRI_ICODE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_ICODE_SHIFT)) & SYSCON_AHBMATPRIO_PRI_ICODE_MASK) +#define SYSCON_AHBMATPRIO_PRI_DCODE_MASK (0xCU) +#define SYSCON_AHBMATPRIO_PRI_DCODE_SHIFT (2U) +/*! PRI_DCODE - Cortex M4 D-Code bus priority. + */ +#define SYSCON_AHBMATPRIO_PRI_DCODE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_DCODE_SHIFT)) & SYSCON_AHBMATPRIO_PRI_DCODE_MASK) +#define SYSCON_AHBMATPRIO_PRI_SYS_MASK (0x30U) +#define SYSCON_AHBMATPRIO_PRI_SYS_SHIFT (4U) +/*! PRI_SYS - Cortex M4 System bus priority. + */ +#define SYSCON_AHBMATPRIO_PRI_SYS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_SYS_SHIFT)) & SYSCON_AHBMATPRIO_PRI_SYS_MASK) +#define SYSCON_AHBMATPRIO_PRI_M0_MASK (0xC0U) +#define SYSCON_AHBMATPRIO_PRI_M0_SHIFT (6U) +/*! PRI_M0 - Cortex-M0+ bus priority. Present on selected devices. + */ +#define SYSCON_AHBMATPRIO_PRI_M0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_M0_SHIFT)) & SYSCON_AHBMATPRIO_PRI_M0_MASK) +#define SYSCON_AHBMATPRIO_PRI_USB_MASK (0x300U) +#define SYSCON_AHBMATPRIO_PRI_USB_SHIFT (8U) +/*! PRI_USB - USB interface priority. + */ +#define SYSCON_AHBMATPRIO_PRI_USB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_USB_SHIFT)) & SYSCON_AHBMATPRIO_PRI_USB_MASK) +#define SYSCON_AHBMATPRIO_PRI_DMA_MASK (0xC00U) +#define SYSCON_AHBMATPRIO_PRI_DMA_SHIFT (10U) +/*! PRI_DMA - DMA controller priority. + */ +#define SYSCON_AHBMATPRIO_PRI_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_DMA_SHIFT)) & SYSCON_AHBMATPRIO_PRI_DMA_MASK) +/*! @} */ + +/*! @name SYSTCKCAL - System tick counter calibration */ +/*! @{ */ +#define SYSCON_SYSTCKCAL_CAL_MASK (0xFFFFFFU) +#define SYSCON_SYSTCKCAL_CAL_SHIFT (0U) +/*! CAL - System tick timer calibration value. + */ +#define SYSCON_SYSTCKCAL_CAL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_CAL_SHIFT)) & SYSCON_SYSTCKCAL_CAL_MASK) +#define SYSCON_SYSTCKCAL_SKEW_MASK (0x1000000U) +#define SYSCON_SYSTCKCAL_SKEW_SHIFT (24U) +/*! SKEW - Initial value for the Systick timer. + */ +#define SYSCON_SYSTCKCAL_SKEW(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_SKEW_SHIFT)) & SYSCON_SYSTCKCAL_SKEW_MASK) +#define SYSCON_SYSTCKCAL_NOREF_MASK (0x2000000U) +#define SYSCON_SYSTCKCAL_NOREF_SHIFT (25U) +/*! NOREF - Initial value for the Systick timer. + */ +#define SYSCON_SYSTCKCAL_NOREF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_NOREF_SHIFT)) & SYSCON_SYSTCKCAL_NOREF_MASK) +/*! @} */ + +/*! @name NMISRC - NMI Source Select */ +/*! @{ */ +#define SYSCON_NMISRC_IRQM4_MASK (0x3FU) +#define SYSCON_NMISRC_IRQM4_SHIFT (0U) +/*! IRQM4 - The IRQ number of the interrupt that acts as the Non-Maskable Interrupt (NMI) for the Cortex-M4, if enabled by NMIENM4. + */ +#define SYSCON_NMISRC_IRQM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM4_SHIFT)) & SYSCON_NMISRC_IRQM4_MASK) +#define SYSCON_NMISRC_IRQM0_MASK (0x3F00U) +#define SYSCON_NMISRC_IRQM0_SHIFT (8U) +/*! IRQM0 - The IRQ number of the interrupt that acts as the Non-Maskable Interrupt (NMI) for the + * Cortex-M0+, if enabled by NMIENM0. Present on selected devices. + */ +#define SYSCON_NMISRC_IRQM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM0_SHIFT)) & SYSCON_NMISRC_IRQM0_MASK) +#define SYSCON_NMISRC_NMIENM0_MASK (0x40000000U) +#define SYSCON_NMISRC_NMIENM0_SHIFT (30U) +/*! NMIENM0 - Write a 1 to this bit to enable the Non-Maskable Interrupt (NMI) source selected by IRQM0. Present on selected devices. + */ +#define SYSCON_NMISRC_NMIENM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM0_SHIFT)) & SYSCON_NMISRC_NMIENM0_MASK) +#define SYSCON_NMISRC_NMIENM4_MASK (0x80000000U) +#define SYSCON_NMISRC_NMIENM4_SHIFT (31U) +/*! NMIENM4 - Write a 1 to this bit to enable the Non-Maskable Interrupt (NMI) source selected by IRQM4. + */ +#define SYSCON_NMISRC_NMIENM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM4_SHIFT)) & SYSCON_NMISRC_NMIENM4_MASK) +/*! @} */ + +/*! @name ASYNCAPBCTRL - Asynchronous APB Control */ +/*! @{ */ +#define SYSCON_ASYNCAPBCTRL_ENABLE_MASK (0x1U) +#define SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT (0U) +/*! ENABLE - Enables the asynchronous APB bridge and subsystem. + * 0b0..Disabled. Asynchronous APB bridge is disabled. + * 0b1..Enabled. Asynchronous APB bridge is enabled. + */ +#define SYSCON_ASYNCAPBCTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT)) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK) +/*! @} */ + +/*! @name PIOPORCAP - POR captured value of port n */ +/*! @{ */ +#define SYSCON_PIOPORCAP_PIOPORCAP_MASK (0xFFFFFFFFU) +#define SYSCON_PIOPORCAP_PIOPORCAP_SHIFT (0U) +/*! PIOPORCAP - State of PIOn_31 through PIOn_0 at power-on reset + */ +#define SYSCON_PIOPORCAP_PIOPORCAP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIOPORCAP_PIOPORCAP_SHIFT)) & SYSCON_PIOPORCAP_PIOPORCAP_MASK) +/*! @} */ + +/* The count of SYSCON_PIOPORCAP */ +#define SYSCON_PIOPORCAP_COUNT (2U) + +/*! @name PIORESCAP - Reset captured value of port n */ +/*! @{ */ +#define SYSCON_PIORESCAP_PIORESCAP_MASK (0xFFFFFFFFU) +#define SYSCON_PIORESCAP_PIORESCAP_SHIFT (0U) +/*! PIORESCAP - State of PIOn_31 through PIOn_0 for resets other than POR. + */ +#define SYSCON_PIORESCAP_PIORESCAP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIORESCAP_PIORESCAP_SHIFT)) & SYSCON_PIORESCAP_PIORESCAP_MASK) +/*! @} */ + +/* The count of SYSCON_PIORESCAP */ +#define SYSCON_PIORESCAP_COUNT (2U) + +/*! @name PRESETCTRL - Peripheral reset control n */ +/*! @{ */ +#define SYSCON_PRESETCTRL_MRT0_RST_MASK (0x1U) +#define SYSCON_PRESETCTRL_MRT0_RST_SHIFT (0U) +/*! MRT0_RST - Multi-rate timer (MRT0) reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_MRT0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_MRT0_RST_SHIFT)) & SYSCON_PRESETCTRL_MRT0_RST_MASK) +#define SYSCON_PRESETCTRL_SCT0_RST_MASK (0x4U) +#define SYSCON_PRESETCTRL_SCT0_RST_SHIFT (2U) +/*! SCT0_RST - State configurable timer 0 (SCT0) reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_SCT0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_SCT0_RST_SHIFT)) & SYSCON_PRESETCTRL_SCT0_RST_MASK) +#define SYSCON_PRESETCTRL_FLASH_RST_MASK (0x80U) +#define SYSCON_PRESETCTRL_FLASH_RST_SHIFT (7U) +/*! FLASH_RST - Flash controller reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FLASH_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FLASH_RST_SHIFT)) & SYSCON_PRESETCTRL_FLASH_RST_MASK) +#define SYSCON_PRESETCTRL_FMC_RST_MASK (0x100U) +#define SYSCON_PRESETCTRL_FMC_RST_SHIFT (8U) +/*! FMC_RST - Flash accelerator reset control. Note that the FMC must not be reset while executing + * from flash, and must be reconfigured after reset. 0 = Clear reset to this function. 1 = Assert + * reset to this function. + */ +#define SYSCON_PRESETCTRL_FMC_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FMC_RST_SHIFT)) & SYSCON_PRESETCTRL_FMC_RST_MASK) +#define SYSCON_PRESETCTRL_UTICK0_RST_MASK (0x400U) +#define SYSCON_PRESETCTRL_UTICK0_RST_SHIFT (10U) +/*! UTICK0_RST - Micro-tick Timer reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_UTICK0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_UTICK0_RST_SHIFT)) & SYSCON_PRESETCTRL_UTICK0_RST_MASK) +#define SYSCON_PRESETCTRL_FC0_RST_MASK (0x800U) +#define SYSCON_PRESETCTRL_FC0_RST_SHIFT (11U) +/*! FC0_RST - Flexcomm 0 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC0_RST_SHIFT)) & SYSCON_PRESETCTRL_FC0_RST_MASK) +#define SYSCON_PRESETCTRL_MUX_RST_MASK (0x800U) +#define SYSCON_PRESETCTRL_MUX_RST_SHIFT (11U) +/*! MUX_RST - Input mux reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_MUX_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_MUX_RST_SHIFT)) & SYSCON_PRESETCTRL_MUX_RST_MASK) +#define SYSCON_PRESETCTRL_FC1_RST_MASK (0x1000U) +#define SYSCON_PRESETCTRL_FC1_RST_SHIFT (12U) +/*! FC1_RST - Flexcomm 1 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC1_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC1_RST_SHIFT)) & SYSCON_PRESETCTRL_FC1_RST_MASK) +#define SYSCON_PRESETCTRL_FC2_RST_MASK (0x2000U) +#define SYSCON_PRESETCTRL_FC2_RST_SHIFT (13U) +/*! FC2_RST - Flexcomm 2 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC2_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC2_RST_SHIFT)) & SYSCON_PRESETCTRL_FC2_RST_MASK) +#define SYSCON_PRESETCTRL_IOCON_RST_MASK (0x2000U) +#define SYSCON_PRESETCTRL_IOCON_RST_SHIFT (13U) +/*! IOCON_RST - IOCON reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_IOCON_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_IOCON_RST_SHIFT)) & SYSCON_PRESETCTRL_IOCON_RST_MASK) +#define SYSCON_PRESETCTRL_FC3_RST_MASK (0x4000U) +#define SYSCON_PRESETCTRL_FC3_RST_SHIFT (14U) +/*! FC3_RST - Flexcomm 3 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC3_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC3_RST_SHIFT)) & SYSCON_PRESETCTRL_FC3_RST_MASK) +#define SYSCON_PRESETCTRL_GPIO0_RST_MASK (0x4000U) +#define SYSCON_PRESETCTRL_GPIO0_RST_SHIFT (14U) +/*! GPIO0_RST - GPIO0 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_GPIO0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GPIO0_RST_SHIFT)) & SYSCON_PRESETCTRL_GPIO0_RST_MASK) +#define SYSCON_PRESETCTRL_FC4_RST_MASK (0x8000U) +#define SYSCON_PRESETCTRL_FC4_RST_SHIFT (15U) +/*! FC4_RST - Flexcomm 4 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC4_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC4_RST_SHIFT)) & SYSCON_PRESETCTRL_FC4_RST_MASK) +#define SYSCON_PRESETCTRL_GPIO1_RST_MASK (0x8000U) +#define SYSCON_PRESETCTRL_GPIO1_RST_SHIFT (15U) +/*! GPIO1_RST - GPIO1 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_GPIO1_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GPIO1_RST_SHIFT)) & SYSCON_PRESETCTRL_GPIO1_RST_MASK) +#define SYSCON_PRESETCTRL_FC5_RST_MASK (0x10000U) +#define SYSCON_PRESETCTRL_FC5_RST_SHIFT (16U) +/*! FC5_RST - Flexcomm 5 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC5_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC5_RST_SHIFT)) & SYSCON_PRESETCTRL_FC5_RST_MASK) +#define SYSCON_PRESETCTRL_FC6_RST_MASK (0x20000U) +#define SYSCON_PRESETCTRL_FC6_RST_SHIFT (17U) +/*! FC6_RST - Flexcomm 6 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC6_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC6_RST_SHIFT)) & SYSCON_PRESETCTRL_FC6_RST_MASK) +#define SYSCON_PRESETCTRL_FC7_RST_MASK (0x40000U) +#define SYSCON_PRESETCTRL_FC7_RST_SHIFT (18U) +/*! FC7_RST - Flexcomm 7 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_FC7_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FC7_RST_SHIFT)) & SYSCON_PRESETCTRL_FC7_RST_MASK) +#define SYSCON_PRESETCTRL_PINT_RST_MASK (0x40000U) +#define SYSCON_PRESETCTRL_PINT_RST_SHIFT (18U) +/*! PINT_RST - Pin interrupt (PINT) reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_PINT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_PINT_RST_SHIFT)) & SYSCON_PRESETCTRL_PINT_RST_MASK) +#define SYSCON_PRESETCTRL_DMIC0_RST_MASK (0x80000U) +#define SYSCON_PRESETCTRL_DMIC0_RST_SHIFT (19U) +/*! DMIC0_RST - Digital microphone interface reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_DMIC0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_DMIC0_RST_SHIFT)) & SYSCON_PRESETCTRL_DMIC0_RST_MASK) +#define SYSCON_PRESETCTRL_GINT_RST_MASK (0x80000U) +#define SYSCON_PRESETCTRL_GINT_RST_SHIFT (19U) +/*! GINT_RST - Grouped interrupt (GINT) reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_GINT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GINT_RST_SHIFT)) & SYSCON_PRESETCTRL_GINT_RST_MASK) +#define SYSCON_PRESETCTRL_DMA0_RST_MASK (0x100000U) +#define SYSCON_PRESETCTRL_DMA0_RST_SHIFT (20U) +/*! DMA0_RST - DMA0 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_DMA0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_DMA0_RST_SHIFT)) & SYSCON_PRESETCTRL_DMA0_RST_MASK) +#define SYSCON_PRESETCTRL_CRC_RST_MASK (0x200000U) +#define SYSCON_PRESETCTRL_CRC_RST_SHIFT (21U) +/*! CRC_RST - CRC generator reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_CRC_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CRC_RST_SHIFT)) & SYSCON_PRESETCTRL_CRC_RST_MASK) +#define SYSCON_PRESETCTRL_CTIMER2_RST_MASK (0x400000U) +#define SYSCON_PRESETCTRL_CTIMER2_RST_SHIFT (22U) +/*! CTIMER2_RST - CTIMER2 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function + */ +#define SYSCON_PRESETCTRL_CTIMER2_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CTIMER2_RST_SHIFT)) & SYSCON_PRESETCTRL_CTIMER2_RST_MASK) +#define SYSCON_PRESETCTRL_WWDT_RST_MASK (0x400000U) +#define SYSCON_PRESETCTRL_WWDT_RST_SHIFT (22U) +/*! WWDT_RST - Watchdog timer reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_WWDT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_WWDT_RST_SHIFT)) & SYSCON_PRESETCTRL_WWDT_RST_MASK) +#define SYSCON_PRESETCTRL_USB0_RST_MASK (0x2000000U) +#define SYSCON_PRESETCTRL_USB0_RST_SHIFT (25U) +/*! USB0_RST - USB0 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_USB0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_USB0_RST_SHIFT)) & SYSCON_PRESETCTRL_USB0_RST_MASK) +#define SYSCON_PRESETCTRL_CTIMER0_RST_MASK (0x4000000U) +#define SYSCON_PRESETCTRL_CTIMER0_RST_SHIFT (26U) +/*! CTIMER0_RST - CTIMER0 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_CTIMER0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CTIMER0_RST_SHIFT)) & SYSCON_PRESETCTRL_CTIMER0_RST_MASK) +#define SYSCON_PRESETCTRL_ADC0_RST_MASK (0x8000000U) +#define SYSCON_PRESETCTRL_ADC0_RST_SHIFT (27U) +/*! ADC0_RST - ADC0 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_ADC0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_ADC0_RST_SHIFT)) & SYSCON_PRESETCTRL_ADC0_RST_MASK) +#define SYSCON_PRESETCTRL_CTIMER1_RST_MASK (0x8000000U) +#define SYSCON_PRESETCTRL_CTIMER1_RST_SHIFT (27U) +/*! CTIMER1_RST - CTIMER1 reset control. 0 = Clear reset to this function. 1 = Assert reset to this function. + */ +#define SYSCON_PRESETCTRL_CTIMER1_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CTIMER1_RST_SHIFT)) & SYSCON_PRESETCTRL_CTIMER1_RST_MASK) +/*! @} */ + +/* The count of SYSCON_PRESETCTRL */ +#define SYSCON_PRESETCTRL_COUNT (2U) + +/*! @name PRESETCTRLSET - Set bits in PRESETCTRLn */ +/*! @{ */ +#define SYSCON_PRESETCTRLSET_RST_SET_MASK (0xFFFFFFFFU) +#define SYSCON_PRESETCTRLSET_RST_SET_SHIFT (0U) +/*! RST_SET - Writing ones to this register sets the corresponding bit or bits in the PRESETCTRLn + * register, if they are implemented. Bits that do not correspond to defined bits in PRESETCTRLn + * are reserved and only zeroes should be written to them. + */ +#define SYSCON_PRESETCTRLSET_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET_RST_SET_MASK) +/*! @} */ + +/* The count of SYSCON_PRESETCTRLSET */ +#define SYSCON_PRESETCTRLSET_COUNT (2U) + +/*! @name PRESETCTRLCLR - Clear bits in PRESETCTRLn */ +/*! @{ */ +#define SYSCON_PRESETCTRLCLR_RST_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_PRESETCTRLCLR_RST_CLR_SHIFT (0U) +/*! RST_CLR - Writing ones to this register clears the corresponding bit or bits in the PRESETCTRLn + * register, if they are implemented. Bits that do not correspond to defined bits in PRESETCTRLn + * are reserved and only zeroes should be written to them. + */ +#define SYSCON_PRESETCTRLCLR_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR_RST_CLR_MASK) +/*! @} */ + +/* The count of SYSCON_PRESETCTRLCLR */ +#define SYSCON_PRESETCTRLCLR_COUNT (2U) + +/*! @name SYSRSTSTAT - System reset status register */ +/*! @{ */ +#define SYSCON_SYSRSTSTAT_POR_MASK (0x1U) +#define SYSCON_SYSRSTSTAT_POR_SHIFT (0U) +/*! POR - POR reset status + * 0b0..No POR detected + * 0b1..POR detected. Writing a one clears this reset. + */ +#define SYSCON_SYSRSTSTAT_POR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_POR_SHIFT)) & SYSCON_SYSRSTSTAT_POR_MASK) +#define SYSCON_SYSRSTSTAT_EXTRST_MASK (0x2U) +#define SYSCON_SYSRSTSTAT_EXTRST_SHIFT (1U) +/*! EXTRST - Status of the external RESET pin. External reset status + * 0b0..No reset event detected. + * 0b1..Reset detected. Writing a one clears this reset. + */ +#define SYSCON_SYSRSTSTAT_EXTRST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_EXTRST_SHIFT)) & SYSCON_SYSRSTSTAT_EXTRST_MASK) +#define SYSCON_SYSRSTSTAT_WDT_MASK (0x4U) +#define SYSCON_SYSRSTSTAT_WDT_SHIFT (2U) +/*! WDT - Status of the Watchdog reset + * 0b0..No WDT reset detected + * 0b1..WDT reset detected. Writing a one clears this reset. + */ +#define SYSCON_SYSRSTSTAT_WDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_WDT_SHIFT)) & SYSCON_SYSRSTSTAT_WDT_MASK) +#define SYSCON_SYSRSTSTAT_BOD_MASK (0x8U) +#define SYSCON_SYSRSTSTAT_BOD_SHIFT (3U) +/*! BOD - Status of the Brown-out detect reset + * 0b0..No BOD reset detected + * 0b1..BOD reset detected. Writing a one clears this reset. + */ +#define SYSCON_SYSRSTSTAT_BOD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_BOD_SHIFT)) & SYSCON_SYSRSTSTAT_BOD_MASK) +#define SYSCON_SYSRSTSTAT_SYSRST_MASK (0x10U) +#define SYSCON_SYSRSTSTAT_SYSRST_SHIFT (4U) +/*! SYSRST - Status of the software system reset + * 0b0..No System reset detected + * 0b1..System reset detected. Writing a one clears this reset. + */ +#define SYSCON_SYSRSTSTAT_SYSRST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_SYSRST_SHIFT)) & SYSCON_SYSRSTSTAT_SYSRST_MASK) +/*! @} */ + +/*! @name AHBCLKCTRL - AHB Clock control n */ +/*! @{ */ +#define SYSCON_AHBCLKCTRL_MRT0_MASK (0x1U) +#define SYSCON_AHBCLKCTRL_MRT0_SHIFT (0U) +/*! MRT0 - Enables the clock for the Multi-Rate Timer. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_MRT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_MRT0_SHIFT)) & SYSCON_AHBCLKCTRL_MRT0_MASK) +#define SYSCON_AHBCLKCTRL_ROM_MASK (0x2U) +#define SYSCON_AHBCLKCTRL_ROM_SHIFT (1U) +/*! ROM - Enables the clock for the Boot ROM. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_ROM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_ROM_SHIFT)) & SYSCON_AHBCLKCTRL_ROM_MASK) +#define SYSCON_AHBCLKCTRL_SCT0_MASK (0x4U) +#define SYSCON_AHBCLKCTRL_SCT0_SHIFT (2U) +/*! SCT0 - Enables the clock for SCT0. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_SCT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SCT0_SHIFT)) & SYSCON_AHBCLKCTRL_SCT0_MASK) +#define SYSCON_AHBCLKCTRL_SRAM1_MASK (0x8U) +#define SYSCON_AHBCLKCTRL_SRAM1_SHIFT (3U) +/*! SRAM1 - Enables the clock for SRAM1. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_SRAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SRAM1_SHIFT)) & SYSCON_AHBCLKCTRL_SRAM1_MASK) +#define SYSCON_AHBCLKCTRL_SRAM2_MASK (0x10U) +#define SYSCON_AHBCLKCTRL_SRAM2_SHIFT (4U) +/*! SRAM2 - Enables the clock for SRAM2. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_SRAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SRAM2_SHIFT)) & SYSCON_AHBCLKCTRL_SRAM2_MASK) +#define SYSCON_AHBCLKCTRL_FLASH_MASK (0x80U) +#define SYSCON_AHBCLKCTRL_FLASH_SHIFT (7U) +/*! FLASH - Enables the clock for the flash controller. 0 = Disable; 1 = Enable. This clock is + * needed for flash programming, not for flash read. + */ +#define SYSCON_AHBCLKCTRL_FLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLASH_SHIFT)) & SYSCON_AHBCLKCTRL_FLASH_MASK) +#define SYSCON_AHBCLKCTRL_FMC_MASK (0x100U) +#define SYSCON_AHBCLKCTRL_FMC_SHIFT (8U) +/*! FMC - Enables the clock for the Flash accelerator. 0 = Disable; 1 = Enable. This clock is needed if the flash is being read. + */ +#define SYSCON_AHBCLKCTRL_FMC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FMC_SHIFT)) & SYSCON_AHBCLKCTRL_FMC_MASK) +#define SYSCON_AHBCLKCTRL_UTICK0_MASK (0x400U) +#define SYSCON_AHBCLKCTRL_UTICK0_SHIFT (10U) +/*! UTICK0 - Enables the clock for the Micro-tick Timer. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_UTICK0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_UTICK0_SHIFT)) & SYSCON_AHBCLKCTRL_UTICK0_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM0_MASK (0x800U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM0_SHIFT (11U) +/*! FLEXCOMM0 - Enables the clock for Flexcomm 0. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM0_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM0_MASK) +#define SYSCON_AHBCLKCTRL_INPUTMUX_MASK (0x800U) +#define SYSCON_AHBCLKCTRL_INPUTMUX_SHIFT (11U) +/*! INPUTMUX - Enables the clock for the input muxes. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_INPUTMUX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_INPUTMUX_SHIFT)) & SYSCON_AHBCLKCTRL_INPUTMUX_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM1_MASK (0x1000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM1_SHIFT (12U) +/*! FLEXCOMM1 - Enables the clock for Flexcomm 1. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM1_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM1_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM2_MASK (0x2000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM2_SHIFT (13U) +/*! FLEXCOMM2 - Enables the clock for Flexcomm 2. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM2_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM2_MASK) +#define SYSCON_AHBCLKCTRL_IOCON_MASK (0x2000U) +#define SYSCON_AHBCLKCTRL_IOCON_SHIFT (13U) +/*! IOCON - Enables the clock for the IOCON block. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_IOCON(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_IOCON_SHIFT)) & SYSCON_AHBCLKCTRL_IOCON_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM3_MASK (0x4000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM3_SHIFT (14U) +/*! FLEXCOMM3 - Enables the clock for Flexcomm 3. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM3_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM3_MASK) +#define SYSCON_AHBCLKCTRL_GPIO0_MASK (0x4000U) +#define SYSCON_AHBCLKCTRL_GPIO0_SHIFT (14U) +/*! GPIO0 - Enables the clock for the GPIO0 port registers. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_GPIO0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GPIO0_SHIFT)) & SYSCON_AHBCLKCTRL_GPIO0_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM4_MASK (0x8000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM4_SHIFT (15U) +/*! FLEXCOMM4 - Enables the clock for Flexcomm 4. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM4_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM4_MASK) +#define SYSCON_AHBCLKCTRL_GPIO1_MASK (0x8000U) +#define SYSCON_AHBCLKCTRL_GPIO1_SHIFT (15U) +/*! GPIO1 - Enables the clock for the GPIO1 port registers. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_GPIO1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GPIO1_SHIFT)) & SYSCON_AHBCLKCTRL_GPIO1_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM5_MASK (0x10000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM5_SHIFT (16U) +/*! FLEXCOMM5 - Enables the clock for Flexcomm 5. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM5(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM5_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM5_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM6_MASK (0x20000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM6_SHIFT (17U) +/*! FLEXCOMM6 - Enables the clock for Flexcomm 6. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM6(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM6_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM6_MASK) +#define SYSCON_AHBCLKCTRL_FLEXCOMM7_MASK (0x40000U) +#define SYSCON_AHBCLKCTRL_FLEXCOMM7_SHIFT (18U) +/*! FLEXCOMM7 - Enables the clock for Flexcomm 7. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_FLEXCOMM7(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLEXCOMM7_SHIFT)) & SYSCON_AHBCLKCTRL_FLEXCOMM7_MASK) +#define SYSCON_AHBCLKCTRL_PINT_MASK (0x40000U) +#define SYSCON_AHBCLKCTRL_PINT_SHIFT (18U) +/*! PINT - Enables the clock for the pin interrupt block.0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_PINT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_PINT_SHIFT)) & SYSCON_AHBCLKCTRL_PINT_MASK) +#define SYSCON_AHBCLKCTRL_DMIC0_MASK (0x80000U) +#define SYSCON_AHBCLKCTRL_DMIC0_SHIFT (19U) +/*! DMIC0 - Enables the clock for the digital microphone interface. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_DMIC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_DMIC0_SHIFT)) & SYSCON_AHBCLKCTRL_DMIC0_MASK) +#define SYSCON_AHBCLKCTRL_GINT_MASK (0x80000U) +#define SYSCON_AHBCLKCTRL_GINT_SHIFT (19U) +/*! GINT - Enables the clock for the grouped pin interrupt block. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_GINT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GINT_SHIFT)) & SYSCON_AHBCLKCTRL_GINT_MASK) +#define SYSCON_AHBCLKCTRL_DMA0_MASK (0x100000U) +#define SYSCON_AHBCLKCTRL_DMA0_SHIFT (20U) +/*! DMA0 - Enables the clock for the DMA0 controller. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_DMA0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_DMA0_SHIFT)) & SYSCON_AHBCLKCTRL_DMA0_MASK) +#define SYSCON_AHBCLKCTRL_CRC_MASK (0x200000U) +#define SYSCON_AHBCLKCTRL_CRC_SHIFT (21U) +/*! CRC - Enables the clock for the CRC engine. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_CRC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CRC_SHIFT)) & SYSCON_AHBCLKCTRL_CRC_MASK) +#define SYSCON_AHBCLKCTRL_CTIMER2_MASK (0x400000U) +#define SYSCON_AHBCLKCTRL_CTIMER2_SHIFT (22U) +/*! CTIMER2 - Enables the clock for CTIMER 2. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_CTIMER2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CTIMER2_SHIFT)) & SYSCON_AHBCLKCTRL_CTIMER2_MASK) +#define SYSCON_AHBCLKCTRL_WWDT_MASK (0x400000U) +#define SYSCON_AHBCLKCTRL_WWDT_SHIFT (22U) +/*! WWDT - Enables the clock for the Watchdog Timer. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_WWDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_WWDT_SHIFT)) & SYSCON_AHBCLKCTRL_WWDT_MASK) +#define SYSCON_AHBCLKCTRL_RTC_MASK (0x800000U) +#define SYSCON_AHBCLKCTRL_RTC_SHIFT (23U) +/*! RTC - Enables the bus clock for the RTC. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_RTC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_RTC_SHIFT)) & SYSCON_AHBCLKCTRL_RTC_MASK) +#define SYSCON_AHBCLKCTRL_USB0_MASK (0x2000000U) +#define SYSCON_AHBCLKCTRL_USB0_SHIFT (25U) +/*! USB0 - Enables the clock for the USB0 interface. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_USB0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_USB0_SHIFT)) & SYSCON_AHBCLKCTRL_USB0_MASK) +#define SYSCON_AHBCLKCTRL_CTIMER0_MASK (0x4000000U) +#define SYSCON_AHBCLKCTRL_CTIMER0_SHIFT (26U) +/*! CTIMER0 - Enables the clock for timer CTIMER0. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_CTIMER0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CTIMER0_SHIFT)) & SYSCON_AHBCLKCTRL_CTIMER0_MASK) +#define SYSCON_AHBCLKCTRL_MAILBOX_MASK (0x4000000U) +#define SYSCON_AHBCLKCTRL_MAILBOX_SHIFT (26U) +/*! MAILBOX - Enables the clock for the Mailbox. 0 = Disable; 1 = Enable. Present on selected devices + */ +#define SYSCON_AHBCLKCTRL_MAILBOX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_MAILBOX_SHIFT)) & SYSCON_AHBCLKCTRL_MAILBOX_MASK) +#define SYSCON_AHBCLKCTRL_ADC0_MASK (0x8000000U) +#define SYSCON_AHBCLKCTRL_ADC0_SHIFT (27U) +/*! ADC0 - Enables the clock for the ADC0 register interface. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_ADC0_SHIFT)) & SYSCON_AHBCLKCTRL_ADC0_MASK) +#define SYSCON_AHBCLKCTRL_CTIMER1_MASK (0x8000000U) +#define SYSCON_AHBCLKCTRL_CTIMER1_SHIFT (27U) +/*! CTIMER1 - Enables the clock for timer CTIMER1. 0 = Disable; 1 = Enable. + */ +#define SYSCON_AHBCLKCTRL_CTIMER1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CTIMER1_SHIFT)) & SYSCON_AHBCLKCTRL_CTIMER1_MASK) +/*! @} */ + +/* The count of SYSCON_AHBCLKCTRL */ +#define SYSCON_AHBCLKCTRL_COUNT (2U) + +/*! @name AHBCLKCTRLSET - Set bits in AHBCLKCTRLn */ +/*! @{ */ +#define SYSCON_AHBCLKCTRLSET_CLK_SET_MASK (0xFFFFFFFFU) +#define SYSCON_AHBCLKCTRLSET_CLK_SET_SHIFT (0U) +/*! CLK_SET - Writing ones to this register sets the corresponding bit or bits in the AHBCLKCTRLn + * register, if they are implemented. Bits that do not correspond to defined bits in AHBCLKCTRLn + * are reserved and only zeroes should be written to them. + */ +#define SYSCON_AHBCLKCTRLSET_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET_CLK_SET_MASK) +/*! @} */ + +/* The count of SYSCON_AHBCLKCTRLSET */ +#define SYSCON_AHBCLKCTRLSET_COUNT (2U) + +/*! @name AHBCLKCTRLCLR - Clear bits in AHBCLKCTRLn */ +/*! @{ */ +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR_SHIFT (0U) +/*! CLK_CLR - Writing ones to this register clears the corresponding bit or bits in the AHBCLKCTRLn + * register, if they are implemented. Bits that do not correspond to defined bits in AHBCLKCTRLn + * are reserved and only zeroes should be written to them. + */ +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR_CLK_CLR_MASK) +/*! @} */ + +/* The count of SYSCON_AHBCLKCTRLCLR */ +#define SYSCON_AHBCLKCTRLCLR_COUNT (2U) + +/*! @name MAINCLKSELA - Main clock source select A */ +/*! @{ */ +#define SYSCON_MAINCLKSELA_SEL_MASK (0x3U) +#define SYSCON_MAINCLKSELA_SEL_SHIFT (0U) +/*! SEL - Clock source for main clock source selector A + * 0b00..FRO 12 MHz (fro_12m) + * 0b01..CLKIN (clk_in) + * 0b10..Watchdog oscillator (wdt_clk) + * 0b11..FRO 96 or 48 MHz (fro_hf) + */ +#define SYSCON_MAINCLKSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSELA_SEL_SHIFT)) & SYSCON_MAINCLKSELA_SEL_MASK) +/*! @} */ + +/*! @name MAINCLKSELB - Main clock source select B */ +/*! @{ */ +#define SYSCON_MAINCLKSELB_SEL_MASK (0x3U) +#define SYSCON_MAINCLKSELB_SEL_SHIFT (0U) +/*! SEL - Clock source for main clock source selector B. Selects the clock source for the main clock. + * 0b00..MAINCLKSELA. Use the clock source selected in MAINCLKSELA register. + * 0b01..Reserved setting + * 0b10..System PLL output (pll_clk) + * 0b11..RTC oscillator 32 kHz output (32k_clk) + */ +#define SYSCON_MAINCLKSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSELB_SEL_SHIFT)) & SYSCON_MAINCLKSELB_SEL_MASK) +/*! @} */ + +/*! @name CLKOUTSELA - CLKOUT clock source select A */ +/*! @{ */ +#define SYSCON_CLKOUTSELA_SEL_MASK (0x7U) +#define SYSCON_CLKOUTSELA_SEL_SHIFT (0U) +/*! SEL - CLKOUT clock source selection + * 0b000..Main clock (main_clk) + * 0b001..CLKIN (clk_in) + * 0b010..Watchdog oscillator (wdt_clk) + * 0b011..FRO 96 or 48 MHz (fro_hf) + * 0b100..PLL output (pll_clk) + * 0b101..FRO 12 MHz (fro_12m) + * 0b110..RTC oscillator 32 kHz output (32k_clk) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_CLKOUTSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSELA_SEL_SHIFT)) & SYSCON_CLKOUTSELA_SEL_MASK) +/*! @} */ + +/*! @name SYSPLLCLKSEL - PLL clock source select */ +/*! @{ */ +#define SYSCON_SYSPLLCLKSEL_SEL_MASK (0x7U) +#define SYSCON_SYSPLLCLKSEL_SEL_SHIFT (0U) +/*! SEL - System PLL clock source selection + * 0b000..FRO 12 MHz (fro_12m) + * 0b001..CLKIN (clk_in) + * 0b010..Watchdog oscillator (wdt_clk) + * 0b011..RTC 32 kHz clock (32k_clk) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_SYSPLLCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCLKSEL_SEL_SHIFT)) & SYSCON_SYSPLLCLKSEL_SEL_MASK) +/*! @} */ + +/*! @name SPIFICLKSEL - SPIFI clock source select */ +/*! @{ */ +#define SYSCON_SPIFICLKSEL_SEL_MASK (0x7U) +#define SYSCON_SPIFICLKSEL_SEL_SHIFT (0U) +/*! SEL - System PLL clock source selection + * 0b000..Main clock (main_clk) + * 0b001..System PLL output (pll_clk) + * 0b011..FRO 96 or 48 MHz (fro_hf) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_SPIFICLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKSEL_SEL_SHIFT)) & SYSCON_SPIFICLKSEL_SEL_MASK) +/*! @} */ + +/*! @name ADCCLKSEL - ADC clock source select */ +/*! @{ */ +#define SYSCON_ADCCLKSEL_SEL_MASK (0x7U) +#define SYSCON_ADCCLKSEL_SEL_SHIFT (0U) +/*! SEL - ADC clock source selection + * 0b000..Main clock (main_clk) + * 0b001..System PLL output (pll_clk) + * 0b010..FRO 96 or 48 MHz (fro_hf) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_ADCCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKSEL_SEL_SHIFT)) & SYSCON_ADCCLKSEL_SEL_MASK) +/*! @} */ + +/*! @name USBCLKSEL - USB clock source select */ +/*! @{ */ +#define SYSCON_USBCLKSEL_SEL_MASK (0x7U) +#define SYSCON_USBCLKSEL_SEL_SHIFT (0U) +/*! SEL - USB device clock source selection + * 0b000..FRO 96 or 48 MHz (fro_hf) + * 0b001..System PLL output (pll_clk) + * 0b010..Main clock (main_clk) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_USBCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_USBCLKSEL_SEL_SHIFT)) & SYSCON_USBCLKSEL_SEL_MASK) +/*! @} */ + +/*! @name FXCOMCLKSEL - Flexcomm 0 clock source select */ +/*! @{ */ +#define SYSCON_FXCOMCLKSEL_SEL_MASK (0x7U) +#define SYSCON_FXCOMCLKSEL_SEL_SHIFT (0U) +/*! SEL - Flexcomm clock source selection. One per Flexcomm. + * 0b000..FRO 12 MHz (fro_12m) + * 0b001..FRO 96 or 48 MHz (fro_hf) + * 0b010..System PLL output (pll_clk) + * 0b011..MCLK pin input, when selected in IOCON (mclk_in) + * 0b100..FRG clock, the output of the fractional rate generator (frg_clk) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_FXCOMCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FXCOMCLKSEL_SEL_SHIFT)) & SYSCON_FXCOMCLKSEL_SEL_MASK) +/*! @} */ + +/* The count of SYSCON_FXCOMCLKSEL */ +#define SYSCON_FXCOMCLKSEL_COUNT (8U) + +/*! @name MCLKCLKSEL - MCLK clock source select */ +/*! @{ */ +#define SYSCON_MCLKCLKSEL_SEL_MASK (0x7U) +#define SYSCON_MCLKCLKSEL_SEL_SHIFT (0U) +/*! SEL - MCLK source select. This may be used by Flexcomms that support I2S, and/or by the digital microphone subsystem. + * 0b000..FRO 96 or 48 MHz (fro_hf) + * 0b001..System PLL output (pll_clk) + * 0b010..Main clock (main_clk) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_MCLKCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MCLKCLKSEL_SEL_SHIFT)) & SYSCON_MCLKCLKSEL_SEL_MASK) +/*! @} */ + +/*! @name FRGCLKSEL - Fractional Rate Generator clock source select */ +/*! @{ */ +#define SYSCON_FRGCLKSEL_SEL_MASK (0x7U) +#define SYSCON_FRGCLKSEL_SEL_SHIFT (0U) +/*! SEL - Fractional Rate Generator clock source select. + * 0b000..Main clock (main_clk) + * 0b001..System PLL output (pll_clk) + * 0b010..FRO 12 MHz (fro_12m) + * 0b011..FRO 96 or 48 MHz (fro_hf) + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_FRGCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCLKSEL_SEL_SHIFT)) & SYSCON_FRGCLKSEL_SEL_MASK) +/*! @} */ + +/*! @name DMICCLKSEL - Digital microphone (D-Mic) subsystem clock select */ +/*! @{ */ +#define SYSCON_DMICCLKSEL_SEL_MASK (0x7U) +#define SYSCON_DMICCLKSEL_SEL_SHIFT (0U) +/*! SEL - D-Mic subsystem clock source select. + * 0b000..FRO 12 MHz (fro_12m) + * 0b001..FRO 96 or 48 MHz (fro_hf) + * 0b010..System PLL output (pll_clk) + * 0b011..MCLK pin input, when selected in IOCON (mclk_in) + * 0b100..Main clock (main_clk) + * 0b101..Watchdog oscillator (wdt_clk) + * 0b110..Reserved setting + * 0b111..None, this may be selected in order to reduce power when no output is needed. + */ +#define SYSCON_DMICCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKSEL_SEL_SHIFT)) & SYSCON_DMICCLKSEL_SEL_MASK) +/*! @} */ + +/*! @name SYSTICKCLKDIV - SYSTICK clock divider */ +/*! @{ */ +#define SYSCON_SYSTICKCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_SYSTICKCLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_SYSTICKCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_DIV_SHIFT)) & SYSCON_SYSTICKCLKDIV_DIV_MASK) +#define SYSCON_SYSTICKCLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_SYSTICKCLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_SYSTICKCLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_RESET_SHIFT)) & SYSCON_SYSTICKCLKDIV_RESET_MASK) +#define SYSCON_SYSTICKCLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_SYSTICKCLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_SYSTICKCLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_HALT_SHIFT)) & SYSCON_SYSTICKCLKDIV_HALT_MASK) +/*! @} */ + +/*! @name TRACECLKDIV - Trace clock divider */ +/*! @{ */ +#define SYSCON_TRACECLKDIV_DIV_MASK (0xFFU) +#define SYSCON_TRACECLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_TRACECLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_DIV_SHIFT)) & SYSCON_TRACECLKDIV_DIV_MASK) +#define SYSCON_TRACECLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_TRACECLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_TRACECLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_RESET_SHIFT)) & SYSCON_TRACECLKDIV_RESET_MASK) +#define SYSCON_TRACECLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_TRACECLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_TRACECLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_TRACECLKDIV_HALT_SHIFT)) & SYSCON_TRACECLKDIV_HALT_MASK) +/*! @} */ + +/*! @name AHBCLKDIV - AHB clock divider */ +/*! @{ */ +#define SYSCON_AHBCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_AHBCLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_AHBCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_DIV_SHIFT)) & SYSCON_AHBCLKDIV_DIV_MASK) +#define SYSCON_AHBCLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_AHBCLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_AHBCLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_RESET_SHIFT)) & SYSCON_AHBCLKDIV_RESET_MASK) +#define SYSCON_AHBCLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_AHBCLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_AHBCLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_HALT_SHIFT)) & SYSCON_AHBCLKDIV_HALT_MASK) +/*! @} */ + +/*! @name CLKOUTDIV - CLKOUT clock divider */ +/*! @{ */ +#define SYSCON_CLKOUTDIV_DIV_MASK (0xFFU) +#define SYSCON_CLKOUTDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_CLKOUTDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_DIV_SHIFT)) & SYSCON_CLKOUTDIV_DIV_MASK) +#define SYSCON_CLKOUTDIV_RESET_MASK (0x20000000U) +#define SYSCON_CLKOUTDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_CLKOUTDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_RESET_SHIFT)) & SYSCON_CLKOUTDIV_RESET_MASK) +#define SYSCON_CLKOUTDIV_HALT_MASK (0x40000000U) +#define SYSCON_CLKOUTDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_CLKOUTDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_HALT_SHIFT)) & SYSCON_CLKOUTDIV_HALT_MASK) +/*! @} */ + +/*! @name SPIFICLKDIV - SPIFI clock divider */ +/*! @{ */ +#define SYSCON_SPIFICLKDIV_DIV_MASK (0xFFU) +#define SYSCON_SPIFICLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_SPIFICLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_DIV_SHIFT)) & SYSCON_SPIFICLKDIV_DIV_MASK) +#define SYSCON_SPIFICLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_SPIFICLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_SPIFICLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_RESET_SHIFT)) & SYSCON_SPIFICLKDIV_RESET_MASK) +#define SYSCON_SPIFICLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_SPIFICLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_SPIFICLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SPIFICLKDIV_HALT_SHIFT)) & SYSCON_SPIFICLKDIV_HALT_MASK) +/*! @} */ + +/*! @name ADCCLKDIV - ADC clock divider */ +/*! @{ */ +#define SYSCON_ADCCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_ADCCLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_ADCCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_DIV_SHIFT)) & SYSCON_ADCCLKDIV_DIV_MASK) +#define SYSCON_ADCCLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_ADCCLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_ADCCLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_RESET_SHIFT)) & SYSCON_ADCCLKDIV_RESET_MASK) +#define SYSCON_ADCCLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_ADCCLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_ADCCLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_HALT_SHIFT)) & SYSCON_ADCCLKDIV_HALT_MASK) +/*! @} */ + +/*! @name USBCLKDIV - USB clock divider */ +/*! @{ */ +#define SYSCON_USBCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_USBCLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_USBCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_USBCLKDIV_DIV_SHIFT)) & SYSCON_USBCLKDIV_DIV_MASK) +#define SYSCON_USBCLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_USBCLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_USBCLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_USBCLKDIV_RESET_SHIFT)) & SYSCON_USBCLKDIV_RESET_MASK) +#define SYSCON_USBCLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_USBCLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_USBCLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_USBCLKDIV_HALT_SHIFT)) & SYSCON_USBCLKDIV_HALT_MASK) +/*! @} */ + +/*! @name FRGCTRL - Fractional rate divider */ +/*! @{ */ +#define SYSCON_FRGCTRL_DIV_MASK (0xFFU) +#define SYSCON_FRGCTRL_DIV_SHIFT (0U) +/*! DIV - Denominator of the fractional divider. DIV is equal to the programmed value +1. Always set + * to 0xFF to use with the fractional baud rate generator. + */ +#define SYSCON_FRGCTRL_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCTRL_DIV_SHIFT)) & SYSCON_FRGCTRL_DIV_MASK) +#define SYSCON_FRGCTRL_MULT_MASK (0xFF00U) +#define SYSCON_FRGCTRL_MULT_SHIFT (8U) +/*! MULT - Numerator of the fractional divider. MULT is equal to the programmed value. + */ +#define SYSCON_FRGCTRL_MULT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FRGCTRL_MULT_SHIFT)) & SYSCON_FRGCTRL_MULT_MASK) +/*! @} */ + +/*! @name DMICCLKDIV - DMIC clock divider */ +/*! @{ */ +#define SYSCON_DMICCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_DMICCLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_DMICCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_DIV_SHIFT)) & SYSCON_DMICCLKDIV_DIV_MASK) +#define SYSCON_DMICCLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_DMICCLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_DMICCLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_RESET_SHIFT)) & SYSCON_DMICCLKDIV_RESET_MASK) +#define SYSCON_DMICCLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_DMICCLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_DMICCLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DMICCLKDIV_HALT_SHIFT)) & SYSCON_DMICCLKDIV_HALT_MASK) +/*! @} */ + +/*! @name MCLKDIV - I2S MCLK clock divider */ +/*! @{ */ +#define SYSCON_MCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_MCLKDIV_DIV_SHIFT (0U) +/*! DIV - Clock divider value. 0: Divide by 1 up to 255: Divide by 256. + */ +#define SYSCON_MCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MCLKDIV_DIV_SHIFT)) & SYSCON_MCLKDIV_DIV_MASK) +#define SYSCON_MCLKDIV_RESET_MASK (0x20000000U) +#define SYSCON_MCLKDIV_RESET_SHIFT (29U) +/*! RESET - Resets the divider counter. Can be used to make sure a new divider value is used right + * away rather than completing the previous count. + */ +#define SYSCON_MCLKDIV_RESET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MCLKDIV_RESET_SHIFT)) & SYSCON_MCLKDIV_RESET_MASK) +#define SYSCON_MCLKDIV_HALT_MASK (0x40000000U) +#define SYSCON_MCLKDIV_HALT_SHIFT (30U) +/*! HALT - Halts the divider counter. The intent is to allow the divider clock source to be changed + * without the risk of a glitch at the output. + */ +#define SYSCON_MCLKDIV_HALT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MCLKDIV_HALT_SHIFT)) & SYSCON_MCLKDIV_HALT_MASK) +/*! @} */ + +/*! @name FLASHCFG - Flash wait states configuration */ +/*! @{ */ +#define SYSCON_FLASHCFG_FETCHCFG_MASK (0x3U) +#define SYSCON_FLASHCFG_FETCHCFG_SHIFT (0U) +/*! FETCHCFG - Instruction fetch configuration. This field determines how flash accelerator buffers are used for instruction fetches. + * 0b00..Instruction fetches from flash are not buffered. Every fetch request from the CPU results in a read of + * the flash memory. This setting may use significantly more power than when buffering is enabled. + * 0b01..One buffer is used for all instruction fetches. + * 0b10..All buffers may be used for instruction fetches. + * 0b11..Reserved setting, do not use. + */ +#define SYSCON_FLASHCFG_FETCHCFG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_FETCHCFG_SHIFT)) & SYSCON_FLASHCFG_FETCHCFG_MASK) +#define SYSCON_FLASHCFG_DATACFG_MASK (0xCU) +#define SYSCON_FLASHCFG_DATACFG_SHIFT (2U) +/*! DATACFG - Data read configuration. This field determines how flash accelerator buffers are used for data accesses. + * 0b00..Data accesses from flash are not buffered. Every data access from the CPU results in a read of the flash memory. + * 0b01..One buffer is used for all data accesses. + * 0b10..All buffers may be used for data accesses. + * 0b11..Reserved setting, do not use. + */ +#define SYSCON_FLASHCFG_DATACFG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_DATACFG_SHIFT)) & SYSCON_FLASHCFG_DATACFG_MASK) +#define SYSCON_FLASHCFG_ACCEL_MASK (0x10U) +#define SYSCON_FLASHCFG_ACCEL_SHIFT (4U) +/*! ACCEL - Acceleration enable. + * 0b0..Flash acceleration is disabled. Every flash read (including those fulfilled from a buffer) takes FLASHTIM + * + 1 system clocks. This allows more determinism at a cost of performance. + * 0b1..Flash acceleration is enabled. Performance is enhanced, dependent on other FLASHCFG settings. + */ +#define SYSCON_FLASHCFG_ACCEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_ACCEL_SHIFT)) & SYSCON_FLASHCFG_ACCEL_MASK) +#define SYSCON_FLASHCFG_PREFEN_MASK (0x20U) +#define SYSCON_FLASHCFG_PREFEN_SHIFT (5U) +/*! PREFEN - Prefetch enable. + * 0b0..No instruction prefetch is performed. + * 0b1..If the FETCHCFG field is not 0, the next flash line following the current execution address is + * automatically prefetched if it is not already buffered. + */ +#define SYSCON_FLASHCFG_PREFEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_PREFEN_SHIFT)) & SYSCON_FLASHCFG_PREFEN_MASK) +#define SYSCON_FLASHCFG_PREFOVR_MASK (0x40U) +#define SYSCON_FLASHCFG_PREFOVR_SHIFT (6U) +/*! PREFOVR - Prefetch override. This bit only applies when PREFEN = 1 and a buffered instruction is + * completing for which the next flash line is not already buffered or being prefetched. + * 0b0..Any previously initiated prefetch will be completed. + * 0b1..Any previously initiated prefetch will be aborted, and the next flash line following the current + * execution address will be prefetched if not already buffered. + */ +#define SYSCON_FLASHCFG_PREFOVR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_PREFOVR_SHIFT)) & SYSCON_FLASHCFG_PREFOVR_MASK) +#define SYSCON_FLASHCFG_FLASHTIM_MASK (0xF000U) +#define SYSCON_FLASHCFG_FLASHTIM_SHIFT (12U) +/*! FLASHTIM - Flash memory access time. The number of system clocks used for flash accesses is equal to FLASHTIM +1. + * 0b0000..1 system clock flash access time (for system clock rates up to 12 MHz). + * 0b0001..2 system clocks flash access time (for system clock rates up to 30 MHz). + * 0b0010..3 system clocks flash access time (for system clock rates up to 60 MHz). + * 0b0011..4 system clocks flash access time (for system clock rates up to 85 MHz). + * 0b0100..5 system clocks flash access time (for system clock rates up to 100 MHz). + */ +#define SYSCON_FLASHCFG_FLASHTIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_FLASHTIM_SHIFT)) & SYSCON_FLASHCFG_FLASHTIM_MASK) +/*! @} */ + +/*! @name USBCLKCTRL - USB clock control */ +/*! @{ */ +#define SYSCON_USBCLKCTRL_POL_CLK_MASK (0x2U) +#define SYSCON_USBCLKCTRL_POL_CLK_SHIFT (1U) +/*! POL_CLK - USB_NEED_CLK polarity for triggering the USB wake-up interrupt + * 0b0..Falling edge of the USB_NEED_CLK triggers the USB wake-up (default). + * 0b1..Rising edge of the USB_NEED_CLK triggers the USB wake-up. + */ +#define SYSCON_USBCLKCTRL_POL_CLK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_USBCLKCTRL_POL_CLK_SHIFT)) & SYSCON_USBCLKCTRL_POL_CLK_MASK) +/*! @} */ + +/*! @name USBCLKSTAT - USB clock status */ +/*! @{ */ +#define SYSCON_USBCLKSTAT_NEED_CLKST_MASK (0x1U) +#define SYSCON_USBCLKSTAT_NEED_CLKST_SHIFT (0U) +/*! NEED_CLKST - USB_NEED_CLK signal status + * 0b0..Low + * 0b1..High + */ +#define SYSCON_USBCLKSTAT_NEED_CLKST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_USBCLKSTAT_NEED_CLKST_SHIFT)) & SYSCON_USBCLKSTAT_NEED_CLKST_MASK) +/*! @} */ + +/*! @name FREQMECTRL - Frequency measure register */ +/*! @{ */ +#define SYSCON_FREQMECTRL_CAPVAL_MASK (0x3FFFU) +#define SYSCON_FREQMECTRL_CAPVAL_SHIFT (0U) +/*! CAPVAL - Stores the capture result which is used to calculate the frequency of the target clock. This field is read-only. + */ +#define SYSCON_FREQMECTRL_CAPVAL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FREQMECTRL_CAPVAL_SHIFT)) & SYSCON_FREQMECTRL_CAPVAL_MASK) +#define SYSCON_FREQMECTRL_PROG_MASK (0x80000000U) +#define SYSCON_FREQMECTRL_PROG_SHIFT (31U) +/*! PROG - Set this bit to one to initiate a frequency measurement cycle. Hardware clears this bit + * when the measurement cycle has completed and there is valid capture data in the CAPVAL field + * (bits 13:0). + */ +#define SYSCON_FREQMECTRL_PROG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FREQMECTRL_PROG_SHIFT)) & SYSCON_FREQMECTRL_PROG_MASK) +/*! @} */ + +/*! @name MCLKIO - MCLK input/output control */ +/*! @{ */ +#define SYSCON_MCLKIO_DIR_MASK (0x1U) +#define SYSCON_MCLKIO_DIR_SHIFT (0U) +/*! DIR - MCLK direction control. + * 0b0..The MCLK function is an input. + * 0b1..The MCLK function is an output. + */ +#define SYSCON_MCLKIO_DIR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MCLKIO_DIR_SHIFT)) & SYSCON_MCLKIO_DIR_MASK) +/*! @} */ + +/*! @name FROCTRL - FRO oscillator control */ +/*! @{ */ +#define SYSCON_FROCTRL_TRIM_MASK (0x3FFFU) +#define SYSCON_FROCTRL_TRIM_SHIFT (0U) +/*! TRIM - This value is factory trimmed to account for bias and temperature compensation. The value + * should not be changed by software. Also see the WRTRIM bit description. + */ +#define SYSCON_FROCTRL_TRIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_TRIM_SHIFT)) & SYSCON_FROCTRL_TRIM_MASK) +#define SYSCON_FROCTRL_SEL_MASK (0x4000U) +#define SYSCON_FROCTRL_SEL_SHIFT (14U) +/*! SEL - Select the fro_hf output frequency. This bit can only be changed by software when the + * WRTRIM bit = 1. Note that the factory trim values are for the 96 MHz FRO only. + * 0b0..48 MHz + * 0b1..96 MHz + */ +#define SYSCON_FROCTRL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_SEL_SHIFT)) & SYSCON_FROCTRL_SEL_MASK) +#define SYSCON_FROCTRL_FREQTRIM_MASK (0xFF0000U) +#define SYSCON_FROCTRL_FREQTRIM_SHIFT (16U) +/*! FREQTRIM - Frequency trim. Boot code configures this to a device-specific factory trim value for + * the 96 MHz FRO. If USBCLKADJ = 1, this field is read-only and provides the value resulting + * from USB rate adjustment. See the USBMODCFG flag regarding reading this field. Application code + * may adjust this field when USBCLKADJ = 0. A single step of FREQTRIM is roughly equivalent to + * 0.1% of the selected FRO frequency. + */ +#define SYSCON_FROCTRL_FREQTRIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_FREQTRIM_SHIFT)) & SYSCON_FROCTRL_FREQTRIM_MASK) +#define SYSCON_FROCTRL_USBCLKADJ_MASK (0x1000000U) +#define SYSCON_FROCTRL_USBCLKADJ_SHIFT (24U) +/*! USBCLKADJ - USB clock adjust mode. + * 0b0..Normal operation. + * 0b1..Automatic USB rate adjustment mode. If the USB FS device peripheral is enabled and connected to a USB + * host, it provides clock adjustment information to the FRO based on SOF packets. USB rate adjustment requires + * a number of cycles to take place. the USBMODCHG bit (see below) indicates when initial adjustment is + * complete, and when later adjustments are in progress. software must not alter TRIM and FREQTRIM while USBCLKADJ + * = 1. see USBCLKADJ usage notes below this table. + */ +#define SYSCON_FROCTRL_USBCLKADJ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_USBCLKADJ_SHIFT)) & SYSCON_FROCTRL_USBCLKADJ_MASK) +#define SYSCON_FROCTRL_USBMODCHG_MASK (0x2000000U) +#define SYSCON_FROCTRL_USBMODCHG_SHIFT (25U) +/*! USBMODCHG - USB Mode value Change flag. When 1, indicates that the USB trim is currently being + * updated (or is still starting up) and software should wait to read FREQTRIM. Update occurs at + * most once per millisecond. + */ +#define SYSCON_FROCTRL_USBMODCHG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_USBMODCHG_SHIFT)) & SYSCON_FROCTRL_USBMODCHG_MASK) +#define SYSCON_FROCTRL_HSPDCLK_MASK (0x40000000U) +#define SYSCON_FROCTRL_HSPDCLK_SHIFT (30U) +/*! HSPDCLK - High speed clock disable. Allows disabling the highs-speed FRO output if it is not needed. + * 0b0..The high-speed FRO output is disabled. + * 0b1..The selected high-speed FRO output (48 MHz or 96 MHz) is enabled. + */ +#define SYSCON_FROCTRL_HSPDCLK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_HSPDCLK_SHIFT)) & SYSCON_FROCTRL_HSPDCLK_MASK) +#define SYSCON_FROCTRL_WRTRIM_MASK (0x80000000U) +#define SYSCON_FROCTRL_WRTRIM_SHIFT (31U) +/*! WRTRIM - Write Trim value. Must be written to 1 to modify the SEL or TRIM fields, during the + * same write. This bit always reads as 0. + */ +#define SYSCON_FROCTRL_WRTRIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FROCTRL_WRTRIM_SHIFT)) & SYSCON_FROCTRL_WRTRIM_MASK) +/*! @} */ + +/*! @name WDTOSCCTRL - Watchdog oscillator control */ +/*! @{ */ +#define SYSCON_WDTOSCCTRL_DIVSEL_MASK (0x1FU) +#define SYSCON_WDTOSCCTRL_DIVSEL_SHIFT (0U) +/*! DIVSEL - Divider select. Selects the value of the divider that adjusts the output of the + * oscillator. 0x00 = divide by 2 0x01 = divide by 4 0x02 = divide by 6 up to 0x1E = divide by 62 0x1F = + * divide by 64 + */ +#define SYSCON_WDTOSCCTRL_DIVSEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTOSCCTRL_DIVSEL_SHIFT)) & SYSCON_WDTOSCCTRL_DIVSEL_MASK) +#define SYSCON_WDTOSCCTRL_FREQSEL_MASK (0x3E0U) +#define SYSCON_WDTOSCCTRL_FREQSEL_SHIFT (5U) +/*! FREQSEL - Frequency select. Selects the frequency of the oscillator. 0x00 = invalid setting when + * watchdog oscillator is running 0x01 = 0.4 MHz 0x02 = 0.6 MHz 0x03 = 0.75 MHz 0x04 = 0.9 MHz + * 0x05 = 1.0 MHz 0x06 = 1.2 MHz 0x07 = 1.3 MHz 0x08 = 1.4 MHz 0x09 = 1.5 MHz 0x0A = 1.6 MHz 0x0B + * = 1.7 MHz 0x0C = 1.8 MHz 0x0D = 1.9 MHz 0x0E = 2.0 MHz 0x0F = 2.05 MHz 0x10 = 2.1 MHz 0x11 = + * 2.2 MHz 0x12 = 2.25 MHz 0x13 = 2.3 MHz 0x14 = 2.4 MHz 0x15 = 2.45 MHz 0x16 = 2.5 MHz 0x17 = 2.6 + * MHz 0x18 = 2.65 MHz 0x19 = 2.7 MHz 0x1A = 2.8 MHz 0x1B = 2.85 MHz 0x1C = 2.9 MHz 0x1D = 2.95 + * MHz 0x1E = 3.0 MHz 0x1F = 3.05 MHz + */ +#define SYSCON_WDTOSCCTRL_FREQSEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)) & SYSCON_WDTOSCCTRL_FREQSEL_MASK) +/*! @} */ + +/*! @name RTCOSCCTRL - RTC oscillator 32 kHz output control */ +/*! @{ */ +#define SYSCON_RTCOSCCTRL_EN_MASK (0x1U) +#define SYSCON_RTCOSCCTRL_EN_SHIFT (0U) +/*! EN - RTC 32 kHz clock enable. + * 0b0..Disabled. RTC clock off. + * 0b1..Enabled. RTC clock on. + */ +#define SYSCON_RTCOSCCTRL_EN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCOSCCTRL_EN_SHIFT)) & SYSCON_RTCOSCCTRL_EN_MASK) +/*! @} */ + +/*! @name SYSPLLCTRL - PLL control */ +/*! @{ */ +#define SYSCON_SYSPLLCTRL_SELR_MASK (0xFU) +#define SYSCON_SYSPLLCTRL_SELR_SHIFT (0U) +/*! SELR - Bandwidth select R value + */ +#define SYSCON_SYSPLLCTRL_SELR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELR_SHIFT)) & SYSCON_SYSPLLCTRL_SELR_MASK) +#define SYSCON_SYSPLLCTRL_SELI_MASK (0x3F0U) +#define SYSCON_SYSPLLCTRL_SELI_SHIFT (4U) +/*! SELI - Bandwidth select I value. + */ +#define SYSCON_SYSPLLCTRL_SELI(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELI_SHIFT)) & SYSCON_SYSPLLCTRL_SELI_MASK) +#define SYSCON_SYSPLLCTRL_SELP_MASK (0x7C00U) +#define SYSCON_SYSPLLCTRL_SELP_SHIFT (10U) +/*! SELP - Bandwidth select P value + */ +#define SYSCON_SYSPLLCTRL_SELP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELP_SHIFT)) & SYSCON_SYSPLLCTRL_SELP_MASK) +#define SYSCON_SYSPLLCTRL_BYPASS_MASK (0x8000U) +#define SYSCON_SYSPLLCTRL_BYPASS_SHIFT (15U) +/*! BYPASS - PLL bypass control. + * 0b0..Bypass disabled. PLL CCO is sent to the PLL post-dividers. + * 0b1..Bypass enabled. PLL input clock is sent directly to the PLL output (default). + */ +#define SYSCON_SYSPLLCTRL_BYPASS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) & SYSCON_SYSPLLCTRL_BYPASS_MASK) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK (0x10000U) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT (16U) +/*! BYPASSCCODIV2 - Bypass feedback clock divide by 2. + * 0b0..Divide by 2. The CCO feedback clock is divided by 2 in addition to the programmed M divide. + * 0b1..Bypass. The CCO feedback clock is divided only by the programmed M divide. + */ +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT)) & SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_MASK (0x20000U) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT (17U) +/*! UPLIMOFF - Disable upper frequency limiter. + * 0b0..Normal mode. + * 0b1..Upper frequency limiter disabled. + */ +#define SYSCON_SYSPLLCTRL_UPLIMOFF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT)) & SYSCON_SYSPLLCTRL_UPLIMOFF_MASK) +#define SYSCON_SYSPLLCTRL_BANDSEL_MASK (0x40000U) +#define SYSCON_SYSPLLCTRL_BANDSEL_SHIFT (18U) +/*! BANDSEL - PLL filter control. Set this bit to one when the spread spectrum controller is + * disabled or at low frequencies. For spread spectrum mode: SEL_EXT = 0, BANDSEL = 0, and UPLIMOFF = 1. + * 0b0..SSCG control. The PLL filter uses the parameters derived from the spread spectrum controller. + * 0b1..MDEC control. The PLL filter uses the programmable fields SELP, SELR, and SELI in this register to control the filter constants. + */ +#define SYSCON_SYSPLLCTRL_BANDSEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BANDSEL_SHIFT)) & SYSCON_SYSPLLCTRL_BANDSEL_MASK) +#define SYSCON_SYSPLLCTRL_DIRECTI_MASK (0x80000U) +#define SYSCON_SYSPLLCTRL_DIRECTI_SHIFT (19U) +/*! DIRECTI - PLL0 direct input enable + * 0b0..Disabled. The PLL input divider (N divider) output is used to drive the PLL CCO. + * 0b1..Enabled. The PLL input divider (N divider) is bypassed. the PLL input clock is used directly to drive the PLL CCO input. + */ +#define SYSCON_SYSPLLCTRL_DIRECTI(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) & SYSCON_SYSPLLCTRL_DIRECTI_MASK) +#define SYSCON_SYSPLLCTRL_DIRECTO_MASK (0x100000U) +#define SYSCON_SYSPLLCTRL_DIRECTO_SHIFT (20U) +/*! DIRECTO - PLL0 direct output enable. + * 0b0..Disabled. The PLL output divider (P divider) is used to create the PLL output. + * 0b1..Enabled. The PLL output divider (P divider) is bypassed, the PLL CCO output is used as the PLL output. + */ +#define SYSCON_SYSPLLCTRL_DIRECTO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT)) & SYSCON_SYSPLLCTRL_DIRECTO_MASK) +/*! @} */ + +/*! @name SYSPLLSTAT - PLL status */ +/*! @{ */ +#define SYSCON_SYSPLLSTAT_LOCK_MASK (0x1U) +#define SYSCON_SYSPLLSTAT_LOCK_SHIFT (0U) +/*! LOCK - PLL0 lock indicator + */ +#define SYSCON_SYSPLLSTAT_LOCK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSTAT_LOCK_SHIFT)) & SYSCON_SYSPLLSTAT_LOCK_MASK) +/*! @} */ + +/*! @name SYSPLLNDEC - PLL N decoder */ +/*! @{ */ +#define SYSCON_SYSPLLNDEC_NDEC_MASK (0x3FFU) +#define SYSCON_SYSPLLNDEC_NDEC_SHIFT (0U) +/*! NDEC - Decoded N-divider coefficient value. + */ +#define SYSCON_SYSPLLNDEC_NDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLNDEC_NDEC_SHIFT)) & SYSCON_SYSPLLNDEC_NDEC_MASK) +#define SYSCON_SYSPLLNDEC_NREQ_MASK (0x400U) +#define SYSCON_SYSPLLNDEC_NREQ_SHIFT (10U) +/*! NREQ - NDEC reload request. When a 1 is written to this bit, the NDEC value is loaded into the + * PLL. Must be cleared by software for any subsequent load, or the PLL can be powered down and + * back up via the PDEN_SYS_PLL bit in the PDRUNCFG register if the NDEC value is changed. + */ +#define SYSCON_SYSPLLNDEC_NREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLNDEC_NREQ_SHIFT)) & SYSCON_SYSPLLNDEC_NREQ_MASK) +/*! @} */ + +/*! @name SYSPLLPDEC - PLL P decoder */ +/*! @{ */ +#define SYSCON_SYSPLLPDEC_PDEC_MASK (0x7FU) +#define SYSCON_SYSPLLPDEC_PDEC_SHIFT (0U) +/*! PDEC - Decoded P-divider coefficient value. + */ +#define SYSCON_SYSPLLPDEC_PDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLPDEC_PDEC_SHIFT)) & SYSCON_SYSPLLPDEC_PDEC_MASK) +#define SYSCON_SYSPLLPDEC_PREQ_MASK (0x80U) +#define SYSCON_SYSPLLPDEC_PREQ_SHIFT (7U) +/*! PREQ - PDEC reload request. When a 1 is written to this bit, the PDEC value is loaded into the + * PLL. Must be cleared by software for any subsequent load, or the PLL can be powered down and + * back up via the PDEN_SYS_PLL bit in the PDRUNCFG register if the PDEC value is changed. + */ +#define SYSCON_SYSPLLPDEC_PREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLPDEC_PREQ_SHIFT)) & SYSCON_SYSPLLPDEC_PREQ_MASK) +/*! @} */ + +/*! @name SYSPLLSSCTRL0 - PLL spread spectrum control 0 */ +/*! @{ */ +#define SYSCON_SYSPLLSSCTRL0_MDEC_MASK (0x1FFFFU) +#define SYSCON_SYSPLLSSCTRL0_MDEC_SHIFT (0U) +/*! MDEC - Decoded M-divider coefficient value. + */ +#define SYSCON_SYSPLLSSCTRL0_MDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_MDEC_SHIFT)) & SYSCON_SYSPLLSSCTRL0_MDEC_MASK) +#define SYSCON_SYSPLLSSCTRL0_MREQ_MASK (0x20000U) +#define SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT (17U) +/*! MREQ - MDEC reload request. When a 1 is written to this bit, the MDEC value is loaded into the + * PLL. Must be cleared by software for any subsequent load, or the PLL can be powered down and + * back up via the PDEN_SYS_PLL bit in the PDRUNCFG register if the MDEC value is changed. + */ +#define SYSCON_SYSPLLSSCTRL0_MREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT)) & SYSCON_SYSPLLSSCTRL0_MREQ_MASK) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK (0x40000U) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT (18U) +/*! SEL_EXT - Select spread spectrum mode. Selects the source of the feedback divider value. For + * normal mode, this must be the value from the MDEC field in this register. For spread spectrum + * mode: SEL_EXT = 0, BANDSEL = 0, and UPLIMOFF = 1. + */ +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT)) & SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK) +/*! @} */ + +/*! @name SYSPLLSSCTRL1 - PLL spread spectrum control 1 */ +/*! @{ */ +#define SYSCON_SYSPLLSSCTRL1_MD_MASK (0x7FFFFU) +#define SYSCON_SYSPLLSSCTRL1_MD_SHIFT (0U) +/*! MD - M- divider value with fraction. MD[18:11]: integer portion of the feedback divider value. + * MD[10:0]: fractional portion of the feedback divider value. In fractional mode, fcco = (2 - + * BYPASSCCODIV2) x (MD x 2^-11) x Fref + */ +#define SYSCON_SYSPLLSSCTRL1_MD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MD_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MD_MASK) +#define SYSCON_SYSPLLSSCTRL1_MDREQ_MASK (0x80000U) +#define SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT (19U) +/*! MDREQ - MD reload request. When a 1 is written to this bit, the MD value is loaded into the PLL. + * This bit is cleared when the load is complete + */ +#define SYSCON_SYSPLLSSCTRL1_MDREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MDREQ_MASK) +#define SYSCON_SYSPLLSSCTRL1_MF_MASK (0x700000U) +#define SYSCON_SYSPLLSSCTRL1_MF_SHIFT (20U) +/*! MF - Programmable modulation frequency fm = Fref/Nss with Fref = Fin/N 0b000 => Nss = 512 (fm _ + * 3.9 - 7.8 kHz) 0b001 => Nss _ 384 (fm _ 5.2 - 10.4 kHz) 0b010 => Nss = 256 (fm _ 7.8 - 15.6 + * kHz) 0b011 => Nss = 128 (fm _ 15.6 - 31.3 kHz) 0b100 => Nss = 64 (fm _ 32.3 - 64.5 kHz) 0b101 => + * Nss = 32 (fm _ 62.5- 125 kHz) 0b110 => Nss _ 24 (fm _ 83.3- 166.6 kHz) 0b111 => Nss = 16 (fm + * _ 125- 250 kHz) + */ +#define SYSCON_SYSPLLSSCTRL1_MF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MF_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MF_MASK) +#define SYSCON_SYSPLLSSCTRL1_MR_MASK (0x3800000U) +#define SYSCON_SYSPLLSSCTRL1_MR_SHIFT (23U) +/*! MR - Programmable frequency modulation depth. 0 = no spread. _fmodpk-pk = Fref x k/Fcco = + * k/MDdec 0b000 -> k = 0 (no spread spectrum) 0b001 => k _ 1 0b010 => k _ 1.5 0b011 => k _ 2 0b100 => + * k _ 3 0b101 => k _ 4 0b110 => k _ 6 0b111 => k _ 8 + */ +#define SYSCON_SYSPLLSSCTRL1_MR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MR_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MR_MASK) +#define SYSCON_SYSPLLSSCTRL1_MC_MASK (0xC000000U) +#define SYSCON_SYSPLLSSCTRL1_MC_SHIFT (26U) +/*! MC - Modulation waveform control. 0 = no compensation. Compensation for low pass filtering of + * the PLL to get a triangular modulation at the output of the PLL, giving a flat frequency + * spectrum. 0b00 => no compensation 0b10 => recommended setting 0b11 => max. compensation + */ +#define SYSCON_SYSPLLSSCTRL1_MC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MC_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MC_MASK) +#define SYSCON_SYSPLLSSCTRL1_PD_MASK (0x10000000U) +#define SYSCON_SYSPLLSSCTRL1_PD_SHIFT (28U) +/*! PD - Spread spectrum power-down. + * 0b0..Enabled. Spread spectrum controller is enabled + * 0b1..Disabled. Spread spectrum controller is disabled. + */ +#define SYSCON_SYSPLLSSCTRL1_PD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_PD_SHIFT)) & SYSCON_SYSPLLSSCTRL1_PD_MASK) +#define SYSCON_SYSPLLSSCTRL1_DITHER_MASK (0x20000000U) +#define SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT (29U) +/*! DITHER - Select modulation frequency. + * 0b0..Fixed. Fixed modulation frequency. + * 0b1..Dither. Randomly dither between two modulation frequencies. + */ +#define SYSCON_SYSPLLSSCTRL1_DITHER(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT)) & SYSCON_SYSPLLSSCTRL1_DITHER_MASK) +/*! @} */ + +/*! @name PDSLEEPCFG - Sleep configuration register n */ +/*! @{ */ +#define SYSCON_PDSLEEPCFG_PD_SLEEP_MASK (0xFFFFFFFFU) +#define SYSCON_PDSLEEPCFG_PD_SLEEP_SHIFT (0U) +/*! PD_SLEEP - See bit descriptions in the PDRUNCFGn register. + */ +#define SYSCON_PDSLEEPCFG_PD_SLEEP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDSLEEPCFG_PD_SLEEP_SHIFT)) & SYSCON_PDSLEEPCFG_PD_SLEEP_MASK) +/*! @} */ + +/* The count of SYSCON_PDSLEEPCFG */ +#define SYSCON_PDSLEEPCFG_COUNT (2U) + +/*! @name PDRUNCFG - Power configuration register n */ +/*! @{ */ +#define SYSCON_PDRUNCFG_PDEN_FRO_MASK (0x10U) +#define SYSCON_PDRUNCFG_PDEN_FRO_SHIFT (4U) +/*! PDEN_FRO - FRO oscillator. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_FRO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_FRO_SHIFT)) & SYSCON_PDRUNCFG_PDEN_FRO_MASK) +#define SYSCON_PDRUNCFG_PD_FLASH_MASK (0x20U) +#define SYSCON_PDRUNCFG_PD_FLASH_SHIFT (5U) +/*! PD_FLASH - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_PD_FLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PD_FLASH_SHIFT)) & SYSCON_PDRUNCFG_PD_FLASH_MASK) +#define SYSCON_PDRUNCFG_PDEN_TS_MASK (0x40U) +#define SYSCON_PDRUNCFG_PDEN_TS_SHIFT (6U) +/*! PDEN_TS - Temp sensor. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_TS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_TS_SHIFT)) & SYSCON_PDRUNCFG_PDEN_TS_MASK) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST_MASK (0x80U) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST_SHIFT (7U) +/*! PDEN_BOD_RST - Brown-out Detect reset. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_BOD_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_BOD_RST_SHIFT)) & SYSCON_PDRUNCFG_PDEN_BOD_RST_MASK) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR_MASK (0x100U) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR_SHIFT (8U) +/*! PDEN_BOD_INTR - Brown-out Detect interrupt. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_BOD_INTR_SHIFT)) & SYSCON_PDRUNCFG_PDEN_BOD_INTR_MASK) +#define SYSCON_PDRUNCFG_PDEN_ADC0_MASK (0x400U) +#define SYSCON_PDRUNCFG_PDEN_ADC0_SHIFT (10U) +/*! PDEN_ADC0 - ADC0. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_ADC0_SHIFT)) & SYSCON_PDRUNCFG_PDEN_ADC0_MASK) +#define SYSCON_PDRUNCFG_PD_VDDFLASH_MASK (0x800U) +#define SYSCON_PDRUNCFG_PD_VDDFLASH_SHIFT (11U) +/*! PD_VDDFLASH - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_PD_VDDFLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PD_VDDFLASH_SHIFT)) & SYSCON_PDRUNCFG_PD_VDDFLASH_MASK) +#define SYSCON_PDRUNCFG_LP_VDDFLASH_MASK (0x1000U) +#define SYSCON_PDRUNCFG_LP_VDDFLASH_SHIFT (12U) +/*! LP_VDDFLASH - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_LP_VDDFLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_LP_VDDFLASH_SHIFT)) & SYSCON_PDRUNCFG_LP_VDDFLASH_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM0_MASK (0x2000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0_SHIFT (13U) +/*! PDEN_SRAM0 - SRAM0. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_SRAM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM0_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM0_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM1_MASK (0x4000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM1_SHIFT (14U) +/*! PDEN_SRAM1 - SRAM1. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_SRAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM1_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM1_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM2_MASK (0x8000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM2_SHIFT (15U) +/*! PDEN_SRAM2 - SRAM2. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_SRAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM2_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM2_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAMX_MASK (0x10000U) +#define SYSCON_PDRUNCFG_PDEN_SRAMX_SHIFT (16U) +/*! PDEN_SRAMX - SRAMX. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_SRAMX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAMX_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAMX_MASK) +#define SYSCON_PDRUNCFG_PDEN_ROM_MASK (0x20000U) +#define SYSCON_PDRUNCFG_PDEN_ROM_SHIFT (17U) +/*! PDEN_ROM - ROM. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_ROM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_ROM_SHIFT)) & SYSCON_PDRUNCFG_PDEN_ROM_MASK) +#define SYSCON_PDRUNCFG_PD_VDDHV_ENA_MASK (0x40000U) +#define SYSCON_PDRUNCFG_PD_VDDHV_ENA_SHIFT (18U) +/*! PD_VDDHV_ENA - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_PD_VDDHV_ENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PD_VDDHV_ENA_SHIFT)) & SYSCON_PDRUNCFG_PD_VDDHV_ENA_MASK) +#define SYSCON_PDRUNCFG_PDEN_VDDA_MASK (0x80000U) +#define SYSCON_PDRUNCFG_PDEN_VDDA_SHIFT (19U) +/*! PDEN_VDDA - Vdda to the ADC, must be enabled for the ADC to work. Also see bit 23. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_VDDA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_VDDA_SHIFT)) & SYSCON_PDRUNCFG_PDEN_VDDA_MASK) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK (0x100000U) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC_SHIFT (20U) +/*! PDEN_WDT_OSC - Watchdog oscillator. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_WDT_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK) +#define SYSCON_PDRUNCFG_PDEN_USB_PHY_MASK (0x200000U) +#define SYSCON_PDRUNCFG_PDEN_USB_PHY_SHIFT (21U) +/*! PDEN_USB_PHY - USB pin interface. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_USB_PHY(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_USB_PHY_SHIFT)) & SYSCON_PDRUNCFG_PDEN_USB_PHY_MASK) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL_MASK (0x400000U) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL_SHIFT (22U) +/*! PDEN_SYS_PLL - PLL0. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SYS_PLL_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SYS_PLL_MASK) +#define SYSCON_PDRUNCFG_PDEN_VREFP_MASK (0x800000U) +#define SYSCON_PDRUNCFG_PDEN_VREFP_SHIFT (23U) +/*! PDEN_VREFP - Vrefp to the ADC, must be enabled for the ADC to work. Also see bit 19. 0 = Powered; 1 = Powered down. + */ +#define SYSCON_PDRUNCFG_PDEN_VREFP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_VREFP_SHIFT)) & SYSCON_PDRUNCFG_PDEN_VREFP_MASK) +#define SYSCON_PDRUNCFG_PD_FLASH_BG_MASK (0x2000000U) +#define SYSCON_PDRUNCFG_PD_FLASH_BG_SHIFT (25U) +/*! PD_FLASH_BG - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_PD_FLASH_BG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PD_FLASH_BG_SHIFT)) & SYSCON_PDRUNCFG_PD_FLASH_BG_MASK) +#define SYSCON_PDRUNCFG_PD_ALT_FLASH_IBG_MASK (0x10000000U) +#define SYSCON_PDRUNCFG_PD_ALT_FLASH_IBG_SHIFT (28U) +/*! PD_ALT_FLASH_IBG - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_PD_ALT_FLASH_IBG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PD_ALT_FLASH_IBG_SHIFT)) & SYSCON_PDRUNCFG_PD_ALT_FLASH_IBG_MASK) +#define SYSCON_PDRUNCFG_SEL_ALT_FLASH_IBG_MASK (0x20000000U) +#define SYSCON_PDRUNCFG_SEL_ALT_FLASH_IBG_SHIFT (29U) +/*! SEL_ALT_FLASH_IBG - Part of flash power control. + */ +#define SYSCON_PDRUNCFG_SEL_ALT_FLASH_IBG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_SEL_ALT_FLASH_IBG_SHIFT)) & SYSCON_PDRUNCFG_SEL_ALT_FLASH_IBG_MASK) +/*! @} */ + +/* The count of SYSCON_PDRUNCFG */ +#define SYSCON_PDRUNCFG_COUNT (2U) + +/*! @name PDRUNCFGSET - Set bits in PDRUNCFGn */ +/*! @{ */ +#define SYSCON_PDRUNCFGSET_PD_SET_MASK (0xFFFFFFFFU) +#define SYSCON_PDRUNCFGSET_PD_SET_SHIFT (0U) +/*! PD_SET - Writing ones to this register sets the corresponding bit or bits in the PDRUNCFG + * register, if they are implemented. Bits that do not correspond to defined bits in PDRUNCFG are + * reserved and only zeroes should be written to them. + */ +#define SYSCON_PDRUNCFGSET_PD_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFGSET_PD_SET_SHIFT)) & SYSCON_PDRUNCFGSET_PD_SET_MASK) +/*! @} */ + +/* The count of SYSCON_PDRUNCFGSET */ +#define SYSCON_PDRUNCFGSET_COUNT (2U) + +/*! @name PDRUNCFGCLR - Clear bits in PDRUNCFGn */ +/*! @{ */ +#define SYSCON_PDRUNCFGCLR_PD_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_PDRUNCFGCLR_PD_CLR_SHIFT (0U) +/*! PD_CLR - Writing ones to this register clears the corresponding bit or bits in the PDRUNCFG + * register, if they are implemented. Bits that do not correspond to defined bits in PDRUNCFG are + * reserved and only zeroes should be written to them. + */ +#define SYSCON_PDRUNCFGCLR_PD_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFGCLR_PD_CLR_SHIFT)) & SYSCON_PDRUNCFGCLR_PD_CLR_MASK) +/*! @} */ + +/* The count of SYSCON_PDRUNCFGCLR */ +#define SYSCON_PDRUNCFGCLR_COUNT (2U) + +/*! @name STARTERP - Start logic n wake-up enable register */ +/*! @{ */ +#define SYSCON_STARTERP_PINT4_MASK (0x1U) +#define SYSCON_STARTERP_PINT4_SHIFT (0U) +/*! PINT4 - GPIO pin interrupt 4 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PINT4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PINT4_SHIFT)) & SYSCON_STARTERP_PINT4_MASK) +#define SYSCON_STARTERP_WDT_BOD_MASK (0x1U) +#define SYSCON_STARTERP_WDT_BOD_SHIFT (0U) +/*! WDT_BOD - WWDT and BOD interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_WDT_BOD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_WDT_BOD_SHIFT)) & SYSCON_STARTERP_WDT_BOD_MASK) +#define SYSCON_STARTERP_DMA0_MASK (0x2U) +#define SYSCON_STARTERP_DMA0_SHIFT (1U) +/*! DMA0 - DMA0 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Typically used in sleep mode + * only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_DMA0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_DMA0_SHIFT)) & SYSCON_STARTERP_DMA0_MASK) +#define SYSCON_STARTERP_PINT5_MASK (0x2U) +#define SYSCON_STARTERP_PINT5_SHIFT (1U) +/*! PINT5 - GPIO pin interrupt 5 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PINT5(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PINT5_SHIFT)) & SYSCON_STARTERP_PINT5_MASK) +#define SYSCON_STARTERP_GINT0_MASK (0x4U) +#define SYSCON_STARTERP_GINT0_SHIFT (2U) +/*! GINT0 - Group interrupt 0 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_GINT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_GINT0_SHIFT)) & SYSCON_STARTERP_GINT0_MASK) +#define SYSCON_STARTERP_PINT6_MASK (0x4U) +#define SYSCON_STARTERP_PINT6_SHIFT (2U) +/*! PINT6 - GPIO pin interrupt 6 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PINT6(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PINT6_SHIFT)) & SYSCON_STARTERP_PINT6_MASK) +#define SYSCON_STARTERP_GINT1_MASK (0x8U) +#define SYSCON_STARTERP_GINT1_SHIFT (3U) +/*! GINT1 - Group interrupt 1 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_GINT1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_GINT1_SHIFT)) & SYSCON_STARTERP_GINT1_MASK) +#define SYSCON_STARTERP_PINT7_MASK (0x8U) +#define SYSCON_STARTERP_PINT7_SHIFT (3U) +/*! PINT7 - GPIO pin interrupt 7 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PINT7(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PINT7_SHIFT)) & SYSCON_STARTERP_PINT7_MASK) +#define SYSCON_STARTERP_CTIMER2_MASK (0x10U) +#define SYSCON_STARTERP_CTIMER2_SHIFT (4U) +/*! CTIMER2 - Standard counter/timer CTIMER2 wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_CTIMER2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_CTIMER2_SHIFT)) & SYSCON_STARTERP_CTIMER2_MASK) +#define SYSCON_STARTERP_PIN_INT0_MASK (0x10U) +#define SYSCON_STARTERP_PIN_INT0_SHIFT (4U) +/*! PIN_INT0 - GPIO pin interrupt 0 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PIN_INT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PIN_INT0_SHIFT)) & SYSCON_STARTERP_PIN_INT0_MASK) +#define SYSCON_STARTERP_CTIMER4_MASK (0x20U) +#define SYSCON_STARTERP_CTIMER4_SHIFT (5U) +/*! CTIMER4 - Standard counter/timer CTIMER4 wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_CTIMER4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_CTIMER4_SHIFT)) & SYSCON_STARTERP_CTIMER4_MASK) +#define SYSCON_STARTERP_PIN_INT1_MASK (0x20U) +#define SYSCON_STARTERP_PIN_INT1_SHIFT (5U) +/*! PIN_INT1 - GPIO pin interrupt 1 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PIN_INT1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PIN_INT1_SHIFT)) & SYSCON_STARTERP_PIN_INT1_MASK) +#define SYSCON_STARTERP_PIN_INT2_MASK (0x40U) +#define SYSCON_STARTERP_PIN_INT2_SHIFT (6U) +/*! PIN_INT2 - GPIO pin interrupt 2 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PIN_INT2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PIN_INT2_SHIFT)) & SYSCON_STARTERP_PIN_INT2_MASK) +#define SYSCON_STARTERP_PIN_INT3_MASK (0x80U) +#define SYSCON_STARTERP_PIN_INT3_SHIFT (7U) +/*! PIN_INT3 - GPIO pin interrupt 3 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Not for pattern match. + */ +#define SYSCON_STARTERP_PIN_INT3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_PIN_INT3_SHIFT)) & SYSCON_STARTERP_PIN_INT3_MASK) +#define SYSCON_STARTERP_UTICK0_MASK (0x100U) +#define SYSCON_STARTERP_UTICK0_SHIFT (8U) +/*! UTICK0 - Micro-tick Timer wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_UTICK0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_UTICK0_SHIFT)) & SYSCON_STARTERP_UTICK0_MASK) +#define SYSCON_STARTERP_MRT0_MASK (0x200U) +#define SYSCON_STARTERP_MRT0_SHIFT (9U) +/*! MRT0 - Multi-Rate Timer wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. Typically used in + * sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_MRT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_MRT0_SHIFT)) & SYSCON_STARTERP_MRT0_MASK) +#define SYSCON_STARTERP_CTIMER0_MASK (0x400U) +#define SYSCON_STARTERP_CTIMER0_SHIFT (10U) +/*! CTIMER0 - Standard counter/timer CTIMER0 wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_CTIMER0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_CTIMER0_SHIFT)) & SYSCON_STARTERP_CTIMER0_MASK) +#define SYSCON_STARTERP_CTIMER1_MASK (0x800U) +#define SYSCON_STARTERP_CTIMER1_SHIFT (11U) +/*! CTIMER1 - Standard counter/timer CTIMER1 wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_CTIMER1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_CTIMER1_SHIFT)) & SYSCON_STARTERP_CTIMER1_MASK) +#define SYSCON_STARTERP_SCT0_MASK (0x1000U) +#define SYSCON_STARTERP_SCT0_SHIFT (12U) +/*! SCT0 - SCT0 wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled.Typically used in sleep mode only + * since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_SCT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_SCT0_SHIFT)) & SYSCON_STARTERP_SCT0_MASK) +#define SYSCON_STARTERP_CTIMER3_MASK (0x2000U) +#define SYSCON_STARTERP_CTIMER3_SHIFT (13U) +/*! CTIMER3 - Standard counter/timer CTIMER3 wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_CTIMER3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_CTIMER3_SHIFT)) & SYSCON_STARTERP_CTIMER3_MASK) +#define SYSCON_STARTERP_FLEXCOMM0_MASK (0x4000U) +#define SYSCON_STARTERP_FLEXCOMM0_SHIFT (14U) +/*! FLEXCOMM0 - Flexcomm0 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM0_SHIFT)) & SYSCON_STARTERP_FLEXCOMM0_MASK) +#define SYSCON_STARTERP_FLEXCOMM1_MASK (0x8000U) +#define SYSCON_STARTERP_FLEXCOMM1_SHIFT (15U) +/*! FLEXCOMM1 - Flexcomm1 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM1_SHIFT)) & SYSCON_STARTERP_FLEXCOMM1_MASK) +#define SYSCON_STARTERP_FLEXCOMM2_MASK (0x10000U) +#define SYSCON_STARTERP_FLEXCOMM2_SHIFT (16U) +/*! FLEXCOMM2 - Flexcomm2 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM2_SHIFT)) & SYSCON_STARTERP_FLEXCOMM2_MASK) +#define SYSCON_STARTERP_FLEXCOMM3_MASK (0x20000U) +#define SYSCON_STARTERP_FLEXCOMM3_SHIFT (17U) +/*! FLEXCOMM3 - Flexcomm3 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM3_SHIFT)) & SYSCON_STARTERP_FLEXCOMM3_MASK) +#define SYSCON_STARTERP_FLEXCOMM4_MASK (0x40000U) +#define SYSCON_STARTERP_FLEXCOMM4_SHIFT (18U) +/*! FLEXCOMM4 - Flexcomm4 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM4_SHIFT)) & SYSCON_STARTERP_FLEXCOMM4_MASK) +#define SYSCON_STARTERP_FLEXCOMM5_MASK (0x80000U) +#define SYSCON_STARTERP_FLEXCOMM5_SHIFT (19U) +/*! FLEXCOMM5 - Flexcomm5 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM5(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM5_SHIFT)) & SYSCON_STARTERP_FLEXCOMM5_MASK) +#define SYSCON_STARTERP_FLEXCOMM6_MASK (0x100000U) +#define SYSCON_STARTERP_FLEXCOMM6_SHIFT (20U) +/*! FLEXCOMM6 - Flexcomm6 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM6(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM6_SHIFT)) & SYSCON_STARTERP_FLEXCOMM6_MASK) +#define SYSCON_STARTERP_FLEXCOMM7_MASK (0x200000U) +#define SYSCON_STARTERP_FLEXCOMM7_SHIFT (21U) +/*! FLEXCOMM7 - Flexcomm7 peripheral interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_FLEXCOMM7(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_FLEXCOMM7_SHIFT)) & SYSCON_STARTERP_FLEXCOMM7_MASK) +#define SYSCON_STARTERP_ADC0_SEQA_MASK (0x400000U) +#define SYSCON_STARTERP_ADC0_SEQA_SHIFT (22U) +/*! ADC0_SEQA - ADC0 sequence A interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_ADC0_SEQA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_ADC0_SEQA_SHIFT)) & SYSCON_STARTERP_ADC0_SEQA_MASK) +#define SYSCON_STARTERP_ADC0_SEQB_MASK (0x800000U) +#define SYSCON_STARTERP_ADC0_SEQB_SHIFT (23U) +/*! ADC0_SEQB - ADC0 sequence B interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to function. + */ +#define SYSCON_STARTERP_ADC0_SEQB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_ADC0_SEQB_SHIFT)) & SYSCON_STARTERP_ADC0_SEQB_MASK) +#define SYSCON_STARTERP_ADC0_THCMP_MASK (0x1000000U) +#define SYSCON_STARTERP_ADC0_THCMP_SHIFT (24U) +/*! ADC0_THCMP - ADC0 threshold and error interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up + * enabled.Typically used in sleep mode only since the peripheral clock must be running for it to + * function. + */ +#define SYSCON_STARTERP_ADC0_THCMP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_ADC0_THCMP_SHIFT)) & SYSCON_STARTERP_ADC0_THCMP_MASK) +#define SYSCON_STARTERP_DMIC0_MASK (0x2000000U) +#define SYSCON_STARTERP_DMIC0_SHIFT (25U) +/*! DMIC0 - Digital microphone interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_DMIC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_DMIC0_SHIFT)) & SYSCON_STARTERP_DMIC0_MASK) +#define SYSCON_STARTERP_USB0_NEEDCLK_MASK (0x8000000U) +#define SYSCON_STARTERP_USB0_NEEDCLK_SHIFT (27U) +/*! USB0_NEEDCLK - USB0 activity interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_USB0_NEEDCLK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_USB0_NEEDCLK_SHIFT)) & SYSCON_STARTERP_USB0_NEEDCLK_MASK) +#define SYSCON_STARTERP_USB0_MASK (0x10000000U) +#define SYSCON_STARTERP_USB0_SHIFT (28U) +/*! USB0 - USB0 function interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_USB0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_USB0_SHIFT)) & SYSCON_STARTERP_USB0_MASK) +#define SYSCON_STARTERP_RTC_MASK (0x20000000U) +#define SYSCON_STARTERP_RTC_SHIFT (29U) +/*! RTC - RTC interrupt alarm and wake-up timer. 0 = Wake-up disabled. 1 = Wake-up enabled. + */ +#define SYSCON_STARTERP_RTC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_RTC_SHIFT)) & SYSCON_STARTERP_RTC_MASK) +#define SYSCON_STARTERP_MAILBOX_MASK (0x80000000U) +#define SYSCON_STARTERP_MAILBOX_SHIFT (31U) +/*! MAILBOX - Mailbox interrupt wake-up. 0 = Wake-up disabled. 1 = Wake-up enabled.At least one CPU + * must be running in order for a mailbox interrupt to occur. Present on selected devices. + */ +#define SYSCON_STARTERP_MAILBOX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERP_MAILBOX_SHIFT)) & SYSCON_STARTERP_MAILBOX_MASK) +/*! @} */ + +/* The count of SYSCON_STARTERP */ +#define SYSCON_STARTERP_COUNT (2U) + +/*! @name STARTERSET - Set bits in STARTERn */ +/*! @{ */ +#define SYSCON_STARTERSET_START_SET_MASK (0xFFFFFFFFU) +#define SYSCON_STARTERSET_START_SET_SHIFT (0U) +/*! START_SET - Writing ones to this register sets the corresponding bit or bits in the STARTERn + * register, if they are implemented. Bits that do not correspond to defined bits in STARTERn are + * reserved and only zeroes should be written to them. + */ +#define SYSCON_STARTERSET_START_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET_START_SET_SHIFT)) & SYSCON_STARTERSET_START_SET_MASK) +/*! @} */ + +/* The count of SYSCON_STARTERSET */ +#define SYSCON_STARTERSET_COUNT (2U) + +/*! @name STARTERCLR - Clear bits in STARTERn */ +/*! @{ */ +#define SYSCON_STARTERCLR_START_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_STARTERCLR_START_CLR_SHIFT (0U) +/*! START_CLR - Writing ones to this register clears the corresponding bit or bits in the STARTERn + * register, if they are implemented. Bits that do not correspond to defined bits in STARTERn are + * reserved and only zeroes should be written to them. + */ +#define SYSCON_STARTERCLR_START_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR_START_CLR_SHIFT)) & SYSCON_STARTERCLR_START_CLR_MASK) +/*! @} */ + +/* The count of SYSCON_STARTERCLR */ +#define SYSCON_STARTERCLR_COUNT (2U) + +/*! @name HWWAKE - Configures special cases of hardware wake-up */ +/*! @{ */ +#define SYSCON_HWWAKE_FORCEWAKE_MASK (0x1U) +#define SYSCON_HWWAKE_FORCEWAKE_SHIFT (0U) +/*! FORCEWAKE - Force peripheral clocking to stay on during Deep Sleep and Power-down modes. When 1, + * clocking to peripherals is prevented from being shut down when the CPU enters Deep Sleep and + * Power-down modes. This is intended to allow a coprocessor to continue operating while the main + * CPU(s) are shut down. + */ +#define SYSCON_HWWAKE_FORCEWAKE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_HWWAKE_FORCEWAKE_SHIFT)) & SYSCON_HWWAKE_FORCEWAKE_MASK) +#define SYSCON_HWWAKE_FCWAKE_MASK (0x2U) +#define SYSCON_HWWAKE_FCWAKE_SHIFT (1U) +/*! FCWAKE - Wake for Flexcomms. When 1, any Flexcomm FIFO reaching the level specified by its own + * TXLVL will cause peripheral clocking to wake up temporarily while the related status is + * asserted. + */ +#define SYSCON_HWWAKE_FCWAKE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_HWWAKE_FCWAKE_SHIFT)) & SYSCON_HWWAKE_FCWAKE_MASK) +#define SYSCON_HWWAKE_WAKEDMIC_MASK (0x4U) +#define SYSCON_HWWAKE_WAKEDMIC_SHIFT (2U) +/*! WAKEDMIC - Wake for Digital Microphone. When 1, the digital microphone input FIFO reaching the + * level specified by TRIGLVL of either channel will cause peripheral clocking to wake up + * temporarily while the related status is asserted. + */ +#define SYSCON_HWWAKE_WAKEDMIC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_HWWAKE_WAKEDMIC_SHIFT)) & SYSCON_HWWAKE_WAKEDMIC_MASK) +#define SYSCON_HWWAKE_WAKEDMA_MASK (0x8U) +#define SYSCON_HWWAKE_WAKEDMA_SHIFT (3U) +/*! WAKEDMA - Wake for DMA. When 1, DMA being busy will cause peripheral clocking to remain running + * until DMA completes. This is generally used in conjunction with bit 1 and/or 2 in order to + * prevent peripheral clocking from being shut down as soon as the cause of wake-up is cleared, but + * before DMA has completed its related activity. + */ +#define SYSCON_HWWAKE_WAKEDMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_HWWAKE_WAKEDMA_SHIFT)) & SYSCON_HWWAKE_WAKEDMA_MASK) +/*! @} */ + +/*! @name CPUCTRL - CPU Control for multiple processors */ +/*! @{ */ +#define SYSCON_CPUCTRL_MASTERCPU_MASK (0x1U) +#define SYSCON_CPUCTRL_MASTERCPU_SHIFT (0U) +/*! MASTERCPU - Indicates which CPU is considered the master. This is factory set assign the + * Cortex-M4 as the master. The master CPU cannot have its clock turned off via the related CMnCLKEN bit + * or be reset via the related CMxRSTEN in this register. The slave CPU wakes up briefly + * following device reset, then goes back to sleep until activated by the master CPU. + * 0b0..M0+. Cortex-M0+ is the master CPU. + * 0b1..M4. Cortex-M4 is the master CPU. + */ +#define SYSCON_CPUCTRL_MASTERCPU(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_MASTERCPU_SHIFT)) & SYSCON_CPUCTRL_MASTERCPU_MASK) +#define SYSCON_CPUCTRL_CM4CLKEN_MASK (0x4U) +#define SYSCON_CPUCTRL_CM4CLKEN_SHIFT (2U) +/*! CM4CLKEN - Cortex-M4 clock enable + * 0b0..Disabled. The Cortex-M4 clock is not enabled + * 0b1..Enabled. The Cortex-M4 clock is enabled. + */ +#define SYSCON_CPUCTRL_CM4CLKEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM4CLKEN_SHIFT)) & SYSCON_CPUCTRL_CM4CLKEN_MASK) +#define SYSCON_CPUCTRL_CM0CLKEN_MASK (0x8U) +#define SYSCON_CPUCTRL_CM0CLKEN_SHIFT (3U) +/*! CM0CLKEN - Cortex-M0+ clock enable + * 0b0..Disabled. The Cortex-M0+ clock is not enabled. + * 0b1..Enabled. The Cortex-M0+ clock is enabled. + */ +#define SYSCON_CPUCTRL_CM0CLKEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM0CLKEN_SHIFT)) & SYSCON_CPUCTRL_CM0CLKEN_MASK) +#define SYSCON_CPUCTRL_CM4RSTEN_MASK (0x10U) +#define SYSCON_CPUCTRL_CM4RSTEN_SHIFT (4U) +/*! CM4RSTEN - Cortex-M4 reset. + * 0b0..Disabled. The Cortex-M4 is not being reset. + * 0b1..Enabled. The Cortex-M4 is being reset. + */ +#define SYSCON_CPUCTRL_CM4RSTEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM4RSTEN_SHIFT)) & SYSCON_CPUCTRL_CM4RSTEN_MASK) +#define SYSCON_CPUCTRL_CM0RSTEN_MASK (0x20U) +#define SYSCON_CPUCTRL_CM0RSTEN_SHIFT (5U) +/*! CM0RSTEN - Cortex-M0+ reset. + * 0b0..Disabled. The Cortex-M0+ is not being reset. + * 0b1..Enabled. The Cortex-M0+ is being reset. + */ +#define SYSCON_CPUCTRL_CM0RSTEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM0RSTEN_SHIFT)) & SYSCON_CPUCTRL_CM0RSTEN_MASK) +#define SYSCON_CPUCTRL_POWERCPU_MASK (0x40U) +#define SYSCON_CPUCTRL_POWERCPU_SHIFT (6U) +/*! POWERCPU - Identifies the owner of reduced power mode control: which CPU can cause the device to + * enter Deep Sleep, Power-down, and Deep Power-down modes. + * 0b0..M0+. Cortex-M0+ is the owner of reduced power mode control. + * 0b1..M4. Cortex-M4 is the owner of reduced power mode control. + */ +#define SYSCON_CPUCTRL_POWERCPU(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_POWERCPU_SHIFT)) & SYSCON_CPUCTRL_POWERCPU_MASK) +/*! @} */ + +/*! @name CPBOOT - Coprocessor Boot Address */ +/*! @{ */ +#define SYSCON_CPBOOT_BOOTADDR_MASK (0xFFFFFFFFU) +#define SYSCON_CPBOOT_BOOTADDR_SHIFT (0U) +/*! BOOTADDR - Slave processor boot address + */ +#define SYSCON_CPBOOT_BOOTADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPBOOT_BOOTADDR_SHIFT)) & SYSCON_CPBOOT_BOOTADDR_MASK) +/*! @} */ + +/*! @name CPSTACK - Coprocessor Stack Address */ +/*! @{ */ +#define SYSCON_CPSTACK_STACKADDR_MASK (0xFFFFFFFFU) +#define SYSCON_CPSTACK_STACKADDR_SHIFT (0U) +/*! STACKADDR - Slave processor stack address + */ +#define SYSCON_CPSTACK_STACKADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTACK_STACKADDR_SHIFT)) & SYSCON_CPSTACK_STACKADDR_MASK) +/*! @} */ + +/*! @name CPSTAT - Coprocessor Status */ +/*! @{ */ +#define SYSCON_CPSTAT_CM4SLEEPING_MASK (0x1U) +#define SYSCON_CPSTAT_CM4SLEEPING_SHIFT (0U) +/*! CM4SLEEPING - When 1, the Cortex-M4 CPU is sleeping + */ +#define SYSCON_CPSTAT_CM4SLEEPING(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM4SLEEPING_SHIFT)) & SYSCON_CPSTAT_CM4SLEEPING_MASK) +#define SYSCON_CPSTAT_CM0SLEEPING_MASK (0x2U) +#define SYSCON_CPSTAT_CM0SLEEPING_SHIFT (1U) +/*! CM0SLEEPING - When 1, the Cortex-M0+ CPU is sleeping + */ +#define SYSCON_CPSTAT_CM0SLEEPING(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM0SLEEPING_SHIFT)) & SYSCON_CPSTAT_CM0SLEEPING_MASK) +#define SYSCON_CPSTAT_CM4LOCKUP_MASK (0x4U) +#define SYSCON_CPSTAT_CM4LOCKUP_SHIFT (2U) +/*! CM4LOCKUP - When 1, the Cortex-M4 CPU is in lockup + */ +#define SYSCON_CPSTAT_CM4LOCKUP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM4LOCKUP_SHIFT)) & SYSCON_CPSTAT_CM4LOCKUP_MASK) +#define SYSCON_CPSTAT_CM0LOCKUP_MASK (0x8U) +#define SYSCON_CPSTAT_CM0LOCKUP_SHIFT (3U) +/*! CM0LOCKUP - When 1, the Cortex-M0+ CPU is in lockup. + */ +#define SYSCON_CPSTAT_CM0LOCKUP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM0LOCKUP_SHIFT)) & SYSCON_CPSTAT_CM0LOCKUP_MASK) +/*! @} */ + +/*! @name AUTOCGOR - Auto Clock-Gate Override Register */ +/*! @{ */ +#define SYSCON_AUTOCGOR_RAM0X_MASK (0x2U) +#define SYSCON_AUTOCGOR_RAM0X_SHIFT (1U) +/*! RAM0X - When 1, automatic clock gating for RAMX and RAM0 are turned off. + */ +#define SYSCON_AUTOCGOR_RAM0X(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AUTOCGOR_RAM0X_SHIFT)) & SYSCON_AUTOCGOR_RAM0X_MASK) +#define SYSCON_AUTOCGOR_RAM1_MASK (0x4U) +#define SYSCON_AUTOCGOR_RAM1_SHIFT (2U) +/*! RAM1 - When 1, automatic clock gating for RAM1 is turned off. + */ +#define SYSCON_AUTOCGOR_RAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AUTOCGOR_RAM1_SHIFT)) & SYSCON_AUTOCGOR_RAM1_MASK) +#define SYSCON_AUTOCGOR_RAM2_MASK (0x8U) +#define SYSCON_AUTOCGOR_RAM2_SHIFT (3U) +/*! RAM2 - When 1, automatic clock gating for RAM2 is turned off. + */ +#define SYSCON_AUTOCGOR_RAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AUTOCGOR_RAM2_SHIFT)) & SYSCON_AUTOCGOR_RAM2_MASK) +/*! @} */ + +/*! @name JTAGIDCODE - JTAG ID code register */ +/*! @{ */ +#define SYSCON_JTAGIDCODE_JTAGID_MASK (0xFFFFFFFFU) +#define SYSCON_JTAGIDCODE_JTAGID_SHIFT (0U) +/*! JTAGID - JTAG ID code. + */ +#define SYSCON_JTAGIDCODE_JTAGID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_JTAGIDCODE_JTAGID_SHIFT)) & SYSCON_JTAGIDCODE_JTAGID_MASK) +/*! @} */ + +/*! @name DEVICE_ID0 - Part ID register */ +/*! @{ */ +#define SYSCON_DEVICE_ID0_PARTID_MASK (0xFFFFFFFFU) +#define SYSCON_DEVICE_ID0_PARTID_SHIFT (0U) +/*! PARTID - Part ID + */ +#define SYSCON_DEVICE_ID0_PARTID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DEVICE_ID0_PARTID_SHIFT)) & SYSCON_DEVICE_ID0_PARTID_MASK) +/*! @} */ + +/*! @name DEVICE_ID1 - Boot ROM and die revision register */ +/*! @{ */ +#define SYSCON_DEVICE_ID1_REVID_MASK (0xFFFFFFFFU) +#define SYSCON_DEVICE_ID1_REVID_SHIFT (0U) +/*! REVID - Revision. + */ +#define SYSCON_DEVICE_ID1_REVID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DEVICE_ID1_REVID_SHIFT)) & SYSCON_DEVICE_ID1_REVID_MASK) +/*! @} */ + +/*! @name BODCTRL - Brown-Out Detect control */ +/*! @{ */ +#define SYSCON_BODCTRL_BODRSTLEV_MASK (0x3U) +#define SYSCON_BODCTRL_BODRSTLEV_SHIFT (0U) +/*! BODRSTLEV - BOD reset level + * 0b00..Level 0: 1.5 V + * 0b01..Level 1: 1.85 V + * 0b10..Level 2: 2.0 V + * 0b11..Level 3: 2.3 V + */ +#define SYSCON_BODCTRL_BODRSTLEV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTLEV_SHIFT)) & SYSCON_BODCTRL_BODRSTLEV_MASK) +#define SYSCON_BODCTRL_BODRSTENA_MASK (0x4U) +#define SYSCON_BODCTRL_BODRSTENA_SHIFT (2U) +/*! BODRSTENA - BOD reset enable + * 0b0..Disable reset function. + * 0b1..Enable reset function. + */ +#define SYSCON_BODCTRL_BODRSTENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTENA_SHIFT)) & SYSCON_BODCTRL_BODRSTENA_MASK) +#define SYSCON_BODCTRL_BODINTLEV_MASK (0x18U) +#define SYSCON_BODCTRL_BODINTLEV_SHIFT (3U) +/*! BODINTLEV - BOD interrupt level + * 0b00..Level 0: 2.05 V + * 0b01..Level 1: 2.45 V + * 0b10..Level 2: 2.75 V + * 0b11..Level 3: 3.05 V + */ +#define SYSCON_BODCTRL_BODINTLEV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTLEV_SHIFT)) & SYSCON_BODCTRL_BODINTLEV_MASK) +#define SYSCON_BODCTRL_BODINTENA_MASK (0x20U) +#define SYSCON_BODCTRL_BODINTENA_SHIFT (5U) +/*! BODINTENA - BOD interrupt enable + * 0b0..Disable interrupt function. + * 0b1..Enable interrupt function. + */ +#define SYSCON_BODCTRL_BODINTENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTENA_SHIFT)) & SYSCON_BODCTRL_BODINTENA_MASK) +#define SYSCON_BODCTRL_BODRSTSTAT_MASK (0x40U) +#define SYSCON_BODCTRL_BODRSTSTAT_SHIFT (6U) +/*! BODRSTSTAT - BOD reset status. When 1, a BOD reset has occurred. Cleared by writing 1 to this bit. + */ +#define SYSCON_BODCTRL_BODRSTSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTSTAT_SHIFT)) & SYSCON_BODCTRL_BODRSTSTAT_MASK) +#define SYSCON_BODCTRL_BODINTSTAT_MASK (0x80U) +#define SYSCON_BODCTRL_BODINTSTAT_SHIFT (7U) +/*! BODINTSTAT - BOD interrupt status. When 1, a BOD interrupt has occurred. Cleared by writing 1 to this bit. + */ +#define SYSCON_BODCTRL_BODINTSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTSTAT_SHIFT)) & SYSCON_BODCTRL_BODINTSTAT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SYSCON_Register_Masks */ + + +/* SYSCON - Peripheral instance base addresses */ +/** Peripheral SYSCON base address */ +#define SYSCON_BASE (0x40000000u) +/** Peripheral SYSCON base pointer */ +#define SYSCON ((SYSCON_Type *)SYSCON_BASE) +/** Array initializer of SYSCON peripheral base addresses */ +#define SYSCON_BASE_ADDRS { SYSCON_BASE } +/** Array initializer of SYSCON peripheral base pointers */ +#define SYSCON_BASE_PTRS { SYSCON } + +/*! + * @} + */ /* end of group SYSCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USART_Peripheral_Access_Layer USART Peripheral Access Layer + * @{ + */ + +/** USART - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< USART Configuration register. Basic USART configuration settings that typically are not changed during operation., offset: 0x0 */ + __IO uint32_t CTL; /**< USART Control register. USART control settings that are more likely to change during operation., offset: 0x4 */ + __IO uint32_t STAT; /**< USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them., offset: 0x8 */ + __IO uint32_t INTENSET; /**< Interrupt Enable read and Set register for USART (not FIFO) status. Contains individual interrupt enable bits for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */ + __O uint32_t INTENCLR; /**< Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared., offset: 0x10 */ + uint8_t RESERVED_0[12]; + __IO uint32_t BRG; /**< Baud Rate Generator register. 16-bit integer baud rate divisor value., offset: 0x20 */ + __I uint32_t INTSTAT; /**< Interrupt status register. Reflects interrupts that are currently enabled., offset: 0x24 */ + __IO uint32_t OSR; /**< Oversample selection register for asynchronous communication., offset: 0x28 */ + __IO uint32_t ADDR; /**< Address register for automatic address matching., offset: 0x2C */ + uint8_t RESERVED_1[3536]; + __IO uint32_t FIFOCFG; /**< FIFO configuration and enable register., offset: 0xE00 */ + __IO uint32_t FIFOSTAT; /**< FIFO status register., offset: 0xE04 */ + __IO uint32_t FIFOTRIG; /**< FIFO trigger settings for interrupt and DMA request., offset: 0xE08 */ + uint8_t RESERVED_2[4]; + __IO uint32_t FIFOINTENSET; /**< FIFO interrupt enable set (enable) and read register., offset: 0xE10 */ + __IO uint32_t FIFOINTENCLR; /**< FIFO interrupt enable clear (disable) and read register., offset: 0xE14 */ + __I uint32_t FIFOINTSTAT; /**< FIFO interrupt status register., offset: 0xE18 */ + uint8_t RESERVED_3[4]; + __IO uint32_t FIFOWR; /**< FIFO write data., offset: 0xE20 */ + uint8_t RESERVED_4[12]; + __I uint32_t FIFORD; /**< FIFO read data., offset: 0xE30 */ + uint8_t RESERVED_5[12]; + __I uint32_t FIFORDNOPOP; /**< FIFO data read with no FIFO pop., offset: 0xE40 */ +} USART_Type; + +/* ---------------------------------------------------------------------------- + -- USART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USART_Register_Masks USART Register Masks + * @{ + */ + +/*! @name CFG - USART Configuration register. Basic USART configuration settings that typically are not changed during operation. */ +/*! @{ */ +#define USART_CFG_ENABLE_MASK (0x1U) +#define USART_CFG_ENABLE_SHIFT (0U) +/*! ENABLE - USART Enable. + * 0b0..Disabled. The USART is disabled and the internal state machine and counters are reset. While Enable = 0, + * all USART interrupts and DMA transfers are disabled. When Enable is set again, CFG and most other control + * bits remain unchanged. When re-enabled, the USART will immediately be ready to transmit because the + * transmitter has been reset and is therefore available. + * 0b1..Enabled. The USART is enabled for operation. + */ +#define USART_CFG_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_ENABLE_SHIFT)) & USART_CFG_ENABLE_MASK) +#define USART_CFG_DATALEN_MASK (0xCU) +#define USART_CFG_DATALEN_SHIFT (2U) +/*! DATALEN - Selects the data size for the USART. + * 0b00..7 bit Data length. + * 0b01..8 bit Data length. + * 0b10..9 bit data length. The 9th bit is commonly used for addressing in multidrop mode. See the ADDRDET bit in the CTL register. + * 0b11..Reserved. + */ +#define USART_CFG_DATALEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_DATALEN_SHIFT)) & USART_CFG_DATALEN_MASK) +#define USART_CFG_PARITYSEL_MASK (0x30U) +#define USART_CFG_PARITYSEL_SHIFT (4U) +/*! PARITYSEL - Selects what type of parity is used by the USART. + * 0b00..No parity. + * 0b01..Reserved. + * 0b10..Even parity. Adds a bit to each character such that the number of 1s in a transmitted character is even, + * and the number of 1s in a received character is expected to be even. + * 0b11..Odd parity. Adds a bit to each character such that the number of 1s in a transmitted character is odd, + * and the number of 1s in a received character is expected to be odd. + */ +#define USART_CFG_PARITYSEL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_PARITYSEL_SHIFT)) & USART_CFG_PARITYSEL_MASK) +#define USART_CFG_STOPLEN_MASK (0x40U) +#define USART_CFG_STOPLEN_SHIFT (6U) +/*! STOPLEN - Number of stop bits appended to transmitted data. Only a single stop bit is required for received data. + * 0b0..1 stop bit. + * 0b1..2 stop bits. This setting should only be used for asynchronous communication. + */ +#define USART_CFG_STOPLEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_STOPLEN_SHIFT)) & USART_CFG_STOPLEN_MASK) +#define USART_CFG_MODE32K_MASK (0x80U) +#define USART_CFG_MODE32K_SHIFT (7U) +/*! MODE32K - Selects standard or 32 kHz clocking mode. + * 0b0..Disabled. USART uses standard clocking. + * 0b1..Enabled. USART uses the 32 kHz clock from the RTC oscillator as the clock source to the BRG, and uses a special bit clocking scheme. + */ +#define USART_CFG_MODE32K(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_MODE32K_SHIFT)) & USART_CFG_MODE32K_MASK) +#define USART_CFG_LINMODE_MASK (0x100U) +#define USART_CFG_LINMODE_SHIFT (8U) +/*! LINMODE - LIN break mode enable. + * 0b0..Disabled. Break detect and generate is configured for normal operation. + * 0b1..Enabled. Break detect and generate is configured for LIN bus operation. + */ +#define USART_CFG_LINMODE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_LINMODE_SHIFT)) & USART_CFG_LINMODE_MASK) +#define USART_CFG_CTSEN_MASK (0x200U) +#define USART_CFG_CTSEN_SHIFT (9U) +/*! CTSEN - CTS Enable. Determines whether CTS is used for flow control. CTS can be from the input + * pin, or from the USART's own RTS if loopback mode is enabled. + * 0b0..No flow control. The transmitter does not receive any automatic flow control signal. + * 0b1..Flow control enabled. The transmitter uses the CTS input (or RTS output in loopback mode) for flow control purposes. + */ +#define USART_CFG_CTSEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_CTSEN_SHIFT)) & USART_CFG_CTSEN_MASK) +#define USART_CFG_SYNCEN_MASK (0x800U) +#define USART_CFG_SYNCEN_SHIFT (11U) +/*! SYNCEN - Selects synchronous or asynchronous operation. + * 0b0..Asynchronous mode. + * 0b1..Synchronous mode. + */ +#define USART_CFG_SYNCEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCEN_SHIFT)) & USART_CFG_SYNCEN_MASK) +#define USART_CFG_CLKPOL_MASK (0x1000U) +#define USART_CFG_CLKPOL_SHIFT (12U) +/*! CLKPOL - Selects the clock polarity and sampling edge of received data in synchronous mode. + * 0b0..Falling edge. Un_RXD is sampled on the falling edge of SCLK. + * 0b1..Rising edge. Un_RXD is sampled on the rising edge of SCLK. + */ +#define USART_CFG_CLKPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_CLKPOL_SHIFT)) & USART_CFG_CLKPOL_MASK) +#define USART_CFG_SYNCMST_MASK (0x4000U) +#define USART_CFG_SYNCMST_SHIFT (14U) +/*! SYNCMST - Synchronous mode Master select. + * 0b0..Slave. When synchronous mode is enabled, the USART is a slave. + * 0b1..Master. When synchronous mode is enabled, the USART is a master. + */ +#define USART_CFG_SYNCMST(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCMST_SHIFT)) & USART_CFG_SYNCMST_MASK) +#define USART_CFG_LOOP_MASK (0x8000U) +#define USART_CFG_LOOP_SHIFT (15U) +/*! LOOP - Selects data loopback mode. + * 0b0..Normal operation. + * 0b1..Loopback mode. This provides a mechanism to perform diagnostic loopback testing for USART data. Serial + * data from the transmitter (Un_TXD) is connected internally to serial input of the receive (Un_RXD). Un_TXD + * and Un_RTS activity will also appear on external pins if these functions are configured to appear on device + * pins. The receiver RTS signal is also looped back to CTS and performs flow control if enabled by CTSEN. + */ +#define USART_CFG_LOOP(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_LOOP_SHIFT)) & USART_CFG_LOOP_MASK) +#define USART_CFG_IOMODE_MASK (0x10000U) +#define USART_CFG_IOMODE_SHIFT (16U) +/*! IOMODE - I/O output mode. + * 0b0..Standard. USART output and input operate in standard fashion. + * 0b1..IrDA. USART output and input operate in IrDA mode. + */ +#define USART_CFG_IOMODE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_IOMODE_SHIFT)) & USART_CFG_IOMODE_MASK) +#define USART_CFG_OETA_MASK (0x40000U) +#define USART_CFG_OETA_SHIFT (18U) +/*! OETA - Output Enable Turnaround time enable for RS-485 operation. + * 0b0..Disabled. If selected by OESEL, the Output Enable signal deasserted at the end of the last stop bit of a transmission. + * 0b1..Enabled. If selected by OESEL, the Output Enable signal remains asserted for one character time after the + * end of the last stop bit of a transmission. OE will also remain asserted if another transmit begins + * before it is deasserted. + */ +#define USART_CFG_OETA(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OETA_SHIFT)) & USART_CFG_OETA_MASK) +#define USART_CFG_AUTOADDR_MASK (0x80000U) +#define USART_CFG_AUTOADDR_SHIFT (19U) +/*! AUTOADDR - Automatic Address matching enable. + * 0b0..Disabled. When addressing is enabled by ADDRDET, address matching is done by software. This provides the + * possibility of versatile addressing (e.g. respond to more than one address). + * 0b1..Enabled. When addressing is enabled by ADDRDET, address matching is done by hardware, using the value in + * the ADDR register as the address to match. + */ +#define USART_CFG_AUTOADDR(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_AUTOADDR_SHIFT)) & USART_CFG_AUTOADDR_MASK) +#define USART_CFG_OESEL_MASK (0x100000U) +#define USART_CFG_OESEL_SHIFT (20U) +/*! OESEL - Output Enable Select. + * 0b0..Standard. The RTS signal is used as the standard flow control function. + * 0b1..RS-485. The RTS signal configured to provide an output enable signal to control an RS-485 transceiver. + */ +#define USART_CFG_OESEL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OESEL_SHIFT)) & USART_CFG_OESEL_MASK) +#define USART_CFG_OEPOL_MASK (0x200000U) +#define USART_CFG_OEPOL_SHIFT (21U) +/*! OEPOL - Output Enable Polarity. + * 0b0..Low. If selected by OESEL, the output enable is active low. + * 0b1..High. If selected by OESEL, the output enable is active high. + */ +#define USART_CFG_OEPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OEPOL_SHIFT)) & USART_CFG_OEPOL_MASK) +#define USART_CFG_RXPOL_MASK (0x400000U) +#define USART_CFG_RXPOL_SHIFT (22U) +/*! RXPOL - Receive data polarity. + * 0b0..Standard. The RX signal is used as it arrives from the pin. This means that the RX rest value is 1, start + * bit is 0, data is not inverted, and the stop bit is 1. + * 0b1..Inverted. The RX signal is inverted before being used by the USART. This means that the RX rest value is + * 0, start bit is 1, data is inverted, and the stop bit is 0. + */ +#define USART_CFG_RXPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_RXPOL_SHIFT)) & USART_CFG_RXPOL_MASK) +#define USART_CFG_TXPOL_MASK (0x800000U) +#define USART_CFG_TXPOL_SHIFT (23U) +/*! TXPOL - Transmit data polarity. + * 0b0..Standard. The TX signal is sent out without change. This means that the TX rest value is 1, start bit is + * 0, data is not inverted, and the stop bit is 1. + * 0b1..Inverted. The TX signal is inverted by the USART before being sent out. This means that the TX rest value + * is 0, start bit is 1, data is inverted, and the stop bit is 0. + */ +#define USART_CFG_TXPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_TXPOL_SHIFT)) & USART_CFG_TXPOL_MASK) +/*! @} */ + +/*! @name CTL - USART Control register. USART control settings that are more likely to change during operation. */ +/*! @{ */ +#define USART_CTL_TXBRKEN_MASK (0x2U) +#define USART_CTL_TXBRKEN_SHIFT (1U) +/*! TXBRKEN - Break Enable. + * 0b0..Normal operation. + * 0b1..Continuous break. Continuous break is sent immediately when this bit is set, and remains until this bit + * is cleared. A break may be sent without danger of corrupting any currently transmitting character if the + * transmitter is first disabled (TXDIS in CTL is set) and then waiting for the transmitter to be disabled + * (TXDISINT in STAT = 1) before writing 1 to TXBRKEN. + */ +#define USART_CTL_TXBRKEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXBRKEN_SHIFT)) & USART_CTL_TXBRKEN_MASK) +#define USART_CTL_ADDRDET_MASK (0x4U) +#define USART_CTL_ADDRDET_SHIFT (2U) +/*! ADDRDET - Enable address detect mode. + * 0b0..Disabled. The USART presents all incoming data. + * 0b1..Enabled. The USART receiver ignores incoming data that does not have the most significant bit of the data + * (typically the 9th bit) = 1. When the data MSB bit = 1, the receiver treats the incoming data normally, + * generating a received data interrupt. Software can then check the data to see if this is an address that + * should be handled. If it is, the ADDRDET bit is cleared by software and further incoming data is handled + * normally. + */ +#define USART_CTL_ADDRDET(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_ADDRDET_SHIFT)) & USART_CTL_ADDRDET_MASK) +#define USART_CTL_TXDIS_MASK (0x40U) +#define USART_CTL_TXDIS_SHIFT (6U) +/*! TXDIS - Transmit Disable. + * 0b0..Not disabled. USART transmitter is not disabled. + * 0b1..Disabled. USART transmitter is disabled after any character currently being transmitted is complete. This + * feature can be used to facilitate software flow control. + */ +#define USART_CTL_TXDIS(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXDIS_SHIFT)) & USART_CTL_TXDIS_MASK) +#define USART_CTL_CC_MASK (0x100U) +#define USART_CTL_CC_SHIFT (8U) +/*! CC - Continuous Clock generation. By default, SCLK is only output while data is being transmitted in synchronous mode. + * 0b0..Clock on character. In synchronous mode, SCLK cycles only when characters are being sent on Un_TXD or to + * complete a character that is being received. + * 0b1..Continuous clock. SCLK runs continuously in synchronous mode, allowing characters to be received on + * Un_RxD independently from transmission on Un_TXD). + */ +#define USART_CTL_CC(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_CC_SHIFT)) & USART_CTL_CC_MASK) +#define USART_CTL_CLRCCONRX_MASK (0x200U) +#define USART_CTL_CLRCCONRX_SHIFT (9U) +/*! CLRCCONRX - Clear Continuous Clock. + * 0b0..No effect. No effect on the CC bit. + * 0b1..Auto-clear. The CC bit is automatically cleared when a complete character has been received. This bit is cleared at the same time. + */ +#define USART_CTL_CLRCCONRX(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_CLRCCONRX_SHIFT)) & USART_CTL_CLRCCONRX_MASK) +#define USART_CTL_AUTOBAUD_MASK (0x10000U) +#define USART_CTL_AUTOBAUD_SHIFT (16U) +/*! AUTOBAUD - Autobaud enable. + * 0b0..Disabled. USART is in normal operating mode. + * 0b1..Enabled. USART is in autobaud mode. This bit should only be set when the USART receiver is idle. The + * first start bit of RX is measured and used the update the BRG register to match the received data rate. + * AUTOBAUD is cleared once this process is complete, or if there is an AERR. + */ +#define USART_CTL_AUTOBAUD(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_AUTOBAUD_SHIFT)) & USART_CTL_AUTOBAUD_MASK) +/*! @} */ + +/*! @name STAT - USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them. */ +/*! @{ */ +#define USART_STAT_RXIDLE_MASK (0x2U) +#define USART_STAT_RXIDLE_SHIFT (1U) +/*! RXIDLE - Receiver Idle. When 0, indicates that the receiver is currently in the process of + * receiving data. When 1, indicates that the receiver is not currently in the process of receiving + * data. + */ +#define USART_STAT_RXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXIDLE_SHIFT)) & USART_STAT_RXIDLE_MASK) +#define USART_STAT_TXIDLE_MASK (0x8U) +#define USART_STAT_TXIDLE_SHIFT (3U) +/*! TXIDLE - Transmitter Idle. When 0, indicates that the transmitter is currently in the process of + * sending data.When 1, indicate that the transmitter is not currently in the process of sending + * data. + */ +#define USART_STAT_TXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXIDLE_SHIFT)) & USART_STAT_TXIDLE_MASK) +#define USART_STAT_CTS_MASK (0x10U) +#define USART_STAT_CTS_SHIFT (4U) +/*! CTS - This bit reflects the current state of the CTS signal, regardless of the setting of the + * CTSEN bit in the CFG register. This will be the value of the CTS input pin unless loopback mode + * is enabled. + */ +#define USART_STAT_CTS(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_CTS_SHIFT)) & USART_STAT_CTS_MASK) +#define USART_STAT_DELTACTS_MASK (0x20U) +#define USART_STAT_DELTACTS_SHIFT (5U) +/*! DELTACTS - This bit is set when a change in the state is detected for the CTS flag above. This bit is cleared by software. + */ +#define USART_STAT_DELTACTS(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTACTS_SHIFT)) & USART_STAT_DELTACTS_MASK) +#define USART_STAT_TXDISSTAT_MASK (0x40U) +#define USART_STAT_TXDISSTAT_SHIFT (6U) +/*! TXDISSTAT - Transmitter Disabled Status flag. When 1, this bit indicates that the USART + * transmitter is fully idle after being disabled via the TXDIS bit in the CFG register (TXDIS = 1). + */ +#define USART_STAT_TXDISSTAT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXDISSTAT_SHIFT)) & USART_STAT_TXDISSTAT_MASK) +#define USART_STAT_RXBRK_MASK (0x400U) +#define USART_STAT_RXBRK_SHIFT (10U) +/*! RXBRK - Received Break. This bit reflects the current state of the receiver break detection + * logic. It is set when the Un_RXD pin remains low for 16 bit times. Note that FRAMERRINT will also + * be set when this condition occurs because the stop bit(s) for the character would be missing. + * RXBRK is cleared when the Un_RXD pin goes high. + */ +#define USART_STAT_RXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXBRK_SHIFT)) & USART_STAT_RXBRK_MASK) +#define USART_STAT_DELTARXBRK_MASK (0x800U) +#define USART_STAT_DELTARXBRK_SHIFT (11U) +/*! DELTARXBRK - This bit is set when a change in the state of receiver break detection occurs. Cleared by software. + */ +#define USART_STAT_DELTARXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTARXBRK_SHIFT)) & USART_STAT_DELTARXBRK_MASK) +#define USART_STAT_START_MASK (0x1000U) +#define USART_STAT_START_SHIFT (12U) +/*! START - This bit is set when a start is detected on the receiver input. Its purpose is primarily + * to allow wake-up from Deep-sleep or Power-down mode immediately when a start is detected. + * Cleared by software. + */ +#define USART_STAT_START(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_START_SHIFT)) & USART_STAT_START_MASK) +#define USART_STAT_FRAMERRINT_MASK (0x2000U) +#define USART_STAT_FRAMERRINT_SHIFT (13U) +/*! FRAMERRINT - Framing Error interrupt flag. This flag is set when a character is received with a + * missing stop bit at the expected location. This could be an indication of a baud rate or + * configuration mismatch with the transmitting source. + */ +#define USART_STAT_FRAMERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_FRAMERRINT_SHIFT)) & USART_STAT_FRAMERRINT_MASK) +#define USART_STAT_PARITYERRINT_MASK (0x4000U) +#define USART_STAT_PARITYERRINT_SHIFT (14U) +/*! PARITYERRINT - Parity Error interrupt flag. This flag is set when a parity error is detected in a received character. + */ +#define USART_STAT_PARITYERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_PARITYERRINT_SHIFT)) & USART_STAT_PARITYERRINT_MASK) +#define USART_STAT_RXNOISEINT_MASK (0x8000U) +#define USART_STAT_RXNOISEINT_SHIFT (15U) +/*! RXNOISEINT - Received Noise interrupt flag. Three samples of received data are taken in order to + * determine the value of each received data bit, except in synchronous mode. This acts as a + * noise filter if one sample disagrees. This flag is set when a received data bit contains one + * disagreeing sample. This could indicate line noise, a baud rate or character format mismatch, or + * loss of synchronization during data reception. + */ +#define USART_STAT_RXNOISEINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXNOISEINT_SHIFT)) & USART_STAT_RXNOISEINT_MASK) +#define USART_STAT_ABERR_MASK (0x10000U) +#define USART_STAT_ABERR_SHIFT (16U) +/*! ABERR - Auto baud Error. An auto baud error can occur if the BRG counts to its limit before the + * end of the start bit that is being measured, essentially an auto baud time-out. + */ +#define USART_STAT_ABERR(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_ABERR_SHIFT)) & USART_STAT_ABERR_MASK) +/*! @} */ + +/*! @name INTENSET - Interrupt Enable read and Set register for USART (not FIFO) status. Contains individual interrupt enable bits for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +/*! @{ */ +#define USART_INTENSET_TXIDLEEN_MASK (0x8U) +#define USART_INTENSET_TXIDLEEN_SHIFT (3U) +/*! TXIDLEEN - When 1, enables an interrupt when the transmitter becomes idle (TXIDLE = 1). + */ +#define USART_INTENSET_TXIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXIDLEEN_SHIFT)) & USART_INTENSET_TXIDLEEN_MASK) +#define USART_INTENSET_DELTACTSEN_MASK (0x20U) +#define USART_INTENSET_DELTACTSEN_SHIFT (5U) +/*! DELTACTSEN - When 1, enables an interrupt when there is a change in the state of the CTS input. + */ +#define USART_INTENSET_DELTACTSEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTACTSEN_SHIFT)) & USART_INTENSET_DELTACTSEN_MASK) +#define USART_INTENSET_TXDISEN_MASK (0x40U) +#define USART_INTENSET_TXDISEN_SHIFT (6U) +/*! TXDISEN - When 1, enables an interrupt when the transmitter is fully disabled as indicated by + * the TXDISINT flag in STAT. See description of the TXDISINT bit for details. + */ +#define USART_INTENSET_TXDISEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXDISEN_SHIFT)) & USART_INTENSET_TXDISEN_MASK) +#define USART_INTENSET_DELTARXBRKEN_MASK (0x800U) +#define USART_INTENSET_DELTARXBRKEN_SHIFT (11U) +/*! DELTARXBRKEN - When 1, enables an interrupt when a change of state has occurred in the detection + * of a received break condition (break condition asserted or deasserted). + */ +#define USART_INTENSET_DELTARXBRKEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTARXBRKEN_SHIFT)) & USART_INTENSET_DELTARXBRKEN_MASK) +#define USART_INTENSET_STARTEN_MASK (0x1000U) +#define USART_INTENSET_STARTEN_SHIFT (12U) +/*! STARTEN - When 1, enables an interrupt when a received start bit has been detected. + */ +#define USART_INTENSET_STARTEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_STARTEN_SHIFT)) & USART_INTENSET_STARTEN_MASK) +#define USART_INTENSET_FRAMERREN_MASK (0x2000U) +#define USART_INTENSET_FRAMERREN_SHIFT (13U) +/*! FRAMERREN - When 1, enables an interrupt when a framing error has been detected. + */ +#define USART_INTENSET_FRAMERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_FRAMERREN_SHIFT)) & USART_INTENSET_FRAMERREN_MASK) +#define USART_INTENSET_PARITYERREN_MASK (0x4000U) +#define USART_INTENSET_PARITYERREN_SHIFT (14U) +/*! PARITYERREN - When 1, enables an interrupt when a parity error has been detected. + */ +#define USART_INTENSET_PARITYERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_PARITYERREN_SHIFT)) & USART_INTENSET_PARITYERREN_MASK) +#define USART_INTENSET_RXNOISEEN_MASK (0x8000U) +#define USART_INTENSET_RXNOISEEN_SHIFT (15U) +/*! RXNOISEEN - When 1, enables an interrupt when noise is detected. See description of the RXNOISEINT bit in Table 354. + */ +#define USART_INTENSET_RXNOISEEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXNOISEEN_SHIFT)) & USART_INTENSET_RXNOISEEN_MASK) +#define USART_INTENSET_ABERREN_MASK (0x10000U) +#define USART_INTENSET_ABERREN_SHIFT (16U) +/*! ABERREN - When 1, enables an interrupt when an auto baud error occurs. + */ +#define USART_INTENSET_ABERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_ABERREN_SHIFT)) & USART_INTENSET_ABERREN_MASK) +/*! @} */ + +/*! @name INTENCLR - Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared. */ +/*! @{ */ +#define USART_INTENCLR_TXIDLECLR_MASK (0x8U) +#define USART_INTENCLR_TXIDLECLR_SHIFT (3U) +/*! TXIDLECLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_TXIDLECLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXIDLECLR_SHIFT)) & USART_INTENCLR_TXIDLECLR_MASK) +#define USART_INTENCLR_DELTACTSCLR_MASK (0x20U) +#define USART_INTENCLR_DELTACTSCLR_SHIFT (5U) +/*! DELTACTSCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_DELTACTSCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTACTSCLR_SHIFT)) & USART_INTENCLR_DELTACTSCLR_MASK) +#define USART_INTENCLR_TXDISCLR_MASK (0x40U) +#define USART_INTENCLR_TXDISCLR_SHIFT (6U) +/*! TXDISCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_TXDISCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXDISCLR_SHIFT)) & USART_INTENCLR_TXDISCLR_MASK) +#define USART_INTENCLR_DELTARXBRKCLR_MASK (0x800U) +#define USART_INTENCLR_DELTARXBRKCLR_SHIFT (11U) +/*! DELTARXBRKCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_DELTARXBRKCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTARXBRKCLR_SHIFT)) & USART_INTENCLR_DELTARXBRKCLR_MASK) +#define USART_INTENCLR_STARTCLR_MASK (0x1000U) +#define USART_INTENCLR_STARTCLR_SHIFT (12U) +/*! STARTCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_STARTCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_STARTCLR_SHIFT)) & USART_INTENCLR_STARTCLR_MASK) +#define USART_INTENCLR_FRAMERRCLR_MASK (0x2000U) +#define USART_INTENCLR_FRAMERRCLR_SHIFT (13U) +/*! FRAMERRCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_FRAMERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_FRAMERRCLR_SHIFT)) & USART_INTENCLR_FRAMERRCLR_MASK) +#define USART_INTENCLR_PARITYERRCLR_MASK (0x4000U) +#define USART_INTENCLR_PARITYERRCLR_SHIFT (14U) +/*! PARITYERRCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_PARITYERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_PARITYERRCLR_SHIFT)) & USART_INTENCLR_PARITYERRCLR_MASK) +#define USART_INTENCLR_RXNOISECLR_MASK (0x8000U) +#define USART_INTENCLR_RXNOISECLR_SHIFT (15U) +/*! RXNOISECLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_RXNOISECLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXNOISECLR_SHIFT)) & USART_INTENCLR_RXNOISECLR_MASK) +#define USART_INTENCLR_ABERRCLR_MASK (0x10000U) +#define USART_INTENCLR_ABERRCLR_SHIFT (16U) +/*! ABERRCLR - Writing 1 clears the corresponding bit in the INTENSET register. + */ +#define USART_INTENCLR_ABERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_ABERRCLR_SHIFT)) & USART_INTENCLR_ABERRCLR_MASK) +/*! @} */ + +/*! @name BRG - Baud Rate Generator register. 16-bit integer baud rate divisor value. */ +/*! @{ */ +#define USART_BRG_BRGVAL_MASK (0xFFFFU) +#define USART_BRG_BRGVAL_SHIFT (0U) +/*! BRGVAL - This value is used to divide the USART input clock to determine the baud rate, based on + * the input clock from the FRG. 0 = FCLK is used directly by the USART function. 1 = FCLK is + * divided by 2 before use by the USART function. 2 = FCLK is divided by 3 before use by the USART + * function. 0xFFFF = FCLK is divided by 65,536 before use by the USART function. + */ +#define USART_BRG_BRGVAL(x) (((uint32_t)(((uint32_t)(x)) << USART_BRG_BRGVAL_SHIFT)) & USART_BRG_BRGVAL_MASK) +/*! @} */ + +/*! @name INTSTAT - Interrupt status register. Reflects interrupts that are currently enabled. */ +/*! @{ */ +#define USART_INTSTAT_TXIDLE_MASK (0x8U) +#define USART_INTSTAT_TXIDLE_SHIFT (3U) +/*! TXIDLE - Transmitter Idle status. + */ +#define USART_INTSTAT_TXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXIDLE_SHIFT)) & USART_INTSTAT_TXIDLE_MASK) +#define USART_INTSTAT_DELTACTS_MASK (0x20U) +#define USART_INTSTAT_DELTACTS_SHIFT (5U) +/*! DELTACTS - This bit is set when a change in the state of the CTS input is detected. + */ +#define USART_INTSTAT_DELTACTS(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTACTS_SHIFT)) & USART_INTSTAT_DELTACTS_MASK) +#define USART_INTSTAT_TXDISINT_MASK (0x40U) +#define USART_INTSTAT_TXDISINT_SHIFT (6U) +/*! TXDISINT - Transmitter Disabled Interrupt flag. + */ +#define USART_INTSTAT_TXDISINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXDISINT_SHIFT)) & USART_INTSTAT_TXDISINT_MASK) +#define USART_INTSTAT_DELTARXBRK_MASK (0x800U) +#define USART_INTSTAT_DELTARXBRK_SHIFT (11U) +/*! DELTARXBRK - This bit is set when a change in the state of receiver break detection occurs. + */ +#define USART_INTSTAT_DELTARXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTARXBRK_SHIFT)) & USART_INTSTAT_DELTARXBRK_MASK) +#define USART_INTSTAT_START_MASK (0x1000U) +#define USART_INTSTAT_START_SHIFT (12U) +/*! START - This bit is set when a start is detected on the receiver input. + */ +#define USART_INTSTAT_START(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_START_SHIFT)) & USART_INTSTAT_START_MASK) +#define USART_INTSTAT_FRAMERRINT_MASK (0x2000U) +#define USART_INTSTAT_FRAMERRINT_SHIFT (13U) +/*! FRAMERRINT - Framing Error interrupt flag. + */ +#define USART_INTSTAT_FRAMERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_FRAMERRINT_SHIFT)) & USART_INTSTAT_FRAMERRINT_MASK) +#define USART_INTSTAT_PARITYERRINT_MASK (0x4000U) +#define USART_INTSTAT_PARITYERRINT_SHIFT (14U) +/*! PARITYERRINT - Parity Error interrupt flag. + */ +#define USART_INTSTAT_PARITYERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_PARITYERRINT_SHIFT)) & USART_INTSTAT_PARITYERRINT_MASK) +#define USART_INTSTAT_RXNOISEINT_MASK (0x8000U) +#define USART_INTSTAT_RXNOISEINT_SHIFT (15U) +/*! RXNOISEINT - Received Noise interrupt flag. + */ +#define USART_INTSTAT_RXNOISEINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXNOISEINT_SHIFT)) & USART_INTSTAT_RXNOISEINT_MASK) +#define USART_INTSTAT_ABERRINT_MASK (0x10000U) +#define USART_INTSTAT_ABERRINT_SHIFT (16U) +/*! ABERRINT - Auto baud Error Interrupt flag. + */ +#define USART_INTSTAT_ABERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_ABERRINT_SHIFT)) & USART_INTSTAT_ABERRINT_MASK) +/*! @} */ + +/*! @name OSR - Oversample selection register for asynchronous communication. */ +/*! @{ */ +#define USART_OSR_OSRVAL_MASK (0xFU) +#define USART_OSR_OSRVAL_SHIFT (0U) +/*! OSRVAL - Oversample Selection Value. 0 to 3 = not supported 0x4 = 5 function clocks are used to + * transmit and receive each data bit. 0x5 = 6 function clocks are used to transmit and receive + * each data bit. 0xF= 16 function clocks are used to transmit and receive each data bit. + */ +#define USART_OSR_OSRVAL(x) (((uint32_t)(((uint32_t)(x)) << USART_OSR_OSRVAL_SHIFT)) & USART_OSR_OSRVAL_MASK) +/*! @} */ + +/*! @name ADDR - Address register for automatic address matching. */ +/*! @{ */ +#define USART_ADDR_ADDRESS_MASK (0xFFU) +#define USART_ADDR_ADDRESS_SHIFT (0U) +/*! ADDRESS - 8-bit address used with automatic address matching. Used when address detection is + * enabled (ADDRDET in CTL = 1) and automatic address matching is enabled (AUTOADDR in CFG = 1). + */ +#define USART_ADDR_ADDRESS(x) (((uint32_t)(((uint32_t)(x)) << USART_ADDR_ADDRESS_SHIFT)) & USART_ADDR_ADDRESS_MASK) +/*! @} */ + +/*! @name FIFOCFG - FIFO configuration and enable register. */ +/*! @{ */ +#define USART_FIFOCFG_ENABLETX_MASK (0x1U) +#define USART_FIFOCFG_ENABLETX_SHIFT (0U) +/*! ENABLETX - Enable the transmit FIFO. + * 0b0..The transmit FIFO is not enabled. + * 0b1..The transmit FIFO is enabled. + */ +#define USART_FIFOCFG_ENABLETX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_ENABLETX_SHIFT)) & USART_FIFOCFG_ENABLETX_MASK) +#define USART_FIFOCFG_ENABLERX_MASK (0x2U) +#define USART_FIFOCFG_ENABLERX_SHIFT (1U) +/*! ENABLERX - Enable the receive FIFO. + * 0b0..The receive FIFO is not enabled. + * 0b1..The receive FIFO is enabled. + */ +#define USART_FIFOCFG_ENABLERX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_ENABLERX_SHIFT)) & USART_FIFOCFG_ENABLERX_MASK) +#define USART_FIFOCFG_SIZE_MASK (0x30U) +#define USART_FIFOCFG_SIZE_SHIFT (4U) +/*! SIZE - FIFO size configuration. This is a read-only field. 0x0 = FIFO is configured as 16 + * entries of 8 bits. 0x1, 0x2, 0x3 = not applicable to USART. + */ +#define USART_FIFOCFG_SIZE(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_SIZE_SHIFT)) & USART_FIFOCFG_SIZE_MASK) +#define USART_FIFOCFG_DMATX_MASK (0x1000U) +#define USART_FIFOCFG_DMATX_SHIFT (12U) +/*! DMATX - DMA configuration for transmit. + * 0b0..DMA is not used for the transmit function. + * 0b1..Trigger DMA for the transmit function if the FIFO is not full. Generally, data interrupts would be disabled if DMA is enabled. + */ +#define USART_FIFOCFG_DMATX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_DMATX_SHIFT)) & USART_FIFOCFG_DMATX_MASK) +#define USART_FIFOCFG_DMARX_MASK (0x2000U) +#define USART_FIFOCFG_DMARX_SHIFT (13U) +/*! DMARX - DMA configuration for receive. + * 0b0..DMA is not used for the receive function. + * 0b1..Trigger DMA for the receive function if the FIFO is not empty. Generally, data interrupts would be disabled if DMA is enabled. + */ +#define USART_FIFOCFG_DMARX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_DMARX_SHIFT)) & USART_FIFOCFG_DMARX_MASK) +#define USART_FIFOCFG_WAKETX_MASK (0x4000U) +#define USART_FIFOCFG_WAKETX_SHIFT (14U) +/*! WAKETX - Wake-up for transmit FIFO level. This allows the device to be woken from reduced power + * modes (up to power-down, as long as the peripheral function works in that power mode) without + * enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The + * CPU will remain stopped until woken by another cause, such as DMA completion. See Hardware + * Wake-up control register. + * 0b0..Only enabled interrupts will wake up the device form reduced power modes. + * 0b1..A device wake-up for DMA will occur if the transmit FIFO level reaches the value specified by TXLVL in + * FIFOTRIG, even when the TXLVL interrupt is not enabled. + */ +#define USART_FIFOCFG_WAKETX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_WAKETX_SHIFT)) & USART_FIFOCFG_WAKETX_MASK) +#define USART_FIFOCFG_WAKERX_MASK (0x8000U) +#define USART_FIFOCFG_WAKERX_SHIFT (15U) +/*! WAKERX - Wake-up for receive FIFO level. This allows the device to be woken from reduced power + * modes (up to power-down, as long as the peripheral function works in that power mode) without + * enabling the TXLVL interrupt. Only DMA wakes up, processes data, and goes back to sleep. The + * CPU will remain stopped until woken by another cause, such as DMA completion. See Hardware + * Wake-up control register. + * 0b0..Only enabled interrupts will wake up the device form reduced power modes. + * 0b1..A device wake-up for DMA will occur if the receive FIFO level reaches the value specified by RXLVL in + * FIFOTRIG, even when the RXLVL interrupt is not enabled. + */ +#define USART_FIFOCFG_WAKERX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_WAKERX_SHIFT)) & USART_FIFOCFG_WAKERX_MASK) +#define USART_FIFOCFG_EMPTYTX_MASK (0x10000U) +#define USART_FIFOCFG_EMPTYTX_SHIFT (16U) +/*! EMPTYTX - Empty command for the transmit FIFO. When a 1 is written to this bit, the TX FIFO is emptied. + */ +#define USART_FIFOCFG_EMPTYTX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_EMPTYTX_SHIFT)) & USART_FIFOCFG_EMPTYTX_MASK) +#define USART_FIFOCFG_EMPTYRX_MASK (0x20000U) +#define USART_FIFOCFG_EMPTYRX_SHIFT (17U) +/*! EMPTYRX - Empty command for the receive FIFO. When a 1 is written to this bit, the RX FIFO is emptied. + */ +#define USART_FIFOCFG_EMPTYRX(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOCFG_EMPTYRX_SHIFT)) & USART_FIFOCFG_EMPTYRX_MASK) +/*! @} */ + +/*! @name FIFOSTAT - FIFO status register. */ +/*! @{ */ +#define USART_FIFOSTAT_TXERR_MASK (0x1U) +#define USART_FIFOSTAT_TXERR_SHIFT (0U) +/*! TXERR - TX FIFO error. Will be set if a transmit FIFO error occurs. This could be an overflow + * caused by pushing data into a full FIFO, or by an underflow if the FIFO is empty when data is + * needed. Cleared by writing a 1 to this bit. + */ +#define USART_FIFOSTAT_TXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXERR_SHIFT)) & USART_FIFOSTAT_TXERR_MASK) +#define USART_FIFOSTAT_RXERR_MASK (0x2U) +#define USART_FIFOSTAT_RXERR_SHIFT (1U) +/*! RXERR - RX FIFO error. Will be set if a receive FIFO overflow occurs, caused by software or DMA + * not emptying the FIFO fast enough. Cleared by writing a 1 to this bit. + */ +#define USART_FIFOSTAT_RXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXERR_SHIFT)) & USART_FIFOSTAT_RXERR_MASK) +#define USART_FIFOSTAT_PERINT_MASK (0x8U) +#define USART_FIFOSTAT_PERINT_SHIFT (3U) +/*! PERINT - Peripheral interrupt. When 1, this indicates that the peripheral function has asserted + * an interrupt. The details can be found by reading the peripheral's STAT register. + */ +#define USART_FIFOSTAT_PERINT(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_PERINT_SHIFT)) & USART_FIFOSTAT_PERINT_MASK) +#define USART_FIFOSTAT_TXEMPTY_MASK (0x10U) +#define USART_FIFOSTAT_TXEMPTY_SHIFT (4U) +/*! TXEMPTY - Transmit FIFO empty. When 1, the transmit FIFO is empty. The peripheral may still be processing the last piece of data. + */ +#define USART_FIFOSTAT_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXEMPTY_SHIFT)) & USART_FIFOSTAT_TXEMPTY_MASK) +#define USART_FIFOSTAT_TXNOTFULL_MASK (0x20U) +#define USART_FIFOSTAT_TXNOTFULL_SHIFT (5U) +/*! TXNOTFULL - Transmit FIFO not full. When 1, the transmit FIFO is not full, so more data can be + * written. When 0, the transmit FIFO is full and another write would cause it to overflow. + */ +#define USART_FIFOSTAT_TXNOTFULL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXNOTFULL_SHIFT)) & USART_FIFOSTAT_TXNOTFULL_MASK) +#define USART_FIFOSTAT_RXNOTEMPTY_MASK (0x40U) +#define USART_FIFOSTAT_RXNOTEMPTY_SHIFT (6U) +/*! RXNOTEMPTY - Receive FIFO not empty. When 1, the receive FIFO is not empty, so data can be read. When 0, the receive FIFO is empty. + */ +#define USART_FIFOSTAT_RXNOTEMPTY(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXNOTEMPTY_SHIFT)) & USART_FIFOSTAT_RXNOTEMPTY_MASK) +#define USART_FIFOSTAT_RXFULL_MASK (0x80U) +#define USART_FIFOSTAT_RXFULL_SHIFT (7U) +/*! RXFULL - Receive FIFO full. When 1, the receive FIFO is full. Data needs to be read out to + * prevent the peripheral from causing an overflow. + */ +#define USART_FIFOSTAT_RXFULL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXFULL_SHIFT)) & USART_FIFOSTAT_RXFULL_MASK) +#define USART_FIFOSTAT_TXLVL_MASK (0x1F00U) +#define USART_FIFOSTAT_TXLVL_SHIFT (8U) +/*! TXLVL - Transmit FIFO current level. A 0 means the TX FIFO is currently empty, and the TXEMPTY + * and TXNOTFULL flags will be 1. Other values tell how much data is actually in the TX FIFO at + * the point where the read occurs. If the TX FIFO is full, the TXEMPTY and TXNOTFULL flags will be + * 0. + */ +#define USART_FIFOSTAT_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_TXLVL_SHIFT)) & USART_FIFOSTAT_TXLVL_MASK) +#define USART_FIFOSTAT_RXLVL_MASK (0x1F0000U) +#define USART_FIFOSTAT_RXLVL_SHIFT (16U) +/*! RXLVL - Receive FIFO current level. A 0 means the RX FIFO is currently empty, and the RXFULL and + * RXNOTEMPTY flags will be 0. Other values tell how much data is actually in the RX FIFO at the + * point where the read occurs. If the RX FIFO is full, the RXFULL and RXNOTEMPTY flags will be + * 1. + */ +#define USART_FIFOSTAT_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOSTAT_RXLVL_SHIFT)) & USART_FIFOSTAT_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOTRIG - FIFO trigger settings for interrupt and DMA request. */ +/*! @{ */ +#define USART_FIFOTRIG_TXLVLENA_MASK (0x1U) +#define USART_FIFOTRIG_TXLVLENA_SHIFT (0U) +/*! TXLVLENA - Transmit FIFO level trigger enable. This trigger will become an interrupt if enabled + * in FIFOINTENSET, or a DMA trigger if DMATX in FIFOCFG is set. + * 0b0..Transmit FIFO level does not generate a FIFO level trigger. + * 0b1..An trigger will be generated if the transmit FIFO level reaches the value specified by the TXLVL field in this register. + */ +#define USART_FIFOTRIG_TXLVLENA(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_TXLVLENA_SHIFT)) & USART_FIFOTRIG_TXLVLENA_MASK) +#define USART_FIFOTRIG_RXLVLENA_MASK (0x2U) +#define USART_FIFOTRIG_RXLVLENA_SHIFT (1U) +/*! RXLVLENA - Receive FIFO level trigger enable. This trigger will become an interrupt if enabled + * in FIFOINTENSET, or a DMA trigger if DMARX in FIFOCFG is set. + * 0b0..Receive FIFO level does not generate a FIFO level trigger. + * 0b1..An trigger will be generated if the receive FIFO level reaches the value specified by the RXLVL field in this register. + */ +#define USART_FIFOTRIG_RXLVLENA(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_RXLVLENA_SHIFT)) & USART_FIFOTRIG_RXLVLENA_MASK) +#define USART_FIFOTRIG_TXLVL_MASK (0xF00U) +#define USART_FIFOTRIG_TXLVL_SHIFT (8U) +/*! TXLVL - Transmit FIFO level trigger point. This field is used only when TXLVLENA = 1. If enabled + * to do so, the FIFO level can wake up the device just enough to perform DMA, then return to + * the reduced power mode. See Hardware Wake-up control register. 0 = trigger when the TX FIFO + * becomes empty. 1 = trigger when the TX FIFO level decreases to one entry. 15 = trigger when the TX + * FIFO level decreases to 15 entries (is no longer full). + */ +#define USART_FIFOTRIG_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_TXLVL_SHIFT)) & USART_FIFOTRIG_TXLVL_MASK) +#define USART_FIFOTRIG_RXLVL_MASK (0xF0000U) +#define USART_FIFOTRIG_RXLVL_SHIFT (16U) +/*! RXLVL - Receive FIFO level trigger point. The RX FIFO level is checked when a new piece of data + * is received. This field is used only when RXLVLENA = 1. If enabled to do so, the FIFO level + * can wake up the device just enough to perform DMA, then return to the reduced power mode. See + * Hardware Wake-up control register. 0 = trigger when the RX FIFO has received one entry (is no + * longer empty). 1 = trigger when the RX FIFO has received two entries. 15 = trigger when the RX + * FIFO has received 16 entries (has become full). + */ +#define USART_FIFOTRIG_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOTRIG_RXLVL_SHIFT)) & USART_FIFOTRIG_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTENSET - FIFO interrupt enable set (enable) and read register. */ +/*! @{ */ +#define USART_FIFOINTENSET_TXERR_MASK (0x1U) +#define USART_FIFOINTENSET_TXERR_SHIFT (0U) +/*! TXERR - Determines whether an interrupt occurs when a transmit error occurs, based on the TXERR flag in the FIFOSTAT register. + * 0b0..No interrupt will be generated for a transmit error. + * 0b1..An interrupt will be generated when a transmit error occurs. + */ +#define USART_FIFOINTENSET_TXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_TXERR_SHIFT)) & USART_FIFOINTENSET_TXERR_MASK) +#define USART_FIFOINTENSET_RXERR_MASK (0x2U) +#define USART_FIFOINTENSET_RXERR_SHIFT (1U) +/*! RXERR - Determines whether an interrupt occurs when a receive error occurs, based on the RXERR flag in the FIFOSTAT register. + * 0b0..No interrupt will be generated for a receive error. + * 0b1..An interrupt will be generated when a receive error occurs. + */ +#define USART_FIFOINTENSET_RXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_RXERR_SHIFT)) & USART_FIFOINTENSET_RXERR_MASK) +#define USART_FIFOINTENSET_TXLVL_MASK (0x4U) +#define USART_FIFOINTENSET_TXLVL_SHIFT (2U) +/*! TXLVL - Determines whether an interrupt occurs when a the transmit FIFO reaches the level + * specified by the TXLVL field in the FIFOTRIG register. + * 0b0..No interrupt will be generated based on the TX FIFO level. + * 0b1..If TXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when the TX FIFO level decreases + * to the level specified by TXLVL in the FIFOTRIG register. + */ +#define USART_FIFOINTENSET_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_TXLVL_SHIFT)) & USART_FIFOINTENSET_TXLVL_MASK) +#define USART_FIFOINTENSET_RXLVL_MASK (0x8U) +#define USART_FIFOINTENSET_RXLVL_SHIFT (3U) +/*! RXLVL - Determines whether an interrupt occurs when a the receive FIFO reaches the level + * specified by the TXLVL field in the FIFOTRIG register. + * 0b0..No interrupt will be generated based on the RX FIFO level. + * 0b1..If RXLVLENA in the FIFOTRIG register = 1, an interrupt will be generated when the when the RX FIFO level + * increases to the level specified by RXLVL in the FIFOTRIG register. + */ +#define USART_FIFOINTENSET_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENSET_RXLVL_SHIFT)) & USART_FIFOINTENSET_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTENCLR - FIFO interrupt enable clear (disable) and read register. */ +/*! @{ */ +#define USART_FIFOINTENCLR_TXERR_MASK (0x1U) +#define USART_FIFOINTENCLR_TXERR_SHIFT (0U) +/*! TXERR - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define USART_FIFOINTENCLR_TXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_TXERR_SHIFT)) & USART_FIFOINTENCLR_TXERR_MASK) +#define USART_FIFOINTENCLR_RXERR_MASK (0x2U) +#define USART_FIFOINTENCLR_RXERR_SHIFT (1U) +/*! RXERR - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define USART_FIFOINTENCLR_RXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_RXERR_SHIFT)) & USART_FIFOINTENCLR_RXERR_MASK) +#define USART_FIFOINTENCLR_TXLVL_MASK (0x4U) +#define USART_FIFOINTENCLR_TXLVL_SHIFT (2U) +/*! TXLVL - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define USART_FIFOINTENCLR_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_TXLVL_SHIFT)) & USART_FIFOINTENCLR_TXLVL_MASK) +#define USART_FIFOINTENCLR_RXLVL_MASK (0x8U) +#define USART_FIFOINTENCLR_RXLVL_SHIFT (3U) +/*! RXLVL - Writing one clears the corresponding bits in the FIFOINTENSET register. + */ +#define USART_FIFOINTENCLR_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTENCLR_RXLVL_SHIFT)) & USART_FIFOINTENCLR_RXLVL_MASK) +/*! @} */ + +/*! @name FIFOINTSTAT - FIFO interrupt status register. */ +/*! @{ */ +#define USART_FIFOINTSTAT_TXERR_MASK (0x1U) +#define USART_FIFOINTSTAT_TXERR_SHIFT (0U) +/*! TXERR - TX FIFO error. + */ +#define USART_FIFOINTSTAT_TXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_TXERR_SHIFT)) & USART_FIFOINTSTAT_TXERR_MASK) +#define USART_FIFOINTSTAT_RXERR_MASK (0x2U) +#define USART_FIFOINTSTAT_RXERR_SHIFT (1U) +/*! RXERR - RX FIFO error. + */ +#define USART_FIFOINTSTAT_RXERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_RXERR_SHIFT)) & USART_FIFOINTSTAT_RXERR_MASK) +#define USART_FIFOINTSTAT_TXLVL_MASK (0x4U) +#define USART_FIFOINTSTAT_TXLVL_SHIFT (2U) +/*! TXLVL - Transmit FIFO level interrupt. + */ +#define USART_FIFOINTSTAT_TXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_TXLVL_SHIFT)) & USART_FIFOINTSTAT_TXLVL_MASK) +#define USART_FIFOINTSTAT_RXLVL_MASK (0x8U) +#define USART_FIFOINTSTAT_RXLVL_SHIFT (3U) +/*! RXLVL - Receive FIFO level interrupt. + */ +#define USART_FIFOINTSTAT_RXLVL(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_RXLVL_SHIFT)) & USART_FIFOINTSTAT_RXLVL_MASK) +#define USART_FIFOINTSTAT_PERINT_MASK (0x10U) +#define USART_FIFOINTSTAT_PERINT_SHIFT (4U) +/*! PERINT - Peripheral interrupt. + */ +#define USART_FIFOINTSTAT_PERINT(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOINTSTAT_PERINT_SHIFT)) & USART_FIFOINTSTAT_PERINT_MASK) +/*! @} */ + +/*! @name FIFOWR - FIFO write data. */ +/*! @{ */ +#define USART_FIFOWR_TXDATA_MASK (0x1FFU) +#define USART_FIFOWR_TXDATA_SHIFT (0U) +/*! TXDATA - Transmit data to the FIFO. + */ +#define USART_FIFOWR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFOWR_TXDATA_SHIFT)) & USART_FIFOWR_TXDATA_MASK) +/*! @} */ + +/*! @name FIFORD - FIFO read data. */ +/*! @{ */ +#define USART_FIFORD_RXDATA_MASK (0x1FFU) +#define USART_FIFORD_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. The number of bits used depends on the DATALEN and PARITYSEL settings. + */ +#define USART_FIFORD_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_RXDATA_SHIFT)) & USART_FIFORD_RXDATA_MASK) +#define USART_FIFORD_FRAMERR_MASK (0x2000U) +#define USART_FIFORD_FRAMERR_SHIFT (13U) +/*! FRAMERR - Framing Error status flag. This bit reflects the status for the data it is read along + * with from the FIFO, and indicates that the character was received with a missing stop bit at + * the expected location. This could be an indication of a baud rate or configuration mismatch + * with the transmitting source. + */ +#define USART_FIFORD_FRAMERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_FRAMERR_SHIFT)) & USART_FIFORD_FRAMERR_MASK) +#define USART_FIFORD_PARITYERR_MASK (0x4000U) +#define USART_FIFORD_PARITYERR_SHIFT (14U) +/*! PARITYERR - Parity Error status flag. This bit reflects the status for the data it is read along + * with from the FIFO. This bit will be set when a parity error is detected in a received + * character. + */ +#define USART_FIFORD_PARITYERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_PARITYERR_SHIFT)) & USART_FIFORD_PARITYERR_MASK) +#define USART_FIFORD_RXNOISE_MASK (0x8000U) +#define USART_FIFORD_RXNOISE_SHIFT (15U) +/*! RXNOISE - Received Noise flag. See description of the RxNoiseInt bit in Table 354. + */ +#define USART_FIFORD_RXNOISE(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORD_RXNOISE_SHIFT)) & USART_FIFORD_RXNOISE_MASK) +/*! @} */ + +/*! @name FIFORDNOPOP - FIFO data read with no FIFO pop. */ +/*! @{ */ +#define USART_FIFORDNOPOP_RXDATA_MASK (0x1FFU) +#define USART_FIFORDNOPOP_RXDATA_SHIFT (0U) +/*! RXDATA - Received data from the FIFO. The number of bits used depends on the DATALEN and PARITYSEL settings. + */ +#define USART_FIFORDNOPOP_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_RXDATA_SHIFT)) & USART_FIFORDNOPOP_RXDATA_MASK) +#define USART_FIFORDNOPOP_FRAMERR_MASK (0x2000U) +#define USART_FIFORDNOPOP_FRAMERR_SHIFT (13U) +/*! FRAMERR - Framing Error status flag. This bit reflects the status for the data it is read along + * with from the FIFO, and indicates that the character was received with a missing stop bit at + * the expected location. This could be an indication of a baud rate or configuration mismatch + * with the transmitting source. + */ +#define USART_FIFORDNOPOP_FRAMERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_FRAMERR_SHIFT)) & USART_FIFORDNOPOP_FRAMERR_MASK) +#define USART_FIFORDNOPOP_PARITYERR_MASK (0x4000U) +#define USART_FIFORDNOPOP_PARITYERR_SHIFT (14U) +/*! PARITYERR - Parity Error status flag. This bit reflects the status for the data it is read along + * with from the FIFO. This bit will be set when a parity error is detected in a received + * character. + */ +#define USART_FIFORDNOPOP_PARITYERR(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_PARITYERR_SHIFT)) & USART_FIFORDNOPOP_PARITYERR_MASK) +#define USART_FIFORDNOPOP_RXNOISE_MASK (0x8000U) +#define USART_FIFORDNOPOP_RXNOISE_SHIFT (15U) +/*! RXNOISE - Received Noise flag. See description of the RxNoiseInt bit in Table 354. + */ +#define USART_FIFORDNOPOP_RXNOISE(x) (((uint32_t)(((uint32_t)(x)) << USART_FIFORDNOPOP_RXNOISE_SHIFT)) & USART_FIFORDNOPOP_RXNOISE_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group USART_Register_Masks */ + + +/* USART - Peripheral instance base addresses */ +/** Peripheral USART0 base address */ +#define USART0_BASE (0x40086000u) +/** Peripheral USART0 base pointer */ +#define USART0 ((USART_Type *)USART0_BASE) +/** Peripheral USART1 base address */ +#define USART1_BASE (0x40087000u) +/** Peripheral USART1 base pointer */ +#define USART1 ((USART_Type *)USART1_BASE) +/** Peripheral USART2 base address */ +#define USART2_BASE (0x40088000u) +/** Peripheral USART2 base pointer */ +#define USART2 ((USART_Type *)USART2_BASE) +/** Peripheral USART3 base address */ +#define USART3_BASE (0x40089000u) +/** Peripheral USART3 base pointer */ +#define USART3 ((USART_Type *)USART3_BASE) +/** Peripheral USART4 base address */ +#define USART4_BASE (0x4008A000u) +/** Peripheral USART4 base pointer */ +#define USART4 ((USART_Type *)USART4_BASE) +/** Peripheral USART5 base address */ +#define USART5_BASE (0x40096000u) +/** Peripheral USART5 base pointer */ +#define USART5 ((USART_Type *)USART5_BASE) +/** Peripheral USART6 base address */ +#define USART6_BASE (0x40097000u) +/** Peripheral USART6 base pointer */ +#define USART6 ((USART_Type *)USART6_BASE) +/** Peripheral USART7 base address */ +#define USART7_BASE (0x40098000u) +/** Peripheral USART7 base pointer */ +#define USART7 ((USART_Type *)USART7_BASE) +/** Array initializer of USART peripheral base addresses */ +#define USART_BASE_ADDRS { USART0_BASE, USART1_BASE, USART2_BASE, USART3_BASE, USART4_BASE, USART5_BASE, USART6_BASE, USART7_BASE } +/** Array initializer of USART peripheral base pointers */ +#define USART_BASE_PTRS { USART0, USART1, USART2, USART3, USART4, USART5, USART6, USART7 } +/** Interrupt vectors for the USART peripheral type */ +#define USART_IRQS { FLEXCOMM0_IRQn, FLEXCOMM1_IRQn, FLEXCOMM2_IRQn, FLEXCOMM3_IRQn, FLEXCOMM4_IRQn, FLEXCOMM5_IRQn, FLEXCOMM6_IRQn, FLEXCOMM7_IRQn } + +/*! + * @} + */ /* end of group USART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Peripheral_Access_Layer USB Peripheral Access Layer + * @{ + */ + +/** USB - Register Layout Typedef */ +typedef struct { + __IO uint32_t DEVCMDSTAT; /**< USB Device Command/Status register, offset: 0x0 */ + __IO uint32_t INFO; /**< USB Info register, offset: 0x4 */ + __IO uint32_t EPLISTSTART; /**< USB EP Command/Status List start address, offset: 0x8 */ + __IO uint32_t DATABUFSTART; /**< USB Data buffer start address, offset: 0xC */ + __IO uint32_t LPM; /**< USB Link Power Management register, offset: 0x10 */ + __IO uint32_t EPSKIP; /**< USB Endpoint skip, offset: 0x14 */ + __IO uint32_t EPINUSE; /**< USB Endpoint Buffer in use, offset: 0x18 */ + __IO uint32_t EPBUFCFG; /**< USB Endpoint Buffer Configuration register, offset: 0x1C */ + __IO uint32_t INTSTAT; /**< USB interrupt status register, offset: 0x20 */ + __IO uint32_t INTEN; /**< USB interrupt enable register, offset: 0x24 */ + __IO uint32_t INTSETSTAT; /**< USB set interrupt status register, offset: 0x28 */ + uint8_t RESERVED_0[8]; + __I uint32_t EPTOGGLE; /**< USB Endpoint toggle register, offset: 0x34 */ +} USB_Type; + +/* ---------------------------------------------------------------------------- + -- USB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Register_Masks USB Register Masks + * @{ + */ + +/*! @name DEVCMDSTAT - USB Device Command/Status register */ +/*! @{ */ +#define USB_DEVCMDSTAT_DEV_ADDR_MASK (0x7FU) +#define USB_DEVCMDSTAT_DEV_ADDR_SHIFT (0U) +/*! DEV_ADDR - USB device address. After bus reset, the address is reset to 0x00. If the enable bit + * is set, the device will respond on packets for function address DEV_ADDR. When receiving a + * SetAddress Control Request from the USB host, software must program the new address before + * completing the status phase of the SetAddress Control Request. + */ +#define USB_DEVCMDSTAT_DEV_ADDR(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DEV_ADDR_SHIFT)) & USB_DEVCMDSTAT_DEV_ADDR_MASK) +#define USB_DEVCMDSTAT_DEV_EN_MASK (0x80U) +#define USB_DEVCMDSTAT_DEV_EN_SHIFT (7U) +/*! DEV_EN - USB device enable. If this bit is set, the HW will start responding on packets for function address DEV_ADDR. + */ +#define USB_DEVCMDSTAT_DEV_EN(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DEV_EN_SHIFT)) & USB_DEVCMDSTAT_DEV_EN_MASK) +#define USB_DEVCMDSTAT_SETUP_MASK (0x100U) +#define USB_DEVCMDSTAT_SETUP_SHIFT (8U) +/*! SETUP - SETUP token received. If a SETUP token is received and acknowledged by the device, this + * bit is set. As long as this bit is set all received IN and OUT tokens will be NAKed by HW. SW + * must clear this bit by writing a one. If this bit is zero, HW will handle the tokens to the + * CTRL EP0 as indicated by the CTRL EP0 IN and OUT data information programmed by SW. + */ +#define USB_DEVCMDSTAT_SETUP(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_SETUP_SHIFT)) & USB_DEVCMDSTAT_SETUP_MASK) +#define USB_DEVCMDSTAT_FORCE_NEEDCLK_MASK (0x200U) +#define USB_DEVCMDSTAT_FORCE_NEEDCLK_SHIFT (9U) +/*! FORCE_NEEDCLK - Forces the NEEDCLK output to always be on: + * 0b0..USB_NEEDCLK has normal function. + * 0b1..USB_NEEDCLK always 1. Clock will not be stopped in case of suspend. + */ +#define USB_DEVCMDSTAT_FORCE_NEEDCLK(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_FORCE_NEEDCLK_SHIFT)) & USB_DEVCMDSTAT_FORCE_NEEDCLK_MASK) +#define USB_DEVCMDSTAT_LPM_SUP_MASK (0x800U) +#define USB_DEVCMDSTAT_LPM_SUP_SHIFT (11U) +/*! LPM_SUP - LPM Supported: + * 0b0..LPM not supported. + * 0b1..LPM supported. + */ +#define USB_DEVCMDSTAT_LPM_SUP(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_LPM_SUP_SHIFT)) & USB_DEVCMDSTAT_LPM_SUP_MASK) +#define USB_DEVCMDSTAT_INTONNAK_AO_MASK (0x1000U) +#define USB_DEVCMDSTAT_INTONNAK_AO_SHIFT (12U) +/*! INTONNAK_AO - Interrupt on NAK for interrupt and bulk OUT EP + * 0b0..Only acknowledged packets generate an interrupt + * 0b1..Both acknowledged and NAKed packets generate interrupts. + */ +#define USB_DEVCMDSTAT_INTONNAK_AO(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_INTONNAK_AO_SHIFT)) & USB_DEVCMDSTAT_INTONNAK_AO_MASK) +#define USB_DEVCMDSTAT_INTONNAK_AI_MASK (0x2000U) +#define USB_DEVCMDSTAT_INTONNAK_AI_SHIFT (13U) +/*! INTONNAK_AI - Interrupt on NAK for interrupt and bulk IN EP + * 0b0..Only acknowledged packets generate an interrupt + * 0b1..Both acknowledged and NAKed packets generate interrupts. + */ +#define USB_DEVCMDSTAT_INTONNAK_AI(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_INTONNAK_AI_SHIFT)) & USB_DEVCMDSTAT_INTONNAK_AI_MASK) +#define USB_DEVCMDSTAT_INTONNAK_CO_MASK (0x4000U) +#define USB_DEVCMDSTAT_INTONNAK_CO_SHIFT (14U) +/*! INTONNAK_CO - Interrupt on NAK for control OUT EP + * 0b0..Only acknowledged packets generate an interrupt + * 0b1..Both acknowledged and NAKed packets generate interrupts. + */ +#define USB_DEVCMDSTAT_INTONNAK_CO(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_INTONNAK_CO_SHIFT)) & USB_DEVCMDSTAT_INTONNAK_CO_MASK) +#define USB_DEVCMDSTAT_INTONNAK_CI_MASK (0x8000U) +#define USB_DEVCMDSTAT_INTONNAK_CI_SHIFT (15U) +/*! INTONNAK_CI - Interrupt on NAK for control IN EP + * 0b0..Only acknowledged packets generate an interrupt + * 0b1..Both acknowledged and NAKed packets generate interrupts. + */ +#define USB_DEVCMDSTAT_INTONNAK_CI(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_INTONNAK_CI_SHIFT)) & USB_DEVCMDSTAT_INTONNAK_CI_MASK) +#define USB_DEVCMDSTAT_DCON_MASK (0x10000U) +#define USB_DEVCMDSTAT_DCON_SHIFT (16U) +/*! DCON - Device status - connect. The connect bit must be set by SW to indicate that the device + * must signal a connect. The pull-up resistor on USB_DP will be enabled when this bit is set and + * the VBUSDEBOUNCED bit is one. + */ +#define USB_DEVCMDSTAT_DCON(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DCON_SHIFT)) & USB_DEVCMDSTAT_DCON_MASK) +#define USB_DEVCMDSTAT_DSUS_MASK (0x20000U) +#define USB_DEVCMDSTAT_DSUS_SHIFT (17U) +/*! DSUS - Device status - suspend. The suspend bit indicates the current suspend state. It is set + * to 1 when the device hasn't seen any activity on its upstream port for more than 3 + * milliseconds. It is reset to 0 on any activity. When the device is suspended (Suspend bit DSUS = 1) and + * the software writes a 0 to it, the device will generate a remote wake-up. This will only happen + * when the device is connected (Connect bit = 1). When the device is not connected or not + * suspended, a writing a 0 has no effect. Writing a 1 never has an effect. + */ +#define USB_DEVCMDSTAT_DSUS(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DSUS_SHIFT)) & USB_DEVCMDSTAT_DSUS_MASK) +#define USB_DEVCMDSTAT_LPM_SUS_MASK (0x80000U) +#define USB_DEVCMDSTAT_LPM_SUS_SHIFT (19U) +/*! LPM_SUS - Device status - LPM Suspend. This bit represents the current LPM suspend state. It is + * set to 1 by HW when the device has acknowledged the LPM request from the USB host and the + * Token Retry Time of 10 ms has elapsed. When the device is in the LPM suspended state (LPM suspend + * bit = 1) and the software writes a zero to this bit, the device will generate a remote + * walk-up. Software can only write a zero to this bit when the LPM_REWP bit is set to 1. HW resets this + * bit when it receives a host initiated resume. HW only updates the LPM_SUS bit when the + * LPM_SUPP bit is equal to one. + */ +#define USB_DEVCMDSTAT_LPM_SUS(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_LPM_SUS_SHIFT)) & USB_DEVCMDSTAT_LPM_SUS_MASK) +#define USB_DEVCMDSTAT_LPM_REWP_MASK (0x100000U) +#define USB_DEVCMDSTAT_LPM_REWP_SHIFT (20U) +/*! LPM_REWP - LPM Remote Wake-up Enabled by USB host. HW sets this bit to one when the bRemoteWake + * bit in the LPM extended token is set to 1. HW will reset this bit to 0 when it receives the + * host initiated LPM resume, when a remote wake-up is sent by the device or when a USB bus reset + * is received. Software can use this bit to check if the remote wake-up feature is enabled by the + * host for the LPM transaction. + */ +#define USB_DEVCMDSTAT_LPM_REWP(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_LPM_REWP_SHIFT)) & USB_DEVCMDSTAT_LPM_REWP_MASK) +#define USB_DEVCMDSTAT_DCON_C_MASK (0x1000000U) +#define USB_DEVCMDSTAT_DCON_C_SHIFT (24U) +/*! DCON_C - Device status - connect change. The Connect Change bit is set when the device's pull-up + * resistor is disconnected because VBus disappeared. The bit is reset by writing a one to it. + */ +#define USB_DEVCMDSTAT_DCON_C(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DCON_C_SHIFT)) & USB_DEVCMDSTAT_DCON_C_MASK) +#define USB_DEVCMDSTAT_DSUS_C_MASK (0x2000000U) +#define USB_DEVCMDSTAT_DSUS_C_SHIFT (25U) +/*! DSUS_C - Device status - suspend change. The suspend change bit is set to 1 when the suspend bit + * toggles. The suspend bit can toggle because: - The device goes in the suspended state - The + * device is disconnected - The device receives resume signaling on its upstream port. The bit is + * reset by writing a one to it. + */ +#define USB_DEVCMDSTAT_DSUS_C(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DSUS_C_SHIFT)) & USB_DEVCMDSTAT_DSUS_C_MASK) +#define USB_DEVCMDSTAT_DRES_C_MASK (0x4000000U) +#define USB_DEVCMDSTAT_DRES_C_SHIFT (26U) +/*! DRES_C - Device status - reset change. This bit is set when the device received a bus reset. On + * a bus reset the device will automatically go to the default state (unconfigured and responding + * to address 0). The bit is reset by writing a one to it. + */ +#define USB_DEVCMDSTAT_DRES_C(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_DRES_C_SHIFT)) & USB_DEVCMDSTAT_DRES_C_MASK) +#define USB_DEVCMDSTAT_VBUSDEBOUNCED_MASK (0x10000000U) +#define USB_DEVCMDSTAT_VBUSDEBOUNCED_SHIFT (28U) +/*! VBUSDEBOUNCED - This bit indicates if Vbus is detected or not. The bit raises immediately when + * Vbus becomes high. It drops to zero if Vbus is low for at least 3 ms. If this bit is high and + * the DCon bit is set, the HW will enable the pull-up resistor to signal a connect. + */ +#define USB_DEVCMDSTAT_VBUSDEBOUNCED(x) (((uint32_t)(((uint32_t)(x)) << USB_DEVCMDSTAT_VBUSDEBOUNCED_SHIFT)) & USB_DEVCMDSTAT_VBUSDEBOUNCED_MASK) +/*! @} */ + +/*! @name INFO - USB Info register */ +/*! @{ */ +#define USB_INFO_FRAME_NR_MASK (0x7FFU) +#define USB_INFO_FRAME_NR_SHIFT (0U) +/*! FRAME_NR - Frame number. This contains the frame number of the last successfully received SOF. + * In case no SOF was received by the device at the beginning of a frame, the frame number + * returned is that of the last successfully received SOF. In case the SOF frame number contained a CRC + * error, the frame number returned will be the corrupted frame number as received by the device. + */ +#define USB_INFO_FRAME_NR(x) (((uint32_t)(((uint32_t)(x)) << USB_INFO_FRAME_NR_SHIFT)) & USB_INFO_FRAME_NR_MASK) +#define USB_INFO_ERR_CODE_MASK (0x7800U) +#define USB_INFO_ERR_CODE_SHIFT (11U) +/*! ERR_CODE - The error code which last occurred: + * 0b0000..No error + * 0b0001..PID encoding error + * 0b0010..PID unknown + * 0b0011..Packet unexpected + * 0b0100..Token CRC error + * 0b0101..Data CRC error + * 0b0110..Time out + * 0b0111..Babble + * 0b1000..Truncated EOP + * 0b1001..Sent/Received NAK + * 0b1010..Sent Stall + * 0b1011..Overrun + * 0b1100..Sent empty packet + * 0b1101..Bitstuff error + * 0b1110..Sync error + * 0b1111..Wrong data toggle + */ +#define USB_INFO_ERR_CODE(x) (((uint32_t)(((uint32_t)(x)) << USB_INFO_ERR_CODE_SHIFT)) & USB_INFO_ERR_CODE_MASK) +/*! @} */ + +/*! @name EPLISTSTART - USB EP Command/Status List start address */ +/*! @{ */ +#define USB_EPLISTSTART_EP_LIST_MASK (0xFFFFFF00U) +#define USB_EPLISTSTART_EP_LIST_SHIFT (8U) +/*! EP_LIST - Start address of the USB EP Command/Status List. + */ +#define USB_EPLISTSTART_EP_LIST(x) (((uint32_t)(((uint32_t)(x)) << USB_EPLISTSTART_EP_LIST_SHIFT)) & USB_EPLISTSTART_EP_LIST_MASK) +/*! @} */ + +/*! @name DATABUFSTART - USB Data buffer start address */ +/*! @{ */ +#define USB_DATABUFSTART_DA_BUF_MASK (0xFFC00000U) +#define USB_DATABUFSTART_DA_BUF_SHIFT (22U) +/*! DA_BUF - Start address of the buffer pointer page where all endpoint data buffers are located. + */ +#define USB_DATABUFSTART_DA_BUF(x) (((uint32_t)(((uint32_t)(x)) << USB_DATABUFSTART_DA_BUF_SHIFT)) & USB_DATABUFSTART_DA_BUF_MASK) +/*! @} */ + +/*! @name LPM - USB Link Power Management register */ +/*! @{ */ +#define USB_LPM_HIRD_HW_MASK (0xFU) +#define USB_LPM_HIRD_HW_SHIFT (0U) +/*! HIRD_HW - Host Initiated Resume Duration - HW. This is the HIRD value from the last received LPM token + */ +#define USB_LPM_HIRD_HW(x) (((uint32_t)(((uint32_t)(x)) << USB_LPM_HIRD_HW_SHIFT)) & USB_LPM_HIRD_HW_MASK) +#define USB_LPM_HIRD_SW_MASK (0xF0U) +#define USB_LPM_HIRD_SW_SHIFT (4U) +/*! HIRD_SW - Host Initiated Resume Duration - SW. This is the time duration required by the USB + * device system to come out of LPM initiated suspend after receiving the host initiated LPM resume. + */ +#define USB_LPM_HIRD_SW(x) (((uint32_t)(((uint32_t)(x)) << USB_LPM_HIRD_SW_SHIFT)) & USB_LPM_HIRD_SW_MASK) +#define USB_LPM_DATA_PENDING_MASK (0x100U) +#define USB_LPM_DATA_PENDING_SHIFT (8U) +/*! DATA_PENDING - As long as this bit is set to one and LPM supported bit is set to one, HW will + * return a NYET handshake on every LPM token it receives. If LPM supported bit is set to one and + * this bit is zero, HW will return an ACK handshake on every LPM token it receives. If SW has + * still data pending and LPM is supported, it must set this bit to 1. + */ +#define USB_LPM_DATA_PENDING(x) (((uint32_t)(((uint32_t)(x)) << USB_LPM_DATA_PENDING_SHIFT)) & USB_LPM_DATA_PENDING_MASK) +/*! @} */ + +/*! @name EPSKIP - USB Endpoint skip */ +/*! @{ */ +#define USB_EPSKIP_SKIP_MASK (0x3FFFFFFFU) +#define USB_EPSKIP_SKIP_SHIFT (0U) +/*! SKIP - Endpoint skip: Writing 1 to one of these bits, will indicate to HW that it must + * deactivate the buffer assigned to this endpoint and return control back to software. When HW has + * deactivated the endpoint, it will clear this bit, but it will not modify the EPINUSE bit. An + * interrupt will be generated when the Active bit goes from 1 to 0. Note: In case of double-buffering, + * HW will only clear the Active bit of the buffer indicated by the EPINUSE bit. + */ +#define USB_EPSKIP_SKIP(x) (((uint32_t)(((uint32_t)(x)) << USB_EPSKIP_SKIP_SHIFT)) & USB_EPSKIP_SKIP_MASK) +/*! @} */ + +/*! @name EPINUSE - USB Endpoint Buffer in use */ +/*! @{ */ +#define USB_EPINUSE_BUF_MASK (0x3FCU) +#define USB_EPINUSE_BUF_SHIFT (2U) +/*! BUF - Buffer in use: This register has one bit per physical endpoint. 0: HW is accessing buffer + * 0. 1: HW is accessing buffer 1. + */ +#define USB_EPINUSE_BUF(x) (((uint32_t)(((uint32_t)(x)) << USB_EPINUSE_BUF_SHIFT)) & USB_EPINUSE_BUF_MASK) +/*! @} */ + +/*! @name EPBUFCFG - USB Endpoint Buffer Configuration register */ +/*! @{ */ +#define USB_EPBUFCFG_BUF_SB_MASK (0x3FCU) +#define USB_EPBUFCFG_BUF_SB_SHIFT (2U) +/*! BUF_SB - Buffer usage: This register has one bit per physical endpoint. 0: Single-buffer. 1: + * Double-buffer. If the bit is set to single-buffer (0), it will not toggle the corresponding + * EPINUSE bit when it clears the active bit. If the bit is set to double-buffer (1), HW will toggle + * the EPINUSE bit when it clears the Active bit for the buffer. + */ +#define USB_EPBUFCFG_BUF_SB(x) (((uint32_t)(((uint32_t)(x)) << USB_EPBUFCFG_BUF_SB_SHIFT)) & USB_EPBUFCFG_BUF_SB_MASK) +/*! @} */ + +/*! @name INTSTAT - USB interrupt status register */ +/*! @{ */ +#define USB_INTSTAT_EP0OUT_MASK (0x1U) +#define USB_INTSTAT_EP0OUT_SHIFT (0U) +/*! EP0OUT - Interrupt status register bit for the Control EP0 OUT direction. This bit will be set + * if NBytes transitions to zero or the skip bit is set by software or a SETUP packet is + * successfully received for the control EP0. If the IntOnNAK_CO is set, this bit will also be set when a + * NAK is transmitted for the Control EP0 OUT direction. Software can clear this bit by writing a + * one to it. + */ +#define USB_INTSTAT_EP0OUT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP0OUT_SHIFT)) & USB_INTSTAT_EP0OUT_MASK) +#define USB_INTSTAT_EP0IN_MASK (0x2U) +#define USB_INTSTAT_EP0IN_SHIFT (1U) +/*! EP0IN - Interrupt status register bit for the Control EP0 IN direction. This bit will be set if + * NBytes transitions to zero or the skip bit is set by software. If the IntOnNAK_CI is set, this + * bit will also be set when a NAK is transmitted for the Control EP0 IN direction. Software can + * clear this bit by writing a one to it. + */ +#define USB_INTSTAT_EP0IN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP0IN_SHIFT)) & USB_INTSTAT_EP0IN_MASK) +#define USB_INTSTAT_EP1OUT_MASK (0x4U) +#define USB_INTSTAT_EP1OUT_SHIFT (2U) +/*! EP1OUT - Interrupt status register bit for the EP1 OUT direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes + * transitions to zero or the skip bit is set by software. If the IntOnNAK_AO is set, this bit will also be + * set when a NAK is transmitted for the EP1 OUT direction. Software can clear this bit by + * writing a one to it. + */ +#define USB_INTSTAT_EP1OUT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP1OUT_SHIFT)) & USB_INTSTAT_EP1OUT_MASK) +#define USB_INTSTAT_EP1IN_MASK (0x8U) +#define USB_INTSTAT_EP1IN_SHIFT (3U) +/*! EP1IN - Interrupt status register bit for the EP1 IN direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes transitions + * to zero or the skip bit is set by software. If the IntOnNAK_AI is set, this bit will also be + * set when a NAK is transmitted for the EP1 IN direction. Software can clear this bit by writing + * a one to it. + */ +#define USB_INTSTAT_EP1IN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP1IN_SHIFT)) & USB_INTSTAT_EP1IN_MASK) +#define USB_INTSTAT_EP2OUT_MASK (0x10U) +#define USB_INTSTAT_EP2OUT_SHIFT (4U) +/*! EP2OUT - Interrupt status register bit for the EP2 OUT direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes + * transitions to zero or the skip bit is set by software. If the IntOnNAK_AO is set, this bit will also be + * set when a NAK is transmitted for the EP2 OUT direction. Software can clear this bit by + * writing a one to it. + */ +#define USB_INTSTAT_EP2OUT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP2OUT_SHIFT)) & USB_INTSTAT_EP2OUT_MASK) +#define USB_INTSTAT_EP2IN_MASK (0x20U) +#define USB_INTSTAT_EP2IN_SHIFT (5U) +/*! EP2IN - Interrupt status register bit for the EP2 IN direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes transitions + * to zero or the skip bit is set by software. If the IntOnNAK_AI is set, this bit will also be + * set when a NAK is transmitted for the EP2 IN direction. Software can clear this bit by writing + * a one to it. + */ +#define USB_INTSTAT_EP2IN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP2IN_SHIFT)) & USB_INTSTAT_EP2IN_MASK) +#define USB_INTSTAT_EP3OUT_MASK (0x40U) +#define USB_INTSTAT_EP3OUT_SHIFT (6U) +/*! EP3OUT - Interrupt status register bit for the EP3 OUT direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes + * transitions to zero or the skip bit is set by software. If the IntOnNAK_AO is set, this bit will also be + * set when a NAK is transmitted for the EP3 OUT direction. Software can clear this bit by + * writing a one to it. + */ +#define USB_INTSTAT_EP3OUT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP3OUT_SHIFT)) & USB_INTSTAT_EP3OUT_MASK) +#define USB_INTSTAT_EP3IN_MASK (0x80U) +#define USB_INTSTAT_EP3IN_SHIFT (7U) +/*! EP3IN - Interrupt status register bit for the EP3 IN direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes transitions + * to zero or the skip bit is set by software. If the IntOnNAK_AI is set, this bit will also be + * set when a NAK is transmitted for the EP3 IN direction. Software can clear this bit by writing + * a one to it. + */ +#define USB_INTSTAT_EP3IN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP3IN_SHIFT)) & USB_INTSTAT_EP3IN_MASK) +#define USB_INTSTAT_EP4OUT_MASK (0x100U) +#define USB_INTSTAT_EP4OUT_SHIFT (8U) +/*! EP4OUT - Interrupt status register bit for the EP4 OUT direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes + * transitions to zero or the skip bit is set by software. If the IntOnNAK_AO is set, this bit will also be + * set when a NAK is transmitted for the EP4 OUT direction. Software can clear this bit by + * writing a one to it. + */ +#define USB_INTSTAT_EP4OUT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP4OUT_SHIFT)) & USB_INTSTAT_EP4OUT_MASK) +#define USB_INTSTAT_EP4IN_MASK (0x200U) +#define USB_INTSTAT_EP4IN_SHIFT (9U) +/*! EP4IN - Interrupt status register bit for the EP4 IN direction. This bit will be set if the + * corresponding Active bit is cleared by HW. This is done in case the programmed NBytes transitions + * to zero or the skip bit is set by software. If the IntOnNAK_AI is set, this bit will also be + * set when a NAK is transmitted for the EP4 IN direction. Software can clear this bit by writing + * a one to it. + */ +#define USB_INTSTAT_EP4IN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_EP4IN_SHIFT)) & USB_INTSTAT_EP4IN_MASK) +#define USB_INTSTAT_FRAME_INT_MASK (0x40000000U) +#define USB_INTSTAT_FRAME_INT_SHIFT (30U) +/*! FRAME_INT - Frame interrupt. This bit is set to one every millisecond when the VbusDebounced bit + * and the DCON bit are set. This bit can be used by software when handling isochronous + * endpoints. Software can clear this bit by writing a one to it. + */ +#define USB_INTSTAT_FRAME_INT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_FRAME_INT_SHIFT)) & USB_INTSTAT_FRAME_INT_MASK) +#define USB_INTSTAT_DEV_INT_MASK (0x80000000U) +#define USB_INTSTAT_DEV_INT_SHIFT (31U) +/*! DEV_INT - Device status interrupt. This bit is set by HW when one of the bits in the Device + * Status Change register are set. Software can clear this bit by writing a one to it. + */ +#define USB_INTSTAT_DEV_INT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSTAT_DEV_INT_SHIFT)) & USB_INTSTAT_DEV_INT_MASK) +/*! @} */ + +/*! @name INTEN - USB interrupt enable register */ +/*! @{ */ +#define USB_INTEN_EP_INT_EN_MASK (0x3FFU) +#define USB_INTEN_EP_INT_EN_SHIFT (0U) +/*! EP_INT_EN - If this bit is set and the corresponding USB interrupt status bit is set, a HW + * interrupt is generated on the interrupt line indicated by the corresponding USB interrupt routing + * bit. + */ +#define USB_INTEN_EP_INT_EN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTEN_EP_INT_EN_SHIFT)) & USB_INTEN_EP_INT_EN_MASK) +#define USB_INTEN_FRAME_INT_EN_MASK (0x40000000U) +#define USB_INTEN_FRAME_INT_EN_SHIFT (30U) +/*! FRAME_INT_EN - If this bit is set and the corresponding USB interrupt status bit is set, a HW + * interrupt is generated on the interrupt line indicated by the corresponding USB interrupt + * routing bit. + */ +#define USB_INTEN_FRAME_INT_EN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTEN_FRAME_INT_EN_SHIFT)) & USB_INTEN_FRAME_INT_EN_MASK) +#define USB_INTEN_DEV_INT_EN_MASK (0x80000000U) +#define USB_INTEN_DEV_INT_EN_SHIFT (31U) +/*! DEV_INT_EN - If this bit is set and the corresponding USB interrupt status bit is set, a HW + * interrupt is generated on the interrupt line indicated by the corresponding USB interrupt routing + * bit. + */ +#define USB_INTEN_DEV_INT_EN(x) (((uint32_t)(((uint32_t)(x)) << USB_INTEN_DEV_INT_EN_SHIFT)) & USB_INTEN_DEV_INT_EN_MASK) +/*! @} */ + +/*! @name INTSETSTAT - USB set interrupt status register */ +/*! @{ */ +#define USB_INTSETSTAT_EP_SET_INT_MASK (0x3FFU) +#define USB_INTSETSTAT_EP_SET_INT_SHIFT (0U) +/*! EP_SET_INT - If software writes a one to one of these bits, the corresponding USB interrupt + * status bit is set. When this register is read, the same value as the USB interrupt status register + * is returned. + */ +#define USB_INTSETSTAT_EP_SET_INT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSETSTAT_EP_SET_INT_SHIFT)) & USB_INTSETSTAT_EP_SET_INT_MASK) +#define USB_INTSETSTAT_FRAME_SET_INT_MASK (0x40000000U) +#define USB_INTSETSTAT_FRAME_SET_INT_SHIFT (30U) +/*! FRAME_SET_INT - If software writes a one to one of these bits, the corresponding USB interrupt + * status bit is set. When this register is read, the same value as the USB interrupt status + * register is returned. + */ +#define USB_INTSETSTAT_FRAME_SET_INT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSETSTAT_FRAME_SET_INT_SHIFT)) & USB_INTSETSTAT_FRAME_SET_INT_MASK) +#define USB_INTSETSTAT_DEV_SET_INT_MASK (0x80000000U) +#define USB_INTSETSTAT_DEV_SET_INT_SHIFT (31U) +/*! DEV_SET_INT - If software writes a one to one of these bits, the corresponding USB interrupt + * status bit is set. When this register is read, the same value as the USB interrupt status + * register is returned. + */ +#define USB_INTSETSTAT_DEV_SET_INT(x) (((uint32_t)(((uint32_t)(x)) << USB_INTSETSTAT_DEV_SET_INT_SHIFT)) & USB_INTSETSTAT_DEV_SET_INT_MASK) +/*! @} */ + +/*! @name EPTOGGLE - USB Endpoint toggle register */ +/*! @{ */ +#define USB_EPTOGGLE_TOGGLE_MASK (0x3FFU) +#define USB_EPTOGGLE_TOGGLE_SHIFT (0U) +/*! TOGGLE - Endpoint data toggle: This field indicates the current value of the data toggle for the corresponding endpoint. + */ +#define USB_EPTOGGLE_TOGGLE(x) (((uint32_t)(((uint32_t)(x)) << USB_EPTOGGLE_TOGGLE_SHIFT)) & USB_EPTOGGLE_TOGGLE_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group USB_Register_Masks */ + + +/* USB - Peripheral instance base addresses */ +/** Peripheral USB0 base address */ +#define USB0_BASE (0x40084000u) +/** Peripheral USB0 base pointer */ +#define USB0 ((USB_Type *)USB0_BASE) +/** Array initializer of USB peripheral base addresses */ +#define USB_BASE_ADDRS { USB0_BASE } +/** Array initializer of USB peripheral base pointers */ +#define USB_BASE_PTRS { USB0 } +/** Interrupt vectors for the USB peripheral type */ +#define USB_IRQS { USB0_IRQn } +#define USB_NEEDCLK_IRQS { USB0_NEEDCLK_IRQn } + +/*! + * @} + */ /* end of group USB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- UTICK Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UTICK_Peripheral_Access_Layer UTICK Peripheral Access Layer + * @{ + */ + +/** UTICK - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< Control register., offset: 0x0 */ + __IO uint32_t STAT; /**< Status register., offset: 0x4 */ + __IO uint32_t CFG; /**< Capture configuration register., offset: 0x8 */ + __O uint32_t CAPCLR; /**< Capture clear register., offset: 0xC */ + __I uint32_t CAP[4]; /**< Capture register ., array offset: 0x10, array step: 0x4 */ +} UTICK_Type; + +/* ---------------------------------------------------------------------------- + -- UTICK Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UTICK_Register_Masks UTICK Register Masks + * @{ + */ + +/*! @name CTRL - Control register. */ +/*! @{ */ +#define UTICK_CTRL_DELAYVAL_MASK (0x7FFFFFFFU) +#define UTICK_CTRL_DELAYVAL_SHIFT (0U) +/*! DELAYVAL - Tick interval value. The delay will be equal to DELAYVAL + 1 periods of the timer + * clock. The minimum usable value is 1, for a delay of 2 timer clocks. A value of 0 stops the timer. + */ +#define UTICK_CTRL_DELAYVAL(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CTRL_DELAYVAL_SHIFT)) & UTICK_CTRL_DELAYVAL_MASK) +#define UTICK_CTRL_REPEAT_MASK (0x80000000U) +#define UTICK_CTRL_REPEAT_SHIFT (31U) +/*! REPEAT - Repeat delay. 0 = One-time delay. 1 = Delay repeats continuously. + */ +#define UTICK_CTRL_REPEAT(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CTRL_REPEAT_SHIFT)) & UTICK_CTRL_REPEAT_MASK) +/*! @} */ + +/*! @name STAT - Status register. */ +/*! @{ */ +#define UTICK_STAT_INTR_MASK (0x1U) +#define UTICK_STAT_INTR_SHIFT (0U) +/*! INTR - Interrupt flag. 0 = No interrupt is pending. 1 = An interrupt is pending. A write of any + * value to this register clears this flag. + */ +#define UTICK_STAT_INTR(x) (((uint32_t)(((uint32_t)(x)) << UTICK_STAT_INTR_SHIFT)) & UTICK_STAT_INTR_MASK) +#define UTICK_STAT_ACTIVE_MASK (0x2U) +#define UTICK_STAT_ACTIVE_SHIFT (1U) +/*! ACTIVE - Active flag. 0 = The Micro-Tick Timer is stopped. 1 = The Micro-Tick Timer is currently active. + */ +#define UTICK_STAT_ACTIVE(x) (((uint32_t)(((uint32_t)(x)) << UTICK_STAT_ACTIVE_SHIFT)) & UTICK_STAT_ACTIVE_MASK) +/*! @} */ + +/*! @name CFG - Capture configuration register. */ +/*! @{ */ +#define UTICK_CFG_CAPEN0_MASK (0x1U) +#define UTICK_CFG_CAPEN0_SHIFT (0U) +/*! CAPEN0 - Enable Capture 0. 1 = Enabled, 0 = Disabled. + */ +#define UTICK_CFG_CAPEN0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN0_SHIFT)) & UTICK_CFG_CAPEN0_MASK) +#define UTICK_CFG_CAPEN1_MASK (0x2U) +#define UTICK_CFG_CAPEN1_SHIFT (1U) +/*! CAPEN1 - Enable Capture 1. 1 = Enabled, 0 = Disabled. + */ +#define UTICK_CFG_CAPEN1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN1_SHIFT)) & UTICK_CFG_CAPEN1_MASK) +#define UTICK_CFG_CAPEN2_MASK (0x4U) +#define UTICK_CFG_CAPEN2_SHIFT (2U) +/*! CAPEN2 - Enable Capture 2. 1 = Enabled, 0 = Disabled. + */ +#define UTICK_CFG_CAPEN2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN2_SHIFT)) & UTICK_CFG_CAPEN2_MASK) +#define UTICK_CFG_CAPEN3_MASK (0x8U) +#define UTICK_CFG_CAPEN3_SHIFT (3U) +/*! CAPEN3 - Enable Capture 3. 1 = Enabled, 0 = Disabled. + */ +#define UTICK_CFG_CAPEN3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN3_SHIFT)) & UTICK_CFG_CAPEN3_MASK) +#define UTICK_CFG_CAPPOL0_MASK (0x100U) +#define UTICK_CFG_CAPPOL0_SHIFT (8U) +/*! CAPPOL0 - Capture Polarity 0. 0 = Positive edge capture, 1 = Negative edge capture. + */ +#define UTICK_CFG_CAPPOL0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL0_SHIFT)) & UTICK_CFG_CAPPOL0_MASK) +#define UTICK_CFG_CAPPOL1_MASK (0x200U) +#define UTICK_CFG_CAPPOL1_SHIFT (9U) +/*! CAPPOL1 - Capture Polarity 1. 0 = Positive edge capture, 1 = Negative edge capture. + */ +#define UTICK_CFG_CAPPOL1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL1_SHIFT)) & UTICK_CFG_CAPPOL1_MASK) +#define UTICK_CFG_CAPPOL2_MASK (0x400U) +#define UTICK_CFG_CAPPOL2_SHIFT (10U) +/*! CAPPOL2 - Capture Polarity 2. 0 = Positive edge capture, 1 = Negative edge capture. + */ +#define UTICK_CFG_CAPPOL2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL2_SHIFT)) & UTICK_CFG_CAPPOL2_MASK) +#define UTICK_CFG_CAPPOL3_MASK (0x800U) +#define UTICK_CFG_CAPPOL3_SHIFT (11U) +/*! CAPPOL3 - Capture Polarity 3. 0 = Positive edge capture, 1 = Negative edge capture. + */ +#define UTICK_CFG_CAPPOL3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL3_SHIFT)) & UTICK_CFG_CAPPOL3_MASK) +/*! @} */ + +/*! @name CAPCLR - Capture clear register. */ +/*! @{ */ +#define UTICK_CAPCLR_CAPCLR0_MASK (0x1U) +#define UTICK_CAPCLR_CAPCLR0_SHIFT (0U) +/*! CAPCLR0 - Clear capture 0. Writing 1 to this bit clears the CAP0 register value. + */ +#define UTICK_CAPCLR_CAPCLR0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR0_SHIFT)) & UTICK_CAPCLR_CAPCLR0_MASK) +#define UTICK_CAPCLR_CAPCLR1_MASK (0x2U) +#define UTICK_CAPCLR_CAPCLR1_SHIFT (1U) +/*! CAPCLR1 - Clear capture 1. Writing 1 to this bit clears the CAP1 register value. + */ +#define UTICK_CAPCLR_CAPCLR1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR1_SHIFT)) & UTICK_CAPCLR_CAPCLR1_MASK) +#define UTICK_CAPCLR_CAPCLR2_MASK (0x4U) +#define UTICK_CAPCLR_CAPCLR2_SHIFT (2U) +/*! CAPCLR2 - Clear capture 2. Writing 1 to this bit clears the CAP2 register value. + */ +#define UTICK_CAPCLR_CAPCLR2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR2_SHIFT)) & UTICK_CAPCLR_CAPCLR2_MASK) +#define UTICK_CAPCLR_CAPCLR3_MASK (0x8U) +#define UTICK_CAPCLR_CAPCLR3_SHIFT (3U) +/*! CAPCLR3 - Clear capture 3. Writing 1 to this bit clears the CAP3 register value. + */ +#define UTICK_CAPCLR_CAPCLR3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR3_SHIFT)) & UTICK_CAPCLR_CAPCLR3_MASK) +/*! @} */ + +/*! @name CAP - Capture register . */ +/*! @{ */ +#define UTICK_CAP_CAP_VALUE_MASK (0x7FFFFFFFU) +#define UTICK_CAP_CAP_VALUE_SHIFT (0U) +/*! CAP_VALUE - Capture value for the related capture event (UTICK_CAPn. Note: the value is 1 lower + * than the actual value of the Micro-tick Timer at the moment of the capture event. + */ +#define UTICK_CAP_CAP_VALUE(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAP_CAP_VALUE_SHIFT)) & UTICK_CAP_CAP_VALUE_MASK) +#define UTICK_CAP_VALID_MASK (0x80000000U) +#define UTICK_CAP_VALID_SHIFT (31U) +/*! VALID - Capture Valid. When 1, a value has been captured based on a transition of the related + * UTICK_CAPn pin. Cleared by writing to the related bit in the CAPCLR register. + */ +#define UTICK_CAP_VALID(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAP_VALID_SHIFT)) & UTICK_CAP_VALID_MASK) +/*! @} */ + +/* The count of UTICK_CAP */ +#define UTICK_CAP_COUNT (4U) + + +/*! + * @} + */ /* end of group UTICK_Register_Masks */ + + +/* UTICK - Peripheral instance base addresses */ +/** Peripheral UTICK0 base address */ +#define UTICK0_BASE (0x4000E000u) +/** Peripheral UTICK0 base pointer */ +#define UTICK0 ((UTICK_Type *)UTICK0_BASE) +/** Array initializer of UTICK peripheral base addresses */ +#define UTICK_BASE_ADDRS { UTICK0_BASE } +/** Array initializer of UTICK peripheral base pointers */ +#define UTICK_BASE_PTRS { UTICK0 } +/** Interrupt vectors for the UTICK peripheral type */ +#define UTICK_IRQS { UTICK0_IRQn } + +/*! + * @} + */ /* end of group UTICK_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- WWDT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WWDT_Peripheral_Access_Layer WWDT Peripheral Access Layer + * @{ + */ + +/** WWDT - Register Layout Typedef */ +typedef struct { + __IO uint32_t MOD; /**< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer., offset: 0x0 */ + __IO uint32_t TC; /**< Watchdog timer constant register. This 24-bit register determines the time-out value., offset: 0x4 */ + __O uint32_t FEED; /**< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in TC., offset: 0x8 */ + __I uint32_t TV; /**< Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer., offset: 0xC */ + uint8_t RESERVED_0[4]; + __IO uint32_t WARNINT; /**< Watchdog Warning Interrupt compare value., offset: 0x14 */ + __IO uint32_t WINDOW; /**< Watchdog Window compare value., offset: 0x18 */ +} WWDT_Type; + +/* ---------------------------------------------------------------------------- + -- WWDT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WWDT_Register_Masks WWDT Register Masks + * @{ + */ + +/*! @name MOD - Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */ +/*! @{ */ +#define WWDT_MOD_WDEN_MASK (0x1U) +#define WWDT_MOD_WDEN_SHIFT (0U) +/*! WDEN - Watchdog enable bit. Once this bit is set to one and a watchdog feed is performed, the + * watchdog timer will run permanently. + * 0b0..Stop. The watchdog timer is stopped. + * 0b1..Run. The watchdog timer is running. + */ +#define WWDT_MOD_WDEN(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDEN_SHIFT)) & WWDT_MOD_WDEN_MASK) +#define WWDT_MOD_WDRESET_MASK (0x2U) +#define WWDT_MOD_WDRESET_SHIFT (1U) +/*! WDRESET - Watchdog reset enable bit. Once this bit has been written with a 1 it cannot be re-written with a 0. + * 0b0..Interrupt. A watchdog time-out will not cause a chip reset. + * 0b1..Reset. A watchdog time-out will cause a chip reset. + */ +#define WWDT_MOD_WDRESET(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDRESET_SHIFT)) & WWDT_MOD_WDRESET_MASK) +#define WWDT_MOD_WDTOF_MASK (0x4U) +#define WWDT_MOD_WDTOF_SHIFT (2U) +/*! WDTOF - Watchdog time-out flag. Set when the watchdog timer times out, by a feed error, or by + * events associated with WDPROTECT. Cleared by software writing a 0 to this bit position. Causes a + * chip reset if WDRESET = 1. + */ +#define WWDT_MOD_WDTOF(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDTOF_SHIFT)) & WWDT_MOD_WDTOF_MASK) +#define WWDT_MOD_WDINT_MASK (0x8U) +#define WWDT_MOD_WDINT_SHIFT (3U) +/*! WDINT - Warning interrupt flag. Set when the timer is at or below the value in WDWARNINT. + * Cleared by software writing a 1 to this bit position. Note that this bit cannot be cleared while the + * WARNINT value is equal to the value of the TV register. This can occur if the value of + * WARNINT is 0 and the WDRESET bit is 0 when TV decrements to 0. + */ +#define WWDT_MOD_WDINT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDINT_SHIFT)) & WWDT_MOD_WDINT_MASK) +#define WWDT_MOD_WDPROTECT_MASK (0x10U) +#define WWDT_MOD_WDPROTECT_SHIFT (4U) +/*! WDPROTECT - Watchdog update mode. This bit can be set once by software and is only cleared by a reset. + * 0b0..Flexible. The watchdog time-out value (TC) can be changed at any time. + * 0b1..Threshold. The watchdog time-out value (TC) can be changed only after the counter is below the value of WDWARNINT and WDWINDOW. + */ +#define WWDT_MOD_WDPROTECT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDPROTECT_SHIFT)) & WWDT_MOD_WDPROTECT_MASK) +#define WWDT_MOD_LOCK_MASK (0x20U) +#define WWDT_MOD_LOCK_SHIFT (5U) +/*! LOCK - Once this bit is set to one and a watchdog feed is performed, disabling or powering down + * the watchdog oscillator is prevented by hardware. This bit can be set once by software and is + * only cleared by any reset. + */ +#define WWDT_MOD_LOCK(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_LOCK_SHIFT)) & WWDT_MOD_LOCK_MASK) +/*! @} */ + +/*! @name TC - Watchdog timer constant register. This 24-bit register determines the time-out value. */ +/*! @{ */ +#define WWDT_TC_COUNT_MASK (0xFFFFFFU) +#define WWDT_TC_COUNT_SHIFT (0U) +/*! COUNT - Watchdog time-out value. + */ +#define WWDT_TC_COUNT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_TC_COUNT_SHIFT)) & WWDT_TC_COUNT_MASK) +/*! @} */ + +/*! @name FEED - Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in TC. */ +/*! @{ */ +#define WWDT_FEED_FEED_MASK (0xFFU) +#define WWDT_FEED_FEED_SHIFT (0U) +/*! FEED - Feed value should be 0xAA followed by 0x55. + */ +#define WWDT_FEED_FEED(x) (((uint32_t)(((uint32_t)(x)) << WWDT_FEED_FEED_SHIFT)) & WWDT_FEED_FEED_MASK) +/*! @} */ + +/*! @name TV - Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer. */ +/*! @{ */ +#define WWDT_TV_COUNT_MASK (0xFFFFFFU) +#define WWDT_TV_COUNT_SHIFT (0U) +/*! COUNT - Counter timer value. + */ +#define WWDT_TV_COUNT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_TV_COUNT_SHIFT)) & WWDT_TV_COUNT_MASK) +/*! @} */ + +/*! @name WARNINT - Watchdog Warning Interrupt compare value. */ +/*! @{ */ +#define WWDT_WARNINT_WARNINT_MASK (0x3FFU) +#define WWDT_WARNINT_WARNINT_SHIFT (0U) +/*! WARNINT - Watchdog warning interrupt compare value. + */ +#define WWDT_WARNINT_WARNINT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_WARNINT_WARNINT_SHIFT)) & WWDT_WARNINT_WARNINT_MASK) +/*! @} */ + +/*! @name WINDOW - Watchdog Window compare value. */ +/*! @{ */ +#define WWDT_WINDOW_WINDOW_MASK (0xFFFFFFU) +#define WWDT_WINDOW_WINDOW_SHIFT (0U) +/*! WINDOW - Watchdog window value. + */ +#define WWDT_WINDOW_WINDOW(x) (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group WWDT_Register_Masks */ + + +/* WWDT - Peripheral instance base addresses */ +/** Peripheral WWDT base address */ +#define WWDT_BASE (0x4000C000u) +/** Peripheral WWDT base pointer */ +#define WWDT ((WWDT_Type *)WWDT_BASE) +/** Array initializer of WWDT peripheral base addresses */ +#define WWDT_BASE_ADDRS { WWDT_BASE } +/** Array initializer of WWDT peripheral base pointers */ +#define WWDT_BASE_PTRS { WWDT } +/** Interrupt vectors for the WWDT peripheral type */ +#define WWDT_IRQS { WDT_BOD_IRQn } + +/*! + * @} + */ /* end of group WWDT_Peripheral_Access_Layer */ + + +/* +** End of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop + #else + #pragma pop + #endif +#elif defined(__GNUC__) + /* leave anonymous unions enabled */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=default +#else + #error Not supported compiler type +#endif + +/*! + * @} + */ /* end of group Peripheral_access_layer */ + + +/* ---------------------------------------------------------------------------- + -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + * @{ + */ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang system_header + #endif +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma system_include +#endif + +/** + * @brief Mask and left-shift a bit field value for use in a register bit range. + * @param field Name of the register bit field. + * @param value Value of the bit field. + * @return Masked and shifted value. + */ +#define NXP_VAL2FLD(field, value) (((value) << (field ## _SHIFT)) & (field ## _MASK)) +/** + * @brief Mask and right-shift a register value to extract a bit field value. + * @param field Name of the register bit field. + * @param value Value of the register. + * @return Masked and shifted bit field value. + */ +#define NXP_FLD2VAL(field, value) (((value) & (field ## _MASK)) >> (field ## _SHIFT)) + +/*! + * @} + */ /* end of group Bit_Field_Generic_Macros */ + + +/* ---------------------------------------------------------------------------- + -- SDK Compatibility + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDK_Compatibility_Symbols SDK Compatibility + * @{ + */ + +/* No SDK compatibility issues. */ + +/*! + * @} + */ /* end of group SDK_Compatibility_Symbols */ + + +#endif /* _LPC54114_CM4_H_ */ + diff --git a/device/LPC54114_cm4_features.h b/device/LPC54114_cm4_features.h new file mode 100644 index 0000000..42ef5ab --- /dev/null +++ b/device/LPC54114_cm4_features.h @@ -0,0 +1,255 @@ +/* +** ################################################################### +** Version: rev. 1.0, 2016-05-09 +** Build: b190225 +** +** Abstract: +** Chip specific module features. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-05-09) +** Initial version. +** +** ################################################################### +*/ + +#ifndef _LPC54114_cm4_FEATURES_H_ +#define _LPC54114_cm4_FEATURES_H_ + +/* SOC module features */ + +/* @brief ADC availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC_COUNT (1) +/* @brief ASYNC_SYSCON availability on the SoC. */ +#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (1) +/* @brief CRC availability on the SoC. */ +#define FSL_FEATURE_SOC_CRC_COUNT (1) +/* @brief CTIMER availability on the SoC. */ +#define FSL_FEATURE_SOC_CTIMER_COUNT (5) +/* @brief DMA availability on the SoC. */ +#define FSL_FEATURE_SOC_DMA_COUNT (1) +/* @brief DMIC availability on the SoC. */ +#define FSL_FEATURE_SOC_DMIC_COUNT (1) +/* @brief FLEXCOMM availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (8) +/* @brief GINT availability on the SoC. */ +#define FSL_FEATURE_SOC_GINT_COUNT (2) +/* @brief GPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_GPIO_COUNT (1) +/* @brief I2C availability on the SoC. */ +#define FSL_FEATURE_SOC_I2C_COUNT (8) +/* @brief I2S availability on the SoC. */ +#define FSL_FEATURE_SOC_I2S_COUNT (2) +/* @brief INPUTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1) +/* @brief IOCON availability on the SoC. */ +#define FSL_FEATURE_SOC_IOCON_COUNT (1) +/* @brief MAILBOX availability on the SoC. */ +#define FSL_FEATURE_SOC_MAILBOX_COUNT (1) +/* @brief MRT availability on the SoC. */ +#define FSL_FEATURE_SOC_MRT_COUNT (1) +/* @brief PINT availability on the SoC. */ +#define FSL_FEATURE_SOC_PINT_COUNT (1) +/* @brief RTC availability on the SoC. */ +#define FSL_FEATURE_SOC_RTC_COUNT (1) +/* @brief SCT availability on the SoC. */ +#define FSL_FEATURE_SOC_SCT_COUNT (1) +/* @brief SPI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPI_COUNT (8) +/* @brief SPIFI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPIFI_COUNT (1) +/* @brief SYSCON availability on the SoC. */ +#define FSL_FEATURE_SOC_SYSCON_COUNT (1) +/* @brief USART availability on the SoC. */ +#define FSL_FEATURE_SOC_USART_COUNT (8) +/* @brief USB availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_COUNT (1) +/* @brief UTICK availability on the SoC. */ +#define FSL_FEATURE_SOC_UTICK_COUNT (1) +/* @brief WWDT availability on the SoC. */ +#define FSL_FEATURE_SOC_WWDT_COUNT (1) + +/* ADC module features */ + +/* @brief Do not has input select (register INSEL). */ +#define FSL_FEATURE_ADC_HAS_NO_INSEL (0) +/* @brief Has ASYNMODE bitfile in CTRL reigster. */ +#define FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE (1) +/* @brief Has ASYNMODE bitfile in CTRL reigster. */ +#define FSL_FEATURE_ADC_HAS_CTRL_RESOL (1) +/* @brief Has ASYNMODE bitfile in CTRL reigster. */ +#define FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL (1) +/* @brief Has ASYNMODE bitfile in CTRL reigster. */ +#define FSL_FEATURE_ADC_HAS_CTRL_TSAMP (1) +/* @brief Has ASYNMODE bitfile in CTRL reigster. */ +#define FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE (0) +/* @brief Has ASYNMODE bitfile in CTRL reigster. */ +#define FSL_FEATURE_ADC_HAS_CTRL_CALMODE (0) +/* @brief Has startup register. */ +#define FSL_FEATURE_ADC_HAS_STARTUP_REG (1) +/* @brief Has ADTrim register */ +#define FSL_FEATURE_ADC_HAS_TRIM_REG (0) +/* @brief Has Calibration register. */ +#define FSL_FEATURE_ADC_HAS_CALIB_REG (1) + +/* DMA module features */ + +/* @brief Number of channels */ +#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (20) +/* @brief Align size of DMA descriptor */ +#define FSL_FEATURE_DMA_DESCRIPTOR_ALIGN_SIZE (512) +/* @brief DMA head link descriptor table align size */ +#define FSL_FEATURE_DMA_LINK_DESCRIPTOR_ALIGN_SIZE (16U) + +/* FLEXCOMM module features */ + +/* @brief FLEXCOMM0 USART INDEX 0 */ +#define FSL_FEATURE_FLEXCOMM0_USART_INDEX (0) +/* @brief FLEXCOMM0 SPI INDEX 0 */ +#define FSL_FEATURE_FLEXCOMM0_SPI_INDEX (0) +/* @brief FLEXCOMM0 I2C INDEX 0 */ +#define FSL_FEATURE_FLEXCOMM0_I2C_INDEX (0) +/* @brief FLEXCOMM1 USART INDEX 1 */ +#define FSL_FEATURE_FLEXCOMM1_USART_INDEX (1) +/* @brief FLEXCOMM1 SPI INDEX 1 */ +#define FSL_FEATURE_FLEXCOMM1_SPI_INDEX (1) +/* @brief FLEXCOMM1 I2C INDEX 1 */ +#define FSL_FEATURE_FLEXCOMM1_I2C_INDEX (1) +/* @brief FLEXCOMM2 USART INDEX 2 */ +#define FSL_FEATURE_FLEXCOMM2_USART_INDEX (2) +/* @brief FLEXCOMM2 SPI INDEX 2 */ +#define FSL_FEATURE_FLEXCOMM2_SPI_INDEX (2) +/* @brief FLEXCOMM2 I2C INDEX 2 */ +#define FSL_FEATURE_FLEXCOMM2_I2C_INDEX (2) +/* @brief FLEXCOMM3 USART INDEX 3 */ +#define FSL_FEATURE_FLEXCOMM3_USART_INDEX (3) +/* @brief FLEXCOMM3 SPI INDEX 3 */ +#define FSL_FEATURE_FLEXCOMM3_SPI_INDEX (3) +/* @brief FLEXCOMM3 I2C INDEX 3 */ +#define FSL_FEATURE_FLEXCOMM3_I2C_INDEX (3) +/* @brief FLEXCOMM4 USART INDEX 4 */ +#define FSL_FEATURE_FLEXCOMM4_USART_INDEX (4) +/* @brief FLEXCOMM4 SPI INDEX 4 */ +#define FSL_FEATURE_FLEXCOMM4_SPI_INDEX (4) +/* @brief FLEXCOMM4 I2C INDEX 4 */ +#define FSL_FEATURE_FLEXCOMM4_I2C_INDEX (4) +/* @brief FLEXCOMM5 USART INDEX 5 */ +#define FSL_FEATURE_FLEXCOMM5_USART_INDEX (5) +/* @brief FLEXCOMM5 SPI INDEX 5 */ +#define FSL_FEATURE_FLEXCOMM5_SPI_INDEX (5) +/* @brief FLEXCOMM5 I2C INDEX 5 */ +#define FSL_FEATURE_FLEXCOMM5_I2C_INDEX (5) +/* @brief FLEXCOMM6 USART INDEX 6 */ +#define FSL_FEATURE_FLEXCOMM6_USART_INDEX (6) +/* @brief FLEXCOMM6 SPI INDEX 6 */ +#define FSL_FEATURE_FLEXCOMM6_SPI_INDEX (6) +/* @brief FLEXCOMM6 I2C INDEX 6 */ +#define FSL_FEATURE_FLEXCOMM6_I2C_INDEX (6) +/* @brief FLEXCOMM7 I2S INDEX 0 */ +#define FSL_FEATURE_FLEXCOMM6_I2S_INDEX (0) +/* @brief FLEXCOMM7 USART INDEX 7 */ +#define FSL_FEATURE_FLEXCOMM7_USART_INDEX (7) +/* @brief FLEXCOMM7 SPI INDEX 7 */ +#define FSL_FEATURE_FLEXCOMM7_SPI_INDEX (7) +/* @brief FLEXCOMM7 I2C INDEX 7 */ +#define FSL_FEATURE_FLEXCOMM7_I2C_INDEX (7) +/* @brief FLEXCOMM7 I2S INDEX 1 */ +#define FSL_FEATURE_FLEXCOMM7_I2S_INDEX (1) +/* @brief I2S has DMIC interconnection */ +#define FSL_FEATURE_FLEXCOMM_INSTANCE_I2S_HAS_DMIC_INTERCONNECTIONn(x) \ + (((x) == FLEXCOMM0) ? (0) : \ + (((x) == FLEXCOMM1) ? (0) : \ + (((x) == FLEXCOMM2) ? (0) : \ + (((x) == FLEXCOMM3) ? (0) : \ + (((x) == FLEXCOMM4) ? (0) : \ + (((x) == FLEXCOMM5) ? (0) : \ + (((x) == FLEXCOMM6) ? (0) : \ + (((x) == FLEXCOMM7) ? (1) : (-1))))))))) + +/* I2S module features */ + +/* @brief I2S support dual channel transfer */ +#define FSL_FEATURE_I2S_SUPPORT_SECONDARY_CHANNEL (0) +/* @brief I2S has DMIC interconnection */ +#define FSL_FEATURE_FLEXCOMM_I2S_HAS_DMIC_INTERCONNECTION (1) + +/* MAILBOX module features */ + +/* @brief Mailbox side for current core */ +#define FSL_FEATURE_MAILBOX_SIDE_A (1) +/* @brief Mailbox has no reset control */ +#define FSL_FEATURE_MAILBOX_HAS_NO_RESET (1) + +/* MRT module features */ + +/* @brief number of channels. */ +#define FSL_FEATURE_MRT_NUMBER_OF_CHANNELS (4) + +/* interrupt module features */ + +/* @brief Lowest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14) +/* @brief Highest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MAX (105) + +/* PINT module features */ + +/* @brief Number of connected outputs */ +#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (8) + +/* RTC module features */ + +/* @brief RTC has no reset control */ +#define FSL_FEATURE_RTC_HAS_NO_RESET (1) + +/* SCT module features */ + +/* @brief Number of events */ +#define FSL_FEATURE_SCT_NUMBER_OF_EVENTS (10) +/* @brief Number of states */ +#define FSL_FEATURE_SCT_NUMBER_OF_STATES (10) +/* @brief Number of match capture */ +#define FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE (10) +/* @brief Number of outputs */ +#define FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS (8) + +/* SYSCON module features */ + +/* @brief Pointer to ROM IAP entry functions */ +#define FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION (0x03000205) +/* @brief Flash page size in bytes */ +#define FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES (256) +/* @brief Flash sector size in bytes */ +#define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (32768) +/* @brief Flash size in bytes */ +#define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (262144) +/* @brief IAP has Flash read & write function */ +#define FSL_FEATURE_IAP_HAS_FLASH_FUNCTION (1) +/* @brief IAP has read Flash signature function */ +#define FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ (1) +/* @brief IAP has read extended Flash signature function */ +#define FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ (0) + +/* SysTick module features */ + +/* @brief Systick has external reference clock. */ +#define FSL_FEATURE_SYSTICK_HAS_EXT_REF (0) +/* @brief Systick external reference clock is core clock divided by this value. */ +#define FSL_FEATURE_SYSTICK_EXT_REF_CORE_DIV (0) + +/* USB module features */ + +/* @brief Number of the endpoint in USB FS */ +#define FSL_FEATURE_USB_EP_NUM (5) + +#endif /* _LPC54114_cm4_FEATURES_H_ */ + diff --git a/device/fsl_device_registers.h b/device/fsl_device_registers.h new file mode 100644 index 0000000..15d028b --- /dev/null +++ b/device/fsl_device_registers.h @@ -0,0 +1,43 @@ +/* + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __FSL_DEVICE_REGISTERS_H__ +#define __FSL_DEVICE_REGISTERS_H__ + +/* + * Include the cpu specific register header files. + * + * The CPU macro should be declared in the project or makefile. + */ +#if (defined(CPU_LPC54114J256BD64_cm4) || defined(CPU_LPC54114J256UK49_cm4)) + +#define LPC54114_cm4_SERIES + +/* CMSIS-style register definitions */ +#include "LPC54114_cm4.h" +/* CPU specific feature definitions */ +#include "LPC54114_cm4_features.h" + +#elif (defined(CPU_LPC54114J256BD64_cm0plus) || defined(CPU_LPC54114J256UK49_cm0plus)) + +#define LPC54114_cm0plus_SERIES + +/* CMSIS-style register definitions */ +#include "LPC54114_cm0plus.h" +/* CPU specific feature definitions */ +#include "LPC54114_cm0plus_features.h" + +#else + #error "No valid CPU defined!" +#endif + +#endif /* __FSL_DEVICE_REGISTERS_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/device/system_LPC54114_cm4.c b/device/system_LPC54114_cm4.c new file mode 100644 index 0000000..0db4288 --- /dev/null +++ b/device/system_LPC54114_cm4.c @@ -0,0 +1,355 @@ +/* +** ################################################################### +** Processors: LPC54114J256BD64_cm4 +** LPC54114J256UK49_cm4 +** +** Compilers: Keil ARM C/C++ Compiler +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5411x User manual Rev. 1.1 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b180802 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54114_cm4 + * @version 1.0 + * @date 2016-04-29 + * @brief Device specific configuration file for LPC54114_cm4 (implementation + * file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#include +#include "fsl_device_registers.h" + +#define NVALMAX (0x100U) +#define PVALMAX (0x20U) +#define MVALMAX (0x8000U) +#define PLL_SSCG0_MDEC_VAL_P (0U) /* MDEC is in bits 16 downto 0 */ +#define PLL_SSCG0_MDEC_VAL_M (0x1FFFFUL << PLL_SSCG0_MDEC_VAL_P) /* NDEC is in bits 9 downto 0 */ +#define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */ +#define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P) +#define PLL_PDEC_VAL_P (0U) /* PDEC is in bits 6:0 */ +#define PLL_PDEC_VAL_M (0x3FFUL << PLL_PDEC_VAL_P) + +/* ---------------------------------------------------------------------------- + -- Core clock + ---------------------------------------------------------------------------- */ + +uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK; + +static const uint8_t wdtFreqLookup[32] = {0, 8, 12, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41, + 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 59, 60, 61}; + +static uint32_t GetWdtOscFreq(void) +{ + uint8_t freq_sel; + uint32_t div_sel; + div_sel = ((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_DIVSEL_MASK) + 1U) << 1U; + freq_sel = + wdtFreqLookup[((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_FREQSEL_MASK) >> SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)]; + return ((uint32_t)freq_sel * 50000U) / div_sel; +} + +/* Find decoded N value for raw NDEC value */ +static uint32_t pllDecodeN(uint32_t NDEC) +{ + uint32_t n, x, i; + + /* Find NDec */ + switch (NDEC) + { + case 0xFFFU: + n = 0U; + break; + case 0x302U: + n = 1U; + break; + case 0x202U: + n = 2U; + break; + default: + x = 0x080U; + n = 0xFFFFFFFFU; + for (i = NVALMAX; i >= 3U; i--) + { + x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU); + if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC) + { + /* Decoded value of NDEC */ + n = i; + } + } + break; + } + return n; +} + +/* Find decoded P value for raw PDEC value */ +static uint32_t pllDecodeP(uint32_t PDEC) +{ + uint32_t p, x, i; + /* Find PDec */ + switch (PDEC) + { + case 0xFFU: + p = 0U; + break; + case 0x62U: + p = 1U; + break; + case 0x42U: + p = 2U; + break; + default: + x = 0x10U; + p = 0xFFFFFFFFU; + for (i = PVALMAX; i >= 3U; i--) + { + x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU); + if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC) + { + /* Decoded value of PDEC */ + p = i; + } + } + break; + } + return p; +} + +/* Find decoded M value for raw MDEC value */ +static uint32_t pllDecodeM(uint32_t MDEC) +{ + uint32_t m, i, x; + + /* Find MDec */ + switch (MDEC) + { + case 0xFFFFFU: + m = 0U; + break; + case 0x18003U: + m = 1U; + break; + case 0x10003U: + m = 2U; + break; + default: + x = 0x04000U; + m = 0xFFFFFFFFU; + for (i = MVALMAX; i >= 3U; i--) + { + x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU); + if ((x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P)) == MDEC) + { + /* Decoded value of MDEC */ + m = i; + } + } + break; + } + return m; +} + +/* Get predivider (N) from PLL NDEC setting */ +static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg) +{ + uint32_t preDiv = 1U; + + /* Direct input is not used? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTI_MASK) == 0U) + { + /* Decode NDEC value to get (N) pre divider */ + preDiv = pllDecodeN(nDecReg & 0x3FFU); + if (preDiv == 0U) + { + preDiv = 1U; + } + } + /* Adjusted by 1, directi is used to bypass */ + return preDiv; +} + +/* Get postdivider (P) from PLL PDEC setting */ +static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg) +{ + uint32_t postDiv = 1U; + + /* Direct input is not used? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U) + { + /* Decode PDEC value to get (P) post divider */ + postDiv = 2U * pllDecodeP(pDecReg & 0x7FU); + if (postDiv == 0U) + { + postDiv = 2U; + } + } + /* Adjusted by 1, directo is used to bypass */ + return postDiv; +} + +/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */ +static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg) +{ + uint32_t mMult = 1U; + + /* Decode MDEC value to get (M) multiplier */ + mMult = pllDecodeM(mDecReg & 0x1FFFFU); + /* Extra multiply by 2 needed? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK) == 0U) + { + mMult = mMult << 1U; + } + if (mMult == 0U) + { + mMult = 1U; + } + return mMult; +} + +/* ---------------------------------------------------------------------------- + -- SystemInit() + ---------------------------------------------------------------------------- */ + +void SystemInit(void) +{ +#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) || (defined(__VFP_FP__) && !defined(__SOFTFP__)) + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access */ +#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ + extern void *__Vectors; + SCB->VTOR = (uint32_t)&__Vectors; +/* Optionally enable RAM banks that may be off by default at reset */ +#if !defined(DONT_ENABLE_DISABLED_RAMBANKS) + SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL_SRAM2_MASK; +#endif + + SystemInitHook(); +} + +/* ---------------------------------------------------------------------------- + -- SystemCoreClockUpdate() + ---------------------------------------------------------------------------- */ + +void SystemCoreClockUpdate(void) +{ + uint32_t clkRate = 0U; + uint32_t prediv, postdiv; + uint32_t bypassccodiv2; + uint64_t workRate; + + switch (SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) + { + case 0x00U: /* MAINCLKSELA clock (main_clk_a)*/ + switch (SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK) + { + case 0x00U: /* FRO 12 MHz (fro_12m) */ + clkRate = CLK_FRO_12MHZ; + break; + case 0x01U: /* CLKIN (clk_in) */ + clkRate = CLK_CLK_IN; + break; + case 0x02U: /* Watchdog oscillator (wdt_clk) */ + clkRate = GetWdtOscFreq(); + break; + default: /* = 0x03 = FRO 96 or 48 MHz (fro_hf) */ + if ((SYSCON->FROCTRL & SYSCON_FROCTRL_SEL_MASK) == SYSCON_FROCTRL_SEL_MASK) + { + clkRate = CLK_FRO_96MHZ; + } + else + { + clkRate = CLK_FRO_48MHZ; + } + break; + } + break; + case 0x02U: /* System PLL clock (pll_clk)*/ + switch (SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) + { + case 0x00U: /* FRO 12 MHz (fro_12m) */ + clkRate = CLK_FRO_12MHZ; + break; + case 0x01U: /* CLKIN (clk_in) */ + clkRate = CLK_CLK_IN; + break; + case 0x02U: /* Watchdog oscillator (wdt_clk) */ + clkRate = GetWdtOscFreq(); + break; + case 0x03U: /* RTC oscillator 32 kHz output (32k_clk) */ + clkRate = CLK_RTC_32K_CLK; + break; + default: + clkRate = 0U; + break; + } + if ((SYSCON->SYSPLLCTRL & SYSCON_SYSPLLCTRL_BYPASS_MASK) == 0U) + { + /* PLL is not in bypass mode, get pre-divider, post-divider, and M divider */ + prediv = findPllPreDiv(SYSCON->SYSPLLCTRL, SYSCON->SYSPLLNDEC); + postdiv = findPllPostDiv(SYSCON->SYSPLLCTRL, SYSCON->SYSPLLPDEC); + /* Adjust input clock */ + clkRate = clkRate / prediv; + /* If using the SS, use the multiplier */ + if ((SYSCON->SYSPLLSSCTRL0 & SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK) == SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK) + { + /* MDEC used for rate */ + workRate = (uint64_t)clkRate * (uint64_t)findPllMMult(SYSCON->SYSPLLCTRL, SYSCON->SYSPLLSSCTRL0); + } + else + { + /* SS multipler used for rate */ + workRate = 0UL; + /* Adjust by fractional */ + bypassccodiv2 = (uint32_t)((SYSCON->SYSPLLCTRL & SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK) >> + SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT); + workRate = (2UL - bypassccodiv2) * (uint64_t)(clkRate) * + ((SYSCON->SYSPLLSSCTRL1 & 0x7FFFFUL) >> 11UL); + } + clkRate = (uint32_t)workRate / postdiv; + } + break; + case 0x03U: /* RTC oscillator 32 kHz output (32k_clk) */ + clkRate = CLK_RTC_32K_CLK; + break; + default: + clkRate = 0U; + break; + } + SystemCoreClock = (uint32_t)(clkRate / ((uint64_t)(SYSCON->AHBCLKDIV & 0xFFUL) + 1UL)); +} + +/* ---------------------------------------------------------------------------- + -- SystemInitHook() + ---------------------------------------------------------------------------- */ + +__attribute__((weak)) void SystemInitHook(void) +{ + /* Void implementation of the weak function. */ +} diff --git a/device/system_LPC54114_cm4.h b/device/system_LPC54114_cm4.h new file mode 100644 index 0000000..1113260 --- /dev/null +++ b/device/system_LPC54114_cm4.h @@ -0,0 +1,109 @@ +/* +** ################################################################### +** Processors: LPC54114J256BD64_cm4 +** LPC54114J256UK49_cm4 +** +** Compilers: Keil ARM C/C++ Compiler +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5411x User manual Rev. 1.1 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b180802 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54114_cm4 + * @version 1.0 + * @date 2016-04-29 + * @brief Device specific configuration file for LPC54114_cm4 (header file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#ifndef _SYSTEM_LPC54114_cm4_H_ +#define _SYSTEM_LPC54114_cm4_H_ /**< Symbol preventing repeated inclusion */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#define DEFAULT_SYSTEM_CLOCK 12000000u /* Default System clock value */ +#define CLK_RTC_32K_CLK 32768u /* RTC oscillator 32 kHz output (32k_clk */ +#define CLK_FRO_12MHZ 12000000u /* FRO 12 MHz (fro_12m) */ +#define CLK_FRO_48MHZ 48000000u /* FRO 48 MHz (fro_48m) */ +#define CLK_FRO_96MHZ 96000000u /* FRO 96 MHz (fro_96m) */ +#define CLK_CLK_IN 0u /* Default CLK_IN pin clock */ + + +/** + * @brief System clock frequency (core clock) + * + * The system clock frequency supplied to the SysTick timer and the processor + * core clock. This variable can be used by the user application to setup the + * SysTick timer or configure other parameters. It may also be used by debugger to + * query the frequency of the debug timer or configure the trace clock speed + * SystemCoreClock is initialized with a correct predefined value. + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Setup the microcontroller system. + * + * Typically this function configures the oscillator (PLL) that is part of the + * microcontroller device. For systems with variable clock speed it also updates + * the variable SystemCoreClock. SystemInit is called from startup_device file. + */ +void SystemInit (void); + +/** + * @brief Updates the SystemCoreClock variable. + * + * It must be called whenever the core clock is changed during program + * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates + * the current core clock. + */ +void SystemCoreClockUpdate (void); + +/** + * @brief SystemInit function hook. + * + * This weak function allows to call specific initialization code during the + * SystemInit() execution.This can be used when an application specific code needs + * to be called as close to the reset entry as possible (for example the Multicore + * Manager MCMGR_EarlyInit() function call). + * NOTE: No global r/w variables can be used in this hook function because the + * initialization of these variables happens after this function. + */ +void SystemInitHook (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_LPC54114_cm4_H_ */ diff --git a/doc/readme.txt b/doc/readme.txt new file mode 100644 index 0000000..a4f6294 --- /dev/null +++ b/doc/readme.txt @@ -0,0 +1,55 @@ +Overview +======== +The spi_polling_board2board_master example shows how to use spi driver as master to do board to board transfer with +polling: + +In this example, one spi instance as master and another spi instance on othereboard as slave. Master sends a piece of +data to slave, and receive a piece of data from slave. This example checks if the data received from slave is correct. + +Toolchain supported +=================== +- IAR embedded Workbench 8.50.9 +- Keil MDK 5.33 +- MCUXpresso 11.3.0 +- GCC ARM Embedded 9.3.1 + +Hardware requirements +===================== +- Micro USB cable +- LPCXpresso54114 board +- Personal Computer + +Board settings +============== +Populate jumper JP6. +Connect SPI master on board to SPI slave on other board +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Master - SPI3 +Pin Name Board Location +MISO J4 pin 3 +MOSI J4 pin 2 +SCK J4 pin 4 +PCS2 J4 pin 7 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Prepare the Demo +================ +1. Connect a micro USB cable between the PC host and the CMSIS DAP USB port (J7) on the board +2. Open a serial terminal with the following settings (See Appendix A in Getting started guide for description how to determine serial port number): + - 115200 baud rate + - 8 data bits + - No parity + - One stop bit + - No flow control +3. Download the program to the target board. +4. Reset the SoC and run the project. + +Running the demo +================ +When the demo runs successfully, the log would be seen on the CMSIS DAP terminal like: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Master Start...! + +Succeed! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/fsl_adc.c b/drivers/fsl_adc.c new file mode 100644 index 0000000..593c5cc --- /dev/null +++ b/drivers/fsl_adc.c @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_adc.h" +#include "fsl_clock.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.lpc_adc" +#endif + +static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#define FREQUENCY_1MHZ (1000000UL) + +static uint32_t ADC_GetInstance(ADC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++) + { + if (s_adcBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_adcBases)); + + return instance; +} + +/*! + * brief Initialize the ADC module. + * + * param base ADC peripheral base address. + * param config Pointer to configuration structure, see to #adc_config_t. + */ +void ADC_Init(ADC_Type *base, const adc_config_t *config) +{ + assert(config != NULL); + + uint32_t tmp32 = 0U; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable clock. */ + CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Disable the interrupts. */ + base->INTEN = 0U; /* Quickly disable all the interrupts. */ + + /* Configure the ADC block. */ + tmp32 = ADC_CTRL_CLKDIV(config->clockDividerNumber); + +#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE + /* Async or Sync clock mode. */ + switch (config->clockMode) + { + case kADC_ClockAsynchronousMode: + tmp32 |= ADC_CTRL_ASYNMODE_MASK; + break; + default: /* kADC_ClockSynchronousMode */ + break; + } +#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */ + +#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL + /* Resolution. */ + + tmp32 |= ADC_CTRL_RESOL(config->resolution); +#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL + /* Bypass calibration. */ + if (config->enableBypassCalibration) + { + tmp32 |= ADC_CTRL_BYPASSCAL_MASK; + } +#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */ + +#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP +/* Sample time clock count. */ +#if (defined(FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) && FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) + if (config->clockMode == kADC_ClockAsynchronousMode) + { +#endif /* FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL */ + tmp32 |= ADC_CTRL_TSAMP(config->sampleTimeNumber); +#if (defined(FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) && FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) + } +#endif /* FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL */ +#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE + if (config->enableLowPowerMode) + { + tmp32 |= ADC_CTRL_LPWRMODE_MASK; + } +#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */ + + base->CTRL = tmp32; + +#if defined(FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN) && FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN + base->GPADC_CTRL0 |= ADC_GPADC_CTRL0_LDO_POWER_EN_MASK; + if (config->clockMode == kADC_ClockSynchronousMode) + { + base->GPADC_CTRL0 |= ADC_GPADC_CTRL0_PASS_ENABLE(config->sampleTimeNumber); + } + SDK_DelayAtLeastUs(300, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); +#endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN */ + +#if defined(FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL) && FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL + tmp32 = *(uint32_t *)FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL; + if (tmp32 & FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL_VALID) + { + base->GPADC_CTRL1 = (tmp32 >> 1); + } +#if !(defined(FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT) && FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT) + base->STARTUP = ADC_STARTUP_ADC_ENA_MASK; /* Set the ADC Start bit */ +#endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL */ +#endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL */ + +#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG + base->TRM &= ~ADC_TRM_VRANGE_MASK; + base->TRM |= ADC_TRM_VRANGE(config->voltageRange); +#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */ +} + +/*! + * brief Gets an available pre-defined settings for initial configuration. + * + * This function initializes the initial configuration structure with an available settings. The default values are: + * code + * config->clockMode = kADC_ClockSynchronousMode; + * config->clockDividerNumber = 0U; + * config->resolution = kADC_Resolution12bit; + * config->enableBypassCalibration = false; + * config->sampleTimeNumber = 0U; + * endcode + * param config Pointer to configuration structure. + */ +void ADC_GetDefaultConfig(adc_config_t *config) +{ + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + +#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE + + config->clockMode = kADC_ClockSynchronousMode; +#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */ + + config->clockDividerNumber = 0U; +#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL + config->resolution = kADC_Resolution12bit; +#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL + config->enableBypassCalibration = false; +#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP + config->sampleTimeNumber = 0U; +#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE + config->enableLowPowerMode = false; +#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */ +#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG + config->voltageRange = kADC_HighVoltageRange; +#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */ +} + +/*! + * brief Deinitialize the ADC module. + * + * param base ADC peripheral base address. + */ +void ADC_Deinit(ADC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the clock. */ + CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) +#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG +/*! + * brief Do the hardware self-calibration. + * deprecated Do not use this function. It has been superceded by @ref ADC_DoOffsetCalibration. + * + * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D + * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation. + * + * param base ADC peripheral base address. + * retval true Calibration succeed. + * retval false Calibration failed. + */ +bool ADC_DoSelfCalibration(ADC_Type *base) +{ + uint32_t frequency = 0U; + uint32_t delayUs = 0U; + bool ret = true; + + /* Enable the converter. */ + /* This bit can only be set 1 by software. It is cleared automatically whenever the ADC is powered down. + This bit should be set after at least 10 ms after the ADC is powered on. */ + base->STARTUP = ADC_STARTUP_ADC_ENA_MASK; + SDK_DelayAtLeastUs(1U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + if (0UL == (base->STARTUP & ADC_STARTUP_ADC_ENA_MASK)) + { + ret = false; /* ADC is not powered up. */ + } + + /* Get the ADC clock frequency in synchronous mode. */ + frequency = CLOCK_GetFreq(kCLOCK_BusClk) / (((base->CTRL & ADC_CTRL_CLKDIV_MASK) >> ADC_CTRL_CLKDIV_SHIFT) + 1UL); +#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) && FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE + /* Get the ADC clock frequency in asynchronous mode. */ + if (ADC_CTRL_ASYNMODE_MASK == (base->CTRL & ADC_CTRL_ASYNMODE_MASK)) + { + frequency = CLOCK_GetAdcClkFreq(); + } +#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */ + assert(0U != frequency); + + /* If not in by-pass mode, do the calibration. */ + if ((ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK)) && + (0U == (base->CTRL & ADC_CTRL_BYPASSCAL_MASK))) + { + /* A calibration cycle requires approximately 81 ADC clocks to complete. */ + delayUs = (120UL * FREQUENCY_1MHZ) / frequency + 1UL; + /* Calibration is needed, do it now. */ + base->CALIB = ADC_CALIB_CALIB_MASK; + SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + if (ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK)) + { + ret = false; /* Calibration timeout. */ + } + } + + /* A “dummy” conversion cycle requires approximately 6 ADC clocks */ + delayUs = (10UL * FREQUENCY_1MHZ) / frequency + 1UL; + base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK; + SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + if (ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK)) + { + ret = false; + } + + return ret; +} + +/*! + * brief Do the hardware offset-calibration. + * + * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D + * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation. + * + * param base ADC peripheral base address. + * param frequency The clock frequency that ADC operates at. + * retval true Calibration succeed. + * retval false Calibration failed. + */ +bool ADC_DoOffsetCalibration(ADC_Type *base, uint32_t frequency) +{ + assert(frequency != 0U); + + uint32_t delayUs = 0U; + uint32_t tmp32 = base->CTRL; + /* The maximum ADC clock frequency during calibration is 30 MHz. */ + const uint32_t maxCalibrationFrequency = 30000000UL; + bool ret = true; + + /* Enable the converter. */ + /* This bit should be set after at least 10 us after the ADC is powered on. */ + SDK_DelayAtLeastUs(10U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + /* This bit can only be set 1 by software. It is cleared automatically whenever the ADC is powered down. */ + base->STARTUP = ADC_STARTUP_ADC_ENA_MASK; + + if (0UL == (base->STARTUP & ADC_STARTUP_ADC_ENA_MASK)) + { + ret = false; /* ADC is not powered up. */ + } + + if (frequency >= maxCalibrationFrequency) + { + /* The divider should round up to ensure the frequency be lower than the maximum frequency. */ + uint8_t divider = (frequency % maxCalibrationFrequency > 0UL) ? + (uint8_t)(frequency / maxCalibrationFrequency + 1UL) : + (uint8_t)(frequency / maxCalibrationFrequency); + /* Divide the system clock to yield an ADC clock of about 30 MHz. */ + base->CTRL &= ~ADC_CTRL_CLKDIV_MASK; + base->CTRL |= ADC_CTRL_CLKDIV(divider - 1UL); + frequency /= divider; + } + + /* Launch the calibration cycle or "dummy" conversions. */ + if (ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK)) + { + /* Calibration is required, do it now. */ + base->CALIB = ADC_CALIB_CALIB_MASK; + + /* A calibration cycle requires approximately 81 ADC clocks to complete. */ + delayUs = (120UL * FREQUENCY_1MHZ) / frequency + 1UL; + SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + if (ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK)) + { + base->CTRL = tmp32; + ret = false; /* Calibration timeout. */ + } + } + else + { + /* If a calibration is not performed, launch the conversion cycle. */ + base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK; + + /* A “dummy” conversion cycle requires approximately 6 ADC clocks */ + delayUs = (10UL * FREQUENCY_1MHZ) / frequency + 1UL; + SDK_DelayAtLeastUs(delayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + if (ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK)) + { + base->CTRL = tmp32; + ret = false; /* Initialization timeout. */ + } + } + + base->CTRL = tmp32; + return ret; +} +#else +/*! + * brief Do the hardware self-calibration. + * + * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D + * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation. + * + * param base ADC peripheral base address. + * param frequency The clock frequency that ADC operates at. + * retval true Calibration succeed. + * retval false Calibration failed. + */ +bool ADC_DoSelfCalibration(ADC_Type *base, uint32_t frequency) +{ + assert(frequency != 0U); + + uint32_t tmp32 = 0U; + + /* Store the current contents of the ADC CTRL register. */ + tmp32 = base->CTRL; + + /* Divide the system clock to yield an ADC clock of about 500 kHz. */ + base->CTRL &= ~ADC_CTRL_CLKDIV_MASK; + base->CTRL |= ADC_CTRL_CLKDIV((frequency / 500000U) - 1U); + + /* Clear the LPWR bit. */ + base->CTRL &= ~ADC_CTRL_LPWRMODE_MASK; + + /* Start ADC self-calibration. */ + base->CTRL |= ADC_CTRL_CALMODE_MASK; + /* Delay for 300 uSec @ 500KHz ADC clock */ + SDK_DelayAtLeastUs(300U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + + /* Check the completion of calibration. */ + if (ADC_CTRL_CALMODE_MASK == (base->CTRL & ADC_CTRL_CALMODE_MASK)) + { + /* Restore the contents of the ADC CTRL register. */ + base->CTRL = tmp32; + return false; /* Calibration timeout. */ + } + /* Restore the contents of the ADC CTRL register. */ + base->CTRL = tmp32; + + return true; +} +#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */ +#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC*/ + +/*! + * brief Configure the conversion sequence A. + * + * param base ADC peripheral base address. + * param config Pointer to configuration structure, see to #adc_conv_seq_config_t. + */ +void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config) +{ + assert(config != NULL); + + uint32_t tmp32; + + tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */ + | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */ + + /* Polarity for tirgger signal. */ + switch (config->triggerPolarity) + { + case kADC_TriggerPolarityPositiveEdge: + tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK; + break; + default: /* kADC_TriggerPolarityNegativeEdge */ + break; + } + + /* Bypass the clock Sync. */ + if (config->enableSyncBypass) + { + tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK; + } + + /* Interrupt point. */ + switch (config->interruptMode) + { + case kADC_InterruptForEachSequence: + tmp32 |= ADC_SEQ_CTRL_MODE_MASK; + break; + default: /* kADC_InterruptForEachConversion */ + break; + } + + /* One trigger for a conversion, or for a sequence. */ + if (config->enableSingleStep) + { + tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK; + } + + base->SEQ_CTRL[0] = tmp32; +} + +#if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ) +/*! + * brief Configure the conversion sequence B. + * + * param base ADC peripheral base address. + * param config Pointer to configuration structure, see to #adc_conv_seq_config_t. + */ +void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config) +{ + assert(config != NULL); + + uint32_t tmp32; + + tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */ + | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */ + + /* Polarity for tirgger signal. */ + switch (config->triggerPolarity) + { + case kADC_TriggerPolarityPositiveEdge: + tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK; + break; + default: /* kADC_TriggerPolarityPositiveEdge */ + break; + } + + /* Bypass the clock Sync. */ + if (config->enableSyncBypass) + { + tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK; + } + + /* Interrupt point. */ + switch (config->interruptMode) + { + case kADC_InterruptForEachSequence: + tmp32 |= ADC_SEQ_CTRL_MODE_MASK; + break; + default: /* kADC_InterruptForEachConversion */ + break; + } + + /* One trigger for a conversion, or for a sequence. */ + if (config->enableSingleStep) + { + tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK; + } + + base->SEQ_CTRL[1] = tmp32; +} +#endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */ + +/*! + * brief Get the global ADC conversion infomation of sequence A. + * + * param base ADC peripheral base address. + * param info Pointer to information structure, see to #adc_result_info_t; + * retval true The conversion result is ready. + * retval false The conversion result is not ready yet. + */ +bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info) +{ + assert(info != NULL); + + uint32_t tmp32 = base->SEQ_GDAT[0]; /* Read to clear the status. */ + bool ret = true; + + if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32)) + { + ret = false; + } + + info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT; + info->thresholdCompareStatus = (adc_threshold_compare_status_t)(uint32_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >> + ADC_SEQ_GDAT_THCMPRANGE_SHIFT); + info->thresholdCorssingStatus = (adc_threshold_crossing_status_t)(uint32_t)( + (tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT); + info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT; + info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK); + + return ret; +} + +#if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ) +/*! + * brief Get the global ADC conversion infomation of sequence B. + * + * param base ADC peripheral base address. + * param info Pointer to information structure, see to #adc_result_info_t; + * retval true The conversion result is ready. + * retval false The conversion result is not ready yet. + */ +bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info) +{ + assert(info != NULL); + + uint32_t tmp32 = base->SEQ_GDAT[1]; /* Read to clear the status. */ + bool ret = true; + + if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32)) + { + ret = false; + } + + info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT; + info->thresholdCompareStatus = (adc_threshold_compare_status_t)(uint32_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >> + ADC_SEQ_GDAT_THCMPRANGE_SHIFT); + info->thresholdCorssingStatus = (adc_threshold_crossing_status_t)(uint32_t)( + (tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT); + info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT; + info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK); + + return ret; +} +#endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */ + +/*! + * brief Get the channel's ADC conversion completed under each conversion sequence. + * + * param base ADC peripheral base address. + * param channel The indicated channel number. + * param info Pointer to information structure, see to #adc_result_info_t; + * retval true The conversion result is ready. + * retval false The conversion result is not ready yet. + */ +bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info) +{ + assert(info != NULL); + assert(channel < ADC_DAT_COUNT); + + uint32_t tmp32 = base->DAT[channel]; /* Read to clear the status. */ + bool ret = true; + + if (0U == (ADC_DAT_DATAVALID_MASK & tmp32)) + { + ret = false; + } + + info->result = (tmp32 & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT; +#if (defined(FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) && FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) + switch ((base->CTRL & ADC_CTRL_RESOL_MASK) >> ADC_CTRL_RESOL_SHIFT) + { + case kADC_Resolution10bit: + info->result >>= kADC_Resolution10bitInfoResultShift; + break; + case kADC_Resolution8bit: + info->result >>= kADC_Resolution8bitInfoResultShift; + break; + case kADC_Resolution6bit: + info->result >>= kADC_Resolution6bitInfoResultShift; + break; + default: + assert(false); + break; + } +#endif + info->thresholdCompareStatus = + (adc_threshold_compare_status_t)(uint32_t)((tmp32 & ADC_DAT_THCMPRANGE_MASK) >> ADC_DAT_THCMPRANGE_SHIFT); + info->thresholdCorssingStatus = + (adc_threshold_crossing_status_t)(uint32_t)((tmp32 & ADC_DAT_THCMPCROSS_MASK) >> ADC_DAT_THCMPCROSS_SHIFT); + info->channelNumber = (tmp32 & ADC_DAT_CHANNEL_MASK) >> ADC_DAT_CHANNEL_SHIFT; + info->overrunFlag = ((tmp32 & ADC_DAT_OVERRUN_MASK) == ADC_DAT_OVERRUN_MASK); + + return ret; +} +#if defined(FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) && (FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) +void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable) +{ + if (enable) + { + SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE_MASK; + ASYNC_SYSCON->TEMPSENSORCTRL = kADC_NoOffsetAdded; + ASYNC_SYSCON->TEMPSENSORCTRL |= ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK; + base->GPADC_CTRL0 |= (kADC_ADCInUnityGainMode | kADC_Impedance87kOhm); + } + else + { + /* if the temperature sensor is not turned on then ASYNCAPBCTRL is likely to be zero + * and accessing the registers will cause a memory access error. Test for this */ + if (SYSCON->ASYNCAPBCTRL == SYSCON_ASYNCAPBCTRL_ENABLE_MASK) + { + ASYNC_SYSCON->TEMPSENSORCTRL = 0x0; + base->GPADC_CTRL0 &= ~(kADC_ADCInUnityGainMode | kADC_Impedance87kOhm); + base->GPADC_CTRL0 |= kADC_Impedance55kOhm; + } + } +} +#endif diff --git a/drivers/fsl_adc.h b/drivers/fsl_adc.h new file mode 100644 index 0000000..82af67d --- /dev/null +++ b/drivers/fsl_adc.h @@ -0,0 +1,775 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __FSL_ADC_H__ +#define __FSL_ADC_H__ + +#include "fsl_common.h" + +/*! + * @addtogroup lpc_adc + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief ADC driver version 2.5.0. */ +#define FSL_ADC_DRIVER_VERSION (MAKE_VERSION(2, 5, 0)) +/*@}*/ + +/*! + * @brief Flags + */ + +enum _adc_status_flags +{ + kADC_ThresholdCompareFlagOnChn0 = 1U << 0U, /*!< Threshold comparison event on Channel 0. */ + kADC_ThresholdCompareFlagOnChn1 = 1U << 1U, /*!< Threshold comparison event on Channel 1. */ + kADC_ThresholdCompareFlagOnChn2 = 1U << 2U, /*!< Threshold comparison event on Channel 2. */ + kADC_ThresholdCompareFlagOnChn3 = 1U << 3U, /*!< Threshold comparison event on Channel 3. */ + kADC_ThresholdCompareFlagOnChn4 = 1U << 4U, /*!< Threshold comparison event on Channel 4. */ + kADC_ThresholdCompareFlagOnChn5 = 1U << 5U, /*!< Threshold comparison event on Channel 5. */ + kADC_ThresholdCompareFlagOnChn6 = 1U << 6U, /*!< Threshold comparison event on Channel 6. */ + kADC_ThresholdCompareFlagOnChn7 = 1U << 7U, /*!< Threshold comparison event on Channel 7. */ + kADC_ThresholdCompareFlagOnChn8 = 1U << 8U, /*!< Threshold comparison event on Channel 8. */ + kADC_ThresholdCompareFlagOnChn9 = 1U << 9U, /*!< Threshold comparison event on Channel 9. */ + kADC_ThresholdCompareFlagOnChn10 = 1U << 10U, /*!< Threshold comparison event on Channel 10. */ + kADC_ThresholdCompareFlagOnChn11 = 1U << 11U, /*!< Threshold comparison event on Channel 11. */ + kADC_OverrunFlagForChn0 = + 1U << 12U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 0. */ + kADC_OverrunFlagForChn1 = + 1U << 13U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 1. */ + kADC_OverrunFlagForChn2 = + 1U << 14U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 2. */ + kADC_OverrunFlagForChn3 = + 1U << 15U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 3. */ + kADC_OverrunFlagForChn4 = + 1U << 16U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 4. */ + kADC_OverrunFlagForChn5 = + 1U << 17U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 5. */ + kADC_OverrunFlagForChn6 = + 1U << 18U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 6. */ + kADC_OverrunFlagForChn7 = + 1U << 19U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 7. */ + kADC_OverrunFlagForChn8 = + 1U << 20U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 8. */ + kADC_OverrunFlagForChn9 = + 1U << 21U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 9. */ + kADC_OverrunFlagForChn10 = + 1U << 22U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 10. */ + kADC_OverrunFlagForChn11 = + 1U << 23U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 11. */ + kADC_GlobalOverrunFlagForSeqA = 1U << 24U, /*!< Mirror the glabal OVERRUN status flag for conversion sequence A. */ + kADC_GlobalOverrunFlagForSeqB = 1U << 25U, /*!< Mirror the global OVERRUN status flag for conversion sequence B. */ + kADC_ConvSeqAInterruptFlag = 1U << 28U, /*!< Sequence A interrupt/DMA trigger. */ + kADC_ConvSeqBInterruptFlag = 1U << 29U, /*!< Sequence B interrupt/DMA trigger. */ + kADC_ThresholdCompareInterruptFlag = 1U << 30U, /*!< Threshold comparision interrupt flag. */ + kADC_OverrunInterruptFlag = (int)(1U << 31U), /*!< Overrun interrupt flag. */ +}; + +/*! + * @brief Interrupts + * @note Not all the interrupt options are listed here + */ +enum _adc_interrupt_enable +{ + kADC_ConvSeqAInterruptEnable = ADC_INTEN_SEQA_INTEN_MASK, /*!< Enable interrupt upon completion of each individual + conversion in sequence A, or entire sequence. */ +#if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ) + kADC_ConvSeqBInterruptEnable = ADC_INTEN_SEQB_INTEN_MASK, /*!< Enable interrupt upon completion of each individual + conversion in sequence B, or entire sequence. */ +#endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */ + kADC_OverrunInterruptEnable = ADC_INTEN_OVR_INTEN_MASK, /*!< Enable the detection of an overrun condition on any of + the channel data registers will cause an overrun + interrupt/DMA trigger. */ +}; + +#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE +/*! + * @brief Define selection of clock mode. + */ +typedef enum _adc_clock_mode +{ + kADC_ClockSynchronousMode = + 0U, /*!< The ADC clock would be derived from the system clock based on "clockDividerNumber". */ + kADC_ClockAsynchronousMode = 1U, /*!< The ADC clock would be based on the SYSCON block's divider. */ +} adc_clock_mode_t; +#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */ + +#if defined(FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) && (FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) +/*! + * @brief Define selection of resolution. + */ +typedef enum _adc_resolution +{ + kADC_Resolution6bit = 3U, + /*!< 6-bit resolution. */ /* This is a HW issue that the ADC resolution enum configure not align with HW implement, + ES2 chip already fixed the issue, Currently, update ADC enum define as a workaround */ + kADC_Resolution8bit = 2U, /*!< 8-bit resolution. */ + kADC_Resolution10bit = 1U, /*!< 10-bit resolution. */ + kADC_Resolution12bit = 0U, /*!< 12-bit resolution. */ +} adc_resolution_t; +#elif defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL +/*! + * @brief Define selection of resolution. + */ +typedef enum _adc_resolution +{ + kADC_Resolution6bit = 0U, /*!< 6-bit resolution. */ + kADC_Resolution8bit = 1U, /*!< 8-bit resolution. */ + kADC_Resolution10bit = 2U, /*!< 10-bit resolution. */ + kADC_Resolution12bit = 3U, /*!< 12-bit resolution. */ +} adc_resolution_t; +#endif + +#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG +/*! + * @brief Definfe range of the analog supply voltage VDDA. + */ +typedef enum _adc_voltage_range +{ + kADC_HighVoltageRange = 0U, /* High voltage. VDD = 2.7 V to 3.6 V. */ + kADC_LowVoltageRange = 1U, /* Low voltage. VDD = 2.4 V to 2.7 V. */ +} adc_vdda_range_t; +#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */ + +/*! + * @brief Define selection of polarity of selected input trigger for conversion sequence. + */ +typedef enum _adc_trigger_polarity +{ + kADC_TriggerPolarityNegativeEdge = 0U, /*!< A negative edge launches the conversion sequence on the trigger(s). */ + kADC_TriggerPolarityPositiveEdge = 1U, /*!< A positive edge launches the conversion sequence on the trigger(s). */ +} adc_trigger_polarity_t; + +/*! + * @brief Define selection of conversion sequence's priority. + */ +typedef enum _adc_priority +{ + kADC_PriorityLow = 0U, /*!< This sequence would be preempted when another sequence is started. */ + kADC_PriorityHigh = 1U, /*!< This sequence would preempt other sequence even when it is started. */ +} adc_priority_t; + +/*! + * @brief Define selection of conversion sequence's interrupt. + */ +typedef enum _adc_seq_interrupt_mode +{ + kADC_InterruptForEachConversion = 0U, /*!< The sequence interrupt/DMA trigger will be set at the end of each + individual ADC conversion inside this conversion sequence. */ + kADC_InterruptForEachSequence = 1U, /*!< The sequence interrupt/DMA trigger will be set when the entire set of + this sequence conversions completes. */ +} adc_seq_interrupt_mode_t; + +/*! + * @brief Define status of threshold compare result. + */ +typedef enum _adc_threshold_compare_status +{ + kADC_ThresholdCompareInRange = 0U, /*!< LOW threshold <= conversion value <= HIGH threshold. */ + kADC_ThresholdCompareBelowRange = 1U, /*!< conversion value < LOW threshold. */ + kADC_ThresholdCompareAboveRange = 2U, /*!< conversion value > HIGH threshold. */ +} adc_threshold_compare_status_t; + +/*! + * @brief Define status of threshold crossing detection result. + */ +typedef enum _adc_threshold_crossing_status +{ + /* The conversion on this channel had the same relationship (above or below) to the threshold value established by + * the designated LOW threshold value as did the previous conversion on this channel. */ + kADC_ThresholdCrossingNoDetected = 0U, /*!< No threshold Crossing detected. */ + + /* Indicates that a threshold crossing in the downward direction has occurred - i.e. the previous sample on this + * channel was above the threshold value established by the designated LOW threshold value and the current sample is + * below that threshold. */ + kADC_ThresholdCrossingDownward = 2U, /*!< Downward Threshold Crossing detected. */ + + /* Indicates that a thre shold crossing in the upward direction has occurred - i.e. the previous sample on this + * channel was below the threshold value established by the designated LOW threshold value and the current sample is + * above that threshold. */ + kADC_ThresholdCrossingUpward = 3U, /*!< Upward Threshold Crossing Detected. */ +} adc_threshold_crossing_status_t; + +/*! + * @brief Define interrupt mode for threshold compare event. + */ +typedef enum _adc_threshold_interrupt_mode +{ + kADC_ThresholdInterruptDisabled = 0U, /*!< Threshold comparison interrupt is disabled. */ + kADC_ThresholdInterruptOnOutside = 1U, /*!< Threshold comparison interrupt is enabled on outside threshold. */ + kADC_ThresholdInterruptOnCrossing = 2U, /*!< Threshold comparison interrupt is enabled on crossing threshold. */ +} adc_threshold_interrupt_mode_t; + +/*! + * @brief Define the info result mode of different resolution. + */ +typedef enum _adc_inforesultshift +{ + kADC_Resolution12bitInfoResultShift = 0U, /*!< Info result shift of Resolution12bit. */ + kADC_Resolution10bitInfoResultShift = 2U, /*!< Info result shift of Resolution10bit. */ + kADC_Resolution8bitInfoResultShift = 4U, /*!< Info result shift of Resolution8bit. */ + kADC_Resolution6bitInfoResultShift = 6U, /*!< Info result shift of Resolution6bit. */ +} adc_inforesult_t; + +/*! + * @brief Define common modes for Temerature sensor. + */ +typedef enum _adc_tempsensor_common_mode +{ + kADC_HighNegativeOffsetAdded = 0x0U, /*!< Temperature sensor common mode: high negative offset added. */ + kADC_IntermediateNegativeOffsetAdded = + 0x4U, /*!< Temperature sensor common mode: intermediate negative offset added. */ + kADC_NoOffsetAdded = 0x8U, /*!< Temperature sensor common mode: no offset added. */ + kADC_LowPositiveOffsetAdded = 0xcU, /*!< Temperature sensor common mode: low positive offset added. */ +} adc_tempsensor_common_mode_t; + +/*! + * @brief Define source impedance modes for GPADC control. + */ +typedef enum _adc_second_control +{ + kADC_Impedance621Ohm = 0x1U << 9U, /*!< Extand ADC sampling time according to source impedance 1: 0.621 kOhm. */ + kADC_Impedance55kOhm = + 0x14U << 9U, /*!< Extand ADC sampling time according to source impedance 20 (default): 55 kOhm. */ + kADC_Impedance87kOhm = 0x1fU << 9U, /*!< Extand ADC sampling time according to source impedance 31: 87 kOhm. */ + + kADC_NormalFunctionalMode = 0x0U << 14U, /*!< TEST mode: Normal functional mode. */ + kADC_MultiplexeTestMode = 0x1U << 14U, /*!< TEST mode: Multiplexer test mode. */ + kADC_ADCInUnityGainMode = 0x2U << 14U, /*!< TEST mode: ADC in unity gain mode. */ +} adc_second_control_t; + +/*! + * @brief Define structure for configuring the block. + */ +typedef struct _adc_config +{ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE + adc_clock_mode_t clockMode; /*!< Select the clock mode for ADC converter. */ +#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */ + uint32_t clockDividerNumber; /*!< This field is only available when using kADC_ClockSynchronousMode for "clockMode" + field. The divider would be plused by 1 based on the value in this field. The + available range is in 8 bits. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL + adc_resolution_t resolution; /*!< Select the conversion bits. */ +#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL + bool enableBypassCalibration; /*!< By default, a calibration cycle must be performed each time the chip is + powered-up. Re-calibration may be warranted periodically - especially if + operating conditions have changed. To enable this option would avoid the need to + calibrate if offset error is not a concern in the application. */ +#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP + uint32_t sampleTimeNumber; /*!< By default, with value as "0U", the sample period would be 2.5 ADC clocks. Then, + to plus the "sampleTimeNumber" value here. The available value range is in 3 bits.*/ +#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */ +#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE + bool enableLowPowerMode; /*!< If disable low-power mode, ADC remains activated even when no conversions are + requested. + If enable low-power mode, The ADC is automatically powered-down when no conversions are + taking place. */ +#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */ +#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG + adc_vdda_range_t + voltageRange; /*!< Configure the ADC for the appropriate operating range of the analog supply voltage VDDA. + Failure to set the area correctly causes the ADC to return incorrect conversion results. */ +#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */ +} adc_config_t; + +/*! + * @brief Define structure for configuring conversion sequence. + */ +typedef struct _adc_conv_seq_config +{ + uint32_t channelMask; /*!< Selects which one or more of the ADC channels will be sampled and converted when this + sequence is launched. The masked channels would be involved in current conversion + sequence, beginning with the lowest-order. The available range is in 12-bit. */ + uint32_t triggerMask; /*!< Selects which one or more of the available hardware trigger sources will cause this + conversion sequence to be initiated. The available range is 6-bit.*/ + adc_trigger_polarity_t triggerPolarity; /*!< Select the trigger to launch conversion sequence. */ + bool enableSyncBypass; /*!< To enable this feature allows the hardware trigger input to bypass synchronization + flip-flop stages and therefore shorten the time between the trigger input signal and the + start of a conversion. */ + bool enableSingleStep; /*!< When enabling this feature, a trigger will launch a single conversion on the next + channel in the sequence instead of the default response of launching an entire sequence + of conversions. */ + adc_seq_interrupt_mode_t interruptMode; /*!< Select the interrpt/DMA trigger mode. */ +} adc_conv_seq_config_t; + +/*! + * @brief Define structure of keeping conversion result information. + */ +typedef struct _adc_result_info +{ + uint32_t result; /*!< Keep the conversion data value. */ + adc_threshold_compare_status_t thresholdCompareStatus; /*!< Keep the threshold compare status. */ + adc_threshold_crossing_status_t thresholdCorssingStatus; /*!< Keep the threshold crossing status. */ + uint32_t channelNumber; /*!< Keep the channel number for this conversion. */ + bool overrunFlag; /*!< Keep the status whether the conversion is overrun or not. */ + /* The data available flag would be returned by the reading result API. */ +} adc_result_info_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name Initialization and Deinitialization + * @{ + */ + +/*! + * @brief Initialize the ADC module. + * + * @param base ADC peripheral base address. + * @param config Pointer to configuration structure, see to #adc_config_t. + */ +void ADC_Init(ADC_Type *base, const adc_config_t *config); + +/*! + * @brief Deinitialize the ADC module. + * + * @param base ADC peripheral base address. + */ +void ADC_Deinit(ADC_Type *base); + +/*! + * @brief Gets an available pre-defined settings for initial configuration. + * + * This function initializes the initial configuration structure with an available settings. The default values are: + * @code + * config->clockMode = kADC_ClockSynchronousMode; + * config->clockDividerNumber = 0U; + * config->resolution = kADC_Resolution12bit; + * config->enableBypassCalibration = false; + * config->sampleTimeNumber = 0U; + * @endcode + * @param config Pointer to configuration structure. + */ +void ADC_GetDefaultConfig(adc_config_t *config); + +#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) +#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG +/*! + * @brief Do the hardware self-calibration. + * @deprecated Do not use this function. It has been superceded by @ref ADC_DoOffsetCalibration. + * + * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D + * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation. + * + * @param base ADC peripheral base address. + * @retval true Calibration succeed. + * @retval false Calibration failed. + */ +bool ADC_DoSelfCalibration(ADC_Type *base); + +/*! + * @brief Do the hardware offset-calibration. + * + * To calibrate the ADC, set the ADC clock to no more then 30 MHz. In order to achieve the specified ADC accuracy, the + * A/D converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation. + * + * @param base ADC peripheral base address. + * @param frequency The clock frequency that ADC operates at. + * @retval true Calibration succeed. + * @retval false Calibration failed. + */ +bool ADC_DoOffsetCalibration(ADC_Type *base, uint32_t frequency); +#else +/*! + * @brief Do the hardware self-calibration. + * + * To calibrate the ADC, set the ADC clock to 500 kHz. In order to achieve the specified ADC accuracy, the A/D + * converter must be recalibrated, at a minimum, following every chip reset before initiating normal ADC operation. + * + * @param base ADC peripheral base address. + * @param frequency The clock frequency that ADC operates at. + * @retval true Calibration succeed. + * @retval false Calibration failed. + */ +bool ADC_DoSelfCalibration(ADC_Type *base, uint32_t frequency); +#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */ +#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */ + +#if !(defined(FSL_FEATURE_ADC_HAS_NO_INSEL) && FSL_FEATURE_ADC_HAS_NO_INSEL) +/*! + * @brief Enable the internal temperature sensor measurement. + * + * When enabling the internal temperature sensor measurement, the channel 0 would be connected to internal sensor + * instead of external pin. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable the feature or not. + */ +#if defined(FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) && (FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) +void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable); +#else +static inline void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable) +{ + if (enable) + { + base->INSEL = (base->INSEL & ~ADC_INSEL_SEL_MASK) | ADC_INSEL_SEL(0x3); + } + else + { + base->INSEL = (base->INSEL & ~ADC_INSEL_SEL_MASK) | ADC_INSEL_SEL(0); + } +} +#endif /* FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP. */ +#endif /* FSL_FEATURE_ADC_HAS_NO_INSEL. */ + /* @} */ + +/*! + * @name Control conversion sequence A. + * @{ + */ + +/*! + * @brief Enable the conversion sequence A. + * + * In order to avoid spuriously triggering the sequence, the trigger to conversion sequence should be ready before the + * sequence is ready. when the sequence is disabled, the trigger would be ignored. Also, it is suggested to disable the + * sequence during changing the sequence's setting. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable the feature or not. + */ +static inline void ADC_EnableConvSeqA(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_SEQ_ENA_MASK; + } + else + { + base->SEQ_CTRL[0] &= ~ADC_SEQ_CTRL_SEQ_ENA_MASK; + } +} + +/*! + * @brief Configure the conversion sequence A. + * + * @param base ADC peripheral base address. + * @param config Pointer to configuration structure, see to #adc_conv_seq_config_t. + */ +void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config); + +/*! + * @brief Do trigger the sequence's conversion by software. + * + * @param base ADC peripheral base address. + */ +static inline void ADC_DoSoftwareTriggerConvSeqA(ADC_Type *base) +{ + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_START_MASK; +} + +/*! + * @brief Enable the burst conversion of sequence A. + * + * Enable the burst mode would cause the conversion sequence to be cntinuously cycled through. Other triggers would be + * ignored while this mode is enabled. Repeated conversions could be halted by disabling this mode. And the sequence + * currently in process will be completed before cnversions are terminated. + * Note that a new sequence could begin just before the burst mode is disabled. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable this feature. + */ +static inline void ADC_EnableConvSeqABurstMode(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_BURST_MASK; + } + else + { + base->SEQ_CTRL[0] &= ~ADC_SEQ_CTRL_BURST_MASK; + } +} + +#if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ) +/*! + * @brief Set the high priority for conversion sequence A. + * + * @param base ADC peripheral bass address. + */ +static inline void ADC_SetConvSeqAHighPriority(ADC_Type *base) +{ + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_LOWPRIO_MASK; +} +#endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */ + +/* @} */ + +#if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ) +/*! + * @name Control conversion sequence B. + * @{ + */ + +/*! + * @brief Enable the conversion sequence B. + * + * In order to avoid spuriously triggering the sequence, the trigger to conversion sequence should be ready before the + * sequence is ready. when the sequence is disabled, the trigger would be ignored. Also, it is suggested to disable the + * sequence during changing the sequence's setting. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable the feature or not. + */ +static inline void ADC_EnableConvSeqB(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[1] |= ADC_SEQ_CTRL_SEQ_ENA_MASK; + } + else + { + base->SEQ_CTRL[1] &= ~ADC_SEQ_CTRL_SEQ_ENA_MASK; + } +} + +/*! + * @brief Configure the conversion sequence B. + * + * @param base ADC peripheral base address. + * @param config Pointer to configuration structure, see to #adc_conv_seq_config_t. + */ +void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config); + +/*! + * @brief Do trigger the sequence's conversion by software. + * + * @param base ADC peripheral base address. + */ +static inline void ADC_DoSoftwareTriggerConvSeqB(ADC_Type *base) +{ + base->SEQ_CTRL[1] |= ADC_SEQ_CTRL_START_MASK; +} + +/*! + * @brief Enable the burst conversion of sequence B. + * + * Enable the burst mode would cause the conversion sequence to be continuously cycled through. Other triggers would be + * ignored while this mode is enabled. Repeated conversions could be halted by disabling this mode. And the sequence + * currently in process will be completed before cnversions are terminated. + * Note that a new sequence could begin just before the burst mode is disabled. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable this feature. + */ +static inline void ADC_EnableConvSeqBBurstMode(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[1] |= ADC_SEQ_CTRL_BURST_MASK; + } + else + { + base->SEQ_CTRL[1] &= ~ADC_SEQ_CTRL_BURST_MASK; + } +} + +/*! + * @brief Set the high priority for conversion sequence B. + * + * @param base ADC peripheral bass address. + */ +static inline void ADC_SetConvSeqBHighPriority(ADC_Type *base) +{ + base->SEQ_CTRL[0] &= ~ADC_SEQ_CTRL_LOWPRIO_MASK; +} + +/* @} */ +#endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */ + +/*! + * @name Data result. + * @{ + */ + +/*! + * @brief Get the global ADC conversion infomation of sequence A. + * + * @param base ADC peripheral base address. + * @param info Pointer to information structure, see to #adc_result_info_t; + * @retval true The conversion result is ready. + * @retval false The conversion result is not ready yet. + */ +bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info); + +#if !(defined(FSL_FEATURE_ADC_HAS_SINGLE_SEQ) && FSL_FEATURE_ADC_HAS_SINGLE_SEQ) +/*! + * @brief Get the global ADC conversion infomation of sequence B. + * + * @param base ADC peripheral base address. + * @param info Pointer to information structure, see to #adc_result_info_t; + * @retval true The conversion result is ready. + * @retval false The conversion result is not ready yet. + */ +bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info); +#endif /* FSL_FEATURE_ADC_HAS_SINGLE_SEQ */ + +/*! + * @brief Get the channel's ADC conversion completed under each conversion sequence. + * + * @param base ADC peripheral base address. + * @param channel The indicated channel number. + * @param info Pointer to information structure, see to #adc_result_info_t; + * @retval true The conversion result is ready. + * @retval false The conversion result is not ready yet. + */ +bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info); + +/* @} */ + +/*! + * @name Threshold function. + * @{ + */ + +/*! + * @brief Set the threshhold pair 0 with low and high value. + * + * @param base ADC peripheral base address. + * @param lowValue LOW threshold value. + * @param highValue HIGH threshold value. + */ +static inline void ADC_SetThresholdPair0(ADC_Type *base, uint32_t lowValue, uint32_t highValue) +{ + base->THR0_LOW = ADC_THR0_LOW_THRLOW(lowValue); + base->THR0_HIGH = ADC_THR0_HIGH_THRHIGH(highValue); +} + +/*! + * @brief Set the threshhold pair 1 with low and high value. + * + * @param base ADC peripheral base address. + * @param lowValue LOW threshold value. The available value is with 12-bit. + * @param highValue HIGH threshold value. The available value is with 12-bit. + */ +static inline void ADC_SetThresholdPair1(ADC_Type *base, uint32_t lowValue, uint32_t highValue) +{ + base->THR1_LOW = ADC_THR1_LOW_THRLOW(lowValue); + base->THR1_HIGH = ADC_THR1_HIGH_THRHIGH(highValue); +} + +/*! + * @brief Set given channels to apply the threshold pare 0. + * + * @param base ADC peripheral base address. + * @param channelMask Indicated channels' mask. + */ +static inline void ADC_SetChannelWithThresholdPair0(ADC_Type *base, uint32_t channelMask) +{ + base->CHAN_THRSEL &= ~(channelMask); +} + +/*! + * @brief Set given channels to apply the threshold pare 1. + * + * @param base ADC peripheral base address. + * @param channelMask Indicated channels' mask. + */ +static inline void ADC_SetChannelWithThresholdPair1(ADC_Type *base, uint32_t channelMask) +{ + base->CHAN_THRSEL |= channelMask; +} + +/* @} */ + +/*! + * @name Interrupts. + * @{ + */ + +/*! + * @brief Enable interrupts for conversion sequences. + * + * @param base ADC peripheral base address. + * @param mask Mask of interrupt mask value for global block except each channal, see to #_adc_interrupt_enable. + */ +static inline void ADC_EnableInterrupts(ADC_Type *base, uint32_t mask) +{ + base->INTEN |= (0x7UL & mask); +} + +/*! + * @brief Disable interrupts for conversion sequence. + * + * @param base ADC peripheral base address. + * @param mask Mask of interrupt mask value for global block except each channel, see to #_adc_interrupt_enable. + */ +static inline void ADC_DisableInterrupts(ADC_Type *base, uint32_t mask) +{ + base->INTEN &= ~(0x7UL & mask); +} + +/*! + * @brief Enable the interrupt of threshold compare event for each channel. + * + * @param base ADC peripheral base address. + * @param channel Channel number. + * @param mode Interrupt mode for threshold compare event, see to #adc_threshold_interrupt_mode_t. + */ +static inline void ADC_EnableThresholdCompareInterrupt(ADC_Type *base, + uint32_t channel, + adc_threshold_interrupt_mode_t mode) +{ + base->INTEN = (base->INTEN & ~(0x3UL << ((channel << 1UL) + 3UL))) | ((uint32_t)(mode) << ((channel << 1UL) + 3UL)); +} + +/* @} */ + +/*! + * @name Status. + * @{ + */ + +/*! + * @brief Get status flags of ADC module. + * + * @param base ADC peripheral base address. + * @return Mask of status flags of module, see to #_adc_status_flags. + */ +static inline uint32_t ADC_GetStatusFlags(ADC_Type *base) +{ + return base->FLAGS; +} + +/*! + * @brief Clear status flags of ADC module. + * + * @param base ADC peripheral base address. + * @param mask Mask of status flags of module, see to #_adc_status_flags. + */ +static inline void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask) +{ + base->FLAGS = mask; /* Write 1 to clear. */ +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/* @} */ + +#endif /* __FSL_ADC_H__ */ diff --git a/drivers/fsl_clock.c b/drivers/fsl_clock.c new file mode 100644 index 0000000..65b5cd6 --- /dev/null +++ b/drivers/fsl_clock.c @@ -0,0 +1,1777 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2019 , NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_clock.h" +#include "fsl_power.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.clock" +#endif +#define NVALMAX (0x100U) +#define PVALMAX (0x20U) +#define MVALMAX (0x8000U) + +#define PLL_MAX_N_DIV 0x100U + +#define INDEX_SECTOR_TRIM48 ((uint32_t *)0x01000444U) +#define INDEX_SECTOR_TRIM96 ((uint32_t *)0x01000430U) +/*-------------------------------------------------------------------------- +!!! If required these #defines can be moved to chip library file +----------------------------------------------------------------------------*/ + +#define PLL_SSCG0_MDEC_VAL_P (0U) /* MDEC is in bits 16 downto 0 */ +#define PLL_SSCG0_MDEC_VAL_M (0x1FFFFUL << PLL_SSCG0_MDEC_VAL_P) /* NDEC is in bits 9 downto 0 */ +#define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */ +#define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P) +#define PLL_PDEC_VAL_P (0U) /* PDEC is in bits 6:0 */ +#define PLL_PDEC_VAL_M (0x7FUL << PLL_PDEC_VAL_P) + +#define PLL_MIN_CCO_FREQ_MHZ (75000000U) +#define PLL_MAX_CCO_FREQ_MHZ (150000000U) +#define PLL_LOWER_IN_LIMIT (4000U) /*!< Minimum PLL input rate */ +#define PLL_MIN_IN_SSMODE (2000000U) +#define PLL_MAX_IN_SSMODE (4000000U) + +/* Middle of the range values for spread-spectrum */ +#define PLL_SSCG_MF_FREQ_VALUE 4U +#define PLL_SSCG_MC_COMP_VALUE 2U +#define PLL_SSCG_MR_DEPTH_VALUE 4U +#define PLL_SSCG_DITHER_VALUE 0U + +/* PLL NDEC reg */ +#define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M) +/* PLL PDEC reg */ +#define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M) +/* SSCG control0 */ +#define PLL_SSCG0_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_SSCG0_MDEC_VAL_P) & PLL_SSCG0_MDEC_VAL_M) + +/* SSCG control1 */ +#define PLL_SSCG1_MD_FRACT_P 0U +#define PLL_SSCG1_MD_INT_P 11U +#define PLL_SSCG1_MD_FRACT_M (0x7FFUL << PLL_SSCG1_MD_FRACT_P) +#define PLL_SSCG1_MD_INT_M (0xFFUL << PLL_SSCG1_MD_INT_P) + +#define PLL_SSCG1_MD_FRACT_SET(value) (((unsigned long)(value) << PLL_SSCG1_MD_FRACT_P) & PLL_SSCG1_MD_FRACT_M) +#define PLL_SSCG1_MD_INT_SET(value) (((unsigned long)(value) << PLL_SSCG1_MD_INT_P) & PLL_SSCG1_MD_INT_M) + +/* Saved value of PLL output rate, computed whenever needed to save run-time + computation on each call to retrive the PLL rate. */ +static uint32_t s_Pll_Freq; + +/* I2S mclk. */ +static uint32_t s_I2S_Mclk_Freq = 0U; + +/** External clock rate on the CLKIN pin in Hz. If not used, + set this to 0. Otherwise, set it to the exact rate in Hz this pin is + being driven at. */ +static const uint32_t s_Ext_Clk_Freq = 0U; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/* Find encoded NDEC value for raw N value, max N = NVALMAX */ +static uint32_t pllEncodeN(uint32_t N); +/* Find decoded N value for raw NDEC value */ +static uint32_t pllDecodeN(uint32_t NDEC); +/* Find encoded PDEC value for raw P value, max P = PVALMAX */ +static uint32_t pllEncodeP(uint32_t P); +/* Find decoded P value for raw PDEC value */ +static uint32_t pllDecodeP(uint32_t PDEC); +/* Find encoded MDEC value for raw M value, max M = MVALMAX */ +static uint32_t pllEncodeM(uint32_t M); +/* Find decoded M value for raw MDEC value */ +static uint32_t pllDecodeM(uint32_t MDEC); +/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */ +static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR); +/* Get predivider (N) from PLL NDEC setting */ +static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg); +/* Get postdivider (P) from PLL PDEC setting */ +static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg); +/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */ +static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg); +/* Get the greatest common divisor */ +static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n); +/* Set PLL output based on desired output rate */ +static pll_error_t CLOCK_GetPllConfig( + uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS); +/* Update local PLL rate variable */ +static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup); + +static const uint8_t wdtFreqLookup[32] = {0, 8, 12, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41, + 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 59, 60, 61}; +/******************************************************************************* + * Code + ******************************************************************************/ + +/** + * brief Configure the clock selection muxes. + * param connection : Clock to be configured. + * return Nothing + */ +void CLOCK_AttachClk(clock_attach_id_t connection) +{ + uint8_t mux; + uint8_t sel; + uint16_t item; + uint32_t tmp32 = (uint32_t)connection; + uint32_t i; + volatile uint32_t *pClkSel; + + pClkSel = &(SYSCON->MAINCLKSELA); + + if (kNONE_to_NONE != connection) + { + for (i = 0U; i < 2U; i++) + { + if (tmp32 == 0U) + { + break; + } + item = (uint16_t)GET_ID_ITEM(tmp32); + if (item != 0U) + { + mux = GET_ID_ITEM_MUX(item); + sel = GET_ID_ITEM_SEL(item); + if (mux == CM_ASYNCAPB) + { + ASYNC_SYSCON->ASYNCAPBCLKSELA = sel; + } + else + { + ((volatile uint32_t *)pClkSel)[mux] = sel; + } + } + tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */ + } + } +} + +/* Return the actual clock attach id */ +/** + * brief Get the actual clock attach id. + * This fuction uses the offset in input attach id, then it reads the actual source value in + * the register and combine the offset to obtain an actual attach id. + * param attachId : Clock attach id to get. + * return Clock source value. + */ +clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId) +{ + uint8_t mux; + uint8_t actualSel; + uint32_t tmp32 = (uint32_t)attachId; + uint32_t i; + uint32_t actualAttachId = 0U; + uint32_t selector = GET_ID_SELECTOR(tmp32); + volatile uint32_t *pClkSel; + + pClkSel = &(SYSCON->MAINCLKSELA); + + if (kNONE_to_NONE == attachId) + { + return kNONE_to_NONE; + } + + for (i = 0U; i < 2U; i++) + { + mux = GET_ID_ITEM_MUX(tmp32); + if (tmp32 != 0UL) + { + if (mux == CM_ASYNCAPB) + { + actualSel = (uint8_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA); + } + else + { + actualSel = (uint8_t)(((volatile uint32_t *)pClkSel)[mux]); + } + + /* Consider the combination of two registers */ + actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i); + } + tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!< pick up next descriptor */ + } + + actualAttachId |= selector; + + return (clock_attach_id_t)actualAttachId; +} + +/** + * brief Setup peripheral clock dividers. + * param div_name : Clock divider name + * param divided_by_value: Value to be divided + * param reset : Whether to reset the divider counter. + * return Nothing + */ +void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset) +{ + volatile uint32_t *pClkDiv; + + pClkDiv = &(SYSCON->SYSTICKCLKDIV); + if (reset) + { + ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 29U; + } + if (divided_by_value == 0UL) /* halt */ + { + ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 30U; + } + else + { + ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = (divided_by_value - 1UL); + } +} + +/* Set FRO Clocking */ +/** + * brief Initialize the Core clock to given frequency (12, 48 or 96 MHz). + * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is + * enabled. + * param iFreq : Desired frequency (must be one of CLK_FRO_12MHZ or CLK_FRO_48MHZ or CLK_FRO_96MHZ) + * return returns success or fail status. + */ +status_t CLOCK_SetupFROClocking(uint32_t iFreq) +{ + uint32_t usb_adj; + if ((iFreq != 12000000U) && (iFreq != 48000000U) && (iFreq != 96000000U)) + { + return kStatus_Fail; + } + /* Power up the FRO and set this as the base clock */ + POWER_DisablePD(kPDRUNCFG_PD_FRO_EN); + /* back up the value of whether USB adj is selected, in which case we will have a value of 1 else 0 */ + usb_adj = ((SYSCON->FROCTRL) & SYSCON_FROCTRL_USBCLKADJ_MASK) >> SYSCON_FROCTRL_USBCLKADJ_SHIFT; + if (iFreq > 12000000U) + { + if (iFreq == 96000000U) + { + SYSCON->FROCTRL = ((SYSCON_FROCTRL_TRIM_MASK | SYSCON_FROCTRL_FREQTRIM_MASK) & *INDEX_SECTOR_TRIM96) | + SYSCON_FROCTRL_SEL(1) | SYSCON_FROCTRL_WRTRIM(1) | SYSCON_FROCTRL_USBCLKADJ(usb_adj) | + SYSCON_FROCTRL_HSPDCLK(1); + } + else + { + SYSCON->FROCTRL = ((SYSCON_FROCTRL_TRIM_MASK | SYSCON_FROCTRL_FREQTRIM_MASK) & *INDEX_SECTOR_TRIM48) | + SYSCON_FROCTRL_SEL(0) | SYSCON_FROCTRL_WRTRIM(1) | SYSCON_FROCTRL_USBCLKADJ(usb_adj) | + SYSCON_FROCTRL_HSPDCLK(1); + } + } + else + { + SYSCON->FROCTRL &= ~SYSCON_FROCTRL_HSPDCLK(1); + } + + return kStatus_Success; +} + +/*! brief Return Frequency of FRO 12MHz + * return Frequency of FRO 12MHz + */ +uint32_t CLOCK_GetFro12MFreq(void) +{ + return ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ? 0U : 12000000U; +} + +/*! brief Return Frequency of External Clock + * return Frequency of External Clock. If no external clock is used returns 0. + */ +uint32_t CLOCK_GetExtClkFreq(void) +{ + return (s_Ext_Clk_Freq); +} +/*! brief Return Frequency of Watchdog Oscillator + * return Frequency of Watchdog Oscillator + */ +uint32_t CLOCK_GetWdtOscFreq(void) +{ + uint8_t freq_sel, div_sel; + if ((SYSCON->PDRUNCFG[(uint32_t)kPDRUNCFG_PD_WDT_OSC >> 8UL] & (1UL << ((uint32_t)kPDRUNCFG_PD_WDT_OSC & 0xffU))) != + 0UL) + { + return 0UL; + } + else + { + div_sel = (uint8_t)(((SYSCON->WDTOSCCTRL & 0x1fU) + 1UL) << 1U); + freq_sel = + wdtFreqLookup[((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_FREQSEL_MASK) >> SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)]; + return ((uint32_t)freq_sel * 50000U) / ((uint32_t)div_sel); + } +} + +/* Get HF FRO Clk */ +/*! brief Return Frequency of High-Freq output of FRO + * return Frequency of High-Freq output of FRO + */ +uint32_t CLOCK_GetFroHfFreq(void) +{ + if (((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) || + ((SYSCON->FROCTRL & SYSCON_FROCTRL_HSPDCLK_MASK) == 0UL)) + { + return 0U; + } + + if ((SYSCON->FROCTRL & SYSCON_FROCTRL_SEL_MASK) != 0UL) + { + return 96000000U; + } + else + { + return 48000000U; + } +} + +/*! brief Return Frequency of PLL + * return Frequency of PLL + */ +uint32_t CLOCK_GetPllOutFreq(void) +{ + return s_Pll_Freq; +} + +/*! brief Return Frequency of 32kHz osc + * return Frequency of 32kHz osc + */ +uint32_t CLOCK_GetOsc32KFreq(void) +{ + return CLK_RTC_32K_CLK; /* Needs to be corrected to check that RTC Clock is enabled */ +} +/*! brief Return Frequency of Core System + * return Frequency of Core System + */ +uint32_t CLOCK_GetCoreSysClkFreq(void) +{ + uint32_t freq = 0U; + + switch (SYSCON->MAINCLKSELB) + { + case 0U: + if (SYSCON->MAINCLKSELA == 0U) + { + freq = CLOCK_GetFro12MFreq(); + } + else if (SYSCON->MAINCLKSELA == 1U) + { + freq = CLOCK_GetExtClkFreq(); + } + else if (SYSCON->MAINCLKSELA == 2U) + { + freq = CLOCK_GetWdtOscFreq(); + } + else if (SYSCON->MAINCLKSELA == 3U) + { + freq = CLOCK_GetFroHfFreq(); + } + else + { + /* Add comment to prevent the case of MISRA C-2012 rule 15.7. */ + } + break; + case 2U: + freq = CLOCK_GetPllOutFreq(); + break; + + case 3U: + freq = CLOCK_GetOsc32KFreq(); + break; + + default: + assert(false); + break; + } + + return freq; +} +/*! brief Return Frequency of I2S MCLK Clock + * return Frequency of I2S MCLK Clock + */ +uint32_t CLOCK_GetI2SMClkFreq(void) +{ + return s_I2S_Mclk_Freq; +} + +/*! brief Return Frequency of Asynchronous APB Clock + * return Frequency of Asynchronous APB Clock Clock + */ +uint32_t CLOCK_GetAsyncApbClkFreq(void) +{ + async_clock_src_t clkSrc; + uint32_t clkRate; + + clkSrc = CLOCK_GetAsyncApbClkSrc(); + + switch (clkSrc) + { + case kCLOCK_AsyncMainClk: + clkRate = CLOCK_GetCoreSysClkFreq(); + break; + case kCLOCK_AsyncFro12Mhz: + clkRate = CLK_FRO_12MHZ; + break; + default: + clkRate = 0U; + break; + } + + return clkRate; +} + +/* Get FLEXCOMM Clk */ +/*! brief Return Frequency of Flexcomm functional Clock + * return Frequency of Flexcomm functional Clock + */ +uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id) +{ + uint32_t freq = 0U; + + switch (SYSCON->FXCOMCLKSEL[id]) + { + case 0U: + freq = CLOCK_GetFro12MFreq(); + break; + case 1U: + freq = CLOCK_GetFroHfFreq(); + break; + case 2U: + freq = CLOCK_GetPllOutFreq(); + break; + case 3U: + freq = CLOCK_GetI2SMClkFreq(); + break; + case 4U: + freq = CLOCK_GetFrgClkFreq(); + break; + + default: + assert(false); + break; + } + + return freq; +} + +/* Get ADC Clk */ +/*! brief Return Frequency of Adc Clock + * return Frequency of Adc Clock. + */ +uint32_t CLOCK_GetAdcClkFreq(void) +{ + uint32_t freq = 0U; + + switch (SYSCON->ADCCLKSEL) + { + case 0U: + freq = CLOCK_GetCoreSysClkFreq(); + break; + case 1U: + freq = CLOCK_GetPllOutFreq(); + break; + case 2U: + freq = CLOCK_GetFroHfFreq(); + break; + case 7U: + freq = 0U; + break; + default: + assert(false); + break; + } + + return freq / ((SYSCON->ADCCLKDIV & 0xffU) + 1U); +} + +/* Get FRG Clk */ +/*! brief Return Input frequency for the Fractional baud rate generator + * return Input Frequency for FRG + */ +uint32_t CLOCK_GetFRGInputClock(void) +{ + uint32_t freq = 0U; + + switch (SYSCON->FRGCLKSEL) + { + case 0U: + freq = CLOCK_GetCoreSysClkFreq(); + break; + case 1U: + freq = CLOCK_GetPllOutFreq(); + break; + case 2U: + freq = CLOCK_GetFro12MFreq(); + break; + case 3U: + freq = CLOCK_GetFroHfFreq(); + break; + + default: + assert(false); + break; + } + + return freq; +} + +/* Get DMIC Clk */ +/*! brief Return Input frequency for the DMIC + * return Input Frequency for DMIC + */ +uint32_t CLOCK_GetDmicClkFreq(void) +{ + uint32_t freq = 0U; + + switch (SYSCON->DMICCLKSEL) + { + case 0U: + freq = CLOCK_GetFro12MFreq(); + break; + case 1U: + freq = CLOCK_GetFroHfFreq(); + break; + case 2U: + freq = CLOCK_GetPllOutFreq(); + break; + case 3U: + freq = CLOCK_GetI2SMClkFreq(); + break; + case 4U: + freq = CLOCK_GetCoreSysClkFreq(); + break; + case 5U: + freq = CLOCK_GetWdtOscFreq(); + break; + default: + assert(false); + break; + } + + return freq / ((SYSCON->DMICCLKDIV & 0xffU) + 1U); +} + +/*! brief Set output of the Fractional baud rate generator + * param freq : Desired output frequency + * return Error Code 0 - fail 1 - success + */ +uint32_t CLOCK_SetFRGClock(uint32_t freq) +{ + uint32_t input = CLOCK_GetFRGInputClock(); + uint32_t mul; + + if ((freq > 48000000UL) || (freq > input) || (input / freq >= 2UL)) + { + /* FRG output frequency should be less than equal to 48MHz */ + return 0; + } + else + { + mul = (uint32_t)((((uint64_t)input - freq) * 256UL) / ((uint64_t)freq)); + SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK; + return 1; + } +} + +/* Get FRG Clk */ +/*! brief Return Input frequency for the FRG + * return Input Frequency for FRG + */ +uint32_t CLOCK_GetFrgClkFreq(void) +{ + uint32_t freq = 0U; + + if ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) == SYSCON_FRGCTRL_DIV_MASK) + { + freq = (uint32_t)(((uint64_t)CLOCK_GetFRGInputClock() * (SYSCON_FRGCTRL_DIV_MASK + 1U)) / + ((SYSCON_FRGCTRL_DIV_MASK + 1U) + + ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT))); + } + else + { + freq = 0U; + } + + return freq; +} + +/*! brief Return Frequency of USB + * return Frequency of USB + */ +uint32_t CLOCK_GetUsbClkFreq(void) +{ + uint32_t freq = 0U; + + if (SYSCON->USBCLKSEL == 0U) + { + freq = CLOCK_GetFroHfFreq(); + } + else if (SYSCON->USBCLKSEL == 1U) + { + freq = CLOCK_GetPllOutFreq(); + } + else + { + /* Add comment to prevent the case of MISRA C-2012 rule 15.7. */ + } + + return freq / ((SYSCON->USBCLKDIV & 0xffU) + 1U); +} + +/*! brief Return Frequency of selected clock + * return Frequency of selected clock + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName) +{ + uint32_t freq; + switch (clockName) + { + case kCLOCK_CoreSysClk: + freq = CLOCK_GetCoreSysClkFreq(); + break; + case kCLOCK_BusClk: + freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U); + break; + case kCLOCK_FroHf: + freq = CLOCK_GetFroHfFreq(); + break; + case kCLOCK_Fro12M: + freq = CLOCK_GetFro12MFreq(); + break; + case kCLOCK_PllOut: + freq = CLOCK_GetPllOutFreq(); + break; + case kCLOCK_UsbClk: + freq = CLOCK_GetUsbClkFreq(); + break; + case kCLOCK_WdtOsc: + freq = CLOCK_GetWdtOscFreq(); + break; + case kCLOCK_Frg: + freq = CLOCK_GetFrgClkFreq(); + break; + case kCLOCK_AsyncApbClk: + freq = CLOCK_GetAsyncApbClkFreq(); + break; + case kCLOCK_FlexI2S: + freq = CLOCK_GetI2SMClkFreq(); + break; + default: + freq = 0U; + break; + } + + return freq; +} + +/* Set the FLASH wait states for the passed frequency */ +/** + * brief Set the flash wait states for the input freuqency. + * param iFreq : Input frequency + * return Nothing + */ +void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq) +{ + if (iFreq <= 12000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash1Cycle); + } + else if (iFreq <= 24000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash2Cycle); + } + else if (iFreq <= 48000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash3Cycle); + } + else if (iFreq <= 72000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash4Cycle); + } + else if (iFreq <= 84000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash5Cycle); + } + else if (iFreq <= 100000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash6Cycle); + } + else + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash7Cycle); + } +} + +/* Find encoded NDEC value for raw N value, max N = NVALMAX */ +static uint32_t pllEncodeN(uint32_t N) +{ + uint32_t x, i; + + /* Find NDec */ + switch (N) + { + case 0U: + x = 0x3FFU; + break; + + case 1U: + x = 0x302U; + break; + + case 2U: + x = 0x202U; + break; + + default: + x = 0x080U; + for (i = N; i <= NVALMAX; i++) + { + x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU); + } + break; + } + + return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P); +} + +/* Find decoded N value for raw NDEC value */ +static uint32_t pllDecodeN(uint32_t NDEC) +{ + uint32_t n, x, i; + + /* Find NDec */ + switch (NDEC) + { + case 0x3FFU: + n = 0U; + break; + + case 0x302U: + n = 1U; + break; + + case 0x202U: + n = 2U; + break; + + default: + x = 0x080U; + n = 0xFFFFFFFFU; + for (i = NVALMAX; i >= 3U; i--) + { + x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU); + if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC) + { + /* Decoded value of NDEC */ + n = i; + break; + } + } + break; + } + + return n; +} + +/* Find encoded PDEC value for raw P value, max P = PVALMAX */ +static uint32_t pllEncodeP(uint32_t P) +{ + uint32_t x, i; + + /* Find PDec */ + switch (P) + { + case 0U: + x = 0x7FU; + break; + + case 1U: + x = 0x62U; + break; + + case 2U: + x = 0x42U; + break; + + default: + x = 0x10U; + for (i = P; i <= PVALMAX; i++) + { + x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU); + } + break; + } + + return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P); +} + +/* Find decoded P value for raw PDEC value */ +static uint32_t pllDecodeP(uint32_t PDEC) +{ + uint32_t p, x, i; + + /* Find PDec */ + switch (PDEC) + { + case 0x7FU: + p = 0U; + break; + + case 0x62U: + p = 1U; + break; + + case 0x42U: + p = 2U; + break; + + default: + x = 0x10U; + p = 0xFFFFFFFFU; + for (i = PVALMAX; i >= 3U; i--) + { + x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU); + if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC) + { + /* Decoded value of PDEC */ + p = i; + break; + } + } + break; + } + + return p; +} + +/* Find encoded MDEC value for raw M value, max M = MVALMAX */ +static uint32_t pllEncodeM(uint32_t M) +{ + uint32_t i, x; + + /* Find MDec */ + switch (M) + { + case 0U: + x = 0x1FFFFU; + break; + + case 1U: + x = 0x18003U; + break; + + case 2U: + x = 0x10003U; + break; + + default: + x = 0x04000U; + for (i = M; i <= MVALMAX; i++) + { + x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU); + } + break; + } + + return x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P); +} + +/* Find decoded M value for raw MDEC value */ +static uint32_t pllDecodeM(uint32_t MDEC) +{ + uint32_t m, i, x; + + /* Find MDec */ + switch (MDEC) + { + case 0x1FFFFU: + m = 0U; + break; + + case 0x18003U: + m = 1U; + break; + + case 0x10003U: + m = 2U; + break; + + default: + x = 0x04000U; + m = 0xFFFFFFFFU; + for (i = MVALMAX; i >= 3U; i--) + { + x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU); + if ((x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P)) == MDEC) + { + /* Decoded value of MDEC */ + m = i; + break; + } + } + break; + } + + return m; +} + +/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */ +static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR) +{ + /* bandwidth: compute selP from Multiplier */ + if (M < 60U) + { + *pSelP = (M >> 1U) + 1U; + } + else + { + *pSelP = PVALMAX - 1U; + } + + /* bandwidth: compute selI from Multiplier */ + if (M > 16384U) + { + *pSelI = 1U; + } + else if (M > 8192U) + { + *pSelI = 2U; + } + else if (M > 2048U) + { + *pSelI = 4U; + } + else if (M >= 501U) + { + *pSelI = 8U; + } + else if (M >= 60U) + { + *pSelI = 4U * (1024U / (M + 9U)); + } + else + { + *pSelI = (M & 0x3CU) + 4U; + } + + if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT)) + { + *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT); + } + + *pSelR = 0U; +} + +/* Get predivider (N) from PLL NDEC setting */ +static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg) +{ + uint32_t preDiv = 1; + + /* Direct input is not used? */ + if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U) + { + /* Decode NDEC value to get (N) pre divider */ + preDiv = pllDecodeN(nDecReg & 0x3FFU); + if (preDiv == 0U) + { + preDiv = 1U; + } + } + + /* Adjusted by 1, directi is used to bypass */ + return preDiv; +} + +/* Get postdivider (P) from PLL PDEC setting */ +static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg) +{ + uint32_t postDiv = 1U; + + /* Direct input is not used? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U) + { + /* Decode PDEC value to get (P) post divider */ + postDiv = 2U * pllDecodeP(pDecReg & 0x7FU); + if (postDiv == 0U) + { + postDiv = 2U; + } + } + + /* Adjusted by 1, directo is used to bypass */ + return postDiv; +} + +/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */ +static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg) +{ + uint32_t mMult = 1U; + + /* Decode MDEC value to get (M) multiplier */ + mMult = pllDecodeM(mDecReg & 0x1FFFFU); + + /* Extra multiply by 2 needed? */ + if ((ctrlReg & (SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK)) == 0U) + { + mMult = mMult << 1U; + } + + if (mMult == 0U) + { + mMult = 1U; + } + + return mMult; +} + +static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n) +{ + uint32_t tmp; + + while (n != 0U) + { + tmp = n; + n = m % n; + m = tmp; + } + + return m; +} + +/* + * Set PLL output based on desired output rate. + * In this function, the it calculates the PLL setting for output frequency from input clock + * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently. + * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function. + */ +static pll_error_t CLOCK_GetPllConfigInternal( + uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS) +{ + uint32_t nDivOutHz, fccoHz, multFccoDiv; + uint32_t pllPreDivider, pllMultiplier, pllBypassFBDIV2, pllPostDivider; + uint32_t pllDirectInput, pllDirectOutput; + uint32_t pllSelP, pllSelI, pllSelR, bandsel, uplimoff; + + /* Baseline parameters (no input or output dividers) */ + pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */ + pllPostDivider = 0U; /* 0 implies post-divider will be disabled */ + pllDirectOutput = 1U; + if (useFeedbackDiv2) + { + /* Using feedback divider for M, so disable bypass */ + pllBypassFBDIV2 = 0U; + } + else + { + pllBypassFBDIV2 = 1U; + } + multFccoDiv = (2U - pllBypassFBDIV2); + + /* Verify output rate parameter */ + if (foutHz > PLL_MAX_CCO_FREQ_MHZ) + { + /* Maximum PLL output with post divider=1 cannot go above this frequency */ + return kStatus_PLL_OutputTooHigh; + } + if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U))) + { + /* Minmum PLL output with maximum post divider cannot go below this frequency */ + return kStatus_PLL_OutputTooLow; + } + + /* If using SS mode, input clock needs to be between 2MHz and 4MHz */ + if (useSS) + { + /* Verify input rate parameter */ + if (finHz < PLL_MIN_IN_SSMODE) + { + /* Input clock into the PLL cannot be lower than this */ + return kStatus_PLL_InputTooLow; + } + /* PLL input in SS mode must be under 4MHz */ + pllPreDivider = finHz / ((PLL_MIN_IN_SSMODE + PLL_MAX_IN_SSMODE) / 2U); + if (pllPreDivider > NVALMAX) + { + return kStatus_PLL_InputTooHigh; + } + } + else + { + /* Verify input rate parameter */ + if (finHz < PLL_LOWER_IN_LIMIT) + { + /* Input clock into the PLL cannot be lower than this */ + return kStatus_PLL_InputTooLow; + } + } + + /* Find the optimal CCO frequency for the output and input that + will keep it inside the PLL CCO range. This may require + tweaking the post-divider for the PLL. */ + fccoHz = foutHz; + while (fccoHz < PLL_MIN_CCO_FREQ_MHZ) + { + /* CCO output is less than minimum CCO range, so the CCO output + needs to be bumped up and the post-divider is used to bring + the PLL output back down. */ + pllPostDivider++; + if (pllPostDivider > PVALMAX) + { + return kStatus_PLL_OutsideIntLimit; + } + + /* Target CCO goes up, PLL output goes down */ + fccoHz = foutHz * (pllPostDivider * 2U); + pllDirectOutput = 0U; + } + + /* Determine if a pre-divider is needed to get the best frequency */ + if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false)) + { + uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz)); + + if (a > 20000U) + { + a = (multFccoDiv * finHz) / a; + if ((a != 0U) && (a < PLL_MAX_N_DIV)) + { + pllPreDivider = a; + } + } + } + + /* Bypass pre-divider hardware if pre-divider is 1 */ + if (pllPreDivider > 1U) + { + pllDirectInput = 0U; + } + else + { + pllDirectInput = 1U; + } + + /* Determine PLL multipler */ + nDivOutHz = (finHz / pllPreDivider); + pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv; + + /* Find optimal values for filter */ + if (useSS == false) + { + /* Will bumping up M by 1 get us closer to the desired CCO frequency? */ + if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U)) + { + pllMultiplier++; + } + + /* Setup filtering */ + pllFindSel(pllMultiplier, (bool)pllBypassFBDIV2, &pllSelP, &pllSelI, &pllSelR); + bandsel = 1U; + uplimoff = 0U; + + /* Get encoded value for M (mult) and use manual filter, disable SS mode */ + pSetup->syspllssctrl[0] = + (PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(pllMultiplier)) | (1UL << SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT)); + + /* Power down SSC, not used */ + pSetup->syspllssctrl[1] = (1UL << SYSCON_SYSPLLSSCTRL1_PD_SHIFT); + } + else + { + uint64_t fc; + + /* Filtering will be handled by SSC */ + pllSelR = 0U; + pllSelI = 0U; + pllSelP = 0U; + bandsel = 0U; + uplimoff = 1U; + + /* The PLL multiplier will get very close and slightly under the + desired target frequency. A small fractional component can be + added to fine tune the frequency upwards to the target. */ + fc = (((uint64_t)fccoHz % ((uint64_t)multFccoDiv * nDivOutHz)) << 11U) / ((uint64_t)multFccoDiv * nDivOutHz); + + /* MDEC set by SSC */ + pSetup->syspllssctrl[0U] = 0U; + + /* Set multiplier */ + pSetup->syspllssctrl[1] = PLL_SSCG1_MD_INT_SET(pllMultiplier) | PLL_SSCG1_MD_FRACT_SET((uint32_t)fc); + } + + /* Get encoded values for N (prediv) and P (postdiv) */ + pSetup->syspllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider)); + pSetup->syspllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider)); + + /* PLL control */ + pSetup->syspllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) | /* Filter coefficient */ + (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) | /* Filter coefficient */ + (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) | /* Filter coefficient */ + (0UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) | /* PLL bypass mode disabled */ + (pllBypassFBDIV2 << SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT) | /* Extra M / 2 divider? */ + (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) | /* SS/fractional mode disabled */ + (bandsel << SYSCON_SYSPLLCTRL_BANDSEL_SHIFT) | /* Manual bandwidth selection enabled */ + (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */ + (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */ + + return kStatus_PLL_Success; +} + +#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) +/* Alloct the static buffer for cache. */ +static pll_setup_t s_PllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT]; +static uint32_t s_FinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0}; +static uint32_t s_FoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0}; +static bool s_UseFeedbackDiv2Cache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false}; +static bool s_UseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false}; +static uint32_t s_PllSetupCacheIdx = 0U; +#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */ + +/* + * Calculate the PLL setting values from input clock freq to output freq. + */ +static pll_error_t CLOCK_GetPllConfig( + uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS) +{ + pll_error_t retErr; +#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) + uint32_t i; + + for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++) + { + if ((finHz == s_FinHzCache[i]) && (foutHz == s_FoutHzCache[i]) && + (useFeedbackDiv2 == s_UseFeedbackDiv2Cache[i]) && (useSS == s_UseSSCache[i])) + { + /* Hit the target in cache buffer. */ + pSetup->syspllctrl = s_PllSetupCacheStruct[i].syspllctrl; + pSetup->syspllndec = s_PllSetupCacheStruct[i].syspllndec; + pSetup->syspllpdec = s_PllSetupCacheStruct[i].syspllpdec; + pSetup->syspllssctrl[0] = s_PllSetupCacheStruct[i].syspllssctrl[0]; + pSetup->syspllssctrl[1] = s_PllSetupCacheStruct[i].syspllssctrl[1]; + retErr = kStatus_PLL_Success; + break; + } + } + + if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) + { + return retErr; + } +#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */ + + retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup, useFeedbackDiv2, useSS); + +#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) + /* Cache the most recent calulation result into buffer. */ + s_FinHzCache[s_PllSetupCacheIdx] = finHz; + s_FoutHzCache[s_PllSetupCacheIdx] = foutHz; + s_UseFeedbackDiv2Cache[s_PllSetupCacheIdx] = useFeedbackDiv2; + s_UseSSCache[s_PllSetupCacheIdx] = useSS; + + s_PllSetupCacheStruct[s_PllSetupCacheIdx].syspllctrl = pSetup->syspllctrl; + s_PllSetupCacheStruct[s_PllSetupCacheIdx].syspllndec = pSetup->syspllndec; + s_PllSetupCacheStruct[s_PllSetupCacheIdx].syspllpdec = pSetup->syspllpdec; + s_PllSetupCacheStruct[s_PllSetupCacheIdx].syspllssctrl[0] = pSetup->syspllssctrl[0]; + s_PllSetupCacheStruct[s_PllSetupCacheIdx].syspllssctrl[1] = pSetup->syspllssctrl[1]; + /* Update the index for next available buffer. */ + s_PllSetupCacheIdx = (s_PllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; +#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */ + + return retErr; +} + +/* Update local PLL rate variable */ +static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup) +{ + s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup); +} + +/* Return System PLL input clock rate */ +/*! brief Return System PLL input clock rate + * return System PLL input clock rate + */ +uint32_t CLOCK_GetSystemPLLInClockRate(void) +{ + uint32_t clkRate = 0U; + + switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK)) + { + case 0x00U: + clkRate = CLK_FRO_12MHZ; + break; + + case 0x01U: + clkRate = CLOCK_GetExtClkFreq(); + break; + + case 0x02U: + clkRate = CLOCK_GetWdtOscFreq(); + break; + + case 0x03U: + clkRate = CLOCK_GetOsc32KFreq(); + break; + + default: + clkRate = 0U; + break; + } + + return clkRate; +} + +/* Return System PLL output clock rate from setup structure */ +/*! brief Return System PLL output clock rate from setup structure + * param pSetup : Pointer to a PLL setup structure + * return System PLL output clock rate calculated from the setup structure + */ +uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup) +{ + uint32_t prediv, postdiv, mMult, inPllRate; + uint64_t workRate; + + /* Get the input clock frequency of PLL. */ + inPllRate = CLOCK_GetSystemPLLInClockRate(); + + /* + * If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock. + */ + if ((pSetup->syspllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U) + { + /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */ + /* + * 1. Pre-divider + * Pre-divider is only available when the DIRECTI is disabled. + */ + if (0U == (pSetup->syspllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK)) + { + prediv = findPllPreDiv(pSetup->syspllctrl, pSetup->syspllndec); + } + else + { + prediv = 1U; /* The pre-divider is bypassed. */ + } + /* Adjust input clock */ + inPllRate = inPllRate / prediv; + + /* + * 2. M divider + * If using the SS, use the multiplier. + */ + if ((pSetup->syspllssctrl[1] & (SYSCON_SYSPLLSSCTRL1_PD_MASK)) != 0UL) + { + /* MDEC used for rate */ + mMult = findPllMMult(pSetup->syspllctrl, pSetup->syspllssctrl[0]); + workRate = (uint64_t)inPllRate * (uint64_t)mMult; + } + else + { + uint64_t fract; + + /* SS multipler used for rate */ + mMult = (pSetup->syspllssctrl[1] & PLL_SSCG1_MD_INT_M) >> PLL_SSCG1_MD_INT_P; + workRate = (uint64_t)inPllRate * (uint64_t)mMult; + + /* Adjust by fractional */ + fract = ((uint64_t)(pSetup->syspllssctrl[1]) & PLL_SSCG1_MD_FRACT_M) >> PLL_SSCG1_MD_FRACT_P; + workRate = workRate + ((inPllRate * fract) / 0x800U); + } + + /* + * 3. Post-divider + * Post-divider is only available when the DIRECTO is disabled. + */ + if (0U == (pSetup->syspllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK)) + { + postdiv = findPllPostDiv(pSetup->syspllctrl, pSetup->syspllpdec); + } + else + { + postdiv = 1U; /* The post-divider is bypassed. */ + } + workRate = workRate / ((uint64_t)postdiv); + } + else + { + /* In bypass mode */ + workRate = (uint64_t)inPllRate; + } + + return (uint32_t)workRate; +} + +/* Set the current PLL Rate */ +/*! brief Store the current PLL rate + * param rate: Current rate of the PLL + * return Nothing + **/ +void CLOCK_SetStoredPLLClockRate(uint32_t rate) +{ + s_Pll_Freq = rate; +} + +/* Return System PLL output clock rate */ +/*! brief Return System PLL output clock rate + * param recompute : Forces a PLL rate recomputation if true + * return System PLL output clock rate + * note The PLL rate is cached in the driver in a variable as + * the rate computation function can take some time to perform. It + * is recommended to use 'false' with the 'recompute' parameter. + */ +uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute) +{ + pll_setup_t Setup; + uint32_t rate; + + if ((recompute) || (s_Pll_Freq == 0U)) + { + Setup.syspllctrl = SYSCON->SYSPLLCTRL; + Setup.syspllndec = SYSCON->SYSPLLNDEC; + Setup.syspllpdec = SYSCON->SYSPLLPDEC; + Setup.syspllssctrl[0] = SYSCON->SYSPLLSSCTRL0; + Setup.syspllssctrl[1] = SYSCON->SYSPLLSSCTRL1; + + CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup); + } + + rate = s_Pll_Freq; + + return rate; +} + +/* Set PLL output based on the passed PLL setup data */ +/*! brief Set PLL output based on the passed PLL setup data + * param pControl : Pointer to populated PLL control structure to generate setup with + * param pSetup : Pointer to PLL setup structure to be filled + * return PLL_ERROR_SUCCESS on success, or PLL setup error code + * note Actual frequency for setup may vary from the desired frequency based on the + * accuracy of input clocks, rounding, non-fractional PLL mode, etc. + */ +pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup) +{ + uint32_t inRate; + bool useSS = (bool)((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0U); + bool useFbDiv2; + + pll_error_t pllError; + + /* Determine input rate for the PLL */ + if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0UL) + { + inRate = pControl->inputRate; + } + else + { + inRate = CLOCK_GetSystemPLLInClockRate(); + } + + if ((pSetup->flags & PLL_SETUPFLAG_USEFEEDBACKDIV2) != 0UL) + { + useFbDiv2 = true; + } + else + { + useFbDiv2 = false; + } + + /* PLL flag options */ + pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup, useFbDiv2, useSS); + if ((useSS) && (pllError == kStatus_PLL_Success)) + { + /* If using SS mode, then some tweaks are made to the generated setup */ + pSetup->syspllssctrl[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc; + if (pControl->mfDither) + { + pSetup->syspllssctrl[1] |= (1UL << SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT); + } + } + + return pllError; +} + +/* Set PLL output from PLL setup structure */ +/*! brief Set PLL output from PLL setup structure (precise frequency) + * param pSetup : Pointer to populated PLL setup structure + * param flagcfg : Flag configuration for PLL config structure + * return PLL_ERROR_SUCCESS on success, or PLL setup error code + * note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg) +{ + /* Power off PLL during setup changes */ + POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0); + + pSetup->flags = flagcfg; + + /* Write PLL setup data */ + SYSCON->SYSPLLCTRL = pSetup->syspllctrl; + SYSCON->SYSPLLNDEC = pSetup->syspllndec; + SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */ + SYSCON->SYSPLLPDEC = pSetup->syspllpdec; + SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0]; + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1UL << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1]; + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1UL << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */ + + /* Flags for lock or power on */ + if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0UL) + { + /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */ + uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/ + uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1UL << 17U); + + /* Initialize and power up PLL */ + SYSCON->SYSPLLSSCTRL0 = maxCCO; + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0); + + /* Set mreq to activate */ + SYSCON->SYSPLLSSCTRL0 = maxCCO | (1UL << 17U); + + /* Delay for 72 uSec @ 12Mhz */ + SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + + /* clear mreq to prepare for restoring mreq */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL; + + /* set original value back and activate */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1UL << 17U); + + /* Enable peripheral states by setting low */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0); + } + if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0UL) + { + while (CLOCK_IsSystemPLLLocked() == false) + { + } + } + + /* Update current programmed PLL rate var */ + CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup); + + /* System voltage adjustment, occurs prior to setting main system clock */ + if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0UL) + { + POWER_SetVoltageForFreq(s_Pll_Freq); + } + + return kStatus_PLL_Success; +} + +/* Setup PLL Frequency from pre-calculated value */ +/** + * brief Set PLL output from PLL setup structure (precise frequency) + * param pSetup : Pointer to populated PLL setup structure + * return kStatus_PLL_Success on success, or PLL setup error code + * note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup) +{ + /* Power off PLL during setup changes */ + POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0); + + /* Write PLL setup data */ + SYSCON->SYSPLLCTRL = pSetup->syspllctrl; + SYSCON->SYSPLLNDEC = pSetup->syspllndec; + SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */ + SYSCON->SYSPLLPDEC = pSetup->syspllpdec; + SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0]; + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1UL << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1]; + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1UL << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */ + + /* Flags for lock or power on */ + if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0UL) + { + /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */ + uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/ + uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1UL << 17U); + + /* Initialize and power up PLL */ + SYSCON->SYSPLLSSCTRL0 = maxCCO; + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0); + + /* Set mreq to activate */ + SYSCON->SYSPLLSSCTRL0 = maxCCO | (1UL << 17U); + + /* Delay for 72 uSec @ 12Mhz */ + SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + + /* clear mreq to prepare for restoring mreq */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL; + + /* set original value back and activate */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1UL << 17U); + + /* Enable peripheral states by setting low */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0); + } + if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0UL) + { + while (CLOCK_IsSystemPLLLocked() == false) + { + } + } + + /* Update current programmed PLL rate var */ + s_Pll_Freq = pSetup->pllRate; + + return kStatus_PLL_Success; +} + +/* Set System PLL clock based on the input frequency and multiplier */ +/*! brief Set PLL output based on the multiplier and input frequency + * param multiply_by : multiplier + * param input_freq : Clock input frequency of the PLL + * return Nothing + * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this + * function does not disable or enable PLL power, wait for PLL lock, + * or adjust system voltages. These must be done in the application. + * The function will not alter any source clocks (ie, main systen clock) + * that may use the PLL, so these should be setup prior to and after + * exiting the function. + */ +void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq) +{ + uint32_t cco_freq = input_freq * multiply_by; + uint32_t pdec = 1U; + uint32_t selr; + uint32_t seli; + uint32_t selp; + uint32_t mdec, ndec; + + uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1); + + while (cco_freq < 75000000U) + { + multiply_by <<= 1U; /* double value in each iteration */ + pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */ + cco_freq = input_freq * multiply_by; + } + selr = 0U; + if (multiply_by < 60U) + { + seli = (multiply_by & 0x3cU) + 4U; + selp = (multiply_by >> 1U) + 1U; + } + else + { + selp = 31U; + if (multiply_by > 16384U) + { + seli = 1U; + } + else if (multiply_by > 8192U) + { + seli = 2U; + } + else if (multiply_by > 2048U) + { + seli = 4U; + } + else if (multiply_by >= 501U) + { + seli = 8U; + } + else + { + seli = 4U * (1024U / (multiply_by + 9U)); + } + } + + if (pdec > 1U) + { + directo = 0U; /* use post divider */ + pdec = pdec / 2U; /* Account for minus 1 encoding */ + /* Translate P value */ + switch (pdec) + { + case 1U: + pdec = 0x62U; /* 1 * 2 */ + break; + case 2U: + pdec = 0x42U; /* 2 * 2 */ + break; + case 4U: + pdec = 0x02U; /* 4 * 2 */ + break; + case 8U: + pdec = 0x0bU; /* 8 * 2 */ + break; + case 16U: + pdec = 0x11U; /* 16 * 2 */ + break; + case 32U: + pdec = 0x08U; /* 32 * 2 */ + break; + default: + pdec = 0x08U; + break; + } + } + + mdec = PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(multiply_by)); + ndec = 0x302U; /* pre divide by 1 (hardcoded) */ + + SYSCON->SYSPLLCTRL = SYSCON_SYSPLLCTRL_BANDSEL(1) | directo | SYSCON_SYSPLLCTRL_BYPASSCCODIV2(1) | + (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) | + (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT); + SYSCON->SYSPLLPDEC = pdec | (1UL << 7U); /* set Pdec value and assert preq */ + SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */ + SYSCON->SYSPLLSSCTRL0 = + (1UL << 18U) | (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */ +} +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) +{ + bool ret = true; + + CLOCK_DisableClock(kCLOCK_Usbd0); + + if (kCLOCK_UsbSrcFro == src) + { + switch (freq) + { + case 96000000U: + CLOCK_SetClkDiv(kCLOCK_DivUsbClk, 2, false); /*!< Div by 2 to get 48MHz, no divider reset */ + break; + case 48000000U: + CLOCK_SetClkDiv(kCLOCK_DivUsbClk, 1, false); /*!< Div by 1 to get 48MHz, no divider reset */ + break; + default: + ret = false; + break; + } + /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */ + SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK | + SYSCON_FROCTRL_USBCLKADJ_MASK; + /* select FRO 96 or 48 MHz */ + CLOCK_AttachClk(kFRO_HF_to_USB_CLK); + } + else + { + /*TODO , we only implement FRO as usb clock source*/ + ret = false; + } + + CLOCK_EnableClock(kCLOCK_Usbd0); + + return ret; +} diff --git a/drivers/fsl_clock.h b/drivers/fsl_clock.h new file mode 100644 index 0000000..68647d2 --- /dev/null +++ b/drivers/fsl_clock.h @@ -0,0 +1,876 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2019 , NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_CLOCK_H_ +#define _FSL_CLOCK_H_ + +#include "fsl_common.h" + +/*! @addtogroup clock */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + *****************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CLOCK driver version 2.5.1. */ +#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 5, 1)) +/*@}*/ + +/*! + * @brief User-defined the size of cache for CLOCK_PllGetConfig() function. + * + * Once define this MACRO to be non-zero value, CLOCK_PllGetConfig() function + * would cache the recent calulation and accelerate the execution to get the + * right settings. + */ +#ifndef CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT +#define CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT 2U +#endif + +/* Definition for delay API in clock driver, users can redefine it to the real application. */ +#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY +#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (150000000UL) +#endif + +/*! @brief Clock ip name array for FLEXCOMM. */ +#define FLEXCOMM_CLOCKS \ + { \ + kCLOCK_FlexComm0, kCLOCK_FlexComm1, kCLOCK_FlexComm2, kCLOCK_FlexComm3, kCLOCK_FlexComm4, kCLOCK_FlexComm5, \ + kCLOCK_FlexComm6, kCLOCK_FlexComm7 \ + } +/*! @brief Clock ip name array for LPUART. */ +#define LPUART_CLOCKS \ + { \ + kCLOCK_MinUart0, kCLOCK_MinUart1, kCLOCK_MinUart2, kCLOCK_MinUart3, kCLOCK_MinUart4, kCLOCK_MinUart5, \ + kCLOCK_MinUart6, kCLOCK_MinUart7 \ + } + +/*! @brief Clock ip name array for BI2C. */ +#define BI2C_CLOCKS \ + { \ + kCLOCK_BI2c0, kCLOCK_BI2c1, kCLOCK_BI2c2, kCLOCK_BI2c3, kCLOCK_BI2c4, kCLOCK_BI2c5, kCLOCK_BI2c6, kCLOCK_BI2c7 \ + } +/*! @brief Clock ip name array for LSPI. */ +#define LPSI_CLOCKS \ + { \ + kCLOCK_LSpi0, kCLOCK_LSpi1, kCLOCK_LSpi2, kCLOCK_LSpi3, kCLOCK_LSpi4, kCLOCK_LSpi5, kCLOCK_LSpi6, kCLOCK_LSpi7 \ + } +/*! @brief Clock ip name array for FLEXI2S. */ +#define FLEXI2S_CLOCKS \ + { \ + kCLOCK_FlexI2s0, kCLOCK_FlexI2s1, kCLOCK_FlexI2s2, kCLOCK_FlexI2s3, kCLOCK_FlexI2s4, kCLOCK_FlexI2s5, \ + kCLOCK_FlexI2s6, kCLOCK_FlexI2s7 \ + } +/*! @brief Clock ip name array for UTICK. */ +#define UTICK_CLOCKS \ + { \ + kCLOCK_Utick \ + } +/*! @brief Clock ip name array for DMIC. */ +#define DMIC_CLOCKS \ + { \ + kCLOCK_DMic \ + } +/*! @brief Clock ip name array for DMA. */ +#define DMA_CLOCKS \ + { \ + kCLOCK_Dma \ + } +/*! @brief Clock ip name array for CT32B. */ +#define CTIMER_CLOCKS \ + { \ + kCLOCK_Ct32b0, kCLOCK_Ct32b1, kCLOCK_Ct32b2, kCLOCK_Ct32b3, kCLOCK_Ct32b4 \ + } + +/*! @brief Clock ip name array for GPIO. */ +#define GPIO_CLOCKS \ + { \ + kCLOCK_Gpio0, kCLOCK_Gpio1 \ + } +/*! @brief Clock ip name array for ADC. */ +#define ADC_CLOCKS \ + { \ + kCLOCK_Adc0 \ + } +/*! @brief Clock ip name array for MRT. */ +#define MRT_CLOCKS \ + { \ + kCLOCK_Mrt \ + } +/*! @brief Clock ip name array for MRT. */ +#define SCT_CLOCKS \ + { \ + kCLOCK_Sct0 \ + } +/*! @brief Clock ip name array for RTC. */ +#define RTC_CLOCKS \ + { \ + kCLOCK_Rtc \ + } +/*! @brief Clock ip name array for WWDT. */ +#define WWDT_CLOCKS \ + { \ + kCLOCK_Wwdt \ + } +/*! @brief Clock ip name array for CRC. */ +#define CRC_CLOCKS \ + { \ + kCLOCK_Crc \ + } +/*! @brief Clock ip name array for USBD. */ +#define USBD_CLOCKS \ + { \ + kCLOCK_Usbd0 \ + } + +/*! @brief Clock ip name array for GINT. GINT0 & GINT1 share same slot */ +#define GINT_CLOCKS \ + { \ + kCLOCK_Gint, kCLOCK_Gint \ + } + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +/*------------------------------------------------------------------------------ + clock_ip_name_t definition: +------------------------------------------------------------------------------*/ + +#define CLK_GATE_REG_OFFSET_SHIFT 8U +#define CLK_GATE_REG_OFFSET_MASK 0xFFFFFF00U +#define CLK_GATE_BIT_SHIFT_SHIFT 0U +#define CLK_GATE_BIT_SHIFT_MASK 0x000000FFU + +#define CLK_GATE_DEFINE(reg_offset, bit_shift) \ + ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \ + (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK)) + +#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((uint32_t)(x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT) +#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((uint32_t)(x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT) + +#define AHB_CLK_CTRL0 0 +#define AHB_CLK_CTRL1 1 +#define ASYNC_CLK_CTRL0 2 + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +typedef enum _clock_ip_name +{ + kCLOCK_IpInvalid = 0U, + kCLOCK_Rom = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 1), + kCLOCK_Sram1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 3), + kCLOCK_Sram2 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 4), + kCLOCK_Regfile = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 6), + kCLOCK_Flash = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 7), + kCLOCK_Fmc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 8), + kCLOCK_InputMux = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 11), + kCLOCK_Iocon = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 13), + kCLOCK_Gpio0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 14), + kCLOCK_Gpio1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 15), + kCLOCK_Gpio2 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 16), + kCLOCK_Gpio3 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 17), + kCLOCK_Pint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 18), + kCLOCK_Gint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 19), /* GPIO_GLOBALINT0 and GPIO_GLOBALINT1 share the same slot */ + kCLOCK_Dma = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 20), + kCLOCK_Crc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 21), + kCLOCK_Wwdt = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 22), + kCLOCK_Rtc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 23), + kCLOCK_Mailbox = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 26), + kCLOCK_Adc0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 27), + kCLOCK_Mrt = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 0), + kCLOCK_Sct0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 2), + kCLOCK_SctIpu0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 6), + kCLOCK_Utick = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 10), + kCLOCK_FlexComm0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11), + kCLOCK_FlexComm1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12), + kCLOCK_FlexComm2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13), + kCLOCK_FlexComm3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14), + kCLOCK_FlexComm4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15), + kCLOCK_FlexComm5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16), + kCLOCK_FlexComm6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17), + kCLOCK_FlexComm7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18), + kCLOCK_MinUart0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11), + kCLOCK_MinUart1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12), + kCLOCK_MinUart2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13), + kCLOCK_MinUart3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14), + kCLOCK_MinUart4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15), + kCLOCK_MinUart5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16), + kCLOCK_MinUart6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17), + kCLOCK_MinUart7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18), + kCLOCK_LSpi0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11), + kCLOCK_LSpi1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12), + kCLOCK_LSpi2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13), + kCLOCK_LSpi3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14), + kCLOCK_LSpi4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15), + kCLOCK_LSpi5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16), + kCLOCK_LSpi6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17), + kCLOCK_LSpi7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18), + kCLOCK_BI2c0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11), + kCLOCK_BI2c1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12), + kCLOCK_BI2c2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13), + kCLOCK_BI2c3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14), + kCLOCK_BI2c4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15), + kCLOCK_BI2c5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16), + kCLOCK_BI2c6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17), + kCLOCK_BI2c7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18), + kCLOCK_FlexI2s0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11), + kCLOCK_FlexI2s1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12), + kCLOCK_FlexI2s2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13), + kCLOCK_FlexI2s3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14), + kCLOCK_FlexI2s4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15), + kCLOCK_FlexI2s5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16), + kCLOCK_FlexI2s6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17), + kCLOCK_FlexI2s7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18), + kCLOCK_DMic = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 19), + kCLOCK_Ct32b2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 22), + kCLOCK_Usbd0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 25), + kCLOCK_Ct32b0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 26), + kCLOCK_Ct32b1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 27), + kCLOCK_Pvtvf0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 28), + kCLOCK_Pvtvf1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 28), + kCLOCK_BodyBias0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 29), + kCLOCK_EzhArchB0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 31), + + kCLOCK_Ct32b3 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 13), + kCLOCK_Ct32b4 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 14) +} clock_ip_name_t; + +/*! @brief Clock name used to get clock frequency. */ +typedef enum _clock_name +{ + kCLOCK_CoreSysClk, /*!< Core/system clock (aka MAIN_CLK) */ + kCLOCK_BusClk, /*!< Bus clock (AHB clock) */ + kCLOCK_FroHf, /*!< FRO48/96 */ + kCLOCK_Fro12M, /*!< FRO12M */ + kCLOCK_ExtClk, /*!< External Clock */ + kCLOCK_PllOut, /*!< PLL Output */ + kCLOCK_UsbClk, /*!< USB input */ + kCLOCK_WdtOsc, /*!< Watchdog Oscillator */ + kCLOCK_Frg, /*!< Frg Clock */ + kCLOCK_AsyncApbClk, /*!< Async APB clock */ + kCLOCK_FlexI2S, /*!< FlexI2S clock */ +} clock_name_t; + +/** + * Clock source selections for the asynchronous APB clock + */ +typedef enum _async_clock_src +{ + kCLOCK_AsyncMainClk = 0, /*!< Main System clock */ + kCLOCK_AsyncFro12Mhz, /*!< 12MHz FRO */ +} async_clock_src_t; + +/*! @brief Clock Mux Switches + * The encoding is as follows each connection identified is 32bits wide while 24bits are valuable + * starting from LSB upwards + * + * [4 bits for choice, 0 means invalid choice] [8 bits mux ID]* + * + */ + +#define CLK_ATTACH_ID(mux, sel, pos) ((((uint32_t)(mux) << 0U) | (((uint32_t)(sel) + 1UL) & 0xFU) << 8U) << ((pos)*12U)) +#define MUX_A(mux, sel) CLK_ATTACH_ID((mux), (sel), 0U) +#define MUX_B(mux, sel, selector) (CLK_ATTACH_ID((mux), (sel), 1U) | ((selector) << 24U)) + +#define GET_ID_ITEM(connection) ((connection)&0xFFFU) +#define GET_ID_NEXT_ITEM(connection) ((connection) >> 12U) +#define GET_ID_ITEM_MUX(connection) (((uint8_t)(connection)) & 0xFFU) +#define GET_ID_ITEM_SEL(connection) (uint8_t)(((((uint32_t)(connection)&0xF00U) >> 8U) - 1U)) +#define GET_ID_SELECTOR(connection) ((connection)&0xF000000U) + +#define CM_MAINCLKSELA 0 +#define CM_MAINCLKSELB 1 +#define CM_CLKOUTCLKSELA 2 +#define CM_CLKOUTCLKSELB 3 +#define CM_SYSPLLCLKSEL 4 +#define CM_USBPLLCLKSEL 5 +#define CM_AUDPLLCLKSEL 6 +#define CM_SCTPLLCLKSEL 7 +#define CM_SPIFICLKSEL 8 +#define CM_ADCASYNCCLKSEL 9 +#define CM_USBCLKSEL 10 +#define CM_USB1CLKSEL 11 +#define CM_FXCOMCLKSEL0 12 +#define CM_FXCOMCLKSEL1 13 +#define CM_FXCOMCLKSEL2 14 +#define CM_FXCOMCLKSEL3 15 +#define CM_FXCOMCLKSEL4 16 +#define CM_FXCOMCLKSEL5 17 +#define CM_FXCOMCLKSEL6 18 +#define CM_FXCOMCLKSEL7 19 +#define CM_FXCOMCLKSEL8 20 +#define CM_FXCOMCLKSEL9 21 +#define CM_FXCOMCLKSEL10 22 +#define CM_FXCOMCLKSEL11 23 +#define CM_FXI2S0MCLKCLKSEL 24 +#define CM_FXI2S1MCLKCLKSEL 25 +#define CM_FRGCLKSEL 26 +#define CM_DMICCLKSEL 27 + +#define CM_ASYNCAPB 28U + +typedef enum _clock_attach_id +{ + + kFRO12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0, 0), + kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 1) | MUX_B(CM_MAINCLKSELB, 0, 0), + kWDT_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 2) | MUX_B(CM_MAINCLKSELB, 0, 0), + kFRO_HF_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 3) | MUX_B(CM_MAINCLKSELB, 0, 0), + kSYS_PLL_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 2, 0), + kOSC32K_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 3, 0), + + kFRO12M_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 0), + kEXT_CLK_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 1), + kWDT_OSC_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 2), + kOSC32K_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 3), + kNONE_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 7), + + kMAIN_CLK_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 0), + kFRO12M_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 1), + + kMAIN_CLK_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 0), + kSYS_PLL_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 1), + kFRO_HF_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 2), + kNONE_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 7), + + kMAIN_CLK_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 0), + kSYS_PLL_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 1), + kFRO_HF_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 3), + kNONE_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 7), + + kFRO12M_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 0), + kFRO_HF_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 1), + kSYS_PLL_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 2), + kMCLK_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 3), + kFRG_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 4), + kNONE_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 7), + + kFRO12M_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 0), + kFRO_HF_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 1), + kSYS_PLL_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 2), + kMCLK_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 3), + kFRG_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 4), + kNONE_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 7), + + kFRO12M_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 0), + kFRO_HF_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 1), + kSYS_PLL_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 2), + kMCLK_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 3), + kFRG_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 4), + kNONE_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 7), + + kFRO12M_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 0), + kFRO_HF_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 1), + kSYS_PLL_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 2), + kMCLK_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 3), + kFRG_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 4), + kNONE_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 7), + + kFRO12M_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 0), + kFRO_HF_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 1), + kSYS_PLL_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 2), + kMCLK_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 3), + kFRG_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 4), + kNONE_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 7), + + kFRO12M_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 0), + kFRO_HF_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 1), + kSYS_PLL_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 2), + kMCLK_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 3), + kFRG_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 4), + kNONE_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 7), + + kFRO12M_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 0), + kFRO_HF_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 1), + kSYS_PLL_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 2), + kMCLK_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 3), + kFRG_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 4), + kNONE_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 7), + + kFRO12M_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 0), + kFRO_HF_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 1), + kSYS_PLL_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 2), + kMCLK_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 3), + kFRG_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 4), + kNONE_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 7), + + kMAIN_CLK_to_FRG = MUX_A(CM_FRGCLKSEL, 0), + kSYS_PLL_to_FRG = MUX_A(CM_FRGCLKSEL, 1), + kFRO12M_to_FRG = MUX_A(CM_FRGCLKSEL, 2), + kFRO_HF_to_FRG = MUX_A(CM_FRGCLKSEL, 3), + kNONE_to_FRG = MUX_A(CM_FRGCLKSEL, 7), + + kFRO_HF_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 0), + kSYS_PLL_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 1), + kMAIN_CLK_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 2), + kNONE_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 7), + + kFRO12M_to_DMIC = MUX_A(CM_DMICCLKSEL, 0), + kFRO_HF_to_DMIC = MUX_A(CM_DMICCLKSEL, 1), + kSYS_PLL_to_DMIC = MUX_A(CM_DMICCLKSEL, 2), + kMCLK_to_DMIC = MUX_A(CM_DMICCLKSEL, 3), + kMAIN_CLK_to_DMIC = MUX_A(CM_DMICCLKSEL, 4), + kWDT_CLK_to_DMIC = MUX_A(CM_DMICCLKSEL, 5), + kNONE_to_DMIC = MUX_A(CM_DMICCLKSEL, 7), + + kFRO_HF_to_USB_CLK = MUX_A(CM_USBCLKSEL, 0), + kSYS_PLL_to_USB_CLK = MUX_A(CM_USBCLKSEL, 1), + kMAIN_CLK_to_USB_CLK = MUX_A(CM_USBCLKSEL, 2), + kNONE_to_USB_CLK = MUX_A(CM_USBCLKSEL, 7), + + kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 0), + kEXT_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 1), + kWDT_OSC_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 2), + kFRO_HF_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 3), + kSYS_PLL_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 4), + kFRO12M_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 5), + kOSC32K_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 6), + kNONE_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 7), + kNONE_to_NONE = (int)0x80000000U, +} clock_attach_id_t; + +/* Clock dividers */ +typedef enum _clock_div_name +{ + kCLOCK_DivSystickClk = 0, + kCLOCK_DivTraceClk = 1, + kCLOCK_DivAhbClk = 32, + kCLOCK_DivClkOut = 33, + kCLOCK_DivSpifiClk = 36, + kCLOCK_DivAdcAsyncClk = 37, + kCLOCK_DivUsbClk = 38, + kCLOCK_DivFrg = 40, + kCLOCK_DivDmicClk = 42, + kCLOCK_DivFxI2s0MClk = 43 +} clock_div_name_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +static inline void CLOCK_EnableClock(clock_ip_name_t clk) +{ + uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk); + if (index < 2UL) + { + SYSCON->AHBCLKCTRLSET[index] = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } + else + { + ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } +} + +static inline void CLOCK_DisableClock(clock_ip_name_t clk) +{ + uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk); + if (index < 2UL) + { + SYSCON->AHBCLKCTRLCLR[index] = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } + else + { + ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } +} +/** + * @brief FLASH Access time definitions + */ +typedef enum _clock_flashtim +{ + kCLOCK_Flash1Cycle = 0, /*!< Flash accesses use 1 CPU clock */ + kCLOCK_Flash2Cycle, /*!< Flash accesses use 2 CPU clocks */ + kCLOCK_Flash3Cycle, /*!< Flash accesses use 3 CPU clocks */ + kCLOCK_Flash4Cycle, /*!< Flash accesses use 4 CPU clocks */ + kCLOCK_Flash5Cycle, /*!< Flash accesses use 5 CPU clocks */ + kCLOCK_Flash6Cycle, /*!< Flash accesses use 6 CPU clocks */ + kCLOCK_Flash7Cycle, /*!< Flash accesses use 7 CPU clocks */ +} clock_flashtim_t; + +/** + * @brief Set FLASH memory access time in clocks + * @param clks : Clock cycles for FLASH access + * @return Nothing + */ +static inline void CLOCK_SetFLASHAccessCycles(clock_flashtim_t clks) +{ + uint32_t tmp; + + tmp = SYSCON->FLASHCFG & ~(SYSCON_FLASHCFG_FLASHTIM_MASK); + + /* Don't alter lower bits */ + SYSCON->FLASHCFG = tmp | ((uint32_t)clks << SYSCON_FLASHCFG_FLASHTIM_SHIFT); +} + +/** + * @brief Initialize the Core clock to given frequency (12, 48 or 96 MHz). + * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed output is + * enabled. + * @param iFreq : Desired frequency (must be one of CLK_FRO_12MHZ or CLK_FRO_48MHZ or CLK_FRO_96MHZ) + * @return returns success or fail status. + */ +status_t CLOCK_SetupFROClocking(uint32_t iFreq); +/** + * @brief Configure the clock selection muxes. + * @param connection : Clock to be configured. + * @return Nothing + */ +void CLOCK_AttachClk(clock_attach_id_t connection); +/** + * @brief Get the actual clock attach id. + * This fuction uses the offset in input attach id, then it reads the actual source value in + * the register and combine the offset to obtain an actual attach id. + * @param attachId : Clock attach id to get. + * @return Clock source value. + */ +clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId); +/** + * @brief Setup peripheral clock dividers. + * @param div_name : Clock divider name + * @param divided_by_value: Value to be divided + * @param reset : Whether to reset the divider counter. + * @return Nothing + */ +void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset); +/** + * @brief Set the flash wait states for the input freuqency. + * @param iFreq : Input frequency + * @return Nothing + */ +void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq); +/*! @brief Return Frequency of selected clock + * @return Frequency of selected clock + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName); + +/*! @brief Return Input frequency for the Fractional baud rate generator + * @return Input Frequency for FRG + */ +uint32_t CLOCK_GetFRGInputClock(void); + +/*! @brief Return Input frequency for the DMIC + * @return Input Frequency for DMIC + */ +uint32_t CLOCK_GetDmicClkFreq(void); + +/*! @brief Return Input frequency for the FRG + * @return Input Frequency for FRG + */ +uint32_t CLOCK_GetFrgClkFreq(void); + +/*! @brief Set output of the Fractional baud rate generator + * @param freq : Desired output frequency + * @return Error Code 0 - fail 1 - success + */ +uint32_t CLOCK_SetFRGClock(uint32_t freq); + +/*! @brief Return Frequency of FRO 12MHz + * @return Frequency of FRO 12MHz + */ +uint32_t CLOCK_GetFro12MFreq(void); +/*! @brief Return Frequency of External Clock + * @return Frequency of External Clock. If no external clock is used returns 0. + */ +uint32_t CLOCK_GetExtClkFreq(void); +/*! @brief Return Frequency of Watchdog Oscillator + * @return Frequency of Watchdog Oscillator + */ +uint32_t CLOCK_GetWdtOscFreq(void); +/*! @brief Return Frequency of High-Freq output of FRO + * @return Frequency of High-Freq output of FRO + */ +uint32_t CLOCK_GetFroHfFreq(void); +/*! @brief Return Frequency of USB + * @return Frequency of USB + */ +uint32_t CLOCK_GetUsbClkFreq(void); +/*! @brief Return Frequency of PLL + * @return Frequency of PLL + */ +uint32_t CLOCK_GetPllOutFreq(void); +/*! @brief Return Frequency of 32kHz osc + * @return Frequency of 32kHz osc + */ +uint32_t CLOCK_GetOsc32KFreq(void); +/*! @brief Return Frequency of Core System + * @return Frequency of Core System + */ +uint32_t CLOCK_GetCoreSysClkFreq(void); +/*! @brief Return Frequency of I2S MCLK Clock + * @return Frequency of I2S MCLK Clock + */ +uint32_t CLOCK_GetI2SMClkFreq(void); +/*! @brief Return Frequency of Flexcomm functional Clock + * @return Frequency of Flexcomm functional Clock + */ +uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id); +/*! @brief Return Frequency of Adc Clock + * @return Frequency of Adc Clock. + */ +uint32_t CLOCK_GetAdcClkFreq(void); +/*! @brief Return Asynchronous APB Clock source + * @return Asynchronous APB CLock source + */ +__STATIC_INLINE async_clock_src_t CLOCK_GetAsyncApbClkSrc(void) +{ + return (async_clock_src_t)((uint32_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA & 0x3UL)); +} +/*! @brief Return Frequency of Asynchronous APB Clock + * @return Frequency of Asynchronous APB Clock Clock + */ +uint32_t CLOCK_GetAsyncApbClkFreq(void); +/*! @brief Return System PLL input clock rate + * @return System PLL input clock rate + */ +uint32_t CLOCK_GetSystemPLLInClockRate(void); + +/*! @brief Return System PLL output clock rate + * @param recompute : Forces a PLL rate recomputation if true + * @return System PLL output clock rate + * @note The PLL rate is cached in the driver in a variable as + * the rate computation function can take some time to perform. It + * is recommended to use 'false' with the 'recompute' parameter. + */ +uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute); + +/*! @brief Enables and disables PLL bypass mode + * @brief bypass : true to bypass PLL (PLL output = PLL input, false to disable bypass + * @return System PLL output clock rate + */ +__STATIC_INLINE void CLOCK_SetBypassPLL(bool bypass) +{ + if (bypass) + { + SYSCON->SYSPLLCTRL |= (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT); + } + else + { + SYSCON->SYSPLLCTRL &= ~(1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT); + } +} + +/*! @brief Check if PLL is locked or not + * @return true if the PLL is locked, false if not locked + */ +__STATIC_INLINE bool CLOCK_IsSystemPLLLocked(void) +{ + return (bool)((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) != 0UL); +} + +/*! @brief Store the current PLL rate + * @param rate: Current rate of the PLL + * @return Nothing + **/ +void CLOCK_SetStoredPLLClockRate(uint32_t rate); + +/*! @brief PLL configuration structure flags for 'flags' field + * These flags control how the PLL configuration function sets up the PLL setup structure.
+ * + * When the PLL_CONFIGFLAG_USEINRATE flag is selected, the 'InputRate' field in the + * configuration structure must be assigned with the expected PLL frequency. If the + * PLL_CONFIGFLAG_USEINRATE is not used, 'InputRate' is ignored in the configuration + * function and the driver will determine the PLL rate from the currently selected + * PLL source. This flag might be used to configure the PLL input clock more accurately + * when using the WDT oscillator or a more dyanmic CLKIN source.
+ * + * When the PLL_CONFIGFLAG_FORCENOFRACT flag is selected, the PLL hardware for the + * automatic bandwidth selection, Spread Spectrum (SS) support, and fractional M-divider + * are not used.
+ */ +#define PLL_CONFIGFLAG_USEINRATE (1U << 0U) /*!< Flag to use InputRate in PLL configuration structure for setup */ +#define PLL_CONFIGFLAG_FORCENOFRACT \ + (1U << 2U) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or \ + SS hardware */ + +/*! @brief PLL Spread Spectrum (SS) Programmable modulation frequency + * See (MF) field in the SYSPLLSSCTRL1 register in the UM. + */ +typedef enum _ss_progmodfm +{ + kSS_MF_512 = (0 << 20), /*!< Nss = 512 (fm ? 3.9 - 7.8 kHz) */ + kSS_MF_384 = (1 << 20), /*!< Nss ?= 384 (fm ? 5.2 - 10.4 kHz) */ + kSS_MF_256 = (2 << 20), /*!< Nss = 256 (fm ? 7.8 - 15.6 kHz) */ + kSS_MF_128 = (3 << 20), /*!< Nss = 128 (fm ? 15.6 - 31.3 kHz) */ + kSS_MF_64 = (4 << 20), /*!< Nss = 64 (fm ? 32.3 - 64.5 kHz) */ + kSS_MF_32 = (5 << 20), /*!< Nss = 32 (fm ? 62.5- 125 kHz) */ + kSS_MF_24 = (6 << 20), /*!< Nss ?= 24 (fm ? 83.3- 166.6 kHz) */ + kSS_MF_16 = (7 << 20) /*!< Nss = 16 (fm ? 125- 250 kHz) */ +} ss_progmodfm_t; + +/*! @brief PLL Spread Spectrum (SS) Programmable frequency modulation depth + * See (MR) field in the SYSPLLSSCTRL1 register in the UM. + */ +typedef enum _ss_progmoddp +{ + kSS_MR_K0 = (0 << 23), /*!< k = 0 (no spread spectrum) */ + kSS_MR_K1 = (1 << 23), /*!< k = 1 */ + kSS_MR_K1_5 = (2 << 23), /*!< k = 1.5 */ + kSS_MR_K2 = (3 << 23), /*!< k = 2 */ + kSS_MR_K3 = (4 << 23), /*!< k = 3 */ + kSS_MR_K4 = (5 << 23), /*!< k = 4 */ + kSS_MR_K6 = (6 << 23), /*!< k = 6 */ + kSS_MR_K8 = (7 << 23) /*!< k = 8 */ +} ss_progmoddp_t; + +/*! @brief PLL Spread Spectrum (SS) Modulation waveform control + * See (MC) field in the SYSPLLSSCTRL1 register in the UM.
+ * Compensation for low pass filtering of the PLL to get a triangular + * modulation at the output of the PLL, giving a flat frequency spectrum. + */ +typedef enum _ss_modwvctrl +{ + kSS_MC_NOC = (0 << 26), /*!< no compensation */ + kSS_MC_RECC = (2 << 26), /*!< recommended setting */ + kSS_MC_MAXC = (3 << 26), /*!< max. compensation */ +} ss_modwvctrl_t; + +/*! @brief PLL configuration structure + * + * This structure can be used to configure the settings for a PLL + * setup structure. Fill in the desired configuration for the PLL + * and call the PLL setup function to fill in a PLL setup structure. + */ +typedef struct _pll_config +{ + uint32_t desiredRate; /*!< Desired PLL rate in Hz */ + uint32_t inputRate; /*!< PLL input clock in Hz, only used if PLL_CONFIGFLAG_USEINRATE flag is set */ + uint32_t flags; /*!< PLL configuration flags, Or'ed value of PLL_CONFIGFLAG_* definitions */ + ss_progmodfm_t ss_mf; /*!< SS Programmable modulation frequency, only applicable when not using + PLL_CONFIGFLAG_FORCENOFRACT flag */ + ss_progmoddp_t ss_mr; /*!< SS Programmable frequency modulation depth, only applicable when not using + PLL_CONFIGFLAG_FORCENOFRACT flag */ + ss_modwvctrl_t + ss_mc; /*!< SS Modulation waveform control, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */ + bool mfDither; /*!< false for fixed modulation frequency or true for dithering, only applicable when not using + PLL_CONFIGFLAG_FORCENOFRACT flag */ + +} pll_config_t; + +/*! @brief PLL setup structure flags for 'flags' field + * These flags control how the PLL setup function sets up the PLL + */ +#define PLL_SETUPFLAG_POWERUP (1U << 0U) /*!< Setup will power on the PLL after setup */ +#define PLL_SETUPFLAG_WAITLOCK (1U << 1U) /*!< Setup will wait for PLL to lock, implying the PLL will be pwoered on */ +#define PLL_SETUPFLAG_ADGVOLT (1U << 2U) /*!< Optimize system voltage for the new PLL rate */ +#define PLL_SETUPFLAG_USEFEEDBACKDIV2 (1U << 3U) /*!< Use feedback divider by 2 in divider path */ + +/*! @brief PLL setup structure + * This structure can be used to pre-build a PLL setup configuration + * at run-time and quickly set the PLL to the configuration. It can be + * populated with the PLL setup function. If powering up or waiting + * for PLL lock, the PLL input clock source should be configured prior + * to PLL setup. + */ +typedef struct _pll_setup +{ + uint32_t syspllctrl; /*!< PLL control register SYSPLLCTRL */ + uint32_t syspllndec; /*!< PLL NDEC register SYSPLLNDEC */ + uint32_t syspllpdec; /*!< PLL PDEC register SYSPLLPDEC */ + uint32_t syspllssctrl[2]; /*!< PLL SSCTL registers SYSPLLSSCTRL */ + uint32_t pllRate; /*!< Acutal PLL rate */ + uint32_t flags; /*!< PLL setup flags, Or'ed value of PLL_SETUPFLAG_* definitions */ +} pll_setup_t; + +/*! @brief PLL status definitions + */ +typedef enum _pll_error +{ + kStatus_PLL_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< PLL operation was successful */ + kStatus_PLL_OutputTooLow = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< PLL output rate request was too low */ + kStatus_PLL_OutputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< PLL output rate request was too high */ + kStatus_PLL_InputTooLow = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< PLL input rate is too low */ + kStatus_PLL_InputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< PLL input rate is too high */ + kStatus_PLL_OutsideIntLimit = MAKE_STATUS(kStatusGroup_Generic, 5) /*!< Requested output rate isn't possible */ +} pll_error_t; + +/*! @brief USB clock source definition. */ +typedef enum _clock_usb_src +{ + kCLOCK_UsbSrcFro = (uint32_t)kCLOCK_FroHf, /*!< Use FRO 96 or 48 MHz. */ + kCLOCK_UsbSrcSystemPll = (uint32_t)kCLOCK_PllOut, /*!< Use System PLL output. */ + kCLOCK_UsbSrcMainClock = (uint32_t)kCLOCK_CoreSysClk, /*!< Use Main clock. */ + kCLOCK_UsbSrcNone = SYSCON_USBCLKSEL_SEL( + 7) /*!< Use None, this may be selected in order to reduce power when no output is needed. */ +} clock_usb_src_t; + +/*! @brief Return System PLL output clock rate from setup structure + * @param pSetup : Pointer to a PLL setup structure + * @return System PLL output clock rate calculated from the setup structure + */ +uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup); + +/*! @brief Set PLL output based on the passed PLL setup data + * @param pControl : Pointer to populated PLL control structure to generate setup with + * @param pSetup : Pointer to PLL setup structure to be filled + * @return PLL_ERROR_SUCCESS on success, or PLL setup error code + * @note Actual frequency for setup may vary from the desired frequency based on the + * accuracy of input clocks, rounding, non-fractional PLL mode, etc. + */ +pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup); + +/*! @brief Set PLL output from PLL setup structure (precise frequency) + * @param pSetup : Pointer to populated PLL setup structure + * @param flagcfg : Flag configuration for PLL config structure + * @return PLL_ERROR_SUCCESS on success, or PLL setup error code + * @note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg); + +/** + * @brief Set PLL output from PLL setup structure (precise frequency) + * @param pSetup : Pointer to populated PLL setup structure + * @return kStatus_PLL_Success on success, or PLL setup error code + * @note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup); + +/*! @brief Set PLL output based on the multiplier and input frequency + * @param multiply_by : multiplier + * @param input_freq : Clock input frequency of the PLL + * @return Nothing + * @note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this + * function does not disable or enable PLL power, wait for PLL lock, + * or adjust system voltages. These must be done in the application. + * The function will not alter any source clocks (ie, main systen clock) + * that may use the PLL, so these should be setup prior to and after + * exiting the function. + */ +void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq); + +/*! @brief Disable USB FS clock. + * + * Disable USB FS clock. + */ +static inline void CLOCK_DisableUsbfs0Clock(void) +{ + CLOCK_DisableClock(kCLOCK_Usbd0); +} +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_CLOCK_H_ */ diff --git a/drivers/fsl_common.c b/drivers/fsl_common.c new file mode 100644 index 0000000..ec52acb --- /dev/null +++ b/drivers/fsl_common.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#define SDK_MEM_MAGIC_NUMBER 12345U + +typedef struct _mem_align_control_block +{ + uint16_t identifier; /*!< Identifier for the memory control block. */ + uint16_t offset; /*!< offset from aligned address to real address */ +} mem_align_cb_t; + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.common" +#endif + +#ifndef __GIC_PRIO_BITS +#if defined(ENABLE_RAM_VECTOR_TABLE) +uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) +{ +#ifdef __VECTOR_TABLE +#undef __VECTOR_TABLE +#endif + +/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) + extern uint32_t Image$$VECTOR_ROM$$Base[]; + extern uint32_t Image$$VECTOR_RAM$$Base[]; + extern uint32_t Image$$RW_m_data$$Base[]; + +#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) +#elif defined(__ICCARM__) + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#elif defined(__GNUC__) + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; + extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; + uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); +#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */ + uint32_t n; + uint32_t ret; + uint32_t irqMaskValue; + + irqMaskValue = DisableGlobalIRQ(); + if (SCB->VTOR != (uint32_t)__VECTOR_RAM) + { + /* Copy the vector table from ROM to RAM */ + for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + + ret = __VECTOR_RAM[(int32_t)irq + 16]; + /* make sure the __VECTOR_RAM is noncachable */ + __VECTOR_RAM[(int32_t)irq + 16] = irqHandler; + + EnableGlobalIRQ(irqMaskValue); + SDK_ISR_EXIT_BARRIER; + + return ret; +} +#endif /* ENABLE_RAM_VECTOR_TABLE. */ +#endif /* __GIC_PRIO_BITS. */ + +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) + +/* + * When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value, + * powerlib should be used instead of these functions. + */ +#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0)) + +/* + * When the SYSCON STARTER registers are discontinuous, these functions are + * implemented in fsl_power.c. + */ +#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) + +void EnableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t intNumber = (uint32_t)interrupt; + + uint32_t index = 0; + + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + SYSCON->STARTERSET[index] = 1UL << intNumber; + (void)EnableIRQ(interrupt); /* also enable interrupt at NVIC */ +} + +void DisableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t intNumber = (uint32_t)interrupt; + + (void)DisableIRQ(interrupt); /* also disable interrupt at NVIC */ + uint32_t index = 0; + + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + SYSCON->STARTERCLR[index] = 1UL << intNumber; +} +#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */ +#endif /* FSL_FEATURE_POWERLIB_EXTEND */ +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + +void *SDK_Malloc(size_t size, size_t alignbytes) +{ + mem_align_cb_t *p_cb = NULL; + uint32_t alignedsize; + + /* Check overflow. */ + alignedsize = SDK_SIZEALIGN(size, alignbytes); + if (alignedsize < size) + { + return NULL; + } + + if (alignedsize > SIZE_MAX - alignbytes - sizeof(mem_align_cb_t)) + { + return NULL; + } + + alignedsize += alignbytes + sizeof(mem_align_cb_t); + + union + { + void *pointer_value; + uint32_t unsigned_value; + } p_align_addr, p_addr; + + p_addr.pointer_value = malloc(alignedsize); + + if (p_addr.pointer_value == NULL) + { + return NULL; + } + + p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes); + + p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U); + p_cb->identifier = SDK_MEM_MAGIC_NUMBER; + p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value); + + return p_align_addr.pointer_value; +} + +void SDK_Free(void *ptr) +{ + union + { + void *pointer_value; + uint32_t unsigned_value; + } p_free; + p_free.pointer_value = ptr; + mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U); + + if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER) + { + return; + } + + p_free.unsigned_value = p_free.unsigned_value - p_cb->offset; + + free(p_free.pointer_value); +} + +/*! + * @brief Delay function bases on while loop, every loop includes three instructions. + * + * @param count Counts of loop needed for dalay. + */ +#if defined(SDK_DELAY_USE_DWT) && defined(DWT) +static void enableCpuCycleCounter(void) +{ + /* Make sure the DWT trace fucntion is enabled. */ + if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR)) + { + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + } + + /* CYCCNT not supported on this device. */ + assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk)); + + /* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */ + if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL)) + { + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + } +} + +static uint32_t getCpuCycleCount(void) +{ + return DWT->CYCCNT; +} +#elif defined __XCC__ +extern uint32_t xthal_get_ccount(void); +static void enableCpuCycleCounter(void) +{ + /* do nothing */ +} + +static uint32_t getCpuCycleCount(void) +{ + return xthal_get_ccount(); +} +#endif + +#ifndef __XCC__ +#if (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) +#if defined(__CC_ARM) /* This macro is arm v5 specific */ +/* clang-format off */ +__ASM static void DelayLoop(uint32_t count) +{ +loop + SUBS R0, R0, #1 + CMP R0, #0 + BNE loop + BX LR +} +/* clang-format on */ +#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__) +/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler, + * use SUB and CMP here for compatibility */ +static void DelayLoop(uint32_t count) +{ + __ASM volatile(" MOV R0, %0" : : "r"(count)); + __ASM volatile( + "loop: \n" +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) + " SUB R0, R0, #1 \n" +#else + " SUBS R0, R0, #1 \n" +#endif + " CMP R0, #0 \n" + + " BNE loop \n"); +} +#endif /* defined(__CC_ARM) */ +#endif /* (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) */ +#endif /* __XCC__ */ +/*! + * @brief Delay at least for some time. + * Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have + * effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delayTime_us and + * coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delayTime_us only supports + * up to 4294967 in current code. If long time delay is needed, please implement a new delay function. + * + * @param delayTime_us Delay time in unit of microsecond. + * @param coreClock_Hz Core clock frequency with Hz. + */ +void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz) +{ + assert(0U != delayTime_us); + uint64_t count = USEC_TO_COUNT(delayTime_us, coreClock_Hz); + assert(count <= UINT32_MAX); + +#if defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) /* Use DWT for better accuracy */ + + enableCpuCycleCounter(); + /* Calculate the count ticks. */ + count += getCpuCycleCount(); + + if (count > UINT32_MAX) + { + count -= UINT32_MAX; + /* Wait for cyccnt overflow. */ + while (count < getCpuCycleCount()) + { + } + } + + /* Wait for cyccnt reach count value. */ + while (count > getCpuCycleCount()) + { + } +#else + /* Divide value may be different in various environment to ensure delay is precise. + * Every loop count includes three instructions, due to Cortex-M7 sometimes executes + * two instructions in one period, through test here set divide 1.5. Other M cores use + * divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does + * not matter because other instructions outside while loop is enough to fill the time. + */ +#if (__CORTEX_M == 7) + count = count / 3U * 2U; +#else + count = count / 4U; +#endif + DelayLoop((uint32_t)count); +#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) */ +} diff --git a/drivers/fsl_common.h b/drivers/fsl_common.h new file mode 100644 index 0000000..c7da1b5 --- /dev/null +++ b/drivers/fsl_common.h @@ -0,0 +1,954 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_COMMON_H_ +#define _FSL_COMMON_H_ + +#include +#include +#include +#include +#include + +#if defined(__ICCARM__) || (defined(__CC_ARM) || defined(__ARMCC_VERSION)) || defined(__GNUC__) +#include +#endif + +/* + * For CMSIS pack RTE. + * CMSIS pack RTE generates "RTC_Components.h" which contains the statements + * of the related element for all selected software components. + */ +#ifdef _RTE_ +#include "RTE_Components.h" +#endif + +#include "fsl_device_registers.h" + +/*! + * @addtogroup ksdk_common + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Construct a status code value from a group and code number. */ +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) + +/*! @brief Construct the version number for drivers. */ +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/*! @name Driver version */ +/*@{*/ +/*! @brief common driver version. */ +#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 2, 9)) +/*@}*/ + +/* Debug console type definition. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */ + +/*! @brief Status group numbers. */ +enum _status_groups +{ + kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ + kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */ + kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */ + kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */ + kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */ + kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */ + kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */ + kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */ + kStatusGroup_UART = 10, /*!< Group number for UART status codes. */ + kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */ + kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */ + kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */ + kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/ + kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/ + kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/ + kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */ + kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ + kStatusGroup_SAI = 19, /*!< Group number for SAI status code */ + kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */ + kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ + kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ + kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ + kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */ + kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */ + kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */ + kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */ + kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */ + kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */ + kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */ + kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ + kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ + kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ + kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */ + kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */ + kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */ + kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */ + kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */ + kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */ + kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */ + kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */ + kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ + kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ + kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ + kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */ + kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */ + kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */ + kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/ + kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */ + kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */ + kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */ + kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */ + kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */ + kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/ + kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/ + kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/ + kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/ + kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */ + kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */ + kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */ + kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */ + kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */ + kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */ + kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */ + kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */ + kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */ + kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */ + kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */ + kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */ + kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ + kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ + kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */ + kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */ + kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */ + kStatusGroup_SFA = 103, /*!< Group number for SFA status codes*/ + kStatusGroup_SPC = 104, /*!< Group number for SPC status codes. */ + kStatusGroup_PUF = 105, /*!< Group number for PUF status codes. */ + kStatusGroup_TOUCH_PANEL = 106, /*!< Group number for touch panel status codes */ + + kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */ + kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */ + kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */ + kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */ + kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */ + kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */ + kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */ + kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */ + kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */ + kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */ + kStatusGroup_LED = 137, /*!< Group number for LED status codes. */ + kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */ + kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */ + kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */ + kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */ + kStatusGroup_LIST = 142, /*!< Group number for List status codes. */ + kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */ + kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */ + kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */ + kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */ + kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/ + kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */ + kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */ + kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */ + kStatusGroup_SDIOSLV = 151, /*!< Group number for SDIOSLV status codes. */ + kStatusGroup_MECC = 152, /*!< Group number for MECC status codes. */ + kStatusGroup_ENET_QOS = 153, /*!< Group number for ENET_QOS status codes. */ + kStatusGroup_LOG = 154, /*!< Group number for LOG status codes. */ +}; + +/*! \public + * @brief Generic status return codes. + */ +enum +{ + kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< Generic status for Success. */ + kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< Generic status for Fail. */ + kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< Generic status for read only failure. */ + kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< Generic status for out of range access. */ + kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Generic status for invalid argument check. */ + kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Generic status for timeout. */ + kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Generic status for no transfer in progress. */ +}; + +/*! @brief Type used for all status and error return values. */ +typedef int32_t status_t; + +/* + * Macro guard for whether to use default weak IRQ implementation in drivers + */ +#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ +#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1 +#endif + +/*! @name Min/max macros */ +/* @{ */ +#if !defined(MIN) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#if !defined(MAX) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +/* @} */ + +/*! @brief Computes the number of elements in an array. */ +#if !defined(ARRAY_SIZE) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/*! @name UINT16_MAX/UINT32_MAX value */ +/* @{ */ +#if !defined(UINT16_MAX) +#define UINT16_MAX ((uint16_t)-1) +#endif + +#if !defined(UINT32_MAX) +#define UINT32_MAX ((uint32_t)-1) +#endif +/* @} */ + +/*! @name Timer utilities */ +/* @{ */ +/*! Macro to convert a microsecond period to raw count value */ +#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U) +/*! Macro to convert a raw count value to microsecond */ +#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000000U / (clockFreqInHz)) + +/*! Macro to convert a millisecond period to raw count value */ +#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U) +/*! Macro to convert a raw count value to millisecond */ +#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000U / (clockFreqInHz)) +/* @} */ + +/*! @name ISR exit barrier + * @{ + * + * ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + * exception return operation might vector to incorrect interrupt. + * For Cortex-M7, if core speed much faster than peripheral register write speed, + * the peripheral interrupt flags may be still set after exiting ISR, this results to + * the same error similar with errata 83869. + */ +#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U)) +#define SDK_ISR_EXIT_BARRIER __DSB() +#else +#define SDK_ISR_EXIT_BARRIER +#endif + +/* @} */ + +/*! @name Alignment variable definition macros */ +/* @{ */ +#if (defined(__ICCARM__)) +/** + * Workaround to disable MISRA C message suppress warnings for IAR compiler. + * http:/ /supp.iar.com/Support/?note=24725 + */ +_Pragma("diag_suppress=Pm120") +#define SDK_PRAGMA(x) _Pragma(#x) + _Pragma("diag_error=Pm120") +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var +#endif +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var +#endif +#elif defined(__GNUC__) +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) +#endif +#else +#error Toolchain not supported +#define SDK_ALIGN(var, alignbytes) var +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) var +#endif +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) var +#endif +#endif + +/*! Macro to change a value to a given size aligned value */ +#define SDK_SIZEALIGN(var, alignbytes) \ + ((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U))) +/* @} */ + +/*! @name Non-cacheable region definition macros */ +/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or + * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables, + * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables + * will be initialized to zero in system startup. + */ +/* @{ */ +#if (defined(__ICCARM__)) +#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) +#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable" +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable" +#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init" +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init" +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +#endif +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var +#if(defined(__CC_ARM)) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var +#else +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var +#endif +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var +#endif +#elif(defined(__XCC__)) +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes))) +#elif(defined(__GNUC__)) +/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA" + * in your projects to make sure the non-cacheable section variables will be initialized in system startup. + */ +#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes))) +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes))) +#endif +#else +#error Toolchain not supported. +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var +#endif +/* @} */ + +/*! @name Time sensitive region */ +/* @{ */ +#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE +#if (defined(__ICCARM__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess" +#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess" +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func +#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func +#elif(defined(__GNUC__)) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func +#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func +#else +#error Toolchain not supported. +#endif /* defined(__ICCARM__) */ +#else +#if (defined(__ICCARM__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#define AT_QUICKACCESS_SECTION_DATA(func) func +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#define AT_QUICKACCESS_SECTION_DATA(func) func +#elif(defined(__GNUC__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#define AT_QUICKACCESS_SECTION_DATA(func) func +#else +#error Toolchain not supported. +#endif +#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */ +/* @} */ + +/*! @name Ram Function */ +#if (defined(__ICCARM__)) +#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction" +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#elif(defined(__GNUC__)) +#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#else +#error Toolchain not supported. +#endif /* defined(__ICCARM__) */ +/* @} */ + +/*! @name Suppress fallthrough warning macro */ +/* For switch case code block, if case section ends without "break;" statement, there wil be + fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc. + To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each + case section which misses "break;"statement. + */ +/* @{ */ +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) +#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough)) +#else +#define SUPPRESS_FALL_THROUGH_WARNING() +#endif +/* @} */ + +/*! @name Atomic modification + * + * These macros are used for atomic access, such as read-modify-write + * to the peripheral registers. + * + * - SDK_ATOMIC_LOCAL_ADD + * - SDK_ATOMIC_LOCAL_SET + * - SDK_ATOMIC_LOCAL_CLEAR + * - SDK_ATOMIC_LOCAL_TOGGLE + * - SDK_ATOMIC_LOCAL_CLEAR_AND_SET + * + * Take SDK_ATOMIC_LOCAL_CLEAR_AND_SET as an example: the parameter @c addr + * means the address of the peripheral register or variable you want to modify + * atomically, the parameter @c clearBits is the bits to clear, the parameter + * @c setBits it the bits to set. + * For example, to set a 32-bit register bit1:bit0 to 0b10, use like this: + * + * @code + volatile uint32_t * reg = (volatile uint32_t *)REG_ADDR; + + SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, 0x03, 0x02); + @endcode + * + * In this example, the register bit1:bit0 are cleared and bit1 is set, as a result, + * register bit1:bit0 = 0b10. + * + * @note For the platforms don't support exclusive load and store, these macros + * disable the global interrupt to pretect the modification. + * + * @note These macros only guarantee the local processor atomic operations. For + * the multi-processor devices, use hardware semaphore such as SEMA42 to + * guarantee exclusive access if necessary. + * + * @{ + */ + +/* clang-format off */ +#if ((defined(__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined(__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1))) +/* clang-format on */ + +/* If the LDREX and STREX are supported, use them. */ +#define _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, val, ops) \ + do \ + { \ + (val) = __LDREXB(addr); \ + (ops); \ + } while (0UL != __STREXB((val), (addr))) + +#define _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, val, ops) \ + do \ + { \ + (val) = __LDREXH(addr); \ + (ops); \ + } while (0UL != __STREXH((val), (addr))) + +#define _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, val, ops) \ + do \ + { \ + (val) = __LDREXW(addr); \ + (ops); \ + } while (0UL != __STREXW((val), (addr))) + +static inline void _SDK_AtomicLocalAdd1Byte(volatile uint8_t *addr, uint8_t val) +{ + uint8_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val += val); +} + +static inline void _SDK_AtomicLocalAdd2Byte(volatile uint16_t *addr, uint16_t val) +{ + uint16_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val += val); +} + +static inline void _SDK_AtomicLocalAdd4Byte(volatile uint32_t *addr, uint32_t val) +{ + uint32_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val += val); +} + +static inline void _SDK_AtomicLocalSub1Byte(volatile uint8_t *addr, uint8_t val) +{ + uint8_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val -= val); +} + +static inline void _SDK_AtomicLocalSub2Byte(volatile uint16_t *addr, uint16_t val) +{ + uint16_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val -= val); +} + +static inline void _SDK_AtomicLocalSub4Byte(volatile uint32_t *addr, uint32_t val) +{ + uint32_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val -= val); +} + +static inline void _SDK_AtomicLocalSet1Byte(volatile uint8_t *addr, uint8_t bits) +{ + uint8_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val |= bits); +} + +static inline void _SDK_AtomicLocalSet2Byte(volatile uint16_t *addr, uint16_t bits) +{ + uint16_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val |= bits); +} + +static inline void _SDK_AtomicLocalSet4Byte(volatile uint32_t *addr, uint32_t bits) +{ + uint32_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val |= bits); +} + +static inline void _SDK_AtomicLocalClear1Byte(volatile uint8_t *addr, uint8_t bits) +{ + uint8_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val &= ~bits); +} + +static inline void _SDK_AtomicLocalClear2Byte(volatile uint16_t *addr, uint16_t bits) +{ + uint16_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val &= ~bits); +} + +static inline void _SDK_AtomicLocalClear4Byte(volatile uint32_t *addr, uint32_t bits) +{ + uint32_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val &= ~bits); +} + +static inline void _SDK_AtomicLocalToggle1Byte(volatile uint8_t *addr, uint8_t bits) +{ + uint8_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val ^= bits); +} + +static inline void _SDK_AtomicLocalToggle2Byte(volatile uint16_t *addr, uint16_t bits) +{ + uint16_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val ^= bits); +} + +static inline void _SDK_AtomicLocalToggle4Byte(volatile uint32_t *addr, uint32_t bits) +{ + uint32_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val ^= bits); +} + +static inline void _SDK_AtomicLocalClearAndSet1Byte(volatile uint8_t *addr, uint8_t clearBits, uint8_t setBits) +{ + uint8_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits); +} + +static inline void _SDK_AtomicLocalClearAndSet2Byte(volatile uint16_t *addr, uint16_t clearBits, uint16_t setBits) +{ + uint16_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits); +} + +static inline void _SDK_AtomicLocalClearAndSet4Byte(volatile uint32_t *addr, uint32_t clearBits, uint32_t setBits) +{ + uint32_t s_val; + + _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits); +} + +#define SDK_ATOMIC_LOCAL_ADD(addr, val) \ + ((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd1Byte((volatile void*)(addr), (val)) : \ + ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd2Byte((volatile void*)(addr), (val)) : \ + _SDK_AtomicLocalAdd4Byte((volatile void*)(addr), (val)))) + +#define SDK_ATOMIC_LOCAL_SET(addr, bits) \ + ((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet1Byte((volatile void*)(addr), (bits)) : \ + ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet2Byte((volatile void*)(addr), (bits)) : \ + _SDK_AtomicLocalSet4Byte((volatile void*)(addr), (bits)))) + +#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \ + ((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalClear1Byte((volatile void*)(addr), (bits)) : \ + ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalClear2Byte((volatile void*)(addr), (bits)) : \ + _SDK_AtomicLocalClear4Byte((volatile void*)(addr), (bits)))) + +#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \ + ((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalToggle1Byte((volatile void*)(addr), (bits)) : \ + ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalToggle2Byte((volatile void*)(addr), (bits)) : \ + _SDK_AtomicLocalToggle4Byte((volatile void*)(addr), (bits)))) + +#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \ + ((1UL == sizeof(*(addr))) ? _SDK_AtomicLocalClearAndSet1Byte((volatile void*)(addr), (clearBits), (setBits)) : \ + ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalClearAndSet2Byte((volatile void*)(addr), (clearBits), (setBits)) : \ + _SDK_AtomicLocalClearAndSet4Byte((volatile void*)(addr), (clearBits), (setBits)))) +#else + +#define SDK_ATOMIC_LOCAL_ADD(addr, val) \ + do { \ + uint32_t s_atomicOldInt; \ + s_atomicOldInt = DisableGlobalIRQ(); \ + *(addr) += (val); \ + EnableGlobalIRQ(s_atomicOldInt); \ + } while (0) + +#define SDK_ATOMIC_LOCAL_SET(addr, bits) \ + do { \ + uint32_t s_atomicOldInt; \ + s_atomicOldInt = DisableGlobalIRQ(); \ + *(addr) |= (bits); \ + EnableGlobalIRQ(s_atomicOldInt); \ + } while (0) + +#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \ + do { \ + uint32_t s_atomicOldInt; \ + s_atomicOldInt = DisableGlobalIRQ(); \ + *(addr) &= ~(bits); \ + EnableGlobalIRQ(s_atomicOldInt); \ + } while (0) + +#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \ + do { \ + uint32_t s_atomicOldInt; \ + s_atomicOldInt = DisableGlobalIRQ(); \ + *(addr) ^= (bits); \ + EnableGlobalIRQ(s_atomicOldInt); \ + } while (0) + +#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \ + do { \ + uint32_t s_atomicOldInt; \ + s_atomicOldInt = DisableGlobalIRQ(); \ + *(addr) = (*(addr) & ~(clearBits)) | (setBits); \ + EnableGlobalIRQ(s_atomicOldInt); \ + } while (0) + +#endif +/* @} */ + +#if defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) +void DefaultISR(void); +#endif +/* + * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t + * defined in previous of this file. + */ +#include "fsl_clock.h" + +/* + * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral + */ +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) +#include "fsl_reset.h" +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) + extern "C" +{ +#endif + + /*! + * @brief Enable specific interrupt. + * + * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt + * levels. For example, there are NVIC and intmux. Here the interrupts connected + * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. + * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed + * to NVIC first then routed to core. + * + * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts + * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. + * + * @param interrupt The IRQ number. + * @retval kStatus_Success Interrupt enabled successfully + * @retval kStatus_Fail Failed to enable the interrupt + */ + static inline status_t EnableIRQ(IRQn_Type interrupt) + { + status_t status = kStatus_Success; + + if (NotAvail_IRQn == interrupt) + { + status = kStatus_Fail; + } + +#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) + else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) + { + status = kStatus_Fail; + } +#endif + + else + { +#if defined(__GIC_PRIO_BITS) + GIC_EnableIRQ(interrupt); +#else + NVIC_EnableIRQ(interrupt); +#endif + } + + return status; + } + + /*! + * @brief Disable specific interrupt. + * + * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt + * levels. For example, there are NVIC and intmux. Here the interrupts connected + * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. + * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed + * to NVIC first then routed to core. + * + * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts + * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. + * + * @param interrupt The IRQ number. + * @retval kStatus_Success Interrupt disabled successfully + * @retval kStatus_Fail Failed to disable the interrupt + */ + static inline status_t DisableIRQ(IRQn_Type interrupt) + { + status_t status = kStatus_Success; + + if (NotAvail_IRQn == interrupt) + { + status = kStatus_Fail; + } + +#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) + else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) + { + status = kStatus_Fail; + } +#endif + + else + { +#if defined(__GIC_PRIO_BITS) + GIC_DisableIRQ(interrupt); +#else + NVIC_DisableIRQ(interrupt); +#endif + } + + return status; + } + + /*! + * @brief Disable the global IRQ + * + * Disable the global interrupt and return the current primask register. User is required to provided the primask + * register for the EnableGlobalIRQ(). + * + * @return Current primask value. + */ + static inline uint32_t DisableGlobalIRQ(void) + { +#if defined (__XCC__) + return 0; +#else +#if defined(CPSR_I_Msk) + uint32_t cpsr = __get_CPSR() & CPSR_I_Msk; + + __disable_irq(); + + return cpsr; +#else + uint32_t regPrimask = __get_PRIMASK(); + + __disable_irq(); + + return regPrimask; +#endif +#endif + } + + /*! + * @brief Enable the global IRQ + * + * Set the primask register with the provided primask value but not just enable the primask. The idea is for the + * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to + * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair. + * + * @param primask value of primask register to be restored. The primask value is supposed to be provided by the + * DisableGlobalIRQ(). + */ + static inline void EnableGlobalIRQ(uint32_t primask) + { +#if defined (__XCC__) +#else +#if defined(CPSR_I_Msk) + __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask); +#else + __set_PRIMASK(primask); +#endif +#endif + } + +#if defined(ENABLE_RAM_VECTOR_TABLE) + /*! + * @brief install IRQ handler + * + * @param irq IRQ number + * @param irqHandler IRQ handler address + * @return The old IRQ handler address + */ + uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); +#endif /* ENABLE_RAM_VECTOR_TABLE. */ + +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) + + /* + * When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value, + * powerlib should be used instead of these functions. + */ +#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0)) + /*! + * @brief Enable specific interrupt for wake-up from deep-sleep mode. + * + * Enable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly). + * + * @param interrupt The IRQ number. + */ + void EnableDeepSleepIRQ(IRQn_Type interrupt); + + /*! + * @brief Disable specific interrupt for wake-up from deep-sleep mode. + * + * Disable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly). + * + * @param interrupt The IRQ number. + */ + void DisableDeepSleepIRQ(IRQn_Type interrupt); +#endif /* FSL_FEATURE_POWERLIB_EXTEND */ +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + + /*! + * @brief Allocate memory with given alignment and aligned size. + * + * This is provided to support the dynamically allocated memory + * used in cache-able region. + * @param size The length required to malloc. + * @param alignbytes The alignment size. + * @retval The allocated memory. + */ + void *SDK_Malloc(size_t size, size_t alignbytes); + + /*! + * @brief Free memory. + * + * @param ptr The memory to be release. + */ + void SDK_Free(void *ptr); + + /*! + * @brief Delay at least for some time. + * Please note that, this API uses while loop for delay, different run-time environments make the time not precise, + * if precise delay count was needed, please implement a new delay function with hardware timer. + * + * @param delayTime_us Delay time in unit of microsecond. + * @param coreClock_Hz Core clock frequency with Hz. + */ + void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz); + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_COMMON_H_ */ diff --git a/drivers/fsl_ctimer.c b/drivers/fsl_ctimer.c new file mode 100644 index 0000000..d15e5b6 --- /dev/null +++ b/drivers/fsl_ctimer.c @@ -0,0 +1,577 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_ctimer.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.ctimer" +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base Ctimer peripheral base address + * + * @return The Timer instance + */ +static uint32_t CTIMER_GetInstance(CTIMER_Type *base); + +/*! + * @brief CTIMER generic IRQ handle function. + * + * @param index FlexCAN peripheral instance index. + */ +static void CTIMER_GenericIRQHandler(uint32_t index); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to Timer bases for each instance. */ +static CTIMER_Type *const s_ctimerBases[] = CTIMER_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to Timer clocks for each instance. */ +static const clock_ip_name_t s_ctimerClocks[] = CTIMER_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET)) +#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) +#if defined(FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET) && FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET +/*! @brief Pointers to Timer resets for each instance, writing a zero asserts the reset */ +static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS_N; +#else +/*! @brief Pointers to Timer resets for each instance, writing a one asserts the reset */ +static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS; +#endif +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */ + +/*! @brief Pointers real ISRs installed by drivers for each instance. */ +static ctimer_callback_t *s_ctimerCallback[sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0])] = {0}; + +/*! @brief Callback type installed by drivers for each instance. */ +static ctimer_callback_type_t ctimerCallbackType[sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0])] = { + kCTIMER_SingleCallback}; + +/*! @brief Array to map timer instance to IRQ number. */ +static const IRQn_Type s_ctimerIRQ[] = CTIMER_IRQS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t CTIMER_GetInstance(CTIMER_Type *base) +{ + uint32_t instance; + uint32_t ctimerArrayCount = (sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ctimerArrayCount; instance++) + { + if (s_ctimerBases[instance] == base) + { + break; + } + } + + assert(instance < ctimerArrayCount); + + return instance; +} + +/*! + * brief Ungates the clock and configures the peripheral for basic operation. + * + * note This API should be called at the beginning of the application before using the driver. + * + * param base Ctimer peripheral base address + * param config Pointer to the user configuration structure. + */ +void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config) +{ + assert(config != NULL); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the timer clock*/ + CLOCK_EnableClock(s_ctimerClocks[CTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) +/* Reset the module. */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET)) + RESET_PeripheralReset(s_ctimerResets[CTIMER_GetInstance(base)]); +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */ + +/* Setup the cimer mode and count select */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) + base->CTCR = CTIMER_CTCR_CTMODE(config->mode) | CTIMER_CTCR_CINSEL(config->input); +#endif + /* Setup the timer prescale value */ + base->PR = CTIMER_PR_PRVAL(config->prescale); +} + +/*! + * brief Gates the timer clock. + * + * param base Ctimer peripheral base address + */ +void CTIMER_Deinit(CTIMER_Type *base) +{ + uint32_t index = CTIMER_GetInstance(base); + /* Stop the timer */ + base->TCR &= ~CTIMER_TCR_CEN_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the timer clock*/ + CLOCK_DisableClock(s_ctimerClocks[index]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Disable IRQ at NVIC Level */ + (void)DisableIRQ(s_ctimerIRQ[index]); +} + +/*! + * brief Fills in the timers configuration structure with the default settings. + * + * The default values are: + * code + * config->mode = kCTIMER_TimerMode; + * config->input = kCTIMER_Capture_0; + * config->prescale = 0; + * endcode + * param config Pointer to the user configuration structure. + */ +void CTIMER_GetDefaultConfig(ctimer_config_t *config) +{ + assert(config != NULL); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + /* Run as a timer */ + config->mode = kCTIMER_TimerMode; + /* This field is ignored when mode is timer */ + config->input = kCTIMER_Capture_0; + /* Timer counter is incremented on every APB bus clock */ + config->prescale = 0; +} + +/*! + * brief Configures the PWM signal parameters. + * + * Enables PWM mode on the match channel passed in and will then setup the match value + * and other match parameters to generate a PWM signal. + * This function can manually assign the specified channel to set the PWM cycle. + * + * note When setting PWM output from multiple output pins, all should use the same PWM + * frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution. + * + * param base Ctimer peripheral base address + * param pwmPeriodChannel Specify the channel to control the PWM period + * param matchChannel Match pin to be used to output the PWM signal + * param dutyCyclePercent PWM pulse width; the value should be between 0 to 100 + * param pwmFreq_Hz PWM signal frequency in Hz + * param srcClock_Hz Timer counter clock in Hz + * param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse, + * if it is 0 then no interrupt will be generated. + * + * return kStatus_Success on success + * kStatus_Fail If matchChannel is equal to pwmPeriodChannel; this channel is reserved to set the PWM cycle + */ +status_t CTIMER_SetupPwm(CTIMER_Type *base, + const ctimer_match_t pwmPeriodChannel, + ctimer_match_t matchChannel, + uint8_t dutyCyclePercent, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + bool enableInt) +{ + assert(pwmFreq_Hz > 0U); + + uint32_t reg; + uint32_t period, pulsePeriod = 0; + uint32_t timerClock = srcClock_Hz / (base->PR + 1U); + uint32_t index = CTIMER_GetInstance(base); + + if (matchChannel == pwmPeriodChannel) + { + return kStatus_Fail; + } + + /* Enable PWM mode on the channel */ + base->PWMC |= (1UL << (uint32_t)matchChannel); + + /* Clear the stop, reset and interrupt bits for this channel */ + reg = base->MCR; + reg &= + ~(((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK | (uint32_t)CTIMER_MCR_MR0S_MASK | (uint32_t)CTIMER_MCR_MR0I_MASK)) + << ((uint32_t)matchChannel * 3U)); + + /* If call back function is valid then enable match interrupt for the channel */ + if (enableInt) + { + reg |= (((uint32_t)CTIMER_MCR_MR0I_MASK) << (CTIMER_MCR_MR0I_SHIFT + ((uint32_t)matchChannel * 3U))); + } + + /* Reset the counter when match on channel 3 */ + reg |= CTIMER_MCR_MR3R_MASK; + + base->MCR = reg; + + /* Calculate PWM period match value */ + period = (timerClock / pwmFreq_Hz) - 1U; + + /* Calculate pulse width match value */ + if (dutyCyclePercent == 0U) + { + pulsePeriod = period + 1U; + } + else + { + pulsePeriod = (period * (100U - (uint32_t)dutyCyclePercent)) / 100U; + } + + /* Specified channel pwmPeriodChannel will define the PWM period */ + base->MR[pwmPeriodChannel] = period; + + /* This will define the PWM pulse period */ + base->MR[matchChannel] = pulsePeriod; + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, ((uint32_t)CTIMER_IR_MR0INT_MASK) << (uint32_t)matchChannel); + /* If call back function is valid then enable interrupt and update the call back function */ + if (enableInt) + { + (void)EnableIRQ(s_ctimerIRQ[index]); + } + + return kStatus_Success; +} + +/*! + * brief Configures the PWM signal parameters. + * + * Enables PWM mode on the match channel passed in and will then setup the match value + * and other match parameters to generate a PWM signal. + * This function can manually assign the specified channel to set the PWM cycle. + * + * note When setting PWM output from multiple output pins, all should use the same PWM + * period + * + * param base Ctimer peripheral base address + * param pwmPeriodChannel Specify the channel to control the PWM period + * param matchChannel Match pin to be used to output the PWM signal + * param pwmPeriod PWM period match value + * param pulsePeriod Pulse width match value + * param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse, + * if it is 0 then no interrupt will be generated. + * + * return kStatus_Success on success + * kStatus_Fail If matchChannel is equal to pwmPeriodChannel; this channel is reserved to set the PWM period + */ +status_t CTIMER_SetupPwmPeriod(CTIMER_Type *base, + const ctimer_match_t pwmPeriodChannel, + ctimer_match_t matchChannel, + uint32_t pwmPeriod, + uint32_t pulsePeriod, + bool enableInt) +{ +/* Some CTimers only have 16bits , so the value is limited*/ +#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B + assert(!((FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32) && (pulsePeriod > 0xFFFFU))); +#endif + + uint32_t reg; + uint32_t index = CTIMER_GetInstance(base); + + if (matchChannel == pwmPeriodChannel) + { + return kStatus_Fail; + } + + /* Enable PWM mode on PWM pulse channel */ + base->PWMC |= (1UL << (uint32_t)matchChannel); + + /* Clear the stop, reset and interrupt bits for PWM pulse channel */ + reg = base->MCR; + reg &= + ~((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK | (uint32_t)CTIMER_MCR_MR0S_MASK | (uint32_t)CTIMER_MCR_MR0I_MASK) + << ((uint32_t)matchChannel * 3U)); + + /* If call back function is valid then enable match interrupt for PWM pulse channel */ + if (enableInt) + { + reg |= (((uint32_t)CTIMER_MCR_MR0I_MASK) << (CTIMER_MCR_MR0I_SHIFT + ((uint32_t)matchChannel * 3U))); + } + + /* Reset the counter when match on PWM period channel (pwmPeriodChannel) */ + reg |= ((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK) << ((uint32_t)pwmPeriodChannel * 3U)); + + base->MCR = reg; + + /* Specified channel pwmPeriodChannel will define the PWM period */ + base->MR[pwmPeriodChannel] = pwmPeriod; + + /* This will define the PWM pulse period */ + base->MR[matchChannel] = pulsePeriod; + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, ((uint32_t)CTIMER_IR_MR0INT_MASK) << (uint32_t)matchChannel); + /* If call back function is valid then enable interrupt and update the call back function */ + if (enableInt) + { + (void)EnableIRQ(s_ctimerIRQ[index]); + } + + return kStatus_Success; +} + +/*! + * brief Updates the duty cycle of an active PWM signal. + * + * note Please use CTIMER_SetupPwmPeriod to update the PWM with high resolution. + * This function can manually assign the specified channel to set the PWM cycle. + * + * param base Ctimer peripheral base address + * param pwmPeriodChannel Specify the channel to control the PWM period + * param matchChannel Match pin to be used to output the PWM signal + * param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100 + */ +void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, + const ctimer_match_t pwmPeriodChannel, + ctimer_match_t matchChannel, + uint8_t dutyCyclePercent) +{ + uint32_t pulsePeriod = 0, period; + + /* Specified channel pwmPeriodChannel defines the PWM period */ + period = base->MR[pwmPeriodChannel]; + + /* For 0% dutycyle, make pulse period greater than period so the event will never occur */ + if (dutyCyclePercent == 0U) + { + pulsePeriod = period + 1U; + } + else + { + pulsePeriod = (period * (100U - (uint32_t)dutyCyclePercent)) / 100U; + } + + /* Update dutycycle */ + base->MR[matchChannel] = pulsePeriod; +} + +/*! + * brief Setup the match register. + * + * User configuration is used to setup the match value and action to be taken when a match occurs. + * + * param base Ctimer peripheral base address + * param matchChannel Match register to configure + * param config Pointer to the match configuration structure + */ +void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config) +{ +/* Some CTimers only have 16bits , so the value is limited*/ +#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B + assert(!(FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32 && config->matchValue > 0xFFFFU)); +#endif + uint32_t reg; + uint32_t index = CTIMER_GetInstance(base); + + /* Set the counter operation when a match on this channel occurs */ + reg = base->MCR; + reg &= + ~((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK | (uint32_t)CTIMER_MCR_MR0S_MASK | (uint32_t)CTIMER_MCR_MR0I_MASK) + << ((uint32_t)matchChannel * 3U)); + reg |= ((uint32_t)(config->enableCounterReset) << (CTIMER_MCR_MR0R_SHIFT + ((uint32_t)matchChannel * 3U))); + reg |= ((uint32_t)(config->enableCounterStop) << (CTIMER_MCR_MR0S_SHIFT + ((uint32_t)matchChannel * 3U))); + reg |= ((uint32_t)(config->enableInterrupt) << (CTIMER_MCR_MR0I_SHIFT + ((uint32_t)matchChannel * 3U))); + base->MCR = reg; + + reg = base->EMR; + /* Set the match output operation when a match on this channel occurs */ + reg &= ~(((uint32_t)CTIMER_EMR_EMC0_MASK) << ((uint32_t)matchChannel * 2U)); + reg |= ((uint32_t)config->outControl) << (CTIMER_EMR_EMC0_SHIFT + ((uint32_t)matchChannel * 2U)); + + /* Set the initial state of the EM bit/output */ + reg &= ~(((uint32_t)CTIMER_EMR_EM0_MASK) << (uint32_t)matchChannel); + reg |= ((uint32_t)config->outPinInitState) << (uint32_t)matchChannel; + base->EMR = reg; + + /* Set the match value */ + base->MR[matchChannel] = config->matchValue; + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, ((uint32_t)CTIMER_IR_MR0INT_MASK) << (uint32_t)matchChannel); + /* If interrupt is enabled then enable interrupt and update the call back function */ + if (config->enableInterrupt) + { + (void)EnableIRQ(s_ctimerIRQ[index]); + } +} + +/*! + * brief Get the status of output match. + * + * This function gets the status of output MAT, whether or not this output is connected to a pin. + * This status is driven to the MAT pins if the match function is selected via IOCON. 0 = LOW. 1 = HIGH. + * + * param base Ctimer peripheral base address + * param matchChannel External match channel, user can obtain the status of multiple match channels + * at the same time by using the logic of "|" + * enumeration ::ctimer_external_match_t + * return The mask of external match channel status flags. Users need to use the + * _ctimer_external_match type to decode the return variables. + */ +uint32_t CTIMER_GetOutputMatchStatus(CTIMER_Type *base, uint32_t matchChannel) +{ + return (base->EMR & matchChannel); +} + +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) +/*! + * brief Setup the capture. + * + * param base Ctimer peripheral base address + * param capture Capture channel to configure + * param edge Edge on the channel that will trigger a capture + * param enableInt Flag to enable channel interrupts, if enabled then the registered call back + * is called upon capture + */ +void CTIMER_SetupCapture(CTIMER_Type *base, + ctimer_capture_channel_t capture, + ctimer_capture_edge_t edge, + bool enableInt) +{ + uint32_t reg = base->CCR; + uint32_t index = CTIMER_GetInstance(base); + + /* Set the capture edge */ + reg &= ~((uint32_t)((uint32_t)CTIMER_CCR_CAP0RE_MASK | (uint32_t)CTIMER_CCR_CAP0FE_MASK | + (uint32_t)CTIMER_CCR_CAP0I_MASK) + << ((uint32_t)capture * 3U)); + reg |= ((uint32_t)edge) << (CTIMER_CCR_CAP0RE_SHIFT + ((uint32_t)capture * 3U)); + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, (((uint32_t)kCTIMER_Capture0Flag) << (uint32_t)capture)); + /* If call back function is valid then enable capture interrupt for the channel and update the call back function */ + if (enableInt) + { + reg |= ((uint32_t)CTIMER_CCR_CAP0I_MASK) << ((uint32_t)capture * 3U); + (void)EnableIRQ(s_ctimerIRQ[index]); + } + base->CCR = reg; +} +#endif + +/*! + * brief Register callback. + * + * param base Ctimer peripheral base address + * param cb_func callback function + * param cb_type callback function type, singular or multiple + */ +void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type) +{ + uint32_t index = CTIMER_GetInstance(base); + s_ctimerCallback[index] = cb_func; + ctimerCallbackType[index] = cb_type; +} + +/*! + * brief CTIMER generic IRQ handle function. + * + * param index FlexCAN peripheral instance index. + */ +static void CTIMER_GenericIRQHandler(uint32_t index) +{ + uint32_t int_stat, i, mask; + /* Get Interrupt status flags */ + int_stat = CTIMER_GetStatusFlags(s_ctimerBases[index]); + /* Clear the status flags that were set */ + CTIMER_ClearStatusFlags(s_ctimerBases[index], int_stat); + if (ctimerCallbackType[index] == kCTIMER_SingleCallback) + { + if (s_ctimerCallback[index][0] != NULL) + { + s_ctimerCallback[index][0](int_stat); + } + } + else + { +#if defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE + for (i = 0; i <= CTIMER_IR_MR3INT_SHIFT; i++) +#else +#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT + for (i = 0; i <= CTIMER_IR_CR3INT_SHIFT; i++) +#else +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT) && FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT) + for (i = 0; i <= CTIMER_IR_CR2INT_SHIFT; i++) +#else + for (i = 0; i <= CTIMER_IR_CR1INT_SHIFT; i++) +#endif /* FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT */ +#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */ +#endif + { + mask = 0x01UL << i; + /* For each status flag bit that was set call the callback function if it is valid */ + if (((int_stat & mask) != 0U) && (s_ctimerCallback[index][i] != NULL)) + { + s_ctimerCallback[index][i](int_stat); + } + } + } + SDK_ISR_EXIT_BARRIER; +} + +/* IRQ handler functions overloading weak symbols in the startup */ +#if defined(CTIMER0) +void CTIMER0_DriverIRQHandler(void); +void CTIMER0_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(0); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(CTIMER1) +void CTIMER1_DriverIRQHandler(void); +void CTIMER1_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(1); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(CTIMER2) +void CTIMER2_DriverIRQHandler(void); +void CTIMER2_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(2); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(CTIMER3) +void CTIMER3_DriverIRQHandler(void); +void CTIMER3_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(3); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(CTIMER4) +void CTIMER4_DriverIRQHandler(void); +void CTIMER4_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(4); + SDK_ISR_EXIT_BARRIER; +} +#endif diff --git a/drivers/fsl_ctimer.h b/drivers/fsl_ctimer.h new file mode 100644 index 0000000..e3a7d92 --- /dev/null +++ b/drivers/fsl_ctimer.h @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_CTIMER_H_ +#define _FSL_CTIMER_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup ctimer + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_CTIMER_DRIVER_VERSION (MAKE_VERSION(2, 2, 1)) /*!< Version 2.2.1 */ +/*@}*/ + +/*! @brief List of Timer capture channels */ +typedef enum _ctimer_capture_channel +{ + kCTIMER_Capture_0 = 0U, /*!< Timer capture channel 0 */ + kCTIMER_Capture_1, /*!< Timer capture channel 1 */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) + kCTIMER_Capture_2, /*!< Timer capture channel 2 */ +#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + kCTIMER_Capture_3 /*!< Timer capture channel 3 */ +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ +} ctimer_capture_channel_t; + +/*! @brief List of capture edge options */ +typedef enum _ctimer_capture_edge +{ + kCTIMER_Capture_RiseEdge = 1U, /*!< Capture on rising edge */ + kCTIMER_Capture_FallEdge = 2U, /*!< Capture on falling edge */ + kCTIMER_Capture_BothEdge = 3U, /*!< Capture on rising and falling edge */ +} ctimer_capture_edge_t; + +/*! @brief List of Timer match registers */ +typedef enum _ctimer_match +{ + kCTIMER_Match_0 = 0U, /*!< Timer match register 0 */ + kCTIMER_Match_1, /*!< Timer match register 1 */ + kCTIMER_Match_2, /*!< Timer match register 2 */ + kCTIMER_Match_3 /*!< Timer match register 3 */ +} ctimer_match_t; + +/*! @brief List of external match */ +typedef enum _ctimer_external_match +{ + kCTIMER_External_Match_0 = (1U << 0), /*!< External match 0 */ + kCTIMER_External_Match_1 = (1U << 1), /*!< External match 1 */ + kCTIMER_External_Match_2 = (1U << 2), /*!< External match 2 */ + kCTIMER_External_Match_3 = (1U << 3) /*!< External match 3 */ +} ctimer_external_match_t; + +/*! @brief List of output control options */ +typedef enum _ctimer_match_output_control +{ + kCTIMER_Output_NoAction = 0U, /*!< No action is taken */ + kCTIMER_Output_Clear, /*!< Clear the EM bit/output to 0 */ + kCTIMER_Output_Set, /*!< Set the EM bit/output to 1 */ + kCTIMER_Output_Toggle /*!< Toggle the EM bit/output */ +} ctimer_match_output_control_t; + +/*! @brief List of Timer modes */ +typedef enum _ctimer_timer_mode +{ + kCTIMER_TimerMode = 0U, /* TC is incremented every rising APB bus clock edge */ + kCTIMER_IncreaseOnRiseEdge, /* TC is incremented on rising edge of input signal */ + kCTIMER_IncreaseOnFallEdge, /* TC is incremented on falling edge of input signal */ + kCTIMER_IncreaseOnBothEdge /* TC is incremented on both edges of input signal */ +} ctimer_timer_mode_t; + +/*! @brief List of Timer interrupts */ +typedef enum _ctimer_interrupt_enable +{ + kCTIMER_Match0InterruptEnable = CTIMER_MCR_MR0I_MASK, /*!< Match 0 interrupt */ + kCTIMER_Match1InterruptEnable = CTIMER_MCR_MR1I_MASK, /*!< Match 1 interrupt */ + kCTIMER_Match2InterruptEnable = CTIMER_MCR_MR2I_MASK, /*!< Match 2 interrupt */ + kCTIMER_Match3InterruptEnable = CTIMER_MCR_MR3I_MASK, /*!< Match 3 interrupt */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) + kCTIMER_Capture0InterruptEnable = CTIMER_CCR_CAP0I_MASK, /*!< Capture 0 interrupt */ + kCTIMER_Capture1InterruptEnable = CTIMER_CCR_CAP1I_MASK, /*!< Capture 1 interrupt */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) + kCTIMER_Capture2InterruptEnable = CTIMER_CCR_CAP2I_MASK, /*!< Capture 2 interrupt */ +#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + kCTIMER_Capture3InterruptEnable = CTIMER_CCR_CAP3I_MASK, /*!< Capture 3 interrupt */ +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ +#endif +} ctimer_interrupt_enable_t; + +/*! @brief List of Timer flags */ +typedef enum _ctimer_status_flags +{ + kCTIMER_Match0Flag = CTIMER_IR_MR0INT_MASK, /*!< Match 0 interrupt flag */ + kCTIMER_Match1Flag = CTIMER_IR_MR1INT_MASK, /*!< Match 1 interrupt flag */ + kCTIMER_Match2Flag = CTIMER_IR_MR2INT_MASK, /*!< Match 2 interrupt flag */ + kCTIMER_Match3Flag = CTIMER_IR_MR3INT_MASK, /*!< Match 3 interrupt flag */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) + kCTIMER_Capture0Flag = CTIMER_IR_CR0INT_MASK, /*!< Capture 0 interrupt flag */ + kCTIMER_Capture1Flag = CTIMER_IR_CR1INT_MASK, /*!< Capture 1 interrupt flag */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT) && FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT) + kCTIMER_Capture2Flag = CTIMER_IR_CR2INT_MASK, /*!< Capture 2 interrupt flag */ +#endif /* FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT */ +#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT + kCTIMER_Capture3Flag = CTIMER_IR_CR3INT_MASK, /*!< Capture 3 interrupt flag */ +#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */ +#endif +} ctimer_status_flags_t; + +typedef void (*ctimer_callback_t)(uint32_t flags); + +/*! @brief Callback type when registering for a callback. When registering a callback + * an array of function pointers is passed the size could be 1 or 8, the callback + * type will tell that. + */ +typedef enum +{ + kCTIMER_SingleCallback, /*!< Single Callback type where there is only one callback for the timer. + based on the status flags different channels needs to be handled differently */ + kCTIMER_MultipleCallback /*!< Multiple Callback type where there can be 8 valid callbacks, one per channel. + for both match/capture */ +} ctimer_callback_type_t; + +/*! + * @brief Match configuration + * + * This structure holds the configuration settings for each match register. + */ +typedef struct _ctimer_match_config +{ + uint32_t matchValue; /*!< This is stored in the match register */ + bool enableCounterReset; /*!< true: Match will reset the counter + false: Match will not reser the counter */ + bool enableCounterStop; /*!< true: Match will stop the counter + false: Match will not stop the counter */ + ctimer_match_output_control_t outControl; /*!< Action to be taken on a match on the EM bit/output */ + bool outPinInitState; /*!< Initial value of the EM bit/output */ + bool enableInterrupt; /*!< true: Generate interrupt upon match + false: Do not generate interrupt on match */ + +} ctimer_match_config_t; + +/*! + * @brief Timer configuration structure + * + * This structure holds the configuration settings for the Timer peripheral. To initialize this + * structure to reasonable defaults, call the CTIMER_GetDefaultConfig() function and pass a + * pointer to the configuration structure instance. + * + * The configuration structure can be made constant so as to reside in flash. + */ +typedef struct _ctimer_config +{ + ctimer_timer_mode_t mode; /*!< Timer mode */ + ctimer_capture_channel_t input; /*!< Input channel to increment the timer, used only in timer + modes that rely on this input signal to increment TC */ + uint32_t prescale; /*!< Prescale value */ +} ctimer_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application before using the driver. + * + * @param base Ctimer peripheral base address + * @param config Pointer to the user configuration structure. + */ +void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config); + +/*! + * @brief Gates the timer clock. + * + * @param base Ctimer peripheral base address + */ +void CTIMER_Deinit(CTIMER_Type *base); + +/*! + * @brief Fills in the timers configuration structure with the default settings. + * + * The default values are: + * @code + * config->mode = kCTIMER_TimerMode; + * config->input = kCTIMER_Capture_0; + * config->prescale = 0; + * @endcode + * @param config Pointer to the user configuration structure. + */ +void CTIMER_GetDefaultConfig(ctimer_config_t *config); + +/*! @}*/ + +/*! + * @name PWM setup operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters. + * + * Enables PWM mode on the match channel passed in and will then setup the match value + * and other match parameters to generate a PWM signal. + * This function can manually assign the specified channel to set the PWM cycle. + * + * @note When setting PWM output from multiple output pins, all should use the same PWM + * period + * + * @param base Ctimer peripheral base address + * @param pwmPeriodChannel Specify the channel to control the PWM period + * @param matchChannel Match pin to be used to output the PWM signal + * @param pwmPeriod PWM period match value + * @param pulsePeriod Pulse width match value + * @param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse, + * if it is 0 then no interrupt will be generated. + */ +status_t CTIMER_SetupPwmPeriod(CTIMER_Type *base, + const ctimer_match_t pwmPeriodChannel, + ctimer_match_t matchChannel, + uint32_t pwmPeriod, + uint32_t pulsePeriod, + bool enableInt); + +/*! + * @brief Configures the PWM signal parameters. + * + * Enables PWM mode on the match channel passed in and will then setup the match value + * and other match parameters to generate a PWM signal. + * This function can manually assign the specified channel to set the PWM cycle. + * + * @note When setting PWM output from multiple output pins, all should use the same PWM + * frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution. + * + * @param base Ctimer peripheral base address + * @param pwmPeriodChannel Specify the channel to control the PWM period + * @param matchChannel Match pin to be used to output the PWM signal + * @param dutyCyclePercent PWM pulse width; the value should be between 0 to 100 + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz Timer counter clock in Hz + * @param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse, + * if it is 0 then no interrupt will be generated. + */ +status_t CTIMER_SetupPwm(CTIMER_Type *base, + const ctimer_match_t pwmPeriodChannel, + ctimer_match_t matchChannel, + uint8_t dutyCyclePercent, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + bool enableInt); + +/*! + * @brief Updates the pulse period of an active PWM signal. + * + * @param base Ctimer peripheral base address + * @param matchChannel Match pin to be used to output the PWM signal + * @param pulsePeriod New PWM pulse width match value + */ +static inline void CTIMER_UpdatePwmPulsePeriod(CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pulsePeriod) +{ + /* Update PWM pulse period match value */ + base->MR[matchChannel] = pulsePeriod; +} + +/*! + * @brief Updates the duty cycle of an active PWM signal. + * + * @note Please use CTIMER_SetupPwmPeriod to update the PWM with high resolution. + * This function can manually assign the specified channel to set the PWM cycle. + * + * @param base Ctimer peripheral base address + * @param pwmPeriodChannel Specify the channel to control the PWM period + * @param matchChannel Match pin to be used to output the PWM signal + * @param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100 + */ +void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, + const ctimer_match_t pwmPeriodChannel, + ctimer_match_t matchChannel, + uint8_t dutyCyclePercent); + +/*! @}*/ + +/*! + * @brief Setup the match register. + * + * User configuration is used to setup the match value and action to be taken when a match occurs. + * + * @param base Ctimer peripheral base address + * @param matchChannel Match register to configure + * @param config Pointer to the match configuration structure + */ +void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config); + +/*! + * @brief Get the status of output match. + * + * This function gets the status of output MAT, whether or not this output is connected to a pin. + * This status is driven to the MAT pins if the match function is selected via IOCON. 0 = LOW. 1 = HIGH. + * + * @param base Ctimer peripheral base address + * @param matchChannel External match channel, user can obtain the status of multiple match channels + * at the same time by using the logic of "|" + * enumeration ::ctimer_external_match_t + * @return The mask of external match channel status flags. Users need to use the + * _ctimer_external_match type to decode the return variables. + */ +uint32_t CTIMER_GetOutputMatchStatus(CTIMER_Type *base, uint32_t matchChannel); + +/*! + * @brief Setup the capture. + * + * @param base Ctimer peripheral base address + * @param capture Capture channel to configure + * @param edge Edge on the channel that will trigger a capture + * @param enableInt Flag to enable channel interrupts, if enabled then the registered call back + * is called upon capture + */ +void CTIMER_SetupCapture(CTIMER_Type *base, + ctimer_capture_channel_t capture, + ctimer_capture_edge_t edge, + bool enableInt); + +/*! + * @brief Get the timer count value from TC register. + * + * @param base Ctimer peripheral base address. + * @return return the timer count value. + */ +static inline uint32_t CTIMER_GetTimerCountValue(CTIMER_Type *base) +{ + return (base->TC); +} + +/*! + * @brief Register callback. + * + * @param base Ctimer peripheral base address + * @param cb_func callback function + * @param cb_type callback function type, singular or multiple + */ +void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type); + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected Timer interrupts. + * + * @param base Ctimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::ctimer_interrupt_enable_t + */ +static inline void CTIMER_EnableInterrupts(CTIMER_Type *base, uint32_t mask) +{ + /* Enable match interrupts */ + base->MCR |= mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK); + +/* Enable capture interrupts */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) + base->CCR |= mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) + | CTIMER_CCR_CAP2I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + | CTIMER_CCR_CAP3I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ + ); +#endif +} + +/*! + * @brief Disables the selected Timer interrupts. + * + * @param base Ctimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::ctimer_interrupt_enable_t + */ +static inline void CTIMER_DisableInterrupts(CTIMER_Type *base, uint32_t mask) +{ + /* Disable match interrupts */ + base->MCR &= ~(mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK)); + +/* Disable capture interrupts */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) + base->CCR &= ~(mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) + | CTIMER_CCR_CAP2I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + | CTIMER_CCR_CAP3I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ + )); +#endif +} + +/*! + * @brief Gets the enabled Timer interrupts. + * + * @param base Ctimer peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::ctimer_interrupt_enable_t + */ +static inline uint32_t CTIMER_GetEnabledInterrupts(CTIMER_Type *base) +{ + uint32_t enabledIntrs = 0; + + /* Get all the match interrupts enabled */ + enabledIntrs = + base->MCR & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK); + +/* Get all the capture interrupts enabled */ +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE)) + enabledIntrs |= base->CCR & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK +#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) + | CTIMER_CCR_CAP2I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + | CTIMER_CCR_CAP3I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ + ); +#endif + + return enabledIntrs; +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the Timer status flags. + * + * @param base Ctimer peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::ctimer_status_flags_t + */ +static inline uint32_t CTIMER_GetStatusFlags(CTIMER_Type *base) +{ + return base->IR; +} + +/*! + * @brief Clears the Timer status flags. + * + * @param base Ctimer peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::ctimer_status_flags_t + */ +static inline void CTIMER_ClearStatusFlags(CTIMER_Type *base, uint32_t mask) +{ + base->IR = mask; +} + +/*! @}*/ + +/*! + * @name Counter Start and Stop + * @{ + */ + +/*! + * @brief Starts the Timer counter. + * + * @param base Ctimer peripheral base address + */ +static inline void CTIMER_StartTimer(CTIMER_Type *base) +{ + base->TCR |= CTIMER_TCR_CEN_MASK; +} + +/*! + * @brief Stops the Timer counter. + * + * @param base Ctimer peripheral base address + */ +static inline void CTIMER_StopTimer(CTIMER_Type *base) +{ + base->TCR &= ~CTIMER_TCR_CEN_MASK; +} + +/*! @}*/ + +/*! + * @brief Reset the counter. + * + * The timer counter and prescale counter are reset on the next positive edge of the APB clock. + * + * @param base Ctimer peripheral base address + */ +static inline void CTIMER_Reset(CTIMER_Type *base) +{ + base->TCR |= CTIMER_TCR_CRST_MASK; + base->TCR &= ~CTIMER_TCR_CRST_MASK; +} + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_CTIMER_H_ */ diff --git a/drivers/fsl_flexcomm.c b/drivers/fsl_flexcomm.c new file mode 100644 index 0000000..0f054d4 --- /dev/null +++ b/drivers/fsl_flexcomm.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_flexcomm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.flexcomm" +#endif + +/*! + * @brief Used for conversion between `void*` and `uint32_t`. + */ +typedef union pvoid_to_u32 +{ + void *pvoid; + uint32_t u32; +} pvoid_to_u32_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! @brief Set the FLEXCOMM mode . */ +static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock); + +/*! @brief check whether flexcomm supports peripheral type */ +static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */ +static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT]; + +/*! @brief Pointers to handles for each instance to provide context to interrupt routines */ +static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT]; + +/*! @brief Array to map FLEXCOMM instance number to IRQ number. */ +IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS; + +/*! @brief Array to map FLEXCOMM instance number to base address. */ +static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief IDs of clock for each FLEXCOMM module */ +static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) +/*! @brief Pointers to FLEXCOMM resets for each instance. */ +static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS; +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* check whether flexcomm supports peripheral type */ +static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph) +{ + if (periph == FLEXCOMM_PERIPH_NONE) + { + return true; + } + else if (periph <= FLEXCOMM_PERIPH_I2S_TX) + { + return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false; + } + else if (periph == FLEXCOMM_PERIPH_I2S_RX) + { + return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false; + } + else + { + return false; + } +} + +/* Get the index corresponding to the FLEXCOMM */ +/*! brief Returns instance number for FLEXCOMM module with given base address. */ +uint32_t FLEXCOMM_GetInstance(void *base) +{ + uint32_t i; + pvoid_to_u32_t BaseAddr; + BaseAddr.pvoid = base; + + for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++) + { + if (BaseAddr.u32 == s_flexcommBaseAddrs[i]) + { + break; + } + } + + assert(i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT); + return i; +} + +/* Changes FLEXCOMM mode */ +static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock) +{ + /* Check whether peripheral type is present */ + if (!FLEXCOMM_PeripheralIsPresent(base, periph)) + { + return kStatus_OutOfRange; + } + + /* Flexcomm is locked to different peripheral type than expected */ + if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) && + ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph)) + { + return kStatus_Fail; + } + + /* Check if we are asked to lock */ + if (lock != 0) + { + base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK; + } + else + { + base->PSELID = (uint32_t)periph; + } + + return kStatus_Success; +} + +/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */ +status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph) +{ + uint32_t idx = FLEXCOMM_GetInstance(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the peripheral clock */ + CLOCK_EnableClock(s_flexcommClocks[idx]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) + /* Reset the FLEXCOMM module */ + RESET_PeripheralReset(s_flexcommResets[idx]); +#endif + + /* Set the FLEXCOMM to given peripheral */ + return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0); +} + +/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM + * mode */ +void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(base); + + /* Clear handler first to avoid execution of the handler with wrong handle */ + s_flexcommIrqHandler[instance] = NULL; + s_flexcommHandle[instance] = flexcommHandle; + s_flexcommIrqHandler[instance] = handler; + SDK_ISR_EXIT_BARRIER; +} + +/* IRQ handler functions overloading weak symbols in the startup */ +#if defined(FLEXCOMM0) +void FLEXCOMM0_DriverIRQHandler(void); +void FLEXCOMM0_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[0]); + s_flexcommIrqHandler[0]((uint32_t *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM1) +void FLEXCOMM1_DriverIRQHandler(void); +void FLEXCOMM1_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[1]); + s_flexcommIrqHandler[1]((uint32_t *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM2) +void FLEXCOMM2_DriverIRQHandler(void); +void FLEXCOMM2_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[2]); + s_flexcommIrqHandler[2]((uint32_t *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM3) +void FLEXCOMM3_DriverIRQHandler(void); +void FLEXCOMM3_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[3]); + s_flexcommIrqHandler[3]((uint32_t *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM4) +void FLEXCOMM4_DriverIRQHandler(void); +void FLEXCOMM4_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[4]); + s_flexcommIrqHandler[4]((uint32_t *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]); + SDK_ISR_EXIT_BARRIER; +} + +#endif + +#if defined(FLEXCOMM5) +void FLEXCOMM5_DriverIRQHandler(void); +void FLEXCOMM5_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[5]); + s_flexcommIrqHandler[5]((uint32_t *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM6) +void FLEXCOMM6_DriverIRQHandler(void); +void FLEXCOMM6_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[6]); + s_flexcommIrqHandler[6]((uint32_t *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM7) +void FLEXCOMM7_DriverIRQHandler(void); +void FLEXCOMM7_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[7]); + s_flexcommIrqHandler[7]((uint32_t *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM8) +void FLEXCOMM8_DriverIRQHandler(void); +void FLEXCOMM8_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[8]); + s_flexcommIrqHandler[8]((uint32_t *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM9) +void FLEXCOMM9_DriverIRQHandler(void); +void FLEXCOMM9_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[9]); + s_flexcommIrqHandler[9]((uint32_t *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM10) +void FLEXCOMM10_DriverIRQHandler(void); +void FLEXCOMM10_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[10]); + s_flexcommIrqHandler[10]((uint32_t *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM11) +void FLEXCOMM11_DriverIRQHandler(void); +void FLEXCOMM11_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[11]); + s_flexcommIrqHandler[11]((uint32_t *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM12) +void FLEXCOMM12_DriverIRQHandler(void); +void FLEXCOMM12_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[12]); + s_flexcommIrqHandler[12]((uint32_t *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM13) +void FLEXCOMM13_DriverIRQHandler(void); +void FLEXCOMM13_DriverIRQHandler(void) +{ + assert(s_flexcommIrqHandler[13]); + s_flexcommIrqHandler[13]((uint32_t *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM14) +void FLEXCOMM14_DriverIRQHandler(void); +void FLEXCOMM14_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM14); + assert(s_flexcommIrqHandler[instance]); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM15) +void FLEXCOMM15_DriverIRQHandler(void); +void FLEXCOMM15_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM15); + assert(s_flexcommIrqHandler[instance]); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM16) +void FLEXCOMM16_DriverIRQHandler(void); +void FLEXCOMM16_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM16); + assert(s_flexcommIrqHandler[instance]); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif diff --git a/drivers/fsl_flexcomm.h b/drivers/fsl_flexcomm.h new file mode 100644 index 0000000..f96086f --- /dev/null +++ b/drivers/fsl_flexcomm.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_FLEXCOMM_H_ +#define _FSL_FLEXCOMM_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup flexcomm_driver + * @{ + */ + +/*! @name Driver version */ +/*@{*/ +/*! @brief FlexCOMM driver version 2.0.2. */ +#define FSL_FLEXCOMM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*@}*/ + +/*! @brief FLEXCOMM peripheral modes. */ +typedef enum +{ + FLEXCOMM_PERIPH_NONE, /*!< No peripheral */ + FLEXCOMM_PERIPH_USART, /*!< USART peripheral */ + FLEXCOMM_PERIPH_SPI, /*!< SPI Peripheral */ + FLEXCOMM_PERIPH_I2C, /*!< I2C Peripheral */ + FLEXCOMM_PERIPH_I2S_TX, /*!< I2S TX Peripheral */ + FLEXCOMM_PERIPH_I2S_RX, /*!< I2S RX Peripheral */ +} FLEXCOMM_PERIPH_T; + +/*! @brief Typedef for interrupt handler. */ +typedef void (*flexcomm_irq_handler_t)(void *base, void *handle); + +/*! @brief Array with IRQ number for each FLEXCOMM module. */ +extern IRQn_Type const kFlexcommIrqs[]; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @brief Returns instance number for FLEXCOMM module with given base address. */ +uint32_t FLEXCOMM_GetInstance(void *base); + +/*! @brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */ +status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph); + +/*! @brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM + * mode */ +void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle); + +#if defined(__cplusplus) +} +#endif + +/*@}*/ + +#endif /* _FSL_FLEXCOMM_H_*/ diff --git a/drivers/fsl_gpio.c b/drivers/fsl_gpio.c new file mode 100644 index 0000000..be100d5 --- /dev/null +++ b/drivers/fsl_gpio.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_gpio.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.lpc_gpio" +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Array to map FGPIO instance number to clock name. */ +static const clock_ip_name_t s_gpioClockName[] = GPIO_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET) +/*! @brief Pointers to GPIO resets for each instance. */ +static const reset_ip_name_t s_gpioResets[] = GPIO_RSTS_N; +#endif +/******************************************************************************* + * Prototypes + ************ ******************************************************************/ +/*! + * @brief Enable GPIO port clock. + * + * @param base GPIO peripheral base pointer. + * @param port GPIO port number. + */ +static void GPIO_EnablePortClock(GPIO_Type *base, uint32_t port); + +/******************************************************************************* + * Code + ******************************************************************************/ +static void GPIO_EnablePortClock(GPIO_Type *base, uint32_t port) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + assert(port < ARRAY_SIZE(s_gpioClockName)); + + /* Upgate the GPIO clock */ + CLOCK_EnableClock(s_gpioClockName[port]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Initializes the GPIO peripheral. + * + * This function ungates the GPIO clock. + * + * param base GPIO peripheral base pointer. + * param port GPIO port number. + */ +void GPIO_PortInit(GPIO_Type *base, uint32_t port) +{ + GPIO_EnablePortClock(base, port); + +#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET) + /* Reset the GPIO module */ + RESET_PeripheralReset(s_gpioResets[port]); +#endif +} + +/*! + * brief Initializes a GPIO pin used by the board. + * + * To initialize the GPIO, define a pin configuration, either input or output, in the user file. + * Then, call the GPIO_PinInit() function. + * + * This is an example to define an input pin or output pin configuration: + * code + * Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * endcode + * + * param base GPIO peripheral base pointer(Typically GPIO) + * param port GPIO port number + * param pin GPIO pin number + * param config GPIO pin configuration pointer + */ +void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config) +{ + GPIO_EnablePortClock(base, port); + + if (config->pinDirection == kGPIO_DigitalInput) + { +#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) + base->DIRCLR[port] = 1UL << pin; +#else + base->DIR[port] &= ~(1UL << pin); +#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/ + } + else + { + /* Set default output value */ + if (config->outputLogic == 0U) + { + base->CLR[port] = (1UL << pin); + } + else + { + base->SET[port] = (1UL << pin); + } +/* Set pin direction */ +#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) + base->DIRSET[port] = 1UL << pin; +#else + base->DIR[port] |= 1UL << pin; +#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/ + } +} + +#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT +/*! + * @brief Set the configuration of pin interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number + * @param pin GPIO pin number. + * @param config GPIO pin interrupt configuration.. + */ +void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config) +{ + base->INTEDG[port] = (base->INTEDG[port] & ~(1UL << pin)) | ((uint32_t)config->mode << pin); + + base->INTPOL[port] = (base->INTPOL[port] & ~(1UL << pin)) | ((uint32_t)config->polarity << pin); +} + +/*! + * @brief Enables multiple pins interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask) +{ + if ((uint32_t)kGPIO_InterruptA == index) + { + base->INTENA[port] = base->INTENA[port] | mask; + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + base->INTENB[port] = base->INTENB[port] | mask; + } + else + { + /*Should not enter here*/ + } +} + +/*! + * @brief Disables multiple pins interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask) +{ + if ((uint32_t)kGPIO_InterruptA == index) + { + base->INTENA[port] = base->INTENA[port] & ~mask; + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + base->INTENB[port] = base->INTENB[port] & ~mask; + } + else + { + /*Should not enter here*/ + } +} + +/*! + * @brief Clears multiple pins interrupt flag. Status flags are cleared by + * writing a 1 to the corresponding bit position. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask) +{ + if ((uint32_t)kGPIO_InterruptA == index) + { + base->INTSTATA[port] = mask; + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + base->INTSTATB[port] = mask; + } + else + { + /*Should not enter here*/ + } +} + +/*! + * @ Read port interrupt status. + * + * @param base GPIO base pointer. + * @param port GPIO port number + * @param index GPIO interrupt number. + * @retval masked GPIO status value + */ +uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index) +{ + uint32_t status = 0U; + + if ((uint32_t)kGPIO_InterruptA == index) + { + status = base->INTSTATA[port]; + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + status = base->INTSTATB[port]; + } + else + { + /*Should not enter here*/ + } + return status; +} + +/*! + * @brief Enables the specific pin interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param pin GPIO pin number. + * @param index GPIO interrupt number. + */ +void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index) +{ + if ((uint32_t)kGPIO_InterruptA == index) + { + base->INTENA[port] = base->INTENA[port] | (1UL << pin); + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + base->INTENB[port] = base->INTENB[port] | (1UL << pin); + } + else + { + /*Should not enter here*/ + } +} + +/*! + * @brief Disables the specific pin interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param pin GPIO pin number. + * @param index GPIO interrupt number. + */ +void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index) +{ + if ((uint32_t)kGPIO_InterruptA == index) + { + base->INTENA[port] = base->INTENA[port] & ~(1UL << pin); + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + base->INTENB[port] = base->INTENB[port] & ~(1UL << pin); + } + else + { + /*Should not enter here*/ + } +} + +/*! + * @brief Clears the specific pin interrupt flag. Status flags are cleared by + * writing a 1 to the corresponding bit position. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index) +{ + if ((uint32_t)kGPIO_InterruptA == index) + { + base->INTSTATA[port] = 1UL << pin; + } + else if ((uint32_t)kGPIO_InterruptB == index) + { + base->INTSTATB[port] = 1UL << pin; + } + else + { + /*Should not enter here*/ + } +} +#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */ diff --git a/drivers/fsl_gpio.h b/drivers/fsl_gpio.h new file mode 100644 index 0000000..50a33f8 --- /dev/null +++ b/drivers/fsl_gpio.h @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _LPC_GPIO_H_ +#define _LPC_GPIO_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpc_gpio + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LPC GPIO driver version. */ +#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 7)) +/*@}*/ + +/*! @brief LPC GPIO direction definition */ +typedef enum _gpio_pin_direction +{ + kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ + kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ +} gpio_pin_direction_t; + +/*! + * @brief The GPIO pin configuration structure. + * + * Every pin can only be configured as either output pin or input pin at a time. + * If configured as a input pin, then leave the outputConfig unused. + */ +typedef struct _gpio_pin_config +{ + gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */ + /* Output configurations, please ignore if configured as a input one */ + uint8_t outputLogic; /*!< Set default output logic, no use in input */ +} gpio_pin_config_t; + +#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT) +#define GPIO_PIN_INT_LEVEL 0x00U +#define GPIO_PIN_INT_EDGE 0x01U + +#define PINT_PIN_INT_HIGH_OR_RISE_TRIGGER 0x00U +#define PINT_PIN_INT_LOW_OR_FALL_TRIGGER 0x01U + +/*! @brief GPIO Pin Interrupt enable mode */ +typedef enum _gpio_pin_enable_mode +{ + kGPIO_PinIntEnableLevel = GPIO_PIN_INT_LEVEL, /*!< Generate Pin Interrupt on level mode */ + kGPIO_PinIntEnableEdge = GPIO_PIN_INT_EDGE /*!< Generate Pin Interrupt on edge mode */ +} gpio_pin_enable_mode_t; + +/*! @brief GPIO Pin Interrupt enable polarity */ +typedef enum _gpio_pin_enable_polarity +{ + kGPIO_PinIntEnableHighOrRise = + PINT_PIN_INT_HIGH_OR_RISE_TRIGGER, /*!< Generate Pin Interrupt on high level or rising edge */ + kGPIO_PinIntEnableLowOrFall = + PINT_PIN_INT_LOW_OR_FALL_TRIGGER /*!< Generate Pin Interrupt on low level or falling edge */ +} gpio_pin_enable_polarity_t; + +/*! @brief LPC GPIO interrupt index definition */ +typedef enum _gpio_interrupt_index +{ + kGPIO_InterruptA = 0U, /*!< Set current pin as interrupt A*/ + kGPIO_InterruptB = 1U, /*!< Set current pin as interrupt B*/ +} gpio_interrupt_index_t; + +/*! @brief Configures the interrupt generation condition. */ +typedef struct _gpio_interrupt_config +{ + uint8_t mode; /* The trigger mode of GPIO interrupts */ + uint8_t polarity; /* The polarity of GPIO interrupts */ +} gpio_interrupt_config_t; +#endif + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @name GPIO Configuration */ +/*@{*/ + +/*! + * @brief Initializes the GPIO peripheral. + * + * This function ungates the GPIO clock. + * + * @param base GPIO peripheral base pointer. + * @param port GPIO port number. + */ +void GPIO_PortInit(GPIO_Type *base, uint32_t port); + +/*! + * @brief Initializes a GPIO pin used by the board. + * + * To initialize the GPIO, define a pin configuration, either input or output, in the user file. + * Then, call the GPIO_PinInit() function. + * + * This is an example to define an input pin or output pin configuration: + * @code + * Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * @endcode + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param pin GPIO pin number + * @param config GPIO pin configuration pointer + */ +void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config); + +/*@}*/ + +/*! @name GPIO Output Operations */ +/*@{*/ + +/*! + * @brief Sets the output level of the one GPIO pin to the logic 1 or 0. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param pin GPIO pin number + * @param output GPIO pin output logic level. + * - 0: corresponding pin output low-logic level. + * - 1: corresponding pin output high-logic level. + */ +static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output) +{ + base->B[port][pin] = output; +} + +/*@}*/ +/*! @name GPIO Input Operations */ +/*@{*/ + +/*! + * @brief Reads the current input value of the GPIO PIN. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param pin GPIO pin number + * @retval GPIO port input value + * - 0: corresponding pin input low-logic level. + * - 1: corresponding pin input high-logic level. + */ +static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin) +{ + return (uint32_t)base->B[port][pin]; +} + +/*@}*/ + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->SET[port] = mask; +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 0. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->CLR[port] = mask; +} + +/*! + * @brief Reverses current output logic of the multiple GPIO pins. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->NOT[port] = mask; +} + +/*@}*/ + +/*! + * @brief Reads the current input value of the whole GPIO port. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + */ +static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port) +{ + return (uint32_t)base->PIN[port]; +} + +/*@}*/ +/*! @name GPIO Mask Operations */ +/*@{*/ + +/*! + * @brief Sets port mask, 0 - enable pin, 1 - disable pin. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->MASK[port] = mask; +} + +/*! + * @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param output GPIO port output value. + */ +static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output) +{ + base->MPIN[port] = output; +} + +/*! + * @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be + * affected. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @retval masked GPIO port value + */ +static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port) +{ + return (uint32_t)base->MPIN[port]; +} + +#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT +/*! + * @brief Set the configuration of pin interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number + * @param pin GPIO pin number. + * @param config GPIO pin interrupt configuration.. + */ +void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config); + +/*! + * @brief Enables multiple pins interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask); + +/*! + * @brief Disables multiple pins interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask); + +/*! + * @brief Clears pin interrupt flag. Status flags are cleared by + * writing a 1 to the corresponding bit position. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param index GPIO interrupt number. + * @param mask GPIO pin number macro. + */ +void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask); + +/*! + * @ Read port interrupt status. + * + * @param base GPIO base pointer. + * @param port GPIO port number + * @param index GPIO interrupt number. + * @retval masked GPIO status value + */ +uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index); + +/*! + * @brief Enables the specific pin interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param pin GPIO pin number. + * @param index GPIO interrupt number. + */ +void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index); + +/*! + * @brief Disables the specific pin interrupt. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param pin GPIO pin number. + * @param index GPIO interrupt number. + */ +void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index); + +/*! + * @brief Clears the specific pin interrupt flag. Status flags are cleared by + * writing a 1 to the corresponding bit position. + * + * @param base GPIO base pointer. + * @param port GPIO port number. + * @param pin GPIO pin number. + * @param index GPIO interrupt number. + */ +void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index); + +#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */ + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ + +#endif /* _LPC_GPIO_H_*/ diff --git a/drivers/fsl_iap.c b/drivers/fsl_iap.c new file mode 100644 index 0000000..e940b58 --- /dev/null +++ b/drivers/fsl_iap.c @@ -0,0 +1,584 @@ +/* + * Copyright 2018-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_iap.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.iap" +#endif + +#define HZ_TO_KHZ_DIV 1000U + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief IAP_ENTRY API function type */ +typedef void (*IAP_ENTRY_T)(uint32_t cmd[], uint32_t stat[]); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Translate the IAP return status. + * + * @param status IAP status return from the IAP function. + * + * @return sdk status code. + */ +static inline status_t translate_iap_status(uint32_t status); + +/*! + * @brief IAP_ENTRY API function type. + * + * Wrapper for rom iap call. + * + * @param cmd_param IAP command and relevant parameter array. + * @param status_result IAP status result array. + */ +static inline void iap_entry(uint32_t *cmd_param, uint32_t *status_result); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +static inline status_t translate_iap_status(uint32_t status) +{ + status_t ret = (status_t)status; + + /* Translate IAP return code to sdk status code */ + if (status != (uint32_t)kStatus_Success) + { + ret = MAKE_STATUS((int32_t)kStatusGroup_IAP, (int32_t)status); + } + + return ret; +} + +static inline void iap_entry(uint32_t *cmd_param, uint32_t *status_result) +{ + __disable_irq(); + ((IAP_ENTRY_T)FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION)(cmd_param, status_result); + __enable_irq(); +} + +/*! + * @brief Read part identification number. + * + * This function is used to read the part identification number. + * + * @param partID Address to store the part identification number. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ReadPartID(uint32_t *partID) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ReadPartId; + iap_entry(command, result); + *partID = result[1]; + + return translate_iap_status(result[0]); +} + +/*! + * @brief Read boot code version number. + * + * This function is used to read the boot code version number. + * + * @param bootCodeVersion Address to store the boot code version. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * + * note Boot code version is two 32-bit words. Word 0 is the major version, word 1 is the minor version. + */ +status_t IAP_ReadBootCodeVersion(uint32_t *bootCodeVersion) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_Read_BootromVersion; + iap_entry(command, result); + bootCodeVersion[0] = result[1]; + bootCodeVersion[1] = result[2]; + + return translate_iap_status(result[0]); +} + +/*! + * @brief Reinvoke ISP. + * + * This function is used to invoke the boot loader in ISP mode. It maps boot vectors and configures the peripherals for + * ISP. + * + * @param ispTyoe ISP type selection. + * @param status store the possible status. + * + * @retval kStatus_IAP_ReinvokeISPConfig reinvoke configuration error. + * + * note The error response will be returned when IAP is disabled or an invalid ISP type selection appears. The call + * won't return unless an error occurs, so there can be no status code. + */ +void IAP_ReinvokeISP(uint8_t ispType, uint32_t *status) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + uint8_t ispParameterArray[8]; + + command[0] = (uint32_t)kIapCmd_IAP_ReinvokeISP; + (void)memset(ispParameterArray, 0, sizeof(uint8_t) * 8U); + ispParameterArray[1] = ispType; + ispParameterArray[7] = ispParameterArray[0] ^ ispParameterArray[1] ^ ispParameterArray[2] ^ ispParameterArray[3] ^ + ispParameterArray[4] ^ ispParameterArray[5] ^ ispParameterArray[6]; + command[1] = (uint32_t)ispParameterArray; + iap_entry(command, result); + *status = (uint32_t)translate_iap_status(result[0]); +} + +/*! + * @brief Read unique identification. + * + * This function is used to read the unique id. + * + * @param uniqueID store the uniqueID. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ReadUniqueID(uint32_t *uniqueID) +{ +#if defined(FSL_FEATURE_IAP_READ_UNIQUE_ID_NOWORK) && FSL_FEATURE_IAP_READ_UNIQUE_ID_NOWORK + uint32_t *result = (uint32_t *)0x01000100; + uint8_t i = 0; + + for (i = 0; i < 4; i++) + uniqueID[i] = result[i]; + return kStatus_IAP_Success; +#else + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ReadUid; + iap_entry(command, result); + uniqueID[0] = result[1]; + uniqueID[1] = result[2]; + uniqueID[2] = result[3]; + uniqueID[3] = result[4]; + + return translate_iap_status(result[0]); +#endif +} + +#if defined(FLASH_CTRL_FLASHCFG_FLASHTIM_MASK) +/*! + * @brief Flash memory access time. + * + * This function is used to configure the access time to the flash memory. + * + * @param accessTime Flash memory access time FLASHTIM +1 is equal to the + * number of system clocks used for flash access. + */ +void IAP_ConfigAccessFlashTime(uint32_t accessTime) +{ + uint32_t temp; + temp = FLASH_CTRL->FLASHCFG; + temp &= ~FLASH_CTRL_FLASHCFG_FLASHTIM_MASK; + FLASH_CTRL->FLASHCFG = temp | FLASH_CTRL_FLASHCFG_FLASHTIM(accessTime); +} +#endif + +#if defined(FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION) && FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION +/*! + * @brief Read factory settings. + * + * This function reads the factory settings for calibration registers. + * + * @param dstRegAddr Address of the targeted calibration register. + * @param factoryValue Store the factory value + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_ParamError Param0 is not one of the supported calibration registers. + */ +status_t IAP_ReadFactorySettings(uint32_t dstRegAddr, uint32_t *factoryValue) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ReadFactorySettings; + command[1] = dstRegAddr; + iap_entry(command, result); + *factoryValue = result[1]; + + return translate_iap_status(result[0]); +} +#endif /* FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION */ + +#if defined(FSL_FEATURE_IAP_HAS_FLASH_FUNCTION) && FSL_FEATURE_IAP_HAS_FLASH_FUNCTION +/*! + * @brief Prepare sector for write operation. + * + * This function prepares sector(s) for write/erase operation. This function must be called before calling the + * IAP_CopyRamToFlash() or IAP_EraseSector() or IAP_ErasePage() function. The end sector number must be greater than or + * equal to the start sector number. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_PrepareSectorforWrite; + command[1] = startSector; + command[2] = endSector; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Copy RAM to flash. + * + * This function programs the flash memory. Corresponding sectors must be prepared via IAP_PrepareSectorForWrite before + * calling this function. The addresses should be a 256 byte boundary and the number of bytes should be 256 | 512 | + * 1024 | 4096. + * + * @param dstAddr Destination flash address where data bytes are to be written. + * @param srcAddr Source ram address from where data bytes are to be read. + * @param numOfBytes Number of bytes to be written. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the + * flash controller has a fixed reference clock, this parameter is bypassed. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_SrcAddrError Source address is not on word boundary. + * @retval kStatus_IAP_DstAddrError Destination address is not on a correct boundary. + * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map. + * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map. + * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value. + * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_CopyRamToFlash; + command[1] = dstAddr; + command[2] = (uint32_t)srcAddr; + command[3] = numOfBytes; +#if !(defined(FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) && FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) + command[4] = systemCoreClock / HZ_TO_KHZ_DIV; +#endif /* FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK */ + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Erase sector. + * + * This function erases sector(s). The end sector number must be greater than or equal to the start sector number. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the + * flash controller has a fixed reference clock, this parameter is bypassed. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number. + * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_EraseSector; + command[1] = startSector; + command[2] = endSector; +#if !(defined(FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) && FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) + command[3] = systemCoreClock / HZ_TO_KHZ_DIV; +#endif /* FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK */ + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Erase page. + * + * This function erases page(s). The end page number must be greater than or equal to the start page number. + * + * @param startPage Start page number. + * @param endPage End page number. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the + * flash controller has a fixed reference clock, this parameter is bypassed. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_InvalidSector Page number is invalid or end page number is greater than start page number. + * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ErasePage; + command[1] = startPage; + command[2] = endPage; +#if !(defined(FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) && FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK) + command[3] = systemCoreClock / HZ_TO_KHZ_DIV; +#endif /* FSL_FEATURE_SYSCON_HAS_FLASH_REFERENCE_CLOCK */ + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Blank check sector(s) + * + * Blank check single or multiples sectors of flash memory. The end sector number must be greater than or equal to the + * start sector number. It can be used to verify the sector erasure after IAP_EraseSector call. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * @retval kStatus_IAP_Success One or more sectors are in erased state. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_SectorNotblank One or more sectors are not blank. + */ +status_t IAP_BlankCheckSector(uint32_t startSector, uint32_t endSector) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_BlankCheckSector; + command[1] = startSector; + command[2] = endSector; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Compare memory contents of flash with ram. + * + * This function compares the contents of flash and ram. It can be used to verify the flash memory contents after + * IAP_CopyRamToFlash call. + * + * @param dstAddr Destination flash address. + * @param srcAddr Source ram address. + * @param numOfBytes Number of bytes to be compared. + * + * @retval kStatus_IAP_Success Contents of flash and ram match. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_AddrError Address is not on word boundary. + * @retval kStatus_IAP_AddrNotMapped Address is not mapped in the memory map. + * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value. + * @retval kStatus_IAP_CompareError Destination and source memory contents do not match. + */ +status_t IAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_Compare; + command[1] = dstAddr; + command[2] = (uint32_t)srcAddr; + command[3] = numOfBytes; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +#if defined(FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ +/*! + * @brief Extended Read signature. + * + * This function calculates the signature value for one or more pages of on-chip flash memory. + * + * @param startPage Start page number. + * @param endPage End page number. + * @param numOfStates Number of wait states. + * @param signature Address to store the signature value. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ExtendedFlashSignatureRead(uint32_t startPage, uint32_t endPage, uint32_t numOfStates, uint32_t *signature) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ExtendedReadSignature; + command[1] = startPage; + command[2] = endPage; + command[3] = numOfStates; + command[4] = 0; + iap_entry(command, result); + signature[0] = result[4]; + signature[1] = result[3]; + signature[2] = result[2]; + signature[3] = result[1]; + + return translate_iap_status(result[0]); +} +#endif /* FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ */ + +#if defined(FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ +/*! + * @brief Read flash signature. + * + * This funtion is used to obtain a 32-bit signature value of the entire flash memory. + * + * @param signature Address to store the 32-bit generated signature value. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ReadFlashSignature(uint32_t *signature) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ReadSignature; + iap_entry(command, result); + *signature = result[1]; + + return translate_iap_status(result[0]); +} +#endif /* FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ */ +#endif /* FSL_FEATURE_IAP_HAS_FLASH_FUNCTION */ + +#if (defined(FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION) && (FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION == 1)) +/*! + * @brief Read EEPROM page. + * + * This function is used to read given page of EEPROM into the memory provided. + * + * @param pageNumber EEPROM page number. + * @param dstAddr Memory address to store the value read from EEPROM. + * @param systemCoreClock Current core clock frequency in kHz. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_InvalidSector Sector number is invalid. + * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map. + * + * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM. + */ +status_t IAP_ReadEEPROMPage(uint32_t pageNumber, uint32_t *dstAddr, uint32_t systemCoreClock) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ReadEEPROMPage; + command[1] = pageNumber; + command[2] = (uint32_t)dstAddr; + command[3] = systemCoreClock / HZ_TO_KHZ_DIV; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Write EEPROM page. + * + * This function is used to write given data in the provided memory to a page of EEPROM. + * + * @param pageNumber EEPROM page number. + * @param srcAddr Memory address holding data to be stored on to EEPROM page. + * @param systemCoreClock Current core clock frequency in kHz. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_InvalidSector Sector number is invalid. + * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map. + * + * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM + */ +status_t IAP_WriteEEPROMPage(uint32_t pageNumber, uint32_t *srcAddr, uint32_t systemCoreClock) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_WriteEEPROMPage; + command[1] = pageNumber; + command[2] = (uint32_t)srcAddr; + command[3] = systemCoreClock / HZ_TO_KHZ_DIV; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} +#endif /* FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION */ + +#if defined(FSL_FEATURE_IAP_HAS_FAIM_FUNCTION) && FSL_FEATURE_IAP_HAS_FAIM_FUNCTION +/*! + * @brief Read FAIM page. + * + * This function is used to read given page of FAIM into the memory provided. + * + * @param pageNumber FAIM page number. + * @param dstAddr Memory address to store the value read from FAIM. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map. + */ +status_t IAP_ReadFAIMPage(uint32_t pageNumber, uint32_t *dstAddr) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_ReadFAIMPage; + command[1] = pageNumber; + command[2] = (uint32_t)dstAddr; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +/*! + * @brief Write FAIM page. + * + * This function is used to write given data in the provided memory to a page of G. + * + * @param pageNumber FAIM page number. + * @param srcAddr Memory address holding data to be stored on to FAIM page. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map. + */ +status_t IAP_WriteFAIMPage(uint32_t pageNumber, uint32_t *srcAddr) +{ + uint32_t command[5] = {0x00U}; + uint32_t result[5] = {0x00U}; + + command[0] = (uint32_t)kIapCmd_IAP_WriteFAIMPage; + command[1] = pageNumber; + command[2] = (uint32_t)srcAddr; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} +#endif /* FSL_FEATURE_IAP_HAS_FAIM_FUNCTION */ diff --git a/drivers/fsl_iap.h b/drivers/fsl_iap.h new file mode 100644 index 0000000..3e9ccf9 --- /dev/null +++ b/drivers/fsl_iap.h @@ -0,0 +1,435 @@ +/* + * Copyright 2018-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_IAP_H_ +#define _FSL_IAP_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup IAP_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_IAP_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*!< Version 2.0.5. */ + /*@}*/ + +/*! + * @brief iap status codes. + */ +enum +{ + kStatus_IAP_Success = kStatus_Success, /*!< Api is executed successfully */ + kStatus_IAP_InvalidCommand = MAKE_STATUS(kStatusGroup_IAP, 1U), /*!< Invalid command */ + kStatus_IAP_SrcAddrError = MAKE_STATUS(kStatusGroup_IAP, 2U), /*!< Source address is not on word boundary */ + kStatus_IAP_DstAddrError = + MAKE_STATUS(kStatusGroup_IAP, 3U), /*!< Destination address is not on a correct boundary */ + kStatus_IAP_SrcAddrNotMapped = + MAKE_STATUS(kStatusGroup_IAP, 4U), /*!< Source address is not mapped in the memory map */ + kStatus_IAP_DstAddrNotMapped = + MAKE_STATUS(kStatusGroup_IAP, 5U), /*!< Destination address is not mapped in the memory map */ + kStatus_IAP_CountError = + MAKE_STATUS(kStatusGroup_IAP, 6U), /*!< Byte count is not multiple of 4 or is not a permitted value */ + kStatus_IAP_InvalidSector = MAKE_STATUS( + kStatusGroup_IAP, + 7), /*!< Sector/page number is invalid or end sector/page number is greater than start sector/page number */ + kStatus_IAP_SectorNotblank = MAKE_STATUS(kStatusGroup_IAP, 8U), /*!< One or more sectors are not blank */ + kStatus_IAP_NotPrepared = + MAKE_STATUS(kStatusGroup_IAP, 9U), /*!< Command to prepare sector for write operation has not been executed */ + kStatus_IAP_CompareError = + MAKE_STATUS(kStatusGroup_IAP, 10U), /*!< Destination and source memory contents do not match */ + kStatus_IAP_Busy = MAKE_STATUS(kStatusGroup_IAP, 11U), /*!< Flash programming hardware interface is busy */ + kStatus_IAP_ParamError = + MAKE_STATUS(kStatusGroup_IAP, 12U), /*!< Insufficient number of parameters or invalid parameter */ + kStatus_IAP_AddrError = MAKE_STATUS(kStatusGroup_IAP, 13U), /*!< Address is not on word boundary */ + kStatus_IAP_AddrNotMapped = MAKE_STATUS(kStatusGroup_IAP, 14U), /*!< Address is not mapped in the memory map */ + kStatus_IAP_NoPower = MAKE_STATUS(kStatusGroup_IAP, 24U), /*!< Flash memory block is powered down */ + kStatus_IAP_NoClock = MAKE_STATUS(kStatusGroup_IAP, 27U), /*!< Flash memory block or controller is not clocked */ + kStatus_IAP_ReinvokeISPConfig = MAKE_STATUS(kStatusGroup_IAP, 0x1CU), /*!< Reinvoke configuration error */ +}; + +/*! + * @brief iap command codes. + */ +enum _iap_commands +{ + kIapCmd_IAP_ReadFactorySettings = 40U, /*!< Read the factory settings */ + kIapCmd_IAP_PrepareSectorforWrite = 50U, /*!< Prepare Sector for write */ + kIapCmd_IAP_CopyRamToFlash = 51U, /*!< Copy RAM to flash */ + kIapCmd_IAP_EraseSector = 52U, /*!< Erase Sector */ + kIapCmd_IAP_BlankCheckSector = 53U, /*!< Blank check sector */ + kIapCmd_IAP_ReadPartId = 54U, /*!< Read part id */ + kIapCmd_IAP_Read_BootromVersion = 55U, /*!< Read bootrom version */ + kIapCmd_IAP_Compare = 56U, /*!< Compare */ + kIapCmd_IAP_ReinvokeISP = 57U, /*!< Reinvoke ISP */ + kIapCmd_IAP_ReadUid = 58U, /*!< Read Uid */ + kIapCmd_IAP_ErasePage = 59U, /*!< Erase Page */ + kIapCmd_IAP_ReadSignature = 70U, /*!< Read Signature */ + kIapCmd_IAP_ExtendedReadSignature = 73U, /*!< Extended Read Signature */ +#if defined(FSL_FEATURE_IAP_HAS_FAIM_FUNCTION) && FSL_FEATURE_IAP_HAS_FAIM_FUNCTION + kIapCmd_IAP_ReadFAIMPage = 80U, /*!< Read FAIM page */ + kIapCmd_IAP_WriteFAIMPage = 81U, /*!< Write FAIM page */ +#else + kIapCmd_IAP_ReadEEPROMPage = 80U, /*!< Read EEPROM page */ + kIapCmd_IAP_WriteEEPROMPage = 81U, /*!< Write EEPROM page */ +#endif /*FSL_FEATURE_IAP_HAS_FAIM_FUNCTION */ +}; + +/*! + * @brief Flash memory access time. + */ +enum _flash_access_time +{ + kFlash_IAP_OneSystemClockTime = 0U, /*! 1 system clock flash access time */ + kFlash_IAP_TwoSystemClockTime = 1U, /*! 2 system clock flash access time */ + kFlash_IAP_ThreeSystemClockTime = 2U, /*! 3 system clock flash access time */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Basic operations + * @{ + */ + +/*! + * @brief Read part identification number. + * + * This function is used to read the part identification number. + * + * @param partID Address to store the part identification number. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ReadPartID(uint32_t *partID); + +/*! + * @brief Read boot code version number. + * + * This function is used to read the boot code version number. + * + * @param bootCodeVersion Address to store the boot code version. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * + * note Boot code version is two 32-bit words. Word 0 is the major version, word 1 is the minor version. + */ +status_t IAP_ReadBootCodeVersion(uint32_t *bootCodeVersion); + +/*! + * @brief Reinvoke ISP. + * + * This function is used to invoke the boot loader in ISP mode. It maps boot vectors and configures the peripherals for + * ISP. + * + * @param ispType ISP type selection. + * @param status store the possible status. + * + * @retval kStatus_IAP_ReinvokeISPConfig reinvoke configuration error. + * + * note The error response will be returned when IAP is disabled or an invalid ISP type selection appears. The call + * won't return unless an error occurs, so there can be no status code. + */ +void IAP_ReinvokeISP(uint8_t ispType, uint32_t *status); + +/*! + * @brief Read unique identification. + * + * This function is used to read the unique id. + * + * @param uniqueID store the uniqueID. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ReadUniqueID(uint32_t *uniqueID); + +#if defined(FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION) && FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION +/*! + * @brief Read factory settings. + * + * This function reads the factory settings for calibration registers. + * + * @param dstRegAddr Address of the targeted calibration register. + * @param factoryValue Store the factory value + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_ParamError Param0 is not one of the supported calibration registers. + */ +status_t IAP_ReadFactorySettings(uint32_t dstRegAddr, uint32_t *factoryValue); +#endif /* FSL_FEATURE_IAP_HAS_READ_FACTORY_SETTINGS_FUNCTION */ + +/*@}*/ + +#if defined(FSL_FEATURE_IAP_HAS_FLASH_FUNCTION) && FSL_FEATURE_IAP_HAS_FLASH_FUNCTION +/*! + * @name Flash operations + * @{ + */ + +#if defined(FLASH_CTRL_FLASHCFG_FLASHTIM_MASK) +/*! + * @brief Flash memory access time. + * + * This function is used to configure the access time to the flash memory. + * + * @param accessTime Flash memory access time FLASHTIM +1 is equal to the + * number of system clocks used for flash access. + */ +void IAP_ConfigAccessFlashTime(uint32_t accessTime); +#endif + +/*! + * @brief Prepare sector for write operation. + * + * This function prepares sector(s) for write/erase operation. This function must be called before calling the + * IAP_CopyRamToFlash() or IAP_EraseSector() or IAP_ErasePage() function. The end sector number must be greater than or + * equal to the start sector number. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector); + +/*! + * @brief Copy RAM to flash. + * + * This function programs the flash memory. Corresponding sectors must be prepared via IAP_PrepareSectorForWrite before + * calling this function. The addresses should be a 256 byte boundary and the number of bytes should be 256 | 512 | + * 1024 | 4096. + * + * @param dstAddr Destination flash address where data bytes are to be written. + * @param srcAddr Source ram address from where data bytes are to be read. + * @param numOfBytes Number of bytes to be written. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the + * flash controller has a fixed reference clock, this parameter is bypassed. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_SrcAddrError Source address is not on word boundary. + * @retval kStatus_IAP_DstAddrError Destination address is not on a correct boundary. + * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map. + * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map. + * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value. + * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock); + +/*! + * @brief Erase sector. + * + * This function erases sector(s). The end sector number must be greater than or equal to the start sector number. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the + * flash controller has a fixed reference clock, this parameter is bypassed. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_InvalidSector Sector number is invalid or end sector number is greater than start sector number. + * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock); + +/*! + * @brief Erase page. + * + * This function erases page(s). The end page number must be greater than or equal to the start page number. + * + * @param startPage Start page number. + * @param endPage End page number. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the rom IAP function. When the + * flash controller has a fixed reference clock, this parameter is bypassed. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_InvalidSector Page number is invalid or end page number is greater than start page number. + * @retval kStatus_IAP_NotPrepared Command to prepare sector for write operation has not been executed. + * @retval kStatus_IAP_Busy Flash programming hardware interface is busy. + */ +status_t IAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock); + +/*! + * @brief Blank check sector(s) + * + * Blank check single or multiples sectors of flash memory. The end sector number must be greater than or equal to the + * start sector number. It can be used to verify the sector erasure after IAP_EraseSector call. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * @retval kStatus_IAP_Success One or more sectors are in erased state. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_SectorNotblank One or more sectors are not blank. + */ +status_t IAP_BlankCheckSector(uint32_t startSector, uint32_t endSector); + +/*! + * @brief Compare memory contents of flash with ram. + * + * This function compares the contents of flash and ram. It can be used to verify the flash memory contents after + * IAP_CopyRamToFlash call. + * + * @param dstAddr Destination flash address. + * @param srcAddr Source ram address. + * @param numOfBytes Number of bytes to be compared. + * + * @retval kStatus_IAP_Success Contents of flash and ram match. + * @retval kStatus_IAP_NoPower Flash memory block is powered down. + * @retval kStatus_IAP_NoClock Flash memory block or controller is not clocked. + * @retval kStatus_IAP_AddrError Address is not on word boundary. + * @retval kStatus_IAP_AddrNotMapped Address is not mapped in the memory map. + * @retval kStatus_IAP_CountError Byte count is not multiple of 4 or is not a permitted value. + * @retval kStatus_IAP_CompareError Destination and source memory contents do not match. + */ +status_t IAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes); + +#if defined(FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ +/*! + * @brief Extended Read signature. + * + * This function calculates the signature value for one or more pages of on-chip flash memory. + * + * @param startPage Start page number. + * @param endPage End page number. + * @param numOfStates Number of wait states. + * @param signature Address to store the signature value. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ExtendedFlashSignatureRead(uint32_t startPage, + uint32_t endPage, + uint32_t numOfStates, + uint32_t *signature); +#endif /* FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ */ + +#if defined(FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ) && FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ +/*! + * @brief Read flash signature. + * + * This funtion is used to obtain a 32-bit signature value of the entire flash memory. + * + * @param signature Address to store the 32-bit generated signature value. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + */ +status_t IAP_ReadFlashSignature(uint32_t *signature); +#endif /* FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ */ + +/*@}*/ +#endif /* FSL_FEATURE_IAP_HAS_FLASH_FUNCTION */ + +#if (defined(FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION) && (FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION == 1)) +/*! + * @name EEPROM operations + * @{ + */ + +/*! + * @brief Read EEPROM page. + * + * This function is used to read given page of EEPROM into the memory provided. + * + * @param pageNumber EEPROM page number. + * @param dstAddr Memory address to store the value read from EEPROM. + * @param systemCoreClock Current core clock frequency in kHz. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_InvalidSector Sector number is invalid. + * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map. + * + * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM. + */ +status_t IAP_ReadEEPROMPage(uint32_t pageNumber, uint32_t *dstAddr, uint32_t systemCoreClock); + +/*! + * @brief Write EEPROM page. + * + * This function is used to write given data in the provided memory to a page of EEPROM. + * + * @param pageNumber EEPROM page number. + * @param srcAddr Memory address holding data to be stored on to EEPROM page. + * @param systemCoreClock Current core clock frequency in kHz. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_InvalidSector Sector number is invalid. + * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map. + * + * note Value 0xFFFFFFFF of systemCoreClock will retain the timing and clock settings for EEPROM + */ +status_t IAP_WriteEEPROMPage(uint32_t pageNumber, uint32_t *srcAddr, uint32_t systemCoreClock); + +/*@}*/ +#endif /* FSL_FEATURE_IAP_HAS_EEPROM_FUNCTION */ + +#if defined(FSL_FEATURE_IAP_HAS_FAIM_FUNCTION) && FSL_FEATURE_IAP_HAS_FAIM_FUNCTION +/*! + * @name FAIM operations + * @{ + */ + +/*! + * @brief Read FAIM page. + * + * This function is used to read given page of FAIM into the memory provided. + * + * @param pageNumber FAIM page number. + * @param dstAddr Memory address to store the value read from FAIM. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_DstAddrNotMapped Destination address is not mapped in the memory map. + */ +status_t IAP_ReadFAIMPage(uint32_t pageNumber, uint32_t *dstAddr); + +/*! + * @brief Write FAIM page. + * + * This function is used to write given data in the provided memory to a page of G. + * + * @param pageNumber FAIM page number. + * @param srcAddr Memory address holding data to be stored on to FAIM page. + * + * @retval kStatus_IAP_Success Api has been executed successfully. + * @retval kStatus_IAP_SrcAddrNotMapped Source address is not mapped in the memory map. + */ +status_t IAP_WriteFAIMPage(uint32_t pageNumber, uint32_t *srcAddr); +#endif /* FSL_FEATURE_IAP_HAS_FAIM_FUNCTION */ + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _FSL_IAP_H_ */ diff --git a/drivers/fsl_inputmux.c b/drivers/fsl_inputmux.c new file mode 100644 index 0000000..edacd71 --- /dev/null +++ b/drivers/fsl_inputmux.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_inputmux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.inputmux" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * brief Initialize INPUTMUX peripheral. + + * This function enables the INPUTMUX clock. + * + * param base Base address of the INPUTMUX peripheral. + * + * retval None. + */ +void INPUTMUX_Init(INPUTMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +#if defined(FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE) && FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE + CLOCK_EnableClock(kCLOCK_Sct); + CLOCK_EnableClock(kCLOCK_Dma); +#else + CLOCK_EnableClock(kCLOCK_InputMux); +#endif /* FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE */ +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Attaches a signal + * + * This function gates the INPUTPMUX clock. + * + * param base Base address of the INPUTMUX peripheral. + * param index Destination peripheral to attach the signal to. + * param connection Selects connection. + * + * retval None. + */ +void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection) +{ + uint32_t pmux_id; + uint32_t output_id; + + /* extract pmux to be used */ + pmux_id = ((uint32_t)(connection)) >> PMUX_SHIFT; + /* extract function number */ + output_id = ((uint32_t)(connection)) & ((1UL << PMUX_SHIFT) - 1U); + /* programm signal */ + *(volatile uint32_t *)(((uint32_t)base) + pmux_id + (index * 4U)) = output_id; +} + +#if defined(FSL_FEATURE_INPUTMUX_HAS_SIGNAL_ENA) +/*! + * brief Enable/disable a signal + * + * This function gates the INPUTPMUX clock. + * + * param base Base address of the INPUTMUX peripheral. + * param signal Enable signal register id and bit offset. + * param enable Selects enable or disable. + * + * retval None. + */ +void INPUTMUX_EnableSignal(INPUTMUX_Type *base, inputmux_signal_t signal, bool enable) +{ + uint32_t ena_id; + uint32_t ena_id_mask = (1UL << (32U - ENA_SHIFT)) - 1U; + uint32_t bit_offset; + +#if defined(FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX) && FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX + uint32_t chmux_offset; + uint32_t chmux_value; + + /* Only enable need to update channel mux */ + if (enable && ((((uint32_t)signal) & (1UL << CHMUX_AVL_SHIFT)) != 0U)) + { + chmux_offset = (((uint32_t)signal) >> CHMUX_OFF_SHIFT) & ((1U << (CHMUX_AVL_SHIFT - CHMUX_OFF_SHIFT)) - 1); + chmux_value = (((uint32_t)signal) >> CHMUX_VAL_SHIFT) & ((1U << (CHMUX_OFF_SHIFT - CHMUX_VAL_SHIFT)) - 1); + *(volatile uint32_t *)(((uint32_t)base) + chmux_offset) = chmux_value; + } + ena_id_mask = (1UL << (CHMUX_VAL_SHIFT - ENA_SHIFT)) - 1U; +#endif + /* extract enable register to be used */ + ena_id = (((uint32_t)signal) >> ENA_SHIFT) & ena_id_mask; + /* extract enable bit offset */ + bit_offset = ((uint32_t)signal) & ((1UL << ENA_SHIFT) - 1U); + /* set signal */ + if (enable) + { + *(volatile uint32_t *)(((uint32_t)base) + ena_id) |= (1UL << bit_offset); + } + else + { + *(volatile uint32_t *)(((uint32_t)base) + ena_id) &= ~(1UL << bit_offset); + } +} +#endif + +/*! + * brief Deinitialize INPUTMUX peripheral. + + * This function disables the INPUTMUX clock. + * + * param base Base address of the INPUTMUX peripheral. + * + * retval None. + */ +void INPUTMUX_Deinit(INPUTMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +#if defined(FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE) && FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE + CLOCK_DisableClock(kCLOCK_Sct); + CLOCK_DisableClock(kCLOCK_Dma); +#else + CLOCK_DisableClock(kCLOCK_InputMux); +#endif /* FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE */ +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} diff --git a/drivers/fsl_inputmux.h b/drivers/fsl_inputmux.h new file mode 100644 index 0000000..0d67a27 --- /dev/null +++ b/drivers/fsl_inputmux.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_INPUTMUX_H_ +#define _FSL_INPUTMUX_H_ + +#include "fsl_inputmux_connections.h" +#include "fsl_common.h" + +/*! + * @addtogroup inputmux_driver + * @{ + */ + +/*! @file */ +/*! @file fsl_inputmux_connections.h */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Group interrupt driver version for SDK */ +#define FSL_INPUTMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) +/*@}*/ + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @brief Initialize INPUTMUX peripheral. + + * This function enables the INPUTMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * + * @retval None. + */ +void INPUTMUX_Init(INPUTMUX_Type *base); + +/*! + * @brief Attaches a signal + * + * This function gates the INPUTPMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * @param index Destination peripheral to attach the signal to. + * @param connection Selects connection. + * + * @retval None. + */ +void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection); + +#if defined(FSL_FEATURE_INPUTMUX_HAS_SIGNAL_ENA) +/*! + * @brief Enable/disable a signal + * + * This function gates the INPUTPMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * @param signal Enable signal register id and bit offset. + * @param enable Selects enable or disable. + * + * @retval None. + */ +void INPUTMUX_EnableSignal(INPUTMUX_Type *base, inputmux_signal_t signal, bool enable); +#endif + +/*! + * @brief Deinitialize INPUTMUX peripheral. + + * This function disables the INPUTMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * + * @retval None. + */ +void INPUTMUX_Deinit(INPUTMUX_Type *base); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _FSL_INPUTMUX_H_ */ diff --git a/drivers/fsl_inputmux_connections.h b/drivers/fsl_inputmux_connections.h new file mode 100644 index 0000000..a70638a --- /dev/null +++ b/drivers/fsl_inputmux_connections.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016, NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_INPUTMUX_CONNECTIONS_ +#define _FSL_INPUTMUX_CONNECTIONS_ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.inputmux_connections" +#endif + +/*! + * @addtogroup inputmux_driver + * @{ + */ + +/*! @brief Periphinmux IDs */ +#define PINTSEL_PMUX_ID 0xC0U +#define DMA_TRIG0_PMUX_ID 0xE0U +#define DMA_OTRIG_PMUX_ID 0x160U +#define FREQMEAS_PMUX_ID 0x180U +#define PMUX_SHIFT 20U + +/*! @brief INPUTMUX connections type */ +typedef enum _inputmux_connection_t +{ + /*!< Frequency measure. */ + kINPUTMUX_MainOscToFreqmeas = 0U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Fro12MhzToFreqmeas = 1U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_WdtOscToFreqmeas = 2U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_32KhzOscToFreqmeas = 3U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_MainClkToFreqmeas = 4U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin4ToFreqmeas = 5U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin20ToFreqmeas = 6U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin24ToFreqmeas = 7U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin4ToFreqmeas = 8U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + /*!< Pin Interrupt. */ + kINPUTMUX_GpioPort0Pin0ToPintsel = 0U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin1ToPintsel = 1U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin2ToPintsel = 2U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin3ToPintsel = 3U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin4ToPintsel = 4U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin5ToPintsel = 5U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin6ToPintsel = 6U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin7ToPintsel = 7U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin8ToPintsel = 8U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin9ToPintsel = 9U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin10ToPintsel = 10U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin11ToPintsel = 11U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin12ToPintsel = 12U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin13ToPintsel = 13U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin14ToPintsel = 14U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin15ToPintsel = 15U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin16ToPintsel = 16U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin17ToPintsel = 17U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin18ToPintsel = 18U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin19ToPintsel = 19U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin20ToPintsel = 20U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin21ToPintsel = 21U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin22ToPintsel = 22U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin23ToPintsel = 23U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin24ToPintsel = 24U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin25ToPintsel = 25U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin26ToPintsel = 26U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin27ToPintsel = 27U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin28ToPintsel = 28U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin29ToPintsel = 29U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin30ToPintsel = 30U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin31ToPintsel = 31U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin0ToPintsel = 32U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin1ToPintsel = 33U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin2ToPintsel = 34U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin3ToPintsel = 35U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin4ToPintsel = 36U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin5ToPintsel = 37U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin6ToPintsel = 38U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin7ToPintsel = 39U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin8ToPintsel = 40U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin9ToPintsel = 41U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin10ToPintsel = 42U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin11ToPintsel = 43U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin12ToPintsel = 44U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin13ToPintsel = 45U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin14ToPintsel = 46U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin15ToPintsel = 47U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin16ToPintsel = 48U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin17ToPintsel = 49U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin18ToPintsel = 50U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin19ToPintsel = 51U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin20ToPintsel = 52U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin21ToPintsel = 53U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin22ToPintsel = 54U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin23ToPintsel = 55U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin24ToPintsel = 56U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin25ToPintsel = 57U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin26ToPintsel = 58U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin27ToPintsel = 59U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin28ToPintsel = 60U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin29ToPintsel = 61U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin30ToPintsel = 62U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin31ToPintsel = 63U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + /*!< DMA ITRIG. */ + kINPUTMUX_Adc0SeqaIrqToDma = 0U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_ADC0SeqbIrqToDma = 1U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Sct0DmaReq0ToDma = 2U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Sct0DmaReq1ToDma = 3U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer0M0ToDma = 4U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer0M1ToDma = 5U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer1M0ToDma = 6U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer2M0ToDma = 7U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer2M1ToDma = 8U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer3M0ToDma = 9U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer4M0ToDma = 10U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer4M1ToDma = 11U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt0ToDma = 12U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt1ToDma = 13U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt2ToDma = 14U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt3ToDma = 15U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig0ToDma = 16U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig1ToDma = 17U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig2ToDma = 18U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig3ToDma = 19U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + /*!< DMA OTRIG. */ + kINPUTMUX_DmaFlexcomm0RxTrigoutToTriginChannels = 0U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm0TxTrigoutToTriginChannels = 1U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm1RxTrigoutToTriginChannels = 2U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm1TxTrigoutToTriginChannels = 3U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm2RxTrigoutToTriginChannels = 4U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm2TxTrigoutToTriginChannels = 5U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm3RxTrigoutToTriginChannels = 6U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm3TxTrigoutToTriginChannels = 7U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm4RxTrigoutToTriginChannels = 8U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm4TxTrigoutToTriginChannels = 9U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm5RxTrigoutToTriginChannels = 10U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm5TxTrigoutToTriginChannels = 11U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm6RxTrigoutToTriginChannels = 12U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm6TxTrigoutToTriginChannels = 13U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm7RxTrigoutToTriginChannels = 14U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaFlexcomm7TxTrigoutToTriginChannels = 15U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaDmic0Ch0TrigoutToTriginChannels = 16U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Dmamic0Ch1TrigoutToTriginChannels = 17U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaSpifi0TrigoutToTriginChannels = 18U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaChannel19_TrigoutToTriginChannels = 19U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), +} inputmux_connection_t; + +/*@}*/ + +#endif /* _FSL_INPUTMUX_CONNECTIONS_ */ diff --git a/drivers/fsl_iocon.h b/drivers/fsl_iocon.h new file mode 100644 index 0000000..3e45026 --- /dev/null +++ b/drivers/fsl_iocon.h @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_IOCON_H_ +#define _FSL_IOCON_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpc_iocon + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.lpc_iocon" +#endif + +/*! @name Driver version */ +/*@{*/ +/*! @brief IOCON driver version. */ +#define FSL_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) +/*@}*/ + +/** + * @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format + */ +typedef struct _iocon_group +{ + uint8_t port; /* Pin port */ + uint8_t pin; /* Pin number */ + uint8_t ionumber; /* IO number */ + uint16_t modefunc; /* Function and mode */ +} iocon_group_t; + +/** + * @brief IOCON function and mode selection definitions + * @note See the User Manual for specific modes and functions supported by the various pins. + */ +#if defined(FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH) && (FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH == 4) +#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */ +#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */ +#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */ +#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */ +#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */ +#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */ +#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */ +#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */ +#define IOCON_FUNC8 0x8 /*!< Selects pin function 8 */ +#define IOCON_FUNC9 0x9 /*!< Selects pin function 9 */ +#define IOCON_FUNC10 0xA /*!< Selects pin function 10 */ +#define IOCON_FUNC11 0xB /*!< Selects pin function 11 */ +#define IOCON_FUNC12 0xC /*!< Selects pin function 12 */ +#define IOCON_FUNC13 0xD /*!< Selects pin function 13 */ +#define IOCON_FUNC14 0xE /*!< Selects pin function 14 */ +#define IOCON_FUNC15 0xF /*!< Selects pin function 15 */ +#if defined(IOCON_PIO_MODE_SHIFT) +#define IOCON_MODE_INACT (0x0 << IOCON_PIO_MODE_SHIFT) /*!< No addition pin function */ +#define IOCON_MODE_PULLDOWN (0x1 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-down function */ +#define IOCON_MODE_PULLUP (0x2 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-up function */ +#define IOCON_MODE_REPEATER (0x3 << IOCON_PIO_MODE_SHIFT) /*!< Selects pin repeater function */ +#endif + +#if defined(IOCON_PIO_I2CSLEW_SHIFT) +#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_I2CSLEW_SHIFT) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_I2CSLEW_SHIFT) /*!< I2C Slew Rate Control */ +#endif + +#if defined(IOCON_PIO_EGP_SHIFT) +#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_EGP_SHIFT) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_EGP_SHIFT) /*!< I2C Slew Rate Control */ +#endif + +#if defined(IOCON_PIO_SLEW_SHIFT) +#define IOCON_SLEW_STANDARD (0x0 << IOCON_PIO_SLEW_SHIFT) /*!< Driver Slew Rate Control */ +#define IOCON_SLEW_FAST (0x1 << IOCON_PIO_SLEW_SHIFT) /*!< Driver Slew Rate Control */ +#endif + +#if defined(IOCON_PIO_INVERT_SHIFT) +#define IOCON_INV_EN (0x1 << IOCON_PIO_INVERT_SHIFT) /*!< Enables invert function on input */ +#endif + +#if defined(IOCON_PIO_DIGIMODE_SHIFT) +#define IOCON_ANALOG_EN (0x0 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables analog function by setting 0 to bit 7 */ +#define IOCON_DIGITAL_EN \ + (0x1 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables digital function by setting 1 to bit 7(default) */ +#endif + +#if defined(IOCON_PIO_FILTEROFF_SHIFT) +#define IOCON_INPFILT_OFF (0x1 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter Off for GPIO pins */ +#define IOCON_INPFILT_ON (0x0 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter On for GPIO pins */ +#endif + +#if defined(IOCON_PIO_I2CDRIVE_SHIFT) +#define IOCON_I2C_LOWDRIVER (0x0 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< Low drive, Output drive sink is 4 mA */ +#define IOCON_I2C_HIGHDRIVER (0x1 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< High drive, Output drive sink is 20 mA */ +#endif + +#if defined(IOCON_PIO_OD_SHIFT) +#define IOCON_OPENDRAIN_EN (0x1 << IOCON_PIO_OD_SHIFT) /*!< Enables open-drain function */ +#endif + +#if defined(IOCON_PIO_I2CFILTER_SHIFT) +#define IOCON_I2CFILTER_OFF (0x1 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter enabled */ +#define IOCON_I2CFILTER_ON (0x0 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter not enabled, */ +#endif + +#if defined(IOCON_PIO_ASW_SHIFT) +#define IOCON_AWS_EN (0x1 << IOCON_PIO_ASW_SHIFT) /*!< Enables analog switch function */ +#endif + +#if defined(IOCON_PIO_SSEL_SHIFT) +#define IOCON_SSEL_3V3 (0x0 << IOCON_PIO_SSEL_SHIFT) /*!< 3V3 signaling in I2C mode */ +#define IOCON_SSEL_1V8 (0x1 << IOCON_PIO_SSEL_SHIFT) /*!< 1V8 signaling in I2C mode */ +#endif + +#if defined(IOCON_PIO_ECS_SHIFT) +#define IOCON_ECS_OFF (0x0 << IOCON_PIO_ECS_SHIFT) /*!< IO is an open drain cell */ +#define IOCON_ECS_ON (0x1 << IOCON_PIO_ECS_SHIFT) /*!< Pull-up resistor is connected */ +#endif + +#if defined(IOCON_PIO_S_MODE_SHIFT) +#define IOCON_S_MODE_0CLK (0x0 << IOCON_PIO_S_MODE_SHIFT) /*!< Bypass input filter */ +#define IOCON_S_MODE_1CLK \ + (0x1 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 1 filter clock are rejected \ \ \ \ \ + */ +#define IOCON_S_MODE_2CLK \ + (0x2 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 2 filter clock2 are rejected \ \ \ \ \ + */ +#define IOCON_S_MODE_3CLK \ + (0x3 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 3 filter clock2 are rejected \ \ \ \ \ + */ +#define IOCON_S_MODE(clks) ((clks) << IOCON_PIO_S_MODE_SHIFT) /*!< Select clocks for digital input filter mode */ +#endif + +#if defined(IOCON_PIO_CLK_DIV_SHIFT) +#define IOCON_CLKDIV(div) \ + ((div) \ + << IOCON_PIO_CLK_DIV_SHIFT) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */ +#endif + +#else +#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */ +#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */ +#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */ +#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */ +#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */ +#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */ +#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */ +#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */ + +#if defined(IOCON_PIO_MODE_SHIFT) +#define IOCON_MODE_INACT (0x0 << IOCON_PIO_MODE_SHIFT) /*!< No addition pin function */ +#define IOCON_MODE_PULLDOWN (0x1 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-down function */ +#define IOCON_MODE_PULLUP (0x2 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-up function */ +#define IOCON_MODE_REPEATER (0x3 << IOCON_PIO_MODE_SHIFT) /*!< Selects pin repeater function */ +#endif + +#if defined(IOCON_PIO_I2CSLEW_SHIFT) +#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_I2CSLEW_SHIFT) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_I2CSLEW_SHIFT) /*!< I2C Slew Rate Control */ +#endif + +#if defined(IOCON_PIO_EGP_SHIFT) +#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_EGP_SHIFT) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_EGP_SHIFT) /*!< I2C Slew Rate Control */ +#endif + +#if defined(IOCON_PIO_INVERT_SHIFT) +#define IOCON_INV_EN (0x1 << IOCON_PIO_INVERT_SHIFT) /*!< Enables invert function on input */ +#endif + +#if defined(IOCON_PIO_DIGIMODE_SHIFT) +#define IOCON_ANALOG_EN (0x0 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables analog function by setting 0 to bit 7 */ +#define IOCON_DIGITAL_EN \ + (0x1 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables digital function by setting 1 to bit 7(default) */ +#endif + +#if defined(IOCON_PIO_FILTEROFF_SHIFT) +#define IOCON_INPFILT_OFF (0x1 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter Off for GPIO pins */ +#define IOCON_INPFILT_ON (0x0 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter On for GPIO pins */ +#endif + +#if defined(IOCON_PIO_I2CDRIVE_SHIFT) +#define IOCON_I2C_LOWDRIVER (0x0 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< Low drive, Output drive sink is 4 mA */ +#define IOCON_I2C_HIGHDRIVER (0x1 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< High drive, Output drive sink is 20 mA */ +#endif + +#if defined(IOCON_PIO_OD_SHIFT) +#define IOCON_OPENDRAIN_EN (0x1 << IOCON_PIO_OD_SHIFT) /*!< Enables open-drain function */ +#endif + +#if defined(IOCON_PIO_I2CFILTER_SHIFT) +#define IOCON_I2CFILTER_OFF (0x1 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter enabled */ +#define IOCON_I2CFILTER_ON (0x0 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter not enabled */ +#endif + +#if defined(IOCON_PIO_S_MODE_SHIFT) +#define IOCON_S_MODE_0CLK (0x0 << IOCON_PIO_S_MODE_SHIFT) /*!< Bypass input filter */ +#define IOCON_S_MODE_1CLK \ + (0x1 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 1 filter clock are rejected \ \ \ \ \ + */ +#define IOCON_S_MODE_2CLK \ + (0x2 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 2 filter clock2 are rejected \ \ \ \ \ + */ +#define IOCON_S_MODE_3CLK \ + (0x3 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 3 filter clock2 are rejected \ \ \ \ \ + */ +#define IOCON_S_MODE(clks) ((clks) << IOCON_PIO_S_MODE_SHIFT) /*!< Select clocks for digital input filter mode */ +#endif + +#if defined(IOCON_PIO_CLK_DIV_SHIFT) +#define IOCON_CLKDIV(div) \ + ((div) \ + << IOCON_PIO_CLK_DIV_SHIFT) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */ +#endif + +#endif +#if defined(__cplusplus) +extern "C" { +#endif + +#if (defined(FSL_FEATURE_IOCON_ONE_DIMENSION) && (FSL_FEATURE_IOCON_ONE_DIMENSION == 1)) +/** + * @brief Sets I/O Control pin mux + * @param base : The base of IOCON peripheral on the chip + * @param ionumber : GPIO number to mux + * @param modefunc : OR'ed values of type IOCON_* + * @return Nothing + */ +__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t ionumber, uint32_t modefunc) +{ + base->PIO[ionumber] = modefunc; +} +#else +/** + * @brief Sets I/O Control pin mux + * @param base : The base of IOCON peripheral on the chip + * @param port : GPIO port to mux + * @param pin : GPIO pin to mux + * @param modefunc : OR'ed values of type IOCON_* + * @return Nothing + */ +__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc) +{ + base->PIO[port][pin] = modefunc; +} +#endif + +/** + * @brief Set all I/O Control pin muxing + * @param base : The base of IOCON peripheral on the chip + * @param pinArray : Pointer to array of pin mux selections + * @param arrayLength : Number of entries in pinArray + * @return Nothing + */ +__STATIC_INLINE void IOCON_SetPinMuxing(IOCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength) +{ + uint32_t i; + + for (i = 0; i < arrayLength; i++) + { +#if (defined(FSL_FEATURE_IOCON_ONE_DIMENSION) && (FSL_FEATURE_IOCON_ONE_DIMENSION == 1)) + IOCON_PinMuxSet(base, pinArray[i].ionumber, pinArray[i].modefunc); +#else + IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc); +#endif /* FSL_FEATURE_IOCON_ONE_DIMENSION */ + } +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +#endif /* _FSL_IOCON_H_ */ diff --git a/drivers/fsl_reset.c b/drivers/fsl_reset.c new file mode 100644 index 0000000..b801e97 --- /dev/null +++ b/drivers/fsl_reset.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016, NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_reset.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.reset" +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) + +/*! + * brief Assert reset to peripheral. + * + * Asserts reset signal to specified peripheral module. + * + * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_SetPeripheralReset(reset_ip_name_t peripheral) +{ + const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16; + const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu); + const uint32_t bitMask = 1UL << bitPos; + + assert(bitPos < 32UL); + + /* ASYNC_SYSCON registers have offset 1024 */ + if (regIndex >= SYSCON_PRESETCTRL_COUNT) + { + /* reset register is in ASYNC_SYSCON */ + + /* set bit */ + ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask; + /* wait until it reads 0b1 */ + while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask)) + { + } + } + else + { + /* reset register is in SYSCON */ + + /* set bit */ + SYSCON->PRESETCTRLSET[regIndex] = bitMask; + /* wait until it reads 0b1 */ + while (0u == (SYSCON->PRESETCTRL[regIndex] & bitMask)) + { + } + } +} + +/*! + * brief Clear reset to peripheral. + * + * Clears reset signal to specified peripheral module, allows it to operate. + * + * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_ClearPeripheralReset(reset_ip_name_t peripheral) +{ + const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16; + const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu); + const uint32_t bitMask = 1UL << bitPos; + + assert(bitPos < 32UL); + + /* ASYNC_SYSCON registers have offset 1024 */ + if (regIndex >= SYSCON_PRESETCTRL_COUNT) + { + /* reset register is in ASYNC_SYSCON */ + + /* clear bit */ + ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask; + /* wait until it reads 0b0 */ + while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask)) + { + } + } + else + { + /* reset register is in SYSCON */ + + /* clear bit */ + SYSCON->PRESETCTRLCLR[regIndex] = bitMask; + /* wait until it reads 0b0 */ + while (bitMask == (SYSCON->PRESETCTRL[regIndex] & bitMask)) + { + } + } +} + +/*! + * brief Reset peripheral module. + * + * Reset peripheral module. + * + * param peripheral Peripheral to reset. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_PeripheralReset(reset_ip_name_t peripheral) +{ + RESET_SetPeripheralReset(peripheral); + RESET_ClearPeripheralReset(peripheral); +} + +/*! + * brief Set slave core to reset state and hold. + */ +void RESET_SetSlaveCoreReset(void) +{ + uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U; + + /* CM4 is the master. */ + if (SYSCON_CPUCTRL_MASTERCPU_MASK == (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK)) + { + SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM0RSTEN_MASK; + } + /* CM0 is the master. */ + else + { + SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM4RSTEN_MASK; + } +} + +/*! + * brief Release slave core from reset state. + */ +void RESET_ClearSlaveCoreReset(void) +{ + uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U; + + /* CM4 is the master. */ + if (SYSCON_CPUCTRL_MASTERCPU_MASK == (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK)) + { + SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM0RSTEN_MASK; + } + /* CM0 is the master. */ + else + { + SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM4RSTEN_MASK; + } +} + +/*! + * brief Reset slave core with the boot entry. + */ +void RESET_SlaveCoreReset(uint32_t bootAddr, uint32_t bootStackPointer) +{ + volatile uint32_t i = 10U; + + SYSCON->CPSTACK = bootStackPointer; + SYSCON->CPBOOT = bootAddr; + + RESET_SetSlaveCoreReset(); + while(0U != i--){} + RESET_ClearSlaveCoreReset(); +} + +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */ diff --git a/drivers/fsl_reset.h b/drivers/fsl_reset.h new file mode 100644 index 0000000..dc32a18 --- /dev/null +++ b/drivers/fsl_reset.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016, NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_RESET_H_ +#define _FSL_RESET_H_ + +#include +#include +#include +#include +#include "fsl_device_registers.h" + +/*! + * @addtogroup reset + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief reset driver version 2.0.1. */ +#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief Enumeration for peripheral reset control bits + * + * Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers + */ +typedef enum _SYSCON_RSTn +{ + kFLASH_RST_SHIFT_RSTn = 0 | 7U, /**< Flash controller reset control */ + kFMC_RST_SHIFT_RSTn = 0 | 8U, /**< Flash accelerator reset control */ + kMUX_RST_SHIFT_RSTn = 0 | 11U, /**< Input mux reset control */ + kIOCON_RST_SHIFT_RSTn = 0 | 13U, /**< IOCON reset control */ + kGPIO0_RST_SHIFT_RSTn = 0 | 14U, /**< GPIO0 reset control */ + kGPIO1_RST_SHIFT_RSTn = 0 | 15U, /**< GPIO1 reset control */ + kPINT_RST_SHIFT_RSTn = 0 | 18U, /**< Pin interrupt (PINT) reset control */ + kGINT_RST_SHIFT_RSTn = 0 | 19U, /**< Grouped interrupt (PINT) reset control. */ + kDMA_RST_SHIFT_RSTn = 0 | 20U, /**< DMA reset control */ + kCRC_RST_SHIFT_RSTn = 0 | 21U, /**< CRC reset control */ + kWWDT_RST_SHIFT_RSTn = 0 | 22U, /**< Watchdog timer reset control */ + kADC0_RST_SHIFT_RSTn = 0 | 27U, /**< ADC0 reset control */ + kMRT_RST_SHIFT_RSTn = 65536 | 0U, /**< Multi-rate timer (MRT) reset control */ + kSCT0_RST_SHIFT_RSTn = 65536 | 2U, /**< SCTimer/PWM 0 (SCT0) reset control */ + kUTICK_RST_SHIFT_RSTn = 65536 | 10U, /**< Micro-tick timer reset control */ + kFC0_RST_SHIFT_RSTn = 65536 | 11U, /**< Flexcomm Interface 0 reset control */ + kFC1_RST_SHIFT_RSTn = 65536 | 12U, /**< Flexcomm Interface 1 reset control */ + kFC2_RST_SHIFT_RSTn = 65536 | 13U, /**< Flexcomm Interface 2 reset control */ + kFC3_RST_SHIFT_RSTn = 65536 | 14U, /**< Flexcomm Interface 3 reset control */ + kFC4_RST_SHIFT_RSTn = 65536 | 15U, /**< Flexcomm Interface 4 reset control */ + kFC5_RST_SHIFT_RSTn = 65536 | 16U, /**< Flexcomm Interface 5 reset control */ + kFC6_RST_SHIFT_RSTn = 65536 | 17U, /**< Flexcomm Interface 6 reset control */ + kFC7_RST_SHIFT_RSTn = 65536 | 18U, /**< Flexcomm Interface 7 reset control */ + kDMIC_RST_SHIFT_RSTn = 65536 | 19U, /**< Digital microphone interface reset control */ + kCT32B2_RST_SHIFT_RSTn = 65536 | 22U, /**< CT32B2 reset control */ + kUSB_RST_SHIFT_RSTn = 65536 | 25U, /**< USB reset control */ + kCT32B0_RST_SHIFT_RSTn = 65536 | 26U, /**< CT32B0 reset control */ + kCT32B1_RST_SHIFT_RSTn = 65536 | 27U, /**< CT32B1 reset control */ + kCT32B3_RST_SHIFT_RSTn = 67108864 | 13U, /**< CT32B3 reset control */ + kCT32B4_RST_SHIFT_RSTn = 67108864 | 14U, /**< CT32B4 reset control */ +} SYSCON_RSTn_t; + +/** Array initializers with peripheral reset bits **/ +#define ADC_RSTS \ + { \ + kADC0_RST_SHIFT_RSTn \ + } /* Reset bits for ADC peripheral */ +#define CRC_RSTS \ + { \ + kCRC_RST_SHIFT_RSTn \ + } /* Reset bits for CRC peripheral */ +#define DMA_RSTS_N \ + { \ + kDMA_RST_SHIFT_RSTn \ + } /* Reset bits for DMA peripheral */ +#define DMIC_RSTS \ + { \ + kDMIC_RST_SHIFT_RSTn \ + } /* Reset bits for ADC peripheral */ +#define FLEXCOMM_RSTS \ + { \ + kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \ + kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn, kFC7_RST_SHIFT_RSTn \ + } /* Reset bits for FLEXCOMM peripheral */ +#define GINT_RSTS \ + { \ + kGINT_RST_SHIFT_RSTn, kGINT_RST_SHIFT_RSTn \ + } /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */ +#define GPIO_RSTS_N \ + { \ + kGPIO0_RST_SHIFT_RSTn, kGPIO1_RST_SHIFT_RSTn \ + } /* Reset bits for GPIO peripheral */ +#define INPUTMUX_RSTS \ + { \ + kMUX_RST_SHIFT_RSTn \ + } /* Reset bits for INPUTMUX peripheral */ +#define IOCON_RSTS \ + { \ + kIOCON_RST_SHIFT_RSTn \ + } /* Reset bits for IOCON peripheral */ +#define FLASH_RSTS \ + { \ + kFLASH_RST_SHIFT_RSTn, kFMC_RST_SHIFT_RSTn \ + } /* Reset bits for Flash peripheral */ +#define MRT_RSTS \ + { \ + kMRT_RST_SHIFT_RSTn \ + } /* Reset bits for MRT peripheral */ +#define PINT_RSTS \ + { \ + kPINT_RST_SHIFT_RSTn \ + } /* Reset bits for PINT peripheral */ +#define SCT_RSTS \ + { \ + kSCT0_RST_SHIFT_RSTn \ + } /* Reset bits for SCT peripheral */ +#define CTIMER_RSTS \ + { \ + kCT32B0_RST_SHIFT_RSTn, kCT32B1_RST_SHIFT_RSTn, kCT32B2_RST_SHIFT_RSTn, kCT32B3_RST_SHIFT_RSTn, \ + kCT32B4_RST_SHIFT_RSTn \ + } /* Reset bits for TIMER peripheral */ +#define USB_RSTS \ + { \ + kUSB_RST_SHIFT_RSTn \ + } /* Reset bits for USB peripheral */ +#define UTICK_RSTS \ + { \ + kUTICK_RST_SHIFT_RSTn \ + } /* Reset bits for UTICK peripheral */ +#define WWDT_RSTS \ + { \ + kWWDT_RST_SHIFT_RSTn \ + } /* Reset bits for WWDT peripheral */ + +typedef SYSCON_RSTn_t reset_ip_name_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Assert reset to peripheral. + * + * Asserts reset signal to specified peripheral module. + * + * @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_SetPeripheralReset(reset_ip_name_t peripheral); + +/*! + * @brief Clear reset to peripheral. + * + * Clears reset signal to specified peripheral module, allows it to operate. + * + * @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_ClearPeripheralReset(reset_ip_name_t peripheral); + +/*! + * @brief Reset peripheral module. + * + * Reset peripheral module. + * + * @param peripheral Peripheral to reset. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_PeripheralReset(reset_ip_name_t peripheral); + +/*! + * @brief Set slave core to reset state and hold. + */ +void RESET_SetSlaveCoreReset(void); + +/*! + * @brief Release slave core from reset state. + */ +void RESET_ClearSlaveCoreReset(void); + +/*! + * @brief Reset slave core with the boot entry. + */ +void RESET_SlaveCoreReset(uint32_t bootAddr, uint32_t bootStackPointer); + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_RESET_H_ */ diff --git a/drivers/fsl_sctimer.c b/drivers/fsl_sctimer.c new file mode 100644 index 0000000..5ed3445 --- /dev/null +++ b/drivers/fsl_sctimer.c @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_sctimer.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.sctimer" +#endif + +/*! @brief Typedef for interrupt handler. */ +typedef void (*sctimer_isr_t)(SCT_Type *base); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base SCTimer peripheral base address + * + * @return The SCTimer instance + */ +static uint32_t SCTIMER_GetInstance(SCT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to SCT bases for each instance. */ +static SCT_Type *const s_sctBases[] = SCT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to SCT clocks for each instance. */ +static const clock_ip_name_t s_sctClocks[] = SCT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) +#if defined(FSL_FEATURE_SCT_WRITE_ZERO_ASSERT_RESET) && FSL_FEATURE_SCT_WRITE_ZERO_ASSERT_RESET +/*! @brief Pointers to SCT resets for each instance, writing a zero asserts the reset */ +static const reset_ip_name_t s_sctResets[] = SCT_RSTS_N; +#else +/*! @brief Pointers to SCT resets for each instance, writing a one asserts the reset */ +static const reset_ip_name_t s_sctResets[] = SCT_RSTS; +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */ + +/*!< @brief SCTimer event Callback function. */ +static sctimer_event_callback_t s_eventCallback[FSL_FEATURE_SCT_NUMBER_OF_EVENTS]; + +/*!< @brief Keep track of SCTimer event number */ +static uint32_t s_currentEvent; + +/*!< @brief Keep track of SCTimer state number */ +static uint32_t s_currentState; + +/*!< @brief Keep track of SCTimer unify 32-bit or low 16-bit match/capture register number. */ +static uint32_t s_currentMatch; +/*!< @brief Keep track of SCTimer high 16-bit match/capture register number. */ +static uint32_t s_currentMatchhigh; + +/*! @brief Pointer to SCTimer IRQ handler */ +static sctimer_isr_t s_sctimerIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t SCTIMER_GetInstance(SCT_Type *base) +{ + uint32_t instance; + uint32_t sctArrayCount = (sizeof(s_sctBases) / sizeof(s_sctBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < sctArrayCount; instance++) + { + if (s_sctBases[instance] == base) + { + break; + } + } + + assert(instance < sctArrayCount); + + return instance; +} + +/*! + * brief Ungates the SCTimer clock and configures the peripheral for basic operation. + * + * note This API should be called at the beginning of the application using the SCTimer driver. + * + * param base SCTimer peripheral base address + * param config Pointer to the user configuration structure. + * + * return kStatus_Success indicates success; Else indicates failure. + */ +status_t SCTIMER_Init(SCT_Type *base, const sctimer_config_t *config) +{ + assert(NULL != config); + + uint32_t i; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the SCTimer clock*/ + CLOCK_EnableClock(s_sctClocks[SCTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) + /* Reset the module. */ + RESET_PeripheralReset(s_sctResets[SCTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */ + + /* Setup the counter operation. For Current Driver interface SCTIMER_Init don't know detail + * frequency of input clock, but User know it. So the INSYNC have to set by user level. */ + base->CONFIG = SCT_CONFIG_CKSEL(config->clockSelect) | SCT_CONFIG_CLKMODE(config->clockMode) | + SCT_CONFIG_UNIFY(config->enableCounterUnify) | SCT_CONFIG_INSYNC(config->inputsync); + + /* Write to the control register, keep the counters halted. */ + base->CTRL = + SCT_CTRL_BIDIR_L(config->enableBidirection_l) | SCT_CTRL_PRE_L(config->prescale_l) | SCT_CTRL_HALT_L_MASK; + /* Clear the counter after changing the PRE value. */ + base->CTRL |= SCT_CTRL_CLRCTR_L_MASK; + + if (!(config->enableCounterUnify)) + { + base->CTRL |= + SCT_CTRL_BIDIR_H(config->enableBidirection_h) | SCT_CTRL_PRE_H(config->prescale_h) | SCT_CTRL_HALT_H_MASK; + base->CTRL |= SCT_CTRL_CLRCTR_H_MASK; + } + + /* Initial state of channel output */ + base->OUTPUT = config->outInitState; + + /* Clear the global variables */ + s_currentEvent = 0U; + s_currentState = 0U; + s_currentMatch = 0U; + s_currentMatchhigh = 0U; + + /* Clear the callback array */ + for (i = 0; i < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS; i++) + { + s_eventCallback[i] = NULL; + } + + /* Save interrupt handler */ + s_sctimerIsr = SCTIMER_EventHandleIRQ; + + return kStatus_Success; +} + +/*! + * brief Gates the SCTimer clock. + * + * param base SCTimer peripheral base address + */ +void SCTIMER_Deinit(SCT_Type *base) +{ + /* Halt the counters */ + base->CTRL |= (SCT_CTRL_HALT_L_MASK | SCT_CTRL_HALT_H_MASK); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the SCTimer clock*/ + CLOCK_DisableClock(s_sctClocks[SCTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Fills in the SCTimer configuration structure with the default settings. + * + * The default values are: + * code + * config->enableCounterUnify = true; + * config->clockMode = kSCTIMER_System_ClockMode; + * config->clockSelect = kSCTIMER_Clock_On_Rise_Input_0; + * config->enableBidirection_l = false; + * config->enableBidirection_h = false; + * config->prescale_l = 0U; + * config->prescale_h = 0U; + * config->outInitState = 0U; + * config->inputsync = 0xFU; + * endcode + * param config Pointer to the user configuration structure. + */ +void SCTIMER_GetDefaultConfig(sctimer_config_t *config) +{ + assert(NULL != config); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + /* SCT operates as a unified 32-bit counter */ + config->enableCounterUnify = true; + /* System clock clocks the entire SCT module */ + config->clockMode = kSCTIMER_System_ClockMode; + /* This is used only by certain clock modes */ + config->clockSelect = kSCTIMER_Clock_On_Rise_Input_0; + /* Up count mode only for the unified counter */ + config->enableBidirection_l = false; + /* Up count mode only for Counte_H */ + config->enableBidirection_h = false; + /* Prescale factor of 1 */ + config->prescale_l = 0U; + /* Prescale factor of 1 for Counter_H*/ + config->prescale_h = 0U; + /* Clear outputs */ + config->outInitState = 0U; + /* Default value is 0xFU, it can be clear as 0 when speical conditions met. + * Condition can be clear as 0: (for all Clock Modes): + * (1) The corresponding input is already synchronous to the SCTimer/PWM clock. + * (2) The SCTimer/PWM clock frequency does not exceed 100 MHz. + * Note: The SCTimer/PWM clock is the bus/system clock for CKMODE 0-2 or asynchronous input + * clock for CKMODE3. + * Another condition can be clear as 0: (for CKMODE2 only) + * (1) The corresponding input is synchronous to the designated CKMODE2 input clock. + * (2) The CKMODE2 input clock frequency is less than one-third the frequency of the bus/system clock. + * Default value set as 0U, input0~input3 are set as bypasses. */ + config->inputsync = 0xFU; +} + +/*! + * brief Configures the PWM signal parameters. + * + * Call this function to configure the PWM signal period, mode, duty cycle, and edge. This + * function will create 2 events; one of the events will trigger on match with the pulse value + * and the other will trigger when the counter matches the PWM period. The PWM period event is + * also used as a limit event to reset the counter or change direction. Both events are enabled + * for the same state. The state number can be retrieved by calling the function + * SCTIMER_GetCurrentStateNumber(). + * The counter is set to operate as one 32-bit counter (unify bit is set to 1). + * The counter operates in bi-directional mode when generating a center-aligned PWM. + * + * note When setting PWM output from multiple output pins, they all should use the same PWM mode + * i.e all PWM's should be either edge-aligned or center-aligned. + * When using this API, the PWM signal frequency of all the initialized channels must be the same. + * Otherwise all the initialized channels' PWM signal frequency is equal to the last call to the + * API's pwmFreq_Hz. + * + * param base SCTimer peripheral base address + * param pwmParams PWM parameters to configure the output + * param mode PWM operation mode, options available in enumeration ::sctimer_pwm_mode_t + * param pwmFreq_Hz PWM signal frequency in Hz + * param srcClock_Hz SCTimer counter clock in Hz + * param event Pointer to a variable where the PWM period event number is stored + * + * return kStatus_Success on success + * kStatus_Fail If we have hit the limit in terms of number of events created or if + * an incorrect PWM dutycylce is passed in. + */ +status_t SCTIMER_SetupPwm(SCT_Type *base, + const sctimer_pwm_signal_param_t *pwmParams, + sctimer_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + uint32_t *event) +{ + assert(NULL != pwmParams); + assert(0U != srcClock_Hz); + assert(0U != pwmFreq_Hz); + assert((uint32_t)pwmParams->output < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS); + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + + /* If we do not have enough events available (this function will create two events), + * the function will return fail. + */ + status_t status = kStatus_Fail; + status_t status2; + uint32_t period, pulsePeriod = 0; + uint32_t sctClock = srcClock_Hz / (((base->CTRL & SCT_CTRL_PRE_L_MASK) >> SCT_CTRL_PRE_L_SHIFT) + 1U); + uint32_t periodEvent = 0, pulseEvent = 0; + uint32_t reg; + + if ((s_currentEvent + 2U) <= (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS) + { + /* Use bi-directional mode for center-aligned PWM */ + if (mode == kSCTIMER_CenterAlignedPwm) + { + base->CTRL |= SCT_CTRL_BIDIR_L_MASK; + } + + /* Calculate PWM period match value */ + if (mode == kSCTIMER_EdgeAlignedPwm) + { + period = (sctClock / pwmFreq_Hz) - 1U; + } + else + { + period = sctClock / (pwmFreq_Hz * 2U); + } + + /* Calculate pulse width and period match value: + * For EdgeAlignedPwm, "pulsePeriod = 0" results in 0% dutycyle, "pulsePeriod = period - 1U" results in 100% + * dutycyle. For CenterAlignedPwm, , "pulsePeriod = 0" results in 0% dutycyle, "pulsePeriod = period + 2U" + * results in 100% dutycyle. + */ + + pulsePeriod = (uint32_t)(((uint64_t)period * pwmParams->dutyCyclePercent) / 100U); + + if (pwmParams->dutyCyclePercent >= 100U) + { + if (mode == kSCTIMER_EdgeAlignedPwm) + { + pulsePeriod = period + 2U; + } + else + { + pulsePeriod = period - 1U; + } + } + + /* Schedule an event when we reach the PWM period */ + status = + SCTIMER_CreateAndScheduleEvent(base, kSCTIMER_MatchEventOnly, period, 0, kSCTIMER_Counter_U, &periodEvent); + + /* Schedule an event when we reach the pulse width */ + status2 = SCTIMER_CreateAndScheduleEvent(base, kSCTIMER_MatchEventOnly, pulsePeriod, 0, kSCTIMER_Counter_U, + &pulseEvent); + + if ((kStatus_Success == status) && (kStatus_Success == status2)) + { + /* Reset the counter when we reach the PWM period */ + SCTIMER_SetupCounterLimitAction(base, kSCTIMER_Counter_U, periodEvent); + + /* Return the period event to the user */ + *event = periodEvent; + + /* For high-true level */ + if ((uint32_t)pwmParams->level == (uint32_t)kSCTIMER_HighTrue) + { + /* Set the initial output level to low which is the inactive state */ + base->OUTPUT &= ~(1UL << (uint32_t)pwmParams->output); + + if (mode == kSCTIMER_EdgeAlignedPwm) + { + /* Set the output when we reach the PWM period */ + SCTIMER_SetupOutputSetAction(base, (uint32_t)pwmParams->output, periodEvent); + /* Clear the output when we reach the PWM pulse value */ + SCTIMER_SetupOutputClearAction(base, (uint32_t)pwmParams->output, pulseEvent); + } + else + { + /* Clear the output when we reach the PWM pulse event */ + SCTIMER_SetupOutputClearAction(base, (uint32_t)pwmParams->output, pulseEvent); + /* Reverse output when down counting */ + reg = base->OUTPUTDIRCTRL; + reg &= ~((uint32_t)SCT_OUTPUTDIRCTRL_SETCLR0_MASK << (2U * (uint32_t)pwmParams->output)); + reg |= (1UL << (2U * (uint32_t)pwmParams->output)); + base->OUTPUTDIRCTRL = reg; + } + } + /* For low-true level */ + else + { + /* Set the initial output level to high which is the inactive state */ + base->OUTPUT |= (1UL << (uint32_t)pwmParams->output); + + if (mode == kSCTIMER_EdgeAlignedPwm) + { + /* Clear the output when we reach the PWM period */ + SCTIMER_SetupOutputClearAction(base, (uint32_t)pwmParams->output, periodEvent); + /* Set the output when we reach the PWM pulse value */ + SCTIMER_SetupOutputSetAction(base, (uint32_t)pwmParams->output, pulseEvent); + } + else + { + /* Set the output when we reach the PWM pulse event */ + SCTIMER_SetupOutputSetAction(base, (uint32_t)pwmParams->output, pulseEvent); + /* Reverse output when down counting */ + reg = base->OUTPUTDIRCTRL; + reg &= ~((uint32_t)SCT_OUTPUTDIRCTRL_SETCLR0_MASK << (2U * (uint32_t)pwmParams->output)); + reg |= (1UL << (2U * (uint32_t)pwmParams->output)); + base->OUTPUTDIRCTRL = reg; + } + } + } + else + { + status = kStatus_Fail; + } + } + + return status; +} + +/*! + * brief Updates the duty cycle of an active PWM signal. + * + * Before calling this function, the counter is set to operate as one 32-bit counter (unify bit is set to 1). + * + * param base SCTimer peripheral base address + * param output The output to configure + * param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100 + * param event Event number associated with this PWM signal. This was returned to the user by the + * function SCTIMER_SetupPwm(). + */ +void SCTIMER_UpdatePwmDutycycle(SCT_Type *base, sctimer_out_t output, uint8_t dutyCyclePercent, uint32_t event) + +{ + assert(dutyCyclePercent <= 100U); + assert((uint32_t)output < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS); + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + + uint32_t periodMatchReg, pulseMatchReg; + uint32_t pulsePeriod = 0, period; + + /* Retrieve the match register number for the PWM period */ + periodMatchReg = base->EV[event].CTRL & SCT_EV_CTRL_MATCHSEL_MASK; + + /* Retrieve the match register number for the PWM pulse period */ + pulseMatchReg = base->EV[event + 1U].CTRL & SCT_EV_CTRL_MATCHSEL_MASK; + + period = base->MATCH[periodMatchReg]; + + /* Calculate pulse width and period match value: + * For EdgeAlignedPwm, "pulsePeriod = 0" results in 0% dutycyle, "pulsePeriod = period - 1U" results in 100% + * dutycyle. For CenterAlignedPwm, , "pulsePeriod = 0" results in 0% dutycyle, "pulsePeriod = period + 2U" + * results in 100% dutycyle. + */ + pulsePeriod = (uint32_t)(((uint64_t)period * dutyCyclePercent) / 100U); + + if (dutyCyclePercent == 100U) + { + if (0U == (base->CTRL & SCT_CTRL_BIDIR_L_MASK)) + { + pulsePeriod = period + 2U; + } + else + { + pulsePeriod = period - 1U; + } + } + + /* Stop the counter before updating match register */ + SCTIMER_StopTimer(base, (uint32_t)kSCTIMER_Counter_U); + + /* Update dutycycle */ + base->MATCH[pulseMatchReg] = SCT_MATCH_MATCHn_L(pulsePeriod); + base->MATCHREL[pulseMatchReg] = SCT_MATCHREL_RELOADn_L(pulsePeriod); + + /* Restart the counter */ + SCTIMER_StartTimer(base, (uint32_t)kSCTIMER_Counter_U); +} + +/*! + * brief Create an event that is triggered on a match or IO and schedule in current state. + * + * This function will configure an event using the options provided by the user. If the event type uses + * the counter match, then the function will set the user provided match value into a match register + * and put this match register number into the event control register. + * The event is enabled for the current state and the event number is increased by one at the end. + * The function returns the event number; this event number can be used to configure actions to be + * done when this event is triggered. + * + * param base SCTimer peripheral base address + * param howToMonitor Event type; options are available in the enumeration ::sctimer_interrupt_enable_t + * param matchValue The match value that will be programmed to a match register + * param whichIO The input or output that will be involved in event triggering. This field + * is ignored if the event type is "match only" + * param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * param event Pointer to a variable where the new event number is stored + * + * return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of number of events created or + if we have reached the limit in terms of number of match registers + */ +status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base, + sctimer_event_t howToMonitor, + uint32_t matchValue, + uint32_t whichIO, + sctimer_counter_t whichCounter, + uint32_t *event) +{ + uint32_t combMode = (((uint32_t)howToMonitor & SCT_EV_CTRL_COMBMODE_MASK) >> SCT_EV_CTRL_COMBMODE_SHIFT); + uint32_t currentCtrlVal = (uint32_t)howToMonitor; + status_t status = kStatus_Success; + + if (s_currentEvent < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS) + { + if (2U == combMode) + { + base->EV[s_currentEvent].CTRL = currentCtrlVal | SCT_EV_CTRL_IOSEL(whichIO); + } + else + { + if ((0U == combMode) || (3U == combMode)) + { + currentCtrlVal |= SCT_EV_CTRL_IOSEL(whichIO); + } + + if ((kSCTIMER_Counter_L == whichCounter) && (0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK))) + { + if (s_currentMatch < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + currentCtrlVal |= SCT_EV_CTRL_MATCHSEL(s_currentMatch); + + /* Use Counter_L bits if user wants to setup the Low counter */ + base->MATCH_ACCESS16BIT[s_currentMatch].MATCHL = (uint16_t)matchValue; + base->MATCHREL_ACCESS16BIT[s_currentMatch].MATCHRELL = (uint16_t)matchValue; + base->EV[s_currentEvent].CTRL = currentCtrlVal; + + /* Increment the match register number */ + s_currentMatch++; + } + else + { + /* An error would occur if we have hit the limit in terms of number of match registers */ + status = kStatus_Fail; + } + } + else if ((kSCTIMER_Counter_H == whichCounter) && (0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK))) + { + if (s_currentMatchhigh < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + currentCtrlVal |= SCT_EV_CTRL_MATCHSEL(s_currentMatchhigh); + + /* Use Counter_H bits if user wants to setup the High counter */ + currentCtrlVal |= SCT_EV_CTRL_HEVENT(1U); + base->MATCH_ACCESS16BIT[s_currentMatchhigh].MATCHH = (uint16_t)matchValue; + base->MATCHREL_ACCESS16BIT[s_currentMatchhigh].MATCHRELH = (uint16_t)matchValue; + + base->EV[s_currentEvent].CTRL = currentCtrlVal; + /* Increment the match register number */ + s_currentMatchhigh++; + } + else + { + /* An error would occur if we have hit the limit in terms of number of match registers */ + status = kStatus_Fail; + } + } + else if ((kSCTIMER_Counter_U == whichCounter) && (0U != (base->CONFIG & SCT_CONFIG_UNIFY_MASK))) + { + if (s_currentMatch < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + /* Use Counter_L bits if counter is operating in 32-bit mode */ + currentCtrlVal |= SCT_EV_CTRL_MATCHSEL(s_currentMatch); + + base->MATCH[s_currentMatch] = matchValue; + base->MATCHREL[s_currentMatch] = matchValue; + base->EV[s_currentEvent].CTRL = currentCtrlVal; + + /* Increment the match register number */ + s_currentMatch++; + } + else + { + /* An error would occur if we have hit the limit in terms of number of match registers */ + status = kStatus_Fail; + } + } + else + { + /* The used counter must match the CONFIG[UNIFY] bit selection */ + status = kStatus_Fail; + } + } + + if (kStatus_Success == status) + { + /* Enable the event in the current state */ + base->EV[s_currentEvent].STATE = (1UL << s_currentState); + + /* Return the event number */ + *event = s_currentEvent; + + /* Increment the event number */ + s_currentEvent++; + } + } + else + { + /* An error would occur if we have hit the limit in terms of number of events created */ + status = kStatus_Fail; + } + + return status; +} + +/*! + * brief Enable an event in the current state. + * + * This function will allow the event passed in to trigger in the current state. The event must + * be created earlier by either calling the function SCTIMER_SetupPwm() or function + * SCTIMER_CreateAndScheduleEvent() . + * + * param base SCTimer peripheral base address + * param event Event number to enable in the current state + * + */ +void SCTIMER_ScheduleEvent(SCT_Type *base, uint32_t event) +{ + /* Enable event in the current state */ + base->EV[event].STATE |= (1UL << s_currentState); +} + +/*! + * brief Increase the state by 1 + * + * All future events created by calling the function SCTIMER_ScheduleEvent() will be enabled in this new + * state. + * + * param base SCTimer peripheral base address + * + * return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of states used + + */ +status_t SCTIMER_IncreaseState(SCT_Type *base) +{ + status_t status = kStatus_Success; + + /* Return an error if we have hit the limit in terms of states used */ + if (s_currentState >= (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_STATES) + { + status = kStatus_Fail; + } + else + { + s_currentState++; + } + + return status; +} + +/*! + * brief Provides the current state + * + * User can use this to set the next state by calling the function SCTIMER_SetupNextStateAction(). + * + * param base SCTimer peripheral base address + * + * return The current state + */ +uint32_t SCTIMER_GetCurrentState(SCT_Type *base) +{ + return s_currentState; +} + +/*! + * brief Toggle the output level. + * + * This change in the output level is triggered by the event number that is passed in by the user. + * + * param base SCTimer peripheral base address + * param whichIO The output to toggle + * param event Event number that will trigger the output change + */ +void SCTIMER_SetupOutputToggleAction(SCT_Type *base, uint32_t whichIO, uint32_t event) +{ + assert(whichIO < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS); + + uint32_t reg; + + /* Set the same event to set and clear the output */ + base->OUT[whichIO].CLR |= (1UL << event); + base->OUT[whichIO].SET |= (1UL << event); + + /* Set the conflict resolution to toggle output */ + reg = base->RES; + reg &= ~(((uint32_t)SCT_RES_O0RES_MASK) << (2U * whichIO)); + reg |= ((uint32_t)(kSCTIMER_ResolveToggle)) << (2U * whichIO); + base->RES = reg; +} + +/*! + * brief Setup capture of the counter value on trigger of a selected event + * + * param base SCTimer peripheral base address + * param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * param captureRegister Pointer to a variable where the capture register number will be returned. User + * can read the captured value from this register when the specified event is triggered. + * param event Event number that will trigger the capture + * + * return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of number of match/capture registers available + */ +status_t SCTIMER_SetupCaptureAction(SCT_Type *base, + sctimer_counter_t whichCounter, + uint32_t *captureRegister, + uint32_t event) +{ + status_t status; + + if ((kSCTIMER_Counter_L == whichCounter) || (kSCTIMER_Counter_U == whichCounter)) + { + if (s_currentMatch < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + /* Set the bit to enable event */ + base->CAPCTRL_ACCESS16BIT[s_currentMatch].CAPCTRLL |= SCT_CAPCTRLL_CAPCTRLL(1UL << event); + + /* Set this resource to be a capture rather than match */ + base->REGMODE_ACCESS16BIT.REGMODEL |= SCT_REGMODEL_REGMODEL(1UL << s_currentMatch); + + /* Return the match register number */ + *captureRegister = s_currentMatch; + + /* Increase the match register number */ + s_currentMatch++; + + status = kStatus_Success; + } + else + { + /* Return an error if we have hit the limit in terms of number of capture/match registers used */ + status = kStatus_Fail; + } + } + else + { + if (s_currentMatchhigh < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + /* Set bit to enable event */ + base->CAPCTRL_ACCESS16BIT[s_currentMatchhigh].CAPCTRLH |= SCT_CAPCTRLL_CAPCTRLL(1UL << event); + + /* Set this resource to be a capture rather than match */ + base->REGMODE_ACCESS16BIT.REGMODEH |= SCT_REGMODEL_REGMODEL(1UL << s_currentMatchhigh); + + /* Return the match register number */ + *captureRegister = s_currentMatchhigh; + + /* Increase the match register number */ + s_currentMatchhigh++; + + status = kStatus_Success; + } + else + { + /* Return an error if we have hit the limit in terms of number of capture/match registers used */ + status = kStatus_Fail; + } + } + + return status; +} + +/*! + * brief Receive noticification when the event trigger an interrupt. + * + * If the interrupt for the event is enabled by the user, then a callback can be registered + * which will be invoked when the event is triggered + * + * param base SCTimer peripheral base address + * param event Event number that will trigger the interrupt + * param callback Function to invoke when the event is triggered + */ + +void SCTIMER_SetCallback(SCT_Type *base, sctimer_event_callback_t callback, uint32_t event) +{ + s_eventCallback[event] = callback; +} + +/*! + * brief SCTimer interrupt handler. + * + * param base SCTimer peripheral base address. + */ +void SCTIMER_EventHandleIRQ(SCT_Type *base) +{ + uint32_t eventFlag = SCT0->EVFLAG; + /* Only clear the flags whose interrupt field is enabled */ + uint32_t clearFlag = (eventFlag & SCT0->EVEN); + uint32_t mask = eventFlag; + uint32_t i; + + /* Invoke the callback for certain events */ + for (i = 0; i < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS; i++) + { + if ((mask & 0x1U) != 0U) + { + if (s_eventCallback[i] != NULL) + { + s_eventCallback[i](); + } + } + mask >>= 1UL; + + if (0U == mask) + { + /* All events have been handled. */ + break; + } + } + + /* Clear event interrupt flag */ + SCT0->EVFLAG = clearFlag; +} + +void SCT0_DriverIRQHandler(void); +void SCT0_DriverIRQHandler(void) +{ + s_sctimerIsr(SCT0); + SDK_ISR_EXIT_BARRIER; +} diff --git a/drivers/fsl_sctimer.h b/drivers/fsl_sctimer.h new file mode 100644 index 0000000..9c483ea --- /dev/null +++ b/drivers/fsl_sctimer.h @@ -0,0 +1,1258 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_SCTIMER_H_ +#define _FSL_SCTIMER_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sctimer + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_SCTIMER_DRIVER_VERSION (MAKE_VERSION(2, 3, 0)) /*!< Version */ +/*@}*/ + +#ifndef SCT_EV_STATE_STATEMSKn +#define SCT_EV_STATE_STATEMSKn(x) (((uint32_t)(x) & (1UL << FSL_FEATURE_SCT_NUMBER_OF_STATES) - 1UL)) +#endif + +/*! @brief SCTimer PWM operation modes */ +typedef enum _sctimer_pwm_mode +{ + kSCTIMER_EdgeAlignedPwm = 0U, /*!< Edge-aligned PWM */ + kSCTIMER_CenterAlignedPwm /*!< Center-aligned PWM */ +} sctimer_pwm_mode_t; + +/*! @brief SCTimer counters type. */ +typedef enum _sctimer_counter +{ + kSCTIMER_Counter_L = (1U << 0), /*!< 16-bit Low counter. */ + kSCTIMER_Counter_H = (1U << 1), /*!< 16-bit High counter. */ + kSCTIMER_Counter_U = (1U << 2), /*!< 32-bit Unified counter. */ +} sctimer_counter_t; + +/*! @brief List of SCTimer input pins */ +typedef enum _sctimer_input +{ + kSCTIMER_Input_0 = 0U, /*!< SCTIMER input 0 */ + kSCTIMER_Input_1, /*!< SCTIMER input 1 */ + kSCTIMER_Input_2, /*!< SCTIMER input 2 */ + kSCTIMER_Input_3, /*!< SCTIMER input 3 */ + kSCTIMER_Input_4, /*!< SCTIMER input 4 */ + kSCTIMER_Input_5, /*!< SCTIMER input 5 */ + kSCTIMER_Input_6, /*!< SCTIMER input 6 */ + kSCTIMER_Input_7 /*!< SCTIMER input 7 */ +} sctimer_input_t; + +/*! @brief List of SCTimer output pins */ +typedef enum _sctimer_out +{ + kSCTIMER_Out_0 = 0U, /*!< SCTIMER output 0*/ + kSCTIMER_Out_1, /*!< SCTIMER output 1 */ + kSCTIMER_Out_2, /*!< SCTIMER output 2 */ + kSCTIMER_Out_3, /*!< SCTIMER output 3 */ + kSCTIMER_Out_4, /*!< SCTIMER output 4 */ + kSCTIMER_Out_5, /*!< SCTIMER output 5 */ + kSCTIMER_Out_6, /*!< SCTIMER output 6 */ + kSCTIMER_Out_7, /*!< SCTIMER output 7 */ + kSCTIMER_Out_8, /*!< SCTIMER output 8 */ + kSCTIMER_Out_9 /*!< SCTIMER output 9 */ +} sctimer_out_t; + +/*! @brief SCTimer PWM output pulse mode: high-true, low-true or no output */ +typedef enum _sctimer_pwm_level_select +{ + kSCTIMER_LowTrue = 0U, /*!< Low true pulses */ + kSCTIMER_HighTrue /*!< High true pulses */ +} sctimer_pwm_level_select_t; + +/*! @brief Options to configure a SCTimer PWM signal */ +typedef struct _sctimer_pwm_signal_param +{ + sctimer_out_t output; /*!< The output pin to use to generate the PWM signal */ + sctimer_pwm_level_select_t level; /*!< PWM output active level select. */ + uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 0 to 100 + 0 = always inactive signal (0% duty cycle) + 100 = always active signal (100% duty cycle).*/ +} sctimer_pwm_signal_param_t; + +/*! @brief SCTimer clock mode options */ +typedef enum _sctimer_clock_mode +{ + kSCTIMER_System_ClockMode = 0U, /*!< System Clock Mode */ + kSCTIMER_Sampled_ClockMode, /*!< Sampled System Clock Mode */ + kSCTIMER_Input_ClockMode, /*!< SCT Input Clock Mode */ + kSCTIMER_Asynchronous_ClockMode /*!< Asynchronous Mode */ +} sctimer_clock_mode_t; + +/*! @brief SCTimer clock select options */ +typedef enum _sctimer_clock_select +{ + kSCTIMER_Clock_On_Rise_Input_0 = 0U, /*!< Rising edges on input 0 */ + kSCTIMER_Clock_On_Fall_Input_0, /*!< Falling edges on input 0 */ + kSCTIMER_Clock_On_Rise_Input_1, /*!< Rising edges on input 1 */ + kSCTIMER_Clock_On_Fall_Input_1, /*!< Falling edges on input 1 */ + kSCTIMER_Clock_On_Rise_Input_2, /*!< Rising edges on input 2 */ + kSCTIMER_Clock_On_Fall_Input_2, /*!< Falling edges on input 2 */ + kSCTIMER_Clock_On_Rise_Input_3, /*!< Rising edges on input 3 */ + kSCTIMER_Clock_On_Fall_Input_3, /*!< Falling edges on input 3 */ + kSCTIMER_Clock_On_Rise_Input_4, /*!< Rising edges on input 4 */ + kSCTIMER_Clock_On_Fall_Input_4, /*!< Falling edges on input 4 */ + kSCTIMER_Clock_On_Rise_Input_5, /*!< Rising edges on input 5 */ + kSCTIMER_Clock_On_Fall_Input_5, /*!< Falling edges on input 5 */ + kSCTIMER_Clock_On_Rise_Input_6, /*!< Rising edges on input 6 */ + kSCTIMER_Clock_On_Fall_Input_6, /*!< Falling edges on input 6 */ + kSCTIMER_Clock_On_Rise_Input_7, /*!< Rising edges on input 7 */ + kSCTIMER_Clock_On_Fall_Input_7 /*!< Falling edges on input 7 */ +} sctimer_clock_select_t; + +/*! + * @brief SCTimer output conflict resolution options. + * + * Specifies what action should be taken if multiple events dictate that a given output should be + * both set and cleared at the same time + */ +typedef enum _sctimer_conflict_resolution +{ + kSCTIMER_ResolveNone = 0U, /*!< No change */ + kSCTIMER_ResolveSet, /*!< Set output */ + kSCTIMER_ResolveClear, /*!< Clear output */ + kSCTIMER_ResolveToggle /*!< Toggle output */ +} sctimer_conflict_resolution_t; + +/*! @brief List of SCTimer event generation active direction when the counters are operating in BIDIR mode. */ +typedef enum _sctimer_event_active_direction +{ + kSCTIMER_ActiveIndependent = 0U, /*!< This event is triggered regardless of the count direction. */ + kSCTIMER_ActiveInCountUp, /*!< This event is triggered only during up-counting when BIDIR = 1. */ + kSCTIMER_ActiveInCountDown /*!< This event is triggered only during down-counting when BIDIR = 1. */ +} sctimer_event_active_direction_t; + +/*! @brief List of SCTimer event types */ +typedef enum _sctimer_event +{ + kSCTIMER_InputLowOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputRiseOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (1 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputFallOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (2 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputHighOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (3 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + + kSCTIMER_MatchEventOnly = + (1 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + + kSCTIMER_InputLowEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputRiseEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (1 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputFallEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (2 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputHighEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (3 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + + kSCTIMER_InputLowAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputRiseAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (1 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputFallAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (2 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputHighAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (3 << SCT_EV_CTRL_IOCOND_SHIFT) + (0 << SCT_EV_CTRL_OUTSEL_SHIFT), + + kSCTIMER_OutputLowOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputRiseOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (1 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputFallOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (2 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputHighOrMatchEvent = + (0 << SCT_EV_CTRL_COMBMODE_SHIFT) + (3 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + + kSCTIMER_OutputLowEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputRiseEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (1 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputFallEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (2 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputHighEvent = + (2 << SCT_EV_CTRL_COMBMODE_SHIFT) + (3 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + + kSCTIMER_OutputLowAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (0 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputRiseAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (1 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputFallAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (2 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputHighAndMatchEvent = + (3 << SCT_EV_CTRL_COMBMODE_SHIFT) + (3 << SCT_EV_CTRL_IOCOND_SHIFT) + (1 << SCT_EV_CTRL_OUTSEL_SHIFT) +} sctimer_event_t; + +/*! @brief SCTimer callback typedef. */ +typedef void (*sctimer_event_callback_t)(void); + +/*! @brief List of SCTimer interrupts */ +typedef enum _sctimer_interrupt_enable +{ + kSCTIMER_Event0InterruptEnable = (1U << 0), /*!< Event 0 interrupt */ + kSCTIMER_Event1InterruptEnable = (1U << 1), /*!< Event 1 interrupt */ + kSCTIMER_Event2InterruptEnable = (1U << 2), /*!< Event 2 interrupt */ + kSCTIMER_Event3InterruptEnable = (1U << 3), /*!< Event 3 interrupt */ + kSCTIMER_Event4InterruptEnable = (1U << 4), /*!< Event 4 interrupt */ + kSCTIMER_Event5InterruptEnable = (1U << 5), /*!< Event 5 interrupt */ + kSCTIMER_Event6InterruptEnable = (1U << 6), /*!< Event 6 interrupt */ + kSCTIMER_Event7InterruptEnable = (1U << 7), /*!< Event 7 interrupt */ + kSCTIMER_Event8InterruptEnable = (1U << 8), /*!< Event 8 interrupt */ + kSCTIMER_Event9InterruptEnable = (1U << 9), /*!< Event 9 interrupt */ + kSCTIMER_Event10InterruptEnable = (1U << 10), /*!< Event 10 interrupt */ + kSCTIMER_Event11InterruptEnable = (1U << 11), /*!< Event 11 interrupt */ + kSCTIMER_Event12InterruptEnable = (1U << 12), /*!< Event 12 interrupt */ +} sctimer_interrupt_enable_t; + +/*! @brief List of SCTimer flags */ +typedef enum _sctimer_status_flags +{ + kSCTIMER_Event0Flag = (1U << 0), /*!< Event 0 Flag */ + kSCTIMER_Event1Flag = (1U << 1), /*!< Event 1 Flag */ + kSCTIMER_Event2Flag = (1U << 2), /*!< Event 2 Flag */ + kSCTIMER_Event3Flag = (1U << 3), /*!< Event 3 Flag */ + kSCTIMER_Event4Flag = (1U << 4), /*!< Event 4 Flag */ + kSCTIMER_Event5Flag = (1U << 5), /*!< Event 5 Flag */ + kSCTIMER_Event6Flag = (1U << 6), /*!< Event 6 Flag */ + kSCTIMER_Event7Flag = (1U << 7), /*!< Event 7 Flag */ + kSCTIMER_Event8Flag = (1U << 8), /*!< Event 8 Flag */ + kSCTIMER_Event9Flag = (1U << 9), /*!< Event 9 Flag */ + kSCTIMER_Event10Flag = (1U << 10), /*!< Event 10 Flag */ + kSCTIMER_Event11Flag = (1U << 11), /*!< Event 11 Flag */ + kSCTIMER_Event12Flag = (1U << 12), /*!< Event 12 Flag */ + kSCTIMER_BusErrorLFlag = + (1U << SCT_CONFLAG_BUSERRL_SHIFT), /*!< Bus error due to write when L counter was not halted */ + kSCTIMER_BusErrorHFlag = + (int)(1U << SCT_CONFLAG_BUSERRH_SHIFT) /*!< Bus error due to write when H counter was not halted */ +} sctimer_status_flags_t; + +/*! + * @brief SCTimer configuration structure + * + * This structure holds the configuration settings for the SCTimer peripheral. To initialize this + * structure to reasonable defaults, call the SCTMR_GetDefaultConfig() function and pass a + * pointer to the configuration structure instance. + * + * The configuration structure can be made constant so as to reside in flash. + */ +typedef struct _sctimer_config +{ + bool enableCounterUnify; /*!< true: SCT operates as a unified 32-bit counter; + false: SCT operates as two 16-bit counters. + User can use the 16-bit low counter and the 16-bit high counters at the + same time; for Hardware limit, user can not use unified 32-bit counter + and any 16-bit low/high counter at the same time. */ + sctimer_clock_mode_t clockMode; /*!< SCT clock mode value */ + sctimer_clock_select_t clockSelect; /*!< SCT clock select value */ + bool enableBidirection_l; /*!< true: Up-down count mode for the L or unified counter + false: Up count mode only for the L or unified counter */ + bool enableBidirection_h; /*!< true: Up-down count mode for the H or unified counter + false: Up count mode only for the H or unified counter. + This field is used only if the enableCounterUnify is set + to false */ + uint8_t prescale_l; /*!< Prescale value to produce the L or unified counter clock */ + uint8_t prescale_h; /*!< Prescale value to produce the H counter clock. + This field is used only if the enableCounterUnify is set + to false */ + uint8_t outInitState; /*!< Defines the initial output value */ + uint8_t inputsync; /*!< SCT INSYNC value, INSYNC field in the CONFIG register, from bit9 to bit 16. + it is used to define synchronization for input N: + bit 9 = input 0 + bit 10 = input 1 + bit 11 = input 2 + bit 12 = input 3 + All other bits are reserved (bit13 ~bit 16). + How User to set the the value for the member inputsync. + IE: delay for input0, and input 1, bypasses for input 2 and input 3 + MACRO definition in user level. + \#define INPUTSYNC0 (0U) + \#define INPUTSYNC1 (1U) + \#define INPUTSYNC2 (2U) + \#define INPUTSYNC3 (3U) + User Code. + sctimerInfo.inputsync = (1 << INPUTSYNC2) | (1 << INPUTSYNC3); */ +} sctimer_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the SCTimer clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the SCTimer driver. + * + * @param base SCTimer peripheral base address + * @param config Pointer to the user configuration structure. + * + * @return kStatus_Success indicates success; Else indicates failure. + */ +status_t SCTIMER_Init(SCT_Type *base, const sctimer_config_t *config); + +/*! + * @brief Gates the SCTimer clock. + * + * @param base SCTimer peripheral base address + */ +void SCTIMER_Deinit(SCT_Type *base); + +/*! + * @brief Fills in the SCTimer configuration structure with the default settings. + * + * The default values are: + * @code + * config->enableCounterUnify = true; + * config->clockMode = kSCTIMER_System_ClockMode; + * config->clockSelect = kSCTIMER_Clock_On_Rise_Input_0; + * config->enableBidirection_l = false; + * config->enableBidirection_h = false; + * config->prescale_l = 0U; + * config->prescale_h = 0U; + * config->outInitState = 0U; + * config->inputsync = 0xFU; + * @endcode + * @param config Pointer to the user configuration structure. + */ +void SCTIMER_GetDefaultConfig(sctimer_config_t *config); + +/*! @}*/ + +/*! + * @name PWM setup operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters. + * + * Call this function to configure the PWM signal period, mode, duty cycle, and edge. This + * function will create 2 events; one of the events will trigger on match with the pulse value + * and the other will trigger when the counter matches the PWM period. The PWM period event is + * also used as a limit event to reset the counter or change direction. Both events are enabled + * for the same state. The state number can be retrieved by calling the function + * SCTIMER_GetCurrentStateNumber(). + * The counter is set to operate as one 32-bit counter (unify bit is set to 1). + * The counter operates in bi-directional mode when generating a center-aligned PWM. + * + * @note When setting PWM output from multiple output pins, they all should use the same PWM mode + * i.e all PWM's should be either edge-aligned or center-aligned. + * When using this API, the PWM signal frequency of all the initialized channels must be the same. + * Otherwise all the initialized channels' PWM signal frequency is equal to the last call to the + * API's pwmFreq_Hz. + * + * @param base SCTimer peripheral base address + * @param pwmParams PWM parameters to configure the output + * @param mode PWM operation mode, options available in enumeration ::sctimer_pwm_mode_t + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz SCTimer counter clock in Hz + * @param event Pointer to a variable where the PWM period event number is stored + * + * @return kStatus_Success on success + * kStatus_Fail If we have hit the limit in terms of number of events created or if + * an incorrect PWM dutycylce is passed in. + */ +status_t SCTIMER_SetupPwm(SCT_Type *base, + const sctimer_pwm_signal_param_t *pwmParams, + sctimer_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + uint32_t *event); + +/*! + * @brief Updates the duty cycle of an active PWM signal. + * + * Before calling this function, the counter is set to operate as one 32-bit counter (unify bit is set to 1). + * + * @param base SCTimer peripheral base address + * @param output The output to configure + * @param dutyCyclePercent New PWM pulse width; the value should be between 1 to 100 + * @param event Event number associated with this PWM signal. This was returned to the user by the + * function SCTIMER_SetupPwm(). + */ +void SCTIMER_UpdatePwmDutycycle(SCT_Type *base, sctimer_out_t output, uint8_t dutyCyclePercent, uint32_t event); + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected SCTimer interrupts. + * + * @param base SCTimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::sctimer_interrupt_enable_t + */ +static inline void SCTIMER_EnableInterrupts(SCT_Type *base, uint32_t mask) +{ + base->EVEN |= mask; +} + +/*! + * @brief Disables the selected SCTimer interrupts. + * + * @param base SCTimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::sctimer_interrupt_enable_t + */ +static inline void SCTIMER_DisableInterrupts(SCT_Type *base, uint32_t mask) +{ + base->EVEN &= ~mask; +} + +/*! + * @brief Gets the enabled SCTimer interrupts. + * + * @param base SCTimer peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::sctimer_interrupt_enable_t + */ +static inline uint32_t SCTIMER_GetEnabledInterrupts(SCT_Type *base) +{ + return (base->EVEN & 0xFFFFU); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the SCTimer status flags. + * + * @param base SCTimer peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::sctimer_status_flags_t + */ +static inline uint32_t SCTIMER_GetStatusFlags(SCT_Type *base) +{ + uint32_t statusFlags = 0; + + /* Add the recorded events */ + statusFlags = (base->EVFLAG & 0xFFFFU); + + /* Add bus error flags */ + statusFlags |= (base->CONFLAG & (SCT_CONFLAG_BUSERRL_MASK | SCT_CONFLAG_BUSERRH_MASK)); + + return statusFlags; +} + +/*! + * @brief Clears the SCTimer status flags. + * + * @param base SCTimer peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::sctimer_status_flags_t + */ +static inline void SCTIMER_ClearStatusFlags(SCT_Type *base, uint32_t mask) +{ + /* Write to the flag registers */ + base->EVFLAG = (mask & 0xFFFFU); + base->CONFLAG = (mask & (SCT_CONFLAG_BUSERRL_MASK | SCT_CONFLAG_BUSERRH_MASK)); +} + +/*! @}*/ + +/*! + * @name Counter Start and Stop + * @{ + */ + +/*! + * @brief Starts the SCTimer counter. + * + * @note In 16-bit mode, we can enable both Counter_L and Counter_H, In 32-bit mode, we only can select Counter_U. + * + * @param base SCTimer peripheral base address + * @param countertoStart The SCTimer counters to enable. This is a logical OR of members of the + * enumeration ::sctimer_counter_t. + */ +static inline void SCTIMER_StartTimer(SCT_Type *base, uint32_t countertoStart) +{ + switch (countertoStart) + { + case (uint32_t)kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Clear HALT_L bit when user wants to start the Low counter */ + base->CTRL_ACCESS16BIT.CTRLL &= ~((uint16_t)SCT_CTRLL_HALT_L_MASK); + break; + + case (uint32_t)kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Clear HALT_H bit when user wants to start the High counter */ + base->CTRL_ACCESS16BIT.CTRLH &= ~((uint16_t)SCT_CTRLH_HALT_H_MASK); + break; + + case (uint32_t)kSCTIMER_Counter_L | (uint32_t)kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Clear HALT_L/HALT_H bit when user wants to H counter and L counter at same time */ + base->CTRL &= ~(SCT_CTRL_HALT_L_MASK | SCT_CTRL_HALT_H_MASK); + break; + + case (uint32_t)kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Clear HALT_L bit when the counter is operating in 32-bit mode (unify counter). */ + base->CTRL &= ~(SCT_CTRL_HALT_L_MASK); + break; + + default: + /* Counter_L/Counter_H can't work together with Counter_U. */ + assert(false); + break; + } +} + +/*! + * @brief Halts the SCTimer counter. + * + * @param base SCTimer peripheral base address + * @param countertoStop The SCTimer counters to stop. This is a logical OR of members of the + * enumeration ::sctimer_counter_t. + */ +static inline void SCTIMER_StopTimer(SCT_Type *base, uint32_t countertoStop) +{ + switch (countertoStop) + { + case (uint32_t)kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Set HALT_L bit when user wants to start the Low counter */ + base->CTRL_ACCESS16BIT.CTRLL |= (SCT_CTRLL_HALT_L_MASK); + break; + + case (uint32_t)kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Set HALT_H bit when user wants to start the High counter */ + base->CTRL_ACCESS16BIT.CTRLH |= (SCT_CTRLH_HALT_H_MASK); + break; + + case (uint32_t)kSCTIMER_Counter_L | (uint32_t)kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Clear HALT_L/HALT_H bit when user wants to H counter and L counter at same time */ + base->CTRL |= (SCT_CTRL_HALT_L_MASK | SCT_CTRL_HALT_H_MASK); + break; + + case (uint32_t)kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Set HALT_L bit when the counter is operating in 32-bit mode (unify counter). */ + base->CTRL |= (SCT_CTRL_HALT_L_MASK); + break; + + default: + /* Counter_L/Counter_H can't work together with Counter_U. */ + assert(false); + break; + } +} + +/*! @}*/ + +/*! + * @name Functions to create a new event and manage the state logic + * @{ + */ + +/*! + * @brief Create an event that is triggered on a match or IO and schedule in current state. + * + * This function will configure an event using the options provided by the user. If the event type uses + * the counter match, then the function will set the user provided match value into a match register + * and put this match register number into the event control register. + * The event is enabled for the current state and the event number is increased by one at the end. + * The function returns the event number; this event number can be used to configure actions to be + * done when this event is triggered. + * + * @param base SCTimer peripheral base address + * @param howToMonitor Event type; options are available in the enumeration ::sctimer_interrupt_enable_t + * @param matchValue The match value that will be programmed to a match register + * @param whichIO The input or output that will be involved in event triggering. This field + * is ignored if the event type is "match only" + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param event Pointer to a variable where the new event number is stored + * + * @return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of number of events created or + if we have reached the limit in terms of number of match registers + */ +status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base, + sctimer_event_t howToMonitor, + uint32_t matchValue, + uint32_t whichIO, + sctimer_counter_t whichCounter, + uint32_t *event); + +/*! + * @brief Enable an event in the current state. + * + * This function will allow the event passed in to trigger in the current state. The event must + * be created earlier by either calling the function SCTIMER_SetupPwm() or function + * SCTIMER_CreateAndScheduleEvent() . + * + * @param base SCTimer peripheral base address + * @param event Event number to enable in the current state + * + */ +void SCTIMER_ScheduleEvent(SCT_Type *base, uint32_t event); + +/*! + * @brief Increase the state by 1 + * + * All future events created by calling the function SCTIMER_ScheduleEvent() will be enabled in this new + * state. + * + * @param base SCTimer peripheral base address + * + * @return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of states used + + */ +status_t SCTIMER_IncreaseState(SCT_Type *base); + +/*! + * @brief Provides the current state + * + * User can use this to set the next state by calling the function SCTIMER_SetupNextStateAction(). + * + * @param base SCTimer peripheral base address + * + * @return The current state + */ +uint32_t SCTIMER_GetCurrentState(SCT_Type *base); + +/*! + * @brief Set the counter current state. + * + * The function is to set the state variable bit field of STATE register. Writing to the STATE_L, STATE_H, or unified + * register is only allowed when the corresponding counter is halted (HALT bits are set to 1 in the CTRL register). + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param state The counter current state number (only support range from 0~31). + */ +static inline void SCTIMER_SetCounterState(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t state) +{ + /* SCT only support 0 ~ FSL_FEATURE_SCT_NUMBER_OF_STATES state value. */ + assert(state < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_STATES); + + SCTIMER_StopTimer(base, (uint32_t)whichCounter); + + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use STATE_L bits when user wants to setup the Low counter */ + base->STATE_ACCESS16BIT.STATEL = SCT_STATEL_STATEL(state); + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use STATE_H bits when user wants to start the High counter */ + base->STATE_ACCESS16BIT.STATEH = SCT_STATEH_STATEH(state); + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use STATE_L bits when counter is operating in 32-bit mode (unify counter). */ + base->STATE = SCT_STATE_STATE_L(state); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } + + SCTIMER_StartTimer(base, (uint32_t)whichCounter); +} + +/*! + * @brief Get the counter current state value. + * + * The function is to get the state variable bit field of STATE register. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @return The the counter current state value. + */ +static inline uint16_t SCTIMER_GetCounterState(SCT_Type *base, sctimer_counter_t whichCounter) +{ + uint16_t regs; + + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use STATE_L bits when user wants to setup the Low counter */ + regs = base->STATE_ACCESS16BIT.STATEL & SCT_STATEL_STATEL_MASK; + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use STATE_H bits when user wants to start the High counter */ + regs = base->STATE_ACCESS16BIT.STATEH & SCT_STATEH_STATEH_MASK; + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use STATE_L bits when counter is operating in 32-bit mode (unify counter). */ + regs = (uint16_t)(base->STATE & SCT_STATE_STATE_L_MASK); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } + + return regs; +} + +/*! @}*/ + +/*! + * @name Actions to take in response to an event + * @{ + */ + +/*! + * @brief Setup capture of the counter value on trigger of a selected event + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param captureRegister Pointer to a variable where the capture register number will be returned. User + * can read the captured value from this register when the specified event is triggered. + * @param event Event number that will trigger the capture + * + * @return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of number of match/capture registers available + */ +status_t SCTIMER_SetupCaptureAction(SCT_Type *base, + sctimer_counter_t whichCounter, + uint32_t *captureRegister, + uint32_t event); + +/*! + * @brief Receive noticification when the event trigger an interrupt. + * + * If the interrupt for the event is enabled by the user, then a callback can be registered + * which will be invoked when the event is triggered + * + * @param base SCTimer peripheral base address + * @param event Event number that will trigger the interrupt + * @param callback Function to invoke when the event is triggered + */ + +void SCTIMER_SetCallback(SCT_Type *base, sctimer_event_callback_t callback, uint32_t event); + +/*! + * @brief Change the load method of transition to the specified state. + * + * Change the load method of transition, it will be triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param event Event number that will change the method to trigger the state transition + * @param fgLoad The method to load highest-numbered event occurring for that state to the STATE register. + * - true: Load the STATEV value to STATE when the event occurs to be the next state. + * - false: Add the STATEV value to STATE when the event occurs to be the next state. + */ +static inline void SCTIMER_SetupStateLdMethodAction(SCT_Type *base, uint32_t event, bool fgLoad) +{ + uint32_t reg = base->EV[event].CTRL; + + if (fgLoad) + { + /* Load the STATEV value to STATE when the event occurs to be the next state */ + reg |= SCT_EV_CTRL_STATELD_MASK; + } + else + { + /* Add the STATEV value to STATE when the event occurs to be the next state */ + reg &= ~SCT_EV_CTRL_STATELD_MASK; + } + + base->EV[event].CTRL = reg; +} + +/*! + * @brief Transition to the specified state with Load method. + * + * This transition will be triggered by the event number that is passed in by the user, the method decide how to load + * the highest-numbered event occurring for that state to the STATE register. + * + * @param base SCTimer peripheral base address + * @param nextState The next state SCTimer will transition to + * @param event Event number that will trigger the state transition + * @param fgLoad The method to load the highest-numbered event occurring for that state to the STATE register. + * - true: Load the STATEV value to STATE when the event occurs to be the next state. + * - false: Add the STATEV value to STATE when the event occurs to be the next state. + */ +static inline void SCTIMER_SetupNextStateActionwithLdMethod(SCT_Type *base, + uint32_t nextState, + uint32_t event, + bool fgLoad) +{ + uint32_t reg = base->EV[event].CTRL; + + reg &= ~(SCT_EV_CTRL_STATEV_MASK | SCT_EV_CTRL_STATELD_MASK); + + reg |= SCT_EV_CTRL_STATEV(nextState); + + if (fgLoad) + { + /* Load the STATEV value when the event occurs to be the next state */ + reg |= SCT_EV_CTRL_STATELD_MASK; + } + + base->EV[event].CTRL = reg; +} + +/*! + * @brief Transition to the specified state. + * @deprecated Do not use this function. It has been superceded by @ref SCTIMER_SetupNextStateActionwithLdMethod + * + * This transition will be triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param nextState The next state SCTimer will transition to + * @param event Event number that will trigger the state transition + */ +static inline void SCTIMER_SetupNextStateAction(SCT_Type *base, uint32_t nextState, uint32_t event) +{ + uint32_t reg = base->EV[event].CTRL; + + reg &= ~(SCT_EV_CTRL_STATEV_MASK); + /* Load the STATEV value when the event occurs to be the next state */ + reg |= SCT_EV_CTRL_STATEV(nextState) | SCT_EV_CTRL_STATELD_MASK; + + base->EV[event].CTRL = reg; +} + +/*! + * @brief Setup event active direction when the counters are operating in BIDIR mode. + * + * @param base SCTimer peripheral base address + * @param activeDirection Event generation active direction, see @ref sctimer_event_active_direction_t. + * @param event Event number that need setup the active direction. + */ +static inline void SCTIMER_SetupEventActiveDirection(SCT_Type *base, + sctimer_event_active_direction_t activeDirection, + uint32_t event) +{ + uint32_t reg = base->EV[event].CTRL; + + reg &= ~(SCT_EV_CTRL_DIRECTION_MASK); + + reg |= SCT_EV_CTRL_DIRECTION(activeDirection); + + base->EV[event].CTRL = reg; +} + +/*! + * @brief Set the Output. + * + * This output will be set when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichIO The output to set + * @param event Event number that will trigger the output change + */ +static inline void SCTIMER_SetupOutputSetAction(SCT_Type *base, uint32_t whichIO, uint32_t event) +{ + assert(whichIO < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS); + + base->OUT[whichIO].SET |= (1UL << event); +} + +/*! + * @brief Clear the Output. + * + * This output will be cleared when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichIO The output to clear + * @param event Event number that will trigger the output change + */ +static inline void SCTIMER_SetupOutputClearAction(SCT_Type *base, uint32_t whichIO, uint32_t event) +{ + assert(whichIO < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS); + + base->OUT[whichIO].CLR |= (1UL << event); +} + +/*! + * @brief Toggle the output level. + * + * This change in the output level is triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param whichIO The output to toggle + * @param event Event number that will trigger the output change + */ +void SCTIMER_SetupOutputToggleAction(SCT_Type *base, uint32_t whichIO, uint32_t event); + +/*! + * @brief Limit the running counter. + * + * The counter is limited when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param event Event number that will trigger the counter to be limited + */ +static inline void SCTIMER_SetupCounterLimitAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when user wants to setup the Low counter */ + base->LIMIT_ACCESS16BIT.LIMITL |= SCT_LIMITL_LIMITL(1UL << event); + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_H bits when user wants to start the High counter */ + base->LIMIT_ACCESS16BIT.LIMITH |= SCT_LIMITH_LIMITH(1UL << event); + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when counter is operating in 32-bit mode (unify counter). */ + base->LIMIT |= SCT_LIMIT_LIMMSK_L(1UL << event); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } +} + +/*! + * @brief Stop the running counter. + * + * The counter is stopped when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param event Event number that will trigger the counter to be stopped + */ +static inline void SCTIMER_SetupCounterStopAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when user wants to setup the Low counter */ + base->STOP_ACCESS16BIT.STOPL |= SCT_STOPL_STOPL(1UL << event); + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_H bits when user wants to start the High counter */ + base->STOP_ACCESS16BIT.STOPH |= SCT_STOPH_STOPH(1UL << event); + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when counter is operating in 32-bit mode (unify counter). */ + base->STOP |= SCT_STOP_STOPMSK_L(1UL << event); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } +} + +/*! + * @brief Re-start the stopped counter. + * + * The counter will re-start when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param event Event number that will trigger the counter to re-start + */ +static inline void SCTIMER_SetupCounterStartAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when user wants to setup the Low counter */ + base->START_ACCESS16BIT.STARTL |= SCT_STARTL_STARTL(1UL << event); + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_H bits when user wants to start the High counter */ + base->START_ACCESS16BIT.STARTH |= SCT_STARTH_STARTH(1UL << event); + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when counter is operating in 32-bit mode (unify counter). */ + base->START |= SCT_START_STARTMSK_L(1UL << event); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } +} + +/*! + * @brief Halt the running counter. + * + * The counter is disabled (halted) when the event number that is passed in by the user is + * triggered. When the counter is halted, all further events are disabled. The HALT condition + * can only be removed by calling the SCTIMER_StartTimer() function. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param event Event number that will trigger the counter to be halted + */ +static inline void SCTIMER_SetupCounterHaltAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when user wants to setup the Low counter */ + base->HALT_ACCESS16BIT.HALTL |= SCT_HALTL_HALTL(1UL << event); + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_H bits when user wants to start the High counter */ + base->HALT_ACCESS16BIT.HALTH |= SCT_HALTH_HALTH(1UL << event); + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when counter is operating in 32-bit mode (unify counter). */ + base->HALT |= SCT_HALT_HALTMSK_L(1UL << event); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } +} + +#if !(defined(FSL_FEATURE_SCT_HAS_NO_DMA_REQUEST) && FSL_FEATURE_SCT_HAS_NO_DMA_REQUEST) +/*! + * @brief Generate a DMA request. + * + * DMA request will be triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param dmaNumber The DMA request to generate + * @param event Event number that will trigger the DMA request + */ +static inline void SCTIMER_SetupDmaTriggerAction(SCT_Type *base, uint32_t dmaNumber, uint32_t event) +{ + if (dmaNumber == 0U) + { + base->DMAREQ0 |= (1UL << event); + } + else + { + base->DMAREQ1 |= (1UL << event); + } +} +#endif /* FSL_FEATURE_SCT_HAS_NO_DMA_REQUEST */ + +/*! + * @brief Set the value of counter. + * + * The function is to set the value of Count register, Writing to the COUNT_L, COUNT_H, or unified register + * is only allowed when the corresponding counter is halted (HALT bits are set to 1 in the CTRL register). + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @param value the counter value update to the COUNT register. + */ +static inline void SCTIMER_SetCOUNTValue(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t value) +{ + SCTIMER_StopTimer(base, (uint32_t)whichCounter); + + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(value <= 0xFFFFU); + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when user wants to setup the Low counter */ + base->COUNT_ACCESS16BIT.COUNTL = (uint16_t)value; + break; + + case kSCTIMER_Counter_H: + assert(value <= 0xFFFFU); + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_H bits when user wants to start the High counter */ + base->COUNT_ACCESS16BIT.COUNTH = (uint16_t)value; + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when counter is operating in 32-bit mode (unify counter). */ + base->COUNT &= ~SCT_COUNT_CTR_L_MASK; + base->COUNT |= SCT_COUNT_CTR_L(value); + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } + + SCTIMER_StartTimer(base, (uint32_t)whichCounter); +} + +/*! + * @brief Get the value of counter. + * + * The function is to read the value of Count register, software can read the counter registers at any time.. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use. In 16-bit mode, we can select Counter_L and Counter_H, + * In 32-bit mode, we can select Counter_U. + * @return The value of counter selected. + */ +static inline uint32_t SCTIMER_GetCOUNTValue(SCT_Type *base, sctimer_counter_t whichCounter) +{ + uint32_t value; + + switch (whichCounter) + { + case kSCTIMER_Counter_L: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when user wants to setup the Low counter */ + value = base->COUNT_ACCESS16BIT.COUNTL; + break; + + case kSCTIMER_Counter_H: + assert(0U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_H bits when user wants to start the High counter */ + value = base->COUNT_ACCESS16BIT.COUNTH; + break; + + case kSCTIMER_Counter_U: + assert(1U == (base->CONFIG & SCT_CONFIG_UNIFY_MASK)); + /* Use Counter_L bits when counter is operating in 32-bit mode (unify counter). */ + value = base->COUNT; + break; + + default: + /* Fix the MISRA C-2012 issue rule 16.4. */ + break; + } + + return value; +} + +/*! + * @brief Set the state mask bit field of EV_STATE register. + * + * @param base SCTimer peripheral base address + * @param event The EV_STATE register be set. + * @param state The state value in which the event is enabled to occur. + */ +static inline void SCTIMER_SetEventInState(SCT_Type *base, uint32_t event, uint32_t state) +{ + assert(state < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_STATES); + assert(event < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS); + + base->EV[event].STATE |= SCT_EV_STATE_STATEMSKn((uint32_t)1U << state); +} + +/*! + * @brief Clear the state mask bit field of EV_STATE register. + * + * @param base SCTimer peripheral base address + * @param event The EV_STATE register be clear. + * @param state The state value in which the event is disabled to occur. + */ +static inline void SCTIMER_ClearEventInState(SCT_Type *base, uint32_t event, uint32_t state) +{ + assert(state < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_STATES); + assert(event < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS); + + base->EV[event].STATE &= ~SCT_EV_STATE_STATEMSKn((uint32_t)1U << state); +} + +/*! + * @brief Get the state mask bit field of EV_STATE register. + * + * @note This function is to check whether the event is enabled in a specific state. + * + * @param base SCTimer peripheral base address + * @param event The EV_STATE register be read. + * @param state The state value. + * + * @return The the state mask bit field of EV_STATE register. + * - true: The event is enable in state. + * - false: The event is disable in state. + */ +static inline bool SCTIMER_GetEventInState(SCT_Type *base, uint32_t event, uint32_t state) +{ + assert(state < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_STATES); + assert(event < (uint32_t)FSL_FEATURE_SCT_NUMBER_OF_EVENTS); + + return (0U != (base->EV[event].STATE & SCT_EV_STATE_STATEMSKn((uint32_t)1U << state))); +} + +/*! + * @brief SCTimer interrupt handler. + * + * @param base SCTimer peripheral base address. + */ +void SCTIMER_EventHandleIRQ(SCT_Type *base); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SCTIMER_H_ */ diff --git a/drivers/fsl_spi.c b/drivers/fsl_spi.c new file mode 100644 index 0000000..ea6a9b2 --- /dev/null +++ b/drivers/fsl_spi.c @@ -0,0 +1,1072 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_spi.h" +#include "fsl_flexcomm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.flexcomm_spi" +#endif + +/* Note: FIFOCFG[SIZE] has always value 1 = 8 items depth */ + +#if defined(FSL_FEATURE_SPI_FIFOSIZE_CFG) && (FSL_FEATURE_SPI_FIFOSIZE_CFG) +#define SPI_FIFO_DEPTH(base) 4 +#else +#define SPI_FIFO_DEPTH(base) ((((base)->FIFOCFG & SPI_FIFOCFG_SIZE_MASK) >> SPI_FIFOCFG_SIZE_SHIFT) << 3) +#endif /*FSL_FEATURE_SPI_FIFOSIZE_CFG*/ + +/* Convert transfer count to transfer bytes. dataWidth is a + * range <0,15>. Range <8,15> represents 2B transfer */ +#define SPI_COUNT_TO_BYTES(dataWidth, count) ((count) << ((dataWidth) >> 3U)) +#define SPI_BYTES_TO_COUNT(dataWidth, bytes) ((bytes) >> ((dataWidth) >> 3U)) +#if defined(FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE) && (FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE) +#define SPI_SSELPOL_MASK ((SPI_CFG_SPOL0_MASK) | (SPI_CFG_SPOL1_MASK) | (SPI_CFG_SPOL2_MASK)) +#else +#define SPI_SSELPOL_MASK ((SPI_CFG_SPOL0_MASK) | (SPI_CFG_SPOL1_MASK) | (SPI_CFG_SPOL2_MASK) | (SPI_CFG_SPOL3_MASK)) +#endif /*FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE*/ + +/*! + * @brief Used for conversion from `flexcomm_irq_handler_t` to `flexcomm_spi_master_irq_handler_t` and + * `flexcomm_spi_slave_irq_handler_t`. + */ +typedef union spi_to_flexcomm +{ + flexcomm_spi_master_irq_handler_t spi_master_handler; + flexcomm_spi_slave_irq_handler_t spi_slave_handler; + flexcomm_irq_handler_t flexcomm_handler; +} spi_to_flexcomm_t; + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief internal SPI config array */ +static spi_config_t g_configs[FSL_FEATURE_SOC_SPI_COUNT] = {(spi_data_width_t)0}; + +/*! @brief Array to map SPI instance number to base address. */ +static const uint32_t s_spiBaseAddrs[FSL_FEATURE_SOC_SPI_COUNT] = SPI_BASE_ADDRS; + +/*! @brief IRQ name array */ +static const IRQn_Type s_spiIRQ[] = SPI_IRQS; + +/* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/ +volatile uint8_t s_dummyData[FSL_FEATURE_SOC_SPI_COUNT] = {0}; +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Get the index corresponding to the FLEXCOMM */ +/*! brief Returns instance number for SPI peripheral base address. */ +uint32_t SPI_GetInstance(SPI_Type *base) +{ + uint32_t i; + + for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_SPI_COUNT; i++) + { + if ((uint32_t)base == s_spiBaseAddrs[i]) + { + break; + } + } + + assert(i < (uint32_t)FSL_FEATURE_SOC_SPI_COUNT); + return i; +} + +/*! + * brief Set up the dummy data. + * + * param base SPI peripheral address. + * param dummyData Data to be transferred when tx buffer is NULL. + */ +void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData) +{ + uint32_t instance = SPI_GetInstance(base); + s_dummyData[instance] = dummyData; +} + +/*! + * brief Returns the configurations. + * + * param base SPI peripheral address. + * return return configurations which contain datawidth and SSEL numbers. + * return data type is a pointer of spi_config_t. + */ +void *SPI_GetConfig(SPI_Type *base) +{ + uint32_t instance; + instance = SPI_GetInstance(base); + return &g_configs[instance]; +} + +/*! + * brief Sets the SPI master configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit(). + * User may use the initialized structure unchanged in SPI_MasterInit(), or modify + * some fields of the structure before calling SPI_MasterInit(). After calling this API, + * the master is ready to transfer. + * Example: + code + spi_master_config_t config; + SPI_MasterGetDefaultConfig(&config); + endcode + * + * param config pointer to master config structure + */ +void SPI_MasterGetDefaultConfig(spi_master_config_t *config) +{ + assert(NULL != config); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + config->enableLoopback = false; + config->enableMaster = true; + config->polarity = kSPI_ClockPolarityActiveHigh; + config->phase = kSPI_ClockPhaseFirstEdge; + config->direction = kSPI_MsbFirst; + config->baudRate_Bps = 500000U; + config->dataWidth = kSPI_Data8Bits; + config->sselNum = kSPI_Ssel0; + config->txWatermark = (uint8_t)kSPI_TxFifo0; + config->rxWatermark = (uint8_t)kSPI_RxFifo1; + config->sselPol = kSPI_SpolActiveAllLow; + config->delayConfig.preDelay = 0U; + config->delayConfig.postDelay = 0U; + config->delayConfig.frameDelay = 0U; + config->delayConfig.transferDelay = 0U; +} + +/*! + * brief Initializes the SPI with master configuration. + * + * The configuration structure can be filled by user from scratch, or be set with default + * values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer. + * Example + code + spi_master_config_t config = { + .baudRate_Bps = 400000, + ... + }; + SPI_MasterInit(SPI0, &config); + endcode + * + * param base SPI base pointer + * param config pointer to master configuration structure + * param srcClock_Hz Source clock frequency. + */ +status_t SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz) +{ + status_t result = kStatus_Success; + uint32_t instance; + uint32_t tmpConfig; + + /* assert params */ + assert(!((NULL == base) || (NULL == config) || (0U == srcClock_Hz))); + if ((NULL == base) || (NULL == config) || (0U == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* initialize flexcomm to SPI mode */ + result = FLEXCOMM_Init(base, FLEXCOMM_PERIPH_SPI); + if (kStatus_Success != result) + { + return result; + } + + /* set divider */ + result = SPI_MasterSetBaud(base, config->baudRate_Bps, srcClock_Hz); + if (kStatus_Success != result) + { + return result; + } + + /* get instance number */ + instance = SPI_GetInstance(base); + + /* configure SPI mode */ + tmpConfig = base->CFG; + tmpConfig &= ~(SPI_CFG_MASTER_MASK | SPI_CFG_LSBF_MASK | SPI_CFG_CPHA_MASK | SPI_CFG_CPOL_MASK | SPI_CFG_LOOP_MASK | + SPI_CFG_ENABLE_MASK | SPI_SSELPOL_MASK); + /* phase */ + tmpConfig |= SPI_CFG_CPHA(config->phase); + /* polarity */ + tmpConfig |= SPI_CFG_CPOL(config->polarity); + /* direction */ + tmpConfig |= SPI_CFG_LSBF(config->direction); + /* master mode */ + tmpConfig |= SPI_CFG_MASTER(1); + /* loopback */ + tmpConfig |= SPI_CFG_LOOP(config->enableLoopback); + /* configure active level for all CS */ + tmpConfig |= ((uint32_t)config->sselPol & (SPI_SSELPOL_MASK)); + base->CFG = tmpConfig; + + /* store configuration */ + g_configs[instance].dataWidth = config->dataWidth; + g_configs[instance].sselNum = config->sselNum; + /* enable FIFOs */ + base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK; + base->FIFOCFG |= SPI_FIFOCFG_ENABLETX_MASK | SPI_FIFOCFG_ENABLERX_MASK; + /* trigger level - empty txFIFO, one item in rxFIFO */ + tmpConfig = base->FIFOTRIG & (~(SPI_FIFOTRIG_RXLVL_MASK | SPI_FIFOTRIG_TXLVL_MASK)); + tmpConfig |= SPI_FIFOTRIG_TXLVL(config->txWatermark) | SPI_FIFOTRIG_RXLVL(config->rxWatermark); + /* enable generating interrupts for FIFOTRIG levels */ + tmpConfig |= SPI_FIFOTRIG_TXLVLENA_MASK | SPI_FIFOTRIG_RXLVLENA_MASK; + /* set FIFOTRIG */ + base->FIFOTRIG = tmpConfig; + + /* Set the delay configuration. */ + SPI_SetTransferDelay(base, &config->delayConfig); + /* Set the dummy data. */ + SPI_SetDummyData(base, (uint8_t)SPI_DUMMYDATA); + + SPI_Enable(base, config->enableMaster); + return kStatus_Success; +} + +/*! + * brief Sets the SPI slave configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit(). + * Modify some fields of the structure before calling SPI_SlaveInit(). + * Example: + code + spi_slave_config_t config; + SPI_SlaveGetDefaultConfig(&config); + endcode + * + * param config pointer to slave configuration structure + */ +void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config) +{ + assert(NULL != config); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + config->enableSlave = true; + config->polarity = kSPI_ClockPolarityActiveHigh; + config->phase = kSPI_ClockPhaseFirstEdge; + config->direction = kSPI_MsbFirst; + config->dataWidth = kSPI_Data8Bits; + config->txWatermark = (uint8_t)kSPI_TxFifo0; + config->rxWatermark = (uint8_t)kSPI_RxFifo1; + config->sselPol = kSPI_SpolActiveAllLow; +} + +/*! + * brief Initializes the SPI with slave configuration. + * + * The configuration structure can be filled by user from scratch or be set with + * default values by SPI_SlaveGetDefaultConfig(). + * After calling this API, the slave is ready to transfer. + * Example + code + spi_slave_config_t config = { + .polarity = flexSPIClockPolarity_ActiveHigh; + .phase = flexSPIClockPhase_FirstEdge; + .direction = flexSPIMsbFirst; + ... + }; + SPI_SlaveInit(SPI0, &config); + endcode + * + * param base SPI base pointer + * param config pointer to slave configuration structure + */ +status_t SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config) +{ + status_t result = kStatus_Success; + uint32_t instance; + uint32_t tmpConfig; + + /* assert params */ + assert(!((NULL == base) || (NULL == config))); + if ((NULL == base) || (NULL == config)) + { + return kStatus_InvalidArgument; + } + /* configure flexcomm to SPI, enable clock gate */ + result = FLEXCOMM_Init(base, FLEXCOMM_PERIPH_SPI); + if (kStatus_Success != result) + { + return result; + } + + instance = SPI_GetInstance(base); + + /* configure SPI mode */ + tmpConfig = base->CFG; + tmpConfig &= ~(SPI_CFG_MASTER_MASK | SPI_CFG_LSBF_MASK | SPI_CFG_CPHA_MASK | SPI_CFG_CPOL_MASK | + SPI_CFG_ENABLE_MASK | SPI_SSELPOL_MASK); + /* phase */ + tmpConfig |= SPI_CFG_CPHA(config->phase); + /* polarity */ + tmpConfig |= SPI_CFG_CPOL(config->polarity); + /* direction */ + tmpConfig |= SPI_CFG_LSBF(config->direction); + /* configure active level for all CS */ + tmpConfig |= ((uint32_t)config->sselPol & (SPI_SSELPOL_MASK)); + base->CFG = tmpConfig; + + /* store configuration */ + g_configs[instance].dataWidth = config->dataWidth; + /* empty and enable FIFOs */ + base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK; + base->FIFOCFG |= SPI_FIFOCFG_ENABLETX_MASK | SPI_FIFOCFG_ENABLERX_MASK; + /* trigger level - empty txFIFO, one item in rxFIFO */ + tmpConfig = base->FIFOTRIG & (~(SPI_FIFOTRIG_RXLVL_MASK | SPI_FIFOTRIG_TXLVL_MASK)); + tmpConfig |= SPI_FIFOTRIG_TXLVL(config->txWatermark) | SPI_FIFOTRIG_RXLVL(config->rxWatermark); + /* enable generating interrupts for FIFOTRIG levels */ + tmpConfig |= SPI_FIFOTRIG_TXLVLENA_MASK | SPI_FIFOTRIG_RXLVLENA_MASK; + /* set FIFOTRIG */ + base->FIFOTRIG = tmpConfig; + + SPI_SetDummyData(base, (uint8_t)SPI_DUMMYDATA); + + SPI_Enable(base, config->enableSlave); + return kStatus_Success; +} + +/*! + * brief De-initializes the SPI. + * + * Calling this API resets the SPI module, gates the SPI clock. + * The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module. + * + * param base SPI base pointer + */ +void SPI_Deinit(SPI_Type *base) +{ + /* Assert arguments */ + assert(NULL != base); + /* Disable interrupts, disable dma requests, disable peripheral */ + base->FIFOINTENCLR = SPI_FIFOINTENCLR_TXERR_MASK | SPI_FIFOINTENCLR_RXERR_MASK | SPI_FIFOINTENCLR_TXLVL_MASK | + SPI_FIFOINTENCLR_RXLVL_MASK; + base->FIFOCFG &= ~(SPI_FIFOCFG_DMATX_MASK | SPI_FIFOCFG_DMARX_MASK); + base->CFG &= ~(SPI_CFG_ENABLE_MASK); +} + +/*! + * brief Enables the DMA request from SPI txFIFO. + * + * param base SPI base pointer + * param enable True means enable DMA, false means disable DMA + */ +void SPI_EnableTxDMA(SPI_Type *base, bool enable) +{ + if (enable) + { + base->FIFOCFG |= SPI_FIFOCFG_DMATX_MASK; + } + else + { + base->FIFOCFG &= ~SPI_FIFOCFG_DMATX_MASK; + } +} + +/*! + * brief Enables the DMA request from SPI rxFIFO. + * + * param base SPI base pointer + * param enable True means enable DMA, false means disable DMA + */ +void SPI_EnableRxDMA(SPI_Type *base, bool enable) +{ + if (enable) + { + base->FIFOCFG |= SPI_FIFOCFG_DMARX_MASK; + } + else + { + base->FIFOCFG &= ~SPI_FIFOCFG_DMARX_MASK; + } +} + +/*! + * brief Sets the baud rate for SPI transfer. This is only used in master. + * + * param base SPI base pointer + * param baudrate_Bps baud rate needed in Hz. + * param srcClock_Hz SPI source clock frequency in Hz. + */ +status_t SPI_MasterSetBaud(SPI_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz) +{ + uint32_t tmpDiv; + + /* assert params */ + assert(!((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz))); + if ((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* calculate baudrate, round up the result */ + tmpDiv = ((srcClock_Hz * 10U) / baudrate_Bps + 5U) / 10U - 1U; + if (tmpDiv > 0xFFFFU) + { + return kStatus_SPI_BaudrateNotSupport; + } + base->DIV &= ~SPI_DIV_DIVVAL_MASK; + base->DIV |= SPI_DIV_DIVVAL(tmpDiv); + return kStatus_Success; +} + +/*! + * brief Writes a data into the SPI data register. + * + * param base SPI base pointer + * param data needs to be write. + * param configFlags transfer configuration options ref spi_xfer_option_t + */ +void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags) +{ + uint32_t control = 0U; + uint32_t instance; + + /* check params */ + assert(NULL != base); + /* get and check instance */ + instance = SPI_GetInstance(base); + + /* set data width */ + control |= (uint32_t)SPI_FIFOWR_LEN((g_configs[instance].dataWidth)); + /* set sssel */ + control |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum)))); + /* mask configFlags */ + control |= (configFlags & (uint32_t)SPI_FIFOWR_FLAGS_MASK); + /* control should not affect lower 16 bits */ + assert(0U == (control & 0xFFFFU)); + base->FIFOWR = data | control; +} + +/*! + * brief Initializes the SPI master handle. + * + * This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * param base SPI peripheral base address. + * param handle SPI handle pointer. + * param callback Callback function. + * param userData User data. + */ +status_t SPI_MasterTransferCreateHandle(SPI_Type *base, + spi_master_handle_t *handle, + spi_master_callback_t callback, + void *userData) +{ + /* check 'base' */ + assert(NULL != base); + /* check 'handle' */ + assert(NULL != handle); + + uint32_t instance; + spi_to_flexcomm_t handler; + + /* get flexcomm instance by 'base' param */ + instance = SPI_GetInstance(base); + + (void)memset(handle, 0, sizeof(*handle)); + /* Initialize the handle */ + if ((base->CFG & SPI_CFG_MASTER_MASK) != 0U) + { + handler.spi_master_handler = SPI_MasterTransferHandleIRQ; + FLEXCOMM_SetIRQHandler(base, handler.flexcomm_handler, handle); + } + else + { + handler.spi_slave_handler = SPI_SlaveTransferHandleIRQ; + FLEXCOMM_SetIRQHandler(base, handler.flexcomm_handler, handle); + } + + handle->dataWidth = (uint8_t)(g_configs[instance].dataWidth); + /* in slave mode, the sselNum is not important */ + handle->sselNum = (uint8_t)(g_configs[instance].sselNum); + handle->txWatermark = (uint8_t)SPI_FIFOTRIG_TXLVL_GET(base); + handle->rxWatermark = (uint8_t)SPI_FIFOTRIG_RXLVL_GET(base); + handle->callback = callback; + handle->userData = userData; + + /* Enable SPI NVIC */ + (void)EnableIRQ(s_spiIRQ[instance]); + + return kStatus_Success; +} + +/*! + * brief Transfers a block of data using a polling method. + * + * param base SPI base pointer + * param xfer pointer to spi_xfer_config_t structure + * retval kStatus_Success Successfully start a transfer. + * retval kStatus_InvalidArgument Input argument is invalid. + * retval kStatus_SPI_Timeout The transfer timed out and was aborted. + */ +status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer) +{ + uint32_t instance; + uint32_t tx_ctrl = 0U, last_ctrl = 0U; + uint32_t tmp32, rxRemainingBytes, txRemainingBytes, dataWidth; + uint32_t toReceiveCount = 0; + uint8_t *txData, *rxData; + uint32_t fifoDepth; +#if SPI_RETRY_TIMES + uint32_t waitTimes = SPI_RETRY_TIMES; +#endif + + /* check params */ + assert(!((NULL == base) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData)))); + if ((NULL == base) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData))) + { + return kStatus_InvalidArgument; + } + + fifoDepth = SPI_FIFO_DEPTH(base); + txData = xfer->txData; + rxData = xfer->rxData; + txRemainingBytes = (txData != NULL) ? xfer->dataSize : 0U; + rxRemainingBytes = (rxData != NULL) ? xfer->dataSize : 0U; + + instance = SPI_GetInstance(base); + dataWidth = (uint32_t)(g_configs[instance].dataWidth); + + /* dataSize (in bytes) is not aligned to 16bit (2B) transfer */ + if ((dataWidth > (uint32_t)kSPI_Data8Bits) && ((xfer->dataSize & 0x1U) != 0U)) + { + return kStatus_InvalidArgument; + } + + /* clear tx/rx errors and empty FIFOs */ + base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK; + base->FIFOSTAT |= SPI_FIFOSTAT_TXERR_MASK | SPI_FIFOSTAT_RXERR_MASK; + /* select slave to talk with */ + tx_ctrl |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum)))); + /* set width of data - range asserted at entry */ + tx_ctrl |= SPI_FIFOWR_LEN(dataWidth); + /* delay for frames */ + tx_ctrl |= ((xfer->configFlags & (uint32_t)kSPI_FrameDelay) != 0U) ? (uint32_t)kSPI_FrameDelay : 0U; + /* end of transfer */ + last_ctrl |= ((xfer->configFlags & (uint32_t)kSPI_FrameAssert) != 0U) ? (uint32_t)kSPI_FrameAssert : 0U; + /* last index of loop */ + while ((txRemainingBytes != 0U) || (rxRemainingBytes != 0U) || (toReceiveCount != 0U)) + { +#if SPI_RETRY_TIMES + if (--waitTimes == 0U) + { + return kStatus_SPI_Timeout; + } +#endif + /* if rxFIFO is not empty */ + if ((base->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) != 0U) + { + tmp32 = base->FIFORD; + /* rxBuffer is not empty */ + if (rxRemainingBytes != 0U) + { + *(rxData++) = (uint8_t)tmp32; + rxRemainingBytes--; + /* read 16 bits at once */ + if (dataWidth > 8U) + { + *(rxData++) = (uint8_t)(tmp32 >> 8); + rxRemainingBytes--; + } + } + /* decrease number of data expected to receive */ + toReceiveCount -= 1U; + } + /* transmit if txFIFO is not full and data to receive does not exceed FIFO depth */ + if (((base->FIFOSTAT & SPI_FIFOSTAT_TXNOTFULL_MASK) != 0U) && (toReceiveCount < fifoDepth) && + ((txRemainingBytes != 0U) || (rxRemainingBytes >= SPI_COUNT_TO_BYTES(dataWidth, toReceiveCount + 1U)))) + { + /* txBuffer is not empty */ + if (txRemainingBytes != 0U) + { + tmp32 = *(txData++); + txRemainingBytes--; + /* write 16 bit at once */ + if (dataWidth > 8U) + { + tmp32 |= ((uint32_t)(*(txData++))) << 8U; + txRemainingBytes--; + } + if (txRemainingBytes == 0U) + { + tx_ctrl |= last_ctrl; + } + } + else + { + tmp32 = (uint32_t)s_dummyData[instance]; + tmp32 |= (uint32_t)s_dummyData[instance] << 8U; + /* last transfer */ + if (rxRemainingBytes == SPI_COUNT_TO_BYTES(dataWidth, toReceiveCount + 1U)) + { + tx_ctrl |= last_ctrl; + } + } + /* send data */ + tmp32 = tx_ctrl | tmp32; + base->FIFOWR = tmp32; + toReceiveCount += 1U; + } + } + /* wait if TX FIFO of previous transfer is not empty */ +#if SPI_RETRY_TIMES + waitTimes = SPI_RETRY_TIMES; + while ((0U == (base->FIFOSTAT & SPI_FIFOSTAT_TXEMPTY_MASK)) && (0U != --waitTimes)) +#else + while (0U == (base->FIFOSTAT & SPI_FIFOSTAT_TXEMPTY_MASK)) +#endif + { + } +#if SPI_RETRY_TIMES + if (waitTimes == 0U) + { + return kStatus_SPI_Timeout; + } +#endif + return kStatus_Success; +} + +/*! + * brief Performs a non-blocking SPI interrupt transfer. + * + * param base SPI peripheral base address. + * param handle pointer to spi_master_handle_t structure which stores the transfer state + * param xfer pointer to spi_xfer_config_t structure + * retval kStatus_Success Successfully start a transfer. + * retval kStatus_InvalidArgument Input argument is invalid. + * retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer) +{ + /* check params */ + assert( + !((NULL == base) || (NULL == handle) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData)))); + if ((NULL == base) || (NULL == handle) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData))) + { + return kStatus_InvalidArgument; + } + + /* dataSize (in bytes) is not aligned to 16bit (2B) transfer */ + assert(!((handle->dataWidth > (uint8_t)kSPI_Data8Bits) && ((xfer->dataSize & 0x1U) != 0U))); + if ((handle->dataWidth > (uint8_t)kSPI_Data8Bits) && ((xfer->dataSize & 0x1U) != 0U)) + { + return kStatus_InvalidArgument; + } + + /* Check if SPI is busy */ + if (handle->state == (uint32_t)kStatus_SPI_Busy) + { + return kStatus_SPI_Busy; + } + + /* Set the handle information */ + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + /* set count */ + handle->txRemainingBytes = (xfer->txData != NULL) ? xfer->dataSize : 0U; + handle->rxRemainingBytes = (xfer->rxData != NULL) ? xfer->dataSize : 0U; + handle->totalByteCount = xfer->dataSize; + /* other options */ + handle->toReceiveCount = 0; + handle->configFlags = xfer->configFlags; + /* Set the SPI state to busy */ + handle->state = (uint32_t)kStatus_SPI_Busy; + /* clear FIFOs when transfer starts */ + base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK; + base->FIFOSTAT |= SPI_FIFOSTAT_TXERR_MASK | SPI_FIFOSTAT_RXERR_MASK; + /* enable generating txIRQ and rxIRQ, first transfer is fired by empty txFIFO */ + base->FIFOINTENSET |= SPI_FIFOINTENSET_TXLVL_MASK | SPI_FIFOINTENSET_RXLVL_MASK; + return kStatus_Success; +} + +/*! + * brief Transfers a block of data using a polling method. + * + * This function will do a half-duplex transfer for SPI master, This is a blocking function, + * which does not retuen until all transfer have been completed. And data transfer mechanism is half-duplex, + * users can set transmit first or receive first. + * + * param base SPI base pointer + * param xfer pointer to spi_half_duplex_transfer_t structure + * return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, spi_half_duplex_transfer_t *xfer) +{ + assert(xfer); + + spi_transfer_t tempXfer = {0}; + status_t status; + + if (xfer->isTransmitFirst) + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + else + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + /* If the pcs pin keep assert between transmit and receive. */ + if (xfer->isPcsAssertInTransfer) + { + tempXfer.configFlags = (xfer->configFlags) & (~(uint32_t)kSPI_FrameAssert); + } + else + { + tempXfer.configFlags = (xfer->configFlags) | (uint32_t)kSPI_FrameAssert; + } + + status = SPI_MasterTransferBlocking(base, &tempXfer); + + if (status != kStatus_Success) + { + return status; + } + + if (xfer->isTransmitFirst) + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + else + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + tempXfer.configFlags = xfer->configFlags; + + /* SPI transfer blocking. */ + status = SPI_MasterTransferBlocking(base, &tempXfer); + + return status; +} + +/*! + * brief Performs a non-blocking SPI interrupt transfer. + * + * This function using polling way to do the first half transimission and using interrupts to + * do the second half transimission, the transfer mechanism is half-duplex. + * When do the second half transimission, code will return right away. When all data is transferred, + * the callback function is called. + * + * param base SPI peripheral base address. + * param handle pointer to spi_master_handle_t structure which stores the transfer state + * param xfer pointer to spi_half_duplex_transfer_t structure + * return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base, + spi_master_handle_t *handle, + spi_half_duplex_transfer_t *xfer) +{ + assert(xfer); + assert(handle); + spi_transfer_t tempXfer = {0}; + status_t status; + + if (xfer->isTransmitFirst) + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + else + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + /* If the PCS pin keep assert between transmit and receive. */ + if (xfer->isPcsAssertInTransfer) + { + tempXfer.configFlags = (xfer->configFlags) & (~(uint32_t)kSPI_FrameAssert); + } + else + { + tempXfer.configFlags = (xfer->configFlags) | (uint32_t)kSPI_FrameAssert; + } + + status = SPI_MasterTransferBlocking(base, &tempXfer); + if (status != kStatus_Success) + { + return status; + } + + if (xfer->isTransmitFirst) + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + else + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + tempXfer.configFlags = xfer->configFlags; + + status = SPI_MasterTransferNonBlocking(base, handle, &tempXfer); + + return status; +} + +/*! + * brief Gets the master transfer count. + * + * This function gets the master transfer count. + * + * param base SPI peripheral base address. + * param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + * param count The number of bytes transferred by using the non-blocking transaction. + * return status of status_t. + */ +status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count) +{ + assert(NULL != handle); + + if (NULL == count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != (uint32_t)kStatus_SPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + *count = handle->totalByteCount - handle->rxRemainingBytes; + return kStatus_Success; +} + +/*! + * brief SPI master aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * param base SPI peripheral base address. + * param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle) +{ + assert(NULL != handle); + + /* Disable interrupt requests*/ + base->FIFOINTENSET &= ~(SPI_FIFOINTENSET_TXLVL_MASK | SPI_FIFOINTENSET_RXLVL_MASK); + /* Empty FIFOs */ + base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK; + + handle->state = (uint32_t)kStatus_SPI_Idle; + handle->txRemainingBytes = 0U; + handle->rxRemainingBytes = 0U; +} + +static void SPI_TransferHandleIRQInternal(SPI_Type *base, spi_master_handle_t *handle) +{ + uint32_t tx_ctrl = 0U, last_ctrl = 0U, tmp32; + bool loopContinue; + uint32_t fifoDepth; + /* Get flexcomm instance by 'base' param */ + uint32_t instance = SPI_GetInstance(base); + size_t txRemainingBytes; + size_t rxRemainingBytes; + uint8_t toReceiveCount; + + /* check params */ + assert((NULL != base) && (NULL != handle) && ((NULL != handle->txData) || (NULL != handle->rxData))); + + fifoDepth = SPI_FIFO_DEPTH(base); + /* select slave to talk with */ + tx_ctrl |= ((uint32_t)SPI_DEASSERT_ALL & (uint32_t)SPI_ASSERTNUM_SSEL(handle->sselNum)); + /* set width of data */ + tx_ctrl |= SPI_FIFOWR_LEN(handle->dataWidth); + /* delay for frames */ + tx_ctrl |= ((handle->configFlags & (uint32_t)kSPI_FrameDelay) != 0U) ? (uint32_t)kSPI_FrameDelay : 0U; + /* end of transfer */ + last_ctrl |= ((handle->configFlags & (uint32_t)kSPI_FrameAssert) != 0U) ? (uint32_t)kSPI_FrameAssert : 0U; + do + { + loopContinue = false; + + /* rxFIFO is not empty */ + if ((base->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) != 0U) + { + tmp32 = base->FIFORD; + /* rxBuffer is not empty */ + if (handle->rxRemainingBytes != 0U) + { + /* low byte must go first */ + *(handle->rxData++) = (uint8_t)tmp32; + handle->rxRemainingBytes--; + /* read 16 bits at once */ + if (handle->dataWidth > (uint8_t)kSPI_Data8Bits) + { + *(handle->rxData++) = (uint8_t)(tmp32 >> 8); + handle->rxRemainingBytes--; + } + } + + /* decrease number of data expected to receive */ + handle->toReceiveCount -= 1; + loopContinue = true; + } + + /* - txFIFO is not full + * - we cannot cause rxFIFO overflow by sending more data than is the depth of FIFO + * - txBuffer is not empty or the next 'toReceiveCount' data can fit into rxBuffer + */ + txRemainingBytes = handle->txRemainingBytes; + rxRemainingBytes = handle->rxRemainingBytes; + toReceiveCount = (handle->toReceiveCount > 0) ? (uint8_t)handle->toReceiveCount : 0U; + if (((base->FIFOSTAT & SPI_FIFOSTAT_TXNOTFULL_MASK) != 0U) && ((uint32_t)toReceiveCount < fifoDepth) && + ((txRemainingBytes != 0U) || + (rxRemainingBytes >= SPI_COUNT_TO_BYTES(handle->dataWidth, (uint32_t)toReceiveCount + 1U)))) + { + /* txBuffer is not empty */ + if ((txRemainingBytes != 0U) && (handle->txData != NULL)) + { + /* low byte must go first */ + tmp32 = *(handle->txData++); + handle->txRemainingBytes--; + txRemainingBytes = handle->txRemainingBytes; + /* write 16 bit at once */ + if (handle->dataWidth > (uint8_t)kSPI_Data8Bits) + { + tmp32 |= ((uint32_t)(*(handle->txData++))) << 8U; + handle->txRemainingBytes--; + txRemainingBytes = handle->txRemainingBytes; + } + /* last transfer */ + if (handle->txRemainingBytes == 0U) + { + tx_ctrl |= last_ctrl; + } + } + else + { + tmp32 = (uint32_t)s_dummyData[instance]; + tmp32 |= (uint32_t)s_dummyData[instance] << 8U; + /* last transfer */ + if (rxRemainingBytes == SPI_COUNT_TO_BYTES(handle->dataWidth, (uint32_t)toReceiveCount + 1U)) + { + tx_ctrl |= last_ctrl; + } + } + /* send data */ + tmp32 = tx_ctrl | tmp32; + base->FIFOWR = tmp32; + /* increase number of expected data to receive */ + handle->toReceiveCount += 1; + toReceiveCount = (handle->toReceiveCount > 0) ? (uint8_t)handle->toReceiveCount : 0U; + loopContinue = true; + } + } while (loopContinue); +} + +/*! + * brief Interrupts the handler for the SPI. + * + * param base SPI peripheral base address. + * param handle pointer to spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle) +{ + assert((NULL != base) && (NULL != handle)); + size_t txRemainingBytes; + uint8_t toReceiveCount; + + /* IRQ behaviour: + * - first interrupt is triggered by empty txFIFO. The transfer function + * then tries empty rxFIFO and fill txFIFO interleaved that results to + * strategy to process as many items as possible. + * - the next IRQs can be: + * rxIRQ from nonempty rxFIFO which requires to empty rxFIFO. + * txIRQ from empty txFIFO which requires to refill txFIFO. + * - last interrupt is triggered by empty txFIFO. The last state is + * known by empty rxBuffer and txBuffer. If there is nothing to receive + * or send - both operations have been finished and interrupts can be + * disabled. + */ + + /* Data to send or read or expected to receive */ + if ((handle->txRemainingBytes != 0U) || (handle->rxRemainingBytes != 0U) || (handle->toReceiveCount != 0)) + { + /* Transmit or receive data */ + SPI_TransferHandleIRQInternal(base, handle); + /* No data to send or read or receive. Transfer ends. Set txTrigger to 0 level and + * enable txIRQ to confirm when txFIFO becomes empty */ + if ((0U == handle->txRemainingBytes) && (0U == handle->rxRemainingBytes) && (0 == handle->toReceiveCount)) + { + base->FIFOTRIG = base->FIFOTRIG & (~SPI_FIFOTRIG_TXLVL_MASK); + base->FIFOINTENSET |= SPI_FIFOINTENSET_TXLVL_MASK; + } + else + { + uint32_t rxRemainingCount = SPI_BYTES_TO_COUNT(handle->dataWidth, handle->rxRemainingBytes); + /* If, there are no data to send or rxFIFO is already filled with necessary number of dummy data, + * disable txIRQ. From this point only rxIRQ is used to receive data without any transmission */ + toReceiveCount = (handle->toReceiveCount > 0) ? (uint8_t)handle->toReceiveCount : 0U; + if ((0U == handle->txRemainingBytes) && (rxRemainingCount <= toReceiveCount)) + { + base->FIFOINTENCLR = SPI_FIFOINTENCLR_TXLVL_MASK; + } + /* Nothing to receive or transmit, but we still have pending data which are bellow rxLevel. + * Cannot clear rxFIFO, txFIFO might be still active */ + if (rxRemainingCount == 0U) + { + txRemainingBytes = handle->txRemainingBytes; + if ((txRemainingBytes == 0U) && (toReceiveCount != 0U) && + (toReceiveCount < SPI_FIFOTRIG_RXLVL_GET(base) + 1U)) + { + base->FIFOTRIG = (base->FIFOTRIG & (~SPI_FIFOTRIG_RXLVL_MASK)) | + SPI_FIFOTRIG_RXLVL((uint32_t)toReceiveCount - 1U); + } + } + else + { + /* Expected to receive less data than rxLevel value, we have to update rxLevel */ + if (rxRemainingCount < (SPI_FIFOTRIG_RXLVL_GET(base) + 1U)) + { + base->FIFOTRIG = + (base->FIFOTRIG & (~SPI_FIFOTRIG_RXLVL_MASK)) | SPI_FIFOTRIG_RXLVL(rxRemainingCount - 1U); + } + } + } + } + else + { + /* Empty txFIFO is confirmed. Disable IRQs and restore triggers values */ + base->FIFOINTENCLR = SPI_FIFOINTENCLR_RXLVL_MASK | SPI_FIFOINTENCLR_TXLVL_MASK; + base->FIFOTRIG = (base->FIFOTRIG & (~(SPI_FIFOTRIG_RXLVL_MASK | SPI_FIFOTRIG_RXLVL_MASK))) | + SPI_FIFOTRIG_RXLVL(handle->rxWatermark) | SPI_FIFOTRIG_TXLVL(handle->txWatermark); + /* set idle state and call user callback */ + handle->state = (uint32_t)kStatus_SPI_Idle; + if (handle->callback != NULL) + { + (handle->callback)(base, handle, handle->state, handle->userData); + } + } +} diff --git a/drivers/fsl_spi.h b/drivers/fsl_spi.h new file mode 100644 index 0000000..2320e57 --- /dev/null +++ b/drivers/fsl_spi.h @@ -0,0 +1,746 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_SPI_H_ +#define _FSL_SPI_H_ + +#include "fsl_common.h" +#include "fsl_flexcomm.h" + +/*! + * @addtogroup spi_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SPI driver version. */ +#define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 2, 1)) +/*@}*/ + +/*! @brief Global variable for dummy data value setting. */ +extern volatile uint8_t s_dummyData[]; + +#ifndef SPI_DUMMYDATA +/*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */ +#define SPI_DUMMYDATA (0xFFU) +#endif + +/*! @brief Retry times for waiting flag. */ +#ifndef SPI_RETRY_TIMES +#define SPI_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */ +#endif + +#define SPI_DATA(n) (((uint32_t)(n)) & 0xFFFFUL) +#define SPI_CTRLMASK (0xFFFF0000U) + +#define SPI_ASSERTNUM_SSEL(n) ((~(1UL << ((n) + 16UL))) & 0xF0000UL) +#define SPI_DEASSERTNUM_SSEL(n) (1UL << ((n) + 16UL)) +#define SPI_DEASSERT_ALL (0xF0000UL) + +#define SPI_FIFOWR_FLAGS_MASK (~(SPI_DEASSERT_ALL | SPI_FIFOWR_TXDATA_MASK | SPI_FIFOWR_LEN_MASK)) + +#define SPI_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & SPI_FIFOTRIG_TXLVL_MASK) >> SPI_FIFOTRIG_TXLVL_SHIFT) +#define SPI_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & SPI_FIFOTRIG_RXLVL_MASK) >> SPI_FIFOTRIG_RXLVL_SHIFT) + +/*! @brief SPI transfer option.*/ +typedef enum _spi_xfer_option +{ + kSPI_FrameDelay = (SPI_FIFOWR_EOF_MASK), /*!< A delay may be inserted, defined in the DLY register.*/ + kSPI_FrameAssert = (SPI_FIFOWR_EOT_MASK), /*!< SSEL will be deasserted at the end of a transfer */ +} spi_xfer_option_t; + +/*! @brief SPI data shifter direction options.*/ +typedef enum _spi_shift_direction +{ + kSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit. */ + kSPI_LsbFirst = 1U /*!< Data transfers start with least significant bit. */ +} spi_shift_direction_t; + +/*! @brief SPI clock polarity configuration.*/ +typedef enum _spi_clock_polarity +{ + kSPI_ClockPolarityActiveHigh = 0x0U, /*!< Active-high SPI clock (idles low). */ + kSPI_ClockPolarityActiveLow /*!< Active-low SPI clock (idles high). */ +} spi_clock_polarity_t; + +/*! @brief SPI clock phase configuration.*/ +typedef enum _spi_clock_phase +{ + kSPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SCK occurs at the middle of the first + * cycle of a data transfer. */ + kSPI_ClockPhaseSecondEdge /*!< First edge on SCK occurs at the start of the + * first cycle of a data transfer. */ +} spi_clock_phase_t; + +/*! @brief txFIFO watermark values */ +typedef enum _spi_txfifo_watermark +{ + kSPI_TxFifo0 = 0, /*!< SPI tx watermark is empty */ + kSPI_TxFifo1 = 1, /*!< SPI tx watermark at 1 item */ + kSPI_TxFifo2 = 2, /*!< SPI tx watermark at 2 items */ + kSPI_TxFifo3 = 3, /*!< SPI tx watermark at 3 items */ + kSPI_TxFifo4 = 4, /*!< SPI tx watermark at 4 items */ + kSPI_TxFifo5 = 5, /*!< SPI tx watermark at 5 items */ + kSPI_TxFifo6 = 6, /*!< SPI tx watermark at 6 items */ + kSPI_TxFifo7 = 7, /*!< SPI tx watermark at 7 items */ +} spi_txfifo_watermark_t; + +/*! @brief rxFIFO watermark values */ +typedef enum _spi_rxfifo_watermark +{ + kSPI_RxFifo1 = 0, /*!< SPI rx watermark at 1 item */ + kSPI_RxFifo2 = 1, /*!< SPI rx watermark at 2 items */ + kSPI_RxFifo3 = 2, /*!< SPI rx watermark at 3 items */ + kSPI_RxFifo4 = 3, /*!< SPI rx watermark at 4 items */ + kSPI_RxFifo5 = 4, /*!< SPI rx watermark at 5 items */ + kSPI_RxFifo6 = 5, /*!< SPI rx watermark at 6 items */ + kSPI_RxFifo7 = 6, /*!< SPI rx watermark at 7 items */ + kSPI_RxFifo8 = 7, /*!< SPI rx watermark at 8 items */ +} spi_rxfifo_watermark_t; + +/*! @brief Transfer data width */ +typedef enum _spi_data_width +{ + kSPI_Data4Bits = 3, /*!< 4 bits data width */ + kSPI_Data5Bits = 4, /*!< 5 bits data width */ + kSPI_Data6Bits = 5, /*!< 6 bits data width */ + kSPI_Data7Bits = 6, /*!< 7 bits data width */ + kSPI_Data8Bits = 7, /*!< 8 bits data width */ + kSPI_Data9Bits = 8, /*!< 9 bits data width */ + kSPI_Data10Bits = 9, /*!< 10 bits data width */ + kSPI_Data11Bits = 10, /*!< 11 bits data width */ + kSPI_Data12Bits = 11, /*!< 12 bits data width */ + kSPI_Data13Bits = 12, /*!< 13 bits data width */ + kSPI_Data14Bits = 13, /*!< 14 bits data width */ + kSPI_Data15Bits = 14, /*!< 15 bits data width */ + kSPI_Data16Bits = 15, /*!< 16 bits data width */ +} spi_data_width_t; + +/*! @brief Slave select */ +typedef enum _spi_ssel +{ + kSPI_Ssel0 = 0, /*!< Slave select 0 */ + kSPI_Ssel1 = 1, /*!< Slave select 1 */ + kSPI_Ssel2 = 2, /*!< Slave select 2 */ + kSPI_Ssel3 = 3, /*!< Slave select 3 */ +} spi_ssel_t; + +/*! @brief ssel polarity */ +typedef enum _spi_spol +{ + kSPI_Spol0ActiveHigh = SPI_CFG_SPOL0(1), + kSPI_Spol1ActiveHigh = SPI_CFG_SPOL1(1), + kSPI_Spol2ActiveHigh = SPI_CFG_SPOL2(1), +#if defined(FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE) && (FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE) + kSPI_SpolActiveAllHigh = (kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh | kSPI_Spol2ActiveHigh), +#else + kSPI_Spol3ActiveHigh = SPI_CFG_SPOL3(1), + kSPI_SpolActiveAllHigh = + (kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh | kSPI_Spol2ActiveHigh | kSPI_Spol3ActiveHigh), +#endif + kSPI_SpolActiveAllLow = 0, +} spi_spol_t; + +/*! + * @brief SPI delay time configure structure. + * Note: + * The DLY register controls several programmable delays related to SPI signalling, + * it stands for how many SPI clock time will be inserted. + * The maxinun value of these delay time is 15. + */ +typedef struct _spi_delay_config +{ + uint8_t preDelay; /*!< Delay between SSEL assertion and the beginning of transfer. */ + uint8_t postDelay; /*!< Delay between the end of transfer and SSEL deassertion. */ + uint8_t frameDelay; /*!< Delay between frame to frame. */ + uint8_t transferDelay; /*!< Delay between transfer to transfer. */ +} spi_delay_config_t; + +/*! @brief SPI master user configure structure.*/ +typedef struct _spi_master_config +{ + bool enableLoopback; /*!< Enable loopback for test purpose */ + bool enableMaster; /*!< Enable SPI at initialization time */ + spi_clock_polarity_t polarity; /*!< Clock polarity */ + spi_clock_phase_t phase; /*!< Clock phase */ + spi_shift_direction_t direction; /*!< MSB or LSB */ + uint32_t baudRate_Bps; /*!< Baud Rate for SPI in Hz */ + spi_data_width_t dataWidth; /*!< Width of the data */ + spi_ssel_t sselNum; /*!< Slave select number */ + spi_spol_t sselPol; /*!< Configure active CS polarity */ + uint8_t txWatermark; /*!< txFIFO watermark */ + uint8_t rxWatermark; /*!< rxFIFO watermark */ + spi_delay_config_t delayConfig; /*!< Delay configuration. */ +} spi_master_config_t; + +/*! @brief SPI slave user configure structure.*/ +typedef struct _spi_slave_config +{ + bool enableSlave; /*!< Enable SPI at initialization time */ + spi_clock_polarity_t polarity; /*!< Clock polarity */ + spi_clock_phase_t phase; /*!< Clock phase */ + spi_shift_direction_t direction; /*!< MSB or LSB */ + spi_data_width_t dataWidth; /*!< Width of the data */ + spi_spol_t sselPol; /*!< Configure active CS polarity */ + uint8_t txWatermark; /*!< txFIFO watermark */ + uint8_t rxWatermark; /*!< rxFIFO watermark */ +} spi_slave_config_t; + +/*! @brief SPI transfer status.*/ +enum +{ + kStatus_SPI_Busy = MAKE_STATUS(kStatusGroup_LPC_SPI, 0), /*!< SPI bus is busy */ + kStatus_SPI_Idle = MAKE_STATUS(kStatusGroup_LPC_SPI, 1), /*!< SPI is idle */ + kStatus_SPI_Error = MAKE_STATUS(kStatusGroup_LPC_SPI, 2), /*!< SPI error */ + kStatus_SPI_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPC_SPI, 3), /*!< Baudrate is not support in current clock source */ + kStatus_SPI_Timeout = MAKE_STATUS(kStatusGroup_LPC_SPI, 4) /*!< SPI timeout polling status flags. */ +}; + +/*! @brief SPI interrupt sources.*/ +enum _spi_interrupt_enable +{ + kSPI_RxLvlIrq = SPI_FIFOINTENSET_RXLVL_MASK, /*!< Rx level interrupt */ + kSPI_TxLvlIrq = SPI_FIFOINTENSET_TXLVL_MASK, /*!< Tx level interrupt */ +}; + +/*! @brief SPI status flags.*/ +enum _spi_statusflags +{ + kSPI_TxEmptyFlag = SPI_FIFOSTAT_TXEMPTY_MASK, /*!< txFifo is empty */ + kSPI_TxNotFullFlag = SPI_FIFOSTAT_TXNOTFULL_MASK, /*!< txFifo is not full */ + kSPI_RxNotEmptyFlag = SPI_FIFOSTAT_RXNOTEMPTY_MASK, /*!< rxFIFO is not empty */ + kSPI_RxFullFlag = SPI_FIFOSTAT_RXFULL_MASK, /*!< rxFIFO is full */ +}; + +/*! @brief SPI transfer structure */ +typedef struct _spi_transfer +{ + uint8_t *txData; /*!< Send buffer */ + uint8_t *rxData; /*!< Receive buffer */ + uint32_t configFlags; /*!< Additional option to control transfer, @ref spi_xfer_option_t. */ + size_t dataSize; /*!< Transfer bytes */ +} spi_transfer_t; + +/*! @brief SPI half-duplex(master only) transfer structure */ +typedef struct _spi_half_duplex_transfer +{ + uint8_t *txData; /*!< Send buffer */ + uint8_t *rxData; /*!< Receive buffer */ + size_t txDataSize; /*!< Transfer bytes for transmit */ + size_t rxDataSize; /*!< Transfer bytes */ + uint32_t configFlags; /*!< Transfer configuration flags, @ref spi_xfer_option_t. */ + bool isPcsAssertInTransfer; /*!< If PCS pin keep assert between transmit and receive. true for assert and false for + deassert. */ + bool isTransmitFirst; /*!< True for transmit first and false for receive first. */ +} spi_half_duplex_transfer_t; + +/*! @brief Internal configuration structure used in 'spi' and 'spi_dma' driver */ +typedef struct _spi_config +{ + spi_data_width_t dataWidth; + spi_ssel_t sselNum; +} spi_config_t; + +/*! @brief Master handle type */ +typedef struct _spi_master_handle spi_master_handle_t; + +/*! @brief Slave handle type */ +typedef spi_master_handle_t spi_slave_handle_t; + +/*! @brief SPI master callback for finished transmit */ +typedef void (*spi_master_callback_t)(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI slave callback for finished transmit */ +typedef void (*spi_slave_callback_t)(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI transfer handle structure */ +struct _spi_master_handle +{ + uint8_t *volatile txData; /*!< Transfer buffer */ + uint8_t *volatile rxData; /*!< Receive buffer */ + volatile size_t txRemainingBytes; /*!< Number of data to be transmitted [in bytes] */ + volatile size_t rxRemainingBytes; /*!< Number of data to be received [in bytes] */ + volatile int8_t toReceiveCount; /*!< The number of data expected to receive in data width. Since the received count + and sent count should be the same to complete the transfer, if the sent count is + x and the received count is y, toReceiveCount is x-y. */ + size_t totalByteCount; /*!< A number of transfer bytes */ + volatile uint32_t state; /*!< SPI internal state */ + spi_master_callback_t callback; /*!< SPI callback */ + void *userData; /*!< Callback parameter */ + uint8_t dataWidth; /*!< Width of the data [Valid values: 1 to 16] */ + uint8_t sselNum; /*!< Slave select number to be asserted when transferring data [Valid values: 0 to 3] */ + uint32_t configFlags; /*!< Additional option to control transfer */ + uint8_t txWatermark; /*!< txFIFO watermark */ + uint8_t rxWatermark; /*!< rxFIFO watermark */ +}; + +/*! @brief Typedef for master interrupt handler. */ +typedef void (*flexcomm_spi_master_irq_handler_t)(SPI_Type *base, spi_master_handle_t *handle); + +/*! @brief Typedef for slave interrupt handler. */ +typedef void (*flexcomm_spi_slave_irq_handler_t)(SPI_Type *base, spi_slave_handle_t *handle); +/*! @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @brief Returns instance number for SPI peripheral base address. */ +uint32_t SPI_GetInstance(SPI_Type *base); + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Sets the SPI master configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit(). + * User may use the initialized structure unchanged in SPI_MasterInit(), or modify + * some fields of the structure before calling SPI_MasterInit(). After calling this API, + * the master is ready to transfer. + * Example: + @code + spi_master_config_t config; + SPI_MasterGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master config structure + */ +void SPI_MasterGetDefaultConfig(spi_master_config_t *config); + +/*! + * @brief Initializes the SPI with master configuration. + * + * The configuration structure can be filled by user from scratch, or be set with default + * values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer. + * Example + @code + spi_master_config_t config = { + .baudRate_Bps = 400000, + ... + }; + SPI_MasterInit(SPI0, &config); + @endcode + * + * @param base SPI base pointer + * @param config pointer to master configuration structure + * @param srcClock_Hz Source clock frequency. + */ +status_t SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Sets the SPI slave configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit(). + * Modify some fields of the structure before calling SPI_SlaveInit(). + * Example: + @code + spi_slave_config_t config; + SPI_SlaveGetDefaultConfig(&config); + @endcode + * + * @param config pointer to slave configuration structure + */ +void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config); + +/*! + * @brief Initializes the SPI with slave configuration. + * + * The configuration structure can be filled by user from scratch or be set with + * default values by SPI_SlaveGetDefaultConfig(). + * After calling this API, the slave is ready to transfer. + * Example + @code + spi_slave_config_t config = { + .polarity = flexSPIClockPolarity_ActiveHigh; + .phase = flexSPIClockPhase_FirstEdge; + .direction = flexSPIMsbFirst; + ... + }; + SPI_SlaveInit(SPI0, &config); + @endcode + * + * @param base SPI base pointer + * @param config pointer to slave configuration structure + */ +status_t SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config); + +/*! + * @brief De-initializes the SPI. + * + * Calling this API resets the SPI module, gates the SPI clock. + * The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module. + * + * @param base SPI base pointer + */ +void SPI_Deinit(SPI_Type *base); + +/*! + * @brief Enable or disable the SPI Master or Slave + * @param base SPI base pointer + * @param enable or disable ( true = enable, false = disable) + */ +static inline void SPI_Enable(SPI_Type *base, bool enable) +{ + if (enable) + { + base->CFG |= SPI_CFG_ENABLE_MASK; + } + else + { + base->CFG &= ~SPI_CFG_ENABLE_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the status flag. + * + * @param base SPI base pointer + * @return SPI Status, use status flag to AND @ref _spi_statusflags could get the related status. + */ +static inline uint32_t SPI_GetStatusFlags(SPI_Type *base) +{ + assert(NULL != base); + return base->FIFOSTAT; +} + +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the interrupt for the SPI. + * + * @param base SPI base pointer + * @param irqs SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxLvlIrq + * @arg kSPI_TxLvlIrq + */ +static inline void SPI_EnableInterrupts(SPI_Type *base, uint32_t irqs) +{ + assert(NULL != base); + base->FIFOINTENSET = irqs; +} + +/*! + * @brief Disables the interrupt for the SPI. + * + * @param base SPI base pointer + * @param irqs SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxLvlIrq + * @arg kSPI_TxLvlIrq + */ +static inline void SPI_DisableInterrupts(SPI_Type *base, uint32_t irqs) +{ + assert(NULL != base); + base->FIFOINTENCLR = irqs; +} + +/*! @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Enables the DMA request from SPI txFIFO. + * + * @param base SPI base pointer + * @param enable True means enable DMA, false means disable DMA + */ +void SPI_EnableTxDMA(SPI_Type *base, bool enable); + +/*! + * @brief Enables the DMA request from SPI rxFIFO. + * + * @param base SPI base pointer + * @param enable True means enable DMA, false means disable DMA + */ +void SPI_EnableRxDMA(SPI_Type *base, bool enable); + +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ +/*! + * @brief Returns the configurations. + * + * @param base SPI peripheral address. + * @return return configurations which contain datawidth and SSEL numbers. + * return data type is a pointer of spi_config_t. + */ +void *SPI_GetConfig(SPI_Type *base); + +/*! + * @brief Sets the baud rate for SPI transfer. This is only used in master. + * + * @param base SPI base pointer + * @param baudrate_Bps baud rate needed in Hz. + * @param srcClock_Hz SPI source clock frequency in Hz. + */ +status_t SPI_MasterSetBaud(SPI_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Writes a data into the SPI data register. + * + * @param base SPI base pointer + * @param data needs to be write. + * @param configFlags transfer configuration options @ref spi_xfer_option_t + */ +void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags); + +/*! + * @brief Gets a data from the SPI data register. + * + * @param base SPI base pointer + * @return Data in the register. + */ +static inline uint32_t SPI_ReadData(SPI_Type *base) +{ + assert(NULL != base); + return base->FIFORD; +} + +/*! + * @brief Set delay time for transfer. + * the delay uint is SPI clock time, maximum value is 0xF. + * @param base SPI base pointer + * @param config configuration for delay option @ref spi_delay_config_t. + */ +static inline void SPI_SetTransferDelay(SPI_Type *base, const spi_delay_config_t *config) +{ + assert(NULL != base); + assert(NULL != config); + base->DLY = (SPI_DLY_PRE_DELAY(config->preDelay) | SPI_DLY_POST_DELAY(config->postDelay) | + SPI_DLY_FRAME_DELAY(config->frameDelay) | SPI_DLY_TRANSFER_DELAY(config->transferDelay)); +} + +/*! + * @brief Set up the dummy data. + * + * @param base SPI peripheral address. + * @param dummyData Data to be transferred when tx buffer is NULL. + */ +void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData); + +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the SPI master handle. + * + * This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +status_t SPI_MasterTransferCreateHandle(SPI_Type *base, + spi_master_handle_t *handle, + spi_master_callback_t callback, + void *userData); + +/*! + * @brief Transfers a block of data using a polling method. + * + * @param base SPI base pointer + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Timeout The transfer timed out and was aborted. + */ +status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SPI interrupt transfer. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer); + +/*! + * @brief Transfers a block of data using a polling method. + * + * This function will do a half-duplex transfer for SPI master, This is a blocking function, + * which does not retuen until all transfer have been completed. And data transfer mechanism is half-duplex, + * users can set transmit first or receive first. + * + * @param base SPI base pointer + * @param xfer pointer to spi_half_duplex_transfer_t structure + * @return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, spi_half_duplex_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SPI interrupt transfer. + * + * This function using polling way to do the first half transimission and using interrupts to + * do the second half transimission, the transfer mechanism is half-duplex. + * When do the second half transimission, code will return right away. When all data is transferred, + * the callback function is called. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_half_duplex_transfer_t structure + * @return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base, + spi_master_handle_t *handle, + spi_half_duplex_transfer_t *xfer); + +/*! + * @brief Gets the master transfer count. + * + * This function gets the master transfer count. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. + * @return status of status_t. + */ +status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count); + +/*! + * @brief SPI master aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Interrupts the handler for the SPI. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Initializes the SPI slave handle. + * + * This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +static inline status_t SPI_SlaveTransferCreateHandle(SPI_Type *base, + spi_slave_handle_t *handle, + spi_slave_callback_t callback, + void *userData) +{ + return SPI_MasterTransferCreateHandle(base, handle, callback, userData); +} + +/*! + * @brief Performs a non-blocking SPI slave interrupt transfer. + * + * @note The API returns immediately after the transfer initialization is finished. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +static inline status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer) +{ + return SPI_MasterTransferNonBlocking(base, handle, xfer); +} + +/*! + * @brief Gets the slave transfer count. + * + * This function gets the slave transfer count. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. + * @return status of status_t. + */ +static inline status_t SPI_SlaveTransferGetCount(SPI_Type *base, spi_slave_handle_t *handle, size_t *count) +{ + return SPI_MasterTransferGetCount(base, (spi_master_handle_t *)handle, count); +} + +/*! + * @brief SPI slave aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_slave_handle_t structure which stores the transfer state. + */ +static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *handle) +{ + SPI_MasterTransferAbort(base, (spi_master_handle_t *)handle); +} + +/*! + * @brief Interrupts a handler for the SPI slave. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_slave_handle_t structure which stores the transfer state + */ +static inline void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle) +{ + SPI_MasterTransferHandleIRQ(base, handle); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_SPI_H_*/ diff --git a/drivers/fsl_usart.c b/drivers/fsl_usart.c new file mode 100644 index 0000000..cab74a5 --- /dev/null +++ b/drivers/fsl_usart.c @@ -0,0 +1,1160 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_usart.h" +#include "fsl_device_registers.h" +#include "fsl_flexcomm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.flexcomm_usart" +#endif + +/*! + * @brief Used for conversion from `flexcomm_usart_irq_handler_t` to `flexcomm_irq_handler_t` + */ +typedef union usart_to_flexcomm +{ + flexcomm_usart_irq_handler_t usart_master_handler; + flexcomm_irq_handler_t flexcomm_handler; +} usart_to_flexcomm_t; + +enum +{ + kUSART_TxIdle, /* TX idle. */ + kUSART_TxBusy, /* TX busy. */ + kUSART_RxIdle, /* RX idle. */ + kUSART_RxBusy /* RX busy. */ +}; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief IRQ name array */ +static const IRQn_Type s_usartIRQ[] = USART_IRQS; + +/*! @brief Array to map USART instance number to base address. */ +static const uint32_t s_usartBaseAddrs[FSL_FEATURE_SOC_USART_COUNT] = USART_BASE_ADDRS; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Get the index corresponding to the USART */ +/*! brief Returns instance number for USART peripheral base address. */ +uint32_t USART_GetInstance(USART_Type *base) +{ + uint32_t i; + + for (i = 0; i < (uint32_t)FSL_FEATURE_SOC_USART_COUNT; i++) + { + if ((uint32_t)base == s_usartBaseAddrs[i]) + { + break; + } + } + + assert(i < (uint32_t)FSL_FEATURE_SOC_USART_COUNT); + return i; +} + +/*! + * brief Get the length of received data in RX ring buffer. + * + * param handle USART handle pointer. + * return Length of received data in RX ring buffer. + */ +size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle) +{ + size_t size; + + /* Check arguments */ + assert(NULL != handle); + uint16_t rxRingBufferHead = handle->rxRingBufferHead; + uint16_t rxRingBufferTail = handle->rxRingBufferTail; + + if (rxRingBufferTail > rxRingBufferHead) + { + size = (size_t)rxRingBufferHead + handle->rxRingBufferSize - (size_t)rxRingBufferTail; + } + else + { + size = (size_t)rxRingBufferHead - (size_t)rxRingBufferTail; + } + return size; +} + +static bool USART_TransferIsRxRingBufferFull(usart_handle_t *handle) +{ + bool full; + + /* Check arguments */ + assert(NULL != handle); + + if (USART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + return full; +} + +/*! + * brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific USART handle. + * + * When the RX ring buffer is used, data received are stored into the ring buffer even when the + * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * note When using the RX ring buffer, one byte is reserved for internal use. In other + * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. + * param ringBufferSize size of the ring buffer. + */ +void USART_TransferStartRingBuffer(USART_Type *base, usart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) +{ + /* Check arguments */ + assert(NULL != base); + assert(NULL != handle); + assert(NULL != ringBuffer); + + /* Setup the ringbuffer address */ + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + /* ring buffer is ready we can start receiving data */ + base->FIFOINTENSET = USART_FIFOINTENSET_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK; +} + +/*! + * brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + */ +void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle) +{ + /* Check arguments */ + assert(NULL != base); + assert(NULL != handle); + + if (handle->rxState == (uint8_t)kUSART_RxIdle) + { + base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK; + } + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +/*! + * brief Initializes a USART instance with user configuration structure and peripheral clock. + * + * This function configures the USART module with the user-defined settings. The user can configure the configuration + * structure and also get the default configuration by using the USART_GetDefaultConfig() function. + * Example below shows how to use this API to configure USART. + * code + * usart_config_t usartConfig; + * usartConfig.baudRate_Bps = 115200U; + * usartConfig.parityMode = kUSART_ParityDisabled; + * usartConfig.stopBitCount = kUSART_OneStopBit; + * USART_Init(USART1, &usartConfig, 20000000U); + * endcode + * + * param base USART peripheral base address. + * param config Pointer to user-defined configuration structure. + * param srcClock_Hz USART clock source frequency in HZ. + * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * retval kStatus_InvalidArgument USART base address is not valid + * retval kStatus_Success Status USART initialize succeed + */ +status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz) +{ + int result; + + /* check arguments */ + assert(!((NULL == base) || (NULL == config) || (0U == srcClock_Hz))); + if ((NULL == base) || (NULL == config) || (0U == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* initialize flexcomm to USART mode */ + result = FLEXCOMM_Init(base, FLEXCOMM_PERIPH_USART); + if (kStatus_Success != result) + { + return result; + } + + if (config->enableTx) + { + /* empty and enable txFIFO */ + base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK | USART_FIFOCFG_ENABLETX_MASK; + /* setup trigger level */ + base->FIFOTRIG &= ~(USART_FIFOTRIG_TXLVL_MASK); + base->FIFOTRIG |= USART_FIFOTRIG_TXLVL(config->txWatermark); + /* enable trigger interrupt */ + base->FIFOTRIG |= USART_FIFOTRIG_TXLVLENA_MASK; + } + + /* empty and enable rxFIFO */ + if (config->enableRx) + { + base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK | USART_FIFOCFG_ENABLERX_MASK; + /* setup trigger level */ + base->FIFOTRIG &= ~(USART_FIFOTRIG_RXLVL_MASK); + base->FIFOTRIG |= USART_FIFOTRIG_RXLVL(config->rxWatermark); + /* enable trigger interrupt */ + base->FIFOTRIG |= USART_FIFOTRIG_RXLVLENA_MASK; + } + /* setup configuration and enable USART */ + base->CFG = USART_CFG_PARITYSEL(config->parityMode) | USART_CFG_STOPLEN(config->stopBitCount) | + USART_CFG_DATALEN(config->bitCountPerChar) | USART_CFG_LOOP(config->loopback) | + USART_CFG_SYNCEN((uint32_t)config->syncMode >> 1) | USART_CFG_SYNCMST((uint8_t)config->syncMode) | + USART_CFG_CLKPOL(config->clockPolarity) | USART_CFG_MODE32K(config->enableMode32k) | + USART_CFG_CTSEN(config->enableHardwareFlowControl) | USART_CFG_ENABLE_MASK; + + /* Setup baudrate */ + if (config->enableMode32k) + { + if ((9600U % config->baudRate_Bps) == 0U) + { + base->BRG = 9600U / config->baudRate_Bps; + } + else + { + return kStatus_USART_BaudrateNotSupport; + } + } + else + { + result = USART_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz); + if (kStatus_Success != result) + { + return result; + } + } + /* Setting continuous Clock configuration. used for synchronous mode. */ + USART_EnableContinuousSCLK(base, config->enableContinuousSCLK); + + return kStatus_Success; +} + +/*! + * brief Deinitializes a USART instance. + * + * This function waits for TX complete, disables TX and RX, and disables the USART clock. + * + * param base USART peripheral base address. + */ +void USART_Deinit(USART_Type *base) +{ + /* Check arguments */ + assert(NULL != base); + while (0U == (base->STAT & USART_STAT_TXIDLE_MASK)) + { + } + /* Disable interrupts, disable dma requests, disable peripheral */ + base->FIFOINTENCLR = USART_FIFOINTENCLR_TXERR_MASK | USART_FIFOINTENCLR_RXERR_MASK | USART_FIFOINTENCLR_TXLVL_MASK | + USART_FIFOINTENCLR_RXLVL_MASK; + base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK | USART_FIFOCFG_DMARX_MASK); + base->CFG &= ~(USART_CFG_ENABLE_MASK); +} + +/*! + * brief Gets the default configuration structure. + * + * This function initializes the USART configuration structure to a default value. The default + * values are: + * usartConfig->baudRate_Bps = 115200U; + * usartConfig->parityMode = kUSART_ParityDisabled; + * usartConfig->stopBitCount = kUSART_OneStopBit; + * usartConfig->bitCountPerChar = kUSART_8BitsPerChar; + * usartConfig->loopback = false; + * usartConfig->enableTx = false; + * usartConfig->enableRx = false; + * + * param config Pointer to configuration structure. + */ +void USART_GetDefaultConfig(usart_config_t *config) +{ + /* Check arguments */ + assert(NULL != config); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + /* Set always all members ! */ + config->baudRate_Bps = 115200U; + config->parityMode = kUSART_ParityDisabled; + config->stopBitCount = kUSART_OneStopBit; + config->bitCountPerChar = kUSART_8BitsPerChar; + config->loopback = false; + config->enableRx = false; + config->enableTx = false; + config->enableMode32k = false; + config->txWatermark = kUSART_TxFifo0; + config->rxWatermark = kUSART_RxFifo1; + config->syncMode = kUSART_SyncModeDisabled; + config->enableContinuousSCLK = false; + config->clockPolarity = kUSART_RxSampleOnFallingEdge; + config->enableHardwareFlowControl = false; +} + +/*! + * brief Sets the USART instance baud rate. + * + * This function configures the USART module baud rate. This function is used to update + * the USART module baud rate after the USART module is initialized by the USART_Init. + * code + * USART_SetBaudRate(USART1, 115200U, 20000000U); + * endcode + * + * param base USART peripheral base address. + * param baudrate_Bps USART baudrate to be set. + * param srcClock_Hz USART clock source frequency in HZ. + * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * retval kStatus_Success Set baudrate succeed. + * retval kStatus_InvalidArgument One or more arguments are invalid. + */ +status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz) +{ + uint32_t best_diff = (uint32_t)-1, best_osrval = 0xf, best_brgval = (uint32_t)-1; + uint32_t osrval, brgval, diff, baudrate; + + /* check arguments */ + assert(!((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz))); + if ((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* If synchronous master mode is enabled, only configure the BRG value. */ + if ((base->CFG & USART_CFG_SYNCEN_MASK) != 0U) + { + if ((base->CFG & USART_CFG_SYNCMST_MASK) != 0U) + { + brgval = srcClock_Hz / baudrate_Bps; + base->BRG = brgval - 1U; + } + } + else + { + /* + * Smaller values of OSR can make the sampling position within a data bit less accurate and may + * potentially cause more noise errors or incorrect data. + */ + for (osrval = best_osrval; osrval >= 8U; osrval--) + { + brgval = (((srcClock_Hz * 10U) / ((osrval + 1U) * baudrate_Bps)) - 5U) / 10U; + if (brgval > 0xFFFFU) + { + continue; + } + baudrate = srcClock_Hz / ((osrval + 1U) * (brgval + 1U)); + diff = (baudrate_Bps < baudrate) ? (baudrate - baudrate_Bps) : (baudrate_Bps - baudrate); + if (diff < best_diff) + { + best_diff = diff; + best_osrval = osrval; + best_brgval = brgval; + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculated OSR and BRG value */ + baudrate = srcClock_Hz / ((best_osrval + 1U) * (best_brgval + 1U)); + diff = (baudrate_Bps < baudrate) ? (baudrate - baudrate_Bps) : (baudrate_Bps - baudrate); + if (diff > ((baudrate_Bps / 100U) * 3U)) + { + return kStatus_USART_BaudrateNotSupport; + } + + /* value over range */ + if (best_brgval > 0xFFFFU) + { + return kStatus_USART_BaudrateNotSupport; + } + + base->OSR = best_osrval; + base->BRG = best_brgval; + } + + return kStatus_Success; +} + +/*! + * brief Enable 32 kHz mode which USART uses clock from the RTC oscillator as the clock source. + * + * Please note that in order to use a 32 kHz clock to operate USART properly, the RTC oscillator + * and its 32 kHz output must be manully enabled by user, by calling RTC_Init and setting + * SYSCON_RTCOSCCTRL_EN bit to 1. + * And in 32kHz clocking mode the USART can only work at 9600 baudrate or at the baudrate that + * 9600 can evenly divide, eg: 4800, 3200. + * + * param base USART peripheral base address. + * param baudRate_Bps USART baudrate to be set.. + * param enableMode32k true is 32k mode, false is normal mode. + * param srcClock_Hz USART clock source frequency in HZ. + * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * retval kStatus_Success Set baudrate succeed. + * retval kStatus_InvalidArgument One or more arguments are invalid. + */ +status_t USART_Enable32kMode(USART_Type *base, uint32_t baudRate_Bps, bool enableMode32k, uint32_t srcClock_Hz) +{ + status_t result = kStatus_Success; + base->CFG &= ~(USART_CFG_ENABLE_MASK); + if (enableMode32k) + { + base->CFG |= USART_CFG_MODE32K_MASK; + if ((9600U % baudRate_Bps) == 0U) + { + base->BRG = 9600U / baudRate_Bps - 1U; + } + else + { + return kStatus_USART_BaudrateNotSupport; + } + } + else + { + base->CFG &= ~(USART_CFG_MODE32K_MASK); + result = USART_SetBaudRate(base, baudRate_Bps, srcClock_Hz); + if (kStatus_Success != result) + { + return result; + } + } + base->CFG |= USART_CFG_ENABLE_MASK; + return result; +} + +/*! + * brief Enable 9-bit data mode for USART. + * + * This function set the 9-bit mode for USART module. The 9th bit is not used for parity thus can be modified by user. + * + * param base USART peripheral base address. + * param enable true to enable, false to disable. + */ +void USART_Enable9bitMode(USART_Type *base, bool enable) +{ + assert(base != NULL); + + uint32_t temp = 0U; + + if (enable) + { + /* Set USART 9-bit mode, disable parity. */ + temp = base->CFG & ~((uint32_t)USART_CFG_DATALEN_MASK | (uint32_t)USART_CFG_PARITYSEL_MASK); + temp |= (uint32_t)USART_CFG_DATALEN(0x2U); + base->CFG = temp; + } + else + { + /* Set USART to 8-bit mode. */ + base->CFG &= ~((uint32_t)USART_CFG_DATALEN_MASK); + base->CFG |= (uint32_t)USART_CFG_DATALEN(0x1U); + } +} + +/*! + * brief Transmit an address frame in 9-bit data mode. + * + * param base USART peripheral base address. + * param address USART slave address. + */ +void USART_SendAddress(USART_Type *base, uint8_t address) +{ + assert(base != NULL); + base->FIFOWR = ((uint32_t)address | 0x100UL); +} + +/*! + * brief Writes to the TX register using a blocking method. + * + * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO + * to have room and writes data to the TX buffer. + * + * param base USART peripheral base address. + * param data Start address of the data to write. + * param length Size of the data to write. + * retval kStatus_USART_Timeout Transmission timed out and was aborted. + * retval kStatus_InvalidArgument Invalid argument. + * retval kStatus_Success Successfully wrote all data. + */ +status_t USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length) +{ + /* Check arguments */ + assert(!((NULL == base) || (NULL == data))); +#if UART_RETRY_TIMES + uint32_t waitTimes; +#endif + if ((NULL == base) || (NULL == data)) + { + return kStatus_InvalidArgument; + } + /* Check whether txFIFO is enabled */ + if (0U == (base->FIFOCFG & USART_FIFOCFG_ENABLETX_MASK)) + { + return kStatus_InvalidArgument; + } + for (; length > 0U; length--) + { + /* Loop until txFIFO get some space for new data */ +#if UART_RETRY_TIMES + waitTimes = UART_RETRY_TIMES; + while ((0U == (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK)) && (--waitTimes != 0U)) +#else + while (0U == (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK)) +#endif + { + } +#if UART_RETRY_TIMES + if (0U == waitTimes) + { + return kStatus_USART_Timeout; + } +#endif + base->FIFOWR = *data; + data++; + } + /* Wait to finish transfer */ +#if UART_RETRY_TIMES + waitTimes = UART_RETRY_TIMES; + while ((0U == (base->STAT & USART_STAT_TXIDLE_MASK)) && (--waitTimes != 0U)) +#else + while (0U == (base->STAT & USART_STAT_TXIDLE_MASK)) +#endif + { + } +#if UART_RETRY_TIMES + if (0U == waitTimes) + { + return kStatus_USART_Timeout; + } +#endif + return kStatus_Success; +} + +/*! + * brief Read RX data register using a blocking method. + * + * This function polls the RX register, waits for the RX register to be full or for RX FIFO to + * have data and read data from the TX register. + * + * param base USART peripheral base address. + * param data Start address of the buffer to store the received data. + * param length Size of the buffer. + * retval kStatus_USART_FramingError Receiver overrun happened while receiving data. + * retval kStatus_USART_ParityError Noise error happened while receiving data. + * retval kStatus_USART_NoiseError Framing error happened while receiving data. + * retval kStatus_USART_RxError Overflow or underflow rxFIFO happened. + * retval kStatus_USART_Timeout Transmission timed out and was aborted. + * retval kStatus_Success Successfully received all data. + */ +status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length) +{ + uint32_t statusFlag; + status_t status = kStatus_Success; +#if UART_RETRY_TIMES + uint32_t waitTimes; +#endif + + /* check arguments */ + assert(!((NULL == base) || (NULL == data))); + if ((NULL == base) || (NULL == data)) + { + return kStatus_InvalidArgument; + } + + /* Check whether rxFIFO is enabled */ + if ((base->FIFOCFG & USART_FIFOCFG_ENABLERX_MASK) == 0U) + { + return kStatus_Fail; + } + for (; length > 0U; length--) + { + /* loop until rxFIFO have some data to read */ +#if UART_RETRY_TIMES + waitTimes = UART_RETRY_TIMES; + while (((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) == 0U) && (--waitTimes != 0U)) +#else + while ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) == 0U) +#endif + { + } +#if UART_RETRY_TIMES + if (waitTimes == 0U) + { + status = kStatus_USART_Timeout; + break; + } +#endif + /* check rxFIFO statusFlag */ + if ((base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK) != 0U) + { + base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK; + base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK; + status = kStatus_USART_RxError; + break; + } + /* check receive statusFlag */ + statusFlag = base->STAT; + /* Clear all status flags */ + base->STAT |= statusFlag; + if ((statusFlag & USART_STAT_PARITYERRINT_MASK) != 0U) + { + status = kStatus_USART_ParityError; + } + if ((statusFlag & USART_STAT_FRAMERRINT_MASK) != 0U) + { + status = kStatus_USART_FramingError; + } + if ((statusFlag & USART_STAT_RXNOISEINT_MASK) != 0U) + { + status = kStatus_USART_NoiseError; + } + + if (kStatus_Success == status) + { + *data = (uint8_t)base->FIFORD; + data++; + } + else + { + break; + } + } + return status; +} + +/*! + * brief Initializes the USART handle. + * + * This function initializes the USART handle which can be used for other USART + * transactional APIs. Usually, for a specified USART instance, + * call this API once to get the initialized handle. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + * param callback The callback function. + * param userData The parameter of the callback function. + */ +status_t USART_TransferCreateHandle(USART_Type *base, + usart_handle_t *handle, + usart_transfer_callback_t callback, + void *userData) +{ + /* Check 'base' */ + assert(!((NULL == base) || (NULL == handle))); + + uint32_t instance = 0; + usart_to_flexcomm_t handler; + handler.usart_master_handler = USART_TransferHandleIRQ; + + if ((NULL == base) || (NULL == handle)) + { + return kStatus_InvalidArgument; + } + + instance = USART_GetInstance(base); + + (void)memset(handle, 0, sizeof(*handle)); + /* Set the TX/RX state. */ + handle->rxState = (uint8_t)kUSART_RxIdle; + handle->txState = (uint8_t)kUSART_TxIdle; + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + handle->rxWatermark = (uint8_t)USART_FIFOTRIG_RXLVL_GET(base); + handle->txWatermark = (uint8_t)USART_FIFOTRIG_TXLVL_GET(base); + + FLEXCOMM_SetIRQHandler(base, handler.flexcomm_handler, handle); + + /* Enable interrupt in NVIC. */ + (void)EnableIRQ(s_usartIRQ[instance]); + + return kStatus_Success; +} + +/*! + * brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in the IRQ handler, the USART driver calls the callback + * function and passes the ref kStatus_USART_TxIdle as status parameter. + * + * note The kStatus_USART_TxIdle is passed to the upper layer when all data is written + * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX, + * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + * param xfer USART transfer structure. See #usart_transfer_t. + * retval kStatus_Success Successfully start the data transmission. + * retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer) +{ + /* Check arguments */ + assert(!((NULL == base) || (NULL == handle) || (NULL == xfer))); + if ((NULL == base) || (NULL == handle) || (NULL == xfer)) + { + return kStatus_InvalidArgument; + } + /* Check xfer members */ + assert(!((0U == xfer->dataSize) || (NULL == xfer->data))); + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* Return error if current TX busy. */ + if ((uint8_t)kUSART_TxBusy == handle->txState) + { + return kStatus_USART_TxBusy; + } + else + { + /* Disable IRQ when configuring transfer handle, in case interrupt occurs during the process and messes up the + * handle value. */ + uint32_t interruptMask = USART_GetEnabledInterrupts(base); + USART_DisableInterrupts(base, interruptMask); + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = (uint8_t)kUSART_TxBusy; + /* Enable transmiter interrupt and the previously disabled interrupt. */ + USART_EnableInterrupts(base, interruptMask | (uint32_t)kUSART_TxLevelInterruptEnable); + } + return kStatus_Success; +} + +/*! + * brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are still not sent out. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + */ +void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle) +{ + assert(NULL != handle); + + /* Disable interrupts */ + USART_DisableInterrupts(base, (uint32_t)kUSART_TxLevelInterruptEnable); + /* Empty txFIFO */ + base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK; + + handle->txDataSize = 0U; + handle->txState = (uint8_t)kUSART_TxIdle; +} + +/*! + * brief Get the number of bytes that have been sent out to bus. + * + * This function gets the number of bytes that have been sent out to bus by interrupt method. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + * param count Send bytes count. + * retval kStatus_NoTransferInProgress No send in progress. + * retval kStatus_InvalidArgument Parameter is invalid. + * retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count) +{ + assert(NULL != handle); + assert(NULL != count); + + if ((uint8_t)kUSART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - handle->txDataSize - + ((base->FIFOSTAT & USART_FIFOSTAT_TXLVL_MASK) >> USART_FIFOSTAT_TXLVL_SHIFT); + + return kStatus_Success; +} + +/*! + * brief Receives a buffer of data using an interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function, which + * returns without waiting for all data to be received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough to read, the receive + * request is saved by the USART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the USART driver notifies the upper layer + * through a callback function and passes the status parameter ref kStatus_USART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer. + * The 5 bytes are copied to the xfer->data and this function returns with the + * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is + * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to the xfer->data. When all data is received, the upper layer is notified. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + * param xfer USART transfer structure, see #usart_transfer_t. + * param receivedBytes Bytes received from the ring buffer directly. + * retval kStatus_Success Successfully queue the transfer into transmit queue. + * retval kStatus_USART_RxBusy Previous receive request is not finished. + * retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferReceiveNonBlocking(USART_Type *base, + usart_handle_t *handle, + usart_transfer_t *xfer, + size_t *receivedBytes) +{ + uint32_t i; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + uint32_t interruptMask = 0U; + + /* Check arguments */ + assert(!((NULL == base) || (NULL == handle) || (NULL == xfer))); + if ((NULL == base) || (NULL == handle) || (NULL == xfer)) + { + return kStatus_InvalidArgument; + } + /* Check xfer members */ + assert(!((0U == xfer->dataSize) || (NULL == xfer->data))); + if ((0U == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* Enable address detect when address match is enabled. */ + if ((base->CFG & (uint32_t)USART_CFG_AUTOADDR_MASK) != 0U) + { + base->CTL |= (uint32_t)USART_CTL_ADDRDET_MASK; + } + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to uart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to uart handle, receive data + to this empty space and trigger callback when finished. */ + if ((uint8_t)kUSART_RxBusy == handle->rxState) + { + return kStatus_USART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0U; + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer != NULL) + { + /* Disable IRQ, protect ring buffer. */ + interruptMask = USART_GetEnabledInterrupts(base); + USART_DisableInterrupts(base, interruptMask); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = USART_TransferGetRxRingBufferLength(handle); + if (bytesToCopy != 0U) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + bytesToReceive -= bytesToCopy; + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive != 0U) + { + /* No data in ring buffer, save the request to UART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = (uint8_t)kUSART_RxBusy; + } + /* Re-enable IRQ. */ + USART_EnableInterrupts(base, interruptMask); + /* Call user callback since all data are received. */ + if (0U == bytesToReceive) + { + if (handle->callback != NULL) + { + handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData); + } + } + } + /* Ring buffer not used. */ + else + { + /* Disable IRQ when configuring transfer handle, in case interrupt occurs during the process and messes up + * the handle value. */ + interruptMask = USART_GetEnabledInterrupts(base); + USART_DisableInterrupts(base, interruptMask); + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = (uint8_t)kUSART_RxBusy; + + /* Enable RX interrupt. */ + base->FIFOINTENSET = USART_FIFOINTENSET_RXLVL_MASK; + /* Re-enable IRQ. */ + USART_EnableInterrupts(base, interruptMask); + } + /* Return the how many bytes have read. */ + if (receivedBytes != NULL) + { + *receivedBytes = bytesCurrentReceived; + } + } + return kStatus_Success; +} + +/*! + * brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + */ +void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle) +{ + assert(NULL != handle); + + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (NULL == handle->rxRingBuffer) + { + /* Disable interrupts */ + USART_DisableInterrupts(base, (uint32_t)kUSART_RxLevelInterruptEnable); + /* Empty rxFIFO */ + base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK; + } + + handle->rxDataSize = 0U; + handle->rxState = (uint8_t)kUSART_RxIdle; +} + +/*! + * brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + * param count Receive bytes count. + * retval kStatus_NoTransferInProgress No receive in progress. + * retval kStatus_InvalidArgument Parameter is invalid. + * retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count) +{ + assert(NULL != handle); + assert(NULL != count); + + if ((uint8_t)kUSART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +/*! + * brief USART IRQ handle function. + * + * This function handles the USART transmit and receive IRQ request. + * + * param base USART peripheral base address. + * param handle USART handle pointer. + */ +void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle) +{ + /* Check arguments */ + assert((NULL != base) && (NULL != handle)); + + bool receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL)); + bool sendEnabled = (handle->txDataSize != 0U); + uint8_t rxdata; + size_t tmpsize; + + /* If RX overrun. */ + if ((base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK) != 0U) + { + /* Clear rx error state. */ + base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK; + /* clear rxFIFO */ + base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK; + /* Trigger callback. */ + if (handle->callback != NULL) + { + handle->callback(base, handle, kStatus_USART_RxError, handle->userData); + } + } + while ((receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)) || + (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U))) + { + /* Receive data */ + if (receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)) + { + /* Clear address detect when RXFIFO has data. */ + base->CTL &= ~(uint32_t)USART_CTL_ADDRDET_MASK; + /* Receive to app bufffer if app buffer is present */ + if (handle->rxDataSize != 0U) + { + rxdata = (uint8_t)base->FIFORD; + *handle->rxData = rxdata; + handle->rxDataSize--; + handle->rxData++; + receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL)); + if (0U == handle->rxDataSize) + { + if (NULL == handle->rxRingBuffer) + { + base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK; + } + handle->rxState = (uint8_t)kUSART_RxIdle; + if (handle->callback != NULL) + { + handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData); + } + } + } + /* Otherwise receive to ring buffer if ring buffer is present */ + else + { + if (handle->rxRingBuffer != NULL) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (USART_TransferIsRxRingBufferFull(handle)) + { + if (handle->callback != NULL) + { + handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData); + } + } + /* If ring buffer is still full after callback function, the oldest data is overridden. */ + if (USART_TransferIsRxRingBufferFull(handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + /* Read data. */ + rxdata = (uint8_t)base->FIFORD; + handle->rxRingBuffer[handle->rxRingBufferHead] = rxdata; + /* Increase handle->rxRingBufferHead. */ + if ((size_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + } + /* Send data */ + if (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U)) + { + base->FIFOWR = *handle->txData; + handle->txDataSize--; + handle->txData++; + sendEnabled = handle->txDataSize != 0U; + if (!sendEnabled) + { + base->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK; + + base->INTENSET = USART_INTENSET_TXIDLEEN_MASK; + } + } + } + + /* Tx idle and the interrupt is enabled. */ + if ((0U != (base->INTENSET & USART_INTENSET_TXIDLEEN_MASK)) && (0U != (base->INTSTAT & USART_INTSTAT_TXIDLE_MASK))) + { + /* Set txState to idle only when all data has been sent out to bus. */ + handle->txState = (uint8_t)kUSART_TxIdle; + /* Disable tx idle interrupt */ + base->INTENCLR = USART_INTENCLR_TXIDLECLR_MASK; + + /* Trigger callback. */ + if (handle->callback != NULL) + { + handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData); + } + } + + /* ring buffer is not used */ + if (NULL == handle->rxRingBuffer) + { + tmpsize = handle->rxDataSize; + + /* restore if rx transfer ends and rxLevel is different from default value */ + if ((tmpsize == 0U) && (USART_FIFOTRIG_RXLVL_GET(base) != handle->rxWatermark)) + { + base->FIFOTRIG = + (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | USART_FIFOTRIG_RXLVL(handle->rxWatermark); + } + /* decrease level if rx transfer is bellow */ + if ((tmpsize != 0U) && (tmpsize < (USART_FIFOTRIG_RXLVL_GET(base) + 1U))) + { + base->FIFOTRIG = (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | (USART_FIFOTRIG_RXLVL(tmpsize - 1U)); + } + } +} diff --git a/drivers/fsl_usart.h b/drivers/fsl_usart.h new file mode 100644 index 0000000..8867f27 --- /dev/null +++ b/drivers/fsl_usart.h @@ -0,0 +1,811 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_USART_H_ +#define _FSL_USART_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup usart_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief USART driver version. */ +#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 4, 0)) +/*@}*/ + +#define USART_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_TXLVL_MASK) >> USART_FIFOTRIG_TXLVL_SHIFT) +#define USART_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_RXLVL_MASK) >> USART_FIFOTRIG_RXLVL_SHIFT) + +/*! @brief Retry times for waiting flag. */ +#ifndef UART_RETRY_TIMES +#define UART_RETRY_TIMES 0U /* Defining to zero means to keep waiting for the flag until it is assert/deassert. */ +#endif + +/*! @brief Error codes for the USART driver. */ +enum +{ + kStatus_USART_TxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 0), /*!< Transmitter is busy. */ + kStatus_USART_RxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 1), /*!< Receiver is busy. */ + kStatus_USART_TxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 2), /*!< USART transmitter is idle. */ + kStatus_USART_RxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 3), /*!< USART receiver is idle. */ + kStatus_USART_TxError = MAKE_STATUS(kStatusGroup_LPC_USART, 7), /*!< Error happens on txFIFO. */ + kStatus_USART_RxError = MAKE_STATUS(kStatusGroup_LPC_USART, 9), /*!< Error happens on rxFIFO. */ + kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8), /*!< Error happens on rx ring buffer */ + kStatus_USART_NoiseError = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */ + kStatus_USART_FramingError = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */ + kStatus_USART_ParityError = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */ + kStatus_USART_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< Baudrate is not support in current clock source */ + kStatus_USART_Timeout = MAKE_STATUS(kStatusGroup_LPC_USART, 14), /*!< USART time out. */ +}; + +/*! @brief USART synchronous mode. */ +typedef enum _usart_sync_mode +{ + kUSART_SyncModeDisabled = 0x0U, /*!< Asynchronous mode. */ + kUSART_SyncModeSlave = 0x2U, /*!< Synchronous slave mode. */ + kUSART_SyncModeMaster = 0x3U, /*!< Synchronous master mode. */ +} usart_sync_mode_t; + +/*! @brief USART parity mode. */ +typedef enum _usart_parity_mode +{ + kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */ + kUSART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ + kUSART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ +} usart_parity_mode_t; + +/*! @brief USART stop bit count. */ +typedef enum _usart_stop_bit_count +{ + kUSART_OneStopBit = 0U, /*!< One stop bit */ + kUSART_TwoStopBit = 1U, /*!< Two stop bits */ +} usart_stop_bit_count_t; + +/*! @brief USART data size. */ +typedef enum _usart_data_len +{ + kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */ + kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */ +} usart_data_len_t; + +/*! @brief USART clock polarity configuration, used in sync mode.*/ +typedef enum _usart_clock_polarity +{ + kUSART_RxSampleOnFallingEdge = 0x0U, /*!< Un_RXD is sampled on the falling edge of SCLK. */ + kUSART_RxSampleOnRisingEdge = 0x1U, /*!< Un_RXD is sampled on the rising edge of SCLK. */ +} usart_clock_polarity_t; + +/*! @brief txFIFO watermark values */ +typedef enum _usart_txfifo_watermark +{ + kUSART_TxFifo0 = 0, /*!< USART tx watermark is empty */ + kUSART_TxFifo1 = 1, /*!< USART tx watermark at 1 item */ + kUSART_TxFifo2 = 2, /*!< USART tx watermark at 2 items */ + kUSART_TxFifo3 = 3, /*!< USART tx watermark at 3 items */ + kUSART_TxFifo4 = 4, /*!< USART tx watermark at 4 items */ + kUSART_TxFifo5 = 5, /*!< USART tx watermark at 5 items */ + kUSART_TxFifo6 = 6, /*!< USART tx watermark at 6 items */ + kUSART_TxFifo7 = 7, /*!< USART tx watermark at 7 items */ +} usart_txfifo_watermark_t; + +/*! @brief rxFIFO watermark values */ +typedef enum _usart_rxfifo_watermark +{ + kUSART_RxFifo1 = 0, /*!< USART rx watermark at 1 item */ + kUSART_RxFifo2 = 1, /*!< USART rx watermark at 2 items */ + kUSART_RxFifo3 = 2, /*!< USART rx watermark at 3 items */ + kUSART_RxFifo4 = 3, /*!< USART rx watermark at 4 items */ + kUSART_RxFifo5 = 4, /*!< USART rx watermark at 5 items */ + kUSART_RxFifo6 = 5, /*!< USART rx watermark at 6 items */ + kUSART_RxFifo7 = 6, /*!< USART rx watermark at 7 items */ + kUSART_RxFifo8 = 7, /*!< USART rx watermark at 8 items */ +} usart_rxfifo_watermark_t; + +/*! + * @brief USART interrupt configuration structure, default settings all disabled. + */ +enum _usart_interrupt_enable +{ + kUSART_TxErrorInterruptEnable = (USART_FIFOINTENSET_TXERR_MASK), + kUSART_RxErrorInterruptEnable = (USART_FIFOINTENSET_RXERR_MASK), + kUSART_TxLevelInterruptEnable = (USART_FIFOINTENSET_TXLVL_MASK), + kUSART_RxLevelInterruptEnable = (USART_FIFOINTENSET_RXLVL_MASK), +}; + +/*! + * @brief USART status flags. + * + * This provides constants for the USART status flags for use in the USART functions. + */ +enum _usart_flags +{ + kUSART_TxError = (USART_FIFOSTAT_TXERR_MASK), /*!< TEERR bit, sets if TX buffer is error */ + kUSART_RxError = (USART_FIFOSTAT_RXERR_MASK), /*!< RXERR bit, sets if RX buffer is error */ + kUSART_TxFifoEmptyFlag = (USART_FIFOSTAT_TXEMPTY_MASK), /*!< TXEMPTY bit, sets if TX buffer is empty */ + kUSART_TxFifoNotFullFlag = (USART_FIFOSTAT_TXNOTFULL_MASK), /*!< TXNOTFULL bit, sets if TX buffer is not full */ + kUSART_RxFifoNotEmptyFlag = (USART_FIFOSTAT_RXNOTEMPTY_MASK), /*!< RXNOEMPTY bit, sets if RX buffer is not empty */ + kUSART_RxFifoFullFlag = (USART_FIFOSTAT_RXFULL_MASK), /*!< RXFULL bit, sets if RX buffer is full */ +}; + +/*! @brief USART configuration structure. */ +typedef struct _usart_config +{ + uint32_t baudRate_Bps; /*!< USART baud rate */ + usart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + usart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ + usart_data_len_t bitCountPerChar; /*!< Data length - 7 bit, 8 bit */ + bool loopback; /*!< Enable peripheral loopback */ + bool enableRx; /*!< Enable RX */ + bool enableTx; /*!< Enable TX */ + bool enableContinuousSCLK; /*!< USART continuous Clock generation enable in synchronous master mode. */ + bool enableMode32k; /*!< USART uses 32 kHz clock from the RTC oscillator as the clock source. */ + bool enableHardwareFlowControl; /*!< Enable hardware control RTS/CTS */ + usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */ + usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */ + usart_sync_mode_t syncMode; /*!< Transfer mode select - asynchronous, synchronous master, synchronous slave. */ + usart_clock_polarity_t clockPolarity; /*!< Selects the clock polarity and sampling edge in synchronous mode. */ +} usart_config_t; + +/*! @brief USART transfer structure. */ +typedef struct _usart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} usart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _usart_handle usart_handle_t; + +/*! @brief USART transfer callback function. */ +typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData); + +/*! @brief USART handle structure. */ +struct _usart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + usart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< USART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ + + uint8_t txWatermark; /*!< txFIFO watermark */ + uint8_t rxWatermark; /*!< rxFIFO watermark */ +}; + +/*! @brief Typedef for usart interrupt handler. */ +typedef void (*flexcomm_usart_irq_handler_t)(USART_Type *base, usart_handle_t *handle); + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! @brief Returns instance number for USART peripheral base address. */ +uint32_t USART_GetInstance(USART_Type *base); + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes a USART instance with user configuration structure and peripheral clock. + * + * This function configures the USART module with the user-defined settings. The user can configure the configuration + * structure and also get the default configuration by using the USART_GetDefaultConfig() function. + * Example below shows how to use this API to configure USART. + * @code + * usart_config_t usartConfig; + * usartConfig.baudRate_Bps = 115200U; + * usartConfig.parityMode = kUSART_ParityDisabled; + * usartConfig.stopBitCount = kUSART_OneStopBit; + * USART_Init(USART1, &usartConfig, 20000000U); + * @endcode + * + * @param base USART peripheral base address. + * @param config Pointer to user-defined configuration structure. + * @param srcClock_Hz USART clock source frequency in HZ. + * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_InvalidArgument USART base address is not valid + * @retval kStatus_Success Status USART initialize succeed + */ +status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Deinitializes a USART instance. + * + * This function waits for TX complete, disables TX and RX, and disables the USART clock. + * + * @param base USART peripheral base address. + */ +void USART_Deinit(USART_Type *base); + +/*! + * @brief Gets the default configuration structure. + * + * This function initializes the USART configuration structure to a default value. The default + * values are: + * usartConfig->baudRate_Bps = 115200U; + * usartConfig->parityMode = kUSART_ParityDisabled; + * usartConfig->stopBitCount = kUSART_OneStopBit; + * usartConfig->bitCountPerChar = kUSART_8BitsPerChar; + * usartConfig->loopback = false; + * usartConfig->enableTx = false; + * usartConfig->enableRx = false; + * + * @param config Pointer to configuration structure. + */ +void USART_GetDefaultConfig(usart_config_t *config); + +/*! + * @brief Sets the USART instance baud rate. + * + * This function configures the USART module baud rate. This function is used to update + * the USART module baud rate after the USART module is initialized by the USART_Init. + * @code + * USART_SetBaudRate(USART1, 115200U, 20000000U); + * @endcode + * + * @param base USART peripheral base address. + * @param baudrate_Bps USART baudrate to be set. + * @param srcClock_Hz USART clock source frequency in HZ. + * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success Set baudrate succeed. + * @retval kStatus_InvalidArgument One or more arguments are invalid. + */ +status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Enable 32 kHz mode which USART uses clock from the RTC oscillator as the clock source + * + * Please note that in order to use a 32 kHz clock to operate USART properly, the RTC oscillator + * and its 32 kHz output must be manully enabled by user, by calling RTC_Init and setting + * SYSCON_RTCOSCCTRL_EN bit to 1. + * And in 32kHz clocking mode the USART can only work at 9600 baudrate or at the baudrate that + * 9600 can evenly divide, eg: 4800, 3200. + * + * @param base USART peripheral base address. + * @param baudRate_Bps USART baudrate to be set.. + * @param enableMode32k true is 32k mode, false is normal mode. + * @param srcClock_Hz USART clock source frequency in HZ. + * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success Set baudrate succeed. + * @retval kStatus_InvalidArgument One or more arguments are invalid. + */ +status_t USART_Enable32kMode(USART_Type *base, uint32_t baudRate_Bps, bool enableMode32k, uint32_t srcClock_Hz); + +/*! + * @brief Enable 9-bit data mode for USART. + * + * This function set the 9-bit mode for USART module. The 9th bit is not used for parity thus can be modified by user. + * + * @param base USART peripheral base address. + * @param enable true to enable, false to disable. + */ +void USART_Enable9bitMode(USART_Type *base, bool enable); + +/*! + * @brief Set the USART slave address. + * + * This function configures the address for USART module that works as slave in 9-bit data mode. When the address + * detection is enabled, the frame it receices with MSB being 1 is considered as an address frame, otherwise it is + * considered as data frame. Once the address frame matches slave's own addresses, this slave is addressed. This + * address frame and its following data frames are stored in the receive buffer, otherwise the frames will be discarded. + * To un-address a slave, just send an address frame with unmatched address. + * + * @note Any USART instance joined in the multi-slave system can work as slave. The position of the address mark is the + * same as the parity bit when parity is enabled for 8 bit and 9 bit data formats. + * + * @param base USART peripheral base address. + * @param address USART slave address. + */ +static inline void USART_SetMatchAddress(USART_Type *base, uint8_t address) +{ + /* Configure match address. */ + base->ADDR = (uint32_t)address; +} + +/*! + * @brief Enable the USART match address feature. + * + * @param base USART peripheral base address. + * @param match true to enable match address, false to disable. + */ +static inline void USART_EnableMatchAddress(USART_Type *base, bool match) +{ + /* Configure match address enable bit. */ + if (match) + { + base->CFG |= (uint32_t)USART_CFG_AUTOADDR_MASK; + base->CTL |= (uint32_t)USART_CTL_ADDRDET_MASK; + } + else + { + base->CFG &= ~(uint32_t)USART_CFG_AUTOADDR_MASK; + base->CTL &= ~(uint32_t)USART_CTL_ADDRDET_MASK; + } +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Get USART status flags. + * + * This function get all USART status flags, the flags are returned as the logical + * OR value of the enumerators @ref _usart_flags. To check a specific status, + * compare the return value with enumerators in @ref _usart_flags. + * For example, to check whether the TX is empty: + * @code + * if (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(USART1)) + * { + * ... + * } + * @endcode + * + * @param base USART peripheral base address. + * @return USART status flags which are ORed by the enumerators in the _usart_flags. + */ +static inline uint32_t USART_GetStatusFlags(USART_Type *base) +{ + return base->FIFOSTAT; +} + +/*! + * @brief Clear USART status flags. + * + * This function clear supported USART status flags + * Flags that can be cleared or set are: + * kUSART_TxError + * kUSART_RxError + * For example: + * @code + * USART_ClearStatusFlags(USART1, kUSART_TxError | kUSART_RxError) + * @endcode + * + * @param base USART peripheral base address. + * @param mask status flags to be cleared. + */ +static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask) +{ + /* Only TXERR, RXERR fields support write. Remaining fields should be set to zero */ + base->FIFOSTAT = mask & (USART_FIFOSTAT_TXERR_MASK | USART_FIFOSTAT_RXERR_MASK); +} + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables USART interrupts according to the provided mask. + * + * This function enables the USART interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref _usart_interrupt_enable. + * For example, to enable TX empty interrupt and RX full interrupt: + * @code + * USART_EnableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable); + * @endcode + * + * @param base USART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable. + */ +static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask) +{ + base->FIFOINTENSET = mask & 0xFUL; +} + +/*! + * @brief Disables USART interrupts according to a provided mask. + * + * This function disables the USART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See @ref _usart_interrupt_enable. + * This example shows how to disable the TX empty interrupt and RX full interrupt: + * @code + * USART_DisableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable); + * @endcode + * + * @param base USART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable. + */ +static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask) +{ + base->FIFOINTENCLR = mask & 0xFUL; +} + +/*! + * @brief Returns enabled USART interrupts. + * + * This function returns the enabled USART interrupts. + * + * @param base USART peripheral base address. + */ +static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base) +{ + return base->FIFOINTENSET; +} + +/*! + * @brief Enable DMA for Tx + */ +static inline void USART_EnableTxDMA(USART_Type *base, bool enable) +{ + if (enable) + { + base->FIFOCFG |= USART_FIFOCFG_DMATX_MASK; + } + else + { + base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK); + } +} + +/*! + * @brief Enable DMA for Rx + */ +static inline void USART_EnableRxDMA(USART_Type *base, bool enable) +{ + if (enable) + { + base->FIFOCFG |= USART_FIFOCFG_DMARX_MASK; + } + else + { + base->FIFOCFG &= ~(USART_FIFOCFG_DMARX_MASK); + } +} + +/*! + * @brief Enable CTS. + * This function will determine whether CTS is used for flow control. + * + * @param base USART peripheral base address. + * @param enable Enable CTS or not, true for enable and false for disable. + */ +static inline void USART_EnableCTS(USART_Type *base, bool enable) +{ + if (enable) + { + base->CFG |= USART_CFG_CTSEN_MASK; + } + else + { + base->CFG &= ~USART_CFG_CTSEN_MASK; + } +} + +/*! + * @brief Continuous Clock generation. + * By default, SCLK is only output while data is being transmitted in synchronous mode. + * Enable this funciton, SCLK will run continuously in synchronous mode, allowing + * characters to be received on Un_RxD independently from transmission on Un_TXD). + * + * @param base USART peripheral base address. + * @param enable Enable Continuous Clock generation mode or not, true for enable and false for disable. + */ +static inline void USART_EnableContinuousSCLK(USART_Type *base, bool enable) +{ + if (enable) + { + base->CTL |= USART_CTL_CC_MASK; + } + else + { + base->CTL &= ~USART_CTL_CC_MASK; + } +} + +/*! + * @brief Enable Continuous Clock generation bit auto clear. + * While enable this cuntion, the Continuous Clock bit is automatically cleared when a complete + * character has been received. This bit is cleared at the same time. + * + * @param base USART peripheral base address. + * @param enable Enable auto clear or not, true for enable and false for disable. + */ +static inline void USART_EnableAutoClearSCLK(USART_Type *base, bool enable) +{ + if (enable) + { + base->CTL |= USART_CTL_CLRCCONRX_MASK; + } + else + { + base->CTL &= ~USART_CTL_CLRCCONRX_MASK; + } +} +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Writes to the FIFOWR register. + * + * This function writes data to the txFIFO directly. The upper layer must ensure + * that txFIFO has space for data to write before calling this function. + * + * @param base USART peripheral base address. + * @param data The byte to write. + */ +static inline void USART_WriteByte(USART_Type *base, uint8_t data) +{ + base->FIFOWR = data; +} + +/*! + * @brief Reads the FIFORD register directly. + * + * This function reads data from the rxFIFO directly. The upper layer must + * ensure that the rxFIFO is not empty before calling this function. + * + * @param base USART peripheral base address. + * @return The byte read from USART data register. + */ +static inline uint8_t USART_ReadByte(USART_Type *base) +{ + return (uint8_t)base->FIFORD; +} + +/*! + * @brief Transmit an address frame in 9-bit data mode. + * + * @param base USART peripheral base address. + * @param address USART slave address. + */ +void USART_SendAddress(USART_Type *base, uint8_t address); + +/*! + * @brief Writes to the TX register using a blocking method. + * + * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO + * to have room and writes data to the TX buffer. + * + * @param base USART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the data to write. + * @retval kStatus_USART_Timeout Transmission timed out and was aborted. + * @retval kStatus_InvalidArgument Invalid argument. + * @retval kStatus_Success Successfully wrote all data. + */ +status_t USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length); + +/*! + * @brief Read RX data register using a blocking method. + * + * This function polls the RX register, waits for the RX register to be full or for RX FIFO to + * have data and read data from the TX register. + * + * @param base USART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_USART_FramingError Receiver overrun happened while receiving data. + * @retval kStatus_USART_ParityError Noise error happened while receiving data. + * @retval kStatus_USART_NoiseError Framing error happened while receiving data. + * @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened. + * @retval kStatus_USART_Timeout Transmission timed out and was aborted. + * @retval kStatus_Success Successfully received all data. + */ +status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the USART handle. + * + * This function initializes the USART handle which can be used for other USART + * transactional APIs. Usually, for a specified USART instance, + * call this API once to get the initialized handle. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param callback The callback function. + * @param userData The parameter of the callback function. + */ +status_t USART_TransferCreateHandle(USART_Type *base, + usart_handle_t *handle, + usart_transfer_callback_t callback, + void *userData); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in the IRQ handler, the USART driver calls the callback + * function and passes the @ref kStatus_USART_TxIdle as status parameter. + * + * @note The kStatus_USART_TxIdle is passed to the upper layer when all data is written + * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX, + * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param xfer USART transfer structure. See #usart_transfer_t. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific USART handle. + * + * When the RX ring buffer is used, data received are stored into the ring buffer even when the + * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * @note When using the RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize size of the ring buffer. + */ +void USART_TransferStartRingBuffer(USART_Type *base, + usart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle); + +/*! + * @brief Get the length of received data in RX ring buffer. + * + * @param handle USART handle pointer. + * @return Length of received data in RX ring buffer. + */ +size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are still not sent out. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been sent out to bus. + * + * This function gets the number of bytes that have been sent out to bus by interrupt method. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count); + +/*! + * @brief Receives a buffer of data using an interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function, which + * returns without waiting for all data to be received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough to read, the receive + * request is saved by the USART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the USART driver notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_USART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer. + * The 5 bytes are copied to the xfer->data and this function returns with the + * parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is + * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to the xfer->data. When all data is received, the upper layer is notified. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param xfer USART transfer structure, see #usart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into transmit queue. + * @retval kStatus_USART_RxBusy Previous receive request is not finished. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferReceiveNonBlocking(USART_Type *base, + usart_handle_t *handle, + usart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count); + +/*! + * @brief USART IRQ handle function. + * + * This function handles the USART transmit and receive IRQ request. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_USART_H_ */ diff --git a/lpcxpresso54114_spi_polling_b2b_transfer_master.mex b/lpcxpresso54114_spi_polling_b2b_transfer_master.mex new file mode 100644 index 0000000..3c36e03 --- /dev/null +++ b/lpcxpresso54114_spi_polling_b2b_transfer_master.mex @@ -0,0 +1,572 @@ + + + + LPC54114J256 + LPC54114J256BD64 + LPCXpresso54114 + ksdk2_0 + + + + + Configuration imported from lpcxpresso54114_spi_polling_b2b_transfer_master + + + true + false + false + true + false + + + + + + + + + 13.0.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + cm4 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 13.0.1 + + + + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + false + + + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + false + + + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + false + + + + + + + + true + + + + + INPUT + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + true + + + + + + + N/A + + + + + + + N/A + + + + + + + + N/A + + + + \ No newline at end of file diff --git a/source/AppChangeLog.txt b/source/AppChangeLog.txt new file mode 100644 index 0000000..a847931 --- /dev/null +++ b/source/AppChangeLog.txt @@ -0,0 +1,280 @@ + Changed dID response to "UM_TX_LOADER" + Trouble connecting from UM_Setup. Connects to Realterm OK. + Found that setting vcp.DtsEnable = true in C# allows connection + New problem: Data larger than 64 bytes throws semaphore exception in C# + Believe this is because of the max USB packet size in usb_device_config.h + + + +11/5/2023 - Started with TX_Loader project with USB and FLASH support + REVERT BOOTLOADER CHANGES + Changed dID response to "UM_TX" + Revert bootloader changes in ctimer_match0_callback() + Left USB_Update() call + Main.c + Removed bootloader function calls + Enabled all code from application + PROGRAM FLASH SETTINGS + Changes MCU Settings: FLASH start @ 0x10000, size 0x30000 + This gives 192kB for the Application program in FLASH + Application builds to 105kB without optimization + UM SETUP SUPPORT + Added support for pLoaderRunRequest and pClearProgramFlag + Added USB_ProcessFrequencyCommand() for handling UM Setup frequency commands + SYSTEM + Added system.c/h for system strings + + +UMTX v0.90 11/10/2023 + SYSTEM + Added SYSTEM_DATA_t struct with system data + EEPROM ISSUE + Found a conflict with the CTIMER0 interrupt - interrupts corrupt EEPROM data + Solved by stopping CTIMER0 during EEPROM data transfers + Added TMR_Start() and TMR_Start() to control the timer from eeprom.c + EEPROM + Added support for UINT32 and uint8_t[] read and write to EEPROM + Filled out eeprom.c/h + Added EE_LoadData() and EE_SaveData() + Call load on startup, call save on power down + Load / save support for system data only. + TODO: Add frequencies and operating states + UM SETUP SUPPORT + Added support for system info + +UMTX v0.91 11/11/2023 + MERGE + Pulled in Keith's changes from 10/21/23 through 11/10/23 + +UMTX v0.92 11/15/2023 + Unit to Italy, Normal running mode, 263Hz reduced. + +UMTX v0.93 11/16/2023 + Test Mode for Yao. + +UMTX v0.94 11/16/2023 + Fixed bug in Test Mode caused by 2nd DDS intermittent turn on. + +UMTX v0.95 12/06/2023 + Fixed bug in causing DDS incorrect initial power up errors. + +UMTX v0.96 12/08/2023 + Softer shut down when using clamp. Improved Overcurrent implemented. + +UMTX v1.0 12/12/2023 + Improved HV blocking HF always blocked. Over power bug fixed. + +UMTX v1.1 12/xx/2023 + MENU + ON_OFF_KEY press exits to main screen from any menu + Changed menu order so that optional menu lines are last and can be hidden easily + Updated Main menu text in MENU_Init() + Updated submenu calls in Menu_Main() + Updated menu line display in MENU_DisplayMain() + Hid Language menu (until language support is ready) + Hid Link Radio and Regulatory menus for Tx10 + Added Diagnostics screen + Added SystemInfoMenu() to control DisplaySystemInfo() and DisplayDiagnostics() + Fixed BC cycling issue. Clamp blocking fixed, Clamp overwrite of BC display fixed. + Frequency init fixed. Time delay between modes and power off improved, Taps issue fixed, + Clamp measurements removed from display. + + +UMTX v1.1b 12/xx/2023 + Fixes to Display of V,I,R. + Added additional filtering slower k factor. + Fixed divide by zero in Ohms calculation + +UMTX v1.2b 12/27/2023 + Fixed, Adc faster measurements, added catchup for power adjustment, Taps forced, + lowered trickle,current limits trimmed.System checking delayed after adjustment. + +UMTX v1.2c 12/27/2023 + Fixed ESTOP. + +UMTX v1.2d 12/28/2023 + Disabled H/W when USB connected, Reset power level to zero when switching modes, reduced + power in broadcast. + +UMTX v1.2e 01/02/2023 + Fixed USB connected during run time, fixed s/c current and power adjust after keypress. + Changed PSU sequencing when switching. + +UMTX v1.2f 01/03/2023 + Fixed stuck power increase, missing taps case, overcurrent standby in very low impedance improved. + +UMTX v1.2g 01/03/2023 + Trickle current increased, current adjust held off in PL1 + +UMTX v1.2j 01/03/2023 + AB amp limited to 500mA. + +UMTX v1.2k 01/04/2023 + Fixed step from Blocking cap transition on PL1. + +UMTX v1.2l 01/04/2023 + ADC offset fixed. + +UMTX v1.2 01/04/2024 + ADC offset fixed. + + +UMTX v1.2aa 01/05/24 + ADC + Applied current offset (was not turned on) + Remove ADC channel 9 - was USB VBUS = not used + Added voltage offset measurement at startup + Apply voltage offset in ADC_Update() + Added error detection to vos and ios measurements + ISSUE: If debugging program from running program, outputs keep running and offsets will measure them! + DIAGNOSTICS + Added voltage and current offsets + Added vos and ios measurements and error status + +UMTX v1.2ab + ADC + Updated voltage and current offsets to use OK instead of error flags + Check for +/- 30 counts from midScale (was only checking one side) + MENU + Updated to use OK flag + +UMTX v1.2ac + Checked out from new svn repo: https://yuriykc.dyndns.info:48443/svn/utility/TX/App/Trunk + Build to make sure it's all working + Had to add libpower_cm4_hardabi.a and _softabi.a + +UMTX v1.3 01/09/24 + same as v1.2ac except USB turned on in main. + + +UMTX v1.3M 02/09/24 + Updated with adc improvement plus usb additional peripherals inits removed. + Also contains Alakline battery fixes, new battery calculator for lithium. Class AB protection. + ADC_REF change. + +UMTX v1.3R 03/06/24 + Gain key lock out. PSU Monitor,Blocking cap moved,Safe output after changing hi/lo ,lo hi frequencies. + System timer fixed. Short detection sped up. + +UMTX v1.3S 03/08/24 + Improved gain handling, improved PSU monitor, improved wrap around.Updated alkaline selection. + +UMTX v1.3T 03/14/24 + Battery voltage changed, Blocking cap operation changed. PL1 on start, Clamp Dc display bug fixed. + USB plug in fixed, Error 2 fix, Error 1 fix. + +UMTX v1.3U 03/22/24 + Temporary incomplete save. + + +UMTX v1.3V 03/27/24 + System timer, fixed. Lowered current steps in HF, increased protection of AB amp. Taps bug fix. + Improved regulation. HF current measurement fixed. Frequency initial fixed. Improved display software. + +UMTX v1.3W 03/28/24 + Contains battery fix plus selectable hidden menu for recording H/w changes. + +UMTX v1.3X 04/02/24 + Contains battery life changes, updated live voltage check, updated battery eol check, updated + current demand limitation in high frequencies. +UMTX v1.3X1 04/03/24 + Contains additional menus to select between ASSY changes. + +UMTX v1.3X2 04/03/24 + Fixes battery scaling error, fixes clamp auto adjustment error. +UMTX v1.3X3 04/03/24 + Fixes 29K, amplitude, and H/W board p/n fix + +UMTX v1.3X4 04/08/24 + HF measurement fix in LOW gain, Ohms display updated to k Ohms. + +UMTX v1.6 04/09/24 + HF measurement fix in LOW gain(Not complete) , Ohms display updated to k Ohms. Not recommended for HF + due to current measurement error. + +v1.7A 04/xx/2024 + CURRENT SCALING + Changed 208023 tables to 208025 + 208023 does NOT use high frequencies and tables are almost identical up to 45k + 208023 and 208025 will both use 208025 tables + Renamed MeasureXxxCurrent208023 -> 208025 + +v1.7 04/12/24 + Updated lowcurrent table. Changes adcinit til after the splash screen, added power up delay for high voltage + adc reading. + +v1.8A 05/30/24 + Supports 200K and 132K. Allows user to cycle frequencies without forcing zero when transitioning from + High to Low frequency and vice versa. + +v1.8B 05/30/24 + Changed 132K to 132110Hz. + +v1.8C 05/31/24 + MODE Key used to toggle HI_GAIN. + +v1.8D 06/03/24 + Updated coefficient for low gain in 200KHz in 208025. +v1.8E 06/03/24 + Same as 1.8D. + +v1.8F 06/05/24 + Updated Coefficients for 131K and 200KHz. + +v1.8J 07/17/24 + Updated Coefficients for 131K and 200KHz. + +v1.8K 07/17/24 + Updated Coefficients for 131K and 200KHz. + +v1.8L 07/31/24 + Released 12K and 16K to Leica for testing purposes. + +v1.8M 08/02/24 + Released Rewrites H/W Assy number to 208025 if 208021 found in EEPROM + Released to Leica for testing purposes. + +v1.8N 09/06/24 + Default Language fix, LD disabled, TX10 changed to 10W. + +v1.8P 09/06/24 + Updated Leica P/n and System info menu and splash screen. + +v1.8R 09/09/24 + High frequency Power monitor updated. + +v1.8S 09/09/24 + High frequency Power monitor updated and Leica PN updated. +v1.9 09/09/24 + Released version of v1.8S. + +v1.9X 09/09/24 + Not released, contains updated High Voltage protection, LD but disabled, Ext 12V, 25W Enabled. + +v1.9Y 04/23/25 + Not released, contains updated High Voltage protection, LD but disabled, Ext 12V, 25W Enabled. + Updated but not complete Clamp changes. +v1.9Z 04/23/25 + Not released, contains updated High Voltage protection, LD but disabled, Ext 12V, 25W Enabled. + Updated but not complete Further updated Clamp changes. + + + DIAGNOSTICS + Added main PCBA PN to Diagnostics1 screen + HWFIXES + Changed HWF_MAX_MAIN_PCBA_PN to 208025 + +>>>>>>>>>>>>>>>>>>>>>>>>>>>> TX_App Debugging and Bootloader compatible builds <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + Debugging requires that the application be built to run at FLASH address 0 + The bootloader requires that the application be built at 0x10000 + To change this: Project > Properties > C/C++ Build > MCU Settings > + TX_App: PROGRAM_FLASH Location = 0x10000 Size = 0x30000 + TX_Loader: PROGRAM FLASH Location = 0x0 Size = 0x10000 + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + +TODO: Add support for UM Setup "pEraseAllData" command + Needs to erase all EEPROM data except the bootloader section diff --git a/source/Fonts/CalibriBoldBasic10_15h.c b/source/Fonts/CalibriBoldBasic10_15h.c new file mode 100644 index 0000000..6c755ed --- /dev/null +++ b/source/Fonts/CalibriBoldBasic10_15h.c @@ -0,0 +1,714 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: Calibri * + * Font width: 0 (proportional font) * + * Font height: 15 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 17:17 04-07-2023 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontCalibriBoldBasic10_15h; + +const UCHAR abc_fontCalibriBoldBasic10_15h_000A[ 14] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x0F, 0xD0, 0xAD, 0x4A, 0xB5, + 0x4A, 0x17, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_000D[ 14] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0020[ 6] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0021[ 8] = { /* code 0021 */ + 0x00, 0x06, 0x66, 0x66, 0x60, 0x66, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0022[ 12] = { /* code 0022 */ + 0x00, 0x00, 0x36, 0xDB, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0023[ 12] = { /* code 0023 */ + 0x00, 0x00, 0x00, 0x28, 0xAF, 0xCA, 0x53, 0xF5, + 0x14, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0024[ 14] = { /* code 0024 */ + 0x00, 0x00, 0x00, 0x87, 0x98, 0xB0, 0x38, 0x38, + 0x1A, 0x33, 0xC2, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0025[ 17] = { /* code 0025 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x24, 0xA2, 0x50, + 0xD0, 0x16, 0x14, 0x8A, 0x48, 0xC0, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0026[ 17] = { /* code 0026 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0xC1, 0xB0, 0xD8, + 0x38, 0x3D, 0x33, 0x98, 0xC7, 0xB0, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0027[ 6] = { /* code 0027 */ + 0x00, 0x6D, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0028[ 8] = { /* code 0028 */ + 0x00, 0x02, 0x64, 0xCC, 0xCC, 0xC4, 0x62, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0029[ 8] = { /* code 0029 */ + 0x00, 0x08, 0xC4, 0x66, 0x66, 0x64, 0xC8, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_002A[ 12] = { /* code 002A */ + 0x00, 0x00, 0x08, 0xA9, 0xC7, 0x2A, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_002B[ 12] = { /* code 002B */ + 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xF8, 0x82, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_002C[ 6] = { /* code 002C */ + 0x00, 0x00, 0x00, 0x01, 0xB7, 0x80 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_002D[ 8] = { /* code 002D */ + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_002E[ 6] = { /* code 002E */ + 0x00, 0x00, 0x00, 0x03, 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_002F[ 12] = { /* code 002F */ + 0x00, 0x00, 0x01, 0x08, 0x21, 0x04, 0x20, 0x84, + 0x10, 0x82, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0030[ 14] = { /* code 0030 */ + 0x00, 0x00, 0x00, 0x07, 0x99, 0xB3, 0x66, 0xCD, + 0x9B, 0x33, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0031[ 14] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x03, 0x0E, 0x2C, 0x18, 0x30, + 0x60, 0xC7, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0032[ 14] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x07, 0x91, 0x83, 0x06, 0x18, + 0x61, 0x87, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0033[ 14] = { /* code 0033 */ + 0x00, 0x00, 0x00, 0x07, 0x91, 0x83, 0x3C, 0x0C, + 0x1A, 0x33, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0034[ 14] = { /* code 0034 */ + 0x00, 0x00, 0x00, 0x03, 0x87, 0x16, 0x2C, 0x99, + 0xF8, 0x60, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0035[ 14] = { /* code 0035 */ + 0x00, 0x00, 0x00, 0x0F, 0xD8, 0x30, 0x7C, 0x0C, + 0x1A, 0x33, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0036[ 14] = { /* code 0036 */ + 0x00, 0x00, 0x00, 0x03, 0x8C, 0x30, 0x7C, 0xCD, + 0x9B, 0x33, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0037[ 14] = { /* code 0037 */ + 0x00, 0x00, 0x00, 0x0F, 0xC1, 0x86, 0x0C, 0x30, + 0x61, 0x83, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0038[ 14] = { /* code 0038 */ + 0x00, 0x00, 0x00, 0x07, 0x99, 0xB3, 0x3C, 0xCD, + 0x9B, 0x33, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0039[ 14] = { /* code 0039 */ + 0x00, 0x00, 0x00, 0x07, 0x99, 0xB3, 0x66, 0x7C, + 0x18, 0x67, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_003A[ 8] = { /* code 003A */ + 0x00, 0x00, 0x00, 0xCC, 0x00, 0xCC, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_003B[ 8] = { /* code 003B */ + 0x00, 0x00, 0x00, 0x66, 0x00, 0x66, 0x6C, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_003C[ 12] = { /* code 003C */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0x81, 0x81, + 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_003D[ 12] = { /* code 003D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x03, 0xE0, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_003E[ 12] = { /* code 003E */ + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x08, 0xCC, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_003F[ 12] = { /* code 003F */ + 0x00, 0x00, 0x1C, 0x98, 0x61, 0x9C, 0x60, 0x06, + 0x18, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0040[ 23] = { /* code 0040 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x81, + 0x04, 0x26, 0xA4, 0x9A, 0x51, 0x25, 0x32, 0x4D, + 0xC2, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0041[ 15] = { /* code 0041 */ + 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x6C, 0x6C, + 0x6C, 0xFE, 0xC6, 0xC6, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0042[ 14] = { /* code 0042 */ + 0x00, 0x00, 0x00, 0x07, 0xCC, 0xD9, 0xBE, 0x66, + 0xCD, 0x9B, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0043[ 14] = { /* code 0043 */ + 0x00, 0x00, 0x00, 0x03, 0xCC, 0x58, 0x30, 0x60, + 0xC1, 0x89, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0044[ 15] = { /* code 0044 */ + 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0045[ 12] = { /* code 0045 */ + 0x00, 0x00, 0x00, 0x7D, 0x86, 0x1F, 0x61, 0x86, + 0x1F, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0046[ 12] = { /* code 0046 */ + 0x00, 0x00, 0x00, 0x7D, 0x86, 0x1F, 0x61, 0x86, + 0x18, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0047[ 15] = { /* code 0047 */ + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x62, 0x60, 0x60, + 0x6E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0048[ 15] = { /* code 0048 */ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x7E, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0049[ 6] = { /* code 0049 */ + 0x00, 0x0D, 0xB6, 0xDB, 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_004A[ 8] = { /* code 004A */ + 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_004B[ 14] = { /* code 004B */ + 0x00, 0x00, 0x00, 0x06, 0x6D, 0x9B, 0x3C, 0x78, + 0xD9, 0xB3, 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_004C[ 12] = { /* code 004C */ + 0x00, 0x00, 0x00, 0x61, 0x86, 0x18, 0x61, 0x86, + 0x1F, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_004D[ 21] = { /* code 004D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0xE3, + 0x9C, 0x73, 0xDE, 0x6A, 0xCD, 0xD9, 0x93, 0x32, + 0x60, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_004E[ 17] = { /* code 004E */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x33, 0x99, 0xCC, + 0xD6, 0x6B, 0x33, 0x99, 0xCC, 0x60, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_004F[ 17] = { /* code 004F */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0xE3, 0x19, 0x8C, + 0xC6, 0x63, 0x31, 0x98, 0xC7, 0xC0, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0050[ 14] = { /* code 0050 */ + 0x00, 0x00, 0x00, 0x07, 0xCC, 0xD9, 0xB3, 0x7C, + 0xC1, 0x83, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0051[ 17] = { /* code 0051 */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0xE3, 0x19, 0x8C, + 0xC6, 0x63, 0x31, 0x98, 0xC7, 0xC0, 0x18, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0052[ 14] = { /* code 0052 */ + 0x00, 0x00, 0x00, 0x07, 0xCC, 0xD9, 0xBE, 0x6C, + 0xCD, 0x9B, 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0053[ 12] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x73, 0x2C, 0x3C, 0x78, 0x69, + 0x9C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0054[ 12] = { /* code 0054 */ + 0x00, 0x00, 0x00, 0xFC, 0xC3, 0x0C, 0x30, 0xC3, + 0x0C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0055[ 15] = { /* code 0055 */ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0056[ 15] = { /* code 0056 */ + 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, + 0x6C, 0x6C, 0x38, 0x38, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0057[ 23] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x3C, + 0x63, 0x6F, 0x66, 0x96, 0x69, 0x63, 0x9C, 0x30, + 0xC3, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0058[ 14] = { /* code 0058 */ + 0x00, 0x00, 0x00, 0x0C, 0x6D, 0x9B, 0x1C, 0x38, + 0xD9, 0xB6, 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0059[ 14] = { /* code 0059 */ + 0x00, 0x00, 0x00, 0x0C, 0xD9, 0x9E, 0x3C, 0x30, + 0x60, 0xC1, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_005A[ 12] = { /* code 005A */ + 0x00, 0x00, 0x00, 0xFC, 0x31, 0x8C, 0x31, 0x8C, + 0x3F, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_005B[ 8] = { /* code 005B */ + 0x00, 0x07, 0x66, 0x66, 0x66, 0x66, 0x67, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_005C[ 12] = { /* code 005C */ + 0x00, 0x00, 0x20, 0x81, 0x04, 0x08, 0x20, 0x41, + 0x02, 0x08, 0x10, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_005D[ 8] = { /* code 005D */ + 0x00, 0x0E, 0x66, 0x66, 0x66, 0x66, 0x6E, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_005E[ 12] = { /* code 005E */ + 0x00, 0x00, 0x00, 0x30, 0xC7, 0x92, 0xCC, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_005F[ 12] = { /* code 005F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xF0, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0061[ 12] = { /* code 0061 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x7B, 0x6D, + 0x9E, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0062[ 14] = { /* code 0062 */ + 0x00, 0x00, 0x06, 0x0C, 0x18, 0x3E, 0x66, 0xCD, + 0x9B, 0x37, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0063[ 10] = { /* code 0063 */ + 0x00, 0x00, 0x00, 0x01, 0xD8, 0xC6, 0x30, 0xE0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0064[ 14] = { /* code 0064 */ + 0x00, 0x00, 0x00, 0x60, 0xC1, 0x9F, 0x66, 0xCD, + 0x9B, 0x33, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0065[ 14] = { /* code 0065 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x66, 0xFD, + 0x83, 0x03, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0066[ 10] = { /* code 0066 */ + 0x00, 0x00, 0x76, 0x33, 0xCC, 0x63, 0x18, 0xC0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0067[ 12] = { /* code 0067 */ + 0x00, 0x00, 0x00, 0x00, 0x07, 0xF6, 0xD9, 0xCC, + 0x1E, 0xDB, 0xC0, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0068[ 14] = { /* code 0068 */ + 0x00, 0x00, 0x06, 0x0C, 0x18, 0x3E, 0x66, 0xCD, + 0x9B, 0x36, 0x60, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0069[ 6] = { /* code 0069 */ + 0x00, 0x6C, 0x36, 0xDB, 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_006A[ 6] = { /* code 006A */ + 0x00, 0x36, 0x1B, 0x6D, 0xB7, 0x80 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_006B[ 12] = { /* code 006B */ + 0x00, 0x00, 0x30, 0xC3, 0x0D, 0xB6, 0xF3, 0xCD, + 0xB6, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_006C[ 6] = { /* code 006C */ + 0x00, 0x6D, 0xB6, 0xDB, 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_006D[ 21] = { /* code 006D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0xE6, 0x66, 0xCC, 0xD9, 0x9B, 0x33, 0x66, + 0x60, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_006E[ 14] = { /* code 006E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x66, 0xCD, + 0x9B, 0x36, 0x60, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_006F[ 14] = { /* code 006F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x66, 0xCD, + 0x9B, 0x33, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0070[ 14] = { /* code 0070 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x66, 0xCD, + 0x9B, 0x37, 0xCC, 0x18, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0071[ 14] = { /* code 0071 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x66, 0xCD, + 0x9B, 0x33, 0xE0, 0xC1, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0072[ 10] = { /* code 0072 */ + 0x00, 0x00, 0x00, 0x03, 0xD8, 0xC6, 0x31, 0x80, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0073[ 10] = { /* code 0073 */ + 0x00, 0x00, 0x00, 0x01, 0xD8, 0xE3, 0x8D, 0xC0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0074[ 10] = { /* code 0074 */ + 0x00, 0x00, 0x06, 0x33, 0xCC, 0x63, 0x18, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0075[ 14] = { /* code 0075 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xCD, + 0x9B, 0x33, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0076[ 12] = { /* code 0076 */ + 0x00, 0x00, 0x00, 0x00, 0x0D, 0xB6, 0xD9, 0x47, + 0x1C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0077[ 19] = { /* code 0077 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, + 0x9B, 0x76, 0xD5, 0x9D, 0xC6, 0x31, 0x8C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0078[ 12] = { /* code 0078 */ + 0x00, 0x00, 0x00, 0x00, 0x0D, 0xB6, 0x71, 0xCD, + 0xB6, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0079[ 12] = { /* code 0079 */ + 0x00, 0x00, 0x00, 0x00, 0x0D, 0xB6, 0xD9, 0x47, + 0x0C, 0x61, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_007A[ 10] = { /* code 007A */ + 0x00, 0x00, 0x00, 0x03, 0xC6, 0x63, 0x31, 0xE0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_007B[ 8] = { /* code 007B */ + 0x00, 0x03, 0x66, 0x66, 0xC6, 0x66, 0x63, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_007C[ 12] = { /* code 007C */ + 0x00, 0x00, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, + 0x08, 0x20, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_007D[ 8] = { /* code 007D */ + 0x00, 0x0C, 0x66, 0x66, 0x36, 0x66, 0x6C, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_00E7[ 10] = { /* code 00E7 */ + 0x00, 0x00, 0x00, 0x01, 0xD8, 0xC6, 0x30, 0xE2, + 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_00F1[ 14] = { /* code 00F1 */ + 0x00, 0x00, 0x01, 0xA5, 0x80, 0x3E, 0x66, 0xCD, + 0x9B, 0x36, 0x60, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0438[ 14] = { /* code 0438 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB7, 0x6E, + 0xED, 0xDB, 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0439[ 14] = { /* code 0439 */ + 0x00, 0x00, 0x01, 0x11, 0xC0, 0x19, 0xB7, 0x6E, + 0xED, 0xDB, 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_043A[ 12] = { /* code 043A */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0xDB, 0x69, 0xC6, + 0x9B, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0441[ 10] = { /* code 0441 */ + 0x00, 0x00, 0x00, 0x01, 0xD9, 0xC6, 0x32, 0xE0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_0443[ 14] = { /* code 0443 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xB6, 0x6C, + 0x50, 0xE1, 0xC3, 0x06, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic10_15h_2126[ 17] = { /* code 2126 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0xE1, 0x99, 0x86, + 0xC3, 0x61, 0xB0, 0xCC, 0xCE, 0x70, 0x00, 0x00, + 0x00 +}; + +const BFC_CHARINFO fontCalibriBoldBasic10_15h_CharInfo[103] = { + { 7, 14, {abc_fontCalibriBoldBasic10_15h_000A} }, /* code 000A */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_000D} }, /* code 000D */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_0020} }, /* code 0020 */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_0021} }, /* code 0021 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0022} }, /* code 0022 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0023} }, /* code 0023 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0024} }, /* code 0024 */ + { 9, 17, {abc_fontCalibriBoldBasic10_15h_0025} }, /* code 0025 */ + { 9, 17, {abc_fontCalibriBoldBasic10_15h_0026} }, /* code 0026 */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_0027} }, /* code 0027 */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_0028} }, /* code 0028 */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_0029} }, /* code 0029 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_002A} }, /* code 002A */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_002B} }, /* code 002B */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_002C} }, /* code 002C */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_002D} }, /* code 002D */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_002E} }, /* code 002E */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_002F} }, /* code 002F */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0030} }, /* code 0030 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0031} }, /* code 0031 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0032} }, /* code 0032 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0033} }, /* code 0033 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0034} }, /* code 0034 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0035} }, /* code 0035 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0036} }, /* code 0036 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0037} }, /* code 0037 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0038} }, /* code 0038 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0039} }, /* code 0039 */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_003A} }, /* code 003A */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_003B} }, /* code 003B */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_003C} }, /* code 003C */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_003D} }, /* code 003D */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_003E} }, /* code 003E */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_003F} }, /* code 003F */ + { 12, 23, {abc_fontCalibriBoldBasic10_15h_0040} }, /* code 0040 */ + { 8, 15, {abc_fontCalibriBoldBasic10_15h_0041} }, /* code 0041 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0042} }, /* code 0042 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0043} }, /* code 0043 */ + { 8, 15, {abc_fontCalibriBoldBasic10_15h_0044} }, /* code 0044 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0045} }, /* code 0045 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0046} }, /* code 0046 */ + { 8, 15, {abc_fontCalibriBoldBasic10_15h_0047} }, /* code 0047 */ + { 8, 15, {abc_fontCalibriBoldBasic10_15h_0048} }, /* code 0048 */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_0049} }, /* code 0049 */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_004A} }, /* code 004A */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_004B} }, /* code 004B */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_004C} }, /* code 004C */ + { 11, 21, {abc_fontCalibriBoldBasic10_15h_004D} }, /* code 004D */ + { 9, 17, {abc_fontCalibriBoldBasic10_15h_004E} }, /* code 004E */ + { 9, 17, {abc_fontCalibriBoldBasic10_15h_004F} }, /* code 004F */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0050} }, /* code 0050 */ + { 9, 17, {abc_fontCalibriBoldBasic10_15h_0051} }, /* code 0051 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0052} }, /* code 0052 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0053} }, /* code 0053 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0054} }, /* code 0054 */ + { 8, 15, {abc_fontCalibriBoldBasic10_15h_0055} }, /* code 0055 */ + { 8, 15, {abc_fontCalibriBoldBasic10_15h_0056} }, /* code 0056 */ + { 12, 23, {abc_fontCalibriBoldBasic10_15h_0057} }, /* code 0057 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0058} }, /* code 0058 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0059} }, /* code 0059 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_005A} }, /* code 005A */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_005B} }, /* code 005B */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_005C} }, /* code 005C */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_005D} }, /* code 005D */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_005E} }, /* code 005E */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_005F} }, /* code 005F */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0061} }, /* code 0061 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0062} }, /* code 0062 */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_0063} }, /* code 0063 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0064} }, /* code 0064 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0065} }, /* code 0065 */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_0066} }, /* code 0066 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0067} }, /* code 0067 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0068} }, /* code 0068 */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_0069} }, /* code 0069 */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_006A} }, /* code 006A */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_006B} }, /* code 006B */ + { 3, 6, {abc_fontCalibriBoldBasic10_15h_006C} }, /* code 006C */ + { 11, 21, {abc_fontCalibriBoldBasic10_15h_006D} }, /* code 006D */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_006E} }, /* code 006E */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_006F} }, /* code 006F */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0070} }, /* code 0070 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0071} }, /* code 0071 */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_0072} }, /* code 0072 */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_0073} }, /* code 0073 */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_0074} }, /* code 0074 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0075} }, /* code 0075 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0076} }, /* code 0076 */ + { 10, 19, {abc_fontCalibriBoldBasic10_15h_0077} }, /* code 0077 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0078} }, /* code 0078 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_0079} }, /* code 0079 */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_007A} }, /* code 007A */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_007B} }, /* code 007B */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_007C} }, /* code 007C */ + { 4, 8, {abc_fontCalibriBoldBasic10_15h_007D} }, /* code 007D */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_00E7} }, /* code 00E7 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_00F1} }, /* code 00F1 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0438} }, /* code 0438 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0439} }, /* code 0439 */ + { 6, 12, {abc_fontCalibriBoldBasic10_15h_043A} }, /* code 043A */ + { 5, 10, {abc_fontCalibriBoldBasic10_15h_0441} }, /* code 0441 */ + { 7, 14, {abc_fontCalibriBoldBasic10_15h_0443} }, /* code 0443 */ + { 9, 17, {abc_fontCalibriBoldBasic10_15h_2126} } /* code 2126 */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop10 = { + 0x2126, /* first character */ + 0x2126, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 102], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop9 = { + 0x0443, /* first character */ + 0x0443, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 101], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop8 = { + 0x0441, /* first character */ + 0x0441, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 100], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop7 = { + 0x0438, /* first character */ + 0x043A, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 97], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop6 = { + 0x00F1, /* first character */ + 0x00F1, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 96], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop5 = { + 0x00E7, /* first character */ + 0x00E7, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 95], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop4 = { + 0x0061, /* first character */ + 0x007D, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 66], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop3 = { + 0x0020, /* first character */ + 0x005F, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 2], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 1], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic10_15h_Prop1 = { + 0x000A, /* first character */ + 0x000A, /* last character */ + &fontCalibriBoldBasic10_15h_CharInfo[ 0], /* address of first character */ + &fontCalibriBoldBasic10_15h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontCalibriBoldBasic10_15h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 15, /* font height in pixels */ + 12, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontCalibriBoldBasic10_15h_Prop1} +}; diff --git a/source/Fonts/CalibriBoldBasic11_18h.c b/source/Fonts/CalibriBoldBasic11_18h.c new file mode 100644 index 0000000..db8f1d1 --- /dev/null +++ b/source/Fonts/CalibriBoldBasic11_18h.c @@ -0,0 +1,766 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: Calibri * + * Font width: 0 (proportional font) * + * Font height: 18 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 17:17 04-07-2023 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontCalibriBoldBasic11_18h; + +const UCHAR abc_fontCalibriBoldBasic11_18h_000A[ 18] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x82, 0xBA, + 0x8A, 0x9A, 0x82, 0x92, 0x82, 0xFE, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_000D[ 18] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0020[ 7] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0021[ 12] = { /* code 0021 */ + 0x00, 0x00, 0x06, 0x31, 0x8C, 0x63, 0x18, 0x06, + 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0022[ 16] = { /* code 0022 */ + 0x00, 0x00, 0x00, 0x06, 0xCD, 0x9B, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0023[ 16] = { /* code 0023 */ + 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x7F, 0x24, + 0x49, 0x27, 0xF4, 0x89, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0024[ 16] = { /* code 0024 */ + 0x00, 0x00, 0x00, 0x81, 0x0F, 0x31, 0x60, 0xE0, + 0xF0, 0x70, 0x68, 0xCF, 0x08, 0x10, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0025[ 25] = { /* code 0025 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x22, + 0x24, 0x84, 0x90, 0x64, 0x01, 0x30, 0x49, 0x09, + 0x22, 0x24, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0026[ 25] = { /* code 0026 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x0C, 0xC1, 0x98, 0x1E, 0x07, 0x99, 0x9B, 0x31, + 0xC6, 0x38, 0x7D, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0027[ 9] = { /* code 0027 */ + 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0028[ 12] = { /* code 0028 */ + 0x00, 0x00, 0x01, 0x98, 0xCC, 0x63, 0x18, 0xC6, + 0x18, 0xC3, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0029[ 12] = { /* code 0029 */ + 0x00, 0x00, 0x0C, 0x31, 0x86, 0x31, 0x8C, 0x63, + 0x31, 0x98, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_002A[ 16] = { /* code 002A */ + 0x00, 0x00, 0x00, 0x01, 0x0A, 0x8E, 0x1C, 0x54, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_002B[ 16] = { /* code 002B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x11, + 0xFC, 0x40, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_002C[ 9] = { /* code 002C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6C, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_002D[ 12] = { /* code 002D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_002E[ 9] = { /* code 002E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_002F[ 14] = { /* code 002F */ + 0x00, 0x00, 0x03, 0x0C, 0x61, 0x86, 0x30, 0xC3, + 0x18, 0x61, 0x8C, 0x30, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0030[ 16] = { /* code 0030 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x33, 0x66, 0xCD, + 0x9B, 0x36, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0031[ 16] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x1C, 0x58, 0x30, + 0x60, 0xC1, 0x83, 0x1F, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0032[ 16] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x23, 0x06, 0x0C, + 0x30, 0xC3, 0x0C, 0x1F, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0033[ 16] = { /* code 0033 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x23, 0x06, 0x0C, + 0xF0, 0x30, 0x68, 0xCF, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0034[ 16] = { /* code 0034 */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x0E, 0x1C, 0x58, + 0xB2, 0x67, 0xE1, 0x83, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0035[ 16] = { /* code 0035 */ + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xB0, 0x60, 0xF8, + 0x18, 0x30, 0x68, 0xCF, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0036[ 16] = { /* code 0036 */ + 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x60, 0xF9, + 0x9B, 0x36, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0037[ 16] = { /* code 0037 */ + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x83, 0x0C, 0x18, + 0x60, 0xC1, 0x86, 0x0C, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0038[ 16] = { /* code 0038 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x33, 0x66, 0xCC, + 0xF3, 0x36, 0x6C, 0xCF, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0039[ 16] = { /* code 0039 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x33, 0x66, 0xCD, + 0x99, 0xF0, 0x61, 0x9E, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_003A[ 9] = { /* code 003A */ + 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x66, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_003B[ 9] = { /* code 003B */ + 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x66, 0x6C, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_003C[ 16] = { /* code 003C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x61, + 0x01, 0x80, 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_003D[ 16] = { /* code 003D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, + 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_003E[ 16] = { /* code 003E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0C, + 0x04, 0x31, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_003F[ 16] = { /* code 003F */ + 0x00, 0x00, 0x00, 0x03, 0x89, 0x83, 0x06, 0x38, + 0x60, 0xC0, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0040[ 30] = { /* code 0040 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xE0, 0x60, 0xC6, 0x03, 0x37, 0xDB, 0x66, + 0xDB, 0x66, 0xDB, 0x26, 0x6E, 0x30, 0x00, 0xC1, + 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0041[ 21] = { /* code 0041 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x70, + 0x6C, 0x36, 0x31, 0x98, 0xCF, 0xEC, 0x1E, 0x0C, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0042[ 18] = { /* code 0042 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, + 0x66, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0043[ 18] = { /* code 0043 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x31, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x31, 0x1E, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0044[ 21] = { /* code 0044 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE1, 0x98, + 0xC6, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x63, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0045[ 16] = { /* code 0045 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD8, 0x30, 0x60, + 0xF9, 0x83, 0x06, 0x0F, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0046[ 16] = { /* code 0046 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xD8, 0x30, 0x60, + 0xF9, 0x83, 0x06, 0x0C, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0047[ 23] = { /* code 0047 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC3, + 0x09, 0x80, 0x60, 0x19, 0xE6, 0x19, 0x86, 0x31, + 0x87, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0048[ 21] = { /* code 0048 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x8C, + 0xC6, 0x63, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0049[ 9] = { /* code 0049 */ + 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_004A[ 12] = { /* code 004A */ + 0x00, 0x00, 0x00, 0x18, 0xC6, 0x31, 0x8C, 0x63, + 0x70, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_004B[ 18] = { /* code 004B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x66, 0x66, + 0x6C, 0x78, 0x6C, 0x66, 0x66, 0x63, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_004C[ 14] = { /* code 004C */ + 0x00, 0x00, 0x00, 0x01, 0x86, 0x18, 0x61, 0x86, + 0x18, 0x61, 0xF0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_004D[ 30] = { /* code 004D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x39, 0xC1, 0xCF, 0x1E, 0x68, 0xB3, 0x6D, + 0x9B, 0x6C, 0xCA, 0x66, 0x73, 0x33, 0x98, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_004E[ 23] = { /* code 004E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x67, + 0x19, 0xE6, 0x69, 0x9B, 0x66, 0x59, 0x9E, 0x63, + 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_004F[ 23] = { /* code 004F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x83, + 0x31, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x33, + 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0050[ 18] = { /* code 0050 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, + 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0051[ 23] = { /* code 0051 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x83, + 0x31, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x33, + 0x07, 0xC0, 0x18, 0x03, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0052[ 18] = { /* code 0052 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, + 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0053[ 16] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x00, 0x07, 0x19, 0x30, 0x70, + 0x70, 0x70, 0x64, 0xC7, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0054[ 16] = { /* code 0054 */ + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x8C, 0x18, 0x30, + 0x60, 0xC1, 0x83, 0x06, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0055[ 23] = { /* code 0055 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, + 0x19, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x33, + 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0056[ 21] = { /* code 0056 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0F, 0x06, + 0xC6, 0x63, 0x31, 0x8D, 0x86, 0xC1, 0xC0, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0057[ 32] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x0C, 0x3C, 0x30, 0xF1, 0xE3, 0x67, 0x99, + 0xB3, 0x66, 0xCD, 0x8E, 0x1C, 0x38, 0x70, 0xC0, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0058[ 18] = { /* code 0058 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x66, 0x66, + 0x3C, 0x18, 0x3C, 0x66, 0x66, 0xC3, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0059[ 18] = { /* code 0059 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x66, 0x66, + 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_005A[ 16] = { /* code 005A */ + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC1, 0x86, 0x18, + 0x30, 0xC3, 0x0C, 0x1F, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_005B[ 12] = { /* code 005B */ + 0x00, 0x00, 0x07, 0x31, 0x8C, 0x63, 0x18, 0xC6, + 0x31, 0x8E, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_005C[ 14] = { /* code 005C */ + 0x00, 0x00, 0x30, 0xC1, 0x86, 0x18, 0x30, 0xC3, + 0x06, 0x18, 0x60, 0xC3, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_005D[ 12] = { /* code 005D */ + 0x00, 0x00, 0x07, 0x18, 0xC6, 0x31, 0x8C, 0x63, + 0x18, 0xCE, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_005E[ 16] = { /* code 005E */ + 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x36, 0x6D, + 0x8F, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_005F[ 16] = { /* code 005F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0061[ 16] = { /* code 0061 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x8C, + 0x19, 0xF6, 0x6C, 0xCF, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0062[ 18] = { /* code 0062 */ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x7C, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0063[ 14] = { /* code 0063 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x65, 0x86, + 0x18, 0x64, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0064[ 18] = { /* code 0064 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x3E, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0065[ 18] = { /* code 0065 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x66, 0x66, 0x7E, 0x60, 0x62, 0x3C, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0066[ 12] = { /* code 0066 */ + 0x00, 0x00, 0x03, 0xB1, 0x9E, 0x63, 0x18, 0xC6, + 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0067[ 16] = { /* code 0067 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x6C, + 0xD9, 0xB1, 0xC6, 0x07, 0x99, 0xB3, 0x3C, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0068[ 18] = { /* code 0068 */ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x7C, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0069[ 9] = { /* code 0069 */ + 0x00, 0x00, 0x66, 0x06, 0x66, 0x66, 0x66, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_006A[ 9] = { /* code 006A */ + 0x00, 0x00, 0x66, 0x06, 0x66, 0x66, 0x66, 0x66, + 0xC0 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_006B[ 16] = { /* code 006B */ + 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x33, 0x6C, + 0xF1, 0xE3, 0x66, 0xCC, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_006C[ 9] = { /* code 006C */ + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_006D[ 27] = { /* code 006D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xDC, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_006E[ 18] = { /* code 006E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_006F[ 18] = { /* code 006F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0070[ 18] = { /* code 0070 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, + 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0071[ 18] = { /* code 0071 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, + 0x06, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0072[ 12] = { /* code 0072 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x63, 0x18, 0xC6, + 0x30, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0073[ 14] = { /* code 0073 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x61, 0xC3, + 0x86, 0x19, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0074[ 12] = { /* code 0074 */ + 0x00, 0x00, 0x00, 0x31, 0x9F, 0x63, 0x18, 0xC6, + 0x1C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0075[ 18] = { /* code 0075 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0076[ 16] = { /* code 0076 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0xC6, + 0xD9, 0xB3, 0x63, 0x87, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0077[ 25] = { /* code 0077 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x23, 0xCE, 0x6D, 0xD9, 0xAB, 0x3D, + 0xE3, 0x18, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0078[ 16] = { /* code 0078 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6C, + 0xD8, 0xE3, 0x66, 0xD8, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0079[ 16] = { /* code 0079 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0xC6, + 0xD9, 0xB3, 0x63, 0x87, 0x06, 0x18, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_007A[ 14] = { /* code 007A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x18, 0xC3, + 0x0C, 0x61, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_007B[ 12] = { /* code 007B */ + 0x00, 0x00, 0x66, 0x31, 0x8C, 0x66, 0x18, 0xC6, + 0x31, 0x86, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_007C[ 16] = { /* code 007C */ + 0x00, 0x00, 0x01, 0x83, 0x06, 0x0C, 0x18, 0x30, + 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_007D[ 12] = { /* code 007D */ + 0x00, 0x00, 0xC3, 0x18, 0xC6, 0x30, 0xCC, 0x63, + 0x18, 0xCC, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_00E7[ 14] = { /* code 00E7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x65, 0x86, + 0x18, 0x64, 0xE1, 0x02, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_00F1[ 18] = { /* code 00F1 */ + 0x00, 0x00, 0x00, 0x00, 0x1A, 0x2C, 0x00, 0x7C, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0438[ 18] = { /* code 0438 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x67, 0x6F, 0x7B, 0x7B, 0x73, 0x63, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0439[ 18] = { /* code 0439 */ + 0x00, 0x00, 0x00, 0x00, 0x36, 0x1C, 0x00, 0x63, + 0x67, 0x6F, 0x7B, 0x7B, 0x73, 0x63, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_043A[ 16] = { /* code 043A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, + 0xD9, 0xE3, 0x66, 0x6C, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0441[ 14] = { /* code 0441 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x65, 0x86, + 0x18, 0x64, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_0443[ 16] = { /* code 0443 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x6C, + 0xD9, 0xB1, 0x43, 0x87, 0x04, 0x18, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic11_18h_2126[ 23] = { /* code 2126 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC3, + 0x19, 0x83, 0x60, 0xD8, 0x36, 0x0D, 0x83, 0x31, + 0x9E, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const BFC_CHARINFO fontCalibriBoldBasic11_18h_CharInfo[103] = { + { 8, 18, {abc_fontCalibriBoldBasic11_18h_000A} }, /* code 000A */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_000D} }, /* code 000D */ + { 3, 7, {abc_fontCalibriBoldBasic11_18h_0020} }, /* code 0020 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_0021} }, /* code 0021 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0022} }, /* code 0022 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0023} }, /* code 0023 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0024} }, /* code 0024 */ + { 11, 25, {abc_fontCalibriBoldBasic11_18h_0025} }, /* code 0025 */ + { 11, 25, {abc_fontCalibriBoldBasic11_18h_0026} }, /* code 0026 */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_0027} }, /* code 0027 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_0028} }, /* code 0028 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_0029} }, /* code 0029 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_002A} }, /* code 002A */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_002B} }, /* code 002B */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_002C} }, /* code 002C */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_002D} }, /* code 002D */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_002E} }, /* code 002E */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_002F} }, /* code 002F */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0030} }, /* code 0030 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0031} }, /* code 0031 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0032} }, /* code 0032 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0033} }, /* code 0033 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0034} }, /* code 0034 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0035} }, /* code 0035 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0036} }, /* code 0036 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0037} }, /* code 0037 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0038} }, /* code 0038 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0039} }, /* code 0039 */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_003A} }, /* code 003A */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_003B} }, /* code 003B */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_003C} }, /* code 003C */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_003D} }, /* code 003D */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_003E} }, /* code 003E */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_003F} }, /* code 003F */ + { 13, 30, {abc_fontCalibriBoldBasic11_18h_0040} }, /* code 0040 */ + { 9, 21, {abc_fontCalibriBoldBasic11_18h_0041} }, /* code 0041 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0042} }, /* code 0042 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0043} }, /* code 0043 */ + { 9, 21, {abc_fontCalibriBoldBasic11_18h_0044} }, /* code 0044 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0045} }, /* code 0045 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0046} }, /* code 0046 */ + { 10, 23, {abc_fontCalibriBoldBasic11_18h_0047} }, /* code 0047 */ + { 9, 21, {abc_fontCalibriBoldBasic11_18h_0048} }, /* code 0048 */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_0049} }, /* code 0049 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_004A} }, /* code 004A */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_004B} }, /* code 004B */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_004C} }, /* code 004C */ + { 13, 30, {abc_fontCalibriBoldBasic11_18h_004D} }, /* code 004D */ + { 10, 23, {abc_fontCalibriBoldBasic11_18h_004E} }, /* code 004E */ + { 10, 23, {abc_fontCalibriBoldBasic11_18h_004F} }, /* code 004F */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0050} }, /* code 0050 */ + { 10, 23, {abc_fontCalibriBoldBasic11_18h_0051} }, /* code 0051 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0052} }, /* code 0052 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0053} }, /* code 0053 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0054} }, /* code 0054 */ + { 10, 23, {abc_fontCalibriBoldBasic11_18h_0055} }, /* code 0055 */ + { 9, 21, {abc_fontCalibriBoldBasic11_18h_0056} }, /* code 0056 */ + { 14, 32, {abc_fontCalibriBoldBasic11_18h_0057} }, /* code 0057 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0058} }, /* code 0058 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0059} }, /* code 0059 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_005A} }, /* code 005A */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_005B} }, /* code 005B */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_005C} }, /* code 005C */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_005D} }, /* code 005D */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_005E} }, /* code 005E */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_005F} }, /* code 005F */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0061} }, /* code 0061 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0062} }, /* code 0062 */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_0063} }, /* code 0063 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0064} }, /* code 0064 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0065} }, /* code 0065 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_0066} }, /* code 0066 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0067} }, /* code 0067 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0068} }, /* code 0068 */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_0069} }, /* code 0069 */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_006A} }, /* code 006A */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_006B} }, /* code 006B */ + { 4, 9, {abc_fontCalibriBoldBasic11_18h_006C} }, /* code 006C */ + { 12, 27, {abc_fontCalibriBoldBasic11_18h_006D} }, /* code 006D */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_006E} }, /* code 006E */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_006F} }, /* code 006F */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0070} }, /* code 0070 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0071} }, /* code 0071 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_0072} }, /* code 0072 */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_0073} }, /* code 0073 */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_0074} }, /* code 0074 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0075} }, /* code 0075 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0076} }, /* code 0076 */ + { 11, 25, {abc_fontCalibriBoldBasic11_18h_0077} }, /* code 0077 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0078} }, /* code 0078 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0079} }, /* code 0079 */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_007A} }, /* code 007A */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_007B} }, /* code 007B */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_007C} }, /* code 007C */ + { 5, 12, {abc_fontCalibriBoldBasic11_18h_007D} }, /* code 007D */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_00E7} }, /* code 00E7 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_00F1} }, /* code 00F1 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0438} }, /* code 0438 */ + { 8, 18, {abc_fontCalibriBoldBasic11_18h_0439} }, /* code 0439 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_043A} }, /* code 043A */ + { 6, 14, {abc_fontCalibriBoldBasic11_18h_0441} }, /* code 0441 */ + { 7, 16, {abc_fontCalibriBoldBasic11_18h_0443} }, /* code 0443 */ + { 10, 23, {abc_fontCalibriBoldBasic11_18h_2126} } /* code 2126 */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop10 = { + 0x2126, /* first character */ + 0x2126, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 102], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop9 = { + 0x0443, /* first character */ + 0x0443, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 101], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop8 = { + 0x0441, /* first character */ + 0x0441, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 100], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop7 = { + 0x0438, /* first character */ + 0x043A, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 97], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop6 = { + 0x00F1, /* first character */ + 0x00F1, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 96], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop5 = { + 0x00E7, /* first character */ + 0x00E7, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 95], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop4 = { + 0x0061, /* first character */ + 0x007D, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 66], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop3 = { + 0x0020, /* first character */ + 0x005F, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 2], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 1], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic11_18h_Prop1 = { + 0x000A, /* first character */ + 0x000A, /* last character */ + &fontCalibriBoldBasic11_18h_CharInfo[ 0], /* address of first character */ + &fontCalibriBoldBasic11_18h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontCalibriBoldBasic11_18h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 18, /* font height in pixels */ + 14, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontCalibriBoldBasic11_18h_Prop1} +}; diff --git a/source/Fonts/CalibriBoldBasic12_19h.c b/source/Fonts/CalibriBoldBasic12_19h.c new file mode 100644 index 0000000..f0847ff --- /dev/null +++ b/source/Fonts/CalibriBoldBasic12_19h.c @@ -0,0 +1,2220 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: Calibri * + * Font width: 0 (proportional font) * + * Font height: 19 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 14:54 05-24-2024 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontCalibriBoldBasic12_19h; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0009[ 19] = { /* code 0009 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x81, 0xB9, + 0x8D, 0x8D, 0x89, 0x99, 0x99, 0x81, 0xFF, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_000A[ 19] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x81, 0xB9, + 0x8D, 0x8D, 0x89, 0x99, 0x99, 0x81, 0xFF, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_000D[ 22] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0020[ 10] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0021[ 12] = { /* code 0021 */ + 0x00, 0x00, 0x06, 0x31, 0x8C, 0x63, 0x18, 0xC0, + 0x31, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0022[ 17] = { /* code 0022 */ + 0x00, 0x00, 0x00, 0x06, 0xCD, 0x9B, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0023[ 19] = { /* code 0023 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, + 0xFF, 0x36, 0x6C, 0xFF, 0x6C, 0x6C, 0x6C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0024[ 19] = { /* code 0024 */ + 0x00, 0x00, 0x00, 0x18, 0x18, 0x7C, 0xFE, 0xC2, + 0xE0, 0x78, 0x3C, 0x0E, 0x86, 0xFE, 0x7C, 0x30, + 0x30, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0025[ 29] = { /* code 0025 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x0C, 0xD9, 0x8D, 0xB0, 0xDB, 0x07, 0x60, 0x0D, + 0xC1, 0xB6, 0x1B, 0x63, 0x36, 0x61, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0026[ 27] = { /* code 0026 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x0F, 0xC1, 0x98, 0x33, 0x03, 0xC0, 0xF3, 0x33, + 0x66, 0x38, 0xFF, 0xCF, 0xB8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0027[ 10] = { /* code 0027 */ + 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0028[ 12] = { /* code 0028 */ + 0x00, 0x00, 0x01, 0x98, 0xC6, 0x63, 0x18, 0xC6, + 0x30, 0xC6, 0x30, 0xC0 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0029[ 12] = { /* code 0029 */ + 0x00, 0x00, 0x0C, 0x31, 0x8C, 0x31, 0x8C, 0x63, + 0x19, 0x8C, 0x66, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_002A[ 19] = { /* code 002A */ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x54, 0x38, 0x38, + 0x54, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_002B[ 19] = { /* code 002B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, + 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_002C[ 10] = { /* code 002C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x66, + 0xC0, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_002D[ 12] = { /* code 002D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_002E[ 10] = { /* code 002E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_002F[ 17] = { /* code 002F */ + 0x00, 0x00, 0x00, 0x30, 0x61, 0x83, 0x0C, 0x18, + 0x30, 0xC1, 0x83, 0x0C, 0x18, 0x60, 0xC0, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0030[ 19] = { /* code 0030 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0xC6, + 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0x7C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0031[ 19] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x78, 0x78, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0032[ 19] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0x86, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFE, 0xFE, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0033[ 19] = { /* code 0033 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0x86, + 0x06, 0x7C, 0x7E, 0x06, 0x86, 0xFE, 0x7C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0034[ 19] = { /* code 0034 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x3C, 0x3C, + 0x6C, 0x6C, 0xCC, 0xFE, 0xFE, 0x0C, 0x0C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0035[ 19] = { /* code 0035 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xC0, + 0xC0, 0xFC, 0xFE, 0x06, 0x86, 0xFE, 0x7C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0036[ 19] = { /* code 0036 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x7E, 0xE0, + 0xC0, 0xDC, 0xFE, 0xC6, 0xC6, 0xFE, 0x7C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0037[ 19] = { /* code 0037 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x0C, + 0x0C, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0038[ 19] = { /* code 0038 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0xC6, + 0xC6, 0x7C, 0x7C, 0xC6, 0xC6, 0xFE, 0x7C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0039[ 19] = { /* code 0039 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0xC6, + 0xC6, 0xFE, 0x76, 0x06, 0x0E, 0xFC, 0xF8, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_003A[ 10] = { /* code 003A */ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x06, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_003B[ 10] = { /* code 003B */ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x06, 0x66, + 0xC0, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_003C[ 19] = { /* code 003C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1E, + 0x78, 0xE0, 0xE0, 0x78, 0x1E, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_003D[ 19] = { /* code 003D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_003E[ 19] = { /* code 003E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x78, + 0x1E, 0x07, 0x07, 0x1E, 0x78, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_003F[ 17] = { /* code 003F */ + 0x00, 0x00, 0x00, 0x07, 0x9F, 0xA3, 0x06, 0x0C, + 0x70, 0xC1, 0x80, 0x06, 0x0C, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0040[ 34] = { /* code 0040 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0x81, 0xFF, 0x0E, 0x0E, 0x37, 0xD9, + 0xBF, 0x66, 0xD9, 0x9B, 0x66, 0x6F, 0xF1, 0x9B, + 0x83, 0x00, 0x0F, 0xF0, 0x0F, 0xC0, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0041[ 24] = { /* code 0041 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, + 0xE0, 0x78, 0x33, 0x0C, 0xC6, 0x19, 0xFE, 0x7F, + 0xB0, 0x3C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0042[ 22] = { /* code 0042 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF1, 0xFC, + 0xC6, 0x63, 0x3F, 0x1F, 0xCC, 0x66, 0x33, 0xF9, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0043[ 19] = { /* code 0043 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x3F, 0x71, + 0x60, 0x60, 0x60, 0x60, 0x71, 0x3F, 0x1E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0044[ 24] = { /* code 0044 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x87, + 0xF1, 0x8E, 0x61, 0x98, 0x66, 0x19, 0x86, 0x63, + 0x9F, 0xC7, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0045[ 19] = { /* code 0045 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0046[ 17] = { /* code 0046 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xDF, 0xB0, 0x60, + 0xF9, 0xF3, 0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0047[ 24] = { /* code 0047 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC3, + 0xF9, 0xC2, 0x60, 0x19, 0xE6, 0x79, 0x86, 0x71, + 0x8F, 0xE1, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0048[ 24] = { /* code 0048 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, + 0x19, 0x86, 0x61, 0x9F, 0xE7, 0xF9, 0x86, 0x61, + 0x98, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0049[ 10] = { /* code 0049 */ + 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_004A[ 12] = { /* code 004A */ + 0x00, 0x00, 0x00, 0x18, 0xC6, 0x31, 0x8C, 0x63, + 0x7B, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_004B[ 22] = { /* code 004B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0D, 0x8E, + 0xCE, 0x6E, 0x3E, 0x1F, 0x0D, 0xC6, 0x73, 0x1D, + 0x86, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_004C[ 17] = { /* code 004C */ + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, + 0xC1, 0x83, 0x06, 0x0F, 0xDF, 0x80, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_004D[ 34] = { /* code 004D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xC0, 0xE7, 0x87, 0x9E, 0x1E, 0x6C, 0xD9, + 0xB3, 0x66, 0xCD, 0x99, 0xE6, 0x67, 0x99, 0x8C, + 0x66, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_004E[ 27] = { /* code 004E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, + 0x9E, 0x33, 0xC6, 0x6C, 0xCD, 0x99, 0x9B, 0x33, + 0x66, 0x3C, 0xC7, 0x98, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_004F[ 27] = { /* code 004F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, + 0x0F, 0xE3, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0x30, + 0x67, 0x1C, 0x7F, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0050[ 22] = { /* code 0050 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF1, 0xFC, + 0xC6, 0x63, 0x31, 0x9F, 0xCF, 0xC6, 0x03, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0051[ 27] = { /* code 0051 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, + 0x0F, 0xE3, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0x30, + 0x67, 0x1C, 0x7F, 0x07, 0xF0, 0x07, 0x00, 0x60, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0052[ 22] = { /* code 0052 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF1, 0xFC, + 0xC6, 0x63, 0x3F, 0x1F, 0x0C, 0xC6, 0x63, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0053[ 19] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x7E, 0x62, + 0x60, 0x7C, 0x3E, 0x06, 0x46, 0x7E, 0x3C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0054[ 19] = { /* code 0054 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0055[ 24] = { /* code 0055 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, + 0x19, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x73, + 0x8F, 0xC1, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0056[ 22] = { /* code 0056 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0F, 0x06, + 0xC6, 0x63, 0x31, 0x8D, 0x86, 0xC3, 0x60, 0xE0, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0057[ 36] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x20, 0xF0, 0xE1, 0xB1, 0xC6, 0x66, + 0xCC, 0xCD, 0x98, 0xDB, 0x61, 0xE3, 0xC3, 0xC7, + 0x83, 0x06, 0x06, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0058[ 22] = { /* code 0058 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x8C, + 0x6C, 0x36, 0x0E, 0x07, 0x06, 0xC3, 0x63, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0059[ 19] = { /* code 0059 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0x66, + 0x66, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_005A[ 19] = { /* code 005A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, + 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_005B[ 12] = { /* code 005B */ + 0x00, 0x00, 0x07, 0x39, 0x8C, 0x63, 0x18, 0xC6, + 0x31, 0x8C, 0x73, 0x80 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_005C[ 17] = { /* code 005C */ + 0x00, 0x00, 0x06, 0x0C, 0x0C, 0x18, 0x30, 0x30, + 0x60, 0x60, 0xC1, 0x81, 0x83, 0x03, 0x06, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_005D[ 12] = { /* code 005D */ + 0x00, 0x00, 0x07, 0x38, 0xC6, 0x31, 0x8C, 0x63, + 0x18, 0xC6, 0x73, 0x80 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_005E[ 19] = { /* code 005E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x6C, + 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_005F[ 19] = { /* code 005F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0061[ 19] = { /* code 0061 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0062[ 22] = { /* code 0062 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x01, 0x80, + 0xC0, 0x6E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF9, + 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0063[ 17] = { /* code 0063 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0xF9, 0x83, 0x06, 0x0F, 0x8F, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0064[ 22] = { /* code 0064 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, + 0x06, 0x3B, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0065[ 19] = { /* code 0065 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3C, 0x7E, 0x66, 0x7E, 0x60, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0066[ 12] = { /* code 0066 */ + 0x00, 0x00, 0x03, 0xBD, 0x8C, 0xFF, 0xD8, 0xC6, + 0x31, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0067[ 19] = { /* code 0067 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0x66, 0x66, 0x66, 0x3C, 0x60, 0x3E, 0x63, + 0x63, 0x3E, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0068[ 22] = { /* code 0068 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x01, 0x80, + 0xC0, 0x6E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0069[ 10] = { /* code 0069 */ + 0x00, 0x00, 0x06, 0x60, 0x66, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_006A[ 10] = { /* code 006A */ + 0x00, 0x00, 0x06, 0x60, 0x66, 0x66, 0x66, 0x66, + 0xEC, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_006B[ 19] = { /* code 006B */ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, + 0x63, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x63, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_006C[ 10] = { /* code 006C */ + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_006D[ 31] = { /* code 006D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xC3, 0xFF, + 0x19, 0x98, 0xCC, 0xC6, 0x66, 0x33, 0x31, 0x99, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_006E[ 22] = { /* code 006E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_006F[ 22] = { /* code 006F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0070[ 22] = { /* code 0070 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF9, + 0xB8, 0xC0, 0x60, 0x30, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0071[ 22] = { /* code 0071 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3B, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xEC, 0x06, 0x03, 0x01, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0072[ 15] = { /* code 0072 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xF6, + 0x18, 0x61, 0x86, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0073[ 15] = { /* code 0073 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xE6, + 0x0C, 0x19, 0xE7, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0074[ 15] = { /* code 0074 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0xFB, 0xE6, + 0x18, 0x61, 0xE3, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0075[ 22] = { /* code 0075 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0076[ 19] = { /* code 0076 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC3, 0xC3, 0x66, 0x66, 0x3C, 0x3C, 0x18, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0077[ 29] = { /* code 0077 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC6, 0x3C, 0x63, 0x6F, + 0x66, 0xF6, 0x39, 0xC3, 0x9C, 0x19, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0078[ 17] = { /* code 0078 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, + 0xD9, 0xB1, 0xC6, 0xCD, 0xB1, 0x80, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0079[ 19] = { /* code 0079 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC3, 0xC3, 0x66, 0x66, 0x3C, 0x3C, 0x18, 0x18, + 0x30, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_007A[ 15] = { /* code 007A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xE1, + 0x8C, 0x61, 0xE7, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_007B[ 15] = { /* code 007B */ + 0x00, 0x00, 0x00, 0x18, 0xE3, 0x0C, 0x30, 0xC6, + 0x18, 0x30, 0xC3, 0x0C, 0x38, 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_007C[ 19] = { /* code 007C */ + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_007D[ 15] = { /* code 007D */ + 0x00, 0x00, 0x00, 0x61, 0xC3, 0x0C, 0x30, 0xC1, + 0x86, 0x30, 0xC3, 0x0C, 0x71, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C1[ 24] = { /* code 00C1 */ + 0x00, 0x01, 0x80, 0xC0, 0x20, 0x00, 0x03, 0x01, + 0xE0, 0x78, 0x33, 0x0C, 0xC6, 0x19, 0xFE, 0x7F, + 0xB0, 0x3C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C4[ 24] = { /* code 00C4 */ + 0x00, 0x00, 0x03, 0x30, 0xCC, 0x00, 0x03, 0x01, + 0xE0, 0x78, 0x33, 0x0C, 0xC6, 0x19, 0xFE, 0x7F, + 0xB0, 0x3C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C5[ 24] = { /* code 00C5 */ + 0x00, 0x00, 0x01, 0xC0, 0x50, 0x1C, 0x03, 0x01, + 0xE0, 0x78, 0x33, 0x0C, 0xC6, 0x19, 0xFE, 0x7F, + 0xB0, 0x3C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C6[ 29] = { /* code 00C6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x0F, 0xF1, 0xB0, 0x1B, 0x03, 0x3E, 0x33, + 0xE7, 0xF0, 0x7F, 0x0C, 0x3F, 0xC3, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C7[ 19] = { /* code 00C7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x3F, 0x71, + 0x60, 0x60, 0x60, 0x60, 0x71, 0x3F, 0x1E, 0x08, + 0x0C, 0x18, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C8[ 19] = { /* code 00C8 */ + 0x00, 0x30, 0x18, 0x08, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00C9[ 19] = { /* code 00C9 */ + 0x00, 0x0C, 0x18, 0x10, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00CA[ 19] = { /* code 00CA */ + 0x00, 0x08, 0x1C, 0x36, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00CD[ 10] = { /* code 00CD */ + 0x03, 0x64, 0x06, 0x66, 0x66, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00D3[ 27] = { /* code 00D3 */ + 0x00, 0x00, 0x60, 0x18, 0x02, 0x00, 0x00, 0x3E, + 0x0F, 0xE3, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0x30, + 0x67, 0x1C, 0x7F, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00D5[ 27] = { /* code 00D5 */ + 0x00, 0x01, 0x90, 0x7E, 0x09, 0x80, 0x00, 0x3E, + 0x0F, 0xE3, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0x30, + 0x67, 0x1C, 0x7F, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00DC[ 24] = { /* code 00DC */ + 0x00, 0x00, 0x03, 0x30, 0xCC, 0x00, 0x18, 0x66, + 0x19, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x73, + 0x8F, 0xC1, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E1[ 19] = { /* code 00E1 */ + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x10, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E2[ 19] = { /* code 00E2 */ + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E3[ 19] = { /* code 00E3 */ + 0x00, 0x00, 0x00, 0x00, 0x32, 0x7E, 0x4C, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E4[ 19] = { /* code 00E4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E5[ 19] = { /* code 00E5 */ + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x14, 0x1C, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E7[ 17] = { /* code 00E7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0xF9, 0x83, 0x06, 0x0F, 0x8F, 0x08, 0x18, 0x60, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E8[ 19] = { /* code 00E8 */ + 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x08, 0x00, + 0x3C, 0x7E, 0x66, 0x7E, 0x60, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00E9[ 19] = { /* code 00E9 */ + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x10, 0x00, + 0x3C, 0x7E, 0x66, 0x7E, 0x60, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00EA[ 19] = { /* code 00EA */ + 0x00, 0x00, 0x00, 0x00, 0x08, 0x1C, 0x36, 0x00, + 0x3C, 0x7E, 0x66, 0x7E, 0x60, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00ED[ 10] = { /* code 00ED */ + 0x00, 0x00, 0x36, 0x40, 0x66, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00EE[ 12] = { /* code 00EE */ + 0x00, 0x00, 0x02, 0x3B, 0x60, 0x63, 0x18, 0xC6, + 0x31, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00F1[ 22] = { /* code 00F1 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x91, 0xF8, 0x98, + 0x00, 0x6E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00F3[ 22] = { /* code 00F3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x20, + 0x00, 0x3E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00F6[ 22] = { /* code 00F6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0xD8, + 0x00, 0x3E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00FA[ 22] = { /* code 00FA */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x20, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00FC[ 22] = { /* code 00FC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0xD8, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_00FD[ 19] = { /* code 00FD */ + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x10, 0x00, + 0xC3, 0xC3, 0x66, 0x66, 0x3C, 0x3C, 0x18, 0x18, + 0x30, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0101[ 19] = { /* code 0101 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x3E, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0102[ 27] = { /* code 0102 */ + 0x00, 0x01, 0x10, 0x22, 0x03, 0x80, 0x00, 0x1C, + 0x02, 0x80, 0xD8, 0x1B, 0x02, 0x30, 0xC6, 0x1F, + 0xC7, 0xFC, 0xC1, 0x98, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0103[ 19] = { /* code 0103 */ + 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x1C, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0104[ 27] = { /* code 0104 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x03, 0xC0, 0xD8, 0x1B, 0x06, 0x30, 0xC6, 0x1F, + 0xC7, 0xFC, 0xC1, 0x98, 0x30, 0x06, 0x00, 0xC0, + 0x18, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0105[ 19] = { /* code 0105 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x06, + 0x0C, 0x0E, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_010C[ 19] = { /* code 010C */ + 0x00, 0x36, 0x36, 0x1C, 0x00, 0x1E, 0x3F, 0x71, + 0x60, 0x60, 0x60, 0x60, 0x71, 0x3F, 0x1E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_010D[ 17] = { /* code 010D */ + 0x00, 0x00, 0x00, 0x03, 0xE3, 0x83, 0x00, 0x1C, + 0x7D, 0x8B, 0x06, 0x2F, 0xCF, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0112[ 19] = { /* code 0112 */ + 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0113[ 19] = { /* code 0113 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x3E, 0x00, + 0x1E, 0x3F, 0x63, 0x7F, 0x60, 0x7F, 0x1F, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0118[ 19] = { /* code 0118 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x0C, + 0x0C, 0x0E, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0119[ 19] = { /* code 0119 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1E, 0x3F, 0x63, 0x7F, 0x60, 0x7F, 0x3F, 0x06, + 0x0C, 0x0F, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_011B[ 19] = { /* code 011B */ + 0x00, 0x00, 0x00, 0x00, 0x3E, 0x1C, 0x0C, 0x00, + 0x1E, 0x3F, 0x63, 0x7F, 0x60, 0x7F, 0x1F, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_012A[ 12] = { /* code 012A */ + 0x00, 0x3F, 0xF0, 0x31, 0x8C, 0x63, 0x18, 0xC6, + 0x31, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_012B[ 12] = { /* code 012B */ + 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x63, 0x18, 0xC6, + 0x31, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_012F[ 10] = { /* code 012F */ + 0x00, 0x00, 0x06, 0x60, 0x66, 0x66, 0x66, 0x6E, + 0xCE, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_013C[ 10] = { /* code 013C */ + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, + 0x6C, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0142[ 10] = { /* code 0142 */ + 0x00, 0x00, 0x66, 0x67, 0xFE, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0151[ 22] = { /* code 0151 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0xB1, 0xB8, 0x98, + 0x00, 0x1E, 0x1F, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0159[ 15] = { /* code 0159 */ + 0x00, 0x00, 0x00, 0x7C, 0xE1, 0x80, 0x79, 0xE6, + 0x18, 0x61, 0x86, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_015A[ 19] = { /* code 015A */ + 0x00, 0x0C, 0x08, 0x18, 0x00, 0x3C, 0x7E, 0x62, + 0x70, 0x3C, 0x1F, 0x03, 0x43, 0x7F, 0x3C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_015B[ 15] = { /* code 015B */ + 0x00, 0x00, 0x00, 0x0C, 0x21, 0x80, 0x3D, 0xF6, + 0x0E, 0x0D, 0xF7, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0161[ 15] = { /* code 0161 */ + 0x00, 0x00, 0x00, 0x6C, 0xE1, 0x00, 0x39, 0xE6, + 0x0C, 0x19, 0xE7, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0173[ 22] = { /* code 0173 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xF8, + 0xEC, 0x06, 0x06, 0x03, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_017B[ 19] = { /* code 017B */ + 0x00, 0x00, 0x18, 0x18, 0x00, 0xFE, 0xFE, 0x06, + 0x0C, 0x18, 0x30, 0x60, 0x40, 0xFE, 0xFE, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_017C[ 15] = { /* code 017C */ + 0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x7D, 0xF1, + 0x8C, 0x61, 0xF7, 0xC0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_017D[ 19] = { /* code 017D */ + 0x00, 0x36, 0x1C, 0x08, 0x00, 0xFF, 0xFF, 0x07, + 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_017E[ 15] = { /* code 017E */ + 0x00, 0x00, 0x00, 0x6C, 0xE1, 0x00, 0x79, 0xE1, + 0x8C, 0x61, 0xE7, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_021A[ 19] = { /* code 021A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_021B[ 15] = { /* code 021B */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0xFB, 0xE6, + 0x18, 0x61, 0xE3, 0x80, 0x31, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0388[ 22] = { /* code 0388 */ + 0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0xFF, 0x7E, + 0x30, 0x18, 0x0F, 0x87, 0xC3, 0x01, 0x80, 0xFC, + 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_038C[ 29] = { /* code 038C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0E, + 0x7C, 0xDF, 0xE1, 0x87, 0x30, 0x33, 0x03, 0x30, + 0x33, 0x03, 0x38, 0x61, 0xFE, 0x0F, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0391[ 27] = { /* code 0391 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x02, 0x80, 0xD8, 0x1B, 0x02, 0x30, 0xC6, 0x1F, + 0xC7, 0xFC, 0xC1, 0x98, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0393[ 17] = { /* code 0393 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xDF, 0xB0, 0x60, + 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0394[ 22] = { /* code 0394 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x70, + 0x2C, 0x36, 0x1B, 0x08, 0xCC, 0x66, 0x33, 0xF9, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0395[ 19] = { /* code 0395 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0397[ 24] = { /* code 0397 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, + 0x19, 0x86, 0x61, 0x9F, 0xE7, 0xF9, 0x86, 0x61, + 0x98, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0398[ 27] = { /* code 0398 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x0F, 0xF1, 0x87, 0x60, 0x6D, 0xED, 0xBD, 0xB0, + 0x37, 0x0C, 0x7F, 0x87, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0399[ 10] = { /* code 0399 */ + 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_039A[ 22] = { /* code 039A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x98, + 0xDC, 0x6C, 0x3C, 0x1F, 0x0D, 0x86, 0x63, 0x31, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_039B[ 24] = { /* code 039B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, + 0xE0, 0x58, 0x36, 0x0D, 0xC3, 0x31, 0x8C, 0x61, + 0x98, 0x6E, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_039C[ 34] = { /* code 039C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xC0, 0xE7, 0x87, 0x9E, 0x1E, 0x6C, 0xD9, + 0xB3, 0x66, 0xCD, 0x99, 0xE6, 0x67, 0x99, 0x9C, + 0x66, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_039D[ 27] = { /* code 039D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, + 0x1E, 0x63, 0xCC, 0x69, 0x8D, 0xB1, 0xB6, 0x33, + 0xC6, 0x78, 0xC7, 0x18, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_039F[ 27] = { /* code 039F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x0F, 0xF1, 0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, + 0x37, 0x0C, 0x7F, 0x87, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A0[ 24] = { /* code 03A0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE7, + 0xF9, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x61, + 0x98, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A1[ 22] = { /* code 03A1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF1, 0xFC, + 0xC6, 0x63, 0x3F, 0x9F, 0x0C, 0x06, 0x03, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A3[ 19] = { /* code 03A3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x70, + 0x18, 0x0C, 0x1C, 0x38, 0x70, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A4[ 19] = { /* code 03A4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A5[ 19] = { /* code 03A5 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xE7, 0x66, + 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A6[ 31] = { /* code 03A6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x0F, 0xC1, 0xFF, 0x8C, 0xCE, 0xC6, 0x36, 0x31, + 0xB1, 0x8D, 0x8C, 0x6E, 0x66, 0x3F, 0xF0, 0x7E, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A7[ 22] = { /* code 03A7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0xDC, + 0x6C, 0x36, 0x0E, 0x07, 0x06, 0xC3, 0x63, 0x1B, + 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03A9[ 27] = { /* code 03A9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, + 0x33, 0x0C, 0xF3, 0xDE, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03AC[ 22] = { /* code 03AC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x60, + 0x00, 0x7B, 0x7F, 0xB1, 0x98, 0xCC, 0x67, 0xFD, + 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03AD[ 17] = { /* code 03AD */ + 0x00, 0x00, 0x00, 0x00, 0xC3, 0x86, 0x00, 0x3E, + 0xFD, 0x81, 0xE6, 0x0F, 0xCF, 0x80, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03AE[ 22] = { /* code 03AE */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x60, + 0x00, 0x7E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x19, + 0x8C, 0x06, 0x03, 0x01, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03AF[ 12] = { /* code 03AF */ + 0x00, 0x00, 0x03, 0x39, 0x80, 0x63, 0x18, 0xC6, + 0x3C, 0xE0, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B1[ 22] = { /* code 03B1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7B, 0x7F, 0xB1, 0x98, 0xCC, 0x67, 0xFD, + 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B3[ 17] = { /* code 03B3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, + 0x8D, 0x9B, 0x66, 0xC7, 0x0C, 0x18, 0x30, 0x60, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B4[ 22] = { /* code 03B4 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0xE1, 0xF0, 0xC0, + 0x30, 0x3E, 0x33, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B5[ 17] = { /* code 03B5 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, + 0xFD, 0x81, 0xE6, 0x0F, 0xCF, 0x80, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B7[ 22] = { /* code 03B7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x19, + 0x8C, 0x06, 0x03, 0x01, 0x80, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B8[ 22] = { /* code 03B8 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0xC1, 0xF1, 0x8C, + 0xC6, 0x7F, 0x3F, 0x98, 0xCC, 0x67, 0x71, 0xF0, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03B9[ 12] = { /* code 03B9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x18, 0xC6, + 0x3C, 0xE0, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03BA[ 19] = { /* code 03BA */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x6C, 0x7C, 0x78, 0x6C, 0x6C, 0x66, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03BB[ 19] = { /* code 03BB */ + 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF8, 0x18, 0x18, + 0x1C, 0x3C, 0x3C, 0x6E, 0x66, 0xC7, 0xC3, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03BC[ 22] = { /* code 03BC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xFD, + 0xFE, 0xC0, 0x60, 0x30, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03BD[ 19] = { /* code 03BD */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x66, 0x66, 0x36, 0x36, 0x3C, 0x1C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03BF[ 22] = { /* code 03BF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1E, 0x1F, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C0[ 22] = { /* code 03C0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xD9, 0x8C, 0xC6, 0x63, 0x3F, + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C1[ 19] = { /* code 03C1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x7F, 0x63, 0x63, 0x63, 0x7F, 0x7E, 0x60, + 0x60, 0x60, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C2[ 17] = { /* code 03C2 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, + 0x7D, 0x83, 0x07, 0x0F, 0x87, 0x83, 0x06, 0x18, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C3[ 22] = { /* code 03C3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0x9F, 0xD8, 0x8C, 0x66, 0x33, 0xF8, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C4[ 15] = { /* code 03C4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, + 0x0C, 0x30, 0xE1, 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C5[ 22] = { /* code 03C5 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C6[ 27] = { /* code 03C6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0C, + 0x01, 0x80, 0x30, 0x1F, 0x87, 0xF9, 0x99, 0xB3, + 0x36, 0x66, 0x7F, 0x87, 0xE0, 0x30, 0x06, 0x00, + 0xC0, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C7[ 17] = { /* code 03C7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, + 0xCD, 0xF1, 0xE3, 0x87, 0x1E, 0x36, 0xEF, 0x8C, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03C9[ 27] = { /* code 03C9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xCC, 0x0D, 0x99, 0xB3, + 0x36, 0x66, 0xFF, 0xCE, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03CC[ 22] = { /* code 03CC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x60, + 0x00, 0x1E, 0x1F, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03CD[ 22] = { /* code 03CD */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x60, + 0x00, 0x63, 0x31, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_03CE[ 27] = { /* code 03CE */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0E, + 0x01, 0x80, 0x00, 0x30, 0xCC, 0x0D, 0x99, 0xB3, + 0x36, 0x66, 0xFF, 0xCE, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0410[ 27] = { /* code 0410 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x02, 0x80, 0xD8, 0x1B, 0x02, 0x30, 0xC6, 0x1F, + 0xC7, 0xFC, 0xC1, 0x98, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0412[ 22] = { /* code 0412 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE1, 0xF8, + 0xCC, 0x66, 0x3E, 0x1F, 0x8C, 0x66, 0x33, 0xF9, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0413[ 17] = { /* code 0413 */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xDF, 0xB0, 0x60, + 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0414[ 27] = { /* code 0414 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0x07, 0xE1, 0xCC, 0x31, 0x86, 0x30, 0xC6, 0x18, + 0xC6, 0x19, 0xFF, 0xBF, 0xF6, 0x06, 0xC0, 0xD8, + 0x18, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0415[ 19] = { /* code 0415 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x60, + 0x60, 0x7C, 0x7C, 0x60, 0x60, 0x7E, 0x7E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0417[ 19] = { /* code 0417 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0x86, + 0x06, 0x7C, 0x7C, 0x06, 0x86, 0xFE, 0x78, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0418[ 24] = { /* code 0418 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, + 0x39, 0x8E, 0x67, 0x9B, 0x66, 0xD9, 0xE6, 0x71, + 0x9C, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0419[ 24] = { /* code 0419 */ + 0x00, 0x00, 0x01, 0x98, 0x3C, 0x00, 0x18, 0x66, + 0x39, 0x8E, 0x67, 0x9B, 0x66, 0xD9, 0xE6, 0x71, + 0x9C, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_041A[ 22] = { /* code 041A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x8C, + 0xCC, 0x66, 0x3E, 0x1F, 0x0C, 0xC6, 0x63, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_041B[ 24] = { /* code 041B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE1, + 0xF8, 0x66, 0x19, 0x8E, 0x63, 0x18, 0xC6, 0x71, + 0xB8, 0x6E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_041C[ 34] = { /* code 041C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xC0, 0xE7, 0x87, 0x9E, 0x1E, 0x6C, 0xD9, + 0xB3, 0x66, 0xCD, 0x99, 0xE6, 0x67, 0x99, 0x9C, + 0x66, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_041D[ 24] = { /* code 041D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, + 0x19, 0x86, 0x61, 0x9F, 0xE7, 0xF9, 0x86, 0x61, + 0x98, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_041E[ 27] = { /* code 041E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x0F, 0xF1, 0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, + 0x37, 0x0C, 0x7F, 0x87, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_041F[ 24] = { /* code 041F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE7, + 0xF9, 0x86, 0x61, 0x98, 0x66, 0x19, 0x86, 0x61, + 0x98, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0420[ 22] = { /* code 0420 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF1, 0xFC, + 0xC6, 0x63, 0x3F, 0x9F, 0x0C, 0x06, 0x03, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0421[ 19] = { /* code 0421 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x3F, 0x71, + 0x60, 0x60, 0x60, 0x60, 0x71, 0x3F, 0x1E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0422[ 19] = { /* code 0422 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0423[ 22] = { /* code 0423 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1D, 0x8C, + 0xC6, 0x36, 0x1B, 0x07, 0x03, 0x81, 0xC3, 0xC1, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0424[ 29] = { /* code 0424 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x1F, 0x83, 0xFC, 0x76, 0xE6, 0x66, 0x66, + 0x67, 0x6E, 0x3F, 0xC1, 0xF8, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0426[ 27] = { /* code 0426 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, + 0x18, 0x63, 0x0C, 0x61, 0x8C, 0x31, 0x86, 0x30, + 0xC6, 0x18, 0xFF, 0x9F, 0xF0, 0x06, 0x00, 0xC0, + 0x18, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0427[ 22] = { /* code 0427 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x19, 0x8C, + 0xC6, 0x63, 0x3F, 0x8F, 0xC0, 0x60, 0x30, 0x18, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_042B[ 31] = { /* code 042B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x19, 0x80, 0xCC, 0x06, 0x7E, 0x33, 0xF9, + 0x98, 0xCC, 0xC6, 0x66, 0x33, 0x3F, 0x19, 0xF0, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_042F[ 22] = { /* code 042F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFE, + 0xC3, 0x61, 0x9F, 0xC7, 0xE7, 0x33, 0x1B, 0x8D, + 0x86, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0430[ 19] = { /* code 0430 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7C, 0x7E, 0x06, 0x3E, 0x66, 0x7E, 0x3E, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0432[ 19] = { /* code 0432 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7C, 0x7E, 0x66, 0x7C, 0x66, 0x7E, 0x7C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0433[ 15] = { /* code 0433 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xF6, + 0x18, 0x61, 0x86, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0434[ 22] = { /* code 0434 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0x1F, 0x8C, 0xCE, 0x66, 0x37, 0xFF, + 0xFF, 0x83, 0xC1, 0xE0, 0xC0, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0435[ 19] = { /* code 0435 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1E, 0x3F, 0x63, 0x7F, 0x60, 0x7F, 0x1F, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0436[ 29] = { /* code 0436 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC6, 0x36, 0x66, 0x3F, + 0xC3, 0xFC, 0x66, 0x6E, 0x67, 0xC6, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0437[ 17] = { /* code 0437 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, + 0xF8, 0x33, 0xC0, 0xDF, 0xBE, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0438[ 22] = { /* code 0438 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x33, 0x9B, 0xCF, 0x67, 0xB3, 0x99, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0439[ 22] = { /* code 0439 */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x31, 0x98, 0x78, + 0x00, 0x63, 0x33, 0x9B, 0xCF, 0x67, 0xB3, 0x99, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_043A[ 19] = { /* code 043A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0x66, 0x7C, 0x7E, 0x66, 0x67, 0x63, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_043B[ 19] = { /* code 043B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x3E, 0x36, 0x36, 0x66, 0xE6, 0xC6, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_043C[ 27] = { /* code 043C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x71, 0xCE, 0x39, 0xEF, 0x3D, + 0xE6, 0xAC, 0xDD, 0x9B, 0xB0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_043D[ 22] = { /* code 043D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x63, 0x31, 0x9F, 0xCF, 0xE6, 0x33, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_043E[ 22] = { /* code 043E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1E, 0x1F, 0x98, 0xCC, 0x66, 0x33, 0xF0, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_043F[ 22] = { /* code 043F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0x19, + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0440[ 22] = { /* code 0440 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7E, 0x3F, 0x98, 0xCC, 0x66, 0x33, 0xF9, + 0xF8, 0xC0, 0x60, 0x30, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0441[ 17] = { /* code 0441 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x7D, 0x8B, 0x06, 0x2F, 0xCF, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0442[ 15] = { /* code 0442 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, + 0x0C, 0x30, 0xC3, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0443[ 19] = { /* code 0443 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE7, 0x66, 0x66, 0x36, 0x34, 0x1C, 0x1C, 0x18, + 0x18, 0x30, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0444[ 27] = { /* code 0444 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x18, + 0x03, 0x00, 0x60, 0x3F, 0x0F, 0xF3, 0x33, 0x66, + 0x6C, 0xCC, 0xFF, 0x0F, 0xC0, 0x60, 0x0C, 0x01, + 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_0447[ 19] = { /* code 0447 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xCC, 0xCC, 0xCC, 0xFC, 0x7C, 0x0C, 0x0C, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_044B[ 27] = { /* code 044B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0xCC, 0x19, 0xF3, 0x3F, + 0x66, 0x6C, 0xFD, 0x9F, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_044F[ 19] = { /* code 044F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0xFE, 0xC6, 0xFE, 0x7E, 0x66, 0xC6, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_2116[ 41] = { /* code 2116 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x8C, 0x01, 0xE6, 0x78, 0xF3, + 0x7E, 0x79, 0xB3, 0x36, 0xD9, 0x9B, 0x6F, 0xCC, + 0xF3, 0xC6, 0x78, 0x03, 0x1D, 0xF9, 0x8E, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic12_19h_2126[ 27] = { /* code 2126 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, + 0x33, 0x0C, 0xF3, 0xDE, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const BFC_CHARINFO fontCalibriBoldBasic12_19h_CharInfo[252] = { + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0009} }, /* code 0009 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_000A} }, /* code 000A */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_000D} }, /* code 000D */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_0020} }, /* code 0020 */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_0021} }, /* code 0021 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0022} }, /* code 0022 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0023} }, /* code 0023 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0024} }, /* code 0024 */ + { 12, 29, {abc_fontCalibriBoldBasic12_19h_0025} }, /* code 0025 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0026} }, /* code 0026 */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_0027} }, /* code 0027 */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_0028} }, /* code 0028 */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_0029} }, /* code 0029 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_002A} }, /* code 002A */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_002B} }, /* code 002B */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_002C} }, /* code 002C */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_002D} }, /* code 002D */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_002E} }, /* code 002E */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_002F} }, /* code 002F */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0030} }, /* code 0030 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0031} }, /* code 0031 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0032} }, /* code 0032 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0033} }, /* code 0033 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0034} }, /* code 0034 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0035} }, /* code 0035 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0036} }, /* code 0036 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0037} }, /* code 0037 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0038} }, /* code 0038 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0039} }, /* code 0039 */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_003A} }, /* code 003A */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_003B} }, /* code 003B */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_003C} }, /* code 003C */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_003D} }, /* code 003D */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_003E} }, /* code 003E */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_003F} }, /* code 003F */ + { 14, 34, {abc_fontCalibriBoldBasic12_19h_0040} }, /* code 0040 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0041} }, /* code 0041 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0042} }, /* code 0042 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0043} }, /* code 0043 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0044} }, /* code 0044 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0045} }, /* code 0045 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0046} }, /* code 0046 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0047} }, /* code 0047 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0048} }, /* code 0048 */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_0049} }, /* code 0049 */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_004A} }, /* code 004A */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_004B} }, /* code 004B */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_004C} }, /* code 004C */ + { 14, 34, {abc_fontCalibriBoldBasic12_19h_004D} }, /* code 004D */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_004E} }, /* code 004E */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_004F} }, /* code 004F */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0050} }, /* code 0050 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0051} }, /* code 0051 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0052} }, /* code 0052 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0053} }, /* code 0053 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0054} }, /* code 0054 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0055} }, /* code 0055 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0056} }, /* code 0056 */ + { 15, 36, {abc_fontCalibriBoldBasic12_19h_0057} }, /* code 0057 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0058} }, /* code 0058 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0059} }, /* code 0059 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_005A} }, /* code 005A */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_005B} }, /* code 005B */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_005C} }, /* code 005C */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_005D} }, /* code 005D */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_005E} }, /* code 005E */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_005F} }, /* code 005F */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0061} }, /* code 0061 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0062} }, /* code 0062 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0063} }, /* code 0063 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0064} }, /* code 0064 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0065} }, /* code 0065 */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_0066} }, /* code 0066 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0067} }, /* code 0067 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0068} }, /* code 0068 */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_0069} }, /* code 0069 */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_006A} }, /* code 006A */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_006B} }, /* code 006B */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_006C} }, /* code 006C */ + { 13, 31, {abc_fontCalibriBoldBasic12_19h_006D} }, /* code 006D */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_006E} }, /* code 006E */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_006F} }, /* code 006F */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0070} }, /* code 0070 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0071} }, /* code 0071 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0072} }, /* code 0072 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0073} }, /* code 0073 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0074} }, /* code 0074 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0075} }, /* code 0075 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0076} }, /* code 0076 */ + { 12, 29, {abc_fontCalibriBoldBasic12_19h_0077} }, /* code 0077 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0078} }, /* code 0078 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0079} }, /* code 0079 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_007A} }, /* code 007A */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_007B} }, /* code 007B */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_007C} }, /* code 007C */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_007D} }, /* code 007D */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_00C1} }, /* code 00C1 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_00C4} }, /* code 00C4 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_00C5} }, /* code 00C5 */ + { 12, 29, {abc_fontCalibriBoldBasic12_19h_00C6} }, /* code 00C6 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00C7} }, /* code 00C7 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00C8} }, /* code 00C8 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00C9} }, /* code 00C9 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00CA} }, /* code 00CA */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_00CD} }, /* code 00CD */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_00D3} }, /* code 00D3 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_00D5} }, /* code 00D5 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_00DC} }, /* code 00DC */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E1} }, /* code 00E1 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E2} }, /* code 00E2 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E3} }, /* code 00E3 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E4} }, /* code 00E4 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E5} }, /* code 00E5 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_00E7} }, /* code 00E7 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E8} }, /* code 00E8 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00E9} }, /* code 00E9 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00EA} }, /* code 00EA */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_00ED} }, /* code 00ED */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_00EE} }, /* code 00EE */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_00F1} }, /* code 00F1 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_00F3} }, /* code 00F3 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_00F6} }, /* code 00F6 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_00FA} }, /* code 00FA */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_00FC} }, /* code 00FC */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_00FD} }, /* code 00FD */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0101} }, /* code 0101 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0102} }, /* code 0102 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0103} }, /* code 0103 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0104} }, /* code 0104 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0105} }, /* code 0105 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_010C} }, /* code 010C */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_010D} }, /* code 010D */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0112} }, /* code 0112 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0113} }, /* code 0113 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0118} }, /* code 0118 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0119} }, /* code 0119 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_011B} }, /* code 011B */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_012A} }, /* code 012A */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_012B} }, /* code 012B */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_012F} }, /* code 012F */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_013C} }, /* code 013C */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_0142} }, /* code 0142 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0151} }, /* code 0151 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0159} }, /* code 0159 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_015A} }, /* code 015A */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_015B} }, /* code 015B */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0161} }, /* code 0161 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0173} }, /* code 0173 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_017B} }, /* code 017B */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_017C} }, /* code 017C */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_017D} }, /* code 017D */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_017E} }, /* code 017E */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_021A} }, /* code 021A */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_021B} }, /* code 021B */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0388} }, /* code 0388 */ + { 12, 29, {abc_fontCalibriBoldBasic12_19h_038C} }, /* code 038C */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0391} }, /* code 0391 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0393} }, /* code 0393 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0394} }, /* code 0394 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0395} }, /* code 0395 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0397} }, /* code 0397 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0398} }, /* code 0398 */ + { 4, 10, {abc_fontCalibriBoldBasic12_19h_0399} }, /* code 0399 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_039A} }, /* code 039A */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_039B} }, /* code 039B */ + { 14, 34, {abc_fontCalibriBoldBasic12_19h_039C} }, /* code 039C */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_039D} }, /* code 039D */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_039F} }, /* code 039F */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_03A0} }, /* code 03A0 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03A1} }, /* code 03A1 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03A3} }, /* code 03A3 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03A4} }, /* code 03A4 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03A5} }, /* code 03A5 */ + { 13, 31, {abc_fontCalibriBoldBasic12_19h_03A6} }, /* code 03A6 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03A7} }, /* code 03A7 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_03A9} }, /* code 03A9 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03AC} }, /* code 03AC */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_03AD} }, /* code 03AD */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03AE} }, /* code 03AE */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_03AF} }, /* code 03AF */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03B1} }, /* code 03B1 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_03B3} }, /* code 03B3 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03B4} }, /* code 03B4 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_03B5} }, /* code 03B5 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03B7} }, /* code 03B7 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03B8} }, /* code 03B8 */ + { 5, 12, {abc_fontCalibriBoldBasic12_19h_03B9} }, /* code 03B9 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03BA} }, /* code 03BA */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03BB} }, /* code 03BB */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03BC} }, /* code 03BC */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03BD} }, /* code 03BD */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03BF} }, /* code 03BF */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03C0} }, /* code 03C0 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_03C1} }, /* code 03C1 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_03C2} }, /* code 03C2 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03C3} }, /* code 03C3 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_03C4} }, /* code 03C4 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03C5} }, /* code 03C5 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_03C6} }, /* code 03C6 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_03C7} }, /* code 03C7 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_03C9} }, /* code 03C9 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03CC} }, /* code 03CC */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_03CD} }, /* code 03CD */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_03CE} }, /* code 03CE */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0410} }, /* code 0410 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0412} }, /* code 0412 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0413} }, /* code 0413 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0414} }, /* code 0414 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0415} }, /* code 0415 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0417} }, /* code 0417 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0418} }, /* code 0418 */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_0419} }, /* code 0419 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_041A} }, /* code 041A */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_041B} }, /* code 041B */ + { 14, 34, {abc_fontCalibriBoldBasic12_19h_041C} }, /* code 041C */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_041D} }, /* code 041D */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_041E} }, /* code 041E */ + { 10, 24, {abc_fontCalibriBoldBasic12_19h_041F} }, /* code 041F */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0420} }, /* code 0420 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0421} }, /* code 0421 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0422} }, /* code 0422 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0423} }, /* code 0423 */ + { 12, 29, {abc_fontCalibriBoldBasic12_19h_0424} }, /* code 0424 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0426} }, /* code 0426 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0427} }, /* code 0427 */ + { 13, 31, {abc_fontCalibriBoldBasic12_19h_042B} }, /* code 042B */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_042F} }, /* code 042F */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0430} }, /* code 0430 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0432} }, /* code 0432 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0433} }, /* code 0433 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0434} }, /* code 0434 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0435} }, /* code 0435 */ + { 12, 29, {abc_fontCalibriBoldBasic12_19h_0436} }, /* code 0436 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0437} }, /* code 0437 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0438} }, /* code 0438 */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0439} }, /* code 0439 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_043A} }, /* code 043A */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_043B} }, /* code 043B */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_043C} }, /* code 043C */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_043D} }, /* code 043D */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_043E} }, /* code 043E */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_043F} }, /* code 043F */ + { 9, 22, {abc_fontCalibriBoldBasic12_19h_0440} }, /* code 0440 */ + { 7, 17, {abc_fontCalibriBoldBasic12_19h_0441} }, /* code 0441 */ + { 6, 15, {abc_fontCalibriBoldBasic12_19h_0442} }, /* code 0442 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0443} }, /* code 0443 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_0444} }, /* code 0444 */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_0447} }, /* code 0447 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_044B} }, /* code 044B */ + { 8, 19, {abc_fontCalibriBoldBasic12_19h_044F} }, /* code 044F */ + { 17, 41, {abc_fontCalibriBoldBasic12_19h_2116} }, /* code 2116 */ + { 11, 27, {abc_fontCalibriBoldBasic12_19h_2126} } /* code 2126 */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop60 = { + 0x2126, /* first character */ + 0x2126, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 251], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop59 = { + 0x2116, /* first character */ + 0x2116, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 250], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop60 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop58 = { + 0x044F, /* first character */ + 0x044F, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 249], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop59 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop57 = { + 0x044B, /* first character */ + 0x044B, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 248], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop58 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop56 = { + 0x0447, /* first character */ + 0x0447, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 247], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop57 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop55 = { + 0x0432, /* first character */ + 0x0444, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 228], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop56 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop54 = { + 0x042F, /* first character */ + 0x0430, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 226], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop55 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop53 = { + 0x042B, /* first character */ + 0x042B, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 225], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop54 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop52 = { + 0x0426, /* first character */ + 0x0427, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 223], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop53 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop51 = { + 0x0417, /* first character */ + 0x0424, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 209], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop52 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop50 = { + 0x0412, /* first character */ + 0x0415, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 205], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop51 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop49 = { + 0x0410, /* first character */ + 0x0410, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 204], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop50 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop48 = { + 0x03CC, /* first character */ + 0x03CE, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 201], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop49 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop47 = { + 0x03C9, /* first character */ + 0x03C9, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 200], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop48 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop46 = { + 0x03BF, /* first character */ + 0x03C7, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 191], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop47 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop45 = { + 0x03B7, /* first character */ + 0x03BD, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 184], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop46 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop44 = { + 0x03B3, /* first character */ + 0x03B5, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 181], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop45 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop43 = { + 0x03B1, /* first character */ + 0x03B1, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 180], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop44 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop42 = { + 0x03AC, /* first character */ + 0x03AF, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 176], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop43 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop41 = { + 0x03A9, /* first character */ + 0x03A9, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 175], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop42 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop40 = { + 0x03A3, /* first character */ + 0x03A7, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 170], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop41 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop39 = { + 0x039F, /* first character */ + 0x03A1, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 167], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop40 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop38 = { + 0x0397, /* first character */ + 0x039D, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 160], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop39 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop37 = { + 0x0393, /* first character */ + 0x0395, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 157], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop38 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop36 = { + 0x0391, /* first character */ + 0x0391, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 156], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop37 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop35 = { + 0x038C, /* first character */ + 0x038C, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 155], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop36 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop34 = { + 0x0388, /* first character */ + 0x0388, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 154], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop35 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop33 = { + 0x021A, /* first character */ + 0x021B, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 152], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop34 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop32 = { + 0x017B, /* first character */ + 0x017E, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 148], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop33 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop31 = { + 0x0173, /* first character */ + 0x0173, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 147], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop32 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop30 = { + 0x0161, /* first character */ + 0x0161, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 146], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop31 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop29 = { + 0x0159, /* first character */ + 0x015B, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 143], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop30 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop28 = { + 0x0151, /* first character */ + 0x0151, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 142], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop29 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop27 = { + 0x0142, /* first character */ + 0x0142, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 141], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop28 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop26 = { + 0x013C, /* first character */ + 0x013C, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 140], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop27 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop25 = { + 0x012F, /* first character */ + 0x012F, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 139], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop26 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop24 = { + 0x012A, /* first character */ + 0x012B, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 137], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop25 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop23 = { + 0x011B, /* first character */ + 0x011B, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 136], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop24 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop22 = { + 0x0118, /* first character */ + 0x0119, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 134], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop23 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop21 = { + 0x0112, /* first character */ + 0x0113, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 132], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop22 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop20 = { + 0x010C, /* first character */ + 0x010D, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 130], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop21 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop19 = { + 0x0101, /* first character */ + 0x0105, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 125], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop20 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop18 = { + 0x00FC, /* first character */ + 0x00FD, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 123], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop19 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop17 = { + 0x00FA, /* first character */ + 0x00FA, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 122], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop18 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop16 = { + 0x00F6, /* first character */ + 0x00F6, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 121], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop17 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop15 = { + 0x00F3, /* first character */ + 0x00F3, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 120], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop16 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop14 = { + 0x00F1, /* first character */ + 0x00F1, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 119], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop15 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop13 = { + 0x00ED, /* first character */ + 0x00EE, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 117], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop14 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop12 = { + 0x00E7, /* first character */ + 0x00EA, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 113], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop13 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop11 = { + 0x00E1, /* first character */ + 0x00E5, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 108], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop12 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop10 = { + 0x00DC, /* first character */ + 0x00DC, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 107], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop11 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop9 = { + 0x00D5, /* first character */ + 0x00D5, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 106], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop8 = { + 0x00D3, /* first character */ + 0x00D3, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 105], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop7 = { + 0x00CD, /* first character */ + 0x00CD, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 104], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop6 = { + 0x00C4, /* first character */ + 0x00CA, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 97], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop5 = { + 0x00C1, /* first character */ + 0x00C1, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 96], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop4 = { + 0x0061, /* first character */ + 0x007D, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 67], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop3 = { + 0x0020, /* first character */ + 0x005F, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 3], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 2], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic12_19h_Prop1 = { + 0x0009, /* first character */ + 0x000A, /* last character */ + &fontCalibriBoldBasic12_19h_CharInfo[ 0], /* address of first character */ + &fontCalibriBoldBasic12_19h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontCalibriBoldBasic12_19h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 19, /* font height in pixels */ + 15, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontCalibriBoldBasic12_19h_Prop1} +}; diff --git a/source/Fonts/CalibriBoldBasic14_23h.c b/source/Fonts/CalibriBoldBasic14_23h.c new file mode 100644 index 0000000..832c51c --- /dev/null +++ b/source/Fonts/CalibriBoldBasic14_23h.c @@ -0,0 +1,912 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: Calibri * + * Font width: 0 (proportional font) * + * Font height: 23 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 17:16 04-07-2023 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontCalibriBoldBasic14_23h; + +const UCHAR abc_fontCalibriBoldBasic14_23h_000A[ 29] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFA, 0x02, 0xBC, 0xA1, 0xA8, 0x6A, 0x1A, 0x9C, + 0xA0, 0x29, 0x8A, 0x62, 0x80, 0xBF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_000D[ 29] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0020[ 12] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0021[ 18] = { /* code 0021 */ + 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0C, 0x30, 0xC3, + 0x0C, 0x30, 0xC3, 0x00, 0x30, 0xC0, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0022[ 23] = { /* code 0022 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0x6C, + 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0023[ 26] = { /* code 0023 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, + 0x66, 0x33, 0x7F, 0xFF, 0xE6, 0x66, 0x67, 0xFF, + 0xFE, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0024[ 29] = { /* code 0024 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x81, + 0xF0, 0xFE, 0x60, 0x98, 0x07, 0x00, 0xF0, 0x0F, + 0x00, 0xE0, 0x19, 0x06, 0x7F, 0x0F, 0x81, 0x80, + 0x60, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0025[ 41] = { /* code 0025 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x83, 0x33, 0x18, 0xCC, 0x63, + 0x33, 0x0C, 0xD8, 0x1E, 0xC0, 0x03, 0x78, 0x1B, + 0x30, 0xCC, 0xC6, 0x33, 0x18, 0xCC, 0xC1, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0026[ 38] = { /* code 0026 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x80, 0xFE, 0x06, 0x30, 0x31, 0x81, 0xDC, + 0x07, 0xC0, 0x7C, 0x67, 0x73, 0x31, 0xD9, 0x87, + 0x8E, 0x1C, 0x3F, 0xF8, 0xF8, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0027[ 12] = { /* code 0027 */ + 0x00, 0x00, 0x06, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0028[ 18] = { /* code 0028 */ + 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x31, 0x86, + 0x18, 0x61, 0x86, 0x18, 0x60, 0xC3, 0x0C, 0x18, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0029[ 18] = { /* code 0029 */ + 0x00, 0x00, 0x00, 0x01, 0x83, 0x0C, 0x30, 0x61, + 0x86, 0x18, 0x61, 0x86, 0x18, 0xC3, 0x0C, 0x60, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_002A[ 26] = { /* code 002A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x68, + 0xEC, 0x18, 0x3B, 0x16, 0x83, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_002B[ 26] = { /* code 002B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0C, 0x06, 0x03, 0x0F, 0xF7, 0xF8, + 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_002C[ 15] = { /* code 002C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x31, 0x8C, 0xC6, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_002D[ 18] = { /* code 002D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_002E[ 15] = { /* code 002E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_002F[ 23] = { /* code 002F */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x06, + 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x18, 0x30, 0x30, + 0x60, 0x60, 0x60, 0xC0, 0xC0, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0030[ 29] = { /* code 0030 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xE0, 0xFC, 0x73, 0x98, 0x66, 0x19, 0x86, 0x61, + 0x98, 0x66, 0x19, 0xCE, 0x3F, 0x07, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0031[ 29] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC0, 0xF0, 0x7C, 0x13, 0x00, 0xC0, 0x30, 0x0C, + 0x03, 0x00, 0xC0, 0x30, 0x7F, 0x9F, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0032[ 29] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xE1, 0xFC, 0x43, 0x00, 0xC0, 0x30, 0x18, 0x06, + 0x03, 0x01, 0x80, 0xC0, 0x7F, 0x9F, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0033[ 29] = { /* code 0033 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xE1, 0xFC, 0x43, 0x00, 0xC0, 0x30, 0xF8, 0x3E, + 0x00, 0xC0, 0x31, 0x0C, 0x7F, 0x0F, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0034[ 29] = { /* code 0034 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x3C, 0x0B, 0x06, 0xC3, 0x30, 0xCC, 0x63, + 0x1F, 0xE7, 0xF8, 0x0C, 0x03, 0x00, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0035[ 29] = { /* code 0035 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xF1, 0xFC, 0x60, 0x18, 0x07, 0xE1, 0xFC, 0x03, + 0x80, 0x60, 0x19, 0x0E, 0x7F, 0x0F, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0036[ 29] = { /* code 0036 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0xFC, 0x30, 0x18, 0x06, 0xE1, 0xFC, 0x73, + 0x98, 0x66, 0x19, 0xCE, 0x3F, 0x07, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0037[ 29] = { /* code 0037 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xF9, 0xFE, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0E, + 0x03, 0x01, 0xC0, 0x60, 0x38, 0x0C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0038[ 29] = { /* code 0038 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xF1, 0xFE, 0x61, 0x98, 0x67, 0x30, 0xF8, 0x1F, + 0x0C, 0xE6, 0x19, 0x86, 0x7F, 0x8F, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0039[ 29] = { /* code 0039 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xE0, 0xFC, 0x73, 0x98, 0x66, 0x19, 0xCE, 0x3F, + 0x87, 0x60, 0x18, 0x0C, 0x7F, 0x1F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_003A[ 15] = { /* code 003A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xC0, + 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_003B[ 15] = { /* code 003B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xC0, + 0x00, 0x00, 0x63, 0x19, 0x8C, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_003C[ 26] = { /* code 003C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x03, 0x87, 0x8F, 0x06, 0x03, 0xC0, + 0x78, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_003D[ 26] = { /* code 003D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xDF, 0xE0, 0x00, 0x03, + 0xFD, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_003E[ 26] = { /* code 003E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x38, 0x0F, 0x01, 0xE0, 0x30, 0x78, + 0xF0, 0xE0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_003F[ 26] = { /* code 003F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE1, 0xF8, + 0x8E, 0x03, 0x01, 0x81, 0xC3, 0xC1, 0x80, 0xC0, + 0x00, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0040[ 49] = { /* code 0040 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1F, + 0xFC, 0x1C, 0x06, 0x1C, 0xD9, 0x8C, 0xFC, 0xCC, + 0xCE, 0x66, 0x66, 0x33, 0x33, 0x39, 0x9F, 0xF8, + 0xC7, 0x78, 0x70, 0x00, 0x1C, 0x08, 0x07, 0xFC, + 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0041[ 35] = { /* code 0041 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0E, 0x00, 0xE0, 0x1B, 0x01, 0xB0, 0x1B, + 0x03, 0x18, 0x31, 0x87, 0xFC, 0x7F, 0xC6, 0x0C, + 0xC0, 0x6C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0042[ 32] = { /* code 0042 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xE3, 0xFE, 0x60, 0xCC, 0x19, 0x83, 0x3F, + 0xC7, 0xFC, 0xC1, 0x98, 0x33, 0x06, 0x7F, 0xCF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0043[ 29] = { /* code 0043 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0x30, 0x58, 0x06, 0x01, 0x80, 0x60, + 0x18, 0x06, 0x00, 0xC1, 0x3F, 0xC3, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0044[ 35] = { /* code 0044 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0x07, 0xFC, 0x60, 0xC6, 0x06, 0x60, + 0x66, 0x06, 0x60, 0x66, 0x06, 0x60, 0x66, 0x0C, + 0x7F, 0xC7, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0045[ 26] = { /* code 0045 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, + 0xFE, 0x60, 0x30, 0x18, 0x0F, 0xC7, 0xE3, 0x01, + 0x80, 0xC0, 0x7F, 0x3F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0046[ 26] = { /* code 0046 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, + 0xFE, 0x60, 0x30, 0x18, 0x0F, 0xC7, 0xE3, 0x01, + 0x80, 0xC0, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0047[ 35] = { /* code 0047 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xC3, 0xFE, 0x30, 0x26, 0x00, 0x60, + 0x06, 0x3E, 0x63, 0xE6, 0x06, 0x60, 0x63, 0x06, + 0x3F, 0xE0, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0048[ 35] = { /* code 0048 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x66, 0x06, 0x60, 0x66, 0x06, 0x60, + 0x67, 0xFE, 0x7F, 0xE6, 0x06, 0x60, 0x66, 0x06, + 0x60, 0x66, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0049[ 15] = { /* code 0049 */ + 0x00, 0x00, 0x00, 0x01, 0x8C, 0x63, 0x18, 0xC6, + 0x31, 0x8C, 0x63, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_004A[ 18] = { /* code 004A */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x18, 0x61, + 0x86, 0x18, 0x61, 0xA6, 0xF9, 0xC0, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_004B[ 29] = { /* code 004B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x0D, 0x87, 0x63, 0x99, 0xC6, 0xE1, 0xF0, 0x7C, + 0x1B, 0x86, 0x71, 0x9C, 0x63, 0x98, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_004C[ 23] = { /* code 004C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_004D[ 49] = { /* code 004D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x38, 0xE0, + 0x1C, 0x78, 0x1E, 0x3C, 0x0F, 0x1B, 0x0D, 0x8D, + 0x86, 0xC6, 0x66, 0x63, 0x33, 0x31, 0x8F, 0x18, + 0xC7, 0x8C, 0x61, 0x86, 0x30, 0xC3, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_004E[ 38] = { /* code 004E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xC0, 0xCF, 0x06, 0x78, 0x33, 0x61, + 0x9B, 0x8C, 0xCC, 0x66, 0x33, 0x31, 0xD9, 0x86, + 0xCC, 0x1E, 0x60, 0xF3, 0x03, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_004F[ 38] = { /* code 004F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3E, 0x07, 0xFC, 0x30, 0x63, 0x01, + 0x98, 0x0C, 0xC0, 0x66, 0x03, 0x30, 0x19, 0x80, + 0xC6, 0x0C, 0x3F, 0xE0, 0x7C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0050[ 29] = { /* code 0050 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xE1, 0xFC, 0x63, 0x98, 0x66, 0x19, 0x8E, 0x7F, + 0x1F, 0x86, 0x01, 0x80, 0x60, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0051[ 38] = { /* code 0051 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3E, 0x07, 0xFC, 0x30, 0x63, 0x01, + 0x98, 0x0C, 0xC0, 0x66, 0x03, 0x30, 0x19, 0x80, + 0xC6, 0x0C, 0x3F, 0xC0, 0x7F, 0x00, 0x1E, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0052[ 32] = { /* code 0052 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xC3, 0xFC, 0x61, 0x8C, 0x31, 0x86, 0x3F, + 0x87, 0xE0, 0xC6, 0x18, 0x63, 0x0C, 0x60, 0xCC, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0053[ 26] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x7E, 0x61, 0x30, 0x1C, 0x07, 0x81, 0xE0, 0x38, + 0x0C, 0x86, 0x7E, 0x1E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0054[ 26] = { /* code 0054 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFD, + 0xFE, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, + 0x60, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0055[ 35] = { /* code 0055 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x66, 0x06, 0x60, 0x66, 0x06, 0x60, + 0x66, 0x06, 0x60, 0x66, 0x06, 0x60, 0x67, 0x0E, + 0x3F, 0xC1, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0056[ 32] = { /* code 0056 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x1E, 0x03, 0x60, 0xCC, 0x19, 0x83, 0x18, + 0xC3, 0x18, 0x36, 0x06, 0xC0, 0xD8, 0x0E, 0x01, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0057[ 49] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x82, 0x0C, 0xC3, + 0x86, 0x61, 0xC3, 0x18, 0xE3, 0x0C, 0xD9, 0x86, + 0x6C, 0xC1, 0xB6, 0xC0, 0xF1, 0xE0, 0x78, 0xF0, + 0x1C, 0x70, 0x0C, 0x18, 0x06, 0x0C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0058[ 29] = { /* code 0058 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, + 0x19, 0x8C, 0x63, 0x0D, 0x83, 0x60, 0x70, 0x1C, + 0x0D, 0x83, 0x61, 0x8C, 0x63, 0x30, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0059[ 29] = { /* code 0059 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x19, 0x86, 0x33, 0x0C, 0xC1, 0xE0, 0x78, 0x0C, + 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_005A[ 26] = { /* code 005A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x03, 0x83, 0x83, 0x83, 0x81, 0x81, 0xC1, + 0xC1, 0xC0, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_005B[ 18] = { /* code 005B */ + 0x00, 0x00, 0x00, 0x01, 0xE7, 0x98, 0x61, 0x86, + 0x18, 0x61, 0x86, 0x18, 0x61, 0x86, 0x1E, 0x78, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_005C[ 23] = { /* code 005C */ + 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x60, 0x60, + 0x60, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0C, 0x0C, + 0x06, 0x06, 0x06, 0x03, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_005D[ 18] = { /* code 005D */ + 0x00, 0x00, 0x00, 0x01, 0xE7, 0x86, 0x18, 0x61, + 0x86, 0x18, 0x61, 0x86, 0x18, 0x61, 0x9E, 0x78, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_005E[ 26] = { /* code 005E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x7C, 0x36, 0x31, 0x98, 0xD8, 0x3C, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_005F[ 26] = { /* code 005F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0061[ 26] = { /* code 0061 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x1F, 0xC8, 0x60, 0x31, 0xF9, + 0x8C, 0xC6, 0x7F, 0x1D, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0062[ 29] = { /* code 0062 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, + 0x01, 0x80, 0x60, 0x1B, 0x87, 0xF1, 0xCE, 0x61, + 0x98, 0x66, 0x19, 0xCE, 0x7F, 0x1B, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0063[ 23] = { /* code 0063 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1C, 0x3E, 0x72, 0x60, 0x60, 0x60, 0x72, + 0x3E, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0064[ 29] = { /* code 0064 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x18, 0x06, 0x01, 0x87, 0x63, 0xF9, 0xCE, 0x61, + 0x98, 0x66, 0x19, 0xCE, 0x3F, 0x87, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0065[ 29] = { /* code 0065 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x83, 0xF1, 0xCE, 0x61, + 0x9F, 0xE6, 0x01, 0xC2, 0x3F, 0x87, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0066[ 18] = { /* code 0066 */ + 0x00, 0x00, 0x00, 0x00, 0x73, 0xCC, 0x31, 0xF7, + 0xCC, 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0067[ 26] = { /* code 0067 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x9F, 0xCC, 0xC6, 0x63, 0xF0, + 0xF0, 0xC0, 0x7E, 0x7F, 0xB0, 0xDF, 0xE7, 0xC0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0068[ 29] = { /* code 0068 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, + 0x01, 0x80, 0x60, 0x1B, 0xC7, 0xF9, 0xC6, 0x61, + 0x98, 0x66, 0x19, 0x86, 0x61, 0x98, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0069[ 15] = { /* code 0069 */ + 0x00, 0x00, 0x00, 0x01, 0x8C, 0x03, 0x18, 0xC6, + 0x31, 0x8C, 0x63, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_006A[ 15] = { /* code 006A */ + 0x00, 0x00, 0x00, 0x00, 0xC6, 0x01, 0x8C, 0x63, + 0x18, 0xC6, 0x31, 0x8D, 0xEE, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_006B[ 26] = { /* code 006B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x80, + 0xC0, 0x60, 0x31, 0xD9, 0xCD, 0xC7, 0xC3, 0xE1, + 0xB8, 0xCE, 0x63, 0xB0, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_006C[ 15] = { /* code 006C */ + 0x00, 0x00, 0x00, 0x31, 0x8C, 0x63, 0x18, 0xC6, + 0x31, 0x8C, 0x63, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_006D[ 44] = { /* code 006D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xDC, 0xE1, 0xFF, 0xE3, 0x9C, 0xC6, 0x31, + 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, + 0xC6, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_006E[ 29] = { /* code 006E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1B, 0xC7, 0xF9, 0xC6, 0x61, + 0x98, 0x66, 0x19, 0x86, 0x61, 0x98, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_006F[ 29] = { /* code 006F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x83, 0xF1, 0xCE, 0x61, + 0x98, 0x66, 0x19, 0xCE, 0x3F, 0x07, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0070[ 29] = { /* code 0070 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1B, 0x87, 0xF1, 0xCE, 0x61, + 0x98, 0x66, 0x19, 0xCE, 0x7F, 0x1B, 0x86, 0x01, + 0x80, 0x60, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0071[ 29] = { /* code 0071 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x63, 0xF9, 0xCE, 0x61, + 0x98, 0x66, 0x19, 0xCE, 0x3F, 0x87, 0x60, 0x18, + 0x06, 0x01, 0x80, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0072[ 21] = { /* code 0072 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD9, 0xF3, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0073[ 23] = { /* code 0073 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3C, 0x7E, 0x62, 0x70, 0x3C, 0x0E, 0x46, + 0x7E, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0074[ 21] = { /* code 0074 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, + 0xF9, 0xF1, 0x83, 0x06, 0x0C, 0x18, 0x3C, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0075[ 29] = { /* code 0075 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x66, 0x19, 0x86, 0x61, + 0x98, 0x66, 0x19, 0x8E, 0x7F, 0x8F, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0076[ 26] = { /* code 0076 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xF0, 0x6C, 0x66, 0x33, 0x18, + 0xD8, 0x6C, 0x1C, 0x0E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0077[ 41] = { /* code 0077 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x0C, 0x3C, 0x30, 0xD9, 0xE6, 0x67, 0x99, 0x92, + 0x63, 0xCF, 0x0F, 0x3C, 0x18, 0x60, 0x61, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0078[ 26] = { /* code 0078 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x31, 0x98, 0xC6, 0xC3, 0xE0, 0xE0, + 0xF8, 0x6C, 0x63, 0x31, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0079[ 26] = { /* code 0079 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xF0, 0x6C, 0x66, 0x33, 0x18, + 0xD8, 0x6C, 0x1C, 0x06, 0x03, 0x03, 0x01, 0x80, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_007A[ 23] = { /* code 007A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7E, 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, + 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_007B[ 21] = { /* code 007B */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0xC7, 0x8C, 0x18, + 0x30, 0x60, 0xC7, 0x0E, 0x06, 0x0C, 0x18, 0x30, + 0x60, 0xF0, 0xE0, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_007C[ 26] = { /* code 007C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x60, + 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, + 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_007D[ 21] = { /* code 007D */ + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x3C, 0x18, 0x30, + 0x60, 0xC1, 0x81, 0xC3, 0x8C, 0x18, 0x30, 0x60, + 0xC7, 0x8E, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_00E7[ 23] = { /* code 00E7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1C, 0x3E, 0x72, 0x60, 0x60, 0x60, 0x72, + 0x3E, 0x1C, 0x0C, 0x3C, 0x38, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_00F1[ 29] = { /* code 00F1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, + 0xF0, 0x98, 0x00, 0x1B, 0xC7, 0xF9, 0xC6, 0x61, + 0x98, 0x66, 0x19, 0x86, 0x61, 0x98, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0438[ 32] = { /* code 0438 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x31, 0x8E, 0x33, + 0xC6, 0xF8, 0xDB, 0x1E, 0x63, 0xCC, 0x71, 0x8C, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0439[ 32] = { /* code 0439 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x0F, 0xE0, 0xF8, 0x00, 0x0C, 0x31, 0x8E, 0x33, + 0xC6, 0xF8, 0xDB, 0x1E, 0x63, 0xCC, 0x71, 0x8C, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_043A[ 26] = { /* code 043A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0xD8, 0xCC, 0xE7, 0xE3, 0xF1, + 0x9C, 0xC6, 0x63, 0xB0, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0441[ 23] = { /* code 0441 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1E, 0x3F, 0x71, 0x60, 0x60, 0x60, 0x71, + 0x3F, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_0443[ 26] = { /* code 0443 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x61, 0xD8, 0xCC, 0x67, 0x71, 0xB0, + 0xD8, 0x7C, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic14_23h_2126[ 38] = { /* code 2126 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3E, 0x03, 0xFC, 0x38, 0x63, 0x81, + 0x98, 0x0C, 0xC0, 0x66, 0x03, 0x30, 0x18, 0xC1, + 0x87, 0x1C, 0x7D, 0xF3, 0xEF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const BFC_CHARINFO fontCalibriBoldBasic14_23h_CharInfo[103] = { + { 10, 29, {abc_fontCalibriBoldBasic14_23h_000A} }, /* code 000A */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_000D} }, /* code 000D */ + { 4, 12, {abc_fontCalibriBoldBasic14_23h_0020} }, /* code 0020 */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_0021} }, /* code 0021 */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_0022} }, /* code 0022 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0023} }, /* code 0023 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0024} }, /* code 0024 */ + { 14, 41, {abc_fontCalibriBoldBasic14_23h_0025} }, /* code 0025 */ + { 13, 38, {abc_fontCalibriBoldBasic14_23h_0026} }, /* code 0026 */ + { 4, 12, {abc_fontCalibriBoldBasic14_23h_0027} }, /* code 0027 */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_0028} }, /* code 0028 */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_0029} }, /* code 0029 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_002A} }, /* code 002A */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_002B} }, /* code 002B */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_002C} }, /* code 002C */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_002D} }, /* code 002D */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_002E} }, /* code 002E */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_002F} }, /* code 002F */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0030} }, /* code 0030 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0031} }, /* code 0031 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0032} }, /* code 0032 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0033} }, /* code 0033 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0034} }, /* code 0034 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0035} }, /* code 0035 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0036} }, /* code 0036 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0037} }, /* code 0037 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0038} }, /* code 0038 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0039} }, /* code 0039 */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_003A} }, /* code 003A */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_003B} }, /* code 003B */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_003C} }, /* code 003C */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_003D} }, /* code 003D */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_003E} }, /* code 003E */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_003F} }, /* code 003F */ + { 17, 49, {abc_fontCalibriBoldBasic14_23h_0040} }, /* code 0040 */ + { 12, 35, {abc_fontCalibriBoldBasic14_23h_0041} }, /* code 0041 */ + { 11, 32, {abc_fontCalibriBoldBasic14_23h_0042} }, /* code 0042 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0043} }, /* code 0043 */ + { 12, 35, {abc_fontCalibriBoldBasic14_23h_0044} }, /* code 0044 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0045} }, /* code 0045 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0046} }, /* code 0046 */ + { 12, 35, {abc_fontCalibriBoldBasic14_23h_0047} }, /* code 0047 */ + { 12, 35, {abc_fontCalibriBoldBasic14_23h_0048} }, /* code 0048 */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_0049} }, /* code 0049 */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_004A} }, /* code 004A */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_004B} }, /* code 004B */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_004C} }, /* code 004C */ + { 17, 49, {abc_fontCalibriBoldBasic14_23h_004D} }, /* code 004D */ + { 13, 38, {abc_fontCalibriBoldBasic14_23h_004E} }, /* code 004E */ + { 13, 38, {abc_fontCalibriBoldBasic14_23h_004F} }, /* code 004F */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0050} }, /* code 0050 */ + { 13, 38, {abc_fontCalibriBoldBasic14_23h_0051} }, /* code 0051 */ + { 11, 32, {abc_fontCalibriBoldBasic14_23h_0052} }, /* code 0052 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0053} }, /* code 0053 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0054} }, /* code 0054 */ + { 12, 35, {abc_fontCalibriBoldBasic14_23h_0055} }, /* code 0055 */ + { 11, 32, {abc_fontCalibriBoldBasic14_23h_0056} }, /* code 0056 */ + { 17, 49, {abc_fontCalibriBoldBasic14_23h_0057} }, /* code 0057 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0058} }, /* code 0058 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0059} }, /* code 0059 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_005A} }, /* code 005A */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_005B} }, /* code 005B */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_005C} }, /* code 005C */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_005D} }, /* code 005D */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_005E} }, /* code 005E */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_005F} }, /* code 005F */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0061} }, /* code 0061 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0062} }, /* code 0062 */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_0063} }, /* code 0063 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0064} }, /* code 0064 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0065} }, /* code 0065 */ + { 6, 18, {abc_fontCalibriBoldBasic14_23h_0066} }, /* code 0066 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0067} }, /* code 0067 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0068} }, /* code 0068 */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_0069} }, /* code 0069 */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_006A} }, /* code 006A */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_006B} }, /* code 006B */ + { 5, 15, {abc_fontCalibriBoldBasic14_23h_006C} }, /* code 006C */ + { 15, 44, {abc_fontCalibriBoldBasic14_23h_006D} }, /* code 006D */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_006E} }, /* code 006E */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_006F} }, /* code 006F */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0070} }, /* code 0070 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0071} }, /* code 0071 */ + { 7, 21, {abc_fontCalibriBoldBasic14_23h_0072} }, /* code 0072 */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_0073} }, /* code 0073 */ + { 7, 21, {abc_fontCalibriBoldBasic14_23h_0074} }, /* code 0074 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_0075} }, /* code 0075 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0076} }, /* code 0076 */ + { 14, 41, {abc_fontCalibriBoldBasic14_23h_0077} }, /* code 0077 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0078} }, /* code 0078 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0079} }, /* code 0079 */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_007A} }, /* code 007A */ + { 7, 21, {abc_fontCalibriBoldBasic14_23h_007B} }, /* code 007B */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_007C} }, /* code 007C */ + { 7, 21, {abc_fontCalibriBoldBasic14_23h_007D} }, /* code 007D */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_00E7} }, /* code 00E7 */ + { 10, 29, {abc_fontCalibriBoldBasic14_23h_00F1} }, /* code 00F1 */ + { 11, 32, {abc_fontCalibriBoldBasic14_23h_0438} }, /* code 0438 */ + { 11, 32, {abc_fontCalibriBoldBasic14_23h_0439} }, /* code 0439 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_043A} }, /* code 043A */ + { 8, 23, {abc_fontCalibriBoldBasic14_23h_0441} }, /* code 0441 */ + { 9, 26, {abc_fontCalibriBoldBasic14_23h_0443} }, /* code 0443 */ + { 13, 38, {abc_fontCalibriBoldBasic14_23h_2126} } /* code 2126 */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop10 = { + 0x2126, /* first character */ + 0x2126, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 102], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop9 = { + 0x0443, /* first character */ + 0x0443, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 101], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop8 = { + 0x0441, /* first character */ + 0x0441, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 100], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop7 = { + 0x0438, /* first character */ + 0x043A, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 97], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop6 = { + 0x00F1, /* first character */ + 0x00F1, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 96], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop5 = { + 0x00E7, /* first character */ + 0x00E7, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 95], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop4 = { + 0x0061, /* first character */ + 0x007D, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 66], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop3 = { + 0x0020, /* first character */ + 0x005F, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 2], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 1], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic14_23h_Prop1 = { + 0x000A, /* first character */ + 0x000A, /* last character */ + &fontCalibriBoldBasic14_23h_CharInfo[ 0], /* address of first character */ + &fontCalibriBoldBasic14_23h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontCalibriBoldBasic14_23h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 23, /* font height in pixels */ + 18, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontCalibriBoldBasic14_23h_Prop1} +}; diff --git a/source/Fonts/CalibriBoldBasic16_26h.c b/source/Fonts/CalibriBoldBasic16_26h.c new file mode 100644 index 0000000..b922030 --- /dev/null +++ b/source/Fonts/CalibriBoldBasic16_26h.c @@ -0,0 +1,1005 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: Calibri * + * Font width: 0 (proportional font) * + * Font height: 26 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 15:59 04-07-2023 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontCalibriBoldBasic16_26h; + +const UCHAR abc_fontCalibriBoldBasic16_26h_000A[ 36] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFE, 0x80, 0x57, 0xCA, 0x0D, 0x41, + 0xA8, 0x35, 0x38, 0xA4, 0x14, 0x02, 0x98, 0x53, + 0x0A, 0x01, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_000D[ 36] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0020[ 17] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0021[ 23] = { /* code 0021 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1C, 0x38, + 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x00, 0x70, + 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0022[ 30] = { /* code 0022 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, + 0x66, 0x33, 0x19, 0x8C, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0023[ 33] = { /* code 0023 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x19, 0x86, 0x67, 0xFD, 0xFF, 0x33, + 0x0C, 0xC3, 0x33, 0xFE, 0xFF, 0x99, 0x86, 0x61, + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0024[ 36] = { /* code 0024 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, + 0x01, 0x80, 0xF8, 0x3F, 0x8E, 0x11, 0xC0, 0x3C, + 0x03, 0xE0, 0x3F, 0x01, 0xF0, 0x0E, 0x01, 0xC8, + 0x79, 0xFE, 0x1F, 0x01, 0x80, 0x30, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0025[ 49] = { /* code 0025 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1E, 0x06, 0x7E, 0x18, 0xCC, + 0x31, 0x98, 0xC3, 0x33, 0x07, 0xEE, 0x07, 0x98, + 0x00, 0x6F, 0x01, 0xFF, 0x03, 0x66, 0x0C, 0xCC, + 0x31, 0x98, 0x63, 0xF1, 0x83, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0026[ 49] = { /* code 0026 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xE0, 0x0F, 0xF0, 0x38, + 0xE0, 0x71, 0xC0, 0xE7, 0x80, 0xFE, 0x01, 0xF0, + 0x07, 0xE3, 0x1D, 0xE6, 0x39, 0xFC, 0x71, 0xF0, + 0xF1, 0xF0, 0xFF, 0xF0, 0xFC, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0027[ 17] = { /* code 0027 */ + 0x00, 0x00, 0x00, 0x01, 0x8C, 0x63, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0028[ 23] = { /* code 0028 */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x87, 0x0C, 0x38, + 0x70, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE0, + 0xC1, 0xC3, 0x83, 0x07, 0x06, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0029[ 23] = { /* code 0029 */ + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x18, 0x38, + 0x70, 0x60, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, + 0x61, 0xC3, 0x86, 0x1C, 0x30, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_002A[ 33] = { /* code 002A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0xC1, 0xFE, 0x3F, 0x0F, 0xC7, 0xF8, 0x30, 0x0C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_002B[ 33] = { /* code 002B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x30, 0x0C, + 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_002C[ 17] = { /* code 002C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xCE, 0x73, 0x39, 0x80, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_002D[ 20] = { /* code 002D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xDF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_002E[ 20] = { /* code 002E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xC7, 0x1C, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_002F[ 30] = { /* code 002F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0E, + 0x0E, 0x07, 0x03, 0x83, 0x81, 0xC1, 0xE0, 0xE0, + 0x70, 0x78, 0x38, 0x1C, 0x1C, 0x0E, 0x07, 0x07, + 0x03, 0x80, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0030[ 36] = { /* code 0030 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0x3F, 0x87, 0x71, 0xC7, 0x38, + 0xE7, 0x1C, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xC7, + 0x70, 0xFE, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0031[ 36] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x7E, 0x0D, 0xC0, 0x38, 0x07, + 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, + 0xC1, 0xFF, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0032[ 36] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xF0, 0x7F, 0x08, 0x70, 0x0E, 0x01, + 0xC0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, + 0x01, 0xFF, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0033[ 36] = { /* code 0033 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xF8, 0x7F, 0x88, 0x70, 0x0E, 0x03, + 0xC3, 0xE0, 0x7F, 0x00, 0xF0, 0x0E, 0x01, 0xC8, + 0x79, 0xFE, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0034[ 36] = { /* code 0034 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x1F, 0x03, 0xE0, 0xDC, 0x1B, + 0x86, 0x70, 0xCE, 0x31, 0xC7, 0xFE, 0xFF, 0xC0, + 0xE0, 0x1C, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0035[ 36] = { /* code 0035 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFC, 0x3F, 0x86, 0x00, 0xC0, 0x18, + 0x03, 0xF0, 0x7F, 0x00, 0xF0, 0x0E, 0x01, 0xC8, + 0x79, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0036[ 36] = { /* code 0036 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7C, 0x1F, 0x87, 0x01, 0xC0, 0x38, + 0x07, 0xF8, 0xFF, 0x9C, 0x73, 0x8E, 0x71, 0xCF, + 0x38, 0xFE, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0037[ 36] = { /* code 0037 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFE, 0x7F, 0xC0, 0x38, 0x0E, 0x01, + 0xC0, 0x70, 0x0E, 0x03, 0x80, 0x70, 0x1C, 0x03, + 0x80, 0xE0, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0038[ 36] = { /* code 0038 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0x3F, 0xCE, 0x39, 0xC7, 0x3C, + 0xE3, 0xF8, 0x3E, 0x0E, 0xE3, 0x8E, 0x71, 0xCE, + 0x39, 0xFE, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0039[ 36] = { /* code 0039 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0x3F, 0x8E, 0x79, 0xC7, 0x38, + 0xE7, 0x1C, 0xFF, 0x8F, 0xF0, 0x0E, 0x01, 0x80, + 0x71, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_003A[ 20] = { /* code 003A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x8E, 0x38, 0x00, 0x00, 0x00, 0xE3, 0x8E, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_003B[ 20] = { /* code 003B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x8E, 0x38, 0x00, 0x00, 0x00, 0xE3, 0x8E, 0x31, + 0xC6, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_003C[ 33] = { /* code 003C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x3C, 0x3C, 0x3C, + 0x1C, 0x07, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_003D[ 33] = { /* code 003D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x7F, + 0xC0, 0x00, 0x01, 0xFF, 0x7F, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_003E[ 33] = { /* code 003E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0x80, 0x78, 0x07, + 0x80, 0x70, 0x1C, 0x1E, 0x1E, 0x1E, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_003F[ 33] = { /* code 003F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xE1, 0xFC, 0x47, 0x80, 0xE0, 0x38, 0x1E, 0x1F, + 0x07, 0x81, 0xC0, 0x70, 0x00, 0x07, 0x01, 0xC0, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0040[ 62] = { /* code 0040 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xC0, 0x07, 0xFE, 0x01, 0xC0, 0xE0, + 0x60, 0x0E, 0x18, 0xEC, 0xC3, 0x3F, 0x98, 0xC6, + 0x73, 0x19, 0x8C, 0x63, 0x31, 0x8C, 0x66, 0x73, + 0x0C, 0xFF, 0xE1, 0x8E, 0x78, 0x38, 0x00, 0x03, + 0x81, 0x00, 0x3F, 0xE0, 0x01, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0041[ 43] = { /* code 0041 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x80, 0x6C, + 0x03, 0x70, 0x3B, 0x81, 0x8C, 0x0C, 0x70, 0xE3, + 0x87, 0xFC, 0x3F, 0xF3, 0x83, 0x98, 0x1D, 0xC0, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0042[ 39] = { /* code 0042 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xF0, 0x7F, 0xC7, 0x1C, 0x71, + 0xC7, 0x1C, 0x7F, 0x07, 0xFC, 0x71, 0xE7, 0x0E, + 0x70, 0xE7, 0x1E, 0x7F, 0xC7, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0043[ 36] = { /* code 0043 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3E, 0x1F, 0xE7, 0x84, 0xE0, 0x38, + 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x78, 0x07, + 0x84, 0x7F, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0044[ 43] = { /* code 0044 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0x8F, + 0x1C, 0x3C, 0xE0, 0xE7, 0x07, 0x38, 0x39, 0xC1, + 0xCE, 0x0E, 0x70, 0xE3, 0x8F, 0x1F, 0xF0, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0045[ 33] = { /* code 0045 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFE, 0x7F, 0x9C, 0x07, 0x01, 0xC0, 0x7F, + 0x1F, 0xC7, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0xF9, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0046[ 33] = { /* code 0046 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFC, 0x7F, 0x1C, 0x07, 0x01, 0xC0, 0x70, + 0x1F, 0xC7, 0xF1, 0xC0, 0x70, 0x1C, 0x07, 0x01, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0047[ 43] = { /* code 0047 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0xF1, 0xE0, + 0x8E, 0x00, 0xE0, 0x07, 0x00, 0x38, 0xF9, 0xC7, + 0xCE, 0x0E, 0x38, 0x71, 0xE3, 0x87, 0xFC, 0x0F, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0048[ 43] = { /* code 0048 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0E, 0x1C, 0x70, 0xE3, 0x87, + 0x1C, 0x38, 0xE1, 0xC7, 0xFE, 0x3F, 0xF1, 0xC3, + 0x8E, 0x1C, 0x70, 0xE3, 0x87, 0x1C, 0x38, 0xE1, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0049[ 20] = { /* code 0049 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x71, 0xC7, + 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_004A[ 23] = { /* code 004A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1C, + 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x3B, + 0xF7, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_004B[ 36] = { /* code 004B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x87, 0x71, 0xCE, 0x79, 0xCE, 0x3B, + 0x87, 0xE0, 0xFC, 0x1D, 0xC3, 0xBC, 0x73, 0x8E, + 0x39, 0xC7, 0xB8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_004C[ 30] = { /* code 004C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, + 0xC0, 0xE0, 0x70, 0x38, 0x1F, 0xCF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_004D[ 59] = { /* code 004D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xF0, 0x7C, 0x7C, 0x1F, 0x1F, 0x87, 0xC7, 0xE3, + 0xF1, 0xD8, 0xDC, 0x76, 0x37, 0x1D, 0xDD, 0xC7, + 0x36, 0x71, 0xCD, 0x9C, 0x73, 0xE7, 0x1C, 0xF1, + 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_004E[ 46] = { /* code 004E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0C, 0x78, 0x31, + 0xF0, 0xC6, 0xC3, 0x1B, 0x8C, 0x66, 0x31, 0x9C, + 0xC6, 0x33, 0x18, 0x6C, 0x61, 0xB1, 0x83, 0xC6, + 0x0F, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_004F[ 46] = { /* code 004F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x1F, 0xF0, + 0xF0, 0xE3, 0x83, 0xDC, 0x07, 0x70, 0x1D, 0xC0, + 0x77, 0x01, 0xDC, 0x07, 0x78, 0x38, 0xE1, 0xE1, + 0xFF, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0050[ 36] = { /* code 0050 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xF8, 0x7F, 0x8E, 0x39, 0xC7, 0x38, + 0xE7, 0x3C, 0xFF, 0x1F, 0xC3, 0x80, 0x70, 0x0E, + 0x01, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0051[ 46] = { /* code 0051 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x3F, 0xE1, + 0xE1, 0xC7, 0x07, 0xB8, 0x0E, 0xE0, 0x3B, 0x80, + 0xEE, 0x03, 0xB8, 0x0E, 0xF0, 0x71, 0xC3, 0xC3, + 0xFE, 0x07, 0xFE, 0x00, 0x3C, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0052[ 39] = { /* code 0052 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xF0, 0x7F, 0x87, 0x1C, 0x71, + 0xC7, 0x1C, 0x73, 0xC7, 0xF8, 0x7F, 0x07, 0x38, + 0x71, 0xC7, 0x1C, 0x70, 0xE7, 0x0E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0053[ 33] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7C, 0x3F, 0x9C, 0x27, 0x01, 0xE0, 0x3E, + 0x07, 0xE0, 0x7C, 0x07, 0x01, 0xD8, 0xF7, 0xF8, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0054[ 36] = { /* code 0054 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xE1, 0xC0, 0x38, 0x07, + 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, + 0xC0, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0055[ 46] = { /* code 0055 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x70, 0x71, + 0xC1, 0xC7, 0x07, 0x1C, 0x1C, 0x70, 0x71, 0xC1, + 0xC7, 0x07, 0x1C, 0x1C, 0x70, 0x71, 0xE3, 0x83, + 0xFE, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0056[ 43] = { /* code 0056 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1E, 0x07, 0x70, 0x73, 0x83, + 0x9C, 0x1C, 0x71, 0xC3, 0x8E, 0x1C, 0x60, 0x77, + 0x03, 0xB8, 0x1D, 0x80, 0x7C, 0x03, 0xE0, 0x0E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0057[ 62] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x07, 0x70, 0xE1, 0xCE, 0x1E, 0x39, + 0xC7, 0xC7, 0x38, 0xD8, 0xE3, 0x9B, 0x18, 0x73, + 0x77, 0x0E, 0xEE, 0xE1, 0xD8, 0xD8, 0x1B, 0x1B, + 0x03, 0xE3, 0xE0, 0x7C, 0x7C, 0x07, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0058[ 39] = { /* code 0058 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x1C, 0x71, 0xC3, 0xB8, 0x3B, + 0x81, 0xB0, 0x1F, 0x00, 0xE0, 0x1F, 0x03, 0xB8, + 0x3B, 0x87, 0x1C, 0x71, 0xCF, 0x1E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0059[ 36] = { /* code 0059 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x07, 0xF0, 0xEE, 0x39, 0xE7, 0x1D, + 0xC1, 0xB0, 0x3E, 0x03, 0x80, 0x70, 0x0E, 0x01, + 0xC0, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_005A[ 33] = { /* code 005A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0x7F, 0xC0, 0x70, 0x38, 0x1C, 0x07, + 0x03, 0x81, 0xC0, 0x70, 0x38, 0x1C, 0x07, 0xFD, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_005B[ 23] = { /* code 005B */ + 0x00, 0x00, 0x00, 0x00, 0x07, 0x8F, 0x18, 0x30, + 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, + 0xC1, 0x83, 0x07, 0x8F, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_005C[ 30] = { /* code 005C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x03, 0x80, + 0xE0, 0x70, 0x38, 0x0E, 0x07, 0x03, 0xC0, 0xE0, + 0x70, 0x3C, 0x0E, 0x07, 0x01, 0xC0, 0xE0, 0x70, + 0x1C, 0x0E, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_005D[ 23] = { /* code 005D */ + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1E, 0x0C, 0x18, + 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, + 0x60, 0xC1, 0x8F, 0x1E, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_005E[ 36] = { /* code 005E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x1F, 0x03, 0x60, 0xEE, 0x1D, + 0xC7, 0x1C, 0xE3, 0xBC, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_005F[ 36] = { /* code 005F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0061[ 33] = { /* code 0061 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xF1, 0xFE, 0x43, + 0x80, 0xE3, 0xF9, 0xFE, 0x73, 0x9C, 0xE7, 0xF8, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0062[ 36] = { /* code 0062 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xDC, 0x3F, + 0xC7, 0xBC, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCF, + 0x79, 0xFE, 0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0063[ 30] = { /* code 0063 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x87, 0xE7, 0x93, 0x81, + 0xC0, 0xE0, 0x70, 0x3C, 0x8F, 0xC3, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0064[ 36] = { /* code 0064 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x77, 0x1F, + 0xE7, 0xBC, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCF, + 0x78, 0xFF, 0x0E, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0065[ 36] = { /* code 0065 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, + 0xC3, 0x1C, 0xE3, 0x9F, 0xF3, 0xFE, 0x70, 0x0F, + 0x08, 0xFF, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0066[ 23] = { /* code 0066 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x9F, 0x38, + 0x73, 0xFF, 0xF3, 0x87, 0x0E, 0x1C, 0x38, 0x70, + 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0067[ 33] = { /* code 0067 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFD, 0xFE, 0x63, + 0x18, 0xC6, 0x31, 0xFC, 0x7E, 0x18, 0x07, 0xF1, + 0xFE, 0xE1, 0xB8, 0x67, 0xF8, 0xF8, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0068[ 36] = { /* code 0068 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xDE, 0x3F, + 0xE7, 0x9C, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCE, + 0x39, 0xC7, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0069[ 17] = { /* code 0069 */ + 0x00, 0x00, 0x00, 0x01, 0xCE, 0x70, 0x1C, 0xE7, + 0x39, 0xCE, 0x73, 0x9C, 0xE0, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_006A[ 17] = { /* code 006A */ + 0x00, 0x00, 0x00, 0x00, 0xE7, 0x38, 0x0E, 0x73, + 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9F, 0xFE, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_006B[ 33] = { /* code 006B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x1D, 0xCE, 0x77, + 0x1D, 0xC7, 0xE1, 0xFC, 0x77, 0x1C, 0xE7, 0x3D, + 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_006C[ 17] = { /* code 006C */ + 0x00, 0x00, 0x00, 0x01, 0xCE, 0x73, 0x9C, 0xE7, + 0x39, 0xCE, 0x73, 0x9C, 0xE0, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_006D[ 56] = { /* code 006D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xE7, 0x8F, + 0xFF, 0xE7, 0x9E, 0x73, 0x8E, 0x39, 0xC7, 0x1C, + 0xE3, 0x8E, 0x71, 0xC7, 0x38, 0xE3, 0x9C, 0x71, + 0xCE, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_006E[ 36] = { /* code 006E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDE, 0x3F, + 0xE7, 0x9C, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCE, + 0x39, 0xC7, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_006F[ 36] = { /* code 006F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x1F, + 0xE3, 0x9E, 0xE1, 0xDC, 0x3B, 0x87, 0x70, 0xEF, + 0x38, 0xFF, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0070[ 36] = { /* code 0070 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDC, 0x3F, + 0xC7, 0xBC, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCF, + 0x79, 0xFE, 0x3B, 0x87, 0x00, 0xE0, 0x1C, 0x03, + 0x80, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0071[ 36] = { /* code 0071 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x1F, + 0xE7, 0xBC, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCF, + 0x78, 0xFF, 0x0E, 0xE0, 0x1C, 0x03, 0x80, 0x70, + 0x0E, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0072[ 23] = { /* code 0072 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xDB, 0xF7, 0x8E, 0x1C, 0x38, 0x70, 0xE1, + 0xC3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0073[ 26] = { /* code 0073 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x7E, 0x62, 0x70, 0x7C, 0x1F, + 0x07, 0x47, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0074[ 23] = { /* code 0074 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x73, 0xFF, 0xF3, 0x87, 0x0E, 0x1C, 0x38, 0x70, + 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0075[ 36] = { /* code 0075 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC7, 0x38, + 0xE7, 0x1C, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCE, + 0x79, 0xFF, 0x1E, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0076[ 36] = { /* code 0076 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC7, 0xB8, + 0xE7, 0x1C, 0xE3, 0x8E, 0xE1, 0xDC, 0x3B, 0x03, + 0xE0, 0x7C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0077[ 52] = { /* code 0077 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF3, 0x8E, 0x73, 0x8C, + 0x73, 0x8C, 0x77, 0xCC, 0x76, 0xDC, 0x36, 0xD8, + 0x36, 0xD8, 0x3E, 0xF8, 0x3C, 0x70, 0x1C, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0078[ 33] = { /* code 0078 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x19, 0xCC, 0x37, + 0x0F, 0x81, 0xE0, 0x78, 0x37, 0x1D, 0xC7, 0x3B, + 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0079[ 33] = { /* code 0079 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1D, 0xCE, 0x73, + 0x9C, 0xE3, 0xB0, 0xEC, 0x1B, 0x07, 0xC1, 0xE0, + 0x38, 0x0E, 0x03, 0x01, 0xC0, 0x70, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_007A[ 26] = { /* code 007A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0x7F, 0x07, 0x0E, 0x1C, 0x1C, + 0x38, 0x70, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_007B[ 23] = { /* code 007B */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x8F, 0x18, 0x30, + 0x60, 0xC1, 0x87, 0x1C, 0x38, 0x38, 0x30, 0x60, + 0xC1, 0x83, 0x07, 0x87, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_007C[ 33] = { /* code 007C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, + 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, + 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_007D[ 23] = { /* code 007D */ + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1E, 0x0C, 0x18, + 0x30, 0x60, 0xC1, 0x81, 0xC3, 0x8E, 0x18, 0x30, + 0x60, 0xC1, 0x8F, 0x1C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_00E7[ 30] = { /* code 00E7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x87, 0xE7, 0x93, 0x81, + 0xC0, 0xE0, 0x70, 0x3C, 0x8F, 0xC3, 0xC0, 0xC0, + 0x60, 0xF0, 0x70, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_00F1[ 36] = { /* code 00F1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x21, 0xFC, 0x27, 0x00, 0x01, 0xDE, 0x3F, + 0xE7, 0x9C, 0xE3, 0x9C, 0x73, 0x8E, 0x71, 0xCE, + 0x39, 0xC7, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0438[ 39] = { /* code 0438 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, + 0xC7, 0x3C, 0x73, 0xC7, 0x7C, 0x77, 0xC7, 0xDC, + 0x7D, 0xC7, 0x9C, 0x71, 0xC7, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0439[ 39] = { /* code 0439 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x31, 0x83, 0xF8, 0x1F, 0x00, 0x00, 0x71, + 0xC7, 0x3C, 0x73, 0xC7, 0x7C, 0x77, 0xC7, 0xDC, + 0x7D, 0xC7, 0x9C, 0x71, 0xC7, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_043A[ 33] = { /* code 043A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x1D, 0xC7, 0x73, + 0x9C, 0xE7, 0xF1, 0xFC, 0x73, 0x9C, 0xE7, 0x1D, + 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0441[ 30] = { /* code 0441 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x87, 0xE7, 0x93, 0x81, + 0xC0, 0xE0, 0x70, 0x3C, 0x8F, 0xC3, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_0443[ 33] = { /* code 0443 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1D, 0xCE, 0x73, + 0x9C, 0xE3, 0xB0, 0xEC, 0x1B, 0x07, 0xC1, 0xE0, + 0x38, 0x0E, 0x03, 0x01, 0xC0, 0x70, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic16_26h_2126[ 46] = { /* code 2126 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x1F, 0xF0, + 0xF1, 0xE3, 0x83, 0xDC, 0x07, 0x70, 0x1D, 0xC0, + 0x77, 0x01, 0xDC, 0x07, 0x38, 0x38, 0x71, 0xC7, + 0xEF, 0xDF, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const BFC_CHARINFO fontCalibriBoldBasic16_26h_CharInfo[103] = { + { 11, 36, {abc_fontCalibriBoldBasic16_26h_000A} }, /* code 000A */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_000D} }, /* code 000D */ + { 5, 17, {abc_fontCalibriBoldBasic16_26h_0020} }, /* code 0020 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_0021} }, /* code 0021 */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_0022} }, /* code 0022 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0023} }, /* code 0023 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0024} }, /* code 0024 */ + { 15, 49, {abc_fontCalibriBoldBasic16_26h_0025} }, /* code 0025 */ + { 15, 49, {abc_fontCalibriBoldBasic16_26h_0026} }, /* code 0026 */ + { 5, 17, {abc_fontCalibriBoldBasic16_26h_0027} }, /* code 0027 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_0028} }, /* code 0028 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_0029} }, /* code 0029 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_002A} }, /* code 002A */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_002B} }, /* code 002B */ + { 5, 17, {abc_fontCalibriBoldBasic16_26h_002C} }, /* code 002C */ + { 6, 20, {abc_fontCalibriBoldBasic16_26h_002D} }, /* code 002D */ + { 6, 20, {abc_fontCalibriBoldBasic16_26h_002E} }, /* code 002E */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_002F} }, /* code 002F */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0030} }, /* code 0030 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0031} }, /* code 0031 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0032} }, /* code 0032 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0033} }, /* code 0033 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0034} }, /* code 0034 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0035} }, /* code 0035 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0036} }, /* code 0036 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0037} }, /* code 0037 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0038} }, /* code 0038 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0039} }, /* code 0039 */ + { 6, 20, {abc_fontCalibriBoldBasic16_26h_003A} }, /* code 003A */ + { 6, 20, {abc_fontCalibriBoldBasic16_26h_003B} }, /* code 003B */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_003C} }, /* code 003C */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_003D} }, /* code 003D */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_003E} }, /* code 003E */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_003F} }, /* code 003F */ + { 19, 62, {abc_fontCalibriBoldBasic16_26h_0040} }, /* code 0040 */ + { 13, 43, {abc_fontCalibriBoldBasic16_26h_0041} }, /* code 0041 */ + { 12, 39, {abc_fontCalibriBoldBasic16_26h_0042} }, /* code 0042 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0043} }, /* code 0043 */ + { 13, 43, {abc_fontCalibriBoldBasic16_26h_0044} }, /* code 0044 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0045} }, /* code 0045 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0046} }, /* code 0046 */ + { 13, 43, {abc_fontCalibriBoldBasic16_26h_0047} }, /* code 0047 */ + { 13, 43, {abc_fontCalibriBoldBasic16_26h_0048} }, /* code 0048 */ + { 6, 20, {abc_fontCalibriBoldBasic16_26h_0049} }, /* code 0049 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_004A} }, /* code 004A */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_004B} }, /* code 004B */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_004C} }, /* code 004C */ + { 18, 59, {abc_fontCalibriBoldBasic16_26h_004D} }, /* code 004D */ + { 14, 46, {abc_fontCalibriBoldBasic16_26h_004E} }, /* code 004E */ + { 14, 46, {abc_fontCalibriBoldBasic16_26h_004F} }, /* code 004F */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0050} }, /* code 0050 */ + { 14, 46, {abc_fontCalibriBoldBasic16_26h_0051} }, /* code 0051 */ + { 12, 39, {abc_fontCalibriBoldBasic16_26h_0052} }, /* code 0052 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0053} }, /* code 0053 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0054} }, /* code 0054 */ + { 14, 46, {abc_fontCalibriBoldBasic16_26h_0055} }, /* code 0055 */ + { 13, 43, {abc_fontCalibriBoldBasic16_26h_0056} }, /* code 0056 */ + { 19, 62, {abc_fontCalibriBoldBasic16_26h_0057} }, /* code 0057 */ + { 12, 39, {abc_fontCalibriBoldBasic16_26h_0058} }, /* code 0058 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0059} }, /* code 0059 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_005A} }, /* code 005A */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_005B} }, /* code 005B */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_005C} }, /* code 005C */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_005D} }, /* code 005D */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_005E} }, /* code 005E */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_005F} }, /* code 005F */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0061} }, /* code 0061 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0062} }, /* code 0062 */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_0063} }, /* code 0063 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0064} }, /* code 0064 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0065} }, /* code 0065 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_0066} }, /* code 0066 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0067} }, /* code 0067 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0068} }, /* code 0068 */ + { 5, 17, {abc_fontCalibriBoldBasic16_26h_0069} }, /* code 0069 */ + { 5, 17, {abc_fontCalibriBoldBasic16_26h_006A} }, /* code 006A */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_006B} }, /* code 006B */ + { 5, 17, {abc_fontCalibriBoldBasic16_26h_006C} }, /* code 006C */ + { 17, 56, {abc_fontCalibriBoldBasic16_26h_006D} }, /* code 006D */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_006E} }, /* code 006E */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_006F} }, /* code 006F */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0070} }, /* code 0070 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0071} }, /* code 0071 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_0072} }, /* code 0072 */ + { 8, 26, {abc_fontCalibriBoldBasic16_26h_0073} }, /* code 0073 */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_0074} }, /* code 0074 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0075} }, /* code 0075 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_0076} }, /* code 0076 */ + { 16, 52, {abc_fontCalibriBoldBasic16_26h_0077} }, /* code 0077 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0078} }, /* code 0078 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0079} }, /* code 0079 */ + { 8, 26, {abc_fontCalibriBoldBasic16_26h_007A} }, /* code 007A */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_007B} }, /* code 007B */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_007C} }, /* code 007C */ + { 7, 23, {abc_fontCalibriBoldBasic16_26h_007D} }, /* code 007D */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_00E7} }, /* code 00E7 */ + { 11, 36, {abc_fontCalibriBoldBasic16_26h_00F1} }, /* code 00F1 */ + { 12, 39, {abc_fontCalibriBoldBasic16_26h_0438} }, /* code 0438 */ + { 12, 39, {abc_fontCalibriBoldBasic16_26h_0439} }, /* code 0439 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_043A} }, /* code 043A */ + { 9, 30, {abc_fontCalibriBoldBasic16_26h_0441} }, /* code 0441 */ + { 10, 33, {abc_fontCalibriBoldBasic16_26h_0443} }, /* code 0443 */ + { 14, 46, {abc_fontCalibriBoldBasic16_26h_2126} } /* code 2126 */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop10 = { + 0x2126, /* first character */ + 0x2126, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 102], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop9 = { + 0x0443, /* first character */ + 0x0443, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 101], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop8 = { + 0x0441, /* first character */ + 0x0441, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 100], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop7 = { + 0x0438, /* first character */ + 0x043A, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 97], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop6 = { + 0x00F1, /* first character */ + 0x00F1, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 96], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop5 = { + 0x00E7, /* first character */ + 0x00E7, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 95], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop4 = { + 0x0061, /* first character */ + 0x007D, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 66], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop3 = { + 0x0020, /* first character */ + 0x005F, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 2], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 1], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic16_26h_Prop1 = { + 0x000A, /* first character */ + 0x000A, /* last character */ + &fontCalibriBoldBasic16_26h_CharInfo[ 0], /* address of first character */ + &fontCalibriBoldBasic16_26h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontCalibriBoldBasic16_26h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 26, /* font height in pixels */ + 20, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontCalibriBoldBasic16_26h_Prop1} +}; diff --git a/source/Fonts/CalibriBoldBasic18_29h.c b/source/Fonts/CalibriBoldBasic18_29h.c new file mode 100644 index 0000000..d5df212 --- /dev/null +++ b/source/Fonts/CalibriBoldBasic18_29h.c @@ -0,0 +1,1107 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: Calibri * + * Font width: 0 (proportional font) * + * Font height: 29 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 15:57 04-07-2023 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontCalibriBoldBasic18_29h; + +const UCHAR abc_fontCalibriBoldBasic18_29h_000A[ 44] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, + 0x3D, 0xF3, 0xDF, 0xBC, 0x1B, 0xC1, 0xBC, 0xF3, + 0xCC, 0x3C, 0x03, 0xCC, 0x3C, 0xC3, 0xC0, 0x3F, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_000D[ 48] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0020[ 19] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0021[ 29] = { /* code 0021 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x00, 0x1C, 0x1C, 0x1C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0022[ 40] = { /* code 0022 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x9C, 0x73, 0x8E, 0x71, 0xCE, 0x39, + 0xC7, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0023[ 44] = { /* code 0023 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0xC1, 0x8C, 0x18, + 0xC1, 0x8C, 0x7F, 0xE7, 0xFE, 0x31, 0x83, 0x18, + 0x31, 0x8F, 0xFC, 0xFF, 0xC6, 0x30, 0x63, 0x06, + 0x30, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0024[ 44] = { /* code 0024 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x03, 0x00, 0x30, 0x0F, 0x83, 0xFC, 0x78, + 0xC7, 0x00, 0x70, 0x07, 0x80, 0x3F, 0x01, 0xFC, + 0x07, 0xE0, 0x1E, 0x00, 0xE0, 0x0E, 0x61, 0xE7, + 0xFC, 0x3F, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0025[ 66] = { /* code 0025 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x18, 0x3F, 0x0C, 0x18, 0xC3, 0x06, 0x31, + 0x81, 0x8C, 0xC0, 0x63, 0x60, 0x1F, 0x98, 0x03, + 0xCC, 0x00, 0x06, 0x3C, 0x03, 0x1F, 0x80, 0xCC, + 0x60, 0x63, 0x18, 0x30, 0xC6, 0x18, 0x31, 0x86, + 0x0F, 0xC3, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0026[ 62] = { /* code 0026 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x80, 0x1F, 0xE0, 0x1C, 0x38, 0x0E, 0x1C, 0x07, + 0x0E, 0x03, 0xDE, 0x00, 0xFE, 0x00, 0x3C, 0x38, + 0x7F, 0x1C, 0x3B, 0xCE, 0x38, 0xFF, 0x1C, 0x3F, + 0x0E, 0x0F, 0x87, 0x8F, 0xE1, 0xFF, 0xF8, 0x3F, + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0027[ 22] = { /* code 0027 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x71, 0xC7, + 0x1C, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0028[ 26] = { /* code 0028 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x38, + 0x70, 0xE3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, + 0xC3, 0x87, 0x0F, 0x0E, 0x1C, 0x38, 0x38, 0x70, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0029[ 26] = { /* code 0029 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x38, + 0x70, 0xE0, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, + 0x70, 0xE1, 0xC7, 0x8E, 0x1C, 0x38, 0xE1, 0xC0, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_002A[ 44] = { /* code 002A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x60, 0x36, 0xC3, 0xFC, 0x0F, + 0x00, 0xF0, 0x3F, 0xC3, 0x6C, 0x06, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_002B[ 44] = { /* code 002B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x07, 0xFF, + 0x7F, 0xF0, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_002C[ 22] = { /* code 002C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0xE3, 0x8E, 0x31, 0x86, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_002D[ 26] = { /* code 002D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_002E[ 22] = { /* code 002E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x79, + 0xE3, 0x80, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_002F[ 37] = { /* code 002F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x07, 0x03, 0x80, 0xE0, 0x38, 0x1C, 0x07, + 0x01, 0xC0, 0xE0, 0x38, 0x1E, 0x07, 0x01, 0xC0, + 0xE0, 0x38, 0x0E, 0x07, 0x01, 0xC0, 0x70, 0x38, + 0x0E, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0030[ 44] = { /* code 0030 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x81, 0xFE, 0x38, + 0xE3, 0x07, 0x70, 0x77, 0x07, 0x70, 0x77, 0x07, + 0x70, 0x77, 0x07, 0x70, 0x77, 0x06, 0x38, 0xE3, + 0xFC, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0031[ 44] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0xF0, 0x3F, + 0x03, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, + 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x03, + 0xFE, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0032[ 44] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x07, 0xF8, 0x63, + 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x03, 0x80, 0x38, + 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x07, + 0xFE, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0033[ 44] = { /* code 0033 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xF8, 0x63, + 0xC0, 0x1C, 0x01, 0xC0, 0x38, 0x3F, 0x03, 0xF8, + 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x61, 0xC7, + 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0034[ 44] = { /* code 0034 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0xF8, 0x0F, + 0x81, 0xB8, 0x1B, 0x83, 0xB8, 0x33, 0x87, 0x38, + 0x73, 0x8E, 0x38, 0xFF, 0xEF, 0xFE, 0x03, 0x80, + 0x38, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0035[ 44] = { /* code 0035 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC3, 0xFC, 0x38, + 0x03, 0x80, 0x38, 0x03, 0x80, 0x3F, 0x83, 0xFC, + 0x01, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x41, 0xC7, + 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0036[ 44] = { /* code 0036 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC1, 0xFC, 0x3C, + 0x03, 0x80, 0x70, 0x07, 0x00, 0x77, 0x87, 0xFC, + 0x70, 0xE7, 0x0E, 0x70, 0xE7, 0x0E, 0x39, 0xC3, + 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0037[ 44] = { /* code 0037 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE7, 0xFE, 0x00, + 0xE0, 0x1C, 0x01, 0xC0, 0x18, 0x03, 0x80, 0x38, + 0x07, 0x00, 0x70, 0x07, 0x00, 0xE0, 0x0E, 0x01, + 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0038[ 44] = { /* code 0038 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC3, 0xFE, 0x78, + 0xF7, 0x07, 0x70, 0x77, 0xCE, 0x3F, 0xC0, 0xFC, + 0x3F, 0xE7, 0x8F, 0x70, 0x77, 0x07, 0x78, 0xF3, + 0xFE, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0039[ 44] = { /* code 0039 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x83, 0xFC, 0x79, + 0xC7, 0x0E, 0x70, 0xE7, 0x0E, 0x78, 0xE3, 0xFE, + 0x1E, 0xE0, 0x0E, 0x00, 0xE0, 0x1C, 0x23, 0xC3, + 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_003A[ 26] = { /* code 003A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x87, 0x0E, 0x1C, 0x00, 0x00, + 0x01, 0xC3, 0x87, 0x0E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_003B[ 26] = { /* code 003B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x87, 0x0E, 0x1C, 0x00, 0x00, + 0x00, 0x03, 0x87, 0x0E, 0x1C, 0x30, 0xC1, 0x80, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_003C[ 44] = { /* code 003C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x1E, 0x03, 0xE0, 0xF8, 0x3E, 0x07, 0x80, + 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x01, 0xE0, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_003D[ 44] = { /* code 003D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFE, 0x7F, 0xE0, 0x00, + 0x00, 0x07, 0xFE, 0x7F, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_003E[ 44] = { /* code 003E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x78, 0x07, 0xE0, 0x1F, 0x80, 0x7E, + 0x00, 0xE0, 0x7E, 0x1F, 0x87, 0xE0, 0x78, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_003F[ 40] = { /* code 003F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xF0, 0x7F, 0x88, 0x78, 0x07, 0x00, + 0xE0, 0x1C, 0x07, 0x87, 0xE0, 0xF8, 0x1C, 0x03, + 0x80, 0x70, 0x00, 0x01, 0xC0, 0x38, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0040[ 80] = { /* code 0040 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x03, 0xFF, + 0xC0, 0x1E, 0x0F, 0x80, 0xE0, 0x0E, 0x07, 0x3D, + 0x9C, 0x39, 0xFE, 0x70, 0xEE, 0x79, 0xC3, 0x38, + 0xC7, 0x1D, 0xC3, 0x1C, 0x77, 0x0C, 0x71, 0xDC, + 0x73, 0x87, 0x73, 0xCE, 0x1D, 0xFB, 0xF0, 0x73, + 0xC7, 0x81, 0xE0, 0x00, 0x03, 0x80, 0x00, 0x0F, + 0x83, 0x00, 0x1F, 0xFC, 0x00, 0x1F, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0041[ 55] = { /* code 0041 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xC0, 0x0F, 0x80, 0x1B, 0x00, 0x77, 0x00, 0xEE, + 0x01, 0x9E, 0x07, 0x1C, 0x0E, 0x38, 0x18, 0x78, + 0x70, 0x70, 0xFF, 0xE3, 0xFF, 0xE7, 0x01, 0xCE, + 0x03, 0xB8, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0042[ 48] = { /* code 0042 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x81, 0xFE, + 0x0E, 0x38, 0x71, 0xC3, 0x8E, 0x1C, 0x70, 0xFE, + 0x07, 0xFC, 0x38, 0xF1, 0xC3, 0x8E, 0x1C, 0x70, + 0xE3, 0x8F, 0x1F, 0xF0, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0043[ 48] = { /* code 0043 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0xFF, + 0x87, 0x0C, 0x70, 0x07, 0x80, 0x38, 0x01, 0xC0, + 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0x70, + 0x03, 0xC3, 0x0F, 0xF8, 0x1F, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0044[ 55] = { /* code 0044 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xE0, 0x7F, 0xF0, 0xE1, 0xF1, 0xC0, 0xE3, 0x81, + 0xE7, 0x01, 0xCE, 0x03, 0x9C, 0x07, 0x38, 0x0E, + 0x70, 0x1C, 0xE0, 0x79, 0xC0, 0xE3, 0x87, 0x87, + 0xFE, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0045[ 44] = { /* code 0045 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE3, 0xFE, 0x38, + 0x03, 0x80, 0x38, 0x03, 0x80, 0x3F, 0xC3, 0xFC, + 0x38, 0x03, 0x80, 0x38, 0x03, 0x80, 0x38, 0x03, + 0xFE, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0046[ 40] = { /* code 0046 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xE7, 0xFC, 0xE0, 0x1C, + 0x03, 0x80, 0x70, 0x0E, 0x01, 0xFF, 0x3F, 0xE7, + 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0047[ 55] = { /* code 0047 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xF8, 0x1F, 0xF8, 0x78, 0x31, 0xC0, 0x03, 0x80, + 0x0E, 0x00, 0x1C, 0x7F, 0x38, 0xFE, 0x70, 0x1C, + 0xE0, 0x39, 0xE0, 0x71, 0xC0, 0xE1, 0xE1, 0xC1, + 0xFF, 0x80, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0048[ 55] = { /* code 0048 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x1C, 0x70, 0x38, 0xE0, 0x71, 0xC0, 0xE3, 0x81, + 0xC7, 0x03, 0x8E, 0x07, 0x1F, 0xFE, 0x3F, 0xFC, + 0x70, 0x38, 0xE0, 0x71, 0xC0, 0xE3, 0x81, 0xC7, + 0x03, 0x8E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0049[ 22] = { /* code 0049 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xE3, + 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, + 0xE3, 0x80, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_004A[ 29] = { /* code 004A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0xF8, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_004B[ 48] = { /* code 004B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x39, 0xC3, + 0x8E, 0x3C, 0x71, 0xC3, 0x9C, 0x1D, 0xC0, 0xFC, + 0x07, 0xE0, 0x3B, 0x81, 0xDE, 0x0E, 0x70, 0x71, + 0xC3, 0x87, 0x1C, 0x3C, 0xE0, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_004C[ 37] = { /* code 004C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, + 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, + 0xE0, 0x38, 0x0F, 0xF3, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_004D[ 77] = { /* code 004D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x01, 0xF1, + 0xF8, 0x0F, 0x8F, 0xC0, 0xFC, 0x76, 0x06, 0xE3, + 0xB8, 0x77, 0x1D, 0xC3, 0xB8, 0xE6, 0x19, 0xC7, + 0x39, 0xCE, 0x39, 0xCE, 0x71, 0xC7, 0xE3, 0x8E, + 0x3F, 0x1C, 0x71, 0xF8, 0xE3, 0x87, 0x87, 0x1C, + 0x3C, 0x38, 0xE1, 0xC1, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_004E[ 58] = { /* code 004E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x0E, 0x3E, 0x0E, 0x3F, 0x0E, 0x3F, 0x0E, + 0x3B, 0x8E, 0x3B, 0x8E, 0x39, 0xCE, 0x39, 0xCE, + 0x38, 0xEE, 0x38, 0xEE, 0x38, 0x6E, 0x38, 0x7E, + 0x38, 0x3E, 0x38, 0x3E, 0x38, 0x1E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_004F[ 58] = { /* code 004F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xE0, 0x1F, 0xF8, 0x3C, 0x3C, 0x38, 0x1C, + 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, + 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x38, 0x1C, + 0x3C, 0x3C, 0x1F, 0xF8, 0x07, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0050[ 48] = { /* code 0050 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x81, 0xFF, + 0x0E, 0x3C, 0x70, 0xE3, 0x87, 0x1C, 0x38, 0xE1, + 0xC7, 0x1C, 0x3F, 0xE1, 0xFC, 0x0E, 0x00, 0x70, + 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0051[ 58] = { /* code 0051 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xE0, 0x1F, 0xF8, 0x3C, 0x3C, 0x38, 0x1C, + 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, + 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x38, 0x1C, + 0x3C, 0x3C, 0x1F, 0xFC, 0x07, 0xFF, 0x00, 0x0F, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0052[ 51] = { /* code 0052 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, + 0xFF, 0x83, 0x8F, 0x0E, 0x1C, 0x38, 0x70, 0xE1, + 0xC3, 0x8E, 0x0F, 0xF8, 0x3F, 0xC0, 0xE7, 0x83, + 0x8E, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xE3, 0x83, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0053[ 40] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x87, 0xF9, 0xE3, 0x38, + 0x07, 0x00, 0xF0, 0x0F, 0xC0, 0xFE, 0x07, 0xC0, + 0x3C, 0x03, 0x80, 0x76, 0x1C, 0xFF, 0x8F, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0054[ 44] = { /* code 0054 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFE, 0x0E, + 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0055[ 58] = { /* code 0055 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, + 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, + 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, + 0x1C, 0x38, 0x1F, 0xF0, 0x07, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0056[ 51] = { /* code 0056 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1D, + 0xC0, 0xE7, 0x03, 0x9E, 0x0E, 0x38, 0x70, 0xE1, + 0xC3, 0xC7, 0x07, 0x18, 0x1C, 0xE0, 0x7B, 0x80, + 0xEE, 0x03, 0xB0, 0x0F, 0xC0, 0x1F, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0057[ 80] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x70, + 0x39, 0xC1, 0xE1, 0xC7, 0x07, 0x87, 0x1C, 0x3E, + 0x1C, 0x78, 0xFC, 0x70, 0xE3, 0x71, 0x83, 0x8D, + 0xCE, 0x0E, 0x37, 0x38, 0x1D, 0xCE, 0xE0, 0x76, + 0x3B, 0x01, 0xD8, 0xEC, 0x07, 0x63, 0xB0, 0x0F, + 0x87, 0xC0, 0x3E, 0x1F, 0x00, 0xF0, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0058[ 48] = { /* code 0058 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0xC7, + 0x8E, 0x38, 0x7B, 0xC1, 0xDC, 0x0F, 0xE0, 0x3E, + 0x01, 0xF0, 0x0F, 0x80, 0xEE, 0x0F, 0x78, 0x71, + 0xC7, 0x8F, 0x38, 0x3B, 0xC1, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0059[ 44] = { /* code 0059 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x77, 0x07, 0x38, + 0xE3, 0x8E, 0x1D, 0xC1, 0xDC, 0x0F, 0x80, 0xF8, + 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x07, 0x00, + 0x70, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_005A[ 40] = { /* code 005A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xEF, 0xFC, 0x03, 0x80, + 0xE0, 0x38, 0x07, 0x01, 0xC0, 0x38, 0x0E, 0x03, + 0x80, 0x70, 0x1C, 0x07, 0x00, 0xFF, 0xDF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_005B[ 29] = { /* code 005B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x3E, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x3E, 0x3E, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_005C[ 37] = { /* code 005C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, + 0x03, 0x80, 0x70, 0x1C, 0x07, 0x80, 0xE0, 0x38, + 0x0F, 0x01, 0xC0, 0x70, 0x0E, 0x03, 0x80, 0xF0, + 0x1C, 0x07, 0x01, 0xE0, 0x38, 0x0E, 0x01, 0xC0, + 0x70, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_005D[ 29] = { /* code 005D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x7C, 0x7C, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_005E[ 44] = { /* code 005E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x01, 0xF0, 0x1B, + 0x03, 0xB8, 0x3B, 0x83, 0x18, 0x71, 0xC7, 0x1C, + 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_005F[ 44] = { /* code 005F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0061[ 44] = { /* code 0061 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x83, 0xFC, 0x30, 0xE0, 0x0E, + 0x1F, 0xE3, 0xFE, 0x78, 0xE7, 0x0E, 0x71, 0xE3, + 0xFE, 0x1E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0062[ 48] = { /* code 0062 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0E, 0x00, 0x70, 0x03, 0x80, + 0x1C, 0x00, 0xE0, 0x07, 0x7C, 0x3F, 0xF1, 0xE3, + 0x8E, 0x0E, 0x70, 0x73, 0x83, 0x9C, 0x1C, 0xE0, + 0xE7, 0x8E, 0x3F, 0xF1, 0xDE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0063[ 37] = { /* code 0063 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0x8F, 0xF3, 0x8D, 0xC0, 0x70, 0x1C, 0x07, 0x01, + 0xC0, 0x38, 0x4F, 0xF0, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0064[ 48] = { /* code 0064 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x70, 0x03, + 0x80, 0x1C, 0x00, 0xE0, 0xF7, 0x1F, 0xF8, 0xE3, + 0xCE, 0x0E, 0x70, 0x73, 0x83, 0x9C, 0x1C, 0xE0, + 0xE3, 0x8F, 0x1F, 0xF8, 0x7D, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0065[ 44] = { /* code 0065 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0x83, 0xFC, 0x38, 0xE7, 0x0E, + 0x7F, 0xE7, 0xFE, 0x70, 0x07, 0x00, 0x38, 0x63, + 0xFE, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0066[ 29] = { /* code 0066 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0x1F, 0x38, 0x38, 0x38, 0xFE, 0xFE, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0067[ 40] = { /* code 0067 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFE, 0x7F, 0xDC, 0x73, 0x8E, 0x71, 0xC7, + 0xF1, 0xFC, 0x30, 0x07, 0xF8, 0xFF, 0x9C, 0x3F, + 0x07, 0xF1, 0xEF, 0xF8, 0xFC, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0068[ 48] = { /* code 0068 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0E, 0x00, 0x70, 0x03, 0x80, + 0x1C, 0x00, 0xE0, 0x07, 0x78, 0x3F, 0xE1, 0xE7, + 0x8E, 0x1C, 0x70, 0xE3, 0x87, 0x1C, 0x38, 0xE1, + 0xC7, 0x0E, 0x38, 0x71, 0xC3, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0069[ 22] = { /* code 0069 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x71, 0xC0, + 0x00, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, + 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_006A[ 22] = { /* code 006A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x38, 0xE0, + 0x00, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, + 0xE3, 0x8E, 0x3B, 0xEF, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_006B[ 44] = { /* code 006B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, + 0x07, 0x00, 0x70, 0xE7, 0x1C, 0x73, 0x87, 0x70, + 0x7E, 0x07, 0xF0, 0x77, 0x07, 0x38, 0x73, 0xC7, + 0x1C, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_006C[ 22] = { /* code 006C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x71, 0xC7, + 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, + 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_006D[ 73] = { /* code 006D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x8F, + 0x07, 0xFD, 0xF8, 0x79, 0xF3, 0xC7, 0x0E, 0x1C, + 0x70, 0xE1, 0xC7, 0x0E, 0x1C, 0x70, 0xE1, 0xC7, + 0x0E, 0x1C, 0x70, 0xE1, 0xC7, 0x0E, 0x1C, 0x70, + 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_006E[ 48] = { /* code 006E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x78, 0x3F, 0xE1, 0xE7, + 0x8E, 0x1C, 0x70, 0xE3, 0x87, 0x1C, 0x38, 0xE1, + 0xC7, 0x0E, 0x38, 0x71, 0xC3, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_006F[ 48] = { /* code 006F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1F, 0xF0, 0xE3, + 0x8E, 0x0E, 0x70, 0x73, 0x83, 0x9C, 0x1C, 0xE0, + 0xE3, 0x8E, 0x1F, 0xF0, 0x3E, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0070[ 48] = { /* code 0070 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x7C, 0x3F, 0xF1, 0xE3, + 0x8E, 0x0E, 0x70, 0x73, 0x83, 0x9C, 0x1C, 0xE0, + 0xE7, 0x8E, 0x3F, 0xF1, 0xDE, 0x0E, 0x00, 0x70, + 0x03, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0071[ 48] = { /* code 0071 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF7, 0x1F, 0xF8, 0xE3, + 0xCE, 0x0E, 0x70, 0x73, 0x83, 0x9C, 0x1C, 0xE0, + 0xE3, 0x8F, 0x1F, 0xF8, 0x7D, 0xC0, 0x0E, 0x00, + 0x70, 0x03, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0072[ 33] = { /* code 0072 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x73, 0xF9, + 0xFC, 0xF0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, + 0x81, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0073[ 37] = { /* code 0073 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, + 0x0F, 0xC7, 0x11, 0xC0, 0x7C, 0x0F, 0xC0, 0xF8, + 0x0E, 0x43, 0x9F, 0xC3, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0074[ 29] = { /* code 0074 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0xFF, 0xFF, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0075[ 48] = { /* code 0075 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x0E, 0x38, 0x71, 0xC3, + 0x8E, 0x1C, 0x70, 0xE3, 0x87, 0x1C, 0x38, 0xE1, + 0xC7, 0x9E, 0x1F, 0xF0, 0x7B, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0076[ 44] = { /* code 0076 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF0, 0xF7, 0x0E, 0x70, 0xE3, 0x8E, + 0x39, 0xC3, 0x9C, 0x1D, 0xC1, 0xD8, 0x1F, 0x80, + 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0077[ 66] = { /* code 0077 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xF1, 0xC7, 0x9C, 0x71, 0xC7, + 0x1C, 0x71, 0xC7, 0x1C, 0x7B, 0x6E, 0x0E, 0xDB, + 0x83, 0xB6, 0xE0, 0xED, 0xB0, 0x1E, 0x3C, 0x07, + 0x8F, 0x01, 0xE3, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0078[ 40] = { /* code 0078 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x1C, 0xF7, 0x8E, 0xE1, 0xDC, 0x1F, 0x03, + 0xE0, 0x7C, 0x1D, 0xC3, 0xB8, 0xE3, 0xBC, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0079[ 44] = { /* code 0079 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0x77, 0x0E, 0x70, 0xE7, 0x8E, + 0x39, 0xC3, 0xDC, 0x1D, 0xC1, 0xD8, 0x0F, 0x80, + 0xF8, 0x0F, 0x00, 0x70, 0x0E, 0x01, 0xE0, 0x1C, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_007A[ 37] = { /* code 007A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0x9F, 0xE0, 0x30, 0x1C, 0x0E, 0x03, 0x01, 0xC0, + 0xE0, 0x30, 0x1F, 0xE7, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_007B[ 29] = { /* code 007B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x3C, 0x78, + 0x78, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x0F, 0x0F, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_007C[ 40] = { /* code 007C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, + 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, + 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, + 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_007D[ 29] = { /* code 007D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x0F, + 0x0F, 0x0E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x78, 0x78, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_00E7[ 37] = { /* code 00E7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0x8F, 0xF3, 0x8D, 0xC0, 0x70, 0x1C, 0x07, 0x01, + 0xC0, 0x38, 0x4F, 0xF0, 0xF8, 0x18, 0x03, 0x07, + 0xC1, 0xE0, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_00F1[ 48] = { /* code 00F1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xC1, 0xFE, + 0x0C, 0xE0, 0x00, 0x07, 0x78, 0x3F, 0xE1, 0xE7, + 0x8E, 0x1C, 0x70, 0xE3, 0x87, 0x1C, 0x38, 0xE1, + 0xC7, 0x0E, 0x38, 0x71, 0xC3, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0438[ 48] = { /* code 0438 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x0E, 0x38, 0xF1, 0xC7, + 0x8E, 0x7C, 0x77, 0xE3, 0xB7, 0x1F, 0xB8, 0xF9, + 0xC7, 0x8E, 0x3C, 0x71, 0xC3, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0439[ 48] = { /* code 0439 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x1C, 0x38, 0xE0, 0xFE, + 0x03, 0xE0, 0x00, 0x07, 0x0E, 0x38, 0xF1, 0xC7, + 0x8E, 0x7C, 0x77, 0xE3, 0xB7, 0x1F, 0xB8, 0xF9, + 0xC7, 0x8E, 0x3C, 0x71, 0xC3, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_043A[ 44] = { /* code 043A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0xE7, 0x1E, 0x71, 0xC7, 0x38, + 0x7F, 0x07, 0xF8, 0x73, 0x87, 0x1C, 0x71, 0xC7, + 0x0E, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0441[ 37] = { /* code 0441 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0x8F, 0xF3, 0x8D, 0xC0, 0x70, 0x1C, 0x07, 0x01, + 0xC0, 0x38, 0x4F, 0xF0, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_0443[ 44] = { /* code 0443 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0x77, 0x0E, 0x70, 0xE7, 0x8E, + 0x39, 0xC3, 0xDC, 0x1D, 0xC1, 0xD8, 0x0F, 0x80, + 0xF8, 0x0F, 0x00, 0x70, 0x0E, 0x01, 0xE0, 0x1C, + 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontCalibriBoldBasic18_29h_2126[ 58] = { /* code 2126 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xE0, 0x1F, 0xF8, 0x1C, 0x3C, 0x38, 0x1C, + 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, + 0x70, 0x0E, 0x70, 0x0E, 0x38, 0x1C, 0x38, 0x1C, + 0x1C, 0x38, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +const BFC_CHARINFO fontCalibriBoldBasic18_29h_CharInfo[103] = { + { 12, 44, {abc_fontCalibriBoldBasic18_29h_000A} }, /* code 000A */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_000D} }, /* code 000D */ + { 5, 19, {abc_fontCalibriBoldBasic18_29h_0020} }, /* code 0020 */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_0021} }, /* code 0021 */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_0022} }, /* code 0022 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0023} }, /* code 0023 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0024} }, /* code 0024 */ + { 18, 66, {abc_fontCalibriBoldBasic18_29h_0025} }, /* code 0025 */ + { 17, 62, {abc_fontCalibriBoldBasic18_29h_0026} }, /* code 0026 */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_0027} }, /* code 0027 */ + { 7, 26, {abc_fontCalibriBoldBasic18_29h_0028} }, /* code 0028 */ + { 7, 26, {abc_fontCalibriBoldBasic18_29h_0029} }, /* code 0029 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_002A} }, /* code 002A */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_002B} }, /* code 002B */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_002C} }, /* code 002C */ + { 7, 26, {abc_fontCalibriBoldBasic18_29h_002D} }, /* code 002D */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_002E} }, /* code 002E */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_002F} }, /* code 002F */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0030} }, /* code 0030 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0031} }, /* code 0031 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0032} }, /* code 0032 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0033} }, /* code 0033 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0034} }, /* code 0034 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0035} }, /* code 0035 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0036} }, /* code 0036 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0037} }, /* code 0037 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0038} }, /* code 0038 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0039} }, /* code 0039 */ + { 7, 26, {abc_fontCalibriBoldBasic18_29h_003A} }, /* code 003A */ + { 7, 26, {abc_fontCalibriBoldBasic18_29h_003B} }, /* code 003B */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_003C} }, /* code 003C */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_003D} }, /* code 003D */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_003E} }, /* code 003E */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_003F} }, /* code 003F */ + { 22, 80, {abc_fontCalibriBoldBasic18_29h_0040} }, /* code 0040 */ + { 15, 55, {abc_fontCalibriBoldBasic18_29h_0041} }, /* code 0041 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0042} }, /* code 0042 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0043} }, /* code 0043 */ + { 15, 55, {abc_fontCalibriBoldBasic18_29h_0044} }, /* code 0044 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0045} }, /* code 0045 */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_0046} }, /* code 0046 */ + { 15, 55, {abc_fontCalibriBoldBasic18_29h_0047} }, /* code 0047 */ + { 15, 55, {abc_fontCalibriBoldBasic18_29h_0048} }, /* code 0048 */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_0049} }, /* code 0049 */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_004A} }, /* code 004A */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_004B} }, /* code 004B */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_004C} }, /* code 004C */ + { 21, 77, {abc_fontCalibriBoldBasic18_29h_004D} }, /* code 004D */ + { 16, 58, {abc_fontCalibriBoldBasic18_29h_004E} }, /* code 004E */ + { 16, 58, {abc_fontCalibriBoldBasic18_29h_004F} }, /* code 004F */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0050} }, /* code 0050 */ + { 16, 58, {abc_fontCalibriBoldBasic18_29h_0051} }, /* code 0051 */ + { 14, 51, {abc_fontCalibriBoldBasic18_29h_0052} }, /* code 0052 */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_0053} }, /* code 0053 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0054} }, /* code 0054 */ + { 16, 58, {abc_fontCalibriBoldBasic18_29h_0055} }, /* code 0055 */ + { 14, 51, {abc_fontCalibriBoldBasic18_29h_0056} }, /* code 0056 */ + { 22, 80, {abc_fontCalibriBoldBasic18_29h_0057} }, /* code 0057 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0058} }, /* code 0058 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0059} }, /* code 0059 */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_005A} }, /* code 005A */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_005B} }, /* code 005B */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_005C} }, /* code 005C */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_005D} }, /* code 005D */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_005E} }, /* code 005E */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_005F} }, /* code 005F */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0061} }, /* code 0061 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0062} }, /* code 0062 */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_0063} }, /* code 0063 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0064} }, /* code 0064 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0065} }, /* code 0065 */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_0066} }, /* code 0066 */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_0067} }, /* code 0067 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0068} }, /* code 0068 */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_0069} }, /* code 0069 */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_006A} }, /* code 006A */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_006B} }, /* code 006B */ + { 6, 22, {abc_fontCalibriBoldBasic18_29h_006C} }, /* code 006C */ + { 20, 73, {abc_fontCalibriBoldBasic18_29h_006D} }, /* code 006D */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_006E} }, /* code 006E */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_006F} }, /* code 006F */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0070} }, /* code 0070 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0071} }, /* code 0071 */ + { 9, 33, {abc_fontCalibriBoldBasic18_29h_0072} }, /* code 0072 */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_0073} }, /* code 0073 */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_0074} }, /* code 0074 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0075} }, /* code 0075 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0076} }, /* code 0076 */ + { 18, 66, {abc_fontCalibriBoldBasic18_29h_0077} }, /* code 0077 */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_0078} }, /* code 0078 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0079} }, /* code 0079 */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_007A} }, /* code 007A */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_007B} }, /* code 007B */ + { 11, 40, {abc_fontCalibriBoldBasic18_29h_007C} }, /* code 007C */ + { 8, 29, {abc_fontCalibriBoldBasic18_29h_007D} }, /* code 007D */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_00E7} }, /* code 00E7 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_00F1} }, /* code 00F1 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0438} }, /* code 0438 */ + { 13, 48, {abc_fontCalibriBoldBasic18_29h_0439} }, /* code 0439 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_043A} }, /* code 043A */ + { 10, 37, {abc_fontCalibriBoldBasic18_29h_0441} }, /* code 0441 */ + { 12, 44, {abc_fontCalibriBoldBasic18_29h_0443} }, /* code 0443 */ + { 16, 58, {abc_fontCalibriBoldBasic18_29h_2126} } /* code 2126 */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop10 = { + 0x2126, /* first character */ + 0x2126, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 102], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop9 = { + 0x0443, /* first character */ + 0x0443, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 101], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop8 = { + 0x0441, /* first character */ + 0x0441, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 100], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop7 = { + 0x0438, /* first character */ + 0x043A, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 97], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop6 = { + 0x00F1, /* first character */ + 0x00F1, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 96], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop5 = { + 0x00E7, /* first character */ + 0x00E7, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 95], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop4 = { + 0x0061, /* first character */ + 0x007D, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 66], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop3 = { + 0x0020, /* first character */ + 0x005F, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 2], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 1], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontCalibriBoldBasic18_29h_Prop1 = { + 0x000A, /* first character */ + 0x000A, /* last character */ + &fontCalibriBoldBasic18_29h_CharInfo[ 0], /* address of first character */ + &fontCalibriBoldBasic18_29h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontCalibriBoldBasic18_29h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 29, /* font height in pixels */ + 23, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontCalibriBoldBasic18_29h_Prop1} +}; diff --git a/source/Fonts/SimSunBold12_19h.c b/source/Fonts/SimSunBold12_19h.c new file mode 100644 index 0000000..77fbea9 --- /dev/null +++ b/source/Fonts/SimSunBold12_19h.c @@ -0,0 +1,1589 @@ +/******************************************************************************* + * * + * This file is generated by BitFontCreator Pro v3.8 * + * by Iseatech Software http://www.iseasoft.com/bitfontcreator.html * + * support@iseasoft.com * + * * + * Font name: SimSun * + * Font width: 0 (proportional font) * + * Font height: 19 * + * Encode: Unicode * + * Data length: 8 bits * + * Invert bits: No * + * Data format: Big Endian, Row based, Row preferred, Packed * + * * + * Create time: 15:21 05-24-2024 * + *******************************************************************************/ + +#include "bfcfont.h" + +/* The following line needs to be included in any file selecting the + font. +*/ +extern const BFC_FONT fontSimSunBold12_19h; + +const UCHAR abc_fontSimSunBold12_19h_000A[ 41] = { /* code 000A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_000D[ 19] = { /* code 000D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_0020[ 22] = { /* code 0020 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_0031[ 22] = { /* code 0031 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x78, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, + 0x30, 0x18, 0x3F, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_0032[ 22] = { /* code 0032 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, + 0xC6, 0x63, 0x31, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC6, 0x7F, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_0053[ 22] = { /* code 0053 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, + 0xC6, 0x63, 0x30, 0x0C, 0x03, 0x80, 0x60, 0x19, + 0x8C, 0xC6, 0x7E, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_0057[ 22] = { /* code 0057 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, + 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE1, 0xE0, + 0xF0, 0x78, 0x3C, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_4E0D[ 41] = { /* code 4E0D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xE0, 0x06, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x01, 0x80, 0x01, 0xF0, 0x01, 0xEC, 0x01, + 0xB3, 0x01, 0x98, 0xC1, 0x8C, 0x31, 0x86, 0x19, + 0x83, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_4E2D[ 41] = { /* code 4E2D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x7F, + 0xF8, 0x31, 0x8C, 0x18, 0xC6, 0x0C, 0x63, 0x06, + 0x31, 0x83, 0x18, 0xC1, 0xFF, 0xE0, 0xC6, 0x30, + 0x03, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_4EA7[ 41] = { /* code 4EA7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x18, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x18, + 0x60, 0x06, 0x30, 0x03, 0x30, 0x0F, 0xFF, 0xC6, + 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_4ECE[ 41] = { /* code 4ECE */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, + 0x00, 0xC3, 0x00, 0x61, 0x80, 0x30, 0xC0, 0x18, + 0x60, 0x0C, 0x30, 0x06, 0x18, 0x03, 0x0C, 0x01, + 0x8F, 0x01, 0xE7, 0x80, 0xDB, 0xC0, 0x6F, 0x30, + 0x61, 0x98, 0x31, 0x86, 0x31, 0x83, 0x31, 0x80, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_4EF6[ 41] = { /* code 4EF6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, + 0x00, 0xC3, 0x00, 0x6D, 0x80, 0x66, 0xC0, 0x33, + 0xFC, 0x3B, 0x30, 0x1D, 0x98, 0x1F, 0x8C, 0x1B, + 0x06, 0x01, 0xFF, 0xF0, 0xC1, 0x80, 0x60, 0xC0, + 0x30, 0x60, 0x18, 0x30, 0x0C, 0x18, 0x06, 0x0C, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_4F53[ 41] = { /* code 4F53 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8C, + 0x00, 0xC6, 0x00, 0x63, 0x00, 0x61, 0x80, 0x3F, + 0xFC, 0x38, 0x60, 0x1C, 0x78, 0x1E, 0x3C, 0x1B, + 0x3F, 0x01, 0x9F, 0x80, 0xDB, 0x60, 0x7F, 0xF8, + 0x38, 0xC6, 0x18, 0x60, 0x0C, 0x30, 0x06, 0x18, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_4FE1[ 41] = { /* code 4FE1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8C, + 0x00, 0xC3, 0x00, 0x7F, 0xF8, 0x60, 0x00, 0x30, + 0x00, 0x39, 0xFE, 0x1C, 0x00, 0x1E, 0x00, 0x1B, + 0x3F, 0xC1, 0x80, 0x00, 0xC0, 0x00, 0x67, 0xF8, + 0x33, 0x0C, 0x19, 0x86, 0x0C, 0xFF, 0x06, 0x61, + 0x80 +}; + +const UCHAR abc_fontSimSunBold12_19h_5173[ 41] = { /* code 5173 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, + 0x00, 0xC1, 0x80, 0x61, 0x80, 0x00, 0x00, 0x7F, + 0xF8, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, 0x1F, + 0xFF, 0xE0, 0x18, 0x00, 0x1E, 0x00, 0x0F, 0x00, + 0x0C, 0xC0, 0x0C, 0x30, 0x1C, 0x0E, 0x38, 0x01, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_5217[ 41] = { /* code 5217 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC7, 0xFC, 0x60, 0x60, 0x30, 0x30, 0xD8, 0x3F, + 0x6C, 0x19, 0xB6, 0x18, 0xDB, 0x0C, 0x6D, 0x8F, + 0x66, 0xCC, 0xF3, 0x60, 0x31, 0xB0, 0x18, 0xD8, + 0x18, 0x0C, 0x18, 0x06, 0x18, 0x0F, 0x18, 0x03, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_52A0[ 41] = { /* code 52A0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x01, 0x80, 0x00, 0xC0, 0x00, 0x61, 0xF9, 0xFE, + 0xCC, 0x1B, 0x66, 0x0D, 0xB3, 0x06, 0xD9, 0x83, + 0x6C, 0xC1, 0xB6, 0x60, 0xDB, 0x30, 0x6D, 0x98, + 0x66, 0xCC, 0x33, 0x7E, 0x37, 0xB3, 0x31, 0x80, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_52A8[ 41] = { /* code 52A8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, + 0x00, 0x06, 0x03, 0xF3, 0x00, 0x01, 0x80, 0x03, + 0xFC, 0x00, 0x66, 0x7F, 0xB3, 0x0C, 0x19, 0x86, + 0x0C, 0xC3, 0x0C, 0x63, 0x66, 0x31, 0x9B, 0x19, + 0xFF, 0x0C, 0x67, 0x86, 0x01, 0x9E, 0x01, 0x86, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_5305[ 41] = { /* code 5305 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, + 0x00, 0xC0, 0x00, 0xFF, 0xC0, 0x60, 0x60, 0x60, + 0x30, 0x7F, 0xD8, 0x6C, 0x6C, 0x06, 0x36, 0x03, + 0x1B, 0x01, 0xFD, 0x80, 0xC3, 0xC0, 0x60, 0xC0, + 0x30, 0x0C, 0x18, 0x06, 0x07, 0xFF, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_53F7[ 41] = { /* code 53F7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0x80, 0xC0, 0xC0, 0x60, 0x60, 0x30, + 0x30, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xC1, + 0x80, 0x01, 0x80, 0x00, 0xFF, 0xC0, 0x00, 0x60, + 0x00, 0x30, 0x00, 0x18, 0x00, 0x78, 0x00, 0x18, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_540D[ 41] = { /* code 540D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x30, 0x00, 0x3F, 0xC0, 0x30, 0x60, 0x3C, + 0x60, 0x73, 0x60, 0x01, 0xE0, 0x00, 0x60, 0x00, + 0xE0, 0x01, 0xFF, 0xC7, 0xE0, 0x60, 0x30, 0x30, + 0x18, 0x18, 0x0C, 0x0C, 0x07, 0xFE, 0x03, 0x03, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_542B[ 41] = { /* code 542B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x18, 0x00, 0x1E, 0x00, 0x19, 0x80, 0x1E, + 0x60, 0x39, 0x9C, 0x70, 0xC3, 0x83, 0xFC, 0x00, + 0x0C, 0x00, 0x0C, 0x00, 0xFF, 0xC0, 0x60, 0x60, + 0x30, 0x30, 0x18, 0x18, 0x0F, 0xFC, 0x06, 0x06, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_578B[ 41] = { /* code 578B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC7, 0xFC, 0x60, 0xD9, 0xB0, 0x6C, 0xD8, 0x36, + 0x6C, 0xFF, 0xF6, 0x0D, 0x9B, 0x0C, 0xC1, 0x86, + 0x63, 0xC6, 0x18, 0xC6, 0x0C, 0x00, 0xFF, 0xF0, + 0x03, 0x00, 0x01, 0x80, 0x7F, 0xFF, 0x80, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_5C0F[ 41] = { /* code 5C0F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x03, + 0x00, 0x19, 0x98, 0x0C, 0xC6, 0x06, 0x61, 0x86, + 0x30, 0xC3, 0x18, 0x33, 0x0C, 0x1B, 0x06, 0x0C, + 0x03, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x00, 0xC0, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_5E8F[ 41] = { /* code 5E8F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x0C, 0x01, 0xFF, 0xF8, 0xC0, 0x00, 0x67, + 0xF8, 0x30, 0x18, 0x18, 0x78, 0x0C, 0x18, 0x07, + 0xFF, 0xE3, 0x06, 0x31, 0x83, 0x30, 0xC1, 0x80, + 0xC0, 0xC0, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x30, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_606F[ 41] = { /* code 606F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x30, 0x00, 0xFF, 0xC0, 0x60, 0x60, 0x3F, + 0xF0, 0x18, 0x18, 0x0F, 0xFC, 0x06, 0x06, 0x03, + 0xFF, 0x01, 0x81, 0x80, 0x0C, 0x00, 0x33, 0x18, + 0xD9, 0xB6, 0x6C, 0x1B, 0x63, 0xFC, 0x00, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_63A5[ 41] = { /* code 63A5 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, + 0x01, 0x86, 0x00, 0xDF, 0xF0, 0x60, 0x01, 0xFF, + 0x18, 0x18, 0xD8, 0x0F, 0xFF, 0x86, 0x18, 0x03, + 0x8C, 0x03, 0xFF, 0xF7, 0xC6, 0x60, 0x66, 0x30, + 0x31, 0xB0, 0x18, 0x70, 0x3C, 0xEE, 0x0D, 0xC1, + 0x80 +}; + +const UCHAR abc_fontSimSunBold12_19h_6570[ 41] = { /* code 6570 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, + 0x06, 0xDB, 0x01, 0xF9, 0x80, 0x30, 0xFD, 0xFF, + 0xCC, 0x3F, 0x66, 0x36, 0xF3, 0x33, 0x3D, 0x83, + 0x07, 0x8F, 0xF3, 0xC1, 0x98, 0xC1, 0x8C, 0x60, + 0xEC, 0x78, 0x1C, 0x3C, 0x1F, 0x33, 0x38, 0xF0, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_6587[ 41] = { /* code 6587 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x18, 0x00, 0x0C, 0x03, 0xFF, 0xFC, 0x30, + 0x30, 0x18, 0x18, 0x06, 0x18, 0x03, 0x0C, 0x00, + 0xCC, 0x00, 0x3C, 0x00, 0x0C, 0x00, 0x0F, 0x00, + 0x0C, 0xC0, 0x0C, 0x30, 0x1C, 0x0E, 0x38, 0x01, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_65E0[ 41] = { /* code 65E0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0x80, 0x18, 0x00, 0x0C, 0x00, 0x06, + 0x00, 0x03, 0x00, 0x3F, 0xFF, 0x01, 0xB0, 0x00, + 0xD8, 0x00, 0x6C, 0x00, 0x66, 0x00, 0x33, 0x00, + 0x31, 0x8C, 0x30, 0xC6, 0x30, 0x3F, 0x30, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_65E5[ 41] = { /* code 65E5 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0x80, 0xC0, 0xC0, 0x60, 0x60, 0x30, + 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x07, 0xFE, 0x03, + 0x03, 0x01, 0x81, 0x80, 0xC0, 0xC0, 0x60, 0x60, + 0x30, 0x30, 0x18, 0x18, 0x0F, 0xFC, 0x06, 0x06, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_65F6[ 41] = { /* code 65F6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0xC3, 0xF0, 0x61, 0x98, 0x30, 0xCF, + 0xFE, 0x66, 0x0C, 0x33, 0x06, 0x1F, 0x83, 0x0C, + 0xD9, 0x86, 0x66, 0xC3, 0x33, 0x61, 0x98, 0x30, + 0xFC, 0x18, 0x66, 0x0C, 0x00, 0x1E, 0x00, 0x06, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_671F[ 41] = { /* code 671F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, + 0x03, 0x37, 0xE3, 0xFF, 0x30, 0xCD, 0x98, 0x66, + 0xCC, 0x3F, 0x7E, 0x19, 0xB3, 0x0C, 0xD9, 0x87, + 0xEC, 0xC3, 0x37, 0xE1, 0x9B, 0x33, 0xFF, 0x98, + 0x0D, 0x8C, 0x33, 0xC6, 0x30, 0xCF, 0x30, 0xC3, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_672C[ 41] = { /* code 672C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0xFF, + 0xFC, 0x03, 0xC0, 0x03, 0xF0, 0x01, 0xF8, 0x01, + 0xB6, 0x01, 0x99, 0x81, 0x8C, 0x61, 0xBF, 0xD9, + 0x83, 0x06, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_673A[ 41] = { /* code 673A */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x01, 0x9F, 0x80, 0xCC, 0xC0, 0x66, 0x61, 0xFF, + 0x30, 0x19, 0x98, 0x1C, 0xCC, 0x0F, 0x66, 0x0F, + 0xF3, 0x07, 0xF9, 0x86, 0xCC, 0xC0, 0x66, 0x6C, + 0x33, 0x36, 0x1B, 0x1B, 0x0D, 0x87, 0x87, 0x80, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7248[ 41] = { /* code 7248 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, + 0x86, 0xC1, 0xE3, 0x6F, 0x81, 0xB6, 0x00, 0xDB, + 0x00, 0x7F, 0xFE, 0x30, 0xF3, 0x18, 0x79, 0x8F, + 0xBC, 0xC6, 0xDB, 0xC3, 0x6D, 0xE1, 0xB6, 0x60, + 0xDB, 0x30, 0x6F, 0x3C, 0x37, 0xB3, 0x33, 0xB0, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_7387[ 41] = { /* code 7387 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x18, 0x03, 0xFF, 0xF0, 0x0C, 0x00, 0xCC, + 0xCC, 0x3F, 0xCC, 0x0C, 0xCC, 0x0C, 0xDB, 0x0D, + 0xFE, 0xC0, 0x03, 0x00, 0x0C, 0x03, 0xFF, 0xFC, + 0x03, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_751F[ 41] = { /* code 751F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x01, 0x98, 0x00, 0xCC, 0x00, 0x66, 0x00, 0x7F, + 0xFC, 0x31, 0x80, 0x30, 0xC0, 0x30, 0x60, 0x00, + 0x30, 0x03, 0xFF, 0xC0, 0x0C, 0x00, 0x06, 0x00, + 0x03, 0x00, 0x01, 0x80, 0x7F, 0xFF, 0x80, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_76D1[ 41] = { /* code 76D1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, + 0x03, 0x66, 0x01, 0xB3, 0xF0, 0xD9, 0x80, 0x6D, + 0xB0, 0x36, 0xCC, 0x1B, 0xC6, 0x01, 0x80, 0x00, + 0x00, 0x03, 0xFF, 0xC1, 0xB3, 0x60, 0xD9, 0xB0, + 0x6C, 0xD8, 0x36, 0x6C, 0x7F, 0xFF, 0x80, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_79F0[ 41] = { /* code 79F0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, + 0x01, 0xEC, 0x07, 0xC6, 0x00, 0x63, 0xFC, 0x33, + 0x06, 0xFF, 0x86, 0x0D, 0x98, 0x0E, 0x0C, 0x07, + 0x9F, 0x87, 0xEF, 0x63, 0xCD, 0xB3, 0x66, 0xCC, + 0x36, 0x66, 0x18, 0x30, 0x0C, 0x78, 0x06, 0x18, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7A0B[ 41] = { /* code 7A0B */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, + 0x01, 0xFF, 0xE7, 0xCC, 0x30, 0x66, 0x18, 0x33, + 0x0C, 0xFF, 0xFE, 0x0C, 0x00, 0x0E, 0x00, 0x07, + 0xBF, 0xE7, 0xE3, 0x03, 0xF1, 0x83, 0x67, 0xF8, + 0x30, 0x60, 0x18, 0x30, 0x0D, 0xFF, 0x86, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7B80[ 41] = { /* code 7B80 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, + 0x03, 0xFF, 0xF3, 0x66, 0xC3, 0x1E, 0x30, 0x30, + 0x00, 0x0F, 0xFC, 0x18, 0x06, 0x0D, 0xFB, 0x06, + 0xCD, 0x83, 0x66, 0xC1, 0xBF, 0x60, 0xD9, 0xB0, + 0x6C, 0xD8, 0x37, 0xEC, 0x18, 0x06, 0x0C, 0x07, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7BA1[ 41] = { /* code 7BA1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, + 0x03, 0xFF, 0xF3, 0x66, 0xC3, 0x1E, 0x30, 0x03, + 0x00, 0x7F, 0xFF, 0x30, 0x01, 0xB7, 0xFD, 0x83, + 0x06, 0x01, 0xFF, 0x00, 0xC0, 0x00, 0x7F, 0xE0, + 0x30, 0x30, 0x18, 0x18, 0x0F, 0xFC, 0x06, 0x06, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7CFB[ 41] = { /* code 7CFB */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0x83, 0xF8, 0x00, 0x30, 0x00, 0x30, 0xC0, 0x30, + 0xC0, 0x3F, 0xC0, 0x00, 0xC0, 0x01, 0xC6, 0x03, + 0x81, 0x87, 0xFF, 0xE0, 0x0C, 0x30, 0x36, 0xC0, + 0x33, 0x30, 0x31, 0x8C, 0x33, 0xC3, 0x00, 0xC0, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7EBF[ 41] = { /* code 7EBF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, + 0x01, 0x86, 0xC1, 0x83, 0x00, 0xD9, 0xF8, 0xCF, + 0xE0, 0xFC, 0x60, 0x0C, 0x3F, 0x8C, 0xFC, 0x0C, + 0x0C, 0xCF, 0xE6, 0xC3, 0x01, 0xC0, 0x00, 0xCC, + 0x3C, 0xF6, 0xF0, 0xCF, 0x31, 0xC3, 0x80, 0x00, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_7EDF[ 41] = { /* code 7EDF */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, + 0x01, 0x83, 0x01, 0x81, 0x80, 0xCF, 0xFC, 0xD8, + 0xC0, 0xFC, 0xCC, 0x0C, 0xC3, 0x0C, 0xFF, 0xCC, + 0x1B, 0x6F, 0xCD, 0x83, 0x06, 0xC0, 0x03, 0x60, + 0x3B, 0x36, 0xF1, 0x9B, 0x31, 0x87, 0x81, 0x80, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_7F6E[ 41] = { /* code 7F6E */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xC6, 0x66, 0x63, 0xFF, 0xF0, 0x06, 0x00, 0xFF, + 0xFC, 0x01, 0x80, 0x0F, 0xFC, 0x06, 0x06, 0x03, + 0xFF, 0x01, 0x81, 0x80, 0xFF, 0xC0, 0x60, 0x60, + 0x3F, 0xF0, 0x18, 0x18, 0x7F, 0xFF, 0x80, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_81EA[ 41] = { /* code 81EA */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x30, 0x00, 0x7F, 0xE0, 0x30, + 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x07, 0xFE, 0x03, + 0x03, 0x01, 0x81, 0x80, 0xFF, 0xC0, 0x60, 0x60, + 0x30, 0x30, 0x18, 0x18, 0x0F, 0xFC, 0x06, 0x06, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_8A00[ 41] = { /* code 8A00 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x18, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x60, 0x18, 0x30, 0x0C, 0x1F, 0xFE, 0x0C, 0x03, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_8BBE[ 41] = { /* code 8BBE */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x1F, 0x80, 0xCC, 0xC0, 0x66, 0x60, 0x03, + 0x30, 0x03, 0x0F, 0x7F, 0x00, 0x06, 0xFF, 0x03, + 0x31, 0x81, 0x99, 0x80, 0xC6, 0xC0, 0x7B, 0xC0, + 0x38, 0xC0, 0x18, 0xF0, 0x01, 0xCE, 0x03, 0x81, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_8BED[ 41] = { /* code 8BED */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x7F, 0xE1, 0x83, 0x00, 0xC1, 0x80, 0x07, + 0xF8, 0x00, 0xCC, 0x78, 0x66, 0x0D, 0xFF, 0xC6, + 0x00, 0x03, 0x00, 0x01, 0x9F, 0xE0, 0xCC, 0x30, + 0x7E, 0x18, 0x3B, 0x0C, 0x19, 0xFE, 0x00, 0xC3, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_8F6F[ 41] = { /* code 8F6F */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, + 0x01, 0x86, 0x00, 0xC3, 0x03, 0xFD, 0xF8, 0x61, + 0x8C, 0x3C, 0xCC, 0x36, 0xD8, 0x1F, 0xCC, 0x01, + 0x86, 0x00, 0xC7, 0x80, 0x7B, 0xC3, 0xF1, 0xE0, + 0xD9, 0x98, 0x0C, 0xCC, 0x06, 0xC3, 0x03, 0xC0, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_8F7D[ 41] = { /* code 8F7D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, + 0x00, 0xC3, 0xC3, 0xFD, 0xB0, 0x30, 0xC1, 0xFF, + 0xFE, 0x18, 0x30, 0x0C, 0x1B, 0x3F, 0xED, 0x86, + 0x06, 0xC6, 0xC3, 0xC3, 0xFD, 0xE0, 0x30, 0x60, + 0x1F, 0x36, 0xFC, 0x3F, 0x06, 0x33, 0x83, 0x30, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_8FDE[ 41] = { /* code 8FDE */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, + 0x03, 0x06, 0x00, 0xFF, 0xF8, 0x63, 0x00, 0x01, + 0xE0, 0x01, 0xB0, 0x7D, 0xFF, 0x06, 0x0C, 0x03, + 0x06, 0x01, 0x83, 0x00, 0xFF, 0xF8, 0x60, 0xC0, + 0x30, 0x60, 0x3C, 0x30, 0x33, 0xFF, 0x80, 0x00, + 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_9891[ 41] = { /* code 9891 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x01, 0x9F, 0xF3, 0xC1, 0x81, 0xF9, 0x80, 0xF3, + 0xFC, 0x79, 0x86, 0x7F, 0xDB, 0x00, 0x6D, 0x83, + 0x36, 0xC7, 0xFB, 0x63, 0xFD, 0xB1, 0xFF, 0x99, + 0x8C, 0xF0, 0x0C, 0xCC, 0x1C, 0xC3, 0x38, 0xC0, + 0xC0 +}; + +const UCHAR abc_fontSimSunBold12_19h_AC04[ 31] = { /* code AC04 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xCC, 0x06, 0x60, 0x63, + 0x03, 0x1C, 0x30, 0xC3, 0x86, 0x30, 0x30, 0x61, + 0x83, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_AD6D[ 31] = { /* code AD6D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x60, 0x03, + 0x00, 0x18, 0xFF, 0xE0, 0x60, 0x03, 0x00, 0x7F, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_ADDC[ 31] = { /* code ADDC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x60, 0x03, + 0x00, 0x18, 0x01, 0x87, 0xFF, 0x06, 0x60, 0x33, + 0x01, 0x98, 0x0C, 0xC0, 0x66, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B0A0[ 31] = { /* code B0A0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0C, 0x30, 0x61, 0x83, + 0x8C, 0x18, 0x7F, 0xC0, 0x00, 0x0F, 0xF0, 0x01, + 0x83, 0xFC, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B354[ 31] = { /* code B354 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xEC, 0x30, 0x61, 0x83, + 0x0C, 0xF8, 0x60, 0xC3, 0x06, 0x18, 0x30, 0xFF, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B378[ 31] = { /* code B378 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x9E, 0x30, 0xF1, 0xBF, + 0x8C, 0x3C, 0x79, 0xE0, 0x00, 0x07, 0xF8, 0x00, + 0xC1, 0xFE, 0x0C, 0x00, 0x7F, 0x80, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B3D9[ 31] = { /* code B3D9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xF8, 0x30, 0x01, 0x80, + 0x0F, 0xF0, 0x06, 0x07, 0xFF, 0x00, 0x00, 0x7F, + 0x06, 0x0C, 0x30, 0x60, 0xFE, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B514[ 31] = { /* code B514 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xEC, 0x30, 0x61, 0x83, + 0x0C, 0x18, 0x60, 0xC3, 0x06, 0x18, 0x30, 0xFF, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B77C[ 31] = { /* code B77C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xEC, 0x03, 0x60, 0x1B, + 0x0F, 0xD8, 0x60, 0xF3, 0x06, 0x18, 0x30, 0xFF, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B828[ 31] = { /* code B828 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xEC, 0x03, 0xE1, 0xFB, + 0x0C, 0x78, 0x60, 0xC3, 0xFE, 0x00, 0x30, 0x61, + 0x83, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B85C[ 31] = { /* code B85C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x60, 0xFF, + 0x06, 0x00, 0x30, 0x01, 0xFE, 0x01, 0x80, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B8CC[ 31] = { /* code B8CC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x61, 0xFF, + 0x0C, 0x00, 0x60, 0x03, 0xFE, 0x06, 0xC0, 0x36, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B984[ 31] = { /* code B984 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x60, 0xFF, + 0x06, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xF8, 0x00, + 0x03, 0xFC, 0x18, 0x60, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_B9C1[ 31] = { /* code B9C1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xEC, 0x03, 0x61, 0xFB, + 0x0C, 0x18, 0x60, 0xC3, 0xFE, 0x00, 0x30, 0x3F, + 0x03, 0x0C, 0x18, 0x60, 0x7E, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_BAA8[ 31] = { /* code BAA8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xF8, 0x18, 0xC0, 0xC6, + 0x06, 0x30, 0x31, 0x81, 0xFC, 0x01, 0x80, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_BC84[ 31] = { /* code BC84 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x6C, 0x33, 0x61, 0x9B, + 0x0F, 0xF8, 0x66, 0xC3, 0x36, 0x19, 0xB0, 0xFD, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_BC88[ 31] = { /* code BC88 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x6C, 0x33, 0x61, 0xFB, + 0x0C, 0xF8, 0x66, 0xC3, 0xF6, 0x00, 0x30, 0x61, + 0x83, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_BCF4[ 31] = { /* code BCF4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x0C, 0x18, 0x60, 0xFF, + 0x06, 0x18, 0x30, 0xC1, 0xFE, 0x01, 0x80, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C124[ 31] = { /* code C124 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x8C, 0x0C, 0x60, 0x7F, + 0x07, 0x98, 0xE6, 0xC0, 0x00, 0x0F, 0xF0, 0x01, + 0x83, 0xFC, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C218[ 31] = { /* code C218 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x7E, + 0x1E, 0x3C, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x0C, + 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C2A4[ 31] = { /* code C2A4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x3C, + 0x07, 0x70, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C2DC[ 31] = { /* code C2DC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x8C, 0x0C, 0x60, 0x63, + 0x03, 0x18, 0x3C, 0xC1, 0xE6, 0x19, 0xB1, 0x87, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C548[ 31] = { /* code C548 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xD8, 0x77, 0xC3, 0x1E, + 0x18, 0xFC, 0xEF, 0x83, 0xEC, 0x00, 0x60, 0xC3, + 0x06, 0x00, 0x30, 0x01, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C5B4[ 31] = { /* code C5B4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xCC, 0x37, 0x63, 0x1B, + 0x18, 0xF8, 0xC6, 0xC6, 0x36, 0x1B, 0x30, 0xF9, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C5B8[ 31] = { /* code C5B8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xEC, 0x3B, 0xE1, 0x8F, + 0x0C, 0x78, 0x77, 0xC1, 0xF6, 0x00, 0x30, 0x61, + 0x83, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C624[ 31] = { /* code C624 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xF0, 0x38, 0xE1, 0x83, + 0x0C, 0x18, 0x71, 0xC0, 0xFC, 0x01, 0x80, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C774[ 31] = { /* code C774 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xCC, 0x36, 0x63, 0x1B, + 0x18, 0xD8, 0xC6, 0xC6, 0x36, 0x1B, 0x30, 0xF9, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C77C[ 31] = { /* code C77C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xCC, 0x33, 0x61, 0x9B, + 0x0C, 0xD8, 0x3C, 0xC0, 0x00, 0x0F, 0xF0, 0x01, + 0x83, 0xFC, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C790[ 31] = { /* code C790 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xEC, 0x0C, 0x60, 0x63, + 0x03, 0x18, 0x3C, 0xF1, 0xE6, 0x19, 0xB1, 0x87, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C804[ 31] = { /* code C804 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xEC, 0x0C, 0x60, 0x7F, + 0x07, 0x98, 0x6C, 0xC6, 0x36, 0x00, 0x30, 0x61, + 0x83, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C815[ 31] = { /* code C815 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xEC, 0x0C, 0x60, 0x7F, + 0x07, 0x98, 0x6C, 0xC6, 0x36, 0x00, 0x00, 0x3F, + 0x03, 0x0C, 0x18, 0x60, 0x7E, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C81C[ 31] = { /* code C81C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x19, 0xE0, 0xCF, + 0x07, 0xF8, 0x33, 0xC3, 0xDE, 0x1E, 0xF1, 0x9F, + 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C870[ 31] = { /* code C870 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFC, 0x03, 0x00, 0x3C, + 0x03, 0x70, 0xF0, 0xE0, 0x30, 0x01, 0x80, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C885[ 31] = { /* code C885 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFC, 0x03, 0x00, 0x7C, + 0x0E, 0xF8, 0x06, 0x07, 0xFF, 0x00, 0x00, 0x3F, + 0x03, 0x0C, 0x18, 0x60, 0x7E, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C8FC[ 31] = { /* code C8FC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFC, 0x03, 0x00, 0x3C, + 0x03, 0x70, 0xF0, 0xE0, 0x00, 0x3F, 0xF8, 0x0C, + 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_C9DC[ 31] = { /* code C9DC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x1B, 0x60, 0xDB, + 0x06, 0xD8, 0x3E, 0xF3, 0xFE, 0x1B, 0xF1, 0xB3, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D06C[ 31] = { /* code D06C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x60, 0x03, + 0x00, 0x18, 0x7F, 0xC0, 0x06, 0x00, 0x60, 0x03, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D15C[ 31] = { /* code D15C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFE, 0x30, 0xF1, 0xFF, + 0x8C, 0x3C, 0x7F, 0xE0, 0x0F, 0x00, 0x00, 0x3F, + 0xC1, 0x86, 0x0C, 0x30, 0x7F, 0x80, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D30C[ 31] = { /* code D30C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x60, 0xDB, + 0x06, 0xD8, 0x36, 0xF1, 0xB6, 0x0D, 0xB1, 0xFF, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D3EC[ 31] = { /* code D3EC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0xEE, + 0x07, 0x70, 0x1B, 0x03, 0xFE, 0x01, 0x80, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D55C[ 31] = { /* code D55C */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x18, 0xFF, 0xC0, 0x06, + 0x0F, 0xB0, 0xC7, 0xE6, 0x3C, 0x1F, 0x60, 0x03, + 0x06, 0x00, 0x30, 0x01, 0xFF, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D568[ 31] = { /* code D568 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x1F, 0xF8, 0x00, 0xC1, 0xF6, + 0x18, 0xFC, 0xC7, 0x83, 0xEC, 0x00, 0x00, 0xFF, + 0x06, 0x18, 0x30, 0xC1, 0xFE, 0x00, 0x00 +}; + +const UCHAR abc_fontSimSunBold12_19h_D638[ 31] = { /* code D638 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x3F, 0xE0, 0x00, + 0x03, 0xF0, 0x30, 0xC1, 0x86, 0x07, 0xE0, 0x0C, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const BFC_CHARINFO fontSimSunBold12_19h_CharInfo[98] = { + { 17, 41, {abc_fontSimSunBold12_19h_000A} }, /* code 000A */ + { 8, 19, {abc_fontSimSunBold12_19h_000D} }, /* code 000D */ + { 9, 22, {abc_fontSimSunBold12_19h_0020} }, /* code 0020 */ + { 9, 22, {abc_fontSimSunBold12_19h_0031} }, /* code 0031 */ + { 9, 22, {abc_fontSimSunBold12_19h_0032} }, /* code 0032 */ + { 9, 22, {abc_fontSimSunBold12_19h_0053} }, /* code 0053 */ + { 9, 22, {abc_fontSimSunBold12_19h_0057} }, /* code 0057 */ + { 17, 41, {abc_fontSimSunBold12_19h_4E0D} }, /* code 4E0D */ + { 17, 41, {abc_fontSimSunBold12_19h_4E2D} }, /* code 4E2D */ + { 17, 41, {abc_fontSimSunBold12_19h_4EA7} }, /* code 4EA7 */ + { 17, 41, {abc_fontSimSunBold12_19h_4ECE} }, /* code 4ECE */ + { 17, 41, {abc_fontSimSunBold12_19h_4EF6} }, /* code 4EF6 */ + { 17, 41, {abc_fontSimSunBold12_19h_4F53} }, /* code 4F53 */ + { 17, 41, {abc_fontSimSunBold12_19h_4FE1} }, /* code 4FE1 */ + { 17, 41, {abc_fontSimSunBold12_19h_5173} }, /* code 5173 */ + { 17, 41, {abc_fontSimSunBold12_19h_5217} }, /* code 5217 */ + { 17, 41, {abc_fontSimSunBold12_19h_52A0} }, /* code 52A0 */ + { 17, 41, {abc_fontSimSunBold12_19h_52A8} }, /* code 52A8 */ + { 17, 41, {abc_fontSimSunBold12_19h_5305} }, /* code 5305 */ + { 17, 41, {abc_fontSimSunBold12_19h_53F7} }, /* code 53F7 */ + { 17, 41, {abc_fontSimSunBold12_19h_540D} }, /* code 540D */ + { 17, 41, {abc_fontSimSunBold12_19h_542B} }, /* code 542B */ + { 17, 41, {abc_fontSimSunBold12_19h_578B} }, /* code 578B */ + { 17, 41, {abc_fontSimSunBold12_19h_5C0F} }, /* code 5C0F */ + { 17, 41, {abc_fontSimSunBold12_19h_5E8F} }, /* code 5E8F */ + { 17, 41, {abc_fontSimSunBold12_19h_606F} }, /* code 606F */ + { 17, 41, {abc_fontSimSunBold12_19h_63A5} }, /* code 63A5 */ + { 17, 41, {abc_fontSimSunBold12_19h_6570} }, /* code 6570 */ + { 17, 41, {abc_fontSimSunBold12_19h_6587} }, /* code 6587 */ + { 17, 41, {abc_fontSimSunBold12_19h_65E0} }, /* code 65E0 */ + { 17, 41, {abc_fontSimSunBold12_19h_65E5} }, /* code 65E5 */ + { 17, 41, {abc_fontSimSunBold12_19h_65F6} }, /* code 65F6 */ + { 17, 41, {abc_fontSimSunBold12_19h_671F} }, /* code 671F */ + { 17, 41, {abc_fontSimSunBold12_19h_672C} }, /* code 672C */ + { 17, 41, {abc_fontSimSunBold12_19h_673A} }, /* code 673A */ + { 17, 41, {abc_fontSimSunBold12_19h_7248} }, /* code 7248 */ + { 17, 41, {abc_fontSimSunBold12_19h_7387} }, /* code 7387 */ + { 17, 41, {abc_fontSimSunBold12_19h_751F} }, /* code 751F */ + { 17, 41, {abc_fontSimSunBold12_19h_76D1} }, /* code 76D1 */ + { 17, 41, {abc_fontSimSunBold12_19h_79F0} }, /* code 79F0 */ + { 17, 41, {abc_fontSimSunBold12_19h_7A0B} }, /* code 7A0B */ + { 17, 41, {abc_fontSimSunBold12_19h_7B80} }, /* code 7B80 */ + { 17, 41, {abc_fontSimSunBold12_19h_7BA1} }, /* code 7BA1 */ + { 17, 41, {abc_fontSimSunBold12_19h_7CFB} }, /* code 7CFB */ + { 17, 41, {abc_fontSimSunBold12_19h_7EBF} }, /* code 7EBF */ + { 17, 41, {abc_fontSimSunBold12_19h_7EDF} }, /* code 7EDF */ + { 17, 41, {abc_fontSimSunBold12_19h_7F6E} }, /* code 7F6E */ + { 17, 41, {abc_fontSimSunBold12_19h_81EA} }, /* code 81EA */ + { 17, 41, {abc_fontSimSunBold12_19h_8A00} }, /* code 8A00 */ + { 17, 41, {abc_fontSimSunBold12_19h_8BBE} }, /* code 8BBE */ + { 17, 41, {abc_fontSimSunBold12_19h_8BED} }, /* code 8BED */ + { 17, 41, {abc_fontSimSunBold12_19h_8F6F} }, /* code 8F6F */ + { 17, 41, {abc_fontSimSunBold12_19h_8F7D} }, /* code 8F7D */ + { 17, 41, {abc_fontSimSunBold12_19h_8FDE} }, /* code 8FDE */ + { 17, 41, {abc_fontSimSunBold12_19h_9891} }, /* code 9891 */ + { 13, 31, {abc_fontSimSunBold12_19h_AC04} }, /* code AC04 */ + { 13, 31, {abc_fontSimSunBold12_19h_AD6D} }, /* code AD6D */ + { 13, 31, {abc_fontSimSunBold12_19h_ADDC} }, /* code ADDC */ + { 13, 31, {abc_fontSimSunBold12_19h_B0A0} }, /* code B0A0 */ + { 13, 31, {abc_fontSimSunBold12_19h_B354} }, /* code B354 */ + { 13, 31, {abc_fontSimSunBold12_19h_B378} }, /* code B378 */ + { 13, 31, {abc_fontSimSunBold12_19h_B3D9} }, /* code B3D9 */ + { 13, 31, {abc_fontSimSunBold12_19h_B514} }, /* code B514 */ + { 13, 31, {abc_fontSimSunBold12_19h_B77C} }, /* code B77C */ + { 13, 31, {abc_fontSimSunBold12_19h_B828} }, /* code B828 */ + { 13, 31, {abc_fontSimSunBold12_19h_B85C} }, /* code B85C */ + { 13, 31, {abc_fontSimSunBold12_19h_B8CC} }, /* code B8CC */ + { 13, 31, {abc_fontSimSunBold12_19h_B984} }, /* code B984 */ + { 13, 31, {abc_fontSimSunBold12_19h_B9C1} }, /* code B9C1 */ + { 13, 31, {abc_fontSimSunBold12_19h_BAA8} }, /* code BAA8 */ + { 13, 31, {abc_fontSimSunBold12_19h_BC84} }, /* code BC84 */ + { 13, 31, {abc_fontSimSunBold12_19h_BC88} }, /* code BC88 */ + { 13, 31, {abc_fontSimSunBold12_19h_BCF4} }, /* code BCF4 */ + { 13, 31, {abc_fontSimSunBold12_19h_C124} }, /* code C124 */ + { 13, 31, {abc_fontSimSunBold12_19h_C218} }, /* code C218 */ + { 13, 31, {abc_fontSimSunBold12_19h_C2A4} }, /* code C2A4 */ + { 13, 31, {abc_fontSimSunBold12_19h_C2DC} }, /* code C2DC */ + { 13, 31, {abc_fontSimSunBold12_19h_C548} }, /* code C548 */ + { 13, 31, {abc_fontSimSunBold12_19h_C5B4} }, /* code C5B4 */ + { 13, 31, {abc_fontSimSunBold12_19h_C5B8} }, /* code C5B8 */ + { 13, 31, {abc_fontSimSunBold12_19h_C624} }, /* code C624 */ + { 13, 31, {abc_fontSimSunBold12_19h_C774} }, /* code C774 */ + { 13, 31, {abc_fontSimSunBold12_19h_C77C} }, /* code C77C */ + { 13, 31, {abc_fontSimSunBold12_19h_C790} }, /* code C790 */ + { 13, 31, {abc_fontSimSunBold12_19h_C804} }, /* code C804 */ + { 13, 31, {abc_fontSimSunBold12_19h_C815} }, /* code C815 */ + { 13, 31, {abc_fontSimSunBold12_19h_C81C} }, /* code C81C */ + { 13, 31, {abc_fontSimSunBold12_19h_C870} }, /* code C870 */ + { 13, 31, {abc_fontSimSunBold12_19h_C885} }, /* code C885 */ + { 13, 31, {abc_fontSimSunBold12_19h_C8FC} }, /* code C8FC */ + { 13, 31, {abc_fontSimSunBold12_19h_C9DC} }, /* code C9DC */ + { 13, 31, {abc_fontSimSunBold12_19h_D06C} }, /* code D06C */ + { 13, 31, {abc_fontSimSunBold12_19h_D15C} }, /* code D15C */ + { 13, 31, {abc_fontSimSunBold12_19h_D30C} }, /* code D30C */ + { 13, 31, {abc_fontSimSunBold12_19h_D3EC} }, /* code D3EC */ + { 13, 31, {abc_fontSimSunBold12_19h_D55C} }, /* code D55C */ + { 13, 31, {abc_fontSimSunBold12_19h_D568} }, /* code D568 */ + { 13, 31, {abc_fontSimSunBold12_19h_D638} } /* code D638 */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop97 = { + 0xD638, /* first character */ + 0xD638, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 97], /* address of first character */ + (const BFC_FONT_PROP *)0 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop96 = { + 0xD568, /* first character */ + 0xD568, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 96], /* address of first character */ + &fontSimSunBold12_19h_Prop97 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop95 = { + 0xD55C, /* first character */ + 0xD55C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 95], /* address of first character */ + &fontSimSunBold12_19h_Prop96 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop94 = { + 0xD3EC, /* first character */ + 0xD3EC, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 94], /* address of first character */ + &fontSimSunBold12_19h_Prop95 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop93 = { + 0xD30C, /* first character */ + 0xD30C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 93], /* address of first character */ + &fontSimSunBold12_19h_Prop94 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop92 = { + 0xD15C, /* first character */ + 0xD15C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 92], /* address of first character */ + &fontSimSunBold12_19h_Prop93 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop91 = { + 0xD06C, /* first character */ + 0xD06C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 91], /* address of first character */ + &fontSimSunBold12_19h_Prop92 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop90 = { + 0xC9DC, /* first character */ + 0xC9DC, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 90], /* address of first character */ + &fontSimSunBold12_19h_Prop91 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop89 = { + 0xC8FC, /* first character */ + 0xC8FC, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 89], /* address of first character */ + &fontSimSunBold12_19h_Prop90 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop88 = { + 0xC885, /* first character */ + 0xC885, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 88], /* address of first character */ + &fontSimSunBold12_19h_Prop89 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop87 = { + 0xC870, /* first character */ + 0xC870, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 87], /* address of first character */ + &fontSimSunBold12_19h_Prop88 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop86 = { + 0xC81C, /* first character */ + 0xC81C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 86], /* address of first character */ + &fontSimSunBold12_19h_Prop87 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop85 = { + 0xC815, /* first character */ + 0xC815, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 85], /* address of first character */ + &fontSimSunBold12_19h_Prop86 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop84 = { + 0xC804, /* first character */ + 0xC804, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 84], /* address of first character */ + &fontSimSunBold12_19h_Prop85 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop83 = { + 0xC790, /* first character */ + 0xC790, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 83], /* address of first character */ + &fontSimSunBold12_19h_Prop84 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop82 = { + 0xC77C, /* first character */ + 0xC77C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 82], /* address of first character */ + &fontSimSunBold12_19h_Prop83 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop81 = { + 0xC774, /* first character */ + 0xC774, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 81], /* address of first character */ + &fontSimSunBold12_19h_Prop82 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop80 = { + 0xC624, /* first character */ + 0xC624, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 80], /* address of first character */ + &fontSimSunBold12_19h_Prop81 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop79 = { + 0xC5B8, /* first character */ + 0xC5B8, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 79], /* address of first character */ + &fontSimSunBold12_19h_Prop80 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop78 = { + 0xC5B4, /* first character */ + 0xC5B4, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 78], /* address of first character */ + &fontSimSunBold12_19h_Prop79 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop77 = { + 0xC548, /* first character */ + 0xC548, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 77], /* address of first character */ + &fontSimSunBold12_19h_Prop78 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop76 = { + 0xC2DC, /* first character */ + 0xC2DC, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 76], /* address of first character */ + &fontSimSunBold12_19h_Prop77 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop75 = { + 0xC2A4, /* first character */ + 0xC2A4, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 75], /* address of first character */ + &fontSimSunBold12_19h_Prop76 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop74 = { + 0xC218, /* first character */ + 0xC218, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 74], /* address of first character */ + &fontSimSunBold12_19h_Prop75 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop73 = { + 0xC124, /* first character */ + 0xC124, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 73], /* address of first character */ + &fontSimSunBold12_19h_Prop74 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop72 = { + 0xBCF4, /* first character */ + 0xBCF4, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 72], /* address of first character */ + &fontSimSunBold12_19h_Prop73 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop71 = { + 0xBC88, /* first character */ + 0xBC88, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 71], /* address of first character */ + &fontSimSunBold12_19h_Prop72 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop70 = { + 0xBC84, /* first character */ + 0xBC84, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 70], /* address of first character */ + &fontSimSunBold12_19h_Prop71 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop69 = { + 0xBAA8, /* first character */ + 0xBAA8, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 69], /* address of first character */ + &fontSimSunBold12_19h_Prop70 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop68 = { + 0xB9C1, /* first character */ + 0xB9C1, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 68], /* address of first character */ + &fontSimSunBold12_19h_Prop69 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop67 = { + 0xB984, /* first character */ + 0xB984, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 67], /* address of first character */ + &fontSimSunBold12_19h_Prop68 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop66 = { + 0xB8CC, /* first character */ + 0xB8CC, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 66], /* address of first character */ + &fontSimSunBold12_19h_Prop67 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop65 = { + 0xB85C, /* first character */ + 0xB85C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 65], /* address of first character */ + &fontSimSunBold12_19h_Prop66 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop64 = { + 0xB828, /* first character */ + 0xB828, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 64], /* address of first character */ + &fontSimSunBold12_19h_Prop65 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop63 = { + 0xB77C, /* first character */ + 0xB77C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 63], /* address of first character */ + &fontSimSunBold12_19h_Prop64 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop62 = { + 0xB514, /* first character */ + 0xB514, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 62], /* address of first character */ + &fontSimSunBold12_19h_Prop63 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop61 = { + 0xB3D9, /* first character */ + 0xB3D9, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 61], /* address of first character */ + &fontSimSunBold12_19h_Prop62 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop60 = { + 0xB378, /* first character */ + 0xB378, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 60], /* address of first character */ + &fontSimSunBold12_19h_Prop61 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop59 = { + 0xB354, /* first character */ + 0xB354, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 59], /* address of first character */ + &fontSimSunBold12_19h_Prop60 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop58 = { + 0xB0A0, /* first character */ + 0xB0A0, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 58], /* address of first character */ + &fontSimSunBold12_19h_Prop59 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop57 = { + 0xADDC, /* first character */ + 0xADDC, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 57], /* address of first character */ + &fontSimSunBold12_19h_Prop58 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop56 = { + 0xAD6D, /* first character */ + 0xAD6D, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 56], /* address of first character */ + &fontSimSunBold12_19h_Prop57 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop55 = { + 0xAC04, /* first character */ + 0xAC04, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 55], /* address of first character */ + &fontSimSunBold12_19h_Prop56 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop54 = { + 0x9891, /* first character */ + 0x9891, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 54], /* address of first character */ + &fontSimSunBold12_19h_Prop55 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop53 = { + 0x8FDE, /* first character */ + 0x8FDE, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 53], /* address of first character */ + &fontSimSunBold12_19h_Prop54 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop52 = { + 0x8F7D, /* first character */ + 0x8F7D, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 52], /* address of first character */ + &fontSimSunBold12_19h_Prop53 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop51 = { + 0x8F6F, /* first character */ + 0x8F6F, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 51], /* address of first character */ + &fontSimSunBold12_19h_Prop52 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop50 = { + 0x8BED, /* first character */ + 0x8BED, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 50], /* address of first character */ + &fontSimSunBold12_19h_Prop51 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop49 = { + 0x8BBE, /* first character */ + 0x8BBE, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 49], /* address of first character */ + &fontSimSunBold12_19h_Prop50 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop48 = { + 0x8A00, /* first character */ + 0x8A00, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 48], /* address of first character */ + &fontSimSunBold12_19h_Prop49 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop47 = { + 0x81EA, /* first character */ + 0x81EA, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 47], /* address of first character */ + &fontSimSunBold12_19h_Prop48 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop46 = { + 0x7F6E, /* first character */ + 0x7F6E, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 46], /* address of first character */ + &fontSimSunBold12_19h_Prop47 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop45 = { + 0x7EDF, /* first character */ + 0x7EDF, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 45], /* address of first character */ + &fontSimSunBold12_19h_Prop46 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop44 = { + 0x7EBF, /* first character */ + 0x7EBF, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 44], /* address of first character */ + &fontSimSunBold12_19h_Prop45 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop43 = { + 0x7CFB, /* first character */ + 0x7CFB, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 43], /* address of first character */ + &fontSimSunBold12_19h_Prop44 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop42 = { + 0x7BA1, /* first character */ + 0x7BA1, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 42], /* address of first character */ + &fontSimSunBold12_19h_Prop43 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop41 = { + 0x7B80, /* first character */ + 0x7B80, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 41], /* address of first character */ + &fontSimSunBold12_19h_Prop42 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop40 = { + 0x7A0B, /* first character */ + 0x7A0B, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 40], /* address of first character */ + &fontSimSunBold12_19h_Prop41 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop39 = { + 0x79F0, /* first character */ + 0x79F0, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 39], /* address of first character */ + &fontSimSunBold12_19h_Prop40 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop38 = { + 0x76D1, /* first character */ + 0x76D1, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 38], /* address of first character */ + &fontSimSunBold12_19h_Prop39 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop37 = { + 0x751F, /* first character */ + 0x751F, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 37], /* address of first character */ + &fontSimSunBold12_19h_Prop38 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop36 = { + 0x7387, /* first character */ + 0x7387, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 36], /* address of first character */ + &fontSimSunBold12_19h_Prop37 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop35 = { + 0x7248, /* first character */ + 0x7248, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 35], /* address of first character */ + &fontSimSunBold12_19h_Prop36 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop34 = { + 0x673A, /* first character */ + 0x673A, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 34], /* address of first character */ + &fontSimSunBold12_19h_Prop35 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop33 = { + 0x672C, /* first character */ + 0x672C, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 33], /* address of first character */ + &fontSimSunBold12_19h_Prop34 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop32 = { + 0x671F, /* first character */ + 0x671F, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 32], /* address of first character */ + &fontSimSunBold12_19h_Prop33 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop31 = { + 0x65F6, /* first character */ + 0x65F6, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 31], /* address of first character */ + &fontSimSunBold12_19h_Prop32 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop30 = { + 0x65E5, /* first character */ + 0x65E5, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 30], /* address of first character */ + &fontSimSunBold12_19h_Prop31 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop29 = { + 0x65E0, /* first character */ + 0x65E0, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 29], /* address of first character */ + &fontSimSunBold12_19h_Prop30 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop28 = { + 0x6587, /* first character */ + 0x6587, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 28], /* address of first character */ + &fontSimSunBold12_19h_Prop29 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop27 = { + 0x6570, /* first character */ + 0x6570, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 27], /* address of first character */ + &fontSimSunBold12_19h_Prop28 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop26 = { + 0x63A5, /* first character */ + 0x63A5, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 26], /* address of first character */ + &fontSimSunBold12_19h_Prop27 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop25 = { + 0x606F, /* first character */ + 0x606F, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 25], /* address of first character */ + &fontSimSunBold12_19h_Prop26 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop24 = { + 0x5E8F, /* first character */ + 0x5E8F, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 24], /* address of first character */ + &fontSimSunBold12_19h_Prop25 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop23 = { + 0x5C0F, /* first character */ + 0x5C0F, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 23], /* address of first character */ + &fontSimSunBold12_19h_Prop24 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop22 = { + 0x578B, /* first character */ + 0x578B, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 22], /* address of first character */ + &fontSimSunBold12_19h_Prop23 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop21 = { + 0x542B, /* first character */ + 0x542B, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 21], /* address of first character */ + &fontSimSunBold12_19h_Prop22 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop20 = { + 0x540D, /* first character */ + 0x540D, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 20], /* address of first character */ + &fontSimSunBold12_19h_Prop21 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop19 = { + 0x53F7, /* first character */ + 0x53F7, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 19], /* address of first character */ + &fontSimSunBold12_19h_Prop20 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop18 = { + 0x5305, /* first character */ + 0x5305, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 18], /* address of first character */ + &fontSimSunBold12_19h_Prop19 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop17 = { + 0x52A8, /* first character */ + 0x52A8, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 17], /* address of first character */ + &fontSimSunBold12_19h_Prop18 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop16 = { + 0x52A0, /* first character */ + 0x52A0, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 16], /* address of first character */ + &fontSimSunBold12_19h_Prop17 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop15 = { + 0x5217, /* first character */ + 0x5217, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 15], /* address of first character */ + &fontSimSunBold12_19h_Prop16 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop14 = { + 0x5173, /* first character */ + 0x5173, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 14], /* address of first character */ + &fontSimSunBold12_19h_Prop15 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop13 = { + 0x4FE1, /* first character */ + 0x4FE1, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 13], /* address of first character */ + &fontSimSunBold12_19h_Prop14 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop12 = { + 0x4F53, /* first character */ + 0x4F53, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 12], /* address of first character */ + &fontSimSunBold12_19h_Prop13 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop11 = { + 0x4EF6, /* first character */ + 0x4EF6, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 11], /* address of first character */ + &fontSimSunBold12_19h_Prop12 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop10 = { + 0x4ECE, /* first character */ + 0x4ECE, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 10], /* address of first character */ + &fontSimSunBold12_19h_Prop11 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop9 = { + 0x4EA7, /* first character */ + 0x4EA7, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 9], /* address of first character */ + &fontSimSunBold12_19h_Prop10 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop8 = { + 0x4E2D, /* first character */ + 0x4E2D, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 8], /* address of first character */ + &fontSimSunBold12_19h_Prop9 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop7 = { + 0x4E0D, /* first character */ + 0x4E0D, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 7], /* address of first character */ + &fontSimSunBold12_19h_Prop8 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop6 = { + 0x0057, /* first character */ + 0x0057, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 6], /* address of first character */ + &fontSimSunBold12_19h_Prop7 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop5 = { + 0x0053, /* first character */ + 0x0053, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 5], /* address of first character */ + &fontSimSunBold12_19h_Prop6 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop4 = { + 0x0031, /* first character */ + 0x0032, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 3], /* address of first character */ + &fontSimSunBold12_19h_Prop5 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop3 = { + 0x0020, /* first character */ + 0x0020, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 2], /* address of first character */ + &fontSimSunBold12_19h_Prop4 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop2 = { + 0x000D, /* first character */ + 0x000D, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 1], /* address of first character */ + &fontSimSunBold12_19h_Prop3 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT_PROP fontSimSunBold12_19h_Prop1 = { + 0x000A, /* first character */ + 0x000A, /* last character */ + &fontSimSunBold12_19h_CharInfo[ 0], /* address of first character */ + &fontSimSunBold12_19h_Prop2 /* pointer to next BFC_FONT_PROP */ +}; + +const BFC_FONT fontSimSunBold12_19h = { + 0x01020802, /* font type = FONTTYPE_PROP | DATA_PACKED | ENCODING_UNICODE | DATALENGTH_8 */ + 19, /* font height in pixels */ + 17, /* font ascent (baseline) in pixels */ + 0 , /* reversed, =0 */ + {&fontSimSunBold12_19h_Prop1} +}; diff --git a/source/Fonts/bfcfont.h b/source/Fonts/bfcfont.h new file mode 100644 index 0000000..cd9750b --- /dev/null +++ b/source/Fonts/bfcfont.h @@ -0,0 +1,137 @@ +/**************************************************************************** +* * +* Copyright (c) 2012, Iseatech Software. All rights reserved. * +* Internet: http://www.iseasoft.com/bitfontcreator.htm * +* Support: support@iseatech.com * +* * +***************************************************************************** +* * +* @file bfcfont.h * +* @version 0.3.1.0 * +* @date Mar-28-2016 * +* @brief BitFontCreator (Pro & Grayscale) font header include file * +* * +*****************************************************************************/ + +#ifndef _BFC_FONT_H_ +#define _BFC_FONT_H_ + +#define UCHAR unsigned char +#define USHORT unsigned short +#define ULONG unsigned long + +#define FONTTYPE_MONO (1<<0) /* Is monospaced font */ +#define FONTTYPE_PROP (1<<1) /* Is proportional font */ +#define FONTTYPE_MONO_AA2 (1<<2) /* Is an antialiased mono font, 2bpp */ +#define FONTTYPE_MONO_AA4 (1<<3) /* Is an antialiased mono font, 4bpp */ +#define FONTTYPE_MONO_AA8 (1<<4) /* Is an antialiased mono font, 8bpp */ +#define FONTTYPE_PROP_AA2 (1<<5) /* Is an antialiased prop font, 2bpp */ +#define FONTTYPE_PROP_AA4 (1<<6) /* Is an antialiased prop font, 4bpp */ +#define FONTTYPE_PROP_AA8 (1<<7) /* Is an antialiased prop font, 8bpp */ + +/* the following 4 flags are added since BitFontCreator Pro v3.7 & Grayscale v4.5 */ +#define LITTLEENDIAN (1<<8) /* Is Little Endian if set, or is Big Endian (default) */ //LITTLE_ENDIAN already defined. 2/9/22 bkb +#define COLUMN_BASED (1<<9) /* Is Column if set, or is Row (default) */ +#define COLUMN_PREFERRED (1<<10) /* Is Column if set, or is Row (default) */ +#define DATA_PACKED (1<<11) /* Is Packed if set, or is Unpacked (default) */ + +#define ENCODING_ASCII (1<<16) /* Character encoding: Ascii + ISO8859 */ +#define ENCODING_UNICODE (1<<17) /* Character encoding: Unicode */ +#define ENCODING_SHIFTJIS (1<<18) /* Character encoding: Shift_JIS */ +#define ENCODING_BIG5 (1<<19) /* Character encoding: Big5 */ +#define ENCODING_GBK (1<<20) /* Character encoding: GBK */ +#define ENCODING_JOHAB (1<<21) /* Character encoding: Johab */ + +#define DATALENGTH_8 (1<<24) /* Data length: 8 bits per unit (1 byte) */ +#define DATALENGTH_16 (1<<25) /* Data length: 16 bits per unit (2 bytes) */ +#define DATALENGTH_32 (1<<26) /* Data length: 32 bits per unit (4 bytes) */ + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + + +/********************************************************************* +* C font structures +**********************************************************************/ +typedef struct BFC_CHARINFO +{ + USHORT Width; /* character width in pixels */ + USHORT DataSize; /* # bytes/words/dwords of pixel data */ + union + { + const void *pData; + const UCHAR *pData8; /* pixel data in bytes */ + const USHORT *pData16; /* pixel data in words */ + const ULONG *pData32; /* pixel data in dwords */ + } p; +} BFC_CHARINFO; + +typedef struct BFC_FONT_PROP //proportional font +{ + USHORT FirstChar; /* index of first character */ + USHORT LastChar; /* index of last character */ + const BFC_CHARINFO *pFirstCharInfo; /* address of first character */ + const struct BFC_FONT_PROP *pNextProp; /* pointer to next BFC_FONT_PROP */ +} BFC_FONT_PROP; + +typedef struct BFC_FONT_MONO //monospace font +{ + USHORT FirstChar; /* index of first character */ + USHORT LastChar; /* index of last character */ + USHORT FontWidth; /* font width in pixels */ + USHORT DataSize; /* # bytes/words/dwords data of single character */ + union + { + const void *pData; + const UCHAR *pData8; /* pixel data in bytes */ + const USHORT *pData16; /* pixel data in words */ + const ULONG *pData32; /* pixel data in dwords */ + } p; +} BFC_FONT_MONO; + +typedef struct +{ + ULONG FontType; /* font type */ + USHORT FontHeight; /* font height in pixels */ + USHORT Baseline; /* font ascent (baseline) in pixels */ + ULONG Reversed; /* reversed, =0 */ + union + { + const void * pData; + const BFC_FONT_MONO * pMono; /* point to Monospaced font */ + const BFC_FONT_PROP * pProp; /* point to proportional font */ + } p; +} BFC_FONT; + + +/********************************************************************* +* Binary font structures (BIN) +**********************************************************************/ +typedef struct +{ + ULONG FontType; /* font type */ + USHORT FontHeight; /* font height in pixels */ + USHORT Baseline; /* font ascent (baseline) in pixels */ + USHORT Reversed; /* reversed, =0 */ + USHORT NumRanges; /* number of character ranges */ +} BFC_BIN_FONT; + +typedef struct +{ + USHORT FirstChar; /* index of first character */ + USHORT LastChar; /* index of last charcter */ +} BFC_BIN_CHARRANGE; + +typedef struct +{ + USHORT Width; /* character width in pixels */ + USHORT DataSize; /* # bytes/words/dwords of pixel data */ + ULONG OffData; /* Offset of pixel data */ +} BFC_BIN_CHARINFO; + +#ifdef __cplusplus +} +#endif + +#endif //#ifndef _BFC_FONT_H_ diff --git a/source/Fonts/fontLibrary.c b/source/Fonts/fontLibrary.c new file mode 100644 index 0000000..d8faae7 --- /dev/null +++ b/source/Fonts/fontLibrary.c @@ -0,0 +1,278 @@ +/* + * fontLibrary.c + * + * Created on: Feb 9, 2022 + * Author: Brian.Bailey + */ + + +#include +#include + +#include "fontLibrary.h" +#include "translate.h" +#include "lcd.h" +#include "System/system.h" + +//UTF8 Decode +// Copyright (c) 2008-2009 Bjoern Hoehrmann +// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 1 + +static const uint8_t utf8d[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 +}; + +uint32_t FL_Decode(uint32_t* state, uint32_t* codep, uint32_t byte) //removed inline to make compiler happy +{ + uint32_t type = utf8d[byte]; + + *codep = (*state != UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + *state*16 + type]; + return *state; +} + + + +/** + * Get information about first codepoint in a UTF8-encoded string + * + * \param str UTF8-encoded string + * \param codepoint Font to draw string in + * \param charCount number of characters in the codepoint + * \return UTF8_ACCEPT if valid, UTF8_REJECT otherwise + */ +uint32_t FL_GetCodepointInfo(const char * str, uint32_t * codepoint, uint32_t * charCount) +{ + uint32_t state = 0; + uint32_t count = 0; //character count + for(; *str; ++str) + { + count++; + if(!FL_Decode(&state, codepoint, *str)) + { + //found the codepoint + *charCount = count; + return state; + } + } + +} + + + +uint32_t FL_GetFontHeight(const BFC_FONT * font) +{ + return font->FontHeight; +} + + +// +void FL_DrawTranslatedString(const char *str, int16_t x, int16_t y, const BFC_FONT *pFont, LCD_DRAWMODE_t drawMode, FL_ALIGN align) +{ + if(SYS_GetLanguage() < LANG_CHINESE) //Use normal fonts if language NOT Chinese or Korean + { + FL_DrawString(Translate(str), x, y, pFont, drawMode, align); + } + else //Chinese or Korean - Use simsun font + { + //if translate returns different pointer, the translation was not found. + char * strTranslated = 0; + strTranslated = (char *)Translate(str); + if(strTranslated == str) + { + //Translation string not found. Use English (So we can see the problem!) + FL_DrawString(Translate(str), x, y, pFont, drawMode, align); + } + else + { + //Translation successful + FL_DrawString(Translate(str), x, y, fontSimsun, drawMode, align); + } + } + //FL_DrawString(Translate(str), x, y, pFont, drawMode, align); +} + +//Draw a null terminated UTF8 encoded string +void FL_DrawString(const char *str, int16_t x, int16_t y, const BFC_FONT *pFont, LCD_DRAWMODE_t drawMode, FL_ALIGN align) +{ + + switch(align) + { + case FL_ALIGN_LEFT: + break; + case FL_ALIGN_CENTER: + x -= (FL_GetStringLengthInPixels(str, pFont)) >> 1; + break; + case FL_ALIGN_RIGHT: + x -= FL_GetStringLengthInPixels(str, pFont); + break; + default: + break; + } + + uint32_t error = 0; + uint32_t index = 0; + while(str[index] != '\0' && !error) + { + uint32_t codepoint; //UTF8 code + uint32_t charCount; //number of chars in the current codepoint + if(FL_GetCodepointInfo(&str[index], &codepoint, &charCount)) + { + codepoint = 0x000A; //not valid UTF8 codepoint so return a distinctive char + charCount = 1; //assume 1 byte consumed. It might be wrong but we won't skip any bytes + } + index += charCount; //Advance index by number of chars consumed from string + + x += FL_DrawChar(codepoint, x, y, pFont, drawMode); //advance x coordinate by glyph width + } +} + + +/* Draw a character to the framebuffer + * Encode: Unicode + * Data length: 8 bits + * Invert bits: No + * 1 bpp + * Data format: Big Endian, Row based, Row preferred, Packed + */ +uint32_t FL_DrawChar(uint16_t codepoint, int x0, int y0, const BFC_FONT *pFont, LCD_DRAWMODE_t drawMode) +{ + // 1. find the character information first + const BFC_CHARINFO *pCharInfo = FL_GetCharInfo(pFont, (unsigned short)codepoint); //cast for this function + + if( pCharInfo != 0 ) + { + int height = pFont->FontHeight; + int width = pCharInfo->Width; + int data_size = pCharInfo->DataSize; // # bytes of the data array + const unsigned char *pData = pCharInfo->p.pData8; // pointer to data array + + int x, y; //pixel coordinates within the glyph + unsigned char data; + + uint32_t packedDataSize = 8; //8-bit data ONLY + uint32_t bitPosition = packedDataSize-1; //bit position in the byte + uint32_t byteIndex = 0; + + unsigned char bitMask[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; + + // 2. draw all the pixels in this character + for(y=0; yWidth; + } + + return widthInPixels; +} + + + +const BFC_CHARINFO* FL_GetCharInfo(const BFC_FONT *pFont, unsigned short ch) +{ + const BFC_CHARINFO *pCharInfo = 0; + const BFC_FONT_PROP *pProp = pFont->p.pProp; + unsigned short first_char, last_char; + + if(pFont == 0 || pFont->p.pProp == 0) + return 0; + + while(pProp != 0) + { + first_char = pProp->FirstChar; + last_char = pProp->LastChar; + pCharInfo = pProp->pFirstCharInfo; + + if( ch >= first_char && ch <= last_char ) + { + // the character "ch" is inside this range, + // return this char info, and not search anymore. + pCharInfo = pCharInfo + (ch - first_char); + return pCharInfo; + } + else + { + // the character "ch" is not in this range + // so search it in the next range + pProp = pProp->pNextProp; + } + } + + // if the character "ch" is not rendered in this font, + // we use the first character in this font as the default one. + if( pCharInfo == 0 ) + { + pProp = pFont->p.pProp; + pCharInfo = pProp->pFirstCharInfo; + } + + return pCharInfo; +} + + + + diff --git a/source/Fonts/fontLibrary.h b/source/Fonts/fontLibrary.h new file mode 100644 index 0000000..069b134 --- /dev/null +++ b/source/Fonts/fontLibrary.h @@ -0,0 +1,54 @@ +/* + * fontLibrary.h + * + * Created on: Feb 9, 2022 + * Author: Brian.Bailey + */ + +#ifndef FONTS_FONTLIBRARY_H_ +#define FONTS_FONTLIBRARY_H_ + +#include +#include "../lcd.h" //include for LCD_DRAW_MODE_t +#include "translate.h" + + +//extern all fonts (required) +extern const BFC_FONT fontCalibriBoldBasic10_15h[]; +extern const BFC_FONT fontCalibriBoldBasic11_18h[]; +extern const BFC_FONT fontCalibriBoldBasic12_19h[]; +extern const BFC_FONT fontCalibriBoldBasic14_23h[]; +extern const BFC_FONT fontCalibriBoldBasic16_26h[]; +extern const BFC_FONT fontCalibriBoldBasic18_29h[]; + +extern const BFC_FONT fontSimSunBold12_19h[]; + +//quick names for fonts (optional) +#define font10Bold fontCalibriBoldBasic10_15h +#define font11Bold fontCalibriBoldBasic11_18h +#define font12Bold fontCalibriBoldBasic12_19h +#define font14Bold fontCalibriBoldBasic14_23h +#define font16Bold fontCalibriBoldBasic16_26h +#define font18Bold fontCalibriBoldBasic18_29h + +#define fontSimsun fontSimSunBold12_19h + +typedef enum { + FL_ALIGN_LEFT, + FL_ALIGN_CENTER, + FL_ALIGN_RIGHT, + FL_ALIGN_NUM +} FL_ALIGN; + + +uint32_t FL_GetCodepointInfo(const char * str, uint32_t * codepoint, uint32_t * charCount); +uint32_t FL_GetFontHeight(const BFC_FONT * font); +void FL_DrawTranslatedString(const char *str, int16_t x, int16_t y, const BFC_FONT *pFont, LCD_DRAWMODE_t drawMode, FL_ALIGN align); +void FL_DrawString(const char *str, int16_t x, int16_t y, const BFC_FONT *font, LCD_DRAWMODE_t drawMode, FL_ALIGN align); +uint32_t FL_DrawChar(uint16_t codepoint, int x0, int y0, const BFC_FONT *pFont, LCD_DRAWMODE_t drawMode); +uint32_t FL_GetStringLengthInPixels(const char * str, const BFC_FONT *pFont); +const BFC_CHARINFO* FL_GetCharInfo(const BFC_FONT *pFont, unsigned short ch); + + + +#endif /* FONTS_FONTLIBRARY_H_ */ diff --git a/source/Fonts/languages.h b/source/Fonts/languages.h new file mode 100644 index 0000000..1af718c --- /dev/null +++ b/source/Fonts/languages.h @@ -0,0 +1,35 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + +#ifndef FONTS_LANGUAGES_H_ +#define FONTS_LANGUAGES_H_ + +extern const char * textEnglish[]; +extern const char * textSpanish[]; +extern const char * textFrench[]; +extern const char * textGerman[]; +extern const char * textItalian[]; +extern const char * textPolish[]; +extern const char * textDutch[]; +extern const char * textPortuguese[]; +extern const char * textRussian[]; +extern const char * textSwedish[]; +extern const char * textDanish[]; +extern const char * textEstonian[]; +extern const char * textLatvian[]; +extern const char * textLithuanian[]; +extern const char * textCzech[]; +extern const char * textFinnish[]; +extern const char * textGreek[]; +extern const char * textNorwegian[]; +extern const char * textHungarian[]; +extern const char * textRomanian[]; +extern const char * textChinese[]; +extern const char * textKorean[]; + +#endif /* FONTS_LANGUAGES_H_ */ + diff --git a/source/Fonts/textChinese.c b/source/Fonts/textChinese.c new file mode 100644 index 0000000..1c389a6 --- /dev/null +++ b/source/Fonts/textChinese.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textChinese[] = +{ + "1 小时", + "2 小时", + "自动关机", + "包含", + "频率", + "频率", + "小时数", + "语言", + "无线连接", + "语言", + "无线连接", + "加载程序版本", + "生产日期", + "型号名称", + "从不", + "监管信息", + "监管", + "设置", + "系统信息", + "序列号", + "软件版本", + "系统信息", +}; + diff --git a/source/Fonts/textCzech.c b/source/Fonts/textCzech.c new file mode 100644 index 0000000..4ab6761 --- /dev/null +++ b/source/Fonts/textCzech.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 6/26/2024 + * Author: Brian.Bailey + */ + + +const char * textCzech[] = +{ + "1 HODINA", + "2 HODINY", + "Auto. vypnutí", + "Obsahuje", + "FREKVENCE", + "Frekvence", + "Počet hodin", + "JAZYK", + "RÁDIOVÉ SPOJENÍ", + "Jazyk", + "Rádiové spojení", + "Verze zavaděče", + "Datum výroby", + "Název modelu", + "NIKDY", + "REGULAČNÍ INFORMACE", + "Právní předpisy", + "NASTAVENÍ", + "SYSTÉMOVÉ INFO", + "Sériové číslo", + "Verze softwaru", + "Systém. infor.", +}; + diff --git a/source/Fonts/textDanish.c b/source/Fonts/textDanish.c new file mode 100644 index 0000000..09fea4d --- /dev/null +++ b/source/Fonts/textDanish.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textDanish[] = +{ + "1 TIME", + "2 TIMER", + "Auto nedlukning", + "Indeholder", + "FREKVENSER", + "Frekvenser", + "Antal timer", + "SPROG", + "LINK RADIO", + "Sprog", + "Link radio", + "Loader-version", + "Fremst.dato", + "Modelnavn", + "ALDRIG", + "LOVGIVNINGSMÆSSIGE OPLYSNINGER", + "Lovgivning", + "INDSTILLINGER", + "SYSTEMOPLYSNINGER", + "Serienummer", + "Softwarev.", + "Systeminfo", +}; + diff --git a/source/Fonts/textDutch.c b/source/Fonts/textDutch.c new file mode 100644 index 0000000..f41393e --- /dev/null +++ b/source/Fonts/textDutch.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textDutch[] = +{ + "1 UUR", + "2 UUR", + "Automatisch uit", + "Bevat", + "FREQUENTIES", + "Frequenties", + "Aantal uur", + "TAAL", + "LINKRADIO", + "Taal", + "Linkradio", + "Versie loader", + "Productiedatum", + "Modelnaam", + "NOOIT", + "WETTELIJKE INFORMATIE", + "Wettelijke info", + "INSTELLINGEN", + "SYSTEEMINFORMATIE", + "Serienummer", + "Softwareversie", + "Systeeminformatie", +}; + diff --git a/source/Fonts/textEnglish.c b/source/Fonts/textEnglish.c new file mode 100644 index 0000000..034f967 --- /dev/null +++ b/source/Fonts/textEnglish.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textEnglish[] = +{ + "1 HOUR", + "2 HOURS", + "Auto Shutdown", + "Contains", + "FREQUENCIES", + "Frequencies", + "Hour Count", + "LANGUAGE", + "LINK RADIO", + "Language", + "Link Radio", + "Loader Version", + "Manufacture Date", + "Model Name", + "NEVER", + "REGULATORY INFO", + "Regulatory", + "SETTINGS", + "SYSTEM INFO", + "Serial Number", + "Software Version", + "System Information", +}; + diff --git a/source/Fonts/textEstonian.c b/source/Fonts/textEstonian.c new file mode 100644 index 0000000..38796f3 --- /dev/null +++ b/source/Fonts/textEstonian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textEstonian[] = +{ + "1 TUND", + "2 TUNDI", + "Autom. väljalülitus", + "Sisaldab", + "SAGEDUSED", + "Sagedused", + "Töötunnid", + "KEEL", + "SEO RAADIO", + "Keel", + "Seo raadio", + "Laaduri versioon", + "Tootmise kuup.", + "Mudeli nimi", + "POLE", + "NORMATIIVTEAVE", + "Normatiivteave", + "SEADED", + "SÜSTEEMI TEAVE", + "Seerianumber", + "Tarkvara versioon", + "Süsteemi teave", +}; + diff --git a/source/Fonts/textFinnish.c b/source/Fonts/textFinnish.c new file mode 100644 index 0000000..14c8167 --- /dev/null +++ b/source/Fonts/textFinnish.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textFinnish[] = +{ + "1 TUNTI", + "2 TUNTIA", + "Autom. sammutus", + "Sisältää", + "TAAJUUDET", + "Taajuudet", + "Tuntimäärä", + "KIELI", + "LANGATON YHTEYS", + "Kieli", + "Langaton yhteys", + "Käynnist.ohj. versio", + "Valmistuspäivä", + "Mallin nimi", + "EI KOSK.", + "SÄÄNTELYTIEDOT", + "Sääntely", + "ASETUKSET", + "JÄRJESTELMÄN TIEDOT", + "Sarjanumero", + "Ohjelmiston versio", + "Järjestelmän tiedot", +}; + diff --git a/source/Fonts/textFrench.c b/source/Fonts/textFrench.c new file mode 100644 index 0000000..5df782e --- /dev/null +++ b/source/Fonts/textFrench.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 6/26/2024 + * Author: Brian.Bailey + */ + + +const char * textFrench[] = +{ + "1 HEURE", + "2 HEURES", + "Arrêt automatique", + "Contient", + "FRÉQUENCES", + "Fréquences", + "Décompte horaire", + "LANGUE", + "LIAISON RADIO", + "Langue", + "Liaison radio", + "Vers. charg. dém.", + "Date de fabrication", + "Nom du modèle", + "JAMAIS", + "INFOS RÉGLEMENTAIRES", + "Réglementation", + "PARAMÈTRES", + "INFORMATIONS SUR LE SYSTÈME", + "Numéro de série", + "Version du logiciel", + "Infos système", +}; + diff --git a/source/Fonts/textGerman.c b/source/Fonts/textGerman.c new file mode 100644 index 0000000..e647a81 --- /dev/null +++ b/source/Fonts/textGerman.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 6/26/2024 + * Author: Brian.Bailey + */ + + +const char * textGerman[] = +{ + "1 STD.", + "2 STDN.", + "Auto-Abschaltung", + "Enthält", + "FREQUENZEN", + "Frequenzen", + "Stundenzahl", + "SPRACHE", + "FUNKANBINDUNG", + "Sprache", + "Funkanbindung", + "Bootloader-Version", + "Herstellungsdatum", + "Modellname", + "NIEMALS", + "REGULATORISCHE INFORMATION", + "Regulatorische Info", + "EINSTELLUNGEN", + "SYSTEMINFO", + "Seriennummer", + "Softwareversion", + "Systeminformation", +}; + diff --git a/source/Fonts/textGreek.c b/source/Fonts/textGreek.c new file mode 100644 index 0000000..4143c3c --- /dev/null +++ b/source/Fonts/textGreek.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textGreek[] = +{ + "1 ΩΡΑ", + "2 ΩΡΕΣ", + "Αυτόματη απενεργ.", + "Περιέχει", + "ΣΥΧΝΟΤΗΤΕΣ", + "Συχνότητες", + "Μέτρηση ωρών", + "ΓΛΩΣΣΑ", + "ΣΥΝΔΕΣΗ ΑΣΥΡΜΑΤΟΥ", + "Γλώσσα", + "Σύνδ. ασυρμ.", + "Έκδ. προγρ. εκκίν.", + "Ημ/α κατασκευής", + "Όνομα μοντέλου", + "ΠΟΤΕ", + "ΚΑΝΟΝΙΣΤΙΚΕΣ ΠΛΗΡΟΦΟΡΙΕΣ", + "Κανονιστικά", + "ΡΥΘΜΙΣΕΙΣ", + "ΠΛΗΡΟΦΟΡΙΕΣ ΣΥΣΤΗΜΑΤΟΣ", + "Σειριακός αριθμός", + "Έκδοση λογισμικού", + "Πληροφορίες συστ.", +}; + diff --git a/source/Fonts/textHungarian.c b/source/Fonts/textHungarian.c new file mode 100644 index 0000000..da611f9 --- /dev/null +++ b/source/Fonts/textHungarian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textHungarian[] = +{ + "1 ÓRA", + "2 ÓRA", + "Automatikus leállítás", + "Tartalom", + "FREKVENCIÁK", + "Frekvenciák", + "Óraszám", + "NYELV", + "RÁDIÓKAPCSOLAT", + "Nyelv", + "Rádiókapcsolat", + "Betöltő verziója", + "Gyártás dátuma", + "Modellnév", + "SOHA", + "SZABÁLYOZÁSI INFORMÁCIÓK", + "Szabályozás", + "BEÁLLÍTÁSOK", + "RENDSZERINFÓ", + "Sorozatszám", + "Szoftververzió", + "Rendszerinformáció", +}; + diff --git a/source/Fonts/textItalian.c b/source/Fonts/textItalian.c new file mode 100644 index 0000000..1f3a5bf --- /dev/null +++ b/source/Fonts/textItalian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textItalian[] = +{ + "1 ORA", + "2 ORE", + "Spegnim. auto", + "Contiene", + "FREQUENZE", + "Frequenze", + "Conteggio ore", + "LINGUA", + "LINK RADIO", + "Lingua", + "Link radio", + "Versione caricatore", + "Data prod.", + "Nome modello", + "MAI", + "INFO NORMATIVE", + "Cont. norm.", + "IMPOSTAZIONI", + "INFO SISTEMA", + "Numero serie", + "Vers. software", + "Info sistema", +}; + diff --git a/source/Fonts/textKorean.c b/source/Fonts/textKorean.c new file mode 100644 index 0000000..ad8a829 --- /dev/null +++ b/source/Fonts/textKorean.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textKorean[] = +{ + "1시간", + "2시간", + "자동 종료", + "포함", + "주파수", + "주파수", + "시간 수", + "언어", + "링크 라디오", + "언어", + "링크 라디오", + "로더 버전", + "제조 날짜", + "모델 이름", + "안 함", + "규정 정보", + "규정", + "설정", + "시스템 정보", + "일련번호", + "SW 버전", + "시스템 정보", +}; + diff --git a/source/Fonts/textLatvian.c b/source/Fonts/textLatvian.c new file mode 100644 index 0000000..5459af0 --- /dev/null +++ b/source/Fonts/textLatvian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textLatvian[] = +{ + "1 ST.", + "2 ST.", + "Autom. izslēgšanās", + "Satur", + "FREKVENCES", + "Frekvences", + "Stundu skaits", + "VALODA", + "RADIOLĪNIJA", + "Valoda", + "Radiolīnija", + "Sākn. ielādēt. vers.", + "Izgatavoš. datums", + "Modeļa nosaukums", + "NEKAD", + "REGULĒJUMA INFORM.", + "Regulējums", + "IESTATĪJUMI", + "SISTĒMAS INFORM.", + "Sērijas numurs", + "Programmat. vers.", + "Sistēmas informācija", +}; + diff --git a/source/Fonts/textLithuanian.c b/source/Fonts/textLithuanian.c new file mode 100644 index 0000000..c738726 --- /dev/null +++ b/source/Fonts/textLithuanian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textLithuanian[] = +{ + "1 VAL.", + "2 VAL.", + "Automat. išjun.", + "Sudaro", + "DAŽNIAI", + "Dažniai", + "Val. skaičiav.", + "KALBA", + "SUSIETI RADIJĄ", + "Kalba", + "Susieti radiją", + "Krautuvo versija", + "Pagaminimo data", + "Model. pavad.", + "NIEKADA", + "REGLAMENTAVIMO INFORMACIJA", + "Reglamentavimas", + "NUOSTATOS", + "SISTEMOS INFORMACIJA", + "Serijos numeris", + "Progr. įr. versija", + "Sistemos informacija", +}; + diff --git a/source/Fonts/textNorwegian.c b/source/Fonts/textNorwegian.c new file mode 100644 index 0000000..607b54a --- /dev/null +++ b/source/Fonts/textNorwegian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textNorwegian[] = +{ + "1 TIME", + "2 TIMER", + "Auto-avslåing", + "Inneholder", + "FREKVENSER", + "Frekvenser", + "Antall timer", + "SPRÅK", + "TILKNYTT RADIO", + "Språk", + "Tilknytt radio", + "Innlastervers.", + "Prod.dato", + "Modellnavn", + "ALDRI", + "REGULATORISK INFORMASJON", + "Regulatorisk", + "INNSTILLINGER", + "SYSTEMINFO", + "Serienummer", + "Pr.vareversj.", + "Systeminfo", +}; + diff --git a/source/Fonts/textPolish.c b/source/Fonts/textPolish.c new file mode 100644 index 0000000..faaa1aa --- /dev/null +++ b/source/Fonts/textPolish.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textPolish[] = +{ + "1 GODZ", + "2 GODZ", + "Autom. wyłączanie", + "Zawiera", + "CZĘSTOTLIWOŚCI", + "Częstotliwości", + "Liczba godzin", + "JĘZYK", + "POWIĄŻ RADIO", + "Język", + "Powiąż radio", + "Wersja ładowarki", + "Data produkcji", + "Nazwa modelu", + "NIGDY", + "INFORMACJE PRAWNE", + "Prawne", + "USTAWIENIA", + "INFO O SYSTEMIE", + "Numer seryjny", + "Wersja oprogr.", + "Info o systemie", +}; + diff --git a/source/Fonts/textPortuguese.c b/source/Fonts/textPortuguese.c new file mode 100644 index 0000000..7f8cdfe --- /dev/null +++ b/source/Fonts/textPortuguese.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textPortuguese[] = +{ + "1 HORA", + "2 HORAS", + "Encerramento auto.", + "Contém", + "FREQUÊNCIAS", + "Frequências", + "Contagem de horas", + "IDIOMA", + "LIGAR RÁDIO", + "Idioma", + "Ligar rádio", + "V. carregador", + "Data de fabrico", + "Nome do modelo", + "NUNCA", + "INFORMAÇÕES REGULAMENTARES", + "Regulamentar", + "DEFINIÇÕES", + "INFO. SISTEMA", + "Número de série", + "Versão do software", + "Info. do sistema", +}; + diff --git a/source/Fonts/textRomanian.c b/source/Fonts/textRomanian.c new file mode 100644 index 0000000..4a0f44b --- /dev/null +++ b/source/Fonts/textRomanian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textRomanian[] = +{ + "1 HOUR", + "2 HOURS", + "Oprire automată", + "Conținut", + "FRECVENȚE", + "Frecvențe", + "Număr de ore", + "LIMBĂ", + "LEGĂTURĂ RADIO", + "Limbă", + "Legătură radio", + "Versiune încărcător", + "Data de fabricație", + "Numele modelului", + "NICIODATĂ", + "INFO REGLEMENTARE", + "Reglementare", + "SETĂRI", + "INFO SISTEM", + "Număr de serie", + "Versiune software", + "Informații de sistem", +}; + diff --git a/source/Fonts/textRussian.c b/source/Fonts/textRussian.c new file mode 100644 index 0000000..29cbf59 --- /dev/null +++ b/source/Fonts/textRussian.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textRussian[] = +{ + "1 ЧАС", + "2 ЧАСА", + "Автовыкл.", + "Содержит", + "ЧАСТОТЫ", + "Частоты", + "Счетчик часов", + "ЯЗЫК", + "РАДИОКАНАЛ УПРАВЛЕНИЯ", + "Язык", + "Радиоканал", + "Верс. загрузч.", + "Дата произв.", + "Назв. модели", + "НИКОГ.", + "НОРМАТИВНАЯ ИНФОРМАЦИЯ", + "Нормативы", + "НАСТРОЙКИ", + "ИНФОРМАЦИЯ О СИСТЕМЕ", + "Серийный №", + "Версия ПО", + "Инфо о сист.", +}; + diff --git a/source/Fonts/textSpanish.c b/source/Fonts/textSpanish.c new file mode 100644 index 0000000..101f68c --- /dev/null +++ b/source/Fonts/textSpanish.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textSpanish[] = +{ + "1 H", + "2 H", + "Apagado auto.", + "Contiene", + "FRECUENCIAS", + "Frecuencias", + "Rcto. de horas", + "IDIOMA", + "ENL. RADIO", + "Idioma", + "Enl. radio", + "Versión cargador", + "Fecha fabricación", + "Nombre modelo", + "NUNCA", + "INFO. NORMA", + "Norma", + "AJUSTES", + "INFO. SISTEMA", + "Número serie", + "Versión software", + "Info. sistema", +}; + diff --git a/source/Fonts/textSwedish.c b/source/Fonts/textSwedish.c new file mode 100644 index 0000000..16655f8 --- /dev/null +++ b/source/Fonts/textSwedish.c @@ -0,0 +1,34 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + + +const char * textSwedish[] = +{ + "1 TIMME", + "2 TIMMAR", + "Autom. avst.", + "Innehåller", + "FREKVENSER", + "Frekvenser", + "Antal timmar", + "SPRÅK", + "RADIOLÄNK", + "Språk", + "Radiolänk", + "Version av laddare", + "Datum för tillv.", + "Modellnamn", + "ALDRIG", + "INFO OM REGLERING", + "Regelverk", + "INSTÄLLNINGAR", + "SYSTEMINFO", + "Serienummer", + "Programvaruv.", + "Systeminfo.", +}; + diff --git a/source/Fonts/translate.c b/source/Fonts/translate.c new file mode 100644 index 0000000..9785fef --- /dev/null +++ b/source/Fonts/translate.c @@ -0,0 +1,204 @@ +/* + * translate.c + * + * Created on: Feb 12, 2022 + * Author: Brian.Bailey + */ + +#include +#include +#include + +#include "System/system.h" +#include "languages.h" +#include "translate.h" + + + +//Language names (in the language) +const char *languageNames[] = +{ + "English", //English + "Español", //Spanish + "Français", //French + "Deutsch", //German + "Italiano", //Italian + "Polski", //Polish + "Nederlands", //Dutch + "Português", //Portuguese + "Русский", //Russian + "Svenska", //Swedish + "Dansk", //Danish + "Eesti", //Estonian + "Latviski", //Latvian + "Lietuvių kalba", //Lithuanian + "Čeština", //Czech + "Suomi", //Finnish + "Ελληνικά", //Greek + "Norsk", //Norwegian + "Magyar", //Hungarian + "Română", //Romanian + "简体中文", //Chinese + "한국어", //Korean +}; + + + + +const char* Translate(const char *input) +{ + //find the index of the input string in textEnglish[] + int16_t low = 0; + int16_t high = NUM_TRANSLATION_STRINGS - 1; + int16_t mid; + int16_t compare; //result of strcmp() + int16_t index; //index of the input string in textEnglish[] + bool done = false; + const char *translatedString; + + //bisection algorithm + + while ((low <= high) && !done) + { + mid = (low + high) / 2; + compare = strcmp(input, textEnglish[mid]); + + if (compare == 0) //strings match + { + done = true; + } + else if (compare < 0) //correct string is "lower" than result + { + high = mid - 1; + } + else //correct string is "higher" than result + { + low = mid + 1; + } + } + + index = mid; + + if (done == false) //string not found in array + { + translatedString = input; //return the input string (no translation) + } + else + { + switch (SYS_GetLanguage()) //language currently used + { + case LANG_SPANISH: + translatedString = textSpanish[index]; + break; + case LANG_FRENCH: + translatedString = textFrench[index]; + break; + case LANG_GERMAN: + translatedString = textGerman[index]; + break; + case LANG_ITALIAN: + translatedString = textItalian[index]; + break; + case LANG_POLISH: + translatedString = textPolish[index]; + break; + case LANG_DUTCH: + translatedString = textDutch[index]; + break; + case LANG_PORTUGUESE: + translatedString = textPortuguese[index]; + break; + case LANG_RUSSIAN: + translatedString = textRussian[index]; + break; + case LANG_SWEDISH: + translatedString = textSwedish[index]; + break; + case LANG_DANISH: + translatedString = textDanish[index]; + break; + case LANG_ESTONIAN: + translatedString = textEstonian[index]; + break; + case LANG_LATVIAN: + translatedString = textLatvian[index]; + break; + case LANG_LITHUANIAN: + translatedString = textLithuanian[index]; + break; + case LANG_CZECH: + translatedString = textCzech[index]; + break; + case LANG_FINNISH: + translatedString = textFinnish[index]; + break; + case LANG_GREEK: + translatedString = textGreek[index]; + break; + case LANG_NORWEGIAN: + translatedString = textNorwegian[index]; + break; + case LANG_HUNGARIAN: + translatedString = textHungarian[index]; + break; + case LANG_ROMANIAN: + translatedString = textRomanian[index]; + break; + case LANG_CHINESE: + translatedString = textChinese[index]; + break; + case LANG_KOREAN: + translatedString = textKorean[index]; + break; + default: + translatedString = textEnglish[index]; + break; + } + } + + return translatedString; +} + +#if 0 +//returns the index of the input string in textEnglish[] +//returns -1 if input string not found +uint16_t GetTranslationIndex(const char *input) +{ + int16_t low = 0; + int16_t high = NUM_TRANSLATION_STRINGS - 1; + int16_t mid; + int16_t compare; + + bool done = false; + + //bisection algorithm + + while ((low <= high) && !done) + { + mid = (low + high) / 2; + compare = strcmp(input, textEnglish[mid]); + + if (compare == 0) //strings match + { + done = true; + } + else if (compare < 0) //correct string is "lower" than result + { + high = mid - 1; + } + else //correct string is "higher" than result + { + low = mid + 1; + } + } + + int16_t retval = mid; + if (done == false) //string not found in array + { + retval = -1; + } + + return retval; +} +#endif + diff --git a/source/Fonts/translate.h b/source/Fonts/translate.h new file mode 100644 index 0000000..ed056e0 --- /dev/null +++ b/source/Fonts/translate.h @@ -0,0 +1,46 @@ +/* + * languages.h + * + * Created on: 5/24/2024 + * Author: Brian.Bailey + */ + +#ifndef FONTS_TRANSLATE_H_ +#define FONTS_TRANSLATE_H_ + +#define NUM_TRANSLATION_STRINGS 22 + +typedef enum { + LANG_ENGLISH, + LANG_SPANISH, + LANG_FRENCH, + LANG_GERMAN, + LANG_ITALIAN, + LANG_POLISH, + LANG_DUTCH, + LANG_PORTUGUESE, + LANG_RUSSIAN, + LANG_SWEDISH, + LANG_DANISH, + LANG_ESTONIAN, + LANG_LATVIAN, + LANG_LITHUANIAN, + LANG_CZECH, + LANG_FINNISH, + LANG_GREEK, + LANG_NORWEGIAN, + LANG_HUNGARIAN, + LANG_ROMANIAN, + LANG_CHINESE, + LANG_KOREAN, + LANG_NUM, +}LANGUAGE_t; + + +extern const char * languageNames[]; + + +const char * Translate(const char * input); + +#endif /* FONTS_LANGUAGES_H_ */ + diff --git a/source/Graphics/graphicsLibrary.c b/source/Graphics/graphicsLibrary.c new file mode 100644 index 0000000..28ea920 --- /dev/null +++ b/source/Graphics/graphicsLibrary.c @@ -0,0 +1,855 @@ +/* + * graphicsLibrary.c + * + * Created on: Feb 12, 2022 + * Author: Brian.Bailey + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_common.h" + +#include "..\lcd.h" +#include "..\Fonts\fontLibrary.h" +#include "lcd.h" + +#include "graphicsLibrary.h" + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define BMP_WIDTH_INDEX 0 //Location of xSize in bitmap array +#define BMP_HEIGHT_INDEX 1 //Location of ySize in bitmap array +#define BMP_DATA_INDEX 2 //Location of data in bitmap array + +#define ABS(x) ((x) > 0 ? (x) : -(x)) + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + +static void DrawHLine(int16_t x0, int16_t y0, uint16_t width, LCD_DRAWMODE_t drawMode); +static void DrawVLine(int16_t x0, int16_t y0, uint16_t height, LCD_DRAWMODE_t drawMode); +static void xLine(int16_t x1, int16_t x2, int16_t y, LCD_DRAWMODE_t drawMode); +static void yLine(int16_t x, int16_t y1, int16_t y2, LCD_DRAWMODE_t drawMode); + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + + +/* + * Draw a horizontal line with given color + */ +static void DrawHLine(int16_t x0, int16_t y0, uint16_t width, LCD_DRAWMODE_t drawMode) +{ + for(int16_t x = x0; x < (x0+width); x++) + { + LCD_DrawPixel(x, y0, drawMode); + } +} + +/* + * Draw a vertical line with given color + */ +static void DrawVLine(int16_t x0, int16_t y0, uint16_t height, LCD_DRAWMODE_t drawMode) +{ + for(int16_t y = y0; y < (y0+height); y++) + { + LCD_DrawPixel(x0, y, drawMode); + } +} + +//Supporting functions for GL_DrawCircle2 +static void xLine(int16_t x1, int16_t x2, int16_t y, LCD_DRAWMODE_t drawMode) +{ + while (x1 <= x2) + { + LCD_DrawPixel(x1++, y, drawMode); + } +} + +static void yLine(int16_t x, int16_t y1, int16_t y2, LCD_DRAWMODE_t drawMode) +{ + while (y1 <= y2) + { + LCD_DrawPixel(x, y1++, drawMode); + } +} + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + + +/* + * Draw a line using Bresenham's algorithm with given color. //ADD WIDTH + */ +void GL_DrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t thickness, LCD_DRAWMODE_t drawMode) +{ + int16_t dx; //width + int16_t sx; //x increment direction + int16_t dy; //height + int16_t sy; //y increment direction + int16_t err; + int16_t e2; + int16_t widthOffsetLow; //line thickness low offset for perpendicular line + int16_t widthOffsetHigh; //line thickness high offset for perpendicular line + + dx = ABS(x1 - x0); + sx = x0 < x1 ? 1 : -1; + dy = ABS(y1 - y0); + sy = y0 < y1 ? 1 : -1; + err = (dx > dy ? dx : -dy) / 2; + + while (1) + { + + if (x0 == x1 && y0 == y1) + { + break; + } + + //Draw a line perpendicular to the first with length "thickness" + widthOffsetLow = ((thickness-1)*-1) >> 1; + widthOffsetHigh = thickness >> 1; + + for(int16_t i =widthOffsetLow; i <= widthOffsetHigh; i++) + { + if(dy > dx) //if line is more horizontal, draw horizontal line + { + LCD_DrawPixel(x0 + i, y0, drawMode); + } + else //vertical line + { + LCD_DrawPixel(x0, y0 + i, drawMode); + } + } + + e2 = err + err; + + if (e2 > -dx) + { + err -= dy; + x0 += sx; + } + + if (e2 < dy) + { + err += dx; + y0 += sy; + } + } +} + + +/* + * Draw a rectangle with given color and thickness. + * Corners will move outward with increasing thickness + */ +void GL_DrawRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t thickness, LCD_DRAWMODE_t drawMode) +{ + /* Make sure x0 is smaller than x1. */ + if (x0 > x1) + { + x0 = x0 + x1; + x1 = x0 - x1; + x0 = x0 - x1; + } + + /* Make sure y0 is smaller than y1. */ + if (y0 > y1) + { + y0 = y0 + y1; + y1 = y0 - y1; + y0 = y0 - y1; + } + + uint16_t width = x1 - x0 + 1; + uint16_t height = y1 - y0 + 1; + + + //Draw concentric rectangles to increase thickness + //This overwrites the corner pixels + int16_t thicknessOffsetLow = ((thickness-1)*-1) >> 1; //line thickness low offset + int16_t thicknessOffsetHigh = thickness >> 1; //line thickness high offset + for(int16_t i = thicknessOffsetLow; i <= thicknessOffsetHigh; i++) + { + DrawHLine(x0 + i, y0 + i, width + 2*i*-1, drawMode); //top horizontal + DrawHLine(x0 - i, y1 + i, width + 2*i, drawMode); //bottom horizontal + DrawVLine(x0 + i, y0 + i, height + 2*i*-1, drawMode); //left vertical + DrawVLine(x1 + i, y0 - i, height + 2*i, drawMode); //right vertical + } + +} + + +/* + * Draw a filled rectangle with given color. + */ +void GL_DrawFilledRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, LCD_DRAWMODE_t drawMode) +{ + /* Make sure x0 is smaller than x1. */ + if (x0 > x1) + { + x0 = x0 + x1; + x1 = x0 - x1; + x0 = x0 - x1; + } + + /* Make sure y0 is smaller than y1. */ + if (y0 > y1) + { + y0 = y0 + y1; + y1 = y0 - y1; + y0 = y0 - y1; + } + + uint16_t width = x1 - x0 + 1; + uint16_t height = y1 - y0 + 1; + + for (uint16_t i = 0; i < height; i++) + { + DrawHLine(x0, y0 + i, width, drawMode); + } +} + +void GL_DrawCircle(int16_t xc, int16_t yc, int16_t r, LCD_DRAWMODE_t drawMode) +{ + int16_t x = 0; + int16_t y = r; + int16_t d = 3 - 2 * r; + + LCD_DrawPixel(xc + x, yc + y, drawMode); + LCD_DrawPixel(xc - x, yc + y, drawMode); + LCD_DrawPixel(xc + x, yc - y, drawMode); + LCD_DrawPixel(xc - x, yc - y, drawMode); + LCD_DrawPixel(xc + y, yc + x, drawMode); + LCD_DrawPixel(xc - y, yc + x, drawMode); + LCD_DrawPixel(xc + y, yc - x, drawMode); + LCD_DrawPixel(xc - y, yc - x, drawMode); + + while (y >= x) + { + x++; + + if (d > 0) + { + y--; + d = d + 4 * (x - y) + 10; + } + else + { + d = d + 4 * x + 6; + } + + LCD_DrawPixel(xc + x, yc + y, drawMode); + LCD_DrawPixel(xc - x, yc + y, drawMode); + LCD_DrawPixel(xc + x, yc - y, drawMode); + LCD_DrawPixel(xc - x, yc - y, drawMode); + LCD_DrawPixel(xc + y, yc + x, drawMode); + LCD_DrawPixel(xc - y, yc + x, drawMode); + LCD_DrawPixel(xc + y, yc - x, drawMode); + LCD_DrawPixel(xc - y, yc - x, drawMode); + } +} + + +//Draw two circles with fill between them (circle with thickness) + //uses midpoint circle algorithm + // from https://stackoverflow.com/questions/27755514/circle-with-thickness-drawing-algorithm +void GL_DrawCircle2(int16_t xc, int16_t yc, int16_t rInner, int16_t rOuter, LCD_DRAWMODE_t drawMode) +{ + if(rInner > rOuter) //exit if inner circle radius larger than rOuter + { + return; + } + + int16_t xo = rOuter; //rOuter circle radius + int16_t xi = rInner; //rInner circle radius + int16_t y = 0; + int16_t erro = 1 - xo; //rOuter circle error + int16_t erri = 1 - xi; //rInner circle error + + while(xo >= y) + { + xLine(xc + xi, xc + xo, yc + y, drawMode); + yLine(xc + y, yc + xi, yc + xo, drawMode); + xLine(xc - xo, xc - xi, yc + y, drawMode); + yLine(xc - y, yc + xi, yc + xo, drawMode); + xLine(xc - xo, xc - xi, yc - y, drawMode); + yLine(xc - y, yc - xo, yc - xi, drawMode); + xLine(xc + xi, xc + xo, yc - y, drawMode); + yLine(xc + y, yc - xo, yc - xi, drawMode); + + y++; + + if (erro < 0) + { + erro += 2 * y + 1; + } + else + { + xo--; + erro += 2 * (y - xo + 1); + } + + if (y > rInner) + { + xi = y; + } + else + { + if (erri < 0) + { + erri += 2 * y + 1; + } + else + { + xi--; + erri += 2 * (y - xi + 1); + } + } + } +} + +void GL_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, LCD_DRAWMODE_t drawMode) +{ + int16_t x = 0; + int16_t y = r; + int16_t d = 3 - 2 * r; + + while (y >= x) + { + DrawHLine(x0 - x, y0 + y, x * 2, drawMode); + DrawHLine(x0 - x, y0 - y, x * 2, drawMode); + DrawHLine(x0 - y, y0 + x, y * 2, drawMode); + DrawHLine(x0 - y, y0 - x, y * 2, drawMode); + x++; + + if (d > 0) + { + y--; + d = d + 4 * (x - y) + 10; + } + else + { + d = d + 4 * x + 6; + } + } +} + +void GL_DrawEllipse(int16_t x0, int16_t y0, int16_t a, int16_t b, + LCD_DRAWMODE_t drawMode) +{ + int16_t wx, wy; + int32_t xa, ya; + int32_t t; + int32_t asq = a * a; + int32_t bsq = b * b; + + LCD_DrawPixel(x0, y0 + b, drawMode); + LCD_DrawPixel(x0, y0 - b, drawMode); + + wx = 0; + wy = b; + xa = 0; + ya = asq * 2 * b; + t = asq / 4 - asq * b; + + while (1) + { + t += xa + bsq; + + if (t >= 0) + { + ya -= asq * 2; + t -= ya; + wy--; + } + + xa += bsq * 2; + wx++; + + if (xa >= ya) + { + break; + } + + LCD_DrawPixel(x0 + wx, y0 - wy, drawMode); + LCD_DrawPixel(x0 - wx, y0 - wy, drawMode); + LCD_DrawPixel(x0 + wx, y0 + wy, drawMode); + LCD_DrawPixel(x0 - wx, y0 + wy, drawMode); + } + + LCD_DrawPixel(x0 + a, y0, drawMode); + LCD_DrawPixel(x0 - a, y0, drawMode); + + wx = a; + wy = 0; + xa = bsq * 2 * a; + + ya = 0; + t = bsq / 4 - bsq * a; + + while (1) + { + t += ya + asq; + + if (t >= 0) + { + xa -= bsq * 2; + t = t - xa; + wx--; + } + + ya += asq * 2; + wy++; + + if (ya > xa) + { + break; + } + + LCD_DrawPixel(x0 + wx, y0 - wy, drawMode); + LCD_DrawPixel(x0 - wx, y0 - wy, drawMode); + LCD_DrawPixel(x0 + wx, y0 + wy, drawMode); + LCD_DrawPixel(x0 - wx, y0 + wy, drawMode); + } +} + +void GL_DrawFilledEllipse(int16_t x0, int16_t y0, int16_t a, int16_t b, + LCD_DRAWMODE_t drawMode) +{ + int16_t wx, wy; + int32_t xa, ya; + int32_t t; + int32_t asq = a * a; + int32_t bsq = b * b; + + LCD_DrawPixel(x0, y0 + b, drawMode); + LCD_DrawPixel(x0, y0 - b, drawMode); + + wx = 0; + wy = b; + xa = 0; + ya = asq * 2 * b; + t = asq / 4 - asq * b; + + while (1) + { + t += xa + bsq; + + if (t >= 0) + { + ya -= asq * 2; + t -= ya; + wy--; + } + + xa += bsq * 2; + wx++; + + if (xa >= ya) + { + break; + } + + DrawHLine(x0 - wx, y0 - wy, wx * 2, drawMode); + DrawHLine(x0 - wx, y0 + wy, wx * 2, drawMode); + } + + DrawHLine(x0 - a, y0, a * 2, drawMode); + + wx = a; + wy = 0; + xa = bsq * 2 * a; + + ya = 0; + t = bsq / 4 - bsq * a; + + while (1) + { + t += ya + asq; + + if (t >= 0) + { + xa -= bsq * 2; + t = t - xa; + wx--; + } + + ya += asq * 2; + wy++; + + if (ya > xa) + { + break; + } + + DrawHLine(x0 - wx, y0 - wy, wx * 2, drawMode); + DrawHLine(x0 - wx, y0 + wy, wx * 2, drawMode); + } +} + +void GL_DrawPolygon(int16_t numVertices, int16_t *vertices, int16_t thickness, LCD_DRAWMODE_t drawMode) +{ + for (int16_t i = 0; i < numVertices - 1; i++) + { + GL_DrawLine(vertices[(i << 1) + 0], vertices[(i << 1) + 1], + vertices[(i << 1) + 2], vertices[(i << 1) + 3], thickness, drawMode); + } + GL_DrawLine(vertices[0], vertices[1], vertices[(numVertices << 1) - 2], + vertices[(numVertices << 1) - 1], thickness, drawMode); +} + +/* Adapted from http://alienryderflex.com/polygon_fill/ */ +void GL_DrawFilledPolygon(int16_t numVertices, int16_t *vertices, LCD_DRAWMODE_t drawMode) +{ + uint16_t nodes[64]; + int16_t y; + + float x0; + float y0; + float x1; + float y1; + + int16_t miny = LCD_HEIGHT_PIXELS; + int16_t maxy = 0; + + for (uint8_t i = 0; i < numVertices; i++) + { + if (miny > vertices[(i << 1) + 1]) + { + miny = vertices[(i << 1) + 1]; + } + if (maxy < vertices[(i << 1) + 1]) + { + maxy = vertices[(i << 1) + 1]; + } + } + + /* Loop through the rows of the image. */ + for (y = miny; y < maxy; y++) + { + + /* Build a list of nodes. */ + int16_t count = 0; + int16_t j = numVertices - 1; + + for (int16_t i = 0; i < numVertices; i++) + { + x0 = vertices[(i << 1) + 0]; + y0 = vertices[(i << 1) + 1]; + x1 = vertices[(j << 1) + 0]; + y1 = vertices[(j << 1) + 1]; + + if ((y0 < (float) y && y1 >= (float) y) + || (y1 < (float) y && y0 >= (float) y)) + { + nodes[count] = + (int16_t) (x0 + (y - y0) / (y1 - y0) * (x1 - x0)); + count++; + } + j = i; + } + + /* Sort the nodes, via a simple “Bubble” sort. */ + int16_t i = 0; + while (i < count - 1) + { + if (nodes[i] > nodes[i + 1]) + { + int16_t swap = nodes[i]; + nodes[i] = nodes[i + 1]; + nodes[i + 1] = swap; + if (i) + { + i--; + } + } + else + { + i++; + } + } + + /* Draw lines between nodes. */ + for (int16_t i = 0; i < count; i += 2) + { + int16_t width = nodes[i + 1] - nodes[i]; + DrawHLine(nodes[i], y, width, drawMode); + } + } +} + +void GL_DrawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t thickness, LCD_DRAWMODE_t drawMode) +{ + int16_t vertices[6] = + { x0, y0, x1, y1, x2, y2 }; + GL_DrawPolygon(3, vertices, thickness, drawMode); +} + + +void GL_DrawFilledTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, LCD_DRAWMODE_t drawMode) +{ + int16_t vertices[6] = + { x0, y0, x1, y1, x2, y2 }; + GL_DrawFilledPolygon(3, vertices, drawMode); +} + +void GL_DrawRoundedRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t r, LCD_DRAWMODE_t drawMode) +{ + + uint16_t width, height; + int16_t x, y, d; + + /* Make sure x0 is smaller than x1. */ + if (x0 > x1) + { + x0 = x0 + x1; + x1 = x0 - x1; + x0 = x0 - x1; + } + + /* Make sure y0 is smaller than y1. */ + if (y0 > y1) + { + y0 = y0 + y1; + y1 = y0 - y1; + y0 = y0 - y1; + } + + + /* Max radius is half of shortest edge. */ + width = x1 - x0 + 1; + height = y1 - y0 + 1; + r = MIN(r, MIN(width / 2, height / 2)); + + DrawHLine(x0 + r, y0, width - 2 * r, drawMode); + DrawHLine(x0 + r, y1, width - 2 * r, drawMode); + DrawVLine(x0, y0 + r, height - 2 * r, drawMode); + DrawVLine(x1, y0 + r, height - 2 * r, drawMode); + + x = 0; + y = r; + d = 3 - 2 * r; + + while (y >= x) + { + x++; + + if (d > 0) + { + y--; + d = d + 4 * (x - y) + 10; + } + else + { + d = d + 4 * x + 6; + } + + /* Top right */ + LCD_DrawPixel(x1 - r + x, y0 + r - y, drawMode); + LCD_DrawPixel(x1 - r + y, y0 + r - x, drawMode); + + /* Top left */ + LCD_DrawPixel(x0 + r - x, y0 + r - y, drawMode); + LCD_DrawPixel(x0 + r - y, y0 + r - x, drawMode); + + /* Bottom right */ + LCD_DrawPixel(x1 - r + x, y1 - r + y, drawMode); + LCD_DrawPixel(x1 - r + y, y1 - r + x, drawMode); + + /* Bottom left */ + LCD_DrawPixel(x0 + r - x, y1 - r + y, drawMode); + LCD_DrawPixel(x0 + r - y, y1 - r + x, drawMode); + } +} +; + +void GL_DrawFilledRoundedRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t r, LCD_DRAWMODE_t drawMode) +{ + + uint16_t width, height; + int16_t rx0, ry0, rx1, x, y, d; + + /* Make sure x0 is smaller than x1. */ + if (x0 > x1) + { + x0 = x0 + x1; + x1 = x0 - x1; + x0 = x0 - x1; + } + + /* Make sure y0 is smaller than y1. */ + if (y0 > y1) + { + y0 = y0 + y1; + y1 = y0 - y1; + y0 = y0 - y1; + } + + + /* Max radius is half of shortest edge. */ + width = x1 - x0 + 1; + height = y1 - y0 + 1; + r = MIN(r, MIN(width / 2, height / 2)); + + x = 0; + y = r; + d = 3 - 2 * r; + + while (y >= x) + { + x++; + + if (d > 0) + { + y--; + d = d + 4 * (x - y) + 10; + } + else + { + d = d + 4 * x + 6; + } + + /* Top */ + ry0 = y0 + r - x; + rx0 = x0 + r - y; + rx1 = x1 - r + y; + width = rx1 - rx0; + DrawHLine(rx0, ry0, width, drawMode); + + ry0 = y0 + r - y; + rx0 = x0 + r - x; + rx1 = x1 - r + x; + width = rx1 - rx0; + DrawHLine(rx0, ry0, width, drawMode); + + /* Bottom */ + ry0 = y1 - r + y; + rx0 = x0 + r - x; + rx1 = x1 - r + x; + width = rx1 - rx0; + DrawHLine(rx0, ry0, width, drawMode); + + ry0 = y1 - r + x; + rx0 = x0 + r - y; + rx1 = x1 - r + y; + width = rx1 - rx0; + DrawHLine(rx0, ry0, width, drawMode); + } + + /* Center */ + GL_DrawFilledRectangle(x0, y0 + r, x1, y1 - r, drawMode); +} +; + +uint16_t GL_GetColorBitmapWidth(const uint16_t *bitmap) +{ + return bitmap[BMP_WIDTH_INDEX]; +} + +uint16_t GL_GetColorBitmapHeight(const uint16_t *bitmap) +{ + return bitmap[BMP_HEIGHT_INDEX]; +} + +/** + * Draw a bitmap in RGB565 color at the specified location + * + * \param *bitmap pointer to bitmap + * \param x0 x coordinate of bitmap (top left) + * \param y0 y coordinate of bitmap (top left) + * \return void + */ +void GL_DrawColorBitmap(const uint16_t *bitmap, uint16_t x0, uint16_t y0) +{ + uint16_t xSize = bitmap[BMP_WIDTH_INDEX]; //bitmap width in pixels + uint16_t ySize = bitmap[BMP_HEIGHT_INDEX]; //bitmap height in pixels + bitmap += BMP_DATA_INDEX; //increment the bitmap pointer to the start of bitmap data + + for (uint16_t y = 0; y < ySize; y++) + { + for (uint16_t x = 0; x < xSize; x++) + { + LCD_DrawPixel(x + x0, y + y0, bitmap[(y * xSize) + x]); + } + } +} + + +uint32_t GL_GetMonoBitmapWidth(const uint32_t *bitmap) +{ + return bitmap[BMP_WIDTH_INDEX]; +} + + +uint32_t GL_GetMonoBitmapHeight(const uint32_t *bitmap) +{ + return bitmap[BMP_HEIGHT_INDEX]; +} + +/** + * Draw mono bitmap in a single RGB565 color at the specified location + * "1" pixels are drawn, "0" pixels are not drawn + * + * Data packed in uint16_t array, 1bpp, MSb first + * + * \param *bitmap pointer to bitmap + * \param x0 x coordinate of bitmap (top left) + * \param y0 y coordinate of bitmap (top left) + * \return void + */ +void GL_DrawMonoBitmap(const uint32_t *bitmap, uint16_t x0, uint16_t y0, LCD_DRAWMODE_t drawMode) +{ + uint32_t xSize = bitmap[BMP_WIDTH_INDEX]; //bitmap width in pixels + uint32_t ySize = bitmap[BMP_HEIGHT_INDEX]; //bitmap height in pixels + const uint32_t *pData = &bitmap[BMP_DATA_INDEX];//data starts @ bitmap[2] + + uint32_t startingBitMask = 0x80000000; //32-bit data, MDb first + + uint32_t bitMask = startingBitMask; + + for (uint16_t y = 0; y < ySize; y++) + { + for (uint16_t x = 0; x < xSize; x++) + { + if (bitMask == 0) + { + bitMask = startingBitMask; + pData++; + } + + if (*pData & bitMask) + { + LCD_DrawPixel(x + x0, y + y0, drawMode); + } + + bitMask = (bitMask >> 1); + } + } +} + +/* +* Draw mono bitmap centered on screen +* \param *bitmap pointer to bitmap +* \param color color to draw bitmap +*/ +void GL_DrawMonoBitmapCentered(const uint32_t *bitmap, LCD_DRAWMODE_t drawMode) +{ + uint16_t x = LCD_X_MID - GL_GetMonoBitmapWidth(bitmap) / 2; + uint16_t y = LCD_Y_MID - GL_GetMonoBitmapHeight(bitmap) / 2; + GL_DrawMonoBitmap(bitmap, x, y, drawMode); +} + diff --git a/source/Graphics/graphicsLibrary.h b/source/Graphics/graphicsLibrary.h new file mode 100644 index 0000000..f597c9a --- /dev/null +++ b/source/Graphics/graphicsLibrary.h @@ -0,0 +1,226 @@ +/* + * graphicsLibrary.h + * + * Created on: Feb 12, 2022 + * Author: Brian.Bailey + */ + +#include +#include + + +#ifndef GRAPHICS_GRAPHICSLIBRARY_H_ +#define GRAPHICS_GRAPHICSLIBRARY_H_ + + +//include all bitmap headers +#include "testIconsMono.h" + + +/** + * Draw a line + * + * Output will be clipped to the current clip window. + * + * @param x0 + * @param y0 + * @param x1 + * @param y1 + * @param color + */ +void GL_DrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t thickness, LCD_DRAWMODE_t drawMode); + + +/** + * Draw a rectangle + * + * Output will be clipped to the current clip window. + * + * @param x0 + * @param y0 + * @param x1 + * @param y1 + * @param thickness + * @param color + */ +void GL_DrawRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t thickness, LCD_DRAWMODE_t drawMode); + +/** + * Draw a filled rectangle + * + * Output will be clipped to the current clip window. + * + * @param x0 + * @param y0 + * @param x1 + * @param y1 + * @param color + */ +void GL_DrawFilledRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, LCD_DRAWMODE_t drawMode); + +/** + * Draw a circle + * + * Output will be clipped to the current clip window. + * + * @param x0 center X + * @param y0 center Y + * @param r radius + * @param color + */ +void GL_DrawCircle(int16_t x0, int16_t y0, int16_t r, LCD_DRAWMODE_t drawMode); + + +void GL_DrawCircle2(int16_t xc, int16_t yc, int16_t rInner, int16_t rOuter, LCD_DRAWMODE_t drawMode); + + +/** + * Draw a filled circle + * + * Output will be clipped to the current clip window. + * + * @param x0 center X + * @param y0 center Y + * @param r radius + * @param color + */ +void GL_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, LCD_DRAWMODE_t drawMode); + +/** + * Draw an ellipse + * + * Output will be clipped to the current clip window. + * + * @param x0 center X + * @param y0 center Y + * @param a vertical radius + * @param b horizontal radius + * @param color + */ +void GL_DrawEllipse(int16_t x0, int16_t y0, int16_t a, int16_t b, LCD_DRAWMODE_t drawMode); + +/** + * Draw a filled ellipse + * + * Output will be clipped to the current clip window. + * + * @param x0 center X + * @param y0 center Y + * @param a vertical radius + * @param b horizontal radius + * @param color + */ +void GL_DrawFilledEllipse(int16_t x0, int16_t y0, int16_t a, int16_t b, LCD_DRAWMODE_t drawMode); + +/** + * Draw a polygon + * + * Output will be clipped to the current clip window. Polygon does + * not need to be convex. They can also be concave or complex. + * + * COLOR_t color = hagl_color(0, 255, 0); + * int16_t vertices[10] = {x0, y0, x1, y1, x2, y2, x3, y3, x4, y4}; + * hagl_draw_polygon(5, vertices, color); + * + * @param numVertices number of vertices + * @param vertices pointer to (an array) of vertices + * @param thickness thickness in pixels + * @param color + */ +void GL_DrawPolygon(int16_t numVertices, int16_t *vertices, int16_t thickness, LCD_DRAWMODE_t drawMode); + +/** + * Draw a filled polygon + * + * Output will be clipped to the current clip window. Polygon does + * not need to be convex. They can also be concave or complex. + * + * COLOR_t color = hagl_color(0, 255, 0); + * int16_t vertices[10] = {x0, y0, x1, y1, x2, y2, x3, y3, x4, y4}; + * hagl_draw_polygon(5, vertices, color); + * + * @param numVertices number of vertices + * @param vertices pointer to (an array) of vertices + * @param thickness thickness in pixels + * @param color + */ +void GL_DrawFilledPolygon(int16_t numVertices, int16_t *vertices, LCD_DRAWMODE_t drawMode); + +/** + * Draw a triangle + * + * Output will be clipped to the current clip window. Internally + * uses hagl_draw_polygon() to draw the triangle. + * + * @param x0 + * @param y0 + * @param x1 + * @param y1 + * @param x2 + * @param y3 + * @param thickness + * @param color + */ +void GL_DrawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t thickness, LCD_DRAWMODE_t drawMode); + +/** + * Draw a filled triangle + * + * Output will be clipped to the current clip window. Internally + * uses hagl_fill_polygon() to draw the triangle. + * + * @param x0 + * @param y0 + * @param x1 + * @param y1 + * @param x2 + * @param y3 + * @param color + */ +void GL_DrawFilledTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, LCD_DRAWMODE_t drawMode); + +/** + * Draw a rounded rectangle + * + * Output will be clipped to the current clip window. + * + * @param x0 + * @param y0 + * @param x0 + * @param y0 + * @param r corner radius + * @param color + */ +void GL_DrawRoundedRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t r, LCD_DRAWMODE_t drawMode); + +/** + * Draw a filled rounded rectangle + * + * Output will be clipped to the current clip window. + * + * @param x0 + * @param y0 + * @param x1 + * @param y1 + * @param r corner radius + * @param color + */ +void GL_DrawFilledRoundedRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t r, LCD_DRAWMODE_t drawMode); + + + + + + +uint16_t GL_GetColorBitmapWidth(const uint16_t *bitmap); +uint16_t GL_GetColorBitmapHeight(const uint16_t *bitmap); +void GL_DrawColorBitmap(const uint16_t *bitmap, uint16_t x0, uint16_t y0); + +uint32_t GL_GetMonoBitmapWidth(const uint32_t *bitmap); +uint32_t GL_GetMonoBitmapHeight(const uint32_t *bitmap); +void GL_DrawMonoBitmap(const uint32_t *bitmap, uint16_t x0, uint16_t y0, LCD_DRAWMODE_t drawMode); +void GL_DrawMonoBitmapCentered(const uint32_t *bitmap, LCD_DRAWMODE_t drawMode); + + + +#endif /* GRAPHICS_GRAPHICSLIBRARY_H_ */ diff --git a/source/Graphics/icons.c b/source/Graphics/icons.c new file mode 100644 index 0000000..586ff91 --- /dev/null +++ b/source/Graphics/icons.c @@ -0,0 +1,564 @@ +// Generated by MonoBitmapConverter +// Bitmap Format: +// [0] bitmap width in pixels +// [1] bitmap height in pixels +// [2] bitmap data + + +#include + +uint32_t battery0[] = +{ 20, 25, + 0x00000000, 0x0003fc00, 0x3fc03fff, 0xc2000420, 0x00420004, 0x20004200, 0x04200042, 0x00042000, + 0x42000420, 0x00420004, 0x20004200, 0x04200042, 0x00042000, 0x4200043f, 0xffc00000, 0x00000000, +}; + +uint32_t battery1[] = +{ 20, 25, + 0x00000000, 0x0003fc00, 0x3fc03fff, 0xc2000420, 0x00420004, 0x20004200, 0x04200042, 0x00042000, + 0x42000420, 0x00420004, 0x20004200, 0x042fff42, 0xfff42fff, 0x4200043f, 0xffc00000, 0x00000000, +}; + +uint32_t battery2[] = +{ 20, 25, + 0x00000000, 0x0003fc00, 0x3fc03fff, 0xc2000420, 0x00420004, 0x20004200, 0x04200042, 0x00042000, + 0x4200042f, 0xff42fff4, 0x2fff4200, 0x042fff42, 0xfff42fff, 0x4200043f, 0xffc00000, 0x00000000, +}; + +uint32_t battery3[] = +{ 20, 25, + 0x00000000, 0x0003fc00, 0x3fc03fff, 0xc2000420, 0x00420004, 0x20004200, 0x042fff42, 0xfff42fff, + 0x4200042f, 0xff42fff4, 0x2fff4200, 0x042fff42, 0xfff42fff, 0x4200043f, 0xffc00000, 0x00000000, +}; + +uint32_t battery4[] = +{ 20, 25, + 0x00000000, 0x0003fc00, 0x3fc03fff, 0xc200042f, 0xff42fff4, 0x2fff4200, 0x042fff42, 0xfff42fff, + 0x4200042f, 0xff42fff4, 0x2fff4200, 0x042fff42, 0xfff42fff, 0x4200043f, 0xffc00000, 0x00000000, +}; + +uint32_t border60x60[] = +{ 60, 60, + 0x03ffffff, 0xfffffc01, 0xc0000000, 0x00003820, 0x00000000, 0x00004400, 0x00000000, 0x00024000, + 0x00000000, 0x00240000, 0x00000000, 0x02800000, 0x00000000, 0x18000000, 0x00000001, 0x80000000, + 0x00000018, 0x00000000, 0x00000180, 0x00000000, 0x00001800, 0x00000000, 0x00018000, 0x00000000, + 0x00180000, 0x00000000, 0x01800000, 0x00000000, 0x18000000, 0x00000001, 0x80000000, 0x00000018, + 0x00000000, 0x00000180, 0x00000000, 0x00001800, 0x00000000, 0x00018000, 0x00000000, 0x00180000, + 0x00000000, 0x01800000, 0x00000000, 0x18000000, 0x00000001, 0x80000000, 0x00000018, 0x00000000, + 0x00000180, 0x00000000, 0x00001800, 0x00000000, 0x00018000, 0x00000000, 0x00180000, 0x00000000, + 0x01800000, 0x00000000, 0x18000000, 0x00000001, 0x80000000, 0x00000018, 0x00000000, 0x00000180, + 0x00000000, 0x00001800, 0x00000000, 0x00018000, 0x00000000, 0x00180000, 0x00000000, 0x01800000, + 0x00000000, 0x18000000, 0x00000001, 0x80000000, 0x00000018, 0x00000000, 0x00000180, 0x00000000, + 0x00001800, 0x00000000, 0x00018000, 0x00000000, 0x00180000, 0x00000000, 0x01800000, 0x00000000, + 0x18000000, 0x00000001, 0x80000000, 0x00000018, 0x00000000, 0x00000180, 0x00000000, 0x00001800, + 0x00000000, 0x00018000, 0x00000000, 0x00180000, 0x00000000, 0x01400000, 0x00000000, 0x24000000, + 0x00000002, 0x40000000, 0x00000022, 0x00000000, 0x0000041c, 0x00000000, 0x0003803f, 0xffffffff, + 0xffc00000, +}; + +uint32_t box_checked[] = +{ 18, 18, + 0x00000fff, 0xc7ffe180, 0x00600058, 0x00360019, 0x900c6606, 0x18c30619, 0x8983c660, 0x61980066, + 0x0019fffe, 0x3fff0000, 0x00000000, +}; + +uint32_t box_unchecked[] = +{ 18, 18, + 0x00000fff, 0xc7fff980, 0x06600198, 0x00660019, 0x80066001, 0x98006600, 0x19800660, 0x01980066, + 0x0019fffe, 0x3fff0000, 0x00000000, +}; + +uint32_t clamp2[] = +{ 48, 48, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, + 0x00000000, 0x001fe000, 0x0000000f, 0xfe000000, 0x0007ff00, 0x00000003, 0xff800000, 0x00003f80, + 0x00000300, 0x1fc00000, 0x07800fc0, 0x00000780, 0x07c00000, 0x078007f0, 0x00000780, 0x07f80000, + 0x038007f8, 0x000003c0, 0x0efc0000, 0x03c00c7c, 0x000001f0, 0x187c0000, 0x01fcf07f, 0xc00000ff, + 0xf77ff000, 0x00ffe77f, 0xfc00007f, 0xe7fffe00, 0x003fe0ff, 0xf700000f, 0xe0c0ef80, 0x0001e0c0, + 0x32c00001, 0xf0c01be0, 0x0001f8c0, 0x0d600000, 0x7dc007e0, 0x00001fc0, 0x03e00000, 0x1fc00000, + 0x00000fc0, 0x00000000, 0x07e00000, 0x000007f0, 0x00000000, 0x03fc0000, 0x000003dc, 0x00000000, + 0x01ee0000, 0x000000f6, 0x00000000, 0x007f0000, 0x0000003f, 0x00000000, 0x001e0000, 0x0000000c, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + +}; + +uint32_t clampIcon[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff, 0xf0000000, 0x00003fff, + 0xc0000000, 0x000fffff, 0x00000000, 0x01fffff8, 0x00000000, 0x3fffffc0, 0x00000007, 0xf801fe00, + 0x000000fe, 0x0007f000, 0x00000fc0, 0x003f0000, 0x0001f800, 0x01f80000, 0x001f0000, 0x0f800000, + 0x03f00000, 0xfc000000, 0x3e000007, 0xc0000007, 0xe000007c, 0x0000007e, 0x000007c0, 0x00000fe0, + 0x00007c00, 0x0001fe00, 0x0007c000, 0x003fe000, 0x007c7fff, 0xfffe0000, 0x07c7ffff, 0xffe00000, + 0x7c7fffff, 0xff00000f, 0xc7ffffff, 0xf00000f8, 0x7fffffff, 0x80001f80, 0x00001ffc, 0x0003f000, + 0x0001ffe0, 0x007f0000, 0x001fff80, 0x1fe00000, 0x03ffffff, 0xfc000000, 0x7fffffff, 0x8000000f, + 0xfffffff0, 0x000001fe, 0x03fffc00, 0x00003fc0, 0x0fff0000, 0x0007f800, 0x00000000, 0x00ff0000, + 0x00000000, 0x1fe00000, 0x00000003, 0xfc000000, 0x0000007f, 0x80000000, 0x00000ff0, 0x00000000, + 0x0001fe00, 0x00000000, 0x003fc000, 0x00000000, 0x07f80000, 0x00000000, 0xff000000, 0x00000007, + 0xe0000000, 0x0000007e, 0x00000000, 0x000003c0, 0x00000000, 0x00001800, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t clampIcon2[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x0007ff00, 0x00000000, 0x01fffc00, 0x00000000, 0x7ffff000, + 0xc000000f, 0xffff800f, 0x000001ff, 0xfffc01fc, 0x00003fc0, 0x1fe01ff0, 0x0007f000, 0x7f03ffe0, + 0x00fe0003, 0xf80fff80, 0x0fc0001f, 0x803ffe01, 0xf80000fc, 0x007ff83f, 0x000007c0, 0x01fffff0, + 0x00007e00, 0x07fffe00, 0x0003e000, 0x1fffe000, 0x003e0000, 0x3f1e0000, 0x03e00000, 0xeee00000, + 0x3e000000, 0xe0000000, 0x0000002e, 0xe000003e, 0x0000071e, 0x000003e0, 0x0000ffe0, 0x00003e00, + 0x003ffe00, 0x0003e000, 0x0ffff000, 0x007e0003, 0xffff0000, 0x07c000ff, 0xe1f80000, 0xfc003ff8, + 0x0fc0001f, 0x800ffe00, 0xfe0003f8, 0x03ffc007, 0xf0007f00, 0xfff0003f, 0xc01fe03f, 0xfc0001ff, + 0xfffc03ff, 0x00000fff, 0xff801fc0, 0x00007fff, 0xf000f800, 0x0001fffc, 0x00060000, 0x0007ff00, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t dangerousVoltage68x60[] = +{ 68, 60, + 0x00000000, 0xf0000000, 0x00000000, 0x1f800000, 0x00000000, 0x03fc0000, 0x00000000, 0x0070e000, + 0x00000000, 0x00070e00, 0x00000000, 0x0000e070, 0x00000000, 0x00000c03, 0x00000000, 0x000001c0, + 0x38000000, 0x00000038, 0x01c00000, 0x00000003, 0x801c0000, 0x00000000, 0x7000e000, 0x00000000, + 0x07000e00, 0x00000000, 0x00e00070, 0x00000000, 0x001c0003, 0x80000000, 0x0001c000, 0x38000000, + 0x00003800, 0x01c00000, 0x00000380, 0x001c0000, 0x00000070, 0x0000e000, 0x00000007, 0x00000e00, + 0x00000000, 0xe0000070, 0x00000000, 0x1c000003, 0x80000000, 0x01c03ffc, 0x38000000, 0x003803ff, + 0x81c00000, 0x0003807f, 0xf81c0000, 0x00007007, 0xff00e000, 0x00000600, 0x7ff00600, 0x000000e0, + 0x0ffe0070, 0x0000001c, 0x00ffc003, 0x80000001, 0xc00ffc00, 0x38000000, 0x3801ff80, 0x01c00000, + 0x03801ff0, 0x001c0000, 0x007001ff, 0xf800e000, 0x000e003f, 0xff800700, 0x0000e003, 0xfff80070, + 0x00001c00, 0x3fff0003, 0x800001c0, 0x07fff000, 0x38000038, 0x007ffe00, 0x01c00003, 0x000fffc0, + 0x001c0000, 0x7000fffc, 0x0000e000, 0x0e00007f, 0x80000700, 0x00e00007, 0xf0000070, 0x001c0000, + 0xff000003, 0x8001c000, 0x0fe00000, 0x38003800, 0x00fc0000, 0x01c00300, 0x000fc000, 0x000e0070, + 0x0001f800, 0x0000e00e, 0x00001f00, 0x00000700, 0xe00001f0, 0x00000070, 0x1c00001e, 0x00000003, + 0x81c00003, 0xc0000000, 0x38380000, 0x3c000000, 0x01c70000, 0x03800000, 0x000e7000, 0x00300000, + 0x0000ee00, 0x00000000, 0x000007e0, 0x00000000, 0x0000007c, 0x00000000, 0x00000003, 0xe0000000, + 0x00000000, 0x7f000000, 0x00000000, 0x0f7fffff, 0xffffffff, 0xffe3ffff, 0xffffffff, 0xfffc0000, +}; + +uint32_t DC1[] = +{ 28, 28, + 0x00000000, 0x001dc000, 0x03de0000, 0x38e00003, 0x8e000078, 0xf000078f, 0x000078f0, 0x0007ff00, + 0x00471000, 0x0c710000, 0xfff8000f, 0xff8000f0, 0x78001e03, 0x8001e03c, 0x001e03c0, 0x03e03efe, + 0x3c03efe3, 0xc03e023c, 0x01e023c0, 0x1e023c01, 0xe023c01e, 0x02180000, 0x21800003, 0xf8000000, + 0x00000000, +}; + +uint32_t directConnectIcon[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00380000, 0x00000000, + 0x03e00000, 0x00000000, 0x1f800000, 0x00000000, 0xfe000000, 0x00000007, 0xf8000000, 0x0000007f, + 0xe0000000, 0x000003ff, 0x80000000, 0x00001ffe, 0x00000000, 0x0000fff0, 0x00000000, 0x000ffff0, + 0x00000000, 0x00ffffe0, 0x00000000, 0x1ffffe00, 0x000001e1, 0xff87e000, 0x3fffffff, 0xfc060003, + 0xffffffff, 0xff00003f, 0xffffffff, 0xfe0001ff, 0xffffffff, 0xe0001fff, 0xfffffffe, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t directConnectIcon2[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, + 0x00000000, 0x000003e0, 0x00000000, 0x00001f80, 0x00000000, 0x0000fe00, 0x00000000, 0x0007f800, + 0x00000000, 0x007fe000, 0x00000000, 0x03ff8000, 0x00000000, 0x1ffe0000, 0x00000000, 0xfff00000, + 0x0000000f, 0xfff00000, 0x000000ff, 0xffe00000, 0x00001fff, 0xfe000000, 0x01e1ff87, 0xe0003fff, + 0xfffffc06, 0x0003ffff, 0xffffff00, 0x003fffff, 0xfffffe00, 0x01ffffff, 0xffffe000, 0x1fffffff, + 0xfffe0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x00000000, 0x00000360, 0x00000000, + 0x00001b80, 0x00000000, 0x0000ce00, 0x00000000, 0x00043800, 0x00000000, 0x0060e000, 0x00000000, + 0x03038000, 0x00000000, 0x180e0000, 0x00000000, 0x80300000, 0x00000008, 0x01f00000, 0x00000080, + 0x01e00000, 0x0000180f, 0xc2000000, 0x01e10087, 0xe0003fff, 0xf3f00c06, 0x00020000, 0x00007f00, + 0x00300000, 0x00001e00, 0x01000000, 0x00002000, 0x1fffffff, 0xfffe0000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t directConnectIcon3[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, + 0x00000000, 0x000003e0, 0x00000000, 0x00001f80, 0x00000000, 0x0000fe00, 0x00000000, 0x0007f800, + 0x00000000, 0x007fe000, 0x00000000, 0x03ff8000, 0x00000000, 0x1ffe0000, 0x00000000, 0xfff00000, + 0x0000000f, 0xfff00000, 0x000000ff, 0xffe00000, 0x00001fff, 0xfe000000, 0x01e1ff77, 0x60003fff, + 0xfffffaaa, 0x0003ffff, 0xffffddc0, 0x003fffff, 0xfffffe00, 0x01ffffff, 0xffffe000, 0x1fffffff, + 0xfffe0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x00000000, 0x00000360, 0x00000000, + 0x00001b80, 0x00000000, 0x0000ce00, 0x00000000, 0x00043800, 0x00000000, 0x0060e000, 0x00000000, + 0x03038000, 0x00000000, 0x180e0000, 0x00000000, 0x80300000, 0x00000008, 0x01f00000, 0x00000080, + 0x01e00000, 0x00001800, 0x02000000, 0x01e10088, 0xa0003fff, 0xf3f00556, 0x00020000, 0x00002220, + 0x00300000, 0x00000200, 0x01000000, 0x00002000, 0x1fffffff, 0xfffe0000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t directConnectIcon4[] = +{ 60, 60, + 0x03ffffff, 0xfffffc01, 0xc0000000, 0x00003820, 0x00000000, 0x00004400, 0x00000000, 0x00024000, + 0x00000000, 0x00240000, 0x00000000, 0x02800000, 0x00000000, 0x18000000, 0x00000001, 0x80000038, + 0x00000018, 0x000003e0, 0x00000180, 0x00001f80, 0x00001800, 0x0000fe00, 0x00018000, 0x0007f800, + 0x00180000, 0x007fe000, 0x01800000, 0x03ff8000, 0x18000000, 0x1ffe0001, 0x80000000, 0xfff00018, + 0x0000000f, 0xfff00180, 0x000000ff, 0xffe01800, 0x00001fff, 0xfe018000, 0x01e1ff77, 0x60183fff, + 0xfffffaaa, 0x0183ffff, 0xffffddc0, 0x183fffff, 0xfffffe01, 0x81ffffff, 0xffffe018, 0x1fffffff, + 0xfffe0180, 0x00000000, 0x00001800, 0x00000000, 0x00018000, 0x00000000, 0x00180000, 0x00000000, + 0x01800000, 0x00000000, 0x18000000, 0x00000001, 0x80000038, 0x00000018, 0x00000360, 0x00000180, + 0x00001b80, 0x00001800, 0x0000ce00, 0x00018000, 0x00043800, 0x00180000, 0x0060e000, 0x01800000, + 0x03038000, 0x18000000, 0x180e0001, 0x80000000, 0x80300018, 0x00000008, 0x01f00180, 0x00000080, + 0x01e01800, 0x00001800, 0x02018000, 0x01e10088, 0xa0183fff, 0xf3f00556, 0x01820000, 0x00002220, + 0x18300000, 0x00000201, 0x81000000, 0x00002018, 0x1fffffff, 0xfffe0180, 0x00000000, 0x00001800, + 0x00000000, 0x00018000, 0x00000000, 0x00180000, 0x00000000, 0x01400000, 0x00000000, 0x24000000, + 0x00000002, 0x40000000, 0x00000022, 0x00000000, 0x0000041c, 0x00000000, 0x0003803f, 0xffffffff, + 0xffc00000, +}; + +uint32_t directConnectIcon5[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00380000, 0x00000000, + 0x03e00000, 0x00000000, 0x1f800000, 0x00000000, 0xfe000000, 0x00000007, 0xf8000000, 0x0000007f, + 0xe0000000, 0x000003ff, 0x80000000, 0x00001ffe, 0x00000000, 0x0000fff0, 0x00000000, 0x000ffff0, + 0x00000000, 0x00ffffe0, 0x00000000, 0x1ffffe00, 0x000001e1, 0xff776000, 0x3fffffff, 0xfaaa0003, + 0xffffffff, 0xddc0003f, 0xffffffff, 0xfe0001ff, 0xffffffff, 0xe0001fff, 0xfffffffe, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t highVoltageIcon[] = +{ 15, 25, + 0x00000ff8, 0x1fe07f80, 0xff01fc07, 0xf00fc01f, 0xfc7ff8ff, 0xe1ffc7ff, 0x0ffc01f0, 0x07e00f80, + 0x1e007c00, 0xf001e007, 0x800e0018, 0x00200000, +}; + +uint32_t inductionIcon[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000001f, 0xffffffff, 0xfff003ff, + 0xffffffff, 0xff007fff, 0xffffffff, 0xf007f800, 0x001fffff, 0x00df0000, 0x00f01ff0, 0x0ef00000, + 0x07fe0200, 0xf7000000, 0xffffe01f, 0xbc00001f, 0xfffc01fd, 0xf80003ff, 0xffe03fef, 0xfe00ffff, + 0xfe03feff, 0xffffffff, 0xf03ff7ff, 0xffffffff, 0x03ff81ff, 0xfffffff0, 0x3fffe001, 0xffffff01, + 0xffffffe0, 0x3ffff81f, 0xffffffff, 0xffff81ff, 0xffffffff, 0xfff81fff, 0xffffffff, 0xffc1ffff, + 0xffffffff, 0xfc1fffff, 0xffffffff, 0xc1ffffff, 0xfffffffc, 0x1fffffff, 0xffffffe1, 0xffffffff, + 0xfffffe1f, 0xc7ffffff, 0xffffe1fe, 0xafffffff, 0xfffe1fed, 0xffffffff, 0xffe0feaf, 0xffffffff, + 0xfc07ffff, 0xffffffff, 0x803fffff, 0xfffffff0, 0x01ffffff, 0xfffffe00, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000060, 0x00000030, 0x00000380, + 0x00000e00, 0x00001fc0, 0x001fc000, 0x00007fff, 0xfff00000, 0x00003fff, 0xe0000000, 0x60000000, + 0x00300007, 0x00000000, 0x0700003c, 0x00000001, 0xe00001f8, 0x000000fc, 0x000007fc, 0x0001ff00, + 0x006007ff, 0xffff0030, 0x070003ff, 0xfe000700, 0x38000000, 0x0000e001, 0xe0000000, 0x003c0007, + 0xc0000000, 0x1f00001f, 0x8000000f, 0xc000007f, 0xc0001ff0, 0x0000007f, 0xfffff000, 0x0000003f, + 0xffe00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t lamp[] = +{ 28, 28, + 0x00000000, 0x00000000, 0x00000000, 0x60000006, 0x00000060, 0x00000f00, 0x0003fc00, 0x00606000, + 0x0fff0001, 0xfff80010, 0x00800100, 0x08003fff, 0xc003fffc, 0x00010800, 0x00198000, 0x00f00000, + 0x06000006, 0x060000e6, 0x70001c63, 0x80018618, 0x00006000, 0x00060000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t ld[] = +{ 21, 18, + 0x3e0001f0, 0x000f8000, 0x780007c0, 0x003e0001, 0xf0ff0f0f, 0xfc787ff7, 0xc3efbfff, 0x3fff00ff, + 0xf8077ffc, 0xf803efc0, 0x1ffc00ff, 0xc00ffc00, +}; + +uint32_t ld2[] = +{ 20, 18, + 0xf0000f00, 0x00f0000f, 0x0000f000, 0x0f0000f0, 0xff0f0ffc, 0xf0ffef0f, 0x3efff1ff, 0xf00fff00, + 0xffff1f00, 0xf3e00ffe, 0x00ffc00f, 0xf0000000, +}; + +uint32_t menuMore[] = +{ 19, 14, + 0xf0780f07, 0x80f0780f, 0x0780f078, 0x0f0780f0, 0x781e0f07, 0x83c1e0f0, 0x783c1e0f, 0x0783c1e0, + 0xf0000000, +}; + +uint32_t power0[] = +{ 81, 42, + 0x00000000, 0x00000000, 0x00018000, 0x00000000, 0x00000003, 0xc0000000, 0x00000000, 0x0007e000, + 0x00000000, 0x0000000f, 0xf0000000, 0x00000000, 0x001f9800, 0x00000000, 0x0000003f, 0x0c000000, + 0x00000000, 0x007e0600, 0x00000000, 0x000000fc, 0x03000000, 0x00000000, 0x01f80180, 0x00000000, + 0x000000f0, 0x00c00000, 0x00000000, 0x0c600060, 0x00000000, 0x00001e30, 0x00300000, 0x00000000, + 0x3f180018, 0x00000000, 0x00007f8c, 0x000c0000, 0x00000000, 0xfcc60006, 0x00000000, 0x0001f863, + 0x00030000, 0x00000003, 0xf0318001, 0x80000000, 0x0007e018, 0xc000c000, 0x0000000f, 0xc00c6000, + 0x60000000, 0x00078006, 0x30003000, 0x00000063, 0x00031800, 0x18000000, 0x00f18001, 0x8c000c00, + 0x000001f8, 0xc000c600, 0x06000000, 0x03fc6000, 0x63000300, 0x000007e6, 0x30003180, 0x01800000, + 0x0fc31800, 0x18c000c0, 0x00001f81, 0x8c000c60, 0x00600000, 0x3f00c600, 0x06300030, 0x00007e00, + 0x63000318, 0x00180000, 0x3c003180, 0x018c000c, 0x00031800, 0x18c000c6, 0x00060007, 0x8c000c60, + 0x00630003, 0x000fc600, 0x06300031, 0x8001801f, 0xe3000318, 0x0018c000, 0xc03f3180, 0x018c000c, + 0x6000607e, 0x18c000c6, 0x00063000, 0x30fc0c60, 0x00630003, 0x180019f8, 0x06300031, 0x80018c00, + 0x0ff00318, 0x0018c000, 0xc60007e0, 0x018c000c, 0x60006300, 0x03ffffc7, 0xfffe3fff, 0xf1ffffff, + 0xffe3ffff, 0x1ffff8ff, 0xffc00000, +}; + +uint32_t power1[] = +{ 81, 42, + 0x00000000, 0x00000000, 0x00018000, 0x00000000, 0x00000003, 0xc0000000, 0x00000000, 0x0007e000, + 0x00000000, 0x0000000f, 0xf0000000, 0x00000000, 0x001f9800, 0x00000000, 0x0000003f, 0x0c000000, + 0x00000000, 0x007e0600, 0x00000000, 0x000000fc, 0x03000000, 0x00000000, 0x01f80180, 0x00000000, + 0x000000f0, 0x00c00000, 0x00000000, 0x0c600060, 0x00000000, 0x00001e30, 0x00300000, 0x00000000, + 0x3f180018, 0x00000000, 0x00007f8c, 0x000c0000, 0x00000000, 0xfcc60006, 0x00000000, 0x0001f863, + 0x00030000, 0x00000003, 0xf0318001, 0x80000000, 0x0007e018, 0xc000c000, 0x0000000f, 0xc00c6000, + 0x60000000, 0x00078006, 0x30003000, 0x00000063, 0x00031800, 0x18000000, 0x00f18001, 0x8c000c00, + 0x000001f8, 0xc000c600, 0x06000000, 0x03fc6000, 0x63000300, 0x000007e6, 0x30003180, 0x01800000, + 0x0fc31800, 0x18c000c0, 0x00001f81, 0x8c000c60, 0x00600000, 0x3f00c600, 0x06300030, 0x00007e00, + 0x63000318, 0x00180000, 0x3c003180, 0x018c000c, 0x00031800, 0x18c000c6, 0x00060007, 0x8c000c60, + 0x00630003, 0x000fc600, 0x06300031, 0x8001801f, 0xe3000318, 0x0018c000, 0xc03ff180, 0x018c000c, + 0x6000607f, 0xf8c000c6, 0x00063000, 0x30fffc60, 0x00630003, 0x180019ff, 0xfe300031, 0x80018c00, + 0x0fffff18, 0x0018c000, 0xc60007ff, 0xff8c000c, 0x60006300, 0x03ffffc7, 0xfffe3fff, 0xf1ffffff, + 0xffe3ffff, 0x1ffff8ff, 0xffc00000, +}; + +uint32_t power2[] = +{ 81, 42, + 0x00000000, 0x00000000, 0x00018000, 0x00000000, 0x00000003, 0xc0000000, 0x00000000, 0x0007e000, + 0x00000000, 0x0000000f, 0xf0000000, 0x00000000, 0x001f9800, 0x00000000, 0x0000003f, 0x0c000000, + 0x00000000, 0x007e0600, 0x00000000, 0x000000fc, 0x03000000, 0x00000000, 0x01f80180, 0x00000000, + 0x000000f0, 0x00c00000, 0x00000000, 0x0c600060, 0x00000000, 0x00001e30, 0x00300000, 0x00000000, + 0x3f180018, 0x00000000, 0x00007f8c, 0x000c0000, 0x00000000, 0xfcc60006, 0x00000000, 0x0001f863, + 0x00030000, 0x00000003, 0xf0318001, 0x80000000, 0x0007e018, 0xc000c000, 0x0000000f, 0xc00c6000, + 0x60000000, 0x00078006, 0x30003000, 0x00000063, 0x00031800, 0x18000000, 0x00f18001, 0x8c000c00, + 0x000001f8, 0xc000c600, 0x06000000, 0x03fc6000, 0x63000300, 0x000007fe, 0x30003180, 0x01800000, + 0x0fff1800, 0x18c000c0, 0x00001fff, 0x8c000c60, 0x00600000, 0x3fffc600, 0x06300030, 0x00007fff, + 0xe3000318, 0x00180000, 0x3ffff180, 0x018c000c, 0x00031fff, 0xf8c000c6, 0x00060007, 0x8ffffc60, + 0x00630003, 0x000fc7ff, 0xfe300031, 0x8001801f, 0xe3ffff18, 0x0018c000, 0xc03ff1ff, 0xff8c000c, + 0x6000607f, 0xf8ffffc6, 0x00063000, 0x30fffc7f, 0xffe30003, 0x180019ff, 0xfe3ffff1, 0x80018c00, + 0x0fffff1f, 0xfff8c000, 0xc60007ff, 0xff8ffffc, 0x60006300, 0x03ffffc7, 0xfffe3fff, 0xf1ffffff, + 0xffe3ffff, 0x1ffff8ff, 0xffc00000, +}; + +uint32_t power3[] = +{ 81, 42, + 0x00000000, 0x00000000, 0x00018000, 0x00000000, 0x00000003, 0xc0000000, 0x00000000, 0x0007e000, + 0x00000000, 0x0000000f, 0xf0000000, 0x00000000, 0x001f9800, 0x00000000, 0x0000003f, 0x0c000000, + 0x00000000, 0x007e0600, 0x00000000, 0x000000fc, 0x03000000, 0x00000000, 0x01f80180, 0x00000000, + 0x000000f0, 0x00c00000, 0x00000000, 0x0c600060, 0x00000000, 0x00001e30, 0x00300000, 0x00000000, + 0x3f180018, 0x00000000, 0x00007f8c, 0x000c0000, 0x00000000, 0xffc60006, 0x00000000, 0x0001ffe3, + 0x00030000, 0x00000003, 0xfff18001, 0x80000000, 0x0007fff8, 0xc000c000, 0x0000000f, 0xfffc6000, + 0x60000000, 0x0007fffe, 0x30003000, 0x00000063, 0xffff1800, 0x18000000, 0x00f1ffff, 0x8c000c00, + 0x000001f8, 0xffffc600, 0x06000000, 0x03fc7fff, 0xe3000300, 0x000007fe, 0x3ffff180, 0x01800000, + 0x0fff1fff, 0xf8c000c0, 0x00001fff, 0x8ffffc60, 0x00600000, 0x3fffc7ff, 0xfe300030, 0x00007fff, + 0xe3ffff18, 0x00180000, 0x3ffff1ff, 0xff8c000c, 0x00031fff, 0xf8ffffc6, 0x00060007, 0x8ffffc7f, + 0xffe30003, 0x000fc7ff, 0xfe3ffff1, 0x8001801f, 0xe3ffff1f, 0xfff8c000, 0xc03ff1ff, 0xff8ffffc, + 0x6000607f, 0xf8ffffc7, 0xfffe3000, 0x30fffc7f, 0xffe3ffff, 0x180019ff, 0xfe3ffff1, 0xffff8c00, + 0x0fffff1f, 0xfff8ffff, 0xc60007ff, 0xff8ffffc, 0x7fffe300, 0x03ffffc7, 0xfffe3fff, 0xf1ffffff, + 0xffe3ffff, 0x1ffff8ff, 0xffc00000, +}; + +uint32_t power4[] = +{ 81, 42, + 0x00000000, 0x00000000, 0x00018000, 0x00000000, 0x00000003, 0xc0000000, 0x00000000, 0x0007e000, + 0x00000000, 0x0000000f, 0xf0000000, 0x00000000, 0x001ff800, 0x00000000, 0x0000003f, 0xfc000000, + 0x00000000, 0x007ffe00, 0x00000000, 0x000000ff, 0xff000000, 0x00000000, 0x01ffff80, 0x00000000, + 0x000000ff, 0xffc00000, 0x00000000, 0x0c7fffe0, 0x00000000, 0x00001e3f, 0xfff00000, 0x00000000, + 0x3f1ffff8, 0x00000000, 0x00007f8f, 0xfffc0000, 0x00000000, 0xffc7fffe, 0x00000000, 0x0001ffe3, + 0xffff0000, 0x00000003, 0xfff1ffff, 0x80000000, 0x0007fff8, 0xffffc000, 0x0000000f, 0xfffc7fff, + 0xe0000000, 0x0007fffe, 0x3ffff000, 0x00000063, 0xffff1fff, 0xf8000000, 0x00f1ffff, 0x8ffffc00, + 0x000001f8, 0xffffc7ff, 0xfe000000, 0x03fc7fff, 0xe3ffff00, 0x000007fe, 0x3ffff1ff, 0xff800000, + 0x0fff1fff, 0xf8ffffc0, 0x00001fff, 0x8ffffc7f, 0xffe00000, 0x3fffc7ff, 0xfe3ffff0, 0x00007fff, + 0xe3ffff1f, 0xfff80000, 0x3ffff1ff, 0xff8ffffc, 0x00031fff, 0xf8ffffc7, 0xfffe0007, 0x8ffffc7f, + 0xffe3ffff, 0x000fc7ff, 0xfe3ffff1, 0xffff801f, 0xe3ffff1f, 0xfff8ffff, 0xc03ff1ff, 0xff8ffffc, + 0x7fffe07f, 0xf8ffffc7, 0xfffe3fff, 0xf0fffc7f, 0xffe3ffff, 0x1ffff9ff, 0xfe3ffff1, 0xffff8fff, + 0xffffff1f, 0xfff8ffff, 0xc7ffffff, 0xff8ffffc, 0x7fffe3ff, 0xffffffc7, 0xfffe3fff, 0xf1ffffff, + 0xffe3ffff, 0x1ffff8ff, 0xffc00000, +}; + +uint32_t teacup[] = +{ 120, 116, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0x00000000, 0x00000000, + 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0x00000000, 0x00000000, 0x00000000, + 0x000c0000, 0x00000000, 0x00000000, 0x00000000, 0x0c000000, 0x00000000, 0x00000000, 0x0000000e, + 0x00000000, 0x00000000, 0x00000000, 0x00000e00, 0x00000000, 0x00000000, 0x00000000, 0x000e0000, + 0x00000000, 0x00000000, 0x00000000, 0x0e000000, 0x00000000, 0x00000000, 0x0000000e, 0x00000000, + 0x00000000, 0x00000000, 0x00000e00, 0x00000000, 0x00000000, 0x00000000, 0x000e0000, 0x00000000, + 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000, + 0x00000000, 0x00001e00, 0x00000000, 0x00000000, 0x00000000, 0x003c0000, 0x00000000, 0x00000000, + 0x00000000, 0x3c000000, 0x00000000, 0x00000000, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, + 0x00007800, 0x00000000, 0x00000000, 0x00000000, 0x00780000, 0x00000000, 0x00000000, 0x00000000, + 0x70000000, 0x00000000, 0x00000000, 0x00000070, 0x00000000, 0x00000000, 0x00000000, 0x0000f000, + 0x00000000, 0x00000000, 0x00000000, 0x00e00000, 0x00000000, 0x00000000, 0x00000000, 0xe0000000, + 0x00000000, 0x00000000, 0x000000c0, 0x00000000, 0x00000000, 0x00000000, 0x0000c000, 0x00000000, + 0x00000000, 0x00000000, 0x00c00000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000000, + 0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07ffffff, 0xfffe0000, + 0x00000000, 0x000003ff, 0xffffffff, 0xfff80000, 0x00000000, 0x00ffffff, 0xffffffff, 0xffe00000, + 0x00000007, 0xffffffff, 0xffffffff, 0xfc000000, 0x00001fff, 0xffffffff, 0xffffffff, 0x80000000, + 0x001fffff, 0xffffffff, 0xfffffe00, 0x00000000, 0x07ffffc0, 0x0000003f, 0xfffc0000, 0x00000040, + 0x3e000000, 0x0000001f, 0xe0600000, 0x00007000, 0x00000000, 0x00000000, 0x60000000, 0x007e0000, + 0x00000000, 0x000001e0, 0x00000000, 0x7f800000, 0x00000000, 0x001ffff8, 0x0000007f, 0xfc000000, + 0x00000001, 0xfffffe00, 0x00007fff, 0xf8000000, 0x000fffff, 0xffff0000, 0x007fffff, 0xffffffff, + 0xffffffff, 0xff800000, 0x7fffffff, 0xffffffff, 0xffffffff, 0xc000003f, 0xffffffff, 0xffffffff, + 0xfff83fe0, 0x00003fff, 0xffffffff, 0xffffffff, 0xe007e000, 0x003fffff, 0xffffffff, 0xffffffe0, + 0x03f00000, 0x3fffffff, 0xffffffff, 0xffffc001, 0xf800003f, 0xffffffff, 0xffffffff, 0xffc001f8, + 0x00003fff, 0xffffffff, 0xffffffff, 0xc000f800, 0x003fffff, 0xffffffff, 0xffffff80, 0x00fc0000, + 0x3fffffff, 0xffffffff, 0xffff8000, 0xfe00003f, 0xffffffff, 0xffffffff, 0xff80007e, 0x00003fff, + 0xffffffff, 0xffffffff, 0x80007e00, 0x001fffff, 0xffffffff, 0xffffff00, 0x007e0000, 0x1fffffff, + 0xffffffff, 0xffff0000, 0x7e00001f, 0xffffffff, 0xffffffff, 0xff00007e, 0x00001fff, 0xffffffff, + 0xfffffffe, 0x00007e00, 0x000fffff, 0xffffffff, 0xfffffe00, 0x00fe0000, 0x0fffffff, 0xffffffff, + 0xfffe0000, 0xfe000007, 0xffffffff, 0xffffffff, 0xfc0000fc, 0x000007ff, 0xffffffff, 0xfffffffc, + 0x0001f800, 0x0003ffff, 0xffffffff, 0xfffffc00, 0x03f80000, 0x03ffffff, 0xffffffff, 0xfff80007, + 0xf0000001, 0xffffffff, 0xffffffff, 0xf8000ff0, 0x000001ff, 0xffffffff, 0xfffffffc, 0x001fe000, + 0x0000ffff, 0xffffffff, 0xffffff00, 0x7fc00000, 0x1fffffff, 0xffffffff, 0xffffe1ff, 0x800000f0, + 0x7fffffff, 0xffffffff, 0xffffff00, 0x001f003f, 0xffffffff, 0xffffffff, 0xfffe0000, 0x78003fff, + 0xffffffff, 0xffff8fff, 0xfc0003c0, 0x001fffff, 0xffffffff, 0xff07fff8, 0x000f0000, 0x0fffffff, + 0xfffffffe, 0x01ffce00, 0x1c000007, 0xffffffff, 0xfffffc00, 0x00030038, 0x000003ff, 0xffffffff, + 0xfff80000, 0x01807000, 0x0001ffff, 0xffffffff, 0xf0000000, 0xc0e00000, 0x00ffffff, 0xffffffe0, + 0x000000e0, 0xe0000000, 0x7fffffff, 0xffffc000, 0x0000e0e0, 0x0000003f, 0xffffffff, 0xff000000, + 0x00e06000, 0x00001fff, 0xfffffffc, 0x00000000, 0xc0700000, 0x0007ffff, 0xfffff800, 0x000001c0, + 0x78000000, 0x01ffffff, 0xffe00000, 0x0003803c, 0x00000000, 0xffffffff, 0xe0000000, 0x0f001f00, + 0x0000003f, 0xffffffc0, 0x0000003e, 0x000fc000, 0x00001fff, 0xffff0000, 0x0000fc00, 0x03fc0000, + 0x0007ffff, 0xfc000000, 0x07f80001, 0xff000000, 0x007fffc0, 0x0000007f, 0xf00000ff, 0xf8000000, + 0x00000000, 0x0007ffc0, 0x00003fff, 0xc0000000, 0x00000007, 0xffff8000, 0x000fffff, 0xff000000, + 0x00ffffff, 0xfe000000, 0x03ffffff, 0xffffffff, 0xfffffff0, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffc000, 0x0000001f, 0xffffffff, 0xffffffff, 0xfe000000, 0x000001ff, 0xffffffff, 0xfffffff0, + 0x00000000, 0x00000fff, 0xffffffff, 0xfffe0000, 0x00000000, 0x0000ffff, 0xffffffff, 0xc0000000, + 0x00000000, 0x003fffff, 0xffffff00, 0x00000000, 0x00000000, 0x07ffffff, 0xfffc0000, 0x00000000, + 0x00000000, 0xffffffff, 0xc0000000, 0x00000000, 0x0000000f, 0xfffff800, 0x00000000, 0x00000000, + 0x00000003, 0xf0000000, 0x00000000, +}; + +uint32_t Turtle1[] = +{ 147, 147, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0xe0000000, 0x00000000, 0x00000000, 0x00000000, + 0x01e0fff0, 0x00000000, 0x00000000, 0x00000000, 0x000001fc, 0x1ffff000, 0x00000000, 0x00000000, + 0x00000000, 0x00ff83ff, 0xffc00000, 0x00000000, 0x00000000, 0x0000007f, 0xf07fffff, 0x00000000, + 0x00000000, 0x00000000, 0x003ffe0f, 0xffffe000, 0x00000000, 0x00000000, 0x0000001f, 0xffc1ffff, + 0xfc100000, 0x00000000, 0x00000000, 0x0007fff8, 0x3fffff03, 0xc0000000, 0x00000000, 0x00000003, + 0xffff07ff, 0xffe0fe00, 0x00000000, 0x00000000, 0x0000ffff, 0xe0fffff8, 0x1ff00000, 0x00000000, + 0x00000000, 0x3ffffc1f, 0xfffc07ff, 0xc0000000, 0x00000000, 0x000003ff, 0xff83fffe, 0x007ffe00, + 0x00000000, 0x00000000, 0x001fffc0, 0x1fff0007, 0xfff00000, 0x0f800000, 0x00000001, 0xff8000ff, + 0x80007ffc, 0x000003fc, 0x00000000, 0x00200f00, 0x0003c004, 0x03ff0000, 0x01ffc000, 0x0000000f, + 0x00000000, 0x0003c03f, 0xc040003f, 0xf8000000, 0x0003f000, 0x00700001, 0xfe03f01e, 0x001fff80, + 0x00000000, 0xff8000ff, 0x8000ffe0, 0x3c07f007, 0xfff00000, 0x00003ff8, 0x00fffe00, 0x7ffe0301, + 0xff01fe7e, 0x00000000, 0x07ff81ff, 0xfff03fff, 0xe0007ff0, 0x7f87c000, 0x000001ff, 0xf07fffff, + 0x07fffe00, 0x1ffc0ff0, 0xf8000000, 0x007ffe1f, 0xffffe0ff, 0xfff007ff, 0x03fe1e00, 0x0000001f, + 0xff83ffff, 0xfc1ffffe, 0x01ffc0ff, 0xe7c00000, 0x0003fff0, 0x7fffff83, 0xffff807f, 0xf81ffff0, + 0x00000000, 0xfffe0fff, 0xfff07fff, 0xc01ffe07, 0xfffe0000, 0x00003fff, 0xc1fffffe, 0x0ffff00f, + 0xff81ffff, 0x80000000, 0x07fff83f, 0xffffc1ff, 0xf803ffe0, 0x7fffe000, 0x000001ff, 0xfe0fffff, + 0xf83ffe00, 0xfff80fff, 0xf8000000, 0x007fffc1, 0xffffff07, 0xff007ffe, 0x03fffe00, 0x0000000f, + 0xfff83fff, 0xffe0ff80, 0x1fff80ff, 0xff800000, 0x0003ffff, 0x07fffffc, 0x1fc00fff, 0xf03fffe0, + 0x00000000, 0x7fffe0ff, 0xffff83e0, 0x07fff80f, 0xfff80000, 0x00001fff, 0xfc3fffff, 0xf07001ff, + 0xfe03fffe, 0x00000000, 0x07ffff07, 0xfffffe00, 0x00ffff80, 0x0fff0000, 0x000000ff, 0xffe0ffff, + 0xffc0007f, 0xffe0007f, 0xc0000000, 0x003ffffc, 0x1fffffe0, 0x003ffff8, 0x0007f000, 0x00000007, + 0xffff83ff, 0xffc0003f, 0xfffe0000, 0x3c000000, 0x000001ff, 0xf07ffe00, 0x001fffff, 0x00f80200, + 0x00000000, 0x00000c0f, 0x8000001f, 0xffffc03f, 0xc0000000, 0x00000000, 0x00000000, 0x001fffff, + 0xf00ffe00, 0x00000000, 0x00000000, 0x0000003f, 0xfffff807, 0xffe00000, 0x00000078, 0x00000000, + 0x007fffff, 0xfe01fffe, 0x00000000, 0x000ffe00, 0x000007ff, 0xffffff00, 0x7fffe000, 0x00000001, + 0xffffffff, 0xffffffff, 0xff801fff, 0xfe000000, 0x00007fff, 0xffffffff, 0xffffffc0, 0x03ffffc0, + 0x00000000, 0x0fffffff, 0xffffffff, 0xffe0007f, 0xfffc0000, 0x000003ff, 0xffffffff, 0xfffffff0, + 0x020fffff, 0x80000000, 0x007fffff, 0xffffffff, 0xfff000c1, 0xfffff800, 0x0000000f, 0xffffffff, + 0xfffffff0, 0x00783fff, 0xff000000, 0x00007fff, 0xffffffff, 0xfff0003f, 0x07ffffe0, 0x00000000, + 0x007fffff, 0xfffffff0, 0x001fe07f, 0xfffc0000, 0x00000000, 0xffffffff, 0xffc0001f, 0xfe07ffff, + 0xc0000000, 0x0000001f, 0xfffffe00, 0x000fffc0, 0x0ffff800, 0x00000040, 0x00000000, 0x0000000f, + 0xfffc003f, 0xff000000, 0x000e0000, 0x00000000, 0x000fffff, 0xc003ffe0, 0x00000001, 0xc0000000, + 0x0000001f, 0xfffffc00, 0x3ffc0000, 0x0000703e, 0x00000000, 0x007fffff, 0xffe003ff, 0x80000000, + 0x080fc1e0, 0x000007ff, 0xffffffff, 0xe03ff000, 0x00000003, 0xf83fffff, 0xffffffff, 0xfffffc07, + 0xfe000000, 0x0000ff0f, 0xffffffff, 0xffffffff, 0xfe00ffc0, 0x00000000, 0x3fc1ffff, 0xffffffff, + 0xffffff00, 0x0ff80000, 0x00000ff8, 0x3fffffff, 0xffffffff, 0xff8001ff, 0x00000000, 0x01ff01ff, + 0xffffffff, 0xffffff80, 0x003fe000, 0x0000003f, 0xe00fffff, 0xffffffff, 0xff800007, 0xfc000000, + 0x0007fc00, 0xffffffff, 0xffffff80, 0x0000fff8, 0x00000000, 0xff800fff, 0xffffffff, 0xff000000, + 0x1fffc000, 0x00001ffe, 0x000fffff, 0xfffffc00, 0x000003ff, 0xfc000000, 0x03fff800, 0x007fffff, + 0x80000000, 0x003fffc0, 0x0000007f, 0xff800000, 0x00000000, 0x00000007, 0xfff80000, 0x0007fff8, + 0x00000000, 0x00000000, 0x00007fff, 0x80000000, 0xffff0000, 0x00000000, 0x00000000, 0x03fff000, + 0x00000fff, 0xf0000000, 0x00000000, 0x00000000, 0x00000000, 0x007ffe00, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +uint32_t turtle2[] = +{ 48, 48, + 0x00000000, 0x00000000, 0x3fc00000, 0x0000ffe0, 0x00000001, 0xfff00000, 0x0003fff0, 0x00000000, + 0x1ff00000, 0x00000200, 0x07c00000, 0x00781fc0, 0x000007ff, 0x8fc00000, 0x07ffe7c0, 0x000077ff, + 0xf3c00000, 0xf3fff180, 0x0003f3ff, 0xe4800007, 0xfbffce00, 0x000ff9ff, 0x9e00000f, 0xf83f3f00, + 0x001ff306, 0x7f00003f, 0xe7f0ff00, 0x003fcffc, 0xff80001f, 0x9ffcff80, 0x00033ffe, 0xffb800f8, + 0x7ffeffbc, 0x00fe7ffe, 0x7fbe00fe, 0x7ffe7fbe, 0x1cff7fff, 0x7f3e3cff, 0x7fff3f3e, 0x7cff3ffe, + 0x073e7cff, 0x3ffce03e, 0x7cffbff9, 0xfc1e1eff, 0x9ff3fc1e, 0x04ff03e7, 0xfc1c00fe, 0x700ff81c, + 0x007cff1f, 0xf0180079, 0xffdff010, 0x0033ffcf, 0xe0000007, 0xffef8000, 0x0007ffef, 0x00000007, + 0xffe60000, 0x0003ffe0, 0x00000000, 0xffc00000, 0x00000000, 0x00000000, 0x20000000, 0x00007f00, + 0x00000000, 0x3f000000, 0x00003f00, 0x00000000, 0x1e000000, 0x00001c00, 0x00000000, 0x00000000, + +}; + +uint32_t txControl[] = +{ 32, 25, + 0x00000000, 0x00000000, 0x000003c0, 0x000000f0, 0x7ffc0038, 0x7ffc0618, 0x7ffc038c, 0x038000cc, + 0x03800044, 0x038c0664, 0x038e0e20, 0x038f1e00, 0x0387bc00, 0x0383f800, 0x0381f000, 0x0380e000, + 0x0380e000, 0x0381f000, 0x0383f800, 0x0387bc00, 0x038f1e00, 0x038e0e00, 0x038c0600, 0x00000000, + 0x00000000, +}; + +uint32_t usbIconSmall[] = +{ 40, 20, + 0x00000000, 0x00000001, 0xc0000000, 0x7fe00000, 0x00ffe000, 0x0001c1c0, 0x00000380, 0x00003c07, + 0x0000007e, 0x0e000010, 0xff1c0000, 0x18ffffff, 0xfffeffff, 0xfffffe7e, 0x00600018, 0x3c003000, + 0x10000018, 0x00000000, 0x0c0e0000, 0x0007ff00, 0x000003ff, 0x00000000, 0x0e000000, 0x00000000, + 0x00000000, +}; + diff --git a/source/Graphics/icons.h b/source/Graphics/icons.h new file mode 100644 index 0000000..38ddcfe --- /dev/null +++ b/source/Graphics/icons.h @@ -0,0 +1,41 @@ +// Generated by MonoBitmapConverter + + + +extern const uint32_t battery0[]; +extern const uint32_t battery1[]; +extern const uint32_t battery2[]; +extern const uint32_t battery3[]; +extern const uint32_t battery4[]; +extern const uint32_t border60x60[]; +extern const uint32_t box_checked[]; +extern const uint32_t box_unchecked[]; +extern const uint32_t clamp2[]; +extern const uint32_t clampIcon[]; +extern const uint32_t clampIcon2[]; +extern const uint32_t dangerousVoltage68x60[]; +extern const uint32_t DC1[]; +extern const uint32_t directConnectIcon[]; +extern const uint32_t directConnectIcon2[]; +extern const uint32_t directConnectIcon3[]; +extern const uint32_t directConnectIcon4[]; +extern const uint32_t directConnectIcon5[]; +extern const uint32_t highVoltageIcon[]; +extern const uint32_t inductionIcon[]; +extern const uint32_t lamp[]; +extern const uint32_t ld[]; +extern const uint32_t ld2[]; +extern const uint32_t menuMore[]; +extern const uint32_t power0[]; +extern const uint32_t power1[]; +extern const uint32_t power2[]; +extern const uint32_t power3[]; +extern const uint32_t power4[]; +extern const uint32_t teacup[]; +extern const uint32_t Turtle1[]; +extern const uint32_t turtle2[]; +extern const uint32_t txControl[]; +extern const uint32_t usbIconSmall[]; + + + diff --git a/source/Graphics/splash.c b/source/Graphics/splash.c new file mode 100644 index 0000000..43e69bd --- /dev/null +++ b/source/Graphics/splash.c @@ -0,0 +1,156 @@ +// Generated by MonoBitmapConverter +// Bitmap Format: +// [0] bitmap width in pixels +// [1] bitmap height in pixels +// [2] bitmap data + + +#include + +uint32_t goldenlandLogo98x60[] = +{ 95, 60, + 0x007fffff, 0xffffffff, 0xfffffe00, 0x03ffffff, 0xffffffff, 0xffffff00, 0x1fffffff, 0xffffffff, + 0xffffff00, 0x7fffffff, 0xffffffff, 0xffffff01, 0xffffffff, 0xffffffff, 0xffffff07, 0xffffffff, + 0xffffffff, 0xffffff1f, 0xf8000000, 0x000fff80, 0x0003fe3f, 0xc0000000, 0x001fff00, 0x0001feff, + 0x00000000, 0x003ffe00, 0x0001fdfc, 0x00000000, 0x007ffc00, 0x0001fff8, 0x00000000, 0x00fff800, + 0x0003ffe0, 0x0001f000, 0x01fff000, 0x0003ffc0, 0x007fff00, 0x03ffe000, 0x0007ff80, 0x07ffff80, + 0x07ffc000, 0x000fff00, 0x3fffff80, 0x0fff8000, 0x001ffe00, 0xffffffc0, 0x1fff0000, 0x003ffc03, + 0xffffffc0, 0x3ffe0000, 0x007ff80f, 0xffffffc0, 0x7ffc0000, 0x00fff03f, 0xffffffc0, 0xfff80000, + 0x01ffe07f, 0xffffff81, 0xfff00000, 0x03ffc1ff, 0xf81fff83, 0xffe00000, 0x07ff83ff, 0xc00fff07, + 0xffc00000, 0x0fff0fff, 0x000ffe0f, 0xff800000, 0x1ffe1ffe, 0x000f801f, 0xff000000, 0x3ffc7ff8, + 0x0000003f, 0xfe000000, 0x7ff8fff0, 0x0000007f, 0xfc000000, 0xfff1ffe0, 0x000000ff, 0xf8000001, + 0xffe3ff80, 0x000001ff, 0xf0000003, 0xffc7ff00, 0x7fff83ff, 0xe0000007, 0xff8ffe01, 0xffff07ff, + 0xc000000f, 0xff1ffc03, 0xfffe0fff, 0x8000001f, 0xfe3ff807, 0xfffc1fff, 0x0000003f, 0xfc7ff00f, + 0xfff83ffe, 0x0000007f, 0xf8ffe01f, 0xfff07ffc, 0x000000ff, 0xf1ffe03f, 0xffe0fff8, 0x000001ff, + 0xe3ffc03f, 0xffc1fff0, 0x000003ff, 0xc7ff8001, 0xff83ffe0, 0x000007ff, 0x87ff8003, 0xff07ffc0, + 0x00000fff, 0x0fff8007, 0xfe0fff80, 0x00001ffe, 0x0fff000f, 0xfc1fffff, 0xfff03ffc, 0x1fff803f, + 0xf83fffff, 0xffe07ff8, 0x1fffffff, 0xf07fffff, 0xffc0fff0, 0x3fffffff, 0xe0ffffff, 0xff81ffe0, + 0x3fffffff, 0xc1ffffff, 0xff03ffc0, 0x3fffffff, 0x83ffffff, 0xfe07ff80, 0x3fffffff, 0x07ffffff, + 0xfc0fff00, 0x1ffffff8, 0x0fffffff, 0xf81ffe00, 0x1fffffc0, 0x1fffffff, 0xf03ffc00, 0x07fffc00, + 0x00000000, 0x007ffc00, 0x007e0000, 0x00000000, 0x01fff800, 0x00000000, 0x00000000, 0x03fbf800, + 0x00000000, 0x00000000, 0x0ff7f800, 0x00000000, 0x00000000, 0x3fc7fc00, 0x00000000, 0x00000001, + 0xff8fffff, 0xffffffff, 0xffffffff, 0xfe0fffff, 0xffffffff, 0xffffffff, 0xf80fffff, 0xffffffff, + 0xffffffff, 0xe00fffff, 0xffffffff, 0xffffffff, 0x800fffff, 0xffffffff, 0xfffffffc, 0x0007ffff, + 0xffffffff, 0xffffffe0, 0x00000000, +}; + +uint32_t leicaSplash[] = +{ 192, 124, + 0x00000000, 0x0000007f, 0xf0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000003ff, + 0xfc000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000fff, 0xfe000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00001fff, 0xff000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00007fff, 0xff800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000fffc, + 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0001fff0, 0x0fc00000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x0003ffe0, 0x0fc00000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0007ffc0, 0x07e00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000fffc0, + 0x07e00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x001fff80, 0x07e00000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x001fff80, 0x07e00000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x003fff00, 0x07e00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003fff00, + 0x07e00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x007ffe00, 0x07c00000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x007ffe00, 0x07c00000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00fffc00, 0x0fc00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fffc00, + 0x0fc00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01fffc00, 0x0f800000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x01fff800, 0x1f800000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01fff800, 0x1f000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x03fff800, + 0x3f000000, 0x03fc0000, 0x00000000, 0x00000000, 0x00000000, 0x03fff000, 0x7f000000, 0x0fff0000, + 0x00000000, 0x00000000, 0x00000000, 0x03fff000, 0x7e000000, 0x0fff8000, 0x00000000, 0x00000000, + 0x00000000, 0x07fff000, 0xfc000000, 0x1fff8000, 0x00000000, 0x00000000, 0x00000000, 0x07fff001, + 0xf8000000, 0x1fffc000, 0x00000000, 0x00000000, 0x00000000, 0x07ffe003, 0xf8000000, 0x1fffc000, + 0x00000000, 0x00000000, 0x00000000, 0x07ffe007, 0xf0000000, 0x1fffc000, 0x00000000, 0x00000000, + 0x00000000, 0x0fffe01f, 0xe0000000, 0x1fff8000, 0x00000000, 0x00000000, 0x00000000, 0x0fffe03f, + 0xc0000000, 0x0fff0000, 0x00000000, 0x00000000, 0x00000000, 0x0fffc0ff, 0x80000000, 0x03fe0000, + 0x00000000, 0x00000000, 0x00000000, 0x0fffc3ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x1fffcffc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000f8, 0x1ffffff8, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000001ff, 0xffffffe0, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x000001ff, 0xffffff80, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xfffffc00, 0x03fe0000, 0x00000000, 0x03800000, 0x3e000000, 0x0000000f, 0xffffe000, + 0x7fffc000, 0x7ffc0000, 0x7ffc0003, 0xffc3ffc0, 0x00000000, 0x7fff0001, 0xfffff000, 0xfff80003, + 0xffff000f, 0xffe3ffc0, 0x00000000, 0x7fff0007, 0xfffff800, 0xfff80007, 0xffff003f, 0xfff7ff80, + 0x00000000, 0x7fff001f, 0xff07fc01, 0xfff8001f, 0xffff00ff, 0xffffff80, 0x00000000, 0x7ffe003f, + 0xfe03fe01, 0xfff8003f, 0xff3f01ff, 0xfcffff80, 0x00000000, 0x7ffe007f, 0xfc03fe01, 0xfff0007f, + 0xfc0603ff, 0xf03fff80, 0x00000000, 0xfffe00ff, 0xf803fe01, 0xfff000ff, 0xf80207ff, 0xe01fff00, + 0x00000000, 0xfffe01ff, 0xf803fe03, 0xfff001ff, 0xf0000fff, 0xc01fff00, 0x00000000, 0xfffc01ff, + 0xf007fe03, 0xfff003ff, 0xf0000fff, 0x801fff00, 0x00000000, 0xfffc03ff, 0xf007fc03, 0xffe007ff, + 0xe0001fff, 0x801ffe00, 0x00000001, 0xfffc07ff, 0xe00ffc07, 0xffe007ff, 0xe0001fff, 0x801ffe00, + 0x00000001, 0xfff807ff, 0xe01ff807, 0xffe00fff, 0xc0003fff, 0x001ffe00, 0x00000001, 0xfff807ff, + 0xe07ff007, 0xffc00fff, 0xc0003fff, 0x003ffe00, 0x00000003, 0xfff80fff, 0xffffe007, 0xffc00fff, + 0xc0007ffe, 0x003ffc00, 0x00000003, 0xfff00fff, 0xffffc00f, 0xffc01fff, 0x80007ffe, 0x003ffc00, + 0x00000003, 0xfff00fff, 0xffff000f, 0xffc01fff, 0x80007ffe, 0x007ffc00, 0x00000007, 0xfff00fff, + 0xfff8000f, 0xff801fff, 0x80007ffe, 0x007ffc00, 0x00000007, 0xffe00fff, 0xc000001f, 0xff801fff, + 0x80007ffe, 0x007ff800, 0x00000007, 0xffe00fff, 0xc000007f, 0xff801fff, 0x8000fffe, 0x00fff800, + 0x0000000f, 0xffe00fff, 0xc00001ff, 0xff803fff, 0x8001fffe, 0x00fff800, 0x0000000f, 0xffc007ff, + 0xc00007ff, 0xff80ffff, 0xc007fffe, 0x01fff800, 0x0000001f, 0xffc007ff, 0xe0003fff, 0xff83ffff, + 0xc00ffffe, 0x03fff800, 0x0000001f, 0xff8003ff, 0xf801ffff, 0xffffffff, 0xe03fffff, 0x07fffc78, + 0x01ffc01f, 0xff8003ff, 0xffffff9f, 0xfffff7ff, 0xffffbfff, 0xdffffff8, 0x07fffe3f, 0xff0001ff, + 0xfffffe0f, 0xffffe3ff, 0xfffe1fff, 0xfffffff8, 0x1fffffff, 0xff0000ff, 0xfffff80f, 0xffff81ff, + 0xfffc0fff, 0xfffffff8, 0x3fffffff, 0xfe00003f, 0xffffe007, 0xfffe00ff, 0xfff007ff, 0xfe7fffe0, + 0x7fffffff, 0xfc00001f, 0xffff0003, 0xfff8007f, 0xffc003ff, 0xf83fff80, 0x7f83ffff, 0xfc000003, + 0xfff80001, 0xffe0001f, 0xff0001ff, 0xe01ffe00, 0xfe003fff, 0xffc00000, 0x00000000, 0x1c000003, + 0xf000003f, 0x0007f000, 0xfc0007ff, 0xfff80000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfc0007ff, 0xffff8000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7c000fff, 0xfffff800, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x7e003fff, 0xffffff80, 0x00000000, 0x00000000, + 0x00000000, 0x0000000e, 0x7f80ffff, 0xbffffff8, 0x00000000, 0x00000000, 0x00000000, 0x000001ff, + 0x3ffffffe, 0x07ffffff, 0xc0000000, 0x00000000, 0x00000000, 0x00003fff, 0x1ffffffc, 0x00ffffff, + 0xff000000, 0x00000000, 0x00000000, 0x000fffff, 0x0ffffff0, 0x001fffff, 0xfffc0000, 0x00000000, + 0x00000000, 0x07fffffc, 0x03ffffc0, 0x0007ffff, 0xfffffe00, 0x00000000, 0x0000000f, 0xffffffe0, + 0x00fffc00, 0x00007fff, 0xffffffff, 0xff800000, 0x0fffffff, 0xfffffc00, 0x00030000, 0x00000fff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffc000, 0x00000000, 0x000000ff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xfff80000, 0x00000000, 0x0000000f, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xc0000000, 0x00000000, 0x00000000, + 0x07ffffff, 0xffffffff, 0xfffffff8, 0x00000000, 0x00000000, 0x00000000, 0x003fffff, 0xffffffff, + 0xfffffc00, 0x00000000, 0x00000000, 0x00000000, 0x0001ffff, 0xffffffff, 0xfffc0000, 0x00000000, + 0x00000000, 0x00000000, 0x000003ff, 0xffffffff, 0xf0000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x3ffff000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0xf0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0000000f, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000001f, 0xfe000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000003f, 0x3e000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x0000003c, 0x1f000000, 0x00000000, 0x00000780, 0x00000000, 0x00000000, + 0x0000007c, 0x1f000000, 0x00000000, 0x00000f80, 0x00000000, 0x00000000, 0x00000078, 0x1e000000, + 0x00000000, 0x00000f80, 0x00000000, 0x00000000, 0x000000f8, 0x0003f003, 0xf00fe1e0, 0xf0fc3fc1, + 0xfc0f3c7c, 0x07e00000, 0x000000f8, 0x000ffc0f, 0xf81ff1e1, 0xe3ff3fc3, 0xfe0ffefe, 0x1ff00000, + 0x000000f0, 0x001ffc1f, 0xfc3cf1e1, 0xe7df3fc7, 0xff0ffffe, 0x3ef80000, 0x000000f0, 0x001e3c3e, + 0x3c78f1e1, 0xc78f1f0f, 0x0f1f1e3e, 0x7c780000, 0x000001f1, 0xfc3c3c3c, 0x3c7871e3, 0xc78f1e0f, + 0x0f1e1e3e, 0x78700000, 0x000001f1, 0xfc3c3c7c, 0x3c7c01e3, 0x87c01e1f, 0x0f1e1e3c, 0x7c000000, + 0x000001e1, 0xfc3ffc78, 0x3c7f01e7, 0x87e01e1f, 0xff1e3e3c, 0x7f000000, 0x000001e0, 0x7c7ffc78, + 0x7c3f81e7, 0x03f81e1f, 0xff3e3c3c, 0x3fc00000, 0x000001e0, 0x787ffc78, 0x781fe1e7, 0x01fc3e1f, + 0xfe3c3c3c, 0x0fe00000, 0x000003e0, 0x78780078, 0x7807e1ee, 0x007e3c3e, 0x003c3c7c, 0x03e00000, + 0x000003e0, 0x787800f8, 0x7801e0fe, 0x003e3c3e, 0x003c3c78, 0x01f00000, 0x000003e0, 0xf87878f8, + 0xf9e1e0fc, 0x1e1e3c3c, 0x3e3c7c78, 0xf1f00000, 0x000001f0, 0xf878f8f8, 0xf1e1e0fc, 0x1e3e3c3e, + 0x3c7c7878, 0xf1e00000, 0x000001ff, 0xf07ff07f, 0xe1f7c0f8, 0x1f7c3e3f, 0xf8787878, 0xfbe00000, + 0x000001ff, 0xf07fe07f, 0xe1ff80f8, 0x1ff83e1f, 0xf07878f8, 0xffc00000, 0x0000007f, 0xf01f803f, + 0x807f00f0, 0x0fe01e0f, 0xe07870f0, 0x7f000000, 0x00000000, 0x00000000, 0x000000f0, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000001f0, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x000001e0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000003e0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000003c0, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000780, 0x00000000, 0x00000000, 0x00000000, + +}; + +uint32_t UMLogo68x64[] = +{ 68, 64, + 0xfffe00ff, 0xffc01fff, 0xffffe00f, 0xfffc01ff, 0xfffffe00, 0xffffc01f, 0xffffffe0, 0x0ffffc01, + 0xfffffffe, 0x00ffffc0, 0x1fffffff, 0xe00ffffc, 0x01ffffff, 0xfe00ffff, 0xc01fffff, 0xffe00fff, + 0xfc01ffff, 0xfffe00ff, 0xffc01fff, 0xffffe00f, 0xfffc01ff, 0xfffffe00, 0xffffc01f, 0xffffffe0, + 0x0ffffc01, 0xfffffffe, 0x00ffffc0, 0x1fffffff, 0xe00ffffc, 0x01ffffff, 0xfe00ffff, 0xc01fffff, + 0xffe00fff, 0xfc01ffff, 0xfffe00ff, 0xffc01fff, 0xffffe00f, 0xfffc01ff, 0xfffffe00, 0xffffc01f, + 0xffffffe0, 0x0ffffc01, 0xfffffffe, 0x00ffffc0, 0x1fffffff, 0xe007fff8, 0x01ffffff, 0xfe007fff, + 0x801fffff, 0xfff003ff, 0xf003ffff, 0xffff001f, 0xfe003fff, 0xfffff000, 0xffc003ff, 0xffffff00, + 0x03f0003f, 0xfffffff8, 0x00000007, 0xffffffff, 0xc0000000, 0xffffffff, 0xfc000000, 0x0fffffff, + 0xffe00000, 0x01ffffff, 0xffff0000, 0x003fffff, 0xfffff800, 0x0007ffff, 0xffffffe0, 0x0001ffff, + 0xffffffff, 0x00003fff, 0xffffffff, 0xfe001fff, 0xffffffff, 0xfffe1fff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffefff, 0xfffffdff, 0xfffffe7f, 0xffffff9f, 0xffffffe3, 0xfffffff1, 0xfffffffe, 0x1ffffffe, + 0x1fffffff, 0xe0ffffff, 0xc1ffffff, 0xfe03ffff, 0xf01fffff, 0xffe007ff, 0xf801ffff, 0xfffe0000, + 0x00001fff, 0xffffe000, 0x000001ff, 0xfffffe00, 0x0000001f, 0xffffffe0, 0x00000001, 0xfffffffe, + 0x00000000, 0x1fffffff, 0xe0000000, 0x01ffffff, 0xfe000000, 0x001fffff, 0xffe00000, 0x0001ffff, + +}; + diff --git a/source/Graphics/splash.h b/source/Graphics/splash.h new file mode 100644 index 0000000..85710a0 --- /dev/null +++ b/source/Graphics/splash.h @@ -0,0 +1,10 @@ +// Generated by MonoBitmapConverter + + + +extern const uint32_t goldenlandLogo98x60[]; +extern const uint32_t leicaSplash[]; +extern const uint32_t UMLogo68x64[]; + + + diff --git a/source/Graphics/testIconsMono.c b/source/Graphics/testIconsMono.c new file mode 100644 index 0000000..28134b3 --- /dev/null +++ b/source/Graphics/testIconsMono.c @@ -0,0 +1,126 @@ +// Generated by MonoBitmapConverter +// Bitmap Format: +// [0] bitmap width in pixels +// [1] bitmap height in pixels +// [2] bitmap data + + +#include + +uint32_t dvdLogo[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fffffc, 0x007fffe0, 0x1fffffe0, 0x0fffff81, + 0xfffffe01, 0xfffffc00, 0x03ffe01f, 0x000fe000, 0x0fff03e0, 0x003e1f00, 0xfdf07c7c, 0x03f3f00f, + 0xdf0f8fc0, 0x3f3e00fc, 0xf8f0fc03, 0xe3e01f8f, 0x9f0f803e, 0x3e01f0ff, 0xe0f807c7, 0xe07f07fc, + 0x1f80f87e, 0x3fc07f81, 0xf83f07ff, 0xf807f01f, 0xffe0fffe, 0x003e03ff, 0xf80ffe00, 0x03c01ff8, + 0x00000000, 0x38000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00ffffff, 0xf000000f, 0xffffffff, 0xff000fff, 0xffffffff, 0xff03ffff, 0xffffffff, 0xfc7fffff, + 0x000fffff, 0xefffffe0, 0x007fffff, 0x7ffffe00, 0x07ffffe3, 0xfffffe07, 0xfffffc0f, 0xffffffff, + 0xffff000f, 0xffffffff, 0xff000003, 0xfffffffc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t internet_bw[] = +{ 96, 96, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003ffc00, 0x00000000, 0x00000000, 0x07ffffe0, + 0x00000000, 0x00000000, 0x3ffffffc, 0x00000000, 0x00000000, 0xfffbdfff, 0x00000000, 0x00000003, + 0xffe3c7ff, 0xc0000000, 0x0000000f, 0xef83c1f7, 0xf0000000, 0x0000003f, 0x1f03c0f8, 0xfc000000, + 0x0000007c, 0x1e03c078, 0x3e000000, 0x000001f8, 0x3c03c03c, 0x1f800000, 0x000003e0, 0x7c03c03e, + 0x07c00000, 0x000007c0, 0x7803c01e, 0x03e00000, 0x00000f80, 0xf003c00f, 0x01f00000, 0x00001f00, + 0xf003c00f, 0x00f80000, 0x00003c01, 0xe003c007, 0x807c0000, 0x00007c01, 0xe003c007, 0x803e0000, + 0x00007803, 0xc003c003, 0xc01e0000, 0x0000f003, 0xc003c003, 0xc00f0000, 0x0001e003, 0xc003c003, + 0xc0078000, 0x0001c007, 0x8003c001, 0xe0038000, 0x0003ffff, 0xffffffff, 0xffffc000, 0x0003ffff, + 0xffffffff, 0xffffc000, 0x0007ffff, 0xffffffff, 0xffffe000, 0x0007ffff, 0xffffffff, 0xffffe000, + 0x000e000f, 0x0003c000, 0xf0007000, 0x000e000e, 0x0003c000, 0x70007000, 0x001e001e, 0x0003c000, + 0x78007800, 0x001c001e, 0x0003c000, 0x78003800, 0x001c001e, 0x0003c000, 0x78003800, 0x0038001e, + 0x0003c000, 0x78001c00, 0x0038001c, 0x0003c000, 0x38001c00, 0x0038001c, 0x0003c000, 0x38001c00, + 0x0038001c, 0x0003c000, 0x38001c00, 0x0030001c, 0x0003c000, 0x38000c00, 0x0070003c, 0x0003c000, + 0x3c000e00, 0x0070003c, 0x0003c000, 0x3c000e00, 0x0070003c, 0x0003c000, 0x3c000e00, 0x0070003c, + 0x0003c000, 0x3c000e00, 0x007fffff, 0xffffffff, 0xc0fffe00, 0x007fffff, 0xffffffff, 0x003ffe00, + 0x007fffff, 0xfffffffe, 0x001ffe00, 0x007fffff, 0xfffffffe, 0x000ffe00, 0x0070003c, 0x0003c000, + 0x1e000e00, 0x0070003c, 0x0003c000, 0x3f000e00, 0x0070003c, 0x0003c000, 0x3f800e00, 0x0070003c, + 0x0003c000, 0x3fc00e00, 0x0030001c, 0x0003c000, 0x3fe00c00, 0x0038001c, 0x0003c000, 0x3ff01c00, + 0x0038001c, 0x0003c000, 0x3df81c00, 0x0038001c, 0x0003c000, 0x3cfc0c00, 0x0038001e, 0x0003c000, + 0x3c7e0000, 0x001c001e, 0x0003c000, 0x3c1f0000, 0x001c001e, 0x0003c000, 0x3c0fc000, 0x001e001e, + 0x0003c000, 0x3c07e000, 0x000e000e, 0x0003c000, 0x3c03f000, 0x000e000f, 0x0003c000, 0x3c01f000, + 0x0007ffff, 0xfffffffc, 0x3c00f800, 0x0007ffff, 0xfffffffc, 0x3c007c00, 0x0003ffff, 0xfffffffc, + 0x3c003e00, 0x0003ffff, 0xfffffffc, 0x3c001f00, 0x0001c007, 0x8003c000, 0x3c000f80, 0x0001e003, + 0x8003c000, 0x3c0007c0, 0x0000f003, 0xc003c000, 0x3c0003e0, 0x00007803, 0xc003c000, 0x3c0001f0, + 0x00007801, 0xe003c004, 0x3c0000f8, 0x00003c01, 0xe003c004, 0x3c00003c, 0x00001e00, 0xf003c00c, + 0x3c00003e, 0x00000f80, 0xf003c00c, 0x3c007fff, 0x000007c0, 0x7803c01c, 0x3c007ffe, 0x000003e0, + 0x7c03c03c, 0x3c003ff0, 0x000001f8, 0x3c03c03c, 0x3c0c3e00, 0x0000007c, 0x1e03c078, 0x3c3c1c00, + 0x0000003f, 0x1f03c0f8, 0x3c7e1c00, 0x0000000f, 0xef83c1f0, 0x3cfe1e00, 0x00000003, 0xffe3c7fc, + 0x3dfe0e00, 0x00000000, 0xfffbdffc, 0x3fef0f00, 0x00000000, 0x3ffffffc, 0x1fc70700, 0x00000000, + 0x07ffffe0, 0x1f878780, 0x00000000, 0x003ffc00, 0x1f038380, 0x00000000, 0x00000000, 0x1e03c380, + 0x00000000, 0x00000000, 0x0001c3c0, 0x00000000, 0x00000000, 0x0001e1c0, 0x00000000, 0x00000000, + 0x0000e7e0, 0x00000000, 0x00000000, 0x0000ffc0, 0x00000000, 0x00000000, 0x0000ff00, 0x00000000, + 0x00000000, 0x00007c00, 0x00000000, 0x00000000, 0x00007000, 0x00000000, 0x00000000, 0x00002000, + +}; + +uint32_t reboot[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1f800000, 0x0000001f, 0xff800000, 0x00000fff, + 0xff000000, 0x0003ffff, 0xfc040000, 0x007f000f, 0xe0c00000, 0x1fc0003f, 0x9c000003, 0xf00000ff, + 0xc000007c, 0x000003fc, 0x00000f80, 0x00001fc0, 0x0001f000, 0x0001fc00, 0x001e0000, 0x003fc000, + 0x03c00000, 0x07fc0000, 0x78000000, 0xffc00007, 0x8000001f, 0xfc0000f0, 0x00000000, 0x00000f00, + 0x00000000, 0x0000e000, 0x00000000, 0x001e0000, 0x00000000, 0x01c00000, 0x00000000, 0x1c000000, + 0x00000001, 0xc0000000, 0x0000003c, 0x00000000, 0x000003c0, 0x00000000, 0x00003c00, 0x00000001, + 0x8003c000, 0x0000003c, 0x003c0000, 0x000003c0, 0x03c00000, 0x00003c00, 0x1c000000, 0x00038001, + 0xc0000000, 0x0038001c, 0x00000000, 0x038001e0, 0x00000000, 0x78000e00, 0x00000007, 0x0000f000, + 0x000000f0, 0x000f0000, 0x00000f00, 0x00780000, 0x0001e000, 0x07800000, 0x001e0000, 0x3c000000, + 0x03c00001, 0xe0000000, 0x7800001f, 0x0000000f, 0x800000f8, 0x000001f0, 0x000007c0, 0x00003e00, + 0x00003f00, 0x000fc000, 0x0001fc00, 0x03f80000, 0x0007f000, 0xfe000000, 0x003fffff, 0xc0000000, + 0x00fffff0, 0x00000000, 0x01fff800, 0x00000000, 0x01f80000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t restart[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x03800000, 0x00000000, 0x7f800000, 0x00000007, + 0xff000000, 0x003f803f, 0xfc000000, 0x7ff8000f, 0xe0000003, 0xff80003f, 0x8000001f, 0xf00000fc, + 0x000001ff, 0x000003e0, 0x00000ff0, 0x00001f00, 0x0001ff00, 0x0000f800, 0x001fe000, 0x00078000, + 0x03fe0000, 0x003c0000, 0x78e00000, 0x01e00007, 0x8c000000, 0x1e0000f0, 0x40000000, 0xf0000f00, + 0x0000000f, 0x0000e000, 0x00000070, 0x001e0000, 0x00000780, 0x01e00000, 0x00003800, 0x1c000000, + 0x00038001, 0xc0000000, 0x0038003c, 0x00000000, 0x03c003c0, 0x00000000, 0x3c003c00, 0x00000003, + 0xc003c000, 0x0000003c, 0x003c0000, 0x000003c0, 0x03c00000, 0x00003c00, 0x1c000000, 0x00038001, + 0xc0000000, 0x0038001c, 0x00000000, 0x038001e0, 0x00000000, 0x78000e00, 0x00000007, 0x0000f000, + 0x000000f0, 0x000f0000, 0x00000f00, 0x00780000, 0x0001e000, 0x07800000, 0x001e0000, 0x3c000000, + 0x03c00001, 0xe0000000, 0x7800001f, 0x0000000f, 0x800000f8, 0x000001f0, 0x000007c0, 0x00003e00, + 0x00003f00, 0x000fc000, 0x0001fc00, 0x03f80000, 0x0007f000, 0xfe000000, 0x003fffff, 0xc0000000, + 0x00fffff0, 0x00000000, 0x01fff800, 0x00000000, 0x01f80000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + +uint32_t shutdown[] = +{ 60, 60, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x60000000, 0x0000000f, + 0x00000000, 0x000380f0, 0x1c000000, 0x007c0f03, 0xe0000000, 0x0f80f01f, 0x00000003, 0xf00f00fc, + 0x0000007c, 0x00f003e0, 0x00000f80, 0x0f001f00, 0x0001f000, 0xf000f800, 0x001e000f, 0x00078000, + 0x03c000f0, 0x003c0000, 0x78000f00, 0x01e00007, 0x8000f000, 0x1e0000f0, 0x000f0000, 0xf0000f00, + 0x00f0000f, 0x0000e000, 0x0f000070, 0x001e0000, 0xf0000780, 0x01c0000f, 0x00003800, 0x1c0000f0, + 0x00038001, 0xc0000f00, 0x0038003c, 0x0000f000, 0x03c003c0, 0x000f0000, 0x3c003c00, 0x00f00003, + 0xc003c000, 0x0600003c, 0x003c0000, 0x000003c0, 0x03c00000, 0x00003c00, 0x1c000000, 0x00038001, + 0xc0000000, 0x0038001c, 0x00000000, 0x038001e0, 0x00000000, 0x78000e00, 0x00000007, 0x0000f000, + 0x000000f0, 0x000f0000, 0x00000f00, 0x00780000, 0x0001e000, 0x07800000, 0x001e0000, 0x3c000000, + 0x03c00001, 0xe0000000, 0x7800001f, 0x0000000f, 0x800000f8, 0x000001f0, 0x000007c0, 0x00003e00, + 0x00003f00, 0x000fc000, 0x0001fc00, 0x03f80000, 0x0007f000, 0xfe000000, 0x003fffff, 0xc0000000, + 0x00fffff0, 0x00000000, 0x01fff800, 0x00000000, 0x01f80000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, +}; + diff --git a/source/Graphics/testIconsMono.h b/source/Graphics/testIconsMono.h new file mode 100644 index 0000000..67c7275 --- /dev/null +++ b/source/Graphics/testIconsMono.h @@ -0,0 +1,12 @@ +// Generated by MonoBitmapConverter + + + +extern const uint32_t dvdLogo[]; +extern const uint32_t internet_bw[]; +extern const uint32_t reboot[]; +extern const uint32_t restart[]; +extern const uint32_t shutdown[]; + + + diff --git a/source/Loader/bootloader.c b/source/Loader/bootloader.c new file mode 100644 index 0000000..3a141c8 --- /dev/null +++ b/source/Loader/bootloader.c @@ -0,0 +1,200 @@ +/* + * bootloader.c + * + * Created on: Oct 22, 2023 + * Author: Brian.Bailey + */ + +#include +#include +#include +#include + +#include "lcd.h" +#include "Fonts/fontLibrary.h" +#include "timer.h" +#include "utils.h" +#include "keys.h" +#include "init.h" +#include "usbComms.h" + +#include "fsl_power.h" +#include "virtual_com.h" +#include "sha256.h" + +// #include "bootloader.h" +#include "Loader/iap_jump.h" +#include "eeprom.h" + + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +BL_DATA_t blData; + +extern uint8_t tempString[40]; +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +void BL_Run(void) +{ + Power_ON_OFF(ON); // Hold power on. + Select_Estop(ON); // Ensure output is ISOLATED from connections + SPI0_Chip_Select(CS_HIGH,E2PROM); // Set EEPROM as SPI CS + KEY_Init(); + SPI_Init(); + + //Read bootloader EEPROM data to the blData structure + //Read the EEPROM + // blData.version = 1; + // blData.loaderRunRequest = 0; + // blData.transmitterProgrammed = 1; +#if 0 //for testing blank EEPROM + blData.version = 0xffffffff; + blData.loaderRunRequest = 0xffffffff; + blData.transmitterProgrammed = 0xffffffff; + M95512_WriteMemoryUINT32(BL_VERSION_EEPROM_ADDR, &blData.version); + M95512_WriteMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + M95512_WriteMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + +#else + EE_ReadMemoryUINT32(BL_VERSION_EEPROM_ADDR, &blData.version); + EE_ReadMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + EE_ReadMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + + + if(blData.version > BL_MAX_VERSION) //Check for bootloader FLASH uninitialized. if uninitialized, this will be 0xffff + { + //Zero out Bootloader EEPROM data + blData.loaderRunRequest = 0; + blData.transmitterProgrammed = 0; + EE_WriteMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + EE_WriteMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + //Set correct BL VERSION in EEPROM + blData.version = BL_VERSION; + EE_WriteMemoryUINT32(BL_VERSION_EEPROM_ADDR, &blData.version); + + //TODO: Maybe need to read back,verify, and add error information + EE_ReadMemoryUINT32(BL_VERSION_EEPROM_ADDR, &blData.version); + EE_ReadMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + EE_ReadMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + } +#endif + + if(!blData.transmitterProgrammed) //If NOT programmed, return to run loader + { + return; + } + + if(blData.loaderRunRequest) //If loaderRunRequest, return to run loader + { + //Clear the loader run request + blData.loaderRunRequest = 0; + EE_WriteMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + return; + } + + + //if FREQ and UP keys are held, return to run the loader screen + if(KEY_GetUpKeyHeld() && KEY_GetFrequencyKeyHeld()) + { + return; + } + + + //Jump to the application at BL_APP_IMAGE_ADDR + IAP_JumpToApp(BL_APP_IMAGE_ADDR); + +} + + +void BL_ShowScreen(void) +{ + float32_t timer = 0.0; + + //Init some things + timer_init(); //Needed for Delay_ticks + Init_Ports(); //make sure port expander outputs are in a safe state + LCD_Init(); + + + //Update screen @ 10Hz and listen for USB data + while(1) + { + uint32_t xText = 20; + uint32_t yText = 30; + uint32_t yInc = 10; + + LCD_Clear(); + + //Draw Text to LCD + sprintf(tempString, "TX Loader v%d", BL_VERSION); + FL_DrawString(tempString, LCD_X_MID, 0, font12Bold, LCD_DRAW_SET, FL_ALIGN_CENTER); + + + + + //TX Programmed + if(true == blData.transmitterProgrammed) + { + FL_DrawString("TX Programmed", xText, yText, font12Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + else + { + FL_DrawString("TX NOT Programmed", xText, yText, font12Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + yText += yInc; + yText += yInc; + + FL_DrawString("Ready for Programming...", xText, yText, font12Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + yText += yInc; + + //show time + timer += 0.1; + sprintf(tempString, "%0.1fs", timer); + FL_DrawString(tempString, 0, LCD_Y_MAX - FL_GetFontHeight(font12Bold), font12Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + LCD_Update(); + + //Power off if user presses power key + if(KEY_GetPowerKeyHeld()) + { + Power_ON_OFF(OFF); + while(1); //wait for power off + } + + Delay_Ticks(10); //100mS delay + } +} + +/* + * Read bootloader data from EEPROM + * Have seen issue where first EEPROM read is garbage. throw the first read away. + */ +void BL_ReadInfo(void) +{ + EE_ReadMemoryUINT32(BL_VERSION_EEPROM_ADDR, &blData.version); + EE_ReadMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + EE_ReadMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); +} + + + diff --git a/source/Loader/bootloader.h b/source/Loader/bootloader.h new file mode 100644 index 0000000..d0bc90d --- /dev/null +++ b/source/Loader/bootloader.h @@ -0,0 +1,44 @@ +/* + * bootloader.h + * + * Created on: Oct 22, 2023 + * Author: Brian.Bailey + */ + +#ifndef LOADER_BOOTLOADER_H_ +#define LOADER_BOOTLOADER_H_ + +#include +#include + +#include "bootloader.h" + + +#define BL_VERSION 1 //Bootloader Version (integer) +#define BL_MAX_VERSION 255 //Max version - otherwise FLASH reads as uninitialized + +//Locations for bootable image components +//Update these for transmitter. +#define BL_BOOTLOADER_IMAGE_ADDR 0x00000000 //base address for the bootloader image in FLASH +#define BL_APP_IMAGE_ADDR 0x00010000 //base address for the application image in FLASH + +//Bootloader EEPROM Addresses +#define BL_RESERVED 0x0000 //Don't use address 0x0 +#define BL_VERSION_EEPROM_ADDR 0x0004 +#define BL_LOADERRUNREQUEST_EEPROM_ADDR 0x0008 +#define BL_PROGRAMMED_EEPROM_ADDR 0x000C +//First 128 addresses (32 entries) in EEPROM are reserved for the bootloader + + +typedef struct { + uint32_t version; //bootloader version (for application to read) + uint32_t loaderRunRequest; //loader run request for program update + uint32_t transmitterProgrammed; //Transmitter has been programmed +}BL_DATA_t; + +void BL_Run(void); +void BL_ShowScreen(void); + +void BL_ReadInfo(void); //for application + +#endif /* LOADER_BOOTLOADER_H_ */ diff --git a/source/Loader/flashUpdate.c b/source/Loader/flashUpdate.c new file mode 100644 index 0000000..5832da1 --- /dev/null +++ b/source/Loader/flashUpdate.c @@ -0,0 +1,343 @@ +/* + * flashUpdate.c + * + * Created on: Oct 23, 2023 + * Author: Brian.Bailey + */ + + +#include +#include +#include + +#include "usbComms.h" +#include "sha256.h" + +#include "flashUpdate.h" + +#include "fsl_common.h" +#include "fsl_iap.h" + +#include "bootloader.h" +#include "eeprom.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define null 0 //NULL is defined at (void *)0 so it causes errors + +//sector0~2 for bootloader, sector3~7 for APP +#define IAP_FLASH_SECTOR_START (3) +#define IAP_FLASH_SECTOR_END (7) +// #define IAP_FLASH_SECTOR_END (3) //for test + +/******************************************************************************* + * Variables + ******************************************************************************/ +FLASH_UPDATE_t fu; +extern USB_t usb; +extern BL_DATA_t blData; + + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + +/* + * Convert the source string to bytes & store in *dst + * Converts 32 ASCII chars to 16 bytes + */ +static void ConvertStringToHalfHash(uint8_t *src, uint8_t *dst) +{ + //32 ASCII chars to 16 bytes + for(uint32_t i = 0; i < SHA256_BLOCK_SIZE/2; i++) + { + //sscanf(&src[i*2], "%02hhX", &dst[i]); //This works in the RX but has problems when ASCII is > 127? + + uint8_t temp[3]; + temp[0] = src[i*2]; + temp[1] = src[i*2+1]; + temp[3] = 0; + + dst[i] = strtol(temp, NULL, 16); + } +} + +/*! + * @brief Convert uint8 to uint32. + * + * @param len length of arr8. + */ +static void ConvertUint8ToUint32(uint8_t *arr8, uint32_t *arr32, uint32_t len) { + + uint32_t temp; + for (uint32_t i = 0; i < FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; i++) + { + *(((uint8_t *)arr32) + i) = 0xFF; + } + //get the length of arr32 + if(len % 4){ + len /= 4; + len += 1; + } + else{ + len /= 4; + } + for(uint32_t i = 0; i < len; i++) { + temp = (uint32_t)arr8[3] << 24; + temp |= (uint32_t)arr8[2] << 16; + temp |= (uint32_t)arr8[1] << 8; + temp |= (uint32_t)arr8[0]; + arr8 += 4; + arr32[i] = temp; + } +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + + +/* Setup for FLASH programming + * /arg *data: csv string: pProgramSetup,, + * Use program length to calculate number of FLASH sectors to erase + * Save hash, program size, and calculated parameters + * Set usb.programMode + * Send ACK / NAK + */ +void FU_ProgramSetup(uint8_t *data) +{ + //reset variables + fu.imageReceived = false; + fu.flashHashMatch = false; + fu.numBytesToProgram = 0; + fu.numBytesProgrammed = 0; + + bool error = false; + + //Parse Program message + static uint8_t *p; //pointer for strtok - static so it doesn't get optimized out. + p = strtok(data, ","); //points to "pProgramSetup" + p = strtok(null, ","); //number of bytes in the image + fu.numBytesToProgram = atoi(p); + + p = strtok(null, ","); //hash - sent as string + ConvertStringToHalfHash(p, fu.hostHash); + + //clear programmed flag in EEPROM + blData.transmitterProgrammed = 0; + EE_WriteMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + + //Erase APP flash + //USB_SendString("Erasing flash..."); //or to LCD + IAP_PrepareSectorForWrite(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END); + IAP_EraseSector(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END, SystemCoreClock); + //USB_SendString("Erase flash completed"); //OR TO LCD + status_t status; + status = IAP_BlankCheckSector(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END); + if (status != kStatus_IAP_Success) + { + error = 1; + // PRINTF("\r\nSector erase failed\r\n"); //to LCD + } + + //Initialize fu + memset(fu.rxPageData, 0xff, sizeof(fu.rxPageData)); + fu.flashProgramTargetAddress = BL_APP_IMAGE_ADDR; + + + if(error) + { + USB_SendString(NAK); + } + else + { + usb.programMode = true; + USB_SendString(ACK); + } +} + +/* Write received data to FLASH using fu struct information + * This function is called repeatedly to write program FLASH + * When all data received, function sends ACK or NACK via USB + */ +void FU_WriteProgramDataToFLASH(void) +{ + bool error = false; + + //Verify packet: check header and check that size matches + if (USB_PACKET_START_BYTE != usb.rxDataBuffer[USB_PACKET_HEADER_OFFSET]) + { + error = true; + } + + uint32_t packetSize = usb.rxDataBuffer[USB_PACKET_LENGTH_H_OFFSET] * 256; //high byte + packetSize += usb.rxDataBuffer[USB_PACKET_LENGTH_L_OFFSET]; //low byte + + if(packetSize != usb.rxDataIndex) //check that computed packet size matches number of bytes received + { + error = true; + } + + //Write data to FLASH + //you can use packetSize. It is the size of the data in bytes + //Best to wait for a whole page or sector of data before writing to FLASH. + //faster this way + uint32_t rxData[64]; + + if(!error){ + //Judge whether it is the last packet + if((packetSize - USB_PACKET_HEADER_SIZE + fu.numBytesProgrammed) == fu.numBytesToProgram) + { + //Judge whether the page is going to be full + if((fu.numBytesInPageData + packetSize - USB_PACKET_HEADER_SIZE) >= FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES) + { + uint16_t numBytesCurrentPage; + numBytesCurrentPage = FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES - fu.numBytesInPageData; + memcpy(&fu.rxPageData[fu.numBytesInPageData], &usb.rxDataBuffer[USB_PACKET_PAYLOAD_OFFSET], numBytesCurrentPage); + + ConvertUint8ToUint32(fu.rxPageData, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); + IAP_PrepareSectorForWrite(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END); + IAP_CopyRamToFlash(fu.flashProgramTargetAddress, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, SystemCoreClock); + fu.flashProgramTargetAddress += FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + + //start the next FLASH page + memset(fu.rxPageData, 0xff, sizeof(fu.rxPageData)); + fu.numBytesInPageData = 0; + memcpy(&fu.rxPageData[fu.numBytesInPageData], &usb.rxDataBuffer[USB_PACKET_PAYLOAD_OFFSET + numBytesCurrentPage], (packetSize - USB_PACKET_HEADER_SIZE - numBytesCurrentPage)); + fu.numBytesInPageData += (packetSize - USB_PACKET_HEADER_SIZE - numBytesCurrentPage); + + //write to FLASH + ConvertUint8ToUint32(fu.rxPageData, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); + IAP_PrepareSectorForWrite(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END); + IAP_CopyRamToFlash(fu.flashProgramTargetAddress, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, SystemCoreClock); + fu.flashProgramTargetAddress += FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + } + else + { + //write the final page to FLASH + memcpy(&fu.rxPageData[fu.numBytesInPageData], &usb.rxDataBuffer[USB_PACKET_PAYLOAD_OFFSET], (packetSize - USB_PACKET_HEADER_SIZE)); //copy packet to fu.rxPageData + fu.numBytesInPageData += (packetSize - USB_PACKET_HEADER_SIZE); + + ConvertUint8ToUint32(fu.rxPageData, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); + IAP_PrepareSectorForWrite(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END); + IAP_CopyRamToFlash(fu.flashProgramTargetAddress, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, SystemCoreClock); + fu.flashProgramTargetAddress += FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + } + } + else{ + //Judge whether the page is going to be full + if((fu.numBytesInPageData + packetSize - USB_PACKET_HEADER_SIZE) >= FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES){ + uint16_t numBytesCurrentPage; + numBytesCurrentPage = FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES - fu.numBytesInPageData; + memcpy(&fu.rxPageData[fu.numBytesInPageData], &usb.rxDataBuffer[USB_PACKET_PAYLOAD_OFFSET], numBytesCurrentPage); + + ConvertUint8ToUint32(fu.rxPageData, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); + IAP_PrepareSectorForWrite(IAP_FLASH_SECTOR_START, IAP_FLASH_SECTOR_END); + IAP_CopyRamToFlash(fu.flashProgramTargetAddress, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES, SystemCoreClock); + fu.flashProgramTargetAddress += FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + + //start the next FLASH page + memset(fu.rxPageData, 0xff, sizeof(fu.rxPageData)); + fu.numBytesInPageData = 0; + memcpy(&fu.rxPageData[fu.numBytesInPageData], &usb.rxDataBuffer[USB_PACKET_PAYLOAD_OFFSET + numBytesCurrentPage], (packetSize - USB_PACKET_HEADER_SIZE - numBytesCurrentPage)); + fu.numBytesInPageData += (packetSize - USB_PACKET_HEADER_SIZE - numBytesCurrentPage); + } + else{ + memcpy(&fu.rxPageData[fu.numBytesInPageData], &usb.rxDataBuffer[USB_PACKET_PAYLOAD_OFFSET], (packetSize - USB_PACKET_HEADER_SIZE)); + fu.numBytesInPageData += (packetSize - USB_PACKET_HEADER_SIZE); + } + } + + fu.numBytesProgrammed += packetSize - USB_PACKET_HEADER_SIZE; + } + + //Test for all data transferred + if(fu.numBytesProgrammed >= fu.numBytesToProgram) + { + usb.programMode = false; + fu.imageReceived = true; + } + + if(error) + { + USB_SendString(NAK); + } + else + { + USB_SendString(ACK); + } +} + +/* Verify FLASH image using sha256 hash + * Compute sha256 hash of program image + * Compare to fu.hostHash + */ +void FU_VerifyImage() +{ + //TODO: Compute sha256 hash of program image from FLASH + static uint32_t dstAddr = BL_APP_IMAGE_ADDR; + uint8_t rxData[FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES]; + uint32_t i = 0; + SHA256_CTX ctx; + + /* EMAMPLE: (Also see sha256_test()) + * SHA256_CTX ctx; + * sha256_init(&ctx); //initialize + * sha256_update(&ctx, data, dataLength); //call this for each block of data + * sha256_final(&ctx, fu.flashHash); //finish + */ + + sha256_init(&ctx); + for(i = 0; i < (fu.numBytesToProgram / FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); i++){ + //read flash + for(uint32_t j = 0; j < FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; j++) //read 256 bytes from FLASH to rxData + { + rxData[j] = *(uint8_t *)(dstAddr + FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES * i + j); + } + //calculate sha256 + // sha256_update(&ctx, rxData, strlen((char *)rxData)); + sha256_update(&ctx, rxData, FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); + } + for(uint32_t j = 0; j < (fu.numBytesToProgram % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES); j++){ + rxData[j] = *(uint8_t *)(dstAddr + FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES * i + j); + } + sha256_update(&ctx, rxData, (fu.numBytesToProgram % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES)); + sha256_final(&ctx, fu.flashHash); + + //Compare fu.flashHash with fu.hostHash - FIRST HALF ONLY! + if(0 == memcmp(fu.hostHash, fu.flashHash, SHA256_BLOCK_SIZE/2)) //Failed, I don't know the reason. +// if(1) //for test, bypass verification and it works + { + //set programmed flag in EEPROM + blData.transmitterProgrammed = true; + EE_WriteMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + USB_SendString(ACK); + } + else + { + USB_SendString(NAK); + } +} + + +/* Reset the processor + * Works even if in ISR + */ +void FU_ResetProcessor(void) +{ + //Disable interrupts. + __disable_irq(); + + // Memory barriers for good measure. + __ISB(); + __DSB(); + + //Reset + NVIC_SystemReset(); +} diff --git a/source/Loader/flashUpdate.h b/source/Loader/flashUpdate.h new file mode 100644 index 0000000..ec76a1c --- /dev/null +++ b/source/Loader/flashUpdate.h @@ -0,0 +1,33 @@ +/* + * flashUpdate.h + * + * Created on: Oct 23, 2023 + * Author: Brian.Bailey + */ + +#ifndef LOADER_FLASHUPDATE_H_ +#define LOADER_FLASHUPDATE_H_ + +#include "sha256.h" +#include "LPC54114_cm4_features.h" + +typedef struct { + uint32_t numBytesToProgram; //number of bytes to burn to FLASH + uint32_t flashProgramTargetAddress; //Target address in FLASH to write program + uint32_t numBytesProgrammed; //number of bytes programmed to FLASH + uint8_t hostHash[SHA256_BLOCK_SIZE]; //SHA256 hash of program data from host + uint8_t flashHash[SHA256_BLOCK_SIZE]; //SHA256 hash computed from data in FLASH + bool imageReceived; //Entire program image received (got the number of bytes) + bool flashHashMatch; //flashHash matches hostHash + uint8_t rxPageData[FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES]; //save packets data when the number is less then one page + uint16_t numBytesInPageData; //number of bytes saved in rxPageData + bool programCompleted; //Entire program completed +}FLASH_UPDATE_t; + + +void FU_ProgramSetup(uint8_t *data); +void FU_WriteProgramDataToFLASH(void); +void FU_VerifyImage(); +void FU_ResetProcessor(); + +#endif /* LOADER_FLASHUPDATE_H_ */ diff --git a/source/Loader/iap_jump.c b/source/Loader/iap_jump.c new file mode 100644 index 0000000..c2b3456 --- /dev/null +++ b/source/Loader/iap_jump.c @@ -0,0 +1,85 @@ +/* + * iap_jump.c + * + * Created on: Oct 23, 2023 + * Author: Warner + */ + +#include +#include +#include +#include + +#include "LPC54114_cm4.h" + + + + +/******************************************************************************* + * Definitions + ******************************************************************************/ +typedef void (*IAP_JumpFun)(void); + + +/******************************************************************************* + * Variables + ******************************************************************************/ + + + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + +/******************************************************************************* + * Public Functions + ******************************************************************************/ +#if 0 +void IAP_JumpToAPP(uint32_t applicationAddress, uint32_t stackPointer){ + /* Static variables are needed as we need to ensure the values we are using are not stored on the + previous stack */ + static uint32_t s_stackPointer = 0; + s_stackPointer = stackPointer; + static void (*farewellBootloader)(void) = 0; + farewellBootloader = (void (*)(void))applicationAddress; + + /* Set the VTOR to the application vector table address */ + SCB->VTOR = applicationAddress; + + /* Set stack pointers to the application stack pointer */ + __set_MSP(s_stackPointer); + __set_PSP(s_stackPointer); + + /* Jump to the application */ + farewellBootloader(); +} +#endif + +void IAP_JumpToApp(uint32_t app_addr){ + /* Static variables are needed as we need to ensure the values we are using are not stored on the + previous stack */ + static uint32_t s_stackPointer = 0; + s_stackPointer = app_addr; + + IAP_JumpFun JumpToApp; + JumpToApp=(IAP_JumpFun)*(uint32_t*)(app_addr+4); + + /* Set the VTOR to the application vector table address */ + SCB->VTOR = app_addr; + + /* Set stack pointers to the application stack pointer */ + __set_MSP(*(uint32_t*)s_stackPointer); + __set_PSP(*(uint32_t*)s_stackPointer); + + /* Jump to the application */ + JumpToApp(); +} + + + + diff --git a/source/Loader/iap_jump.h b/source/Loader/iap_jump.h new file mode 100644 index 0000000..ff8f06d --- /dev/null +++ b/source/Loader/iap_jump.h @@ -0,0 +1,17 @@ +/* + * iap_jump.h + * + * Created on: Oct 23, 2023 + * Author: Warner + */ + +#ifndef IAP_JUMP_H_ +#define IAP_JUMP_H_ + +#include +#include + +// void IAP_JumpToAPP(uint32_t applicationAddress, uint32_t stackPointer); +void IAP_JumpToApp(uint32_t app_addr); + +#endif /* IAP_JUMP_H_ */ diff --git a/source/Loader/sha256.c b/source/Loader/sha256.c new file mode 100644 index 0000000..c5cd6db --- /dev/null +++ b/source/Loader/sha256.c @@ -0,0 +1,204 @@ +/********************************************************************* +* Filename: sha256.c +* Author: Brad Conte (brad AT bradconte.com) +* Copyright: +* Disclaimer: This code is presented "as is" without any guarantees. +* Details: Implementation of the SHA-256 hashing algorithm. + SHA-256 is one of the three algorithms in the SHA2 + specification. The others, SHA-384 and SHA-512, are not + offered in this implementation. + Algorithm specification can be found here: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf + This implementation uses little endian byte order. + +* github: https://github.com/B-Con/crypto-algorithms +*********************************************************************/ + +/*************************** HEADER FILES ***************************/ +#include +#include +#include "sha256.h" + +/****************************** MACROS ******************************/ +#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) +#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) + +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) +#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) +#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) +#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) + +/**************************** VARIABLES *****************************/ +static const WORD k[64] = { + 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, + 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, + 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, + 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, + 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, + 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, + 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, + 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +}; + +/*********************** FUNCTION DEFINITIONS ***********************/ +void sha256_transform(SHA256_CTX *ctx, const BYTE data[]) +{ + WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; + + for (i = 0, j = 0; i < 16; ++i, j += 4) + m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); + for ( ; i < 64; ++i) + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; + + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; + + for (i = 0; i < 64; ++i) { + t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; + t2 = EP0(a) + MAJ(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; +} + +void sha256_init(SHA256_CTX *ctx) +{ + ctx->datalen = 0; + ctx->bitlen = 0; + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; +} + +void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) +{ + WORD i; + + for (i = 0; i < len; ++i) { + ctx->data[ctx->datalen] = data[i]; + ctx->datalen++; + if (ctx->datalen == 64) { + sha256_transform(ctx, ctx->data); + ctx->bitlen += 512; + ctx->datalen = 0; + } + } +} + +void sha256_final(SHA256_CTX *ctx, BYTE hash[]) +{ + WORD i; + + i = ctx->datalen; + + // Pad whatever data is left in the buffer. + if (ctx->datalen < 56) { + ctx->data[i++] = 0x80; + while (i < 56) + ctx->data[i++] = 0x00; + } + else { + ctx->data[i++] = 0x80; + while (i < 64) + ctx->data[i++] = 0x00; + sha256_transform(ctx, ctx->data); + memset(ctx->data, 0, 56); + } + + // Append to the padding the total message's length in bits and transform. + ctx->bitlen += ctx->datalen * 8; + ctx->data[63] = ctx->bitlen; + ctx->data[62] = ctx->bitlen >> 8; + ctx->data[61] = ctx->bitlen >> 16; + ctx->data[60] = ctx->bitlen >> 24; + ctx->data[59] = ctx->bitlen >> 32; + ctx->data[58] = ctx->bitlen >> 40; + ctx->data[57] = ctx->bitlen >> 48; + ctx->data[56] = ctx->bitlen >> 56; + sha256_transform(ctx, ctx->data); + + // Since this implementation uses little endian byte ordering and SHA uses big endian, + // reverse all the bytes when copying the final state to the output hash. + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; + } +} + +void sha256_ComputeHash(BYTE *data, WORD numBytes, BYTE *hash) +{ + SHA256_CTX ctx; + sha256_init(&ctx); + sha256_update(&ctx, data, numBytes); + sha256_final(&ctx, hash); +} + +int sha256_test() +{ + BYTE text1[] = {"abc"}; + BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; + BYTE text3[] = {"aaaaaaaaaa"}; + BYTE hash1[SHA256_BLOCK_SIZE] = {0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, + 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}; + BYTE hash2[SHA256_BLOCK_SIZE] = {0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, + 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}; + BYTE hash3[SHA256_BLOCK_SIZE] = {0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, + 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0}; + BYTE buf[SHA256_BLOCK_SIZE]; + SHA256_CTX ctx; + int idx; + int pass = 1; + + sha256_init(&ctx); + sha256_update(&ctx, text1, strlen((char *)text1)); + sha256_final(&ctx, buf); + pass = pass && !memcmp(hash1, buf, SHA256_BLOCK_SIZE); + + sha256_init(&ctx); + sha256_update(&ctx, text2, strlen((char *)text2)); + sha256_final(&ctx, buf); + pass = pass && !memcmp(hash2, buf, SHA256_BLOCK_SIZE); + + sha256_init(&ctx); + for (idx = 0; idx < 100000; ++idx) + sha256_update(&ctx, text3, strlen((char *)text3)); + sha256_final(&ctx, buf); + pass = pass && !memcmp(hash3, buf, SHA256_BLOCK_SIZE); + + return(pass); +} + diff --git a/source/Loader/sha256.h b/source/Loader/sha256.h new file mode 100644 index 0000000..8e42f23 --- /dev/null +++ b/source/Loader/sha256.h @@ -0,0 +1,37 @@ +/********************************************************************* +* Filename: sha256.h +* Author: Brad Conte (brad AT bradconte.com) +* Copyright: +* Disclaimer: This code is presented "as is" without any guarantees. +* Details: Defines the API for the corresponding SHA1 implementation. +*********************************************************************/ + +#ifndef SHA256_H +#define SHA256_H + +/*************************** HEADER FILES ***************************/ +#include + +/****************************** MACROS ******************************/ +#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest +#define SHA256_DIGEST_SIZE 32 // Added for rsa.c + +/**************************** DATA TYPES ****************************/ +typedef unsigned char BYTE; // 8-bit byte +typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines + +typedef struct { + BYTE data[64]; + WORD datalen; + unsigned long long bitlen; + WORD state[8]; +} SHA256_CTX; + +/*********************** FUNCTION DECLARATIONS **********************/ +void sha256_init(SHA256_CTX *ctx); +void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len); +void sha256_final(SHA256_CTX *ctx, BYTE hash[]); +void sha256_ComputeHash(BYTE *data, WORD numBytes, BYTE *hash); +int sha256_test(); + +#endif // SHA256_H diff --git a/source/System/system.c b/source/System/system.c new file mode 100644 index 0000000..65270a7 --- /dev/null +++ b/source/System/system.c @@ -0,0 +1,65 @@ +/* + * system.c + * + * Created on: Oct 23, 2023 + * Author: Brian.Bailey + */ + + +#include +#include +#include + +//Application includes +#include "eeprom.h" +#include "System/system.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +SYSTEM_DATA_t sys; + +/******************************************************************************* + * Variables + ******************************************************************************/ + + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +/* + * Load factory default settings + * System info, Data, Frequencies, etc. + */ +void SYS_LoadFactoryDefaults(void) +{ + //System info + sprintf(sys.manufacturer, "UM"); + sprintf(sys.modelNumber, "N/A"); + sprintf(sys.modelName, "N/A"); + sprintf(sys.serialNumber, "N/A"); + sprintf(sys.mfgDate, "N/A"); + + //Data + + //Frequencies + +} + +uint32_t SYS_GetLanguage(void) +{ + return sys.language; +} + diff --git a/source/System/system.h b/source/System/system.h new file mode 100644 index 0000000..2549823 --- /dev/null +++ b/source/System/system.h @@ -0,0 +1,39 @@ +/* + * system.h + * + * Created on: Oct 23, 2023 + * Author: Brian.Bailey + */ + +#ifndef SYSTEM_SYSTEM_H_ +#define SYSTEM_SYSTEM_H_ + + +#define SW_VERSION "1.10A" + + +#define SYS_INFO_LENGTH 24 //max string length for setup parameters (model, mfg, etc.) + + + + +//System data +typedef struct +{ + uint8_t manufacturer[SYS_INFO_LENGTH]; //manufacturer + uint8_t modelName[SYS_INFO_LENGTH]; //model name + uint8_t serialNumber[SYS_INFO_LENGTH]; //serial number + uint8_t mfgDate[SYS_INFO_LENGTH]; //manufacture date + uint8_t modelNumber[SYS_INFO_LENGTH]; //model number + + uint32_t bootloaderVersion; //bootloader version + + uint32_t language; //system language + +}SYSTEM_DATA_t; + + +void SYS_LoadFactoryDefaults(void); +uint32_t SYS_GetLanguage(void); + +#endif /* SYSTEM_SYSTEM_H_ */ diff --git a/source/USB/usbComms.c b/source/USB/usbComms.c new file mode 100644 index 0000000..f35a6ab --- /dev/null +++ b/source/USB/usbComms.c @@ -0,0 +1,413 @@ +/* + * usbComms.c + * + * Created on: May 17, 2023 + * Author: Brian.Bailey + */ + +/* + * USB Comms + * Data is received by APP_and placed in rxBuffer[] + */ + +#include +#include + + + +//Drivers +#include "fsl_gpio.h" +#include "fsl_device_registers.h" +#include "fsl_debug_console.h" +#include "pin_mux.h" +#include "clock_config.h" +#include "board.h" + +//Application Includes +#include "virtual_com.h" +#include "flashUpdate.h" +#include "bootloader.h" +#include "eeprom.h" +#include "System/system.h" +#include "frq.h" +#include "hwFixes.h" + +#include "usbComms.h" + + + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define USB_DETECT_PORT 1 //USB VBUS on GPIO1_6. Not sure we can read this +#define USB_DETECT_PIN 6 + + +#define CR '\r' //carriage return +#define LF '\n' //line feed +#define null 0 //NULL is defined at (void *)0 so it causes errors + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_t usb; +extern SYSTEM_DATA_t sys; + + +extern BL_DATA_t blData; +extern usb_cdc_vcom_struct_t s_cdcVcom; +extern uint8_t frq_update_flag; +extern HARDWARE_FIX_t hwf; + + + +//temp storage for string data +uint8_t usbTempString[USB_RX_BUFFER_SIZE]; + + + + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +uint8_t USB_IsConnected(void) +{ + return GPIO_PinRead(GPIO, USB_DETECT_PORT, USB_DETECT_PIN); +} + + +/* Process incoming USB string + * Commands are LF terminated ASCII text + * @param size number of bytes to process + */ +void USB_ProcessString(uint32_t size) +{ + //operates on usb.rxDataBuffer[] + //index is usb.rxCommandIndex + + uint32_t usbBusyCount = 0; + + usb.rxStringReceived = false; + for(uint32_t i = 0; i < size; i++) //Look for LF character in rxDataBuffer + { + if(LF == usb.rxDataBuffer[i]) + { + + usb.rxDataBuffer[i] = 0; //replace LF with NULL to terminate string + usb.rxStringReceived = true; + break; + } + } + + if(usb.rxStringReceived) + { + //Process the command + USB_ProcessCommand(); + } + else + { + //This is an error. search the ringbuffer for the next LF and throw away everything before it. + } + +} + +/* + * Process Incoming USB commands + */ +void USB_ProcessCommand(void) +{ + if(USB_CommandCompare("dID")) //device ID + { + USB_SendString("UM_TX"); + } + else if(USB_CommandPrefixCompare("p")) + { + USB_ProcessProgramCommand(); + } + else if(USB_CommandPrefixCompare("s")) + { + USB_ProcessSystemCommand(); + } + else if(USB_CommandPrefixCompare("f")) + { + USB_ProcessFrequencyCommand(); + } + else + { + //Bad Command + USB_SendString(NAK); + } +} + +/* + * Process Program commands + */ +void USB_ProcessProgramCommand(void) +{ + if (USB_CommandCompare("pLoaderRunRequest")) //Request bootloader run + { + blData.loaderRunRequest = 1; + EE_WriteMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + + //TESTING: Verify write + EE_ReadMemoryUINT32(BL_LOADERRUNREQUEST_EEPROM_ADDR, &blData.loaderRunRequest); + + if(blData.loaderRunRequest == 1) + { + USB_SendString(ACK); + } + else + { + USB_SendString(NAK); + } + } + else if (USB_CommandPrefixCompare("pProgramSetup,")) //Program setup information - RX can ONLY update the bootloader at 0x6000 0000 + { + FU_ProgramSetup(usb.rxDataBuffer); + } + else if(USB_CommandCompare("pVerifyImage")) //verify image in FLASH - compare hashes + { + FU_VerifyImage(); + } + else if(USB_CommandCompare("pReset")) + { + FU_ResetProcessor(); + } + else if (USB_CommandCompare("pClearProgramFlag")) + { + blData.transmitterProgrammed = false; + EE_WriteMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + + //TESTING: Verify write + EE_ReadMemoryUINT32(BL_PROGRAMMED_EEPROM_ADDR, &blData.transmitterProgrammed); + + if(blData.transmitterProgrammed == false) + { + USB_SendString(ACK); + } + else + { + USB_SendString(NAK); + } + + } + else if (USB_CommandCompare("pEraseAllData")) //Erase settings and factory data. Leave bootloader data + { + EE_EraseAllData(); // Erase EEPROM data + + USB_SendString(ACK); + + } + else + { + USB_SendString(NAK); + } +} + + +/* + * Process System commands + */ +void USB_ProcessSystemCommand(void) +{ + static uint8_t *p; //pointer for strtok - static so it doesn't get optimized out. + + if (USB_CommandPrefixCompare("sSetMfg,")) + { + p = strtok(usb.rxDataBuffer, ","); //points to command + p = strtok(null, ","); //points to arg + strncpy(sys.manufacturer, p, SYS_INFO_LENGTH); + USB_SendString(ACK); + } + else if (USB_CommandPrefixCompare("sSetModelNumber,")) + { + char* token = strtok(usb.rxDataBuffer, ","); + token = strtok(null, ","); //points to arg + strncpy(sys.modelNumber, token, SYS_INFO_LENGTH); + USB_SendString(ACK); + } + else if (USB_CommandPrefixCompare("sSetModelName,")) + { + char* token = strtok(usb.rxDataBuffer, ","); + token = strtok(null, ","); //points to arg + strncpy(sys.modelName, token, SYS_INFO_LENGTH); + USB_SendString(ACK); + } + else if (USB_CommandPrefixCompare("sSetSerial,")) + { + char* token = strtok(usb.rxDataBuffer, ","); + token = strtok(null, ","); //points to arg + strncpy(sys.serialNumber, token, SYS_INFO_LENGTH); + USB_SendString(ACK); + } + else if (USB_CommandPrefixCompare("sSetMfgDate,")) + { + char* token = strtok(usb.rxDataBuffer, ","); + token = strtok(null, ","); //points to arg + strncpy(sys.mfgDate, token, SYS_INFO_LENGTH); + USB_SendString(ACK); + } + else if (USB_CommandPrefixCompare("sSetHourCount,")) + { + //do nothing + USB_SendString(ACK); + } + else if(USB_CommandPrefixCompare("sSetMainPcbaPN,")) + { + char* token = strtok(usb.rxDataBuffer, ","); + token = strtok(null, ","); //points to arg + hwf.mainPcbaPN = atoi(token); + EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN); + USB_SendString(ACK); + } + else if (USB_CommandCompare("sSaveSettings")) + { + //Save settings data + EE_SaveData(); + frq_update_flag = false; + Change_To_Next_BC_Freq(); + USB_SendString(ACK); + + } + else if (USB_CommandCompare("sGetSwVersion")) + { + USB_SendString(SW_VERSION); + } + else if (USB_CommandCompare("sGetMfg")) + { + USB_SendString(sys.manufacturer); + } + else if (USB_CommandCompare("sGetModelNumber")) + { + USB_SendString(sys.modelNumber); + } + else if (USB_CommandCompare("sGetModelName")) + { + USB_SendString(sys.modelName); + } + else if (USB_CommandCompare("sGetSerial")) + { + USB_SendString(sys.serialNumber); + } + else if (USB_CommandCompare("sGetMfgDate")) + { + USB_SendString(sys.mfgDate); + } + else if(USB_CommandCompare("sGetMainPcbaPN")) + { + sprintf(usbTempString, "%d", hwf.mainPcbaPN); + USB_SendString(usbTempString); + } + else if(USB_CommandCompare("sGetbootloaderVerion")) + { + sprintf(usbTempString, "%d", sys.bootloaderVersion); + USB_SendString(usbTempString); + } + + else //Unknown command + { + USB_SendString(NAK); + } +} + + +/* + * Process Frequency Commands + */ +void USB_ProcessFrequencyCommand(void) +{ + static uint8_t *p; //pointer for strtok - static so it doesn't get optimized out. + if (USB_CommandPrefixCompare("fAdd,")) + { + //Add a frequency to FreqArray[] + + //Parse message + p = strtok(usb.rxDataBuffer, ","); //points to "fAdd" + p = strtok(null, ","); //frequency + uint32_t frequency = atoi(p); + p = strtok(null, ","); //type + uint32_t type = atoi(p); + p = strtok(null, ","); //enabled + uint32_t enabled = atoi(p); + p = strtok(null, ","); //inMenu + uint32_t inMenu = atoi(p); + + FREQ_AddFrequency(frequency, enabled, inMenu, type); + + USB_SendString(ACK); + } + else if (USB_CommandCompare("fClear")) + { + //Clear the frequency list + frq_update_flag = true; + + FREQ_ClearFrequencies(); + USB_SendString(ACK); + } + else if (USB_CommandCompare("fSave")) + { + //Save frequency data to EEPROM + EE_SaveData(); + USB_SendString(ACK); + } + else if (USB_CommandCompare("fGetNum")) //Get number of frequencies in the receiver + { + sprintf(usbTempString, "%d", FREQ_GetNumFrequencies()); + USB_SendString(usbTempString); + } + else if (USB_CommandPrefixCompare("fGet,")) //Get string representing a single frequency + { + + p = strtok(usb.rxDataBuffer, ","); //points to "fGet" + p = strtok(null, ","); //index + uint32_t index = atoi(p); + + FREQUENCY_t frq = FREQ_GetFreqByIndex(index); + sprintf(usbTempString, "%d,%d,%d,%d", frq.frequency1, 0, frq.enabled, 1); //FREQ_TYPE-t always 0, inMenu always 1 + USB_SendString(usbTempString); + + + } + else //Unknown command + { + USB_SendString(NAK); + } +} + + +/* + * Return true if str matches data in usb.rxDataBuffer + */ +bool USB_CommandCompare(uint8_t *str) +{ + return (0 == strncmp(str, usb.rxDataBuffer, USB_RX_BUFFER_SIZE)); +} + +/* Compare str to contents of usb.rxDataBuffer + * Return true if str matches data in usb.rxDataBuffer + */ +bool USB_CommandPrefixCompare(uint8_t *str) +{ + return (0 == strncmp(str, usb.rxDataBuffer, strlen(str))); +} + + + + + + + diff --git a/source/USB/usbComms.h b/source/USB/usbComms.h new file mode 100644 index 0000000..28c589a --- /dev/null +++ b/source/USB/usbComms.h @@ -0,0 +1,73 @@ +/* + * usbComms.h + * + * Created on: May 17, 2023 + * Author: Brian.Bailey + */ + +#ifndef COMMS_USBCOMMS_H_ +#define COMMS_USBCOMMS_H_ + +#include "virtual_com.h" //required for USB_RX_BUFFER_SIZE + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define USB_RX_BUFFER_SIZE 512 //Size of rxDataBuffer in bytes (same size as USB_DATA_BUFFER) + +#define ACK "ACK" +#define NAK "NAK" +#define OK "ACK" +#define NO "NAK" + +//Packet Mode +#define USB_PACKET_START_BYTE 0xA5 //start byte +#define USB_PACKET_HEADER_SIZE 3 //header size in bytes +#define USB_PACKET_MAX_LENGTH 63 //503 //max length of packet including header +#define USB_PACKET_MAX_PAYLOAD 60 //500 //max bytes for packet payload + +#define USB_PACKET_HEADER_OFFSET 0 //header byte offset +#define USB_PACKET_LENGTH_H_OFFSET 1 //packet size high byte offset +#define USB_PACKET_LENGTH_L_OFFSET 2 //packet size low byte offset +#define USB_PACKET_PAYLOAD_OFFSET 3 //payload byte offset + +//PACKET FORMAT: + //PACKET_START byte + //Size byte high - Size of packet including header + //Size byte low + //Payload + + + +typedef struct +{ + uint8_t rxDataBuffer[USB_RX_BUFFER_SIZE]; //buffer for received data (copied from rxBuffer) + uint32_t rxDataIndex; //index in rxDataBuffer + bool rxStringReceived; //string received and ready to process + + bool programMode; //USB program mode: use packet format + + uint32_t sendErrorCount; //number of times USB_SendString() has failed to send + bool initialized; +}USB_t; + + + +uint8_t USB_IsConnected(void); + +void USB_ProcessString(uint32_t size); +void USB_ProcessCommand(void); +void USB_ProcessProgramCommand(void); +void USB_ProcessSystemCommand(void); +void USB_ProcessFrequencyCommand(void); + +bool USB_CommandCompare(uint8_t *str); +bool USB_CommandPrefixCompare(uint8_t *str); + +void USB_Send(uint8_t * data); + + + + +#endif /* COMMS_USBCOMMS_H_ */ diff --git a/source/USB/usb_device_config.h b/source/USB/usb_device_config.h new file mode 100644 index 0000000..d76450c --- /dev/null +++ b/source/USB/usb_device_config.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _USB_DEVICE_CONFIG_H_ +#define _USB_DEVICE_CONFIG_H_ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @addtogroup usb_device_configuration + * @{ + */ + +/*! + * @name Hardware instance define + * @{ + */ + +/*! @brief KHCI instance count */ +#define USB_DEVICE_CONFIG_KHCI (0U) + +/*! @brief EHCI instance count */ +#define USB_DEVICE_CONFIG_EHCI (0U) + +/*! @brief LPC USB IP3511 FS instance count */ +#define USB_DEVICE_CONFIG_LPCIP3511FS (1U) //12Mbps, NXP driver - Default setup uses this + +/*! @brief LPC USB IP3511 HS instance count */ +#define USB_DEVICE_CONFIG_LPCIP3511HS (0U) //480Mbps, NXP driver + +/*! @brief Device instance count, the sum of KHCI and EHCI instance counts*/ +#define USB_DEVICE_CONFIG_NUM \ + (USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) + +/* @} */ + +/*! + * @name class instance define + * @{ + */ + +/*! @brief HID instance count */ +#define USB_DEVICE_CONFIG_HID (0U) + +/*! @brief CDC ACM instance count */ +#define USB_DEVICE_CONFIG_CDC_ACM (1U) + +/*! @brief MSC instance count */ +#define USB_DEVICE_CONFIG_MSC (0U) + +/*! @brief Audio instance count */ +#define USB_DEVICE_CONFIG_AUDIO (0U) + +/*! @brief PHDC instance count */ +#define USB_DEVICE_CONFIG_PHDC (0U) + +/*! @brief Video instance count */ +#define USB_DEVICE_CONFIG_VIDEO (0U) + +/*! @brief CCID instance count */ +#define USB_DEVICE_CONFIG_CCID (0U) + +/*! @brief Printer instance count */ +#define USB_DEVICE_CONFIG_PRINTER (0U) + +/*! @brief DFU instance count */ +#define USB_DEVICE_CONFIG_DFU (0U) + +/* @} */ + +/*! @brief Whether device is self power. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_SELF_POWER (1U) + +/*! @brief How many endpoints are supported in the stack. */ +#define USB_DEVICE_CONFIG_ENDPOINTS (4U) + +/*! @brief Whether the device task is enabled. */ +#define USB_DEVICE_CONFIG_USE_TASK (0U) + +/*! @brief How many the notification message are supported when the device task is enabled. */ +#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U) + +/*! @brief Whether test mode enabled. */ +#define USB_DEVICE_CONFIG_USB20_TEST_MODE (0U) + +/*! @brief Whether device CV test is enabled. */ +#define USB_DEVICE_CONFIG_CV_TEST (0U) + +/*! @brief Whether device compliance test is enabled. If the macro is enabled, + the test mode and CV test macroes will be set.*/ +#define USB_DEVICE_CONFIG_COMPLIANCE_TEST (0U) + +#if ((defined(USB_DEVICE_CONFIG_COMPLIANCE_TEST)) && (USB_DEVICE_CONFIG_COMPLIANCE_TEST > 0U)) + +/*! @brief Undefine the macro USB_DEVICE_CONFIG_USB20_TEST_MODE. */ +#undef USB_DEVICE_CONFIG_USB20_TEST_MODE +/*! @brief Undefine the macro USB_DEVICE_CONFIG_CV_TEST. */ +#undef USB_DEVICE_CONFIG_CV_TEST + +/*! @brief enable the test mode. */ +#define USB_DEVICE_CONFIG_USB20_TEST_MODE (1U) + +/*! @brief enable the CV test */ +#define USB_DEVICE_CONFIG_CV_TEST (1U) + +#endif + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + +/*! @brief The MAX buffer length for the KHCI DMA workaround.*/ +#define USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH (64U) +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! @brief How many the DTD are supported. */ +#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U) + +/*! @brief Whether the EHCI ID pin detect feature enabled. */ +#define USB_DEVICE_CONFIG_EHCI_ID_PIN_DETECT (0U) +#endif + +/*! @brief Whether the keep alive feature enabled. */ +#define USB_DEVICE_CONFIG_KEEP_ALIVE_MODE (0U) + +/*! @brief Whether the transfer buffer is cache-enabled or not. */ +#ifndef USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE +#define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U) +#endif +/*! @brief Whether the low power mode is enabled or not. */ +#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U) + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) + +/*! @brief Whether LPM is supported. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_LPM_L1 (0U) +#else +/*! @brief The device remote wakeup is unsupported. */ +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) +#endif + +/*! @brief Whether the device detached feature is enabled or not. */ +#define USB_DEVICE_CONFIG_DETACH_ENABLE (0U) + +/*! @brief Whether handle the USB bus error. */ +#define USB_DEVICE_CONFIG_ERROR_HANDLING (0U) + +/* @} */ + +#endif /* _USB_DEVICE_CONFIG_H_ */ diff --git a/source/USB/usb_device_descriptor.c b/source/USB/usb_device_descriptor.c new file mode 100644 index 0000000..2d8c189 --- /dev/null +++ b/source/USB/usb_device_descriptor.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016, 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" +#include "usb_device_cdc_acm.h" + +#include "usb_device_descriptor.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Define endpoint for communication class */ +usb_device_endpoint_struct_t g_UsbDeviceCdcVcomCicEndpoints[USB_CDC_VCOM_ENDPOINT_CIC_COUNT] = { + { + USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U), + USB_ENDPOINT_INTERRUPT, + FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE, + FS_CDC_VCOM_INTERRUPT_IN_INTERVAL, + }, +}; + +/* Define endpoint for data class */ +usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[USB_CDC_VCOM_ENDPOINT_DIC_COUNT] = { + { + USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U), + USB_ENDPOINT_BULK, + FS_CDC_VCOM_BULK_IN_PACKET_SIZE, + 0U, + }, + { + USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U), + USB_ENDPOINT_BULK, + FS_CDC_VCOM_BULK_OUT_PACKET_SIZE, + 0U, + }}; + +/* Define interface for communication class */ +usb_device_interface_struct_t g_UsbDeviceCdcVcomCommunicationInterface[] = {{0, + { + USB_CDC_VCOM_ENDPOINT_CIC_COUNT, + g_UsbDeviceCdcVcomCicEndpoints, + }, + NULL}}; + +/* Define interface for data class */ +usb_device_interface_struct_t g_UsbDeviceCdcVcomDataInterface[] = {{0, + { + USB_CDC_VCOM_ENDPOINT_DIC_COUNT, + g_UsbDeviceCdcVcomDicEndpoints, + }, + NULL}}; + +/* Define interfaces for virtual com */ +usb_device_interfaces_struct_t g_UsbDeviceCdcVcomInterfaces[USB_CDC_VCOM_INTERFACE_COUNT] = { + {USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, USB_CDC_VCOM_COMM_INTERFACE_INDEX, + g_UsbDeviceCdcVcomCommunicationInterface, + sizeof(g_UsbDeviceCdcVcomCommunicationInterface) / sizeof(usb_device_interface_struct_t)}, + {USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, USB_CDC_VCOM_DATA_INTERFACE_INDEX, + g_UsbDeviceCdcVcomDataInterface, sizeof(g_UsbDeviceCdcVcomDataInterface) / sizeof(usb_device_interface_struct_t)}, +}; + +/* Define configurations for virtual com */ +usb_device_interface_list_t g_UsbDeviceCdcVcomInterfaceList[USB_DEVICE_CONFIGURATION_COUNT] = { + { + USB_CDC_VCOM_INTERFACE_COUNT, + g_UsbDeviceCdcVcomInterfaces, + }, +}; + +/* Define class information for virtual com */ +usb_device_class_struct_t g_UsbDeviceCdcVcomConfig = { + g_UsbDeviceCdcVcomInterfaceList, + kUSB_DeviceClassTypeCdc, + USB_DEVICE_CONFIGURATION_COUNT, +}; + +/* Define device descriptor */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +uint8_t g_UsbDeviceDescriptor[] = { + /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_LENGTH_DEVICE, + /* DEVICE Descriptor Type */ + USB_DESCRIPTOR_TYPE_DEVICE, + /* USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). */ + USB_SHORT_GET_LOW(USB_DEVICE_SPECIFIC_BCD_VERSION), + USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFIC_BCD_VERSION), + /* Class code (assigned by the USB-IF). */ + USB_DEVICE_CLASS, + /* Subclass code (assigned by the USB-IF). */ + USB_DEVICE_SUBCLASS, + /* Protocol code (assigned by the USB-IF). */ + USB_DEVICE_PROTOCOL, + /* Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid) */ + USB_CONTROL_MAX_PACKET_SIZE, + USB_SHORT_GET_LOW(USB_DEVICE_VID), + USB_SHORT_GET_HIGH(USB_DEVICE_VID), /* Vendor ID (assigned by the USB-IF) */ + USB_SHORT_GET_LOW(USB_DEVICE_PID), + USB_SHORT_GET_HIGH(USB_DEVICE_PID), /* Product ID (assigned by the manufacturer) */ + /* Device release number in binary-coded decimal */ + USB_SHORT_GET_LOW(USB_DEVICE_DEMO_BCD_VERSION), + USB_SHORT_GET_HIGH(USB_DEVICE_DEMO_BCD_VERSION), + /* Index of string descriptor describing manufacturer */ + 0x01, + /* Index of string descriptor describing product */ + 0x02, + /* Index of string descriptor describing the device's serial number */ + 0x00, + /* Number of possible configurations */ + USB_DEVICE_CONFIGURATION_COUNT, +}; + +/* Define configuration descriptor */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +uint8_t g_UsbDeviceConfigurationDescriptor[] = { + /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_LENGTH_CONFIGURE, + /* CONFIGURATION Descriptor Type */ + USB_DESCRIPTOR_TYPE_CONFIGURE, + /* Total length of data returned for this configuration. */ + USB_SHORT_GET_LOW(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE + + USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG + + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC + + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE + + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_ENDPOINT), + USB_SHORT_GET_HIGH(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE + + USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG + + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC + + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE + + USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_ENDPOINT), + /* Number of interfaces supported by this configuration */ + USB_CDC_VCOM_INTERFACE_COUNT, + /* Value to use as an argument to the SetConfiguration() request to select this configuration */ + USB_CDC_VCOM_CONFIGURE_INDEX, + /* Index of string descriptor describing this configuration */ + 0, + /* Configuration characteristics D7: Reserved (set to one) D6: Self-powered D5: Remote Wakeup D4...0: Reserved + (reset to zero) */ + (USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) | + (USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) | + (USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT), + /* Maximum power consumption of the USB * device from the bus in this specific * configuration when the device is + fully * operational. Expressed in 2 mA units * (i.e., 50 = 100 mA). */ + USB_DEVICE_MAX_POWER, + + /* Communication Interface Descriptor */ + USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_COMM_INTERFACE_INDEX, 0x00, + USB_CDC_VCOM_ENDPOINT_CIC_COUNT, USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, + 0x00, /* Interface Description String Index*/ + + /* CDC Class-Specific descriptor */ + USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_HEADER_FUNC_DESC, 0x10, + 0x01, /* USB Class Definitions for Communications the Communication specification version 1.10 */ + + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_CALL_MANAGEMENT_FUNC_DESC, + 0x01, /*Bit 0: Whether device handle call management itself 1, Bit 1: Whether device can send/receive call + management information over a Data Class Interface 0 */ + 0x01, /* Indicates multiplexed commands are handled via data interface */ + + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_ABSTRACT_CONTROL_FUNC_DESC, + 0x06, /* Bit 0: Whether device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and + Get_Comm_Feature 0, Bit 1: Whether device supports the request combination of Set_Line_Coding, + Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State 1, Bit ... */ + + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_UNION_FUNC_DESC, 0x00, /* The interface number of the Communications or Data Class interface */ + 0x01, /* Interface number of subordinate interface in the Union */ + + /*Notification Endpoint descriptor */ + USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U), + USB_ENDPOINT_INTERRUPT, USB_SHORT_GET_LOW(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE), + USB_SHORT_GET_HIGH(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE), FS_CDC_VCOM_INTERRUPT_IN_INTERVAL, + + /* Data Interface Descriptor */ + USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_DATA_INTERFACE_INDEX, 0x00, + USB_CDC_VCOM_ENDPOINT_DIC_COUNT, USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, + 0x00, /* Interface Description String Index*/ + + /*Bulk IN Endpoint descriptor */ + USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U), + USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_IN_PACKET_SIZE), + USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_IN_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */ + + /*Bulk OUT Endpoint descriptor */ + USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U), + USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE), + USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */ +}; + +/* Define string descriptor */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +uint8_t g_UsbDeviceString0[] = {2U + 2U, USB_DESCRIPTOR_TYPE_STRING, 0x09, 0x04}; + +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +uint8_t g_UsbDeviceString1[] = { + 2U + 2U * 18U, USB_DESCRIPTOR_TYPE_STRING, + 'N', 0x00U, + 'X', 0x00U, + 'P', 0x00U, + ' ', 0x00U, + 'S', 0x00U, + 'E', 0x00U, + 'M', 0x00U, + 'I', 0x00U, + 'C', 0x00U, + 'O', 0x00U, + 'N', 0x00U, + 'D', 0x00U, + 'U', 0x00U, + 'C', 0x00U, + 'T', 0x00U, + 'O', 0x00U, + 'R', 0x00U, + 'S', 0x00U, +}; + +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +#if 1 //Changed Descriptor +uint8_t g_UsbDeviceString2[] = {2U + 2U * 16U, USB_DESCRIPTOR_TYPE_STRING, + 'U', 0, + 'M', 0, + 'A', 0, + 'G', 0, + ' ', 0, + 'T', 0, + 'R', 0, + 'A', 0, + 'N', 0, + 'S', 0, + 'M', 0, + 'I', 0, + 'T', 0, + 'T', 0, + 'E', 0, + 'R', 0}; + +#else +uint8_t g_UsbDeviceString2[] = {2U + 2U * 20U, USB_DESCRIPTOR_TYPE_STRING, + 'M', 0, + 'C', 0, + 'U', 0, + ' ', 0, + 'V', 0, + 'I', 0, + 'R', 0, + 'T', 0, + 'U', 0, + 'A', 0, + 'L', 0, + ' ', 0, + 'C', 0, + 'O', 0, + 'M', 0, + ' ', 0, + 'D', 0, + 'E', 0, + 'M', 0, + 'O', 0}; +#endif + +uint8_t *g_UsbDeviceStringDescriptorArray[USB_DEVICE_STRING_COUNT] = {g_UsbDeviceString0, g_UsbDeviceString1, + g_UsbDeviceString2}; + +/* Define string descriptor size */ +uint32_t g_UsbDeviceStringDescriptorLength[USB_DEVICE_STRING_COUNT] = { + sizeof(g_UsbDeviceString0), sizeof(g_UsbDeviceString1), sizeof(g_UsbDeviceString2)}; +usb_language_t g_UsbDeviceLanguage[USB_DEVICE_LANGUAGE_COUNT] = {{ + g_UsbDeviceStringDescriptorArray, + g_UsbDeviceStringDescriptorLength, + (uint16_t)0x0409, +}}; + +usb_language_list_t g_UsbDeviceLanguageList = { + g_UsbDeviceString0, + sizeof(g_UsbDeviceString0), + g_UsbDeviceLanguage, + USB_DEVICE_LANGUAGE_COUNT, +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief USB device get device descriptor function. + * + * This function gets the device descriptor of the USB device. + * + * @param handle The USB device handle. + * @param deviceDescriptor The pointer to the device descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle, + usb_device_get_device_descriptor_struct_t *deviceDescriptor) +{ + deviceDescriptor->buffer = g_UsbDeviceDescriptor; + deviceDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE; + return kStatus_USB_Success; +} + +/*! + * @brief USB device get configuration descriptor function. + * + * This function gets the configuration descriptor of the USB device. + * + * @param handle The USB device handle. + * @param configurationDescriptor The pointer to the configuration descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetConfigurationDescriptor( + usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor) +{ + if (USB_CDC_VCOM_CONFIGURE_INDEX > configurationDescriptor->configuration) + { + configurationDescriptor->buffer = g_UsbDeviceConfigurationDescriptor; + configurationDescriptor->length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL; + return kStatus_USB_Success; + } + return kStatus_USB_InvalidRequest; +} + +/*! + * @brief USB device get string descriptor function. + * + * This function gets the string descriptor of the USB device. + * + * @param handle The USB device handle. + * @param stringDescriptor Pointer to the string descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle, + usb_device_get_string_descriptor_struct_t *stringDescriptor) +{ + if (stringDescriptor->stringIndex == 0U) + { + stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageString; + stringDescriptor->length = g_UsbDeviceLanguageList.stringLength; + } + else + { + uint8_t languageId = 0U; + uint8_t languageIndex = USB_DEVICE_STRING_COUNT; + + for (; languageId < USB_DEVICE_LANGUAGE_COUNT; languageId++) + { + if (stringDescriptor->languageId == g_UsbDeviceLanguageList.languageList[languageId].languageId) + { + if (stringDescriptor->stringIndex < USB_DEVICE_STRING_COUNT) + { + languageIndex = stringDescriptor->stringIndex; + } + break; + } + } + + if (USB_DEVICE_STRING_COUNT == languageIndex) + { + return kStatus_USB_InvalidRequest; + } + stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageList[languageId].string[languageIndex]; + stringDescriptor->length = g_UsbDeviceLanguageList.languageList[languageId].length[languageIndex]; + } + return kStatus_USB_Success; +} + +/*! + * @brief USB device set speed function. + * + * This function sets the speed of the USB device. + * + * Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match + * current speed. + * As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and + * KHCI. + * When the EHCI is enabled, the application needs to call this function to update device by using current speed. + * The updated information includes endpoint max packet size, endpoint interval, etc. + * + * @param handle The USB device handle. + * @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed) +{ + usb_descriptor_union_t *ptr1; + usb_descriptor_union_t *ptr2; + int i; + + ptr1 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[0]); + ptr2 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL - 1]); + + while (ptr1 < ptr2) + { + if (ptr1->common.bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT) + { + if (USB_SPEED_HIGH == speed) + { + if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) == + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) && + (USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT == + (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + ptr1->endpoint.bInterval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL; + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE, + ptr1->endpoint.wMaxPacketSize); + } + else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) == + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) && + (USB_CDC_VCOM_BULK_IN_ENDPOINT == + (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) == + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) && + (USB_CDC_VCOM_BULK_OUT_ENDPOINT == + (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else + { + } + } + else + { + if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) == + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) && + (USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT == + (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + ptr1->endpoint.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL; + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE, + ptr1->endpoint.wMaxPacketSize); + } + else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) == + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) && + (USB_CDC_VCOM_BULK_IN_ENDPOINT == + (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else if (((ptr1->endpoint.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) == + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) && + (USB_CDC_VCOM_BULK_OUT_ENDPOINT == + (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else + { + } + } + } + ptr1 = (usb_descriptor_union_t *)((uint8_t *)ptr1 + ptr1->common.bLength); + } + + for (i = 0; i < USB_CDC_VCOM_ENDPOINT_CIC_COUNT; i++) + { + if (USB_SPEED_HIGH == speed) + { + g_UsbDeviceCdcVcomCicEndpoints[i].maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE; + g_UsbDeviceCdcVcomCicEndpoints[i].interval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL; + } + else + { + g_UsbDeviceCdcVcomCicEndpoints[i].maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE; + g_UsbDeviceCdcVcomCicEndpoints[i].interval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL; + } + } + for (i = 0; i < USB_CDC_VCOM_ENDPOINT_DIC_COUNT; i++) + { + if (USB_SPEED_HIGH == speed) + { + if (g_UsbDeviceCdcVcomDicEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) + { + g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE; + } + else + { + g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE; + } + } + else + { + if (g_UsbDeviceCdcVcomDicEndpoints[i].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) + { + g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE; + } + else + { + g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE; + } + } + } + + return kStatus_USB_Success; +} diff --git a/source/USB/usb_device_descriptor.h b/source/USB/usb_device_descriptor.h new file mode 100644 index 0000000..8f5693f --- /dev/null +++ b/source/USB/usb_device_descriptor.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _USB_DEVICE_DESCRIPTOR_H_ +#define _USB_DEVICE_DESCRIPTOR_H_ 1 + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define USB_DEVICE_SPECIFIC_BCD_VERSION (0x0200) +#define USB_DEVICE_DEMO_BCD_VERSION (0x0101U) + +#define USB_DEVICE_VID (0x1FC9U) +#define USB_DEVICE_PID (0x8310U) + +/* Communication Class Codes */ +#define CDC_COMM_CLASS (0x02) +/* Data Class Codes */ +#define CDC_DATA_CLASS (0x0A) + +/* Communication Class SubClass Codes */ +#define USB_CDC_DIRECT_LINE_CONTROL_MODEL (0x01) +#define USB_CDC_ABSTRACT_CONTROL_MODEL (0x02) +#define USB_CDC_TELEPHONE_CONTROL_MODEL (0x03) +#define USB_CDC_MULTI_CHANNEL_CONTROL_MODEL (0x04) +#define USB_CDC_CAPI_CONTROL_MOPDEL (0x05) +#define USB_CDC_ETHERNET_NETWORKING_CONTROL_MODEL (0x06) +#define USB_CDC_ATM_NETWORKING_CONTROL_MODEL (0x07) +#define USB_CDC_WIRELESS_HANDSET_CONTROL_MODEL (0x08) +#define USB_CDC_DEVICE_MANAGEMENT (0x09) +#define USB_CDC_MOBILE_DIRECT_LINE_MODEL (0x0A) +#define USB_CDC_OBEX (0x0B) +#define USB_CDC_ETHERNET_EMULATION_MODEL (0x0C) + +/* Communication Class Protocol Codes */ +#define USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL (0x00) /*also for Data Class Protocol Code */ +#define USB_CDC_AT_250_PROTOCOL (0x01) +#define USB_CDC_AT_PCCA_101_PROTOCOL (0x02) +#define USB_CDC_AT_PCCA_101_ANNEX_O (0x03) +#define USB_CDC_AT_GSM_7_07 (0x04) +#define USB_CDC_AT_3GPP_27_007 (0x05) +#define USB_CDC_AT_TIA_CDMA (0x06) +#define USB_CDC_ETHERNET_EMULATION_PROTOCOL (0x07) +#define USB_CDC_EXTERNAL_PROTOCOL (0xFE) +#define USB_CDC_VENDOR_SPECIFIC (0xFF) /*also for Data Class Protocol Code */ + +/* Data Class Protocol Codes */ +#define USB_CDC_PYHSICAL_INTERFACE_PROTOCOL (0x30) +#define USB_CDC_HDLC_PROTOCOL (0x31) +#define USB_CDC_TRANSPARENT_PROTOCOL (0x32) +#define USB_CDC_MANAGEMENT_PROTOCOL (0x50) +#define USB_CDC_DATA_LINK_Q931_PROTOCOL (0x51) +#define USB_CDC_DATA_LINK_Q921_PROTOCOL (0x52) +#define USB_CDC_DATA_COMPRESSION_V42BIS (0x90) +#define USB_CDC_EURO_ISDN_PROTOCOL (0x91) +#define USB_CDC_RATE_ADAPTION_ISDN_V24 (0x92) +#define USB_CDC_CAPI_COMMANDS (0x93) +#define USB_CDC_HOST_BASED_DRIVER (0xFD) +#define USB_CDC_UNIT_FUNCTIONAL (0xFE) + +/* Descriptor SubType in Communications Class Functional Descriptors */ +#define USB_CDC_HEADER_FUNC_DESC (0x00) +#define USB_CDC_CALL_MANAGEMENT_FUNC_DESC (0x01) +#define USB_CDC_ABSTRACT_CONTROL_FUNC_DESC (0x02) +#define USB_CDC_DIRECT_LINE_FUNC_DESC (0x03) +#define USB_CDC_TELEPHONE_RINGER_FUNC_DESC (0x04) +#define USB_CDC_TELEPHONE_REPORT_FUNC_DESC (0x05) +#define USB_CDC_UNION_FUNC_DESC (0x06) +#define USB_CDC_COUNTRY_SELECT_FUNC_DESC (0x07) +#define USB_CDC_TELEPHONE_MODES_FUNC_DESC (0x08) +#define USB_CDC_TERMINAL_FUNC_DESC (0x09) +#define USB_CDC_NETWORK_CHANNEL_FUNC_DESC (0x0A) +#define USB_CDC_PROTOCOL_UNIT_FUNC_DESC (0x0B) +#define USB_CDC_EXTENSION_UNIT_FUNC_DESC (0x0C) +#define USB_CDC_MULTI_CHANNEL_FUNC_DESC (0x0D) +#define USB_CDC_CAPI_CONTROL_FUNC_DESC (0x0E) +#define USB_CDC_ETHERNET_NETWORKING_FUNC_DESC (0x0F) +#define USB_CDC_ATM_NETWORKING_FUNC_DESC (0x10) +#define USB_CDC_WIRELESS_CONTROL_FUNC_DESC (0x11) +#define USB_CDC_MOBILE_DIRECT_LINE_FUNC_DESC (0x12) +#define USB_CDC_MDLM_DETAIL_FUNC_DESC (0x13) +#define USB_CDC_DEVICE_MANAGEMENT_FUNC_DESC (0x14) +#define USB_CDC_OBEX_FUNC_DESC (0x15) +#define USB_CDC_COMMAND_SET_FUNC_DESC (0x16) +#define USB_CDC_COMMAND_SET_DETAIL_FUNC_DESC (0x17) +#define USB_CDC_TELEPHONE_CONTROL_FUNC_DESC (0x18) +#define USB_CDC_OBEX_SERVICE_ID_FUNC_DESC (0x19) + +/* usb descriptor length */ +#define USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL (sizeof(g_UsbDeviceConfigurationDescriptor)) +#define USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC (5) +#define USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG (5) +#define USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT (4) +#define USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC (5) + +/* Configuration, interface and endpoint. */ +#define USB_DEVICE_CONFIGURATION_COUNT (1) +#define USB_DEVICE_STRING_COUNT (3) +#define USB_DEVICE_LANGUAGE_COUNT (1) + +#define USB_CDC_VCOM_CONFIGURE_INDEX (1) + +#define USB_CDC_VCOM_ENDPOINT_CIC_COUNT (1) +#define USB_CDC_VCOM_ENDPOINT_DIC_COUNT (2) +#define USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT (1) +#define USB_CDC_VCOM_BULK_IN_ENDPOINT (2) +#define USB_CDC_VCOM_BULK_OUT_ENDPOINT (3) +#define USB_CDC_VCOM_INTERFACE_COUNT (2) +#define USB_CDC_VCOM_COMM_INTERFACE_INDEX (0) +#define USB_CDC_VCOM_DATA_INTERFACE_INDEX (1) + +/* Packet size. */ +#define HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16) +#define FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16) +#define HS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x07) /* 2^(7-1) = 8ms */ +#define FS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x08) +#define HS_CDC_VCOM_BULK_IN_PACKET_SIZE (512) +#define FS_CDC_VCOM_BULK_IN_PACKET_SIZE (64) +#define HS_CDC_VCOM_BULK_OUT_PACKET_SIZE (512) +#define FS_CDC_VCOM_BULK_OUT_PACKET_SIZE (64) + +/* String descriptor length. */ +#define USB_DESCRIPTOR_LENGTH_STRING0 (sizeof(g_UsbDeviceString0)) +#define USB_DESCRIPTOR_LENGTH_STRING1 (sizeof(g_UsbDeviceString1)) +#define USB_DESCRIPTOR_LENGTH_STRING2 (sizeof(g_UsbDeviceString2)) + +#define USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE (0x24) +#define USB_DESCRIPTOR_TYPE_CDC_CS_ENDPOINT (0x25) + +/* Class code. */ +#define USB_DEVICE_CLASS (0x02) +#define USB_DEVICE_SUBCLASS (0x00) +#define USB_DEVICE_PROTOCOL (0x00) + +#define USB_DEVICE_MAX_POWER (0x32) + +#define USB_CDC_VCOM_CIC_CLASS (CDC_COMM_CLASS) +#define USB_CDC_VCOM_CIC_SUBCLASS (USB_CDC_ABSTRACT_CONTROL_MODEL) +#define USB_CDC_VCOM_CIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL) + +#define USB_CDC_VCOM_DIC_CLASS (CDC_DATA_CLASS) +#define USB_CDC_VCOM_DIC_SUBCLASS (0x00) +#define USB_CDC_VCOM_DIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL) + +/******************************************************************************* + * API + ******************************************************************************/ +/*! + * @brief USB device set speed function. + * + * This function sets the speed of the USB device. + * + * Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match + * current speed. + * As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and + * KHCI. + * When the EHCI is enabled, the application needs to call this function to update device by using current speed. + * The updated information includes endpoint max packet size, endpoint interval, etc. + * + * @param handle The USB device handle. + * @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed); +/*! + * @brief USB device get device descriptor function. + * + * This function gets the device descriptor of the USB device. + * + * @param handle The USB device handle. + * @param deviceDescriptor The pointer to the device descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle, + usb_device_get_device_descriptor_struct_t *deviceDescriptor); +/*! + * @brief USB device get string descriptor function. + * + * This function gets the string descriptor of the USB device. + * + * @param handle The USB device handle. + * @param stringDescriptor Pointer to the string descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle, + usb_device_get_string_descriptor_struct_t *stringDescriptor); +/*! + * @brief USB device get configuration descriptor function. + * + * This function gets the configuration descriptor of the USB device. + * + * @param handle The USB device handle. + * @param configurationDescriptor The pointer to the configuration descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceGetConfigurationDescriptor( + usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor); +#endif /* _USB_DEVICE_DESCRIPTOR_H_ */ diff --git a/source/USB/virtual_com.c b/source/USB/virtual_com.c new file mode 100644 index 0000000..eea1f2a --- /dev/null +++ b/source/USB/virtual_com.c @@ -0,0 +1,673 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include "fsl_device_registers.h" +#include "fsl_debug_console.h" +#include "pin_mux.h" +#include "clock_config.h" +#include "board.h" + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" +#include "usb_device_cdc_acm.h" +#include "usb_device_ch9.h" + +#include "usb_device_descriptor.h" +#include "virtual_com.h" +#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U)) +#include "fsl_sysmpu.h" +#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */ + +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) +#include "usb_phy.h" +#endif +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) +extern uint8_t USB_EnterLowpowerMode(void); +#endif +#include "fsl_power.h" + +//Application Includes +#include "flashUpdate.h" +#include "usbComms.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define CR '\r' //carriage return +#define LF '\n' //line feed +#define null 0 //NULL is defined at (void *)0 so it causes errors + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +void BOARD_InitHardware(void); +void USB_DeviceClockInit(void); +void USB_DeviceIsrEnable(void); +#if USB_DEVICE_CONFIG_USE_TASK +void USB_DeviceTaskFn(void *deviceHandle); +#endif + +void BOARD_DbgConsole_Deinit(void); +void BOARD_DbgConsole_Init(void); +usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param); +usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param); + + +#if 0 //Trying to fix project after adding, then removing FLASHIAP driver. Makes no difference +extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); +extern usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ + +//Application +extern USB_t usb; + + +extern usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[]; +extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig; +/* Data structure of virtual com device */ +usb_cdc_vcom_struct_t s_cdcVcom; + +/* Line coding of cdc device */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +static uint8_t s_lineCoding[LINE_CODING_SIZE] = { + /* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */ + (LINE_CODING_DTERATE >> 0U) & 0x000000FFU, + (LINE_CODING_DTERATE >> 8U) & 0x000000FFU, + (LINE_CODING_DTERATE >> 16U) & 0x000000FFU, + (LINE_CODING_DTERATE >> 24U) & 0x000000FFU, + LINE_CODING_CHARFORMAT, + LINE_CODING_PARITYTYPE, + LINE_CODING_DATABITS}; + +/* Abstract state of cdc device */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU, + (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU}; + +/* Country code of cdc device */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) +static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU, + (COUNTRY_SETTING >> 8U) & 0x00FFU}; + +/* CDC ACM information */ +USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static usb_cdc_acm_info_t s_usbCdcAcmInfo; +/* Data buffer for receiving and sending*/ +USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t rxBuffer[USB_BUFFER_SIZE]; +USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t txBuffer[USB_BUFFER_SIZE]; +volatile static uint32_t rxDataSize = 0; +volatile static uint32_t txDataSize = 0; + +/* USB device class information */ +static usb_device_class_config_struct_t s_cdcAcmConfig[1] = {{ + USB_DeviceCdcVcomCallback, + 0, + &g_UsbDeviceCdcVcomConfig, +}}; + +/* USB device class configuration information */ +static usb_device_class_config_list_struct_t s_cdcAcmConfigList = { + s_cdcAcmConfig, + USB_DeviceCallback, + 1, +}; + +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) +volatile static uint8_t s_waitForDataReceive = 0; +volatile static uint8_t s_comOpen = 0; +#endif +/******************************************************************************* + * Code + ******************************************************************************/ + +void USB0_IRQHandler(void) +{ + USB_DeviceLpcIp3511IsrFunction(s_cdcVcom.deviceHandle); +} + +void USB_DeviceClockInit(void) +{ + /* enable USB IP clock */ + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); +} +void USB_DeviceIsrEnable(void) +{ + uint8_t irqNumber; + + uint8_t usbDeviceIP3511Irq[] = USB_IRQS; + irqNumber = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Fs0]; + + /* Install isr, set priority, and enable IRQ. */ + NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY); + EnableIRQ((IRQn_Type)irqNumber); +} +#if USB_DEVICE_CONFIG_USE_TASK +void USB_DeviceTaskFn(void *deviceHandle) +{ + USB_DeviceLpcIp3511TaskFunction(deviceHandle); +} +#endif +/*! + * @brief CDC class specific callback function. + * + * This function handles the CDC class specific requests. + * + * @param handle The CDC ACM class handle. + * @param event The CDC ACM class event type. + * @param param The parameter of the class specific request. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param) +{ + uint32_t len; + uint8_t *uartBitmap; + usb_device_cdc_acm_request_param_struct_t *acmReqParam; + usb_device_endpoint_callback_message_struct_t *epCbParam; + usb_status_t error = kStatus_USB_Error; + usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo; + acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param; + epCbParam = (usb_device_endpoint_callback_message_struct_t *)param; + switch (event) + { + case kUSB_DeviceCdcEventSendResponse: + { + if ((epCbParam->length != 0) && (!(epCbParam->length % g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize))) + { + /* If the last packet is the size of endpoint, then send also zero-ended packet, + ** meaning that we want to inform the host that we do not have any additional + ** data, so it can flush the output. + */ + error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0); + } + else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)) + { + if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0))) + { + /* User: add your own code for send complete event */ + /* Schedule buffer for next receive event */ + error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer, + g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize); +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 1; + USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK; +#endif + } + } + else + { + } + } + break; + case kUSB_DeviceCdcEventRecvResponse: + { + if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)) + { + rxDataSize = epCbParam->length; + +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 0; + USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK; +#endif + if (!rxDataSize) + { + /* Schedule buffer for next receive event */ + error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer, + g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize); +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 1; + USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK; +#endif + } + } + } + break; + case kUSB_DeviceCdcEventSerialStateNotif: + ((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0; + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventSendEncapsulatedCommand: + break; + case kUSB_DeviceCdcEventGetEncapsulatedResponse: + break; + case kUSB_DeviceCdcEventSetCommFeature: + if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue) + { + if (1 == acmReqParam->isSetup) + { + *(acmReqParam->buffer) = s_abstractState; + } + else + { + *(acmReqParam->length) = 0; + } + } + else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue) + { + if (1 == acmReqParam->isSetup) + { + *(acmReqParam->buffer) = s_countryCode; + } + else + { + *(acmReqParam->length) = 0; + } + } + else + { + } + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventGetCommFeature: + if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue) + { + *(acmReqParam->buffer) = s_abstractState; + *(acmReqParam->length) = COMM_FEATURE_DATA_SIZE; + } + else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue) + { + *(acmReqParam->buffer) = s_countryCode; + *(acmReqParam->length) = COMM_FEATURE_DATA_SIZE; + } + else + { + } + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventClearCommFeature: + break; + case kUSB_DeviceCdcEventGetLineCoding: + *(acmReqParam->buffer) = s_lineCoding; + *(acmReqParam->length) = LINE_CODING_SIZE; + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventSetLineCoding: + { + if (1 == acmReqParam->isSetup) + { + *(acmReqParam->buffer) = s_lineCoding; + } + else + { + *(acmReqParam->length) = 0; + } + } + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventSetControlLineState: + { + s_usbCdcAcmInfo.dteStatus = acmReqParam->setupValue; + /* activate/deactivate Tx carrier */ + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION) + { + acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER; + } + else + { + acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER; + } + + /* activate carrier and DTE. Com port of terminal tool running on PC is open now */ + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) + { + acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER; + } + /* Com port of terminal tool running on PC is closed now */ + else + { + acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER; + } + + /* Indicates to DCE if DTE is present or not */ + acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? 1 : 0; + + /* Initialize the serial state buffer */ + acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */ + acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE; /* bNotification */ + acmInfo->serialStateBuf[2] = 0x00; /* wValue */ + acmInfo->serialStateBuf[3] = 0x00; + acmInfo->serialStateBuf[4] = 0x00; /* wIndex */ + acmInfo->serialStateBuf[5] = 0x00; + acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */ + acmInfo->serialStateBuf[7] = 0x00; + /* Notify to host the line state */ + acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex; + /* Lower byte of UART BITMAP */ + uartBitmap = (uint8_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2]; + uartBitmap[0] = acmInfo->uartState & 0xFFu; + uartBitmap[1] = (acmInfo->uartState >> 8) & 0xFFu; + len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE); + if (0 == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState) + { + error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len); + if (kStatus_USB_Success != error) + { + //usb_echo("kUSB_DeviceCdcEventSetControlLineState error!"); + } + ((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1; + } + + /* Update status */ + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION) + { + /* To do: CARRIER_ACTIVATED */ + } + else + { + /* To do: CARRIER_DEACTIVATED */ + } + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) + { + /* DTE_ACTIVATED */ + if (1 == s_cdcVcom.attach) + { + s_cdcVcom.startTransactions = 1; +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 1; + USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK; + s_comOpen = 1; + usb_echo("USB_APP_CDC_DTE_ACTIVATED\r\n"); +#endif + } + } + else + { + /* DTE_DEACTIVATED */ + if (1 == s_cdcVcom.attach) + { + s_cdcVcom.startTransactions = 0; + } + } + } + break; + case kUSB_DeviceCdcEventSendBreak: + break; + default: + break; + } + + return error; +} + +/*! + * @brief USB device callback function. + * + * This function handles the usb device specific requests. + * + * @param handle The USB device handle. + * @param event The USB device event type. + * @param param The parameter of the device specific request. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param) +{ + usb_status_t error = kStatus_USB_Error; + uint16_t *temp16 = (uint16_t *)param; + uint8_t *temp8 = (uint8_t *)param; + + switch (event) + { + case kUSB_DeviceEventBusReset: + { + s_cdcVcom.attach = 0; + s_cdcVcom.currentConfiguration = 0U; +#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + /* Get USB speed to configure the device, including max packet size and interval of the endpoints. */ + if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &s_cdcVcom.speed)) + { + USB_DeviceSetSpeed(handle, s_cdcVcom.speed); + } +#endif + } + break; + case kUSB_DeviceEventSetConfiguration: + if (0U == (*temp8)) + { + s_cdcVcom.attach = 0; + s_cdcVcom.currentConfiguration = 0U; + } + else if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8)) + { + s_cdcVcom.attach = 1; + s_cdcVcom.currentConfiguration = *temp8; + /* Schedule buffer for receive */ + USB_DeviceCdcAcmRecv(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, rxBuffer, + g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize); + } + else + { + error = kStatus_USB_InvalidRequest; + } + break; + case kUSB_DeviceEventSetInterface: + if (s_cdcVcom.attach) + { + uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U); + uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU); + if (interface < USB_CDC_VCOM_INTERFACE_COUNT) + { + s_cdcVcom.currentInterfaceAlternateSetting[interface] = alternateSetting; + } + } + break; + case kUSB_DeviceEventGetConfiguration: + break; + case kUSB_DeviceEventGetInterface: + break; + case kUSB_DeviceEventGetDeviceDescriptor: + if (param) + { + error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param); + } + break; + case kUSB_DeviceEventGetConfigurationDescriptor: + if (param) + { + error = USB_DeviceGetConfigurationDescriptor(handle, + (usb_device_get_configuration_descriptor_struct_t *)param); + } + break; + case kUSB_DeviceEventGetStringDescriptor: + if (param) + { + /* Get device string descriptor request */ + error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param); + } + break; + default: + break; + } + + return error; +} + +/*! + * @brief Application initialization function. + * + * This function initializes the application. + * + * @return None. + */ +void USB_Init(void) +{ + if(usb.initialized) + { + return; + } + + usb.initialized = true; + + USB_DeviceClockInit(); +#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U)) + SYSMPU_Enable(SYSMPU, 0); +#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */ + + usb.rxDataIndex = 0; + + s_cdcVcom.speed = USB_SPEED_FULL; + s_cdcVcom.attach = 0; + s_cdcVcom.cdcAcmHandle = (class_handle_t)NULL; + s_cdcVcom.deviceHandle = NULL; + + if (kStatus_USB_Success != USB_DeviceClassInit(CONTROLLER_ID, &s_cdcAcmConfigList, &s_cdcVcom.deviceHandle)) + { + //usb_echo("USB device init failed\r\n"); + } + else + { + usb_echo("USB device CDC virtual com demo\r\n"); + s_cdcVcom.cdcAcmHandle = s_cdcAcmConfigList.config->classHandle; + } + + USB_DeviceIsrEnable(); + + /*Add one delay here to make the DP pull down long enough to allow host to detect the previous disconnection.*/ + SDK_DelayAtLeastUs(5000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); + USB_DeviceRun(s_cdcVcom.deviceHandle); +} + +/*! + * @brief Application task function. + * + * This function runs the task for application. + * + * @return None. + */ +void USB_Update(void) +{ + usb_status_t error = kStatus_USB_Error; + if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)) + { + /* User Code */ + /* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */ + if ((0 != rxDataSize) && (USB_CANCELLED_TRANSFER_LENGTH != rxDataSize)) + { + + usb.rxDataIndex = 0; + + //copy to rxDataBuffer for processing + for (int32_t i = 0; i < rxDataSize; i++) + { + usb.rxDataBuffer[usb.rxDataIndex++] = rxBuffer[i]; + } + uint32_t tempDataSize = rxDataSize; //temp variable to pass to USB_ProcessData() + rxDataSize = 0; + + if(usb.programMode) //ProgramMode = send data for write to FLASH + { + FU_WriteProgramDataToFLASH(); + } + else + { + //Process String + USB_ProcessString(tempDataSize); + } + + } +#if 0 //Transmit + if (txDataSize) + { + uint32_t size = txDataSize; + txDataSize = 0; + + error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, txBuffer, size); + + if (error != kStatus_USB_Success) + { + /* Failure to send Data Handling code here */ + } + } +#endif + } +} + +//Send data to via USB +void USB_SendString(uint8_t * str) +{ + if(!s_cdcVcom.attach) //exit if USB not connected + { + return; + } + + uint32_t length = strlen(str); + + if(length > USB_BUFFER_SIZE - 1) //allow for LF char + { + return; //TODO: handle this better. Use a txRingbuffer + } + + //copy data to txBuffer + memcpy(txBuffer, str, length); + txBuffer[length++] = CR; //append CR for realterm + txBuffer[length++] = LF; //append LF for windows + txDataSize = length; + +#if 1 //Send data + + //Wait for USB ready + while(!((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))); //TODO: make this not block forever + + uint32_t size = txDataSize; + txDataSize = 0; + + usb_status_t error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, txBuffer, size); + if (error != kStatus_USB_Success) + { + /* Failure to send Data Handling code here */ + + usb.sendErrorCount++; + } + +#endif + +} + +#if 0 //main function from example +int main(void) +{ + /* attach 12 MHz clock to FLEXCOMM0 (debug console) */ + CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); + BOARD_InitPins(); + BOARD_BootClockPLL150M(); + CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */ + BOARD_InitDebugConsole(); + POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*Turn on USB Phy */ + + USB_Init(); + + while (1) + { + USB_Update(); + + } +} +#endif + diff --git a/source/USB/virtual_com.h b/source/USB/virtual_com.h new file mode 100644 index 0000000..f17f78d --- /dev/null +++ b/source/USB/virtual_com.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _USB_CDC_VCOM_H_ +#define _USB_CDC_VCOM_H_ 1 + + + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" +#include "usb_device_cdc_acm.h" +#include "usb_device_ch9.h" + +#include "usb_device_descriptor.h" +#include "virtual_com.h" + + +#include "usb.h" + + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0) +#define CONTROLLER_ID kUSB_ControllerEhci0 +#define USB_BUFFER_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE + +#endif +#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0) +#define CONTROLLER_ID kUSB_ControllerKhci0 +#define USB_BUFFER_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE + +#endif +#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U) +#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0 +#define USB_BUFFER_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE + +#endif + +#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U) +#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0 +#define USB_BUFFER_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE +#endif + +#define USB_DEVICE_INTERRUPT_PRIORITY (3U) +/* Currently configured line coding */ +#define LINE_CODING_SIZE (0x07) +#define LINE_CODING_DTERATE (115200) +#define LINE_CODING_CHARFORMAT (0x00) +#define LINE_CODING_PARITYTYPE (0x00) +#define LINE_CODING_DATABITS (0x08) + +/* Communications feature */ +#define COMM_FEATURE_DATA_SIZE (0x02) +#define STATUS_ABSTRACT_STATE (0x0000) +#define COUNTRY_SETTING (0x0000) + +/* Notification of serial state */ +#define NOTIF_PACKET_SIZE (0x08) +#define UART_BITMAP_SIZE (0x02) +#define NOTIF_REQUEST_TYPE (0xA1) + +/* Define the types for application */ +typedef struct _usb_cdc_vcom_struct +{ + usb_device_handle deviceHandle; /* USB device handle. */ + class_handle_t cdcAcmHandle; /* USB CDC ACM class handle. */ + volatile uint8_t attach; /* A flag to indicate whether a usb device is attached. 1: attached, 0: not attached */ + uint8_t speed; /* Speed of USB device. USB_SPEED_FULL/USB_SPEED_LOW/USB_SPEED_HIGH. */ + volatile uint8_t + startTransactions; /* A flag to indicate whether a CDC device is ready to transmit and receive data. */ + uint8_t currentConfiguration; /* Current configuration value. */ + uint8_t currentInterfaceAlternateSetting[USB_CDC_VCOM_INTERFACE_COUNT]; /* Current alternate setting value for each + interface. */ +} usb_cdc_vcom_struct_t; + +/* Define the information relates to abstract control model */ +typedef struct _usb_cdc_acm_info +{ + uint8_t serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE]; /* Serial state buffer of the CDC device to notify the + serial state to host. */ + uint8_t dtePresent; /* A flag to indicate whether DTE is present. */ + uint16_t breakDuration; /* Length of time in milliseconds of the break signal */ + uint8_t dteStatus; /* Status of data terminal equipment */ + uint8_t currentInterface; /* Current interface index. */ + uint16_t uartState; /* UART state of the CDC device. */ +} usb_cdc_acm_info_t; + + +void USB_Init(void); +void USB_Update(void); + +void USB_SendString(uint8_t * str); + +#if 0 //TESTING - definitions for USB functions +void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle); +#endif + + +#endif /* _USB_CDC_VCOM_H_ */ diff --git a/source/adc.c b/source/adc.c new file mode 100644 index 0000000..172ab91 --- /dev/null +++ b/source/adc.c @@ -0,0 +1,1206 @@ +/* + * adc.c + * + * Created on: Mar 31, 2023 + * Author: Keith.Lloyd + */ + + +#include +#include + +#include "fsl_device_registers.h" +#include "fsl_debug_console.h" +#include "pin_mux.h" +#include "board.h" +#include "fsl_adc.h" +#include "fsl_clock.h" +#include "fsl_power.h" + +//Application includes +#include "timer.h" +#include "adc.h" +#include "frq.h" +#include "ports.h" +#include "measure.h" +#include "utils.h" +#include "hwFixes.h" + +#include "adc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define DEMO_ADC_BASE ADC0 +#define DEMO_ADC_SAMPLE_CHANNEL_NUMBER 7U +#define DEMO_ADC_CLOCK_DIVIDER 1U + + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void ADC_Configuration(void); + +extern uint8_t Port_State[]; +uint32_t what_val1,what_val2; +extern uint8_t frequency; +extern FREQUENCY_t freqArray[FREQ_MAX_NUM]; +float32_t volts_check; +extern float32_t Watts_Filt; + +extern HARDWARE_FIX_t hwf; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +ADC_t adc; +adc_result_info_t adcResultInfoStruct; + +/* + * Current measurement scaling vs frequency for LOW gain + * This is used to look up and interpolate current scaling + * Number of rows is not specified and can be any length + * Number of columns hard coded at 2: frequency, scale + */ +//Values from SN ONION using offset compensated single point @ 1000mA +float32_t currentTableLowGain[][ADC_TABLE_COLUMNS] = { +{ 256 , 0.002118644 } , +{ 360 , 0.001926782 } , +{ 512 , 0.001858736 } , +{ 640 , 0.001821494 } , +{ 1170 , 0.001785714 } , +{ 3140 , 0.001769912 } , +{ 8192 , 0.00177305 } , +{ 14000 , 0.001778726 } , +{ 20000 , 0.001786991 } , +{ 29430 , 0.001801802 } , +{ 32800 , 0.001806685 } , +{ 44500 , 0.001828154 } , +#if 1 //temporary change +{ 66100 , 0.001874414 * 1.28} ,//1.28 +{ 88800 , 0.001931621 * 1.84} ,//1.84 +{ 99000 , 0.001960784 * 1.58} ,//1.58 +{ 150000 , 0.00213858 } , +{ 200000 , 0.002364066 } , +#else //original values +{ 66100 , 0.001874414 } , +{ 88800 , 0.001931621 } , +{ 99000 , 0.001960784 } , +{ 150000 , 0.00213858 } , +{ 200000 , 0.002364066 } , +#endif + +}; + + +//High gain current table - Works same as low gain table. Values from SN ONION +float32_t currentTableHighGain[][ADC_TABLE_COLUMNS] = { +{ 256 , 5.27426E-05 } , +{ 360 , 4.92126E-05 } , +{ 512 , 4.64684E-05 } , +{ 640 , 4.54959E-05 } , +{ 1170 , 4.44444E-05 } , +{ 3140 , 4.42087E-05 } , +{ 8192 , 4.53309E-05 } , +{ 14000 , 4.77464E-05 } , +{ 20000 , 5.13663E-05 } , +{ 29430 , 5.9004E-05 } , +{ 32800 , 6.21891E-05 } , +{ 44500 , 7.47831E-05 } , +{ 66100 , 0.000103907 } , +{ 88800 , 0.000143349 } , +{ 99000 , 0.000165017 } , +{ 150000 , 0.000340136 } , +{ 200000 , 0.000702247 } , +}; + + + +/* + * Voltage measurement scaling vs frequency for LOW gain + * This is used to look up and interpolate current scaling + * Number of rows is not specified and can be any length + * Number of columns hard coded at 2: frequency, scale + */ +float32_t voltageTableLowGain[][ADC_TABLE_COLUMNS] = { +{ 256 , 0.182338205 } , +{ 360 , 0.165825101 } , +{ 512 , 0.159240069 } , +{ 640 , 0.155824916 } , +{ 870 , 0.147733711 } , +{ 1170 , 0.14674221 } , +{ 3140 , 0.146165644 } , +{ 5600 , 0.146347826 } , +{ 8192 , 0.146907216 } , +{ 14000 , 0.148426509 } , +{ 20000 , 0.148590381 } , +{ 29430 , 0.147376717 } , +{ 32800 , 0.152678378 } , +{ 44500 , 0.149038462 } , +{ 66100 , 0.179871383 } , +{ 88800 , 0.19462585 } , +{ 99000 , 0.202585604 } , +{ 150000 , 0.252818035 } , +{ 200000 , 0.312444837 } , +}; + + +//Values from SN ONION (208023) using offset compensated single point @ 500mA +float32_t currentTableLowGain208023[][ADC_TABLE_COLUMNS] = { +{ 256 , 0.00203666 } , +{ 360 , 0.00187970 } , +{ 512 , 0.00181818 } , +{ 640 , 0.00179856 } , +{ 1170 , 0.00175747 } , +{ 3140 , 0.00174459 } , +{ 8192 , 0.00174825 } , +{ 14000 , 0.00176056 } , +{ 20000 , 0.00177431 } , +{ 29430 , 0.00179856 } , +{ 32800 , 0.00180897 } , +{ 44500 , 0.00184502 } , +{ 66100 , 0.00192678 } , +{ 88800 , 0.00202840 } , +{ 99000 , 0.00208333 } , +{ 150000 , 0.00241313 } , +{ 200000 , 0.00286862 } , +}; + + +//High gain current table - Works same as low gain table. Values from SN ONION +float32_t currentTableHighGain208023[][ADC_TABLE_COLUMNS] = { +{ 256 , 0.00005171 } , +{ 360 , 0.00004817 } , +{ 512 , 0.00004695 } , +{ 640 , 0.00004600 } , +{ 1170 , 0.00004505 } , +{ 3140 , 0.00004464 } , +{ 8192 , 0.00004452 } , +{ 14000 , 0.00004460 } , +{ 20000 , 0.00004468 } , +{ 29430 , 0.00004492 } , +{ 32800 , 0.00004500 } , +{ 44500 , 0.00004533 } , +{ 66100 , 0.00004610 } , +{ 88800 , 0.00004707 } , +{ 99000 , 0.00004762 } , +{ 150000 , 0.00005086 } , +{ 200000 , 0.00005513 } , +}; + + +/* + * Voltage measurement scaling vs frequency for LOW gain + * This is used to look up and interpolate current scaling + * Number of rows is not specified and can be any length + * Number of columns hard coded at 2: frequency, scale + */ +float32_t voltageTableLowGain208023[][ADC_TABLE_COLUMNS] = { +{ 98 , 0.155877863 } , +{ 256 , 0.155877863 } , +{ 360 , 0.151178571 } , +{ 512 , 0.148143054 } , +{ 640 , 0.147208986 } , +{ 870 , 0.146820809 } , +{ 1170 , 0.14350365 } , +{ 3140 , 0.145137645 } , +{ 5600 , 0.146038095 } , +{ 8192 , 0.146697229 } , +{ 14000 , 0.146918994 } , +{ 20000 , 0.147096457 } , +{ 29430 , 0.145183742 } , +{ 32800 , 0.14886061 } , +{ 44500 , 0.150783939 } , +{ 66100 , 0.157547751 } , +{ 88800 , 0.163411541 } , +{ 99000 , 0.166688103 } , +{ 150000 , 0.187197232 } , +{ 200000 , 0.21567892 } , +}; + + + +//Values from SN 2060-00424 (208025) using offset compensated single point @ 500mA +float32_t currentTableLowGain208025[][ADC_TABLE_COLUMNS2] = { +{ 98 , 0.00124072 , 0.000 } , +{ 256 , 0.00124072 , 0.000 } , +{ 360 , 0.00116692 , 0.000 } , +{ 512 , 0.00112509 , 0.000 } , +{ 640 , 0.00110724 , 0.000 } , +{ 1170 , 0.00108541 , 0.000 } , +{ 3140 , 0.00107574 , 0.000 } , +{ 8192 , 0.00107574 , 0.000 } , +{ 14000 , 0.00107870 , 0.000 } , +{ 20000 , 0.00108242 , 0.000 } , +{ 29430 , 0.00108918 , 0.000 } , +{ 32800 , 0.00109183 , 0.000 } , +{ 44500 , 0.00110334 , 0.000 } , +{ 66100 , 0.00112671 * 1.1052 , 0.000 } , +{ 88800 , 0.00115831 * 1.1052, 0.000 } , +{ 99000 , 0.00117346 * 1.2413, 0.000 } , +{ 150000 , 0.00127086 * 1.6322 , 0.000 } , //1.327 +{ 200000 , 0.00140135 * 2.4123 , 0.000 } ,//2.805 +}; + + + + +//High gain current table. Values from SN 2060-00424 (208025) +//Scale values are Amps/count, offsets are in Amps +float32_t currentTableHighGain208025[][ADC_TABLE_COLUMNS2] = { +{ 98 , 0.00004951 , 0.000 } , +{ 256 , 0.00004951 , 0.000 } , +{ 360 , 0.00004662 , 0.000 } , +{ 512 , 0.00004499 , 0.000 } , +{ 640 , 0.00004437 , 0.000 } , +{ 1170 , 0.00004342 , 0.000 } , +{ 3140 , 0.00004296 , 0.000 } , +{ 8192 , 0.00004289 , 0.000 } , +{ 14000 , 0.00004289 , 0.000 } , +{ 20000 , 0.00004293 , 0.000 } , +{ 29430 , 0.00004304 , 0.000 } , +{ 32800 , 0.00004308 , 0.000 } , +{ 44500 , 0.00004327 , 0.000 } , +{ 66100 , 0.00004374 , 0.000 } , +{ 88800 , 0.00004437 , 0.000 } , +{ 99000 , 0.00004470 , 0.000 } , +{ 150000 , 0.00004685 , 0.000 } , +{ 200000 , 0.00004967 , 0.000 } , +}; + + + + + + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + +static void ADC_ClockPower_Configuration(void) +{ + /* SYSCON power. */ + POWER_DisablePD(kPDRUNCFG_PD_ADC0); /* Power on the ADC converter. */ + POWER_DisablePD(kPDRUNCFG_PD_VD7_ENA); /* Power on the analog power supply. */ + POWER_DisablePD(kPDRUNCFG_PD_VREFP_SW); /* Power on the reference voltage source. */ + POWER_DisablePD(kPDRUNCFG_PD_TEMPS); /* Power on the temperature sensor. */ + + CLOCK_EnableClock(kCLOCK_Adc0); /* SYSCON->AHBCLKCTRL[0] |= SYSCON_AHBCLKCTRL_ADC0_MASK; */ +} + +static void ADC_Configuration(void) +{ + adc_config_t adcConfigStruct; + adc_conv_seq_config_t adcConvSeqConfigStruct; + + /* Configure the converter. */ + adcConfigStruct.clockMode = kADC_ClockSynchronousMode; /* Using sync clock source. */ + adcConfigStruct.clockDividerNumber = DEMO_ADC_CLOCK_DIVIDER; + adcConfigStruct.resolution = kADC_Resolution12bit; + adcConfigStruct.enableBypassCalibration = false; + adcConfigStruct.sampleTimeNumber = 0U; + ADC_Init(DEMO_ADC_BASE, &adcConfigStruct); + + /* Use the temperature sensor input to channel 0. */ + ADC_EnableTemperatureSensor(DEMO_ADC_BASE, false); //was true + + + /* Enable channel DEMO_ADC_SAMPLE_CHANNEL_NUMBER's conversion in Sequence A. */ + adcConvSeqConfigStruct.channelMask = + (1U << 7) | (1 << 5) | (1 << 6) | ( 1 << 10 ) | (1 << 9) | ( 1 << 8) | (1 << 4) | (1 << 3) | ( 1 << 1) | (1 << 0); // added ID1 and 2 + //adcConvSeqConfigStruct.channelMask = + // (1 << 5) |(1 << 6); // ACCY1 and 2 only + adcConvSeqConfigStruct.triggerMask = 0U; + adcConvSeqConfigStruct.triggerPolarity = kADC_TriggerPolarityPositiveEdge; + adcConvSeqConfigStruct.enableSingleStep = false; + adcConvSeqConfigStruct.enableSyncBypass = false; + adcConvSeqConfigStruct.interruptMode = kADC_InterruptForEachSequence; + + ADC_SetConvSeqAConfig(DEMO_ADC_BASE, &adcConvSeqConfigStruct); + ADC_EnableConvSeqA(DEMO_ADC_BASE, true); /* Enable the conversion sequence A. */ + + /* Clear the result register. */ + ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE); + while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, 6, &adcResultInfoStruct)) //MAKE SURE THIS CHANNEL IS USED! + { + } + ADC_GetConvSeqAGlobalConversionResult(DEMO_ADC_BASE, &adcResultInfoStruct); +} + + + + +/* + * Get Current for LOW gain + * @arg input raw ADC counts + * @return + */ +static float32_t ScaleLowGainCurrent(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0;//scale factor for the frequency. input * scale = current + + //Get number of entries in table + uint32_t numEntries = sizeof(currentTableLowGain) / sizeof(float32_t) / 2; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in currentTableLowGain that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((currentTableLowGain[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(currentTableLowGain[highIndex][ADC_TABLE_FREQ] < targetFreq)//If targetFreq is too large, use the highest table value + { + scale = currentTableLowGain[numEntries][ADC_TABLE_SCALE]; + } + else if(currentTableLowGain[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = currentTableLowGain[highIndex][ADC_TABLE_SCALE]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + float32_t x = targetFreq; + float32_t x1 = currentTableLowGain[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = currentTableLowGain[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = currentTableLowGain[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = currentTableLowGain[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.currentClipping + adc.currentClipping = (input > ADC_LOW_GAIN_CURR_CLIP_THRESH); + + return (input * scale); +} + +/* + * Get Current for HIGH gain + * @arg input raw ADC counts + * @return + */ +static float32_t ScaleHighGainCurrent(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0;//scale factor for the frequency. input * scale = current + + //Get number of entries in table + uint32_t numEntries = sizeof(currentTableHighGain) / sizeof(float32_t) / 2; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in currentTableHighGain that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((currentTableHighGain[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(currentTableHighGain[highIndex][ADC_TABLE_FREQ] < targetFreq)//If targetFreq is too large, use the highest table value + { + scale = currentTableHighGain[numEntries][ADC_TABLE_SCALE]; + } + else if(currentTableHighGain[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = currentTableHighGain[highIndex][ADC_TABLE_SCALE]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + float32_t x = targetFreq; + float32_t x1 = currentTableHighGain[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = currentTableHighGain[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = currentTableHighGain[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = currentTableHighGain[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.currentClipping + adc.currentClipping = (input > ADC_HIGH_GAIN_CURR_CLIP_THRESH); + + return (input * scale); +} + +/* + * Get Voltage for LOW gain + * @arg input raw ADC counts + * @return + */ +static float32_t ScaleLowGainVoltage(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0;//scale factor for the frequency. input * scale = current + + //Get number of entries in table + uint32_t numEntries = sizeof(voltageTableLowGain) / sizeof(float32_t) / 2; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in voltageTableLowGain that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((voltageTableLowGain[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(voltageTableLowGain[highIndex][ADC_TABLE_FREQ] < targetFreq)//If targetFreq is too large, use the highest table value + { + scale = voltageTableLowGain[numEntries][ADC_TABLE_SCALE]; + } + else if(voltageTableLowGain[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = voltageTableLowGain[highIndex][ADC_TABLE_SCALE]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + float32_t x = targetFreq; + float32_t x1 = voltageTableLowGain[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = voltageTableLowGain[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = voltageTableLowGain[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = voltageTableLowGain[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.votageClipping + adc.voltageClipping = (input > ADC_LOW_GAIN_VOLT_CLIP_THRESH); + + return (input * scale); +} + + +/* + * Get Current for LOW gain + * @arg input raw ADC counts + * @return corrected current + */ +static float32_t ScaleLowGainCurrent208023(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0;//scale factor for the frequency. input * scale = current + + //Get number of entries in table + uint32_t numEntries = sizeof(currentTableLowGain208023) / sizeof(float32_t) / 2; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in currentTableLowGain208023 that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((currentTableLowGain208023[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(currentTableLowGain208023[highIndex][ADC_TABLE_FREQ] < targetFreq)//If targetFreq is too large, use the highest table value + { + scale = currentTableLowGain208023[numEntries][ADC_TABLE_SCALE]; + } + else if(currentTableLowGain208023[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = currentTableLowGain208023[highIndex][ADC_TABLE_SCALE]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + float32_t x = targetFreq; + float32_t x1 = currentTableLowGain208023[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = currentTableLowGain208023[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = currentTableLowGain208023[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = currentTableLowGain208023[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.currentClipping + adc.currentClipping = (input > ADC_LOW_GAIN_CURR_CLIP_THRESH); + + return (input * scale); +} + +/* + * Get Current for HIGH gain + * @arg input raw ADC counts + * @return corrected current + */ +static float32_t ScaleHighGainCurrent208023(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0;//scale factor for the frequency. input * scale = current + + //Get number of entries in table + uint32_t numEntries = sizeof(currentTableHighGain208023) / sizeof(float32_t) / 2; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in currentTableHighGain208023 that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((currentTableHighGain208023[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(currentTableHighGain208023[highIndex][ADC_TABLE_FREQ] < targetFreq)//If targetFreq is too large, use the highest table value + { + scale = currentTableHighGain208023[numEntries][ADC_TABLE_FREQ]; + } + else if(currentTableHighGain208023[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = currentTableHighGain208023[highIndex][ADC_TABLE_SCALE]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + float32_t x = targetFreq; + float32_t x1 = currentTableHighGain208023[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = currentTableHighGain208023[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = currentTableHighGain208023[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = currentTableHighGain208023[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.currentClipping + adc.currentClipping = (input > ADC_HIGH_GAIN_CURR_CLIP_THRESH); + + return (input * scale); +} + +/* + * Get Voltage for LOW gain 208023. Also used for 208025 + * @arg input raw ADC counts + * @return corrected voltage + */ +static float32_t ScaleLowGainVoltage208023(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0;//scale factor for the frequency. input * scale = current + + //Get number of entries in table + uint32_t numEntries = sizeof(voltageTableLowGain208023) / sizeof(float32_t) / 2; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in voltageTableLowGain208023 that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((voltageTableLowGain208023[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(voltageTableLowGain208023[highIndex][ADC_TABLE_FREQ] < targetFreq)//If targetFreq is too large, use the highest table value + { + scale = voltageTableLowGain208023[numEntries][ADC_TABLE_SCALE]; + } + else if(voltageTableLowGain208023[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = voltageTableLowGain208023[highIndex][ADC_TABLE_SCALE]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + float32_t x = targetFreq; + float32_t x1 = voltageTableLowGain208023[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = voltageTableLowGain208023[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = voltageTableLowGain208023[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = voltageTableLowGain208023[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.votageClipping + adc.voltageClipping = (input > ADC_LOW_GAIN_VOLT_CLIP_THRESH); + + return (input * scale); +} + +/* + * Get Current for LOW gain + * Apply scaling and offset from table + * @arg input raw ADC counts + * @return corrected current + */ +static float32_t ScaleLowGainCurrent208025(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0; //scale factor for the frequency. input * scale = current + float32_t offset = 0; //offset for the frequency in Amps + + //Get number of entries in table + uint32_t numEntries = sizeof(currentTableLowGain208025) / sizeof(float32_t) / 3; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 0 //TESTING - Use a specific frequency + targetFreq = 384; +#endif + + //Find the first index in currentTableLowGain208025 that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((currentTableLowGain208025[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(currentTableLowGain208025[highIndex][ADC_TABLE_FREQ] < targetFreq) //If targetFreq is too large, use the highest table value + { + scale = currentTableLowGain208025[numEntries][ADC_TABLE_SCALE]; + offset = currentTableLowGain208025[numEntries][ADC_TABLE_OFFSET]; + } + else if(currentTableLowGain208025[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = currentTableLowGain208025[highIndex][ADC_TABLE_SCALE]; + offset = currentTableLowGain208025[highIndex][ADC_TABLE_OFFSET]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + //scale + float32_t x = targetFreq; + float32_t x1 = currentTableLowGain208025[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = currentTableLowGain208025[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = currentTableLowGain208025[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = currentTableLowGain208025[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + + //OFFSET + y1 = currentTableLowGain208025[lowIndex][ADC_TABLE_OFFSET]; + y2 = currentTableLowGain208025[highIndex][ADC_TABLE_OFFSET]; + + offset = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.currentClipping + adc.currentClipping = (input > ADC_LOW_GAIN_CURR_CLIP_THRESH); + + return ((input * scale) + offset); +} + +/* + * Get Current for HIGH gain + * Apply scaling and offset from table + * @arg input raw ADC counts + * @return corrected current + */ +static float32_t ScaleHighGainCurrent208025(float32_t input) +{ + uint32_t lowIndex; //index of the closest table frequency below the target frequency + uint32_t highIndex; //index of the closest table frequency above the target frequency + float32_t scale = 0; //scale factor for the frequency. input * scale = current + float32_t offset = 0; //offset for the frequency in Amps + + //Get number of entries in table + uint32_t numEntries = sizeof(currentTableHighGain208025) / sizeof(float32_t) / 3; + + //Get target frequency + float32_t targetFreq = FREQ_GetFreqByIndex(frequency).frequency1; + +#if 1 //TESTING - Use a specific frequency + targetFreq = 5666; +#endif + + //Find the first index in currentTableHighGain208025 that is greater than or equal to targetFreq. This will be highIndex + highIndex = 0; + while((currentTableHighGain208025[highIndex][ADC_TABLE_FREQ] < targetFreq) && (highIndex < numEntries)) + { + highIndex++; + } + + + if(currentTableHighGain208025[highIndex][ADC_TABLE_FREQ] < targetFreq) //If targetFreq is too large, use the highest table value + { + scale = currentTableHighGain208025[numEntries][ADC_TABLE_SCALE]; + offset = currentTableHighGain208025[numEntries][ADC_TABLE_OFFSET]; + } + else if(currentTableHighGain208025[highIndex][ADC_TABLE_FREQ] == targetFreq) //If it's equal, use the value in the table + { + scale = currentTableHighGain208025[highIndex][ADC_TABLE_SCALE]; + offset = currentTableHighGain208025[highIndex][ADC_TABLE_OFFSET]; + } + else //else interpolate + { + lowIndex = highIndex-1; + + //scale + float32_t x = targetFreq; + float32_t x1 = currentTableHighGain208025[lowIndex][ADC_TABLE_FREQ]; + float32_t x2 = currentTableHighGain208025[highIndex][ADC_TABLE_FREQ]; + float32_t y1 = currentTableHighGain208025[lowIndex][ADC_TABLE_SCALE]; + float32_t y2 = currentTableHighGain208025[highIndex][ADC_TABLE_SCALE]; + + scale = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + + //OFFSET + y1 = currentTableHighGain208025[lowIndex][ADC_TABLE_OFFSET]; + y2 = currentTableHighGain208025[highIndex][ADC_TABLE_OFFSET]; + + offset = y1 + (x - x1) * (y2 - y1) / (x2 - x1); + } + + //Update adc.currentClipping + adc.currentClipping = (input > ADC_HIGH_GAIN_CURR_CLIP_THRESH); + + return ((input * scale) + offset); +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +/*! + * @brief Main function + */ +void ADC_Init2(void) +{ + /* Enable the power and clock for ADC. */ + ADC_ClockPower_Configuration(); + + + uint32_t adcClockFreq = 0U; + + /* Calibration after power up. */ + //DEMO_ADC_BASE->CTRL |= ADC_CTRL_BYPASSCAL_MASK; //This line skips adc offset calibration + adcClockFreq = CLOCK_GetFreq(kCLOCK_BusClk); + if (true == ADC_DoOffsetCalibration(DEMO_ADC_BASE, adcClockFreq)) //Also fixes ADCCLK (30MHZ max) + { + //PRINTF("ADC Calibration Done.\r\n"); + } + else + { + //PRINTF("ADC Calibration Failed.\r\n"); + while(1); + } + + + /* Configure the converter and work mode. */ + ADC_Configuration(); + + ADC_MeasureCurrentOffset(); + + //Start automatic ADC measurements (ctimer callback) + adc.measure = true; + } + +//Measure offset for current measurement channel +//Also output voltage channel +void ADC_MeasureCurrentOffset(void) +{ + //Measure current 8x and average + //Store as adc.I_Offset + + + Delay_Ticks(7); //70mS for current signal to stabilize + + uint32_t currentOffsetSum = 0; + uint32_t voltageOffsetSum = 0; + + uint32_t test[8]; + + for(uint32_t i = 0; i < 8; i++) //8 samples + { + ADC_Update(); + + Delay_Ticks(2); //20mS + + currentOffsetSum += adc.rawCurrent; + voltageOffsetSum += adc.rawVoltage; + + test[i] = adc.rawVoltage; //collect samples for testing + } + + adc.I_OffsetAdc = currentOffsetSum >> 3; //average of 8 samples + +#if ADC_USE_NOISE_OFFSET + adc.I_OffsetAdc -= ADC_NOISE_OFFSET_COUNTS; +#endif + +#if 0 //TESTING: Allow larger offset + if(abs((int32_t)(adc.I_OffsetAdc) - ADC_HALF_COUNTS) <= 50) +#else + if(abs((int32_t)(adc.I_OffsetAdc) - ADC_HALF_COUNTS) <= ADC_OFFSET_MAX_ERROR) //offset within 30 counts of mid scale +#endif + { + adc.iosOK = true; + } + else + { + adc.iosOK = false; //This will NOT be needed after keith removes the restart when USB is disconnected + } + + adc.V_OffsetAdc = voltageOffsetSum >> 3; //average of 8 samples + if(abs((int32_t)(adc.V_OffsetAdc) - ADC_HALF_COUNTS) <= ADC_OFFSET_MAX_ERROR) //offset within 30 counts of mid scale + { + adc.vosOK = true; + } + else + { + adc.vosOK = false; + } +} + + +/* + * Measure analog voltages and convert to quantities + * 100Hz sample rate + * Voltage and current are sampled and filtered at 100Hz + * All others are averages of 10 samples, so output at 10Hz + */ +void ADC_Update(void) +{ + //start conversion + ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE); + + // Wait for the converter to be done with the LAST channel (10) + while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, 10, &adcResultInfoStruct)); + + //Add measurement to adc struct + adc.V_BID_RAW += adcResultInfoStruct.result; //ch10 + + + //CURRENT + ADC_GetChannelConversionResult(DEMO_ADC_BASE, 0, &adcResultInfoStruct); + adc.rawCurrent = adcResultInfoStruct.result; + adc.I_OUT_RAW = adc.rawCurrent; + adc.I_OUT = adc.rawCurrent; //route raw current measurement to testIout + +#if 0 //TESTING: Don't use offset + adc.I_OUT -= ADC_HALF_COUNTS; +#else + if(adc.iosOK) {adc.I_OUT -= adc.I_OffsetAdc; } + else {adc.I_OUT -= ADC_HALF_COUNTS; } +#endif + + +#if 1 //Testing filtered raw value + adc.IRaw = adc.I_OUT; //ADC value with offset applied + adc.IRawFilt = adc.I_OUT; //filtered ADC counts w/ offset + adc.IRawFilt = FILT_ExpAvgF32(adc.IRawFilt,&adc.IRawDelay,0.02); +#endif + + +#if ADC_CORRECT_FOR_CURRENT_NOISE + //signal = SQRT( measurement^2 - noise^2) + if(adc.I_OUT > ADC_NOISE_OFFSET_COUNTS) //avoid sqrt(negative number) + { + adc.I_OUT = sqrtf(adc.I_OUT * adc.I_OUT - ADC_NOISE_OFFSET_COUNTS * ADC_NOISE_OFFSET_COUNTS); + } + else + { + adc.I_OUT = 0; + } + +#endif + + //Current Scaling + if((Port_State[MID_SR] & I_GAIN) > 0) //High Current Gain + { + if(hwf.mainPcbaPN >= 208025) + { + adc.I_OUT = ScaleHighGainCurrent208025(adc.I_OUT); + } + else if(hwf.mainPcbaPN == 208023) + { + adc.I_OUT = ScaleHighGainCurrent208023(adc.I_OUT); + } + else + { + adc.I_OUT = ScaleHighGainCurrent(adc.I_OUT); + } + } + else //Low Current Gain + { + if(hwf.mainPcbaPN >= 208025) + { + adc.I_OUT = ScaleLowGainCurrent208025(adc.I_OUT); + } + else if(hwf.mainPcbaPN == 208023) + { + adc.I_OUT = ScaleLowGainCurrent208025(adc.I_OUT); + } + else + { + adc.I_OUT = ScaleLowGainCurrent(adc.I_OUT); + } + } + + + //VOLTAGE + ADC_GetChannelConversionResult(DEMO_ADC_BASE, 1, &adcResultInfoStruct); + adc.rawVoltage = adcResultInfoStruct.result; + adc.V_OUT_RAW = adc.rawVoltage; + adc.V_OUT = adc.rawVoltage; + +#if 0 //TESTING: Don't use offset + adc.V_OUT -= ADC_HALF_COUNTS; +#else + if(adc.vosOK) {adc.V_OUT -= adc.V_OffsetAdc; } //use offset if in range + else {adc.V_OUT -= ADC_HALF_COUNTS; } //otherwise, use ADC_HALF_COUNTS +#endif + +#if 1 //Testing filtered raw value + adc.VRaw = adc.V_OUT; //ADC value with offset applied. Snapshot since V_OUT gets modified later + adc.VRawFilt = FILT_ExpAvgF32(adc.VRaw,&adc.VRawDelay,0.02); //filtered ADC counts w/ offset +#endif + +#if 1 + //Voltage Scaling + if((Port_State[BOTTOM_SR] & 0x80) > 0) //High Voltage Gain + { + //Not implemented + //adc.V_OUT = MeasureHighGainVoltage(adc.V_OUT); + } + else //Low Current Gain + { + if(hwf.mainPcbaPN >= 208023) //208023 and 208025 use the same table + { + adc.V_OUT = ScaleLowGainVoltage208023(adc.V_OUT); + } + else + { + adc.V_OUT = ScaleLowGainVoltage(adc.V_OUT); + } + } + +#else + adc.V_OUT = adc.V_OUT / 4096.0 * ADC_VREF; //scale to input voltage + //adc.V_OUT = adc.V_OUT * (804.0 + 10.0) / 10.0; //Scale for external voltage divider + + adc.V_OUT = CompensateVout(adc.V_OUT); //divider scaling sucked because AC... + + Measure_Volts(); +#endif + + + + ADC_GetChannelConversionResult(DEMO_ADC_BASE, 3, &adcResultInfoStruct); + adc.V_PSU_RAW += adcResultInfoStruct.result; + + ADC_GetChannelConversionResult(DEMO_ADC_BASE, 4, &adcResultInfoStruct); + adc.V_BAT_RAW += adcResultInfoStruct.result; + + while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, 5, &adcResultInfoStruct)); + adc.V_ID2_RAW += adcResultInfoStruct.result; + what_val2 = adcResultInfoStruct.result; + + while(!ADC_GetChannelConversionResult(DEMO_ADC_BASE, 6, &adcResultInfoStruct)); + adc.V_ID1_RAW += adcResultInfoStruct.result; + what_val1 = adcResultInfoStruct.result; + + ADC_GetChannelConversionResult(DEMO_ADC_BASE, 7, &adcResultInfoStruct); + adc.V_CHK_RAW += adcResultInfoStruct.result; + + ADC_GetChannelConversionResult(DEMO_ADC_BASE, 8, &adcResultInfoStruct); + adc.V_TMP_RAW += adcResultInfoStruct.result; + + + static uint32_t index = 0; + + //On nth measurement, calculate final variable and store in adc struct + if(++index >= ADC_NUM_AVERAGES) + { + index = 0; + + //CHANNEL 5 + adc.V_ID1 = adc.V_ID1_RAW / ADC_NUM_AVERAGES; //average + adc.V_ID1 = adc.V_ID1 / 4096.0 * ADC_VREF; //scaling + + //CHANNEL 6 + adc.V_ID2 = adc.V_ID2_RAW / ADC_NUM_AVERAGES; //average + adc.V_ID2 = adc.V_ID2 / 4096.0 * ADC_VREF; //scaling + + //CHANNEL 4 + adc.V_BAT = adc.V_BAT_RAW / ADC_NUM_AVERAGES; //average + adc.diag_bat = (adc.V_BAT); + + adc.V_BAT = adc.V_BAT / 4096.0 * 3.3;//ADC_VREF; //scaling +float temp; + + temp = 10000.0/59900.0; + adc.V_BAT = adc.V_BAT / temp; + + + //CHANNEL 3 + adc.V_PSU = adc.V_PSU_RAW / ADC_NUM_AVERAGES; //average + adc.V_PSU = adc.V_PSU / 4096.0 * ADC_VREF; //scaling + + //CHANNEL 8 + adc.V_TMP = adc.V_TMP_RAW / ADC_NUM_AVERAGES; //average + adc.V_TMP = adc.V_TMP / 4096.0 * ADC_VREF; //scaling + + //CHANNEL 10 - Battery ID + adc.V_BID = adc.V_BID_RAW / ADC_NUM_AVERAGES; //average + adc.V_BID = adc.V_BID / 4096.0 * 3.3;//ADC_VREF; //scaling + + //############# Added 2/5/24 + // adc.V_BID = adc.V_BID * 1.09; // additional scaling factor + + temp = 10000.0/59900.0; + adc.V_BID = adc.V_BID / temp; +//############## + + + //CHANNEL 7 + adc.V_CHK = adc.V_CHK_RAW / ADC_NUM_AVERAGES; //average + volts_check = adc.V_CHK; + + //scaling + + adc.V_PSU = adc.V_PSU * (1000+47.5)/47.5; // vratio; + + adc.V_CHK = adc.V_CHK / 4096.0 * ADC_VREF; //ADC bits & ref voltage +#if 1 //HV scaling + adc.V_CHK *= 2.0; //Divider in the LPF + adc.V_CHK += 0.7; //diode drop from rectifier + adc.V_CHK = adc.V_CHK * (402.0 + 3.92) / 3.92; //voltage divider +#else + adc.V_CHK *= 599.0 / 100.0; // Vin = Vadc* (R1+R2) / R2 + + adc.V_CHK *= 100; //rough scale factor needs to be re done later +#endif + //clear raw sums + adc.V_ID1_RAW = 0; + adc.V_ID2_RAW = 0; + adc.V_CHK_RAW = 0; + adc.V_PSU_RAW = 0; + adc.V_BAT_RAW = 0; + adc.V_TMP_RAW = 0; + adc.V_BID_RAW = 0; + + } + + + + // ######################################################################### + // New Filter Section + // float32_t FILT_ExpAvgF32(float32_t input, float32_t *temp, float32_t k) + float32_t k=0.02; + float32_t fast_k=0.0951; + + + adc.V_OUT_SlowFilt = FILT_ExpAvgF32(adc.V_OUT,&adc.V_OUT_Delay,k); + adc.I_OUT_SlowFilt = FILT_ExpAvgF32(adc.I_OUT,&adc.I_OUT_Delay,k); + + adc.V_OUT_FastFilt = FILT_ExpAvgF32(adc.V_OUT,&adc.V_OUT_FastDelay,fast_k); + adc.I_OUT_FastFilt = FILT_ExpAvgF32(adc.I_OUT,&adc.I_OUT_FastDelay,fast_k); + + if(adc.I_OUT_FastFilt > 0) + { + adc.Ohms_slowfilt = FILT_ExpAvgF32(adc.V_OUT_FastFilt/adc.I_OUT_FastFilt,&adc.Ohms_SlowDelay,k); + + if(isnanf(adc.Ohms_SlowDelay)) //Fix nan delay line + { + adc.Ohms_SlowDelay = 0.00001; + } + } + + + //########################################################################## + Watts_Filt = adc.V_OUT_FastFilt * (adc.I_OUT_FastFilt); +// Ohms_filt = adc.V_OUT_Filt/adc.I_OUT_Filt; + + +#if ADC_MEASUREMENT_TEST + //USAGE: Set adc.testCollectData = 1; to start data collection + + + //adc.testIout = FILT_ExpAvgF32(adc.testIout,&adc.testIoutDelay,fast_k); + //adc.testVout = FILT_ExpAvgF32(adc.testVout,&adc.testVoutDelay,fast_k); + + //Test data collection for measuring filter responses + static uint32_t idx = 0; + static bool measure = 1; + + if(adc.testCollectData && measure) + { + adc.testData1[idx] = adc.V_OUT_FastFilt; + adc.testData2[idx] = adc.I_OUT_FastFilt * 1000.0; //convert to mA + + idx++; + if(idx >= ADC_NUM_TEST) + { + adc.testCollectData = 0; //stop data collection + idx = 0; //reset idx + measure = 0; //DO NOT take another measurement (Don't clear and it'll measure again) + } + } + +#endif + +} + + + + + +/* Exponential averaging filter +* @input float32_t input +* @*temp float32_t storage for temporary variable +* @k float32_t filter constant k = 1 - exp(-1/T*Fs) +*/ +float32_t FILT_ExpAvgF32(float32_t input, float32_t *temp, float32_t k) +{ + return *temp += (input - *temp) * k; +} + + diff --git a/source/adc.h b/source/adc.h new file mode 100644 index 0000000..ba63eec --- /dev/null +++ b/source/adc.h @@ -0,0 +1,141 @@ +/* + * adc.h + * + * Created on: Mar 31, 2023 + * Author: Keith.Lloyd + */ + +#ifndef ADC_H_ +#define ADC_H_ + + +#include "arm_math.h" + +#define ADC_NUM_AVERAGES 10 //number of samples averaged for measurements + +#define ADC_VREF 3.3 //3.23 //ADC reference voltage = 3v3 supply (Measured @ 3.23v) +#define ADC_HALF_COUNTS 2048 //half of max ADC reading +#define ADC_OFFSET_MAX_ERROR 30 //maximum allowed error for ADC offset measurement + + + + +#define ADC_USE_NOISE_OFFSET 1 //Use a standard noise offset +#define ADC_NOISE_OFFSET_COUNTS 13 //ADC offset due to precision rectifier noise conversion to DC + +#define ADC_CORRECT_FOR_CURRENT_NOISE 1 //Correct current measurement for noise from the precision rectifier + + +#define ADC_USE_CURRENT_TABLE 1 //Use the current table to scale current measurements +#define ADC_TABLE_COLUMNS 2 //number of columns for current and voltage tables +#define ADC_TABLE_COLUMNS2 3 //number of columns for current and voltage tables with offset +#define ADC_TABLE_FREQ 0 //frequency column in current and voltage tables +#define ADC_TABLE_SCALE 1 //scale column in current and voltage tables +#define ADC_TABLE_OFFSET 2 //offset column in current tables + + +#define ADC_LOW_GAIN_CURR_CLIP_THRESH 1050 //LOW gain current measurement clipping threshold (in ADC counts) +#define ADC_HIGH_GAIN_CURR_CLIP_THRESH 800 //HIGH gain current measurement clipping threshold (in ADC counts) + +#define ADC_LOW_GAIN_VOLT_CLIP_THRESH 1050 +#define ADC_HIGH_GAIN_VOLT_CLIP_THRESH 800 + +#define ADC_MEASUREMENT_TEST 0 //Collect ADC data @ adc sampleRate when triggered. FOR TESTING + +#if ADC_MEASUREMENT_TEST +#define ADC_NUM_TEST 40 //10mS samples +#endif + +typedef struct { + bool measure; //measure ADC values in timer ISR + //current measurement offset + bool iosOK; //current offset within limits, use it + uint32_t I_OffsetAdc; //Current channel offset - measured @ startup + uint32_t rawCurrent; //raw current measurement used for offset + + //Voltage measurement offset + bool vosOK; //voltage offset error within limits, use it + uint32_t V_OffsetAdc; //VOltage channel offset - measured @ startup + uint32_t rawVoltage; //raw voltage measurement used for offset + + bool currentClipping; //Current measurement clip status (for LOW and HIGH gains) + bool voltageClipping; //Voltage measurement clip status (for LOW and HIGH gains) + + + //storage for raw ADC values (0 - 4096). Sum up samples + uint32_t V_ID1_RAW; //ch5 Port A identifier. + uint32_t V_ID2_RAW; //ch6 Port B identifier + uint32_t V_CHK_RAW; //ch7 Incoming voltage eg. 110V + uint32_t V_PSU_RAW; //ch3 Power supply monitor + uint32_t V_TMP_RAW; //ch8 External temperature + uint32_t I_OUT_RAW; // ch0 Current out + uint32_t V_OUT_RAW; // ch1 Volts Out + uint32_t V_BAT_RAW; //ch4 Battery Voltage + uint32_t V_BID_RAW; //ch10 Battery ID + + //Storage for scaled value - float32_t + float32_t V_ID1; + float32_t V_ID2; + float32_t V_CHK; + float32_t V_BID; + float32_t V_BAT; + float32_t I_OUT; + float32_t V_OUT; + float32_t V_TMP; + float32_t V_PSU; + + //Storage for filtered values - float32_t + float32_t I_OUT_SlowFilt; + float32_t V_OUT_SlowFilt; + float32_t V_OUT_FastFilt; + float32_t I_OUT_FastFilt; + float32_t Ohms_slowfilt; + + + // Delay Lines for filters + float32_t V_OUT_Delay; + float32_t I_OUT_Delay; + float32_t V_OUT_FastDelay; + float32_t I_OUT_FastDelay; + float32_t Ohms_FastDelay; + float32_t Ohms_SlowDelay; + +#if 1 //ADC raw current filtering - This is for testing + float32_t IRaw; + float32_t IRawFilt; + float32_t IRawDelay; +#endif + +#if 1 //ADC raw voltage filtering - This is for testing + float32_t VRaw; + float32_t VRawFilt; + float32_t VRawDelay; +#endif + uint32_t diag_bat; // commented test value for battery diagnosis + //TESTING - faster current measurement without averaging +#if ADC_MEASUREMENT_TEST + bool testCollectData; + uint32_t testIndex; + //storage for sampled data + float32_t testData1[ADC_NUM_TEST]; + float32_t testData2[ADC_NUM_TEST]; + + + float32_t testIout; + float32_t testIoutDelay; + + float32_t testVout; + float32_t testVoutDelay; + +#endif + +}ADC_t; + + +void ADC_Init2(void); +void ADC_MeasureCurrentOffset(void); +void ADC_Update(void); +float32_t FILT_ExpAvgF32(float32_t input, float32_t *temp, float32_t k); + + +#endif /* ADC_H_ */ diff --git a/source/amps.c b/source/amps.c new file mode 100644 index 0000000..5705769 --- /dev/null +++ b/source/amps.c @@ -0,0 +1,165 @@ +/* + * amps.c + * + * Created on: Mar 6, 2023 + * Author: Keith.Lloyd + */ + +#include +#include +#include "amps.h" +#include "utils.h" +#include "psu_ctrl.h" +#include "timer.h" +#include "ports.h" +#include "frq.h" +#include "taps.h" + +extern uint8_t frequency, Power_Level,old_freq, psu_failed; +extern uint8_t Port_State[]; +extern uint16_t PSU_Check_tmr; +extern uint8_t Dds_Pot_Val[],catch_up_flag,Suspend_Step_Chk,step_count; + + +void Enable_Amplifier(void) +{ + + // Port_State[BOTTOM_SR] |= 0b00000100; // for testing only select TAP1 TODO remove + + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + { + +// if(freqArray[old_freq].frequency1 >= MAX_DTYPE && old_freq !=DUMMY_FRQ) + if(freqArray[old_freq].frequency1 > freqArray[frequency].frequency1 && old_freq !=DUMMY_FRQ) + { + + Reduce_Kick_Back();// prevent the HF amp demand from setting the LF amp. +//# Power_Level = 0; +// catch_up_flag = true; + Suspend_Step_Chk = false; + step_count = 0; + +// Check_Pot_Val(); // reload max_pot + + Port_State[BOTTOM_SR] &= TAPS_OFF_MASK; // Set taps to safe + Port_State[BOTTOM_SR] |= TAP2_LF_ON; + + + } + + + + // Enable D'type amp +// Port_State[1] = 0x22; // U13 + Port_State[BOTTOM_SR] &= ~AMP_AB_SW; // Disable AB amp + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + Delay_Ticks(5); + + Port_State[BOTTOM_SR] &= AMP_PSU_ON; // switch AMP PSU on + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + Delay_Ticks(5); + + if((Check_For_Clamp())) + Set_PSU_Voltage(V_42V); + else + Set_PSU_Voltage(V_36V); // TODO V_36V Set PSU Pot to D amp max + + Delay_Ticks(1); + + PSU_Check_tmr = PSU_DELAY; + + Port_State[BOTTOM_SR] |= SLCT_AMPD_ON; // Enable switch to allow power to driver + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + Delay_Ticks(5); + + + Port_State[MID_SR] |= DAMP_EN_ON; // Enable driver + + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register +// Port_State[MID_SR] &= ~DAMP_EN_ON; // TODO Disable driver remove later + +// Select_Amp_Xfrmr_Rly(LFA_LFX); // Select LF amp and LF transformer + } + else + { + +// if(freqArray[old_freq].frequency1 <= MAX_DTYPE && old_freq !=DUMMY_FRQ) + if(freqArray[old_freq].frequency1 <= MAX_DTYPE && old_freq !=DUMMY_FRQ) + + { + + Reduce_Kick_Back(); +// Power_Level = 0; + Suspend_Step_Chk = false; + step_count = 0; + + } + + if((Check_For_Clamp())) + Set_PSU_Voltage(V_27V); + else + Set_PSU_Voltage(V_24V); // TODO V_36V Set PSU Pot to D amp max + +// Set_PSU_Voltage(MAX_AB_PSU); // Set PSU Pot to AB amp max + + + // Disable D amp//enable AB amp + Port_State[BOTTOM_SR] &= ~AMP_AB_SW; // Disable AB amp + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + + Port_State[BOTTOM_SR] &= AMP_PSU_ON; // switch AMP PSU on + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register +#if 1 + psu_failed = false; + if(!Wait_For_Psu(32.0)) // wait for PSU to drop + { + psu_failed = true; + Delay_Ticks(100); + } +#endif + Port_State[MID_SR] &= ~DAMP_EN_ON; // Disable driver + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + + Port_State[BOTTOM_SR] &= ~SLCT_AMPD_ON; // Disable D Amps PSU Switch + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + Delay_Ticks(5); + + if(!psu_failed) + { + Port_State[BOTTOM_SR] |= AMP_AB_SW; // Enable AB AMP Power Switch. + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + } + + + } + +} + +void All_Amps_Off(void) // shut down Amplifiers DC for broadcast mode +{ + Port_State[BOTTOM_SR] &= ~AMP_AB_SW; // Power down AB amp + Port_State[BOTTOM_SR] &= ~SLCT_AMPD_ON; // Power down D amp + Port_State[TOP_SR] &= ~ANT_AMP_SW; // Power down D amp + + Port_State[MID_SR] &= ~DAMP_EN_ON; // Disable driver DC Driver + Port_State[MID_SR] &= ~ANT_AMP_EN; // Disable driver Antenna Driver + + + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + +} + +void Check_Pot_Val(void) +{ + if(Dds_Pot_Val[1] > freqArray[frequency].max_pot) // if the old value is > max for new freq + { + Dds_Pot_Val[0] = 0; // address + Dds_Pot_Val[1] = freqArray[frequency].max_pot; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); // reduce amplitude + + } + + + + +} diff --git a/source/amps.h b/source/amps.h new file mode 100644 index 0000000..ac6b49f --- /dev/null +++ b/source/amps.h @@ -0,0 +1,20 @@ +/* + * amps.h + * + * Created on: Mar 6, 2023 + * Author: Keith.Lloyd + */ + +#ifndef AMPS_H_ +#define AMPS_H_ + +#define MAX_DTYPE 44500 +#define MAX_LOW_FRQ 83078 +#define AMP_D_SW 0b00000010 //AMPD_ON U13 D1 +#define AMP_AB_SW 0b00000001 // AMPAB_ON U13 D0 ACTIVE LOW + + +void Enable_Amplifier(void); +void All_Amps_Off(void); // shut down Amplifiers DC connections +void Check_Pot_Val(void); +#endif /* AMPS_H_ */ diff --git a/source/battery.c b/source/battery.c new file mode 100644 index 0000000..21811f1 --- /dev/null +++ b/source/battery.c @@ -0,0 +1,181 @@ +/* + * Battery.c + * + * Created on: Jun 10, 2022 + * Author: Keith.Lloyd + */ +#include "arm_math.h" +#include "utils.h" +#include "battery.h" +#include "adc.h" +#include "main.h" +#include "timer.h" +#include "lcd.h" +#include "display.h" +#include "safety_key.h" +#include "amps.h" +#include "ports.h" +#include "hwFixes.h" + +uint8_t Bat_Type; + +extern uint8_t Task, Error; +extern ADC_t adc; +extern float32_t Max_Power_Limit; +extern uint16_t Low_Bat_timer; +extern uint16_t battery; +//uint16_t Bat_Level[] = {100,200,300,400,500,125,225,325,425,525}; // Battery life levels 5 Alkaline and 5 Lithium. +extern HARDWARE_FIX_t hwf; + + +bool Compare_With_Limit(float32_t V1 ,float32_t V2,float32_t limit) +{ +float32_t tolerance; + +bool result; + + result = false; + + tolerance = limit / 100.0; + tolerance = tolerance + 1.0; + tolerance = tolerance * V2; + + if(V1 < tolerance) + result = true; + + tolerance = limit /100.0; + tolerance = 1.0 - tolerance; + tolerance = tolerance * V2; + + if(V1 > tolerance) + result = true; + + return(result); +} + + + +void Check_Bat_Id(void) +{ +float32_t Battery; +float32_t Bat_Mid_Point; + + + if(adc.V_BID > LITHIUM_MID_POINT) // BAT_ID = 0V for lithium, mid point for Alkaline + { + if(Compare_With_Limit(adc.V_BID,adc.V_BAT,5.0)) + { + Bat_Type = EXT_DC; + Max_Power_Limit = 10.0; // Limit max power to 5W. + + } + else + { + Bat_Type = ALKALINE; + Max_Power_Limit = 5.0; // Limit max power to 5W. + + Battery = adc.V_BAT; // Calculate mid-point for alkaline + Bat_Mid_Point = Battery / 2; + if ((adc.V_BID > (Bat_Mid_Point * 1.1)) || (adc.V_BID < (Bat_Mid_Point * 0.9)) ) // Check if not at mid-point + Bat_Type = BAT_ERROR; // indicate battery insertion error + } + } + else + { + Bat_Type = LITHIUM; + Max_Power_Limit = 10.0; // Limit max power to 5W. 1.7 = 10.0 1.7X = 25.0 + } + + if(Bat_Type == BAT_ERROR) + { + LCD_Clear(); + Task=BAT_INSERTION_ERROR; + + while(1) + { + safe_key(); + Display_Update(); + Delay_Ticks(10); + } + + } + +} + +void Chk_Bat_Level(void) +{ + if(Bat_Type == LITHIUM) + { + if(hwf.vBattCap_021) + Test_Bat_Level(CF_LITHIUM_CUT_OFF); + else + Test_Bat_Level(LITHIUM_CUT_OFF); + } + else + { + if(hwf.vBattCap_021) + Test_Bat_Level(CF_ALKALINE_CUT_OFF); + else + Test_Bat_Level(ALKALINE_CUT_OFF); + } +} + +void Test_Bat_Level(float32_t Bat_Cut_Off) +{ + if(adc.V_BAT < Bat_Cut_Off && Task != LOW_BATTERY_TASK) + { + if(Task != PWR_OFF_TASK) + { + All_Amps_Off(); + Disable_BC(); //Disable BC + Select_Estop(ON); + + Delay_Ticks(25); //wait for battery voltage to rise + +// if(adc.V_BAT <= Bat_Cut_Off) +// { + Task = LOW_BATTERY_TASK; + Low_Bat_timer = DELAY_2S; +// } +// else +// { + // Task = FATAL_ERROR_TASK; + // Error = 2; + // } + + } + } +} + +float32_t Adjust_Battery_For_Load() // adjust to true battery voltage due to battery cable + //drop and current demand +{ // assumed frequency and efficiency may need table for frequency adjust + float32_t battery; //assumes taps are correct + battery = adc.V_BAT; + if(Bat_Type == LITHIUM) + { + if(adc.I_OUT_SlowFilt < DEMAND1) + battery = battery + 1.1; + else if(adc.I_OUT_SlowFilt < DEMAND2) + battery = battery + 1.2; + else if(adc.I_OUT_SlowFilt < DEMAND3) + battery = battery + 1.3; + else if(adc.I_OUT_SlowFilt < DEMAND4) + battery = battery + 1.4; + else if(adc.I_OUT_SlowFilt < DEMAND5) + battery = battery + 1.5; + else if(adc.I_OUT_SlowFilt < DEMAND6) + battery = battery + 1.6; + else + battery = battery + 2; + + return(battery); + } + + else + { + + } + +} + diff --git a/source/battery.h b/source/battery.h new file mode 100644 index 0000000..2384295 --- /dev/null +++ b/source/battery.h @@ -0,0 +1,95 @@ +/* + * battery.h + * + * Created on: Mar 1, 2023 + * Author: Keith.Lloyd + */ + +#ifndef BATTERY_H_ +#define BATTERY_H_ +#define ALKALINE_VAL 300 +#define LITHIUM_MID_POINT 1.0 // mid point tap = 0V for lithium + +//#define BATTERY_NINETY 15.2 +//#define BATTERY_FULL 16.4 +//#define BATTERY_3QUARTERS 15.0 +//#define BATTERY_FIFTY 14.4 +//#define BATTERY_1QUARTER 14.28 +//#define BATTERY_EMPTY 12.3 + +#define L_BATTERY_FULL 16.4 // Cap fitted Lithium +#define L_BATTERY_NINETY 16.0 +#define L_BATTERY_3QUARTERS 15.6 +#define L_BATTERY_FIFTY 14.8 +#define L_BATTERY_1QUARTER 14.0 +#define L_BATTERY_1EIGTH 13.6 +#define L_BATTERY_EMPTY 12.3 + +#define NCL_BATTERY_FULL 14.94 // No Cap Fitted Lithium +#define NCL_BATTERY_NINETY 14.62 +#define NCL_BATTERY_3QUARTERS 14.3 +#define NCL_BATTERY_FIFTY 13.68 +#define NCL_BATTERY_1QUARTER 13.05 +#define NCL_BATTERY_1EIGTH 12.72 +#define NCL_BATTERY_EMPTY 11.72 + + + +#define A_BATTERY_FULL 12.0 +#define A_BATTERY_NINETY 11.85 +#define A_BATTERY_3QUARTERS 10.72 +#define A_BATTERY_FIFTY 10.24 +#define A_BATTERY_1QUARTER 9.76 +#define A_BATTERY_1EIGTH 9.20 +#define A_BATTERY_EMPTY 9.15 + +#define NCA_BATTERY_FULL 11.61 +#define NCA_BATTERY_NINETY 11.17 +#define NCA_BATTERY_3QUARTERS 10.95 +#define NCA_BATTERY_FIFTY 10.42 +#define NCA_BATTERY_1QUARTER 9.86 +#define NCA_BATTERY_1EIGTH 9.44 +#define NCA_BATTERY_EMPTY 8.98 + +#define LITHIUM_CUT_OFF 11.69 // No Cap fitted +#define ALKALINE_CUT_OFF 9.2 // No Cap fitted + +#define CF_LITHIUM_CUT_OFF 12.28 //Cap fitted +#define CF_ALKALINE_CUT_OFF 9.0 // Cap fitted + +#define DEMAND1 0.1 // current demand +#define DEMAND2 0.2 +#define DEMAND3 0.3 +#define DEMAND4 0.4 +#define DEMAND5 0.5 +#define DEMAND6 0.6 + + +typedef enum { + ALKALINE, + LITHIUM, + BAT_ERROR, + EXT_DC +}BAT_STACK_t; + +void Check_Bat_Id(void); +void Chk_Bat_Level(void); +void Test_Bat_Level(float32_t Bat_Cut_Off); +float32_t Adjust_Battery_For_Load(); +bool Compare_With_Limit(float32_t V1 ,float32_t V2,float32_t limit); + +/*typedef enum { + I_OUT1, + V_OUT1, + N_USED, + PSU_MON, + VBAT_MON, + ID1, + ID2, + V_CHK, + TEMP_SENSOR, + VBUS, + BAT_ID +}ADC_STACK_t; +*/ +#endif /* BATTERY_H_ */ diff --git a/source/display.c b/source/display.c new file mode 100644 index 0000000..69ddecf --- /dev/null +++ b/source/display.c @@ -0,0 +1,1102 @@ +/* + * display.c + * + * Created on: Jun 17, 2022 + * Author: Keith.Lloyd + */ + + +#include +#include +#include +#include +#include +#include +#include "fsl_gpio.h" + +#include "spi.h" +#include "lcd.h" +#include "display.h" +#include "frq.h" +#include "battery.h" +#include "utils.h" +#include "Graphics/splash.h" + +#include "Graphics/graphicsLibrary.h" +#include "Fonts/fontLibrary.h" +#include "Graphics/testIconsMono.h" +#include "Graphics/icons.h" +#include "adc.h" +#include "mode.h" +#include "ports.h" +#include "timer.h" +#include "taps.h" +#include "main.h" +#include "hwFixes.h" +#include "menu.h" +#include "System\system.h" + +uint8_t tempString[40]; // Todo move +uint8_t frequency = 0; +uint32_t new_freq; +float32_t Volts = 96.345; + +uint16_t Bcast_Pwr_Dispval[5] = {0,25,50,75,100}; // broadcast value to display. +uint32_t Safety_Select = false; +float32_t Milli_amps; +float32_t Watts_Filt; + +extern SYSTEM_DATA_t sys; + +extern ADC_t adc; +extern uint8_t Bat_Type, Cur_Mode, Task, Over_Voltage_Flag, Error; +extern MODE_REC_t mode_Array[]; +extern uint8_t Bcast_Pwr_Level; +extern uint8_t Power_Level,Test_Mode,LD_Flag; +extern float32_t volts_check; +extern uint8_t Port_State[]; +extern uint8_t Dds_Pot_Val[]; +extern HARDWARE_FIX_t hwf; +extern float32_t test_val2; + +extern uint32_t systemTime; +extern ClampData_t clampData; + +void Display_Bcast(void) +{ + if(Cur_Mode == BROADCAST) + { + sprintf(tempString,"%d%%",Bcast_Pwr_Dispval[Bcast_Pwr_Level]); + FL_DrawString( tempString, LCD_X_MID, 60, font18Bold, LCD_DRAW_SET, FL_ALIGN_CENTER); + Display_Level(Bcast_Pwr_Level); + } + +} +void Display_USB(void) +{ + GL_DrawMonoBitmap(usbIconSmall, LCD_X_MID-16, LCD_Y_MID, LCD_DRAW_SET); +} + + + +void Display_Splash(void) +{ + LCD_Clear(); + + + // if(Read_Model_type() != LEICA) +// GL_DrawMonoBitmapCentered(UMLogo68x64, LCD_DRAW_SET); +// else +// GL_DrawMonoBitmapCentered(leicaSplash, LCD_DRAW_SET); + +// LCD_Update(); + + + switch(Read_Model_type()) + { + case UMAG: + GL_DrawMonoBitmapCentered(UMLogo68x64, LCD_DRAW_SET); + break; + + case LEICA: + GL_DrawMonoBitmapCentered(leicaSplash, LCD_DRAW_SET); + break; + + case GLAND: + GL_DrawMonoBitmapCentered(goldenlandLogo98x60, LCD_DRAW_SET); + break; + + default: + GL_DrawMonoBitmapCentered(UMLogo68x64, LCD_DRAW_SET); + break; + + + + } + LCD_Update(); + +} + +uint8_t Read_Model_type() +{ + + if(strncmp(sys.modelName,"10W",3) == 0 ) + return(UMAG); + if(strncmp(sys.modelName,"DE100",5) == 0 ) + return(LEICA); + if(strncmp(sys.modelName,"GT3",3) == 0 ) + return(GLAND); + if(strncmp(sys.modelName,"Nexus",5) == 0 ) + return(UMAG); + if(strncmp(sys.modelName,"Tx10",4) == 0 ) + return(UMAG); + + +} +void Display_Volts(void) +{ + + + if((( Cur_Mode != BROADCAST) && (!Is_Clamp_Detected()))) + Display_Line_Voltage(); + else + { + if((Is_Clamp_Detected()) && (Test_Mode) && (Cur_Mode != BROADCAST)) + { + Display_Clamp_Power(); + } + } + + + +#if 0// testing the new averager + sprintf(tempString,"%.2fmA",adc.I_OUT_SlowFilt* 1000.0); + FL_DrawString( tempString, X_POS_MA+50, 18, font16Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); +#endif + + + +} +void Display_Line_Voltage(void) +{ + + Volts = adc.V_OUT_FastFilt; + + if(Volts < 0) + Volts = 0; + + sprintf(tempString,"%.0fVa",Volts); + FL_DrawString( tempString, X_POS_MA+90, 48, font16Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + GL_DrawLine( X_POS_MA+90, 74, X_POS_MA+130, 74, 3, LCD_DRAW_SET); + +} + +void Display_Clamp_Power(void) +{ + + float power = 0.0f; + + Volts = adc.V_OUT_FastFilt; + if(Volts < 0) + Volts = 0; + + power = Volts * adc.I_OUT_FastFilt; + + sprintf(tempString,"%.1fW", power); + FL_DrawString( tempString, LCD_X_MID -10, 60, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + +} + +void Display_Clamp_Volts(void) +{ + + Volts = adc.V_OUT_FastFilt; + if(Volts < 0) + Volts = 0; + + sprintf(tempString,"%.0fVb",Volts); + FL_DrawString( tempString, LCD_X_MID -10, 60, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + +} + +void Display_Current(void) +{ + + + if(( Cur_Mode != BROADCAST) && (!Is_Clamp_Detected())) + Display_Line_Current(); + else + { + if((Is_Clamp_Detected()) && (Test_Mode)) + Display_Line_Current(); + } + +} + +void Display_Ohms(void) +{ + if(( Cur_Mode != BROADCAST) && (!Is_Clamp_Detected())) + Display_Line_Ohms(); + else + { + if((Is_Clamp_Detected()) && (Test_Mode)) + Display_Line_Ohms(); + } + +} + +void Display_Line_Current(void) +{ + + Milli_amps = adc.I_OUT_SlowFilt; + + + if(Milli_amps < 0) + Milli_amps = 0; + + sprintf(tempString,"%.0fmA =",Milli_amps * 1000.0); + FL_DrawString( tempString, X_POS_MA+85, 60, font16Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + +} + +void Display_Line_Ohms(void) +{ + if(adc.Ohms_slowfilt < 0) + adc.Ohms_slowfilt = 0; + + + if(adc.Ohms_slowfilt < 10000) + { + sprintf(tempString,"%.0fΩ",adc.Ohms_slowfilt); + FL_DrawString( tempString, X_POS_MA+90, 72, font16Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + else + { + if(adc.Ohms_slowfilt < 100000) + { + sprintf(tempString,"%.0f kΩ",adc.Ohms_slowfilt/1000); + FL_DrawString( tempString, X_POS_MA+90, 72, font16Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + else + FL_DrawString( "- - - Ω", X_POS_MA+90, 72, font16Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + } +} + +void Display_Watts(void) +{ + if(( Cur_Mode != BROADCAST) && (!Is_Clamp_Detected())) + { + + if(Watts_Filt < 0) + Watts_Filt = 0; + + sprintf(tempString,"%.1fW",Watts_Filt ); + FL_DrawString( tempString, LCD_X_MAX+4, LCD_Y_MAX-40, font16Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + } +} + +void Display_Line_Watts(void) +{ + if(Watts_Filt < 0) + Watts_Filt = 0; + + sprintf(tempString,"%.1fW",Watts_Filt ); + FL_DrawString( tempString, LCD_X_MAX+4, LCD_Y_MAX-40, font16Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + +} + +void Display_BroadCastSignal(void) +{ + + +} + +void Display_Battery(void) +{ + if(Bat_Type != EXT_DC) + { + if(hwf.vBattCap_021) + Display_Battery_CF(); + else + Display_Battery_NC(); + } + + else + Display_EXT_DC(); +} + +void Display_EXT_DC(void) +{ + sprintf(tempString, "EXT_DC"); + FL_DrawString(tempString, 0, LCD_Y_MAX - 22, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + +} + +void Display_Battery_NC() // No Cap +{ + +// battery = Adjust_Battery_For_Load(); //adjust battery dependant on load and Vdrop + + + if (Bat_Type == LITHIUM) + { + if(adc.V_BAT >= NCL_BATTERY_NINETY) + Draw_Battery(STACKS_4); + else if(adc.V_BAT > NCL_BATTERY_3QUARTERS) + Draw_Battery(STACKS_3); + else if(adc.V_BAT > NCL_BATTERY_FIFTY) + Draw_Battery(STACKS_2); + else if(adc.V_BAT > NCL_BATTERY_1QUARTER) + Draw_Battery(STACKS_1); + else if (adc.V_BAT > NCL_BATTERY_1EIGTH) + Draw_Battery(STACKS_EMPTY); + else + Display_Bat_Frame_Flash(); + } + + else + { + + if(adc.V_BAT >= NCA_BATTERY_NINETY) + Draw_Battery(STACKS_4); + else if(adc.V_BAT > NCA_BATTERY_3QUARTERS) + Draw_Battery(STACKS_3); + else if(adc.V_BAT > NCA_BATTERY_FIFTY) + Draw_Battery(STACKS_2); + else if(adc.V_BAT > NCA_BATTERY_1QUARTER) + Draw_Battery(STACKS_1); + else if (adc.V_BAT > NCA_BATTERY_1EIGTH) + Draw_Battery(STACKS_EMPTY); + else + Display_Bat_Frame_Flash(); + + + } +} + +void Display_Battery_CF() // cap fitted +{ + +// battery = Adjust_Battery_For_Load(); //adjust battery dependant on load and Vdrop + + + if (Bat_Type == LITHIUM) + { + if(adc.V_BAT >= L_BATTERY_NINETY) + Draw_Battery(STACKS_4); + else if(adc.V_BAT > L_BATTERY_3QUARTERS) + Draw_Battery(STACKS_3); + else if(adc.V_BAT > L_BATTERY_FIFTY) + Draw_Battery(STACKS_2); + else if(adc.V_BAT > L_BATTERY_1QUARTER) + Draw_Battery(STACKS_1); + else if (adc.V_BAT > L_BATTERY_1EIGTH) + Draw_Battery(STACKS_EMPTY); + else + Display_Bat_Frame_Flash(); + } + + else + { + + if(adc.V_BAT >= A_BATTERY_NINETY) + Draw_Battery(STACKS_4); + else if(adc.V_BAT > A_BATTERY_3QUARTERS) + Draw_Battery(STACKS_3); + else if(adc.V_BAT > A_BATTERY_FIFTY) + Draw_Battery(STACKS_2); + else if(adc.V_BAT > A_BATTERY_1QUARTER) + Draw_Battery(STACKS_1); + else if (adc.V_BAT > A_BATTERY_1EIGTH) + Draw_Battery(STACKS_EMPTY); + else + Display_Bat_Frame_Flash(); + + + } +} + + +void Draw_Battery(uint8_t stacks) +{ + uint16_t battx = 0; + uint16_t batty = LCD_Y_MAX - GL_GetMonoBitmapHeight(battery0)+3; + + switch(stacks) + { + case STACKS_4: + GL_DrawMonoBitmap(battery4, battx, batty, LCD_DRAW_SET); // Draw all 4 + GL_DrawMonoBitmap(battery3, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery2, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery1, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery0, battx, batty, LCD_DRAW_SET); + + break; + + case STACKS_3: + GL_DrawMonoBitmap(battery3, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery2, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery1, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery0, battx, batty, LCD_DRAW_SET); + + break; + + case STACKS_2: + GL_DrawMonoBitmap(battery2, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery1, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery0, battx, batty, LCD_DRAW_SET); + + break; + + case STACKS_1: + GL_DrawMonoBitmap(battery1, battx, batty, LCD_DRAW_SET); + GL_DrawMonoBitmap(battery0, battx, batty, LCD_DRAW_SET); + + break; + + case STACKS_0: + GL_DrawMonoBitmap(battery0, battx, batty, LCD_DRAW_SET); + + break; + } +} + +void Display_Bat_Frame_Flash(void) +{ + static uint8_t flasher = 0; + + uint16_t battx = 0; + uint16_t batty = LCD_Y_MAX - GL_GetMonoBitmapHeight(battery0)+3; + + if(flasher > 3) + { + GL_DrawMonoBitmap(battery0, battx, batty, LCD_DRAW_SET); + flasher = 0; + + } + else + flasher++; +} + +void Display_Wireless(uint8_t wireless) +{ + if(wireless) + GL_DrawMonoBitmap(txControl, LCD_X_MID-90, LCD_Y_MAX-22, LCD_DRAW_SET); +} + +void Display_Mode(uint8_t Con_Mode1) +{ +uint8_t What; // What to display + +// Con_Mode1 = Cur_Mode; // Currently indexed is the selected. + + // mod_Array[Cur_Mode].Select = false; + + //What = mode_Array[Cur_Mode].Plugged; + + switch(Con_Mode1) // Where to draw + { + case BROADCAST: + //GL_DrawMonoBitmap(border60x60, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + + // GL_DrawMonoBitmap(clampIcon2, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + // GL_DrawMonoBitmap(directConnectIcon3, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw +// GL_DrawMonoBitmap(directConnectIcon5, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + GL_DrawMonoBitmap(inductionIcon, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + + // GL_DrawMonoBitmap(lamp, LCD_X_MAX-28,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + + break; + + case PORT1_A: // ACtually PORT 2 + What = ACCY_GetConnectedAccessory(1); + // What = ID_TX_DUAL_DIRECT; // Test + if(What == ID_CLAMP || What == ID_CLAMP2) + GL_DrawMonoBitmap(clampIcon2, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); + if(What == ID_TX_SINGLE_DIRECT) + GL_DrawMonoBitmap(directConnectIcon5, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + if(What == ID_TX_DUAL_DIRECT) + GL_DrawMonoBitmap(directConnectIcon3, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + + if (What == ID_TX_DUAL_DIRECT) + FL_DrawString("1A", LCD_X_MAX-40, LCD_Y_MIN+5, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + else + FL_DrawString("1", LCD_X_MAX-40, LCD_Y_MIN, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + + break; + + case PORT1_B: //can only be lower half of Dual +// GL_DrawMonoBitmap(box_unchecked, LCD_X_MAX-44, LCD_Y_MIN + 24, LCD_DRAW_SET); +// GL_DrawRectangle(189, 0, 239, 49, 1, LCD_DRAW_SET); +// GL_DrawRectangle(179, 0, 239, 59, 1, LCD_DRAW_SET); + GL_DrawMonoBitmap(directConnectIcon3, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + FL_DrawString("1B", LCD_X_MAX-40, LCD_Y_MIN+29, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + + break; + + case PORT2_A: + What = ACCY_GetConnectedAccessory(2); + + if(What == ID_CLAMP || What == ID_CLAMP2) + GL_DrawMonoBitmap(clampIcon2, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); + if(What == ID_TX_SINGLE_DIRECT) + GL_DrawMonoBitmap(directConnectIcon5, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + + if(What == ID_TX_DUAL_DIRECT) + GL_DrawMonoBitmap(directConnectIcon3, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + + if (What == ID_TX_DUAL_DIRECT) + FL_DrawString("2A", LCD_X_MAX-40, LCD_Y_MIN+5, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + else + FL_DrawString("2", LCD_X_MAX-40, LCD_Y_MIN, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + + break; + case PORT2_B: //can only be lower half of Dual + GL_DrawMonoBitmap(directConnectIcon3, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); // Always draw + FL_DrawString("2B", LCD_X_MAX-40, LCD_Y_MIN+29, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + + break; + } +} + + + + +#if 0 +void Display_Connection(CON_MODE_t Con_Output1, CON_MODE_t Con_Output2) +{ + + switch(Con_Output1) + { + case A1: + FL_DrawString("A1", LCD_X_MAX -48, LCD_Y_MIN , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case A2: + FL_DrawString("A2", LCD_X_MAX-48, LCD_Y_MIN , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case B1: + FL_DrawString("B1", LCD_X_MAX-48, LCD_Y_MIN , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case B2: + FL_DrawString("B2", LCD_X_MAX-48, LCD_Y_MIN , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + } + + switch(Con_Output2) + { + case A1: + FL_DrawString("A1", LCD_X_MAX -48, LCD_Y_MIN+48 , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case A2: + FL_DrawString("A2", LCD_X_MAX-48, LCD_Y_MIN+48 , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case B1: + FL_DrawString("B1", LCD_X_MAX-48, LCD_Y_MIN+48 , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case B2: + FL_DrawString("B2", LCD_X_MAX-48, LCD_Y_MIN+48 , font14Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + + } + + + +} +#endif + +void Display_Level(PWR_MODE_t Level) +{ +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); + + // Print all bars + + switch(Level) + { + case LEVEL0: +// GL_DrawMonoBitmap(power0, LCD_X_MID-60, LCD_Y_MID-64, LCD_DRAW_SET); + GL_DrawRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + +// GL_DrawFilledRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + + // GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); //second +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); //third +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); //fourth + + break; + + case LEVEL1: +// GL_DrawMonoBitmap(power1, LCD_X_MID-60, LCD_Y_MID-64, LCD_DRAW_SET); +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); + GL_DrawRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + + GL_DrawFilledRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + break; + + case LEVEL2: +// GL_DrawMonoBitmap(power2, LCD_X_MID-60, LCD_Y_MID-64, LCD_DRAW_SET); +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); + GL_DrawRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + + GL_DrawFilledRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + GL_DrawFilledRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + break; + + case LEVEL3: +// GL_DrawMonoBitmap(power3, LCD_X_MID-60,LCD_Y_MID-64, LCD_DRAW_SET); +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); + GL_DrawRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + + GL_DrawFilledRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + GL_DrawFilledRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + GL_DrawFilledRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1,LCD_DRAW_SET); //first + + break; + + default: +// GL_DrawMonoBitmap(power4, LCD_X_MID-60, LCD_Y_MID-64, LCD_DRAW_SET); +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); + GL_DrawRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + GL_DrawRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, 2, LCD_DRAW_SET); //first + + GL_DrawFilledRectangle(70, LCD_Y_MIN+15, 90, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + GL_DrawFilledRectangle(94, LCD_Y_MIN+15, 114, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + GL_DrawFilledRectangle(118, LCD_Y_MIN+15, 138, LCD_Y_MIN + 1,LCD_DRAW_SET); //first + GL_DrawFilledRectangle(142, LCD_Y_MIN+15, 162, LCD_Y_MIN + 1, LCD_DRAW_SET); //first + + } +} + +void Display_Backlight(uint8_t Back_Light) +{ + if (Back_Light) + GL_DrawMonoBitmap(lamp, LCD_X_MIN+0, LCD_Y_MIN+30, LCD_DRAW_SET); +} + +void Display_High_Voltage(void) +{ + GL_DrawMonoBitmap(highVoltageIcon, LCD_X_MIN+0, LCD_Y_MIN+0, LCD_DRAW_SET); +} + +void Display_Frequency(uint8_t frequency) +{ +// if (freqArray[frequency].frequency2 > 0) +// Display_CD_Symbol(); // place a CD symbol in front in correct position + + if(LD_Flag) + Display_CD_Symbol(); // place a CD symbol in front in correct position + + if (freqArray[frequency].frequency1 < 1000) + sprintf(tempString,"%dHz", freqArray[frequency].frequency1); + + if (freqArray[frequency].frequency1 < 10000 && freqArray[frequency].frequency1 >= 1000 ) + sprintf(tempString,"%.2fkHz", (float32_t)freqArray[frequency].frequency1/1000.0 ); + + if (freqArray[frequency].frequency1 < 100000 && freqArray[frequency].frequency1 >= 10000) + sprintf(tempString,"%.1fkHz",(float32_t)freqArray[frequency].frequency1/1000 ); + + if (freqArray[frequency].frequency1 > 100000) +// { +// if(freqArray[frequency].frequency1 == 131148) +// sprintf(tempString,"%.0fKHz",(float32_t)132000/1000 ); +// else + sprintf(tempString,"%.0fKHz",(float32_t)freqArray[frequency].frequency1/1000 ); +// } + + FL_DrawString( tempString, LCD_X_MAX+6, LCD_Y_MAX - 22, font18Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); +} + +void Display_CD_Symbol(void) +{ +// uint16_t ldy = LCD_Y_MAX - GL_GetMonoBitmapHeight(ld2)+3; + + + if (freqArray[frequency].frequency1 < 1000) + GL_DrawMonoBitmap(ld, LCD_X_MAX - 90, LCD_Y_MAX - 16, LCD_DRAW_SET); + else + GL_DrawMonoBitmap(ld, LCD_X_MAX - 106, LCD_Y_MAX - 16, LCD_DRAW_SET); +} + + +void Test_Frequency(void) +{ + if(freqArray[frequency].enabled) + Display_Frequency(frequency); + + frequency = Next_Frequency(frequency); +} + +void Display_Bye_Bye() +{ + LCD_Clear(); + Display_Splash(); +// FL_DrawString("Bye Bye", 52, LCD_Y_MIN + 49 , font16Bold, LCD_DRAW_XOR, FL_ALIGN_LEFT); + LCD_Update(); +} + +void Display_Danger_Menu() +{ + static uint32_t count = 0; + + if (count < 3) + { + count++; +// FL_DrawString("Extreme Voltage! ", 16, LCD_Y_MIN + 19 , font16Bold, LCD_DRAW_XOR, FL_ALIGN_LEFT); + GL_DrawMonoBitmap(dangerousVoltage68x60, LCD_X_MIN+88, LCD_Y_MIN+30, LCD_DRAW_SET); + + } + else + count = 0; + +} + +void Display_Estop(void) +{ + static uint32_t count_msg_tmr = 0; + + if(count_msg_tmr < 3) + { + FL_DrawString("Unsafe Voltage Detected !", 16, LCD_Y_MIN + 19 , font16Bold, LCD_DRAW_XOR, FL_ALIGN_LEFT); + count_msg_tmr++; + + } + + else + { + FL_DrawString(" ", 32, 16, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + count_msg_tmr = 0; + } + +} +void Display_Measurements(void) +{ + Display_Volts(); + Display_Current(); + Display_Ohms(); + Display_Watts(); +} +void Display_Normal(void) +{ +// Display_Measurements(); 3/11/24 + + if(Power_Level > 0) + Display_Currently_Selected(); + + Display_Battery(); + + Display_Mode(Cur_Mode); + + Display_Wireless(0); + if(Cur_Mode == BROADCAST) + Display_Bcast(); + else + Display_Level(Power_Level); // Display bars + + Display_Frequency(frequency); + + if(Test_Mode) + FL_DrawString("Test", LCD_X_MIN, LCD_Y_MIN, font16Bold, LCD_DRAW_XOR, FL_ALIGN_LEFT); + +} +void Display_Flash_Bat(void) + +{ + static uint32_t flash_count = 0; + + if(flash_count < 3) + { + LCD_Clear(); //clear the frameBuffer + FL_DrawString("Low Battery", X_POS_MA+85, LCD_Y_MIN + 48 , font16Bold, LCD_DRAW_XOR, FL_ALIGN_CENTER); + flash_count++; + } + else + { +// FL_DrawString(" ", 32, 16, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + LCD_Clear(); //clear the frameBuffer + flash_count = 0; + } +} + +void Display_Bat_Error(void) +{ + static uint32_t count_msg_tmr = 0; + + if(count_msg_tmr < 3) + { + FL_DrawString("Battery Insertion Error!", 16, LCD_Y_MIN + 19 , font16Bold, LCD_DRAW_XOR, FL_ALIGN_LEFT); + count_msg_tmr++; + } + else + { + FL_DrawString(" ", 16, LCD_Y_MIN +19, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + count_msg_tmr = 0; + } +} + +uint8_t Display_Taps(void) +{ + uint8_t temp; + + temp = Port_State[BOTTOM_SR] & 0b00011000; // preserve the taps + + switch(temp) + { + case TAP1_LF_ON: + temp = 1; + break; + + case TAP2_LF_ON: + temp = 2; + + break; + + case TAP3_LF_ON: + temp = 3; + + break; + + case TAP4_LF_ON: + temp = 4; + break; + + default: + temp = 5; + } + return(temp); +} + + +void Display_Currently_Selected(void) +{ + + + switch (Cur_Mode) + { + + case BROADCAST: + break; + + case PORT1_A: + if(ACCY_GetConnectedAccessory(1) == ID_CLAMP || ACCY_GetConnectedAccessory(1) == ID_CLAMP2) + //Display_Clamp_Volts(); + Display_Clamp_Power(); + else + Display_Line_Measurements(); + break; + + case PORT1_B: + if(ACCY_GetConnectedAccessory(1) == ID_CLAMP || ACCY_GetConnectedAccessory(1) == ID_CLAMP2) + //Display_Clamp_Volts(); + Display_Clamp_Power(); + else + Display_Line_Measurements(); + + break; + + case PORT2_A: + if(ACCY_GetConnectedAccessory(2) == ID_CLAMP || ACCY_GetConnectedAccessory(2) == ID_CLAMP2) + //Display_Clamp_Volts(); + Display_Clamp_Power(); + else + Display_Line_Measurements(); + + break; + + case PORT2_B: + if(ACCY_GetConnectedAccessory(2) == ID_CLAMP || ACCY_GetConnectedAccessory(2) == ID_CLAMP2) + //Display_Clamp_Volts(); + Display_Clamp_Power(); + else + Display_Line_Measurements(); + + break; + + + } + +} + +void Display_Line_Measurements(void) +{ + Display_Line_Voltage(); + Display_Line_Current(); + Display_Line_Ohms(); + Display_Line_Watts(); + +} + + +void Display_Tx_Status(void) +{ + + switch(Task) + { + case SAFETY_TASK: + Display_Danger_Menu(); + break; + + case FATAL_ERROR_TASK: + Display_Fatal_Error(); + break; + + case ESTOP_TASK: + Display_Estop(); + break; + + case LOW_BATTERY_TASK: + Display_Flash_Bat(); + break; + + case BAT_INSERTION_ERROR: + LCD_Clear(); //clear the frameBuffer + Display_Bat_Error(); + break; + + default: + Display_Normal(); + + } + + +} + +void Display_USB_Status(void) +{ + if(GPIO_PinRead(GPIO,1,6)) + Display_USB(); +// GL_DrawMonoBitmap(usbIconSmall, LCD_X_MID, 30, LCD_DRAW_SET); + +} + +void Display_Over_Voltage_Status(void) +{ + static uint32_t county = 0; + + if(Over_Voltage_Flag) + { + if(county<3) + { + county++; + Display_High_Voltage(); // TODO Display correct graphic once agreed + } + else + county = 0; + } +} + +void Display_Fatal_Error(void) +{ + sprintf(tempString,"Error %d", Error); + FL_DrawString(tempString, 80, 90, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); +} + +void Display_OnScreen_Diagnostics(void) +{ + sprintf(tempString, "POT %d", Dds_Pot_Val[1]); + FL_DrawString(tempString, 0, 30, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + if((Port_State[MID_SR] & 0x40) > 0) + sprintf(tempString, "HI", Dds_Pot_Val[1]); + else + sprintf(tempString, "LO"); + + FL_DrawString(tempString, 0, 50, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + if(hwf.vBattCap_021) + sprintf(tempString, "CF"); + else + sprintf(tempString, "CNF"); + FL_DrawString(tempString, 0, 0, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + sprintf(tempString,"Taps %d", Display_Taps()); + FL_DrawString(tempString, 0, 20, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + sprintf(tempString,"B %.2fV",adc.V_BAT); + FL_DrawString(tempString, 0, 60, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + +// sprintf(tempString,"VPSU %.2fV", adc.V_PSU); +// FL_DrawString(tempString, 0, 80, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + sprintf(tempString,"C %.2fV",adc.V_CHK); + FL_DrawString(tempString, 0, 70, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + // sprintf(tempString,"Time: %d", systemTime); + // FL_DrawString(tempString, 0, 80, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + //if (clampData.slope > 0) + { + float t = sqrtf(clampData.impedance * 10.0f); + + //sprintf(tempString,"Vmax: %f", t); + sprintf(tempString,"Target: %f", clampData.targetPower); + FL_DrawString(tempString, 0, 80, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + +// sprintf(tempString,"R %.2f",adc.IRawFilt); +// FL_DrawString(tempString, 0, 80, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + +} + +//if(GPIO_PinRead(GPIO,1,6)) +// GL_DrawMonoBitmap(usbIconSmall, LCD_X_MID, 30, LCD_DRAW_SET); + +// if (countx >= 25) +// countx = 0; +// else +// countx++; +// +// if (!GPIO_PinRead(GPIO, 0, 31)) +// { +// FL_DrawString("Key0", 12, 80, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); +// } + + +// tunaX += tunaXStep; +// if(tunaX > tunaXMax) +// { +// tunaX = 0; +// } + + + +// char a[] = "29KHz"; +// char *ptr1 = a; + +// char *frqptr[26] = {" 98Hz","128Hz","263Hz","440Hz","512Hz","560Hz","577Hz","640Hz","815Hz","870Hz", +// "940Hz","1.02KHz","1.17KHz","3.14KHz","4.09KHz","6.00KHz","8.01KHz","9.82KHz","29.4KHz", +// "32.7KHz","44.6KHz","65.5KHz","83.0KHz","131KHz","200KHz","480KHz"}; + + +// GL_DrawLine(1, 1, 33, 33, 3, LCD_DRAW_SET); +// GL_DrawFilledRectangle(160, 0, 200, 40, LCD_DRAW_SET); + +// FL_DrawString("Over Voltage!", tunaX, 80, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + +// GL_DrawMonoBitmap(anchor, 160, 20, LCD_DRAW_SET); + +// GL_DrawFilledRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, LCD_DRAW_XOR); + +// GL_DrawRectangle(00, LCD_Y_MAX-40, 40, LCD_Y_MAX, 1, LCD_DRAW_SET); +// GL_DrawRectangle(50, LCD_Y_MAX-30, 80, LCD_Y_MAX, 1, LCD_DRAW_SET); + + // FL_DrawString("8 KHz", LCD_X_MAX, LCD_Y_MAX - FL_GetFontHeight(font18Bold), font18Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); +//# FL_DrawString( ptr1, LCD_X_MAX, LCD_Y_MAX - FL_GetFontHeight(font18Bold), font18Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); +// FL_DrawString( frqptr[countx], LCD_X_MAX, LCD_Y_MAX - FL_GetFontHeight(font18Bold), font18Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); +// FL_DrawString( frqptr[countx], LCD_X_MAX, LCD_Y_MAX - 22, font18Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); +// GL_DrawRectangle(0, 0, LCD_X_MAX, LCD_Y_MAX, 1, LCD_DRAW_SET); // Outer Border + + + + + + + +// sprintf(tempString, "1: %.2f", adc.V_ID1); +// FL_DrawString( tempString, 0, 0, font12Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); +// sprintf(tempString, "2: %.2f", adc.V_ID2); +// FL_DrawString( tempString, 0, 15, font12Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); +// sprintf(tempString, "%d", Power_Level); // Display number +// FL_DrawString(tempString, 120, 00, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + +// Display_Backlight(1); +//SetBacklightPower(1); + + diff --git a/source/display.h b/source/display.h new file mode 100644 index 0000000..af945ba --- /dev/null +++ b/source/display.h @@ -0,0 +1,103 @@ +/* + * display.h + * + * Created on: Jun 17, 2022 + * Author: Keith.Lloyd + */ + +#ifndef DISPLAY_H_ +#define DISPLAY_H_ + +#define X_POS_MA 36 +#define X_POS_FRQ 80 + +#define STACKS_4 4 +#define STACKS_3 3 +#define STACKS_2 2 +#define STACKS_1 1 +#define STACKS_0 0 +#define STACKS_EMPTY STACKS_0 +//#define LEICA 1 // temporary replace with Enum + +typedef enum{ + UMAG, + LEICA, + GLAND +} D_MODE_t; + +typedef enum { + DIRECT_CON, + DCLAMP, + BCAST, + DUAL_DIRECT + +} OP_MODE_t; + +typedef enum { + A1, + A2, + B1, + B2 + +} CON_MODE_t; + + +typedef enum { + LEVEL0, + LEVEL1, + LEVEL2, + LEVEL3, + LEVEL4, + LEVEL_MAX +} PWR_MODE_t; + + + +void Display_Volts(void); +void Display_Current(void); +void Display_Ohms(void); +void Display_Watts(void); +void Display_Battery(void); +void Display_Battery_NC(void); +void Display_Battery_CF(void); +void Display_Mode(uint8_t Con_Mode1); +void Display_Wireless(uint8_t wireless); +void Display_Level(PWR_MODE_t Level); +void Display_Connection(CON_MODE_t Con_Output1, CON_MODE_t Con_Output2); +void Display_Level(PWR_MODE_t Level); +void Display_Backlight(uint8_t Back_Light); +void Display_Frequency(uint8_t frequency); +void Display_CD_Symbol(void); +void Display_Bye_Bye(void); +void Display_Splash(void); +void Display_Bcast(void); +void Display_Danger_Menu(void); +void Display_Measurements(void); +void Display_Normal(void); +void Display_Flash_Bat(void); +void Display_Estop(void); +void Display_Bat_Error(void); +void Display_High_Voltage(void); +void Display_Line_Ohms(void); +void Display_Line_Current(void); +void Display_Clamp_Volts(void); +void Display_Clamp_Power(void); +void Display_Line_Voltage(void); +void Display_Clamp_Volts(void); +void Display_USB(void); +uint8_t Display_Taps(void); +void Display_Bat_Frame_Flash(void); +void Display_Currently_Selected(void); +void Display_Line_Measurements(void); +void Display_Fatal_Error(void); +void Display_OnScreen_Diagnostics(void); +void Display_Over_Voltage_Status(void); +void Display_USB_Status(void); +void Display_Tx_Status(void); +void Draw_Battery(uint8_t stacks); +uint8_t Read_Model_type(); +void Display_EXT_DC(void); + +#endif /* DISPLAY_H_ */ + + diff --git a/source/eeprom.c b/source/eeprom.c new file mode 100644 index 0000000..aa71e40 --- /dev/null +++ b/source/eeprom.c @@ -0,0 +1,415 @@ +/* + * eeprom.c + * + * Created on: Jun 10, 2022 + * Author: Keith.Lloyd + */ + + +#include + +#include "fsl_spi.h" +#include +#include + +#include "m95512.h" +#include "spi.h" +#include "timer.h" +#include "System/system.h" +#include "bootloader.h" +#include "frq.h" +#include "eeprom.h" +#include "Fonts/translate.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define EE_BUFFER_SIZE (8) //size of buffer for send/receive 4-byte words +#define EE_BYTES_PER_WORD (4) + +#define EE_HEADER_NUM_BYTES (3) //number of bytes in m95512 header - instruction, addrH, addrL + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +extern SYSTEM_DATA_t sys; +extern spi_transfer_t SPI0_xfer; +extern uint8_t frequency; +extern TIMER_t tmr; +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + +static bool EE_Busy(void) +{ + uint8_t sr; + M95512_ReadStatus(&sr); + return sr & EE_SR_WIP; +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +/* + * Load data from EEPROM + */ +void EE_LoadData(void) +{ + //Check for blank EEPROM + EE_ReadBytes(EE_SYS_MFG, sys.manufacturer, SYS_INFO_LENGTH); + if(sys.manufacturer[0] == 0xff) + { + SYS_LoadFactoryDefaults(); + EE_SaveData(); + } + + //System Data + EE_ReadBytes(EE_SYS_MFG, sys.manufacturer, SYS_INFO_LENGTH); + EE_ReadBytes(EE_SYS_MODEL_NUMBER, sys.modelNumber, SYS_INFO_LENGTH); + EE_ReadBytes(EE_SYS_MODEL_NAME, sys.modelName, SYS_INFO_LENGTH); + EE_ReadBytes(EE_SYS_SERIAL, sys.serialNumber, SYS_INFO_LENGTH); + EE_ReadBytes(EE_SYS_MFG_DATE, sys.mfgDate, SYS_INFO_LENGTH); + + EE_ReadMemoryUINT32(BL_VERSION_EEPROM_ADDR, &sys.bootloaderVersion); + + EE_ReadMemoryUINT32(EE_DATA_LANGUAGE, &sys.language); + if(sys.language > NUM_TRANSLATION_STRINGS) + sys.language = LANG_ENGLISH; + + EE_ReadBytes(EE_DATA_FREQUENCY, &frequency, 1); //1 byte only + + EE_ReadBytes(EE_DATA_TIMER, &tmr.autoShutdown, 1); //timer 1 byte only + if(tmr.autoShutdown >= SD_NUM) + tmr.autoShutdown = SD_1_HR; + + if(frequency > FREQ_MAX_NUM) + frequency = 1; + + +} + +bool EE_LoadFrequencies(void) +{ + bool success = true; + + //Load frequencies + uint32_t tempNumFreqs = EE_ReadUINT32(EE_FREQ_NUM); + if((tempNumFreqs > FREQ_MAX_NUM) || (tempNumFreqs == 0)) //Error check numFreqs + { + return false; + } + else + { + for(uint32_t i = 0; i < tempNumFreqs; i++) + { + uint32_t packedFreq = EE_ReadUINT32(EE_FREQ_START + EE_BYTES_PER_WORD * i); + FREQ_AddPackedFrequency(packedFreq); + } + } + + return success; +} + +/* + * Save data to EEPROM + */ +void EE_SaveData(void) +{ + EE_WriteBytes(EE_SYS_MFG, sys.manufacturer, SYS_INFO_LENGTH); + EE_WriteBytes(EE_SYS_MODEL_NUMBER, sys.modelNumber, SYS_INFO_LENGTH); + EE_WriteBytes(EE_SYS_MODEL_NAME, sys.modelName, SYS_INFO_LENGTH); + EE_WriteBytes(EE_SYS_SERIAL, sys.serialNumber, SYS_INFO_LENGTH); + EE_WriteBytes(EE_SYS_MFG_DATE, sys.mfgDate, SYS_INFO_LENGTH); + + EE_WriteUINT32(EE_DATA_LANGUAGE, sys.language); + + EE_WriteBytes(EE_DATA_FREQUENCY, &frequency, 1); + + EE_WriteBytes(EE_DATA_TIMER, &tmr.autoShutdown, 1); // Save Power down timer status + + //Save Frequencies + uint32_t numFreqs = FREQ_GetNumFrequencies(); + EE_WriteUINT32(EE_FREQ_NUM, numFreqs); + for(uint32_t i = 0; i < numFreqs; i++) + { + EE_WriteUINT32(EE_FREQ_START + EE_BYTES_PER_WORD * i, FREQ_GetPackedFrequency(i)); + } +} + +/* + * Erase ALL EEPROM data except for bootloader data + * Write 0xff to all + */ +void EE_EraseAllData(void) +{ + for(uint32_t i = EE_PAGE_SYS; i < EE_PAGE_DATA; i++) //EE_DATA_END; i++) + { + EE_WriteUINT32(i, 0xffffffff); + } +} + +void EE_Test(void) +{ + uint32_t data = 0; + uint32_t TEST_START_ADDR = 256; + uint32_t numWords = 64; + + uint32_t writeData[numWords]; //write to EEPROM + uint32_t readData[numWords]; //read from EEPROM + + static uint32_t numGood = 0; + static uint32_t numBad = 0; + + //Init writeData + for(uint32_t i = 0; i < numWords; i++) + { + writeData[i] = i; + } + + + + //Write data to EEPROM + for(uint32_t i = 0; i < numWords; i++) + { + data = i; + EE_WriteMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &writeData[i]); + } + + + //Read back + memset(readData, 0, sizeof(readData)); + + for(uint32_t i = 0; i < numWords; i++) + { + EE_ReadMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &readData[i]); + } + + //COMPARE DATA + if(0 == memcmp(writeData, readData, numWords)) + { + numGood++; + } + else + { + numBad++; + } + + + + + //Write zeros to EEPROM + for(uint32_t i = 0; i < numWords; i++) + { + data = 0; + EE_WriteMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &data); + } + + //Read back + memset(readData, 0, sizeof(readData)); + + for(uint32_t i = 0; i < numWords; i++) + { + EE_ReadMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &readData[i]); + } + +} + +void EE_TestBytes(void) +{ + uint32_t data = 0; + uint32_t TEST_START_ADDR = 256; + uint32_t numBytes = 128; + + uint8_t writeData[numBytes]; //write to EEPROM + uint8_t readData[numBytes]; //read from EEPROM + + static uint32_t numGood = 0; + static uint32_t numBad = 0; + + //Init writeData + for(uint32_t i = 0; i < numBytes; i++) + { + writeData[i] = i; + } + + //Write data to EEPROM + EE_WriteBytes(TEST_START_ADDR, writeData, numBytes); + + + //Read back + memset(readData, 0, numBytes); + + EE_ReadBytes(TEST_START_ADDR, readData, numBytes); + + //COMPARE DATA + if(0 == memcmp(writeData, readData, numBytes)) + { + numGood++; + } + else + { + numBad++; + } + + + + + //Write zeros to EEPROM + memset(writeData, 0, sizeof(writeData)); + EE_WriteBytes(TEST_START_ADDR, writeData, numBytes); + + //Read back + memset(readData, 0, sizeof(readData)); + EE_ReadBytes(TEST_START_ADDR, readData, numBytes); + +} + + +void EE_WriteMemoryUINT32(uint16_t address, uint32_t *pdata) +{ + TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms + uint32_t data; + uint8_t srcBuff[EE_BUFFER_SIZE]; + + M95512_WriteEnable(); + + data = *pdata; + srcBuff[0] = WRITE_MEM_ARRAY; + srcBuff[1] = address >> 8; + srcBuff[2] = address; + srcBuff[3] = (data & 0xff000000) >> 24; + srcBuff[4] = (data & 0x00ff0000) >> 16; + srcBuff[5] = (data & 0x0000ff00) >> 8; + srcBuff[6] = (data & 0x000000ff); + SPI0_SendBytes(srcBuff, 7, E2PROM); + + //Wait for EEPROM WIP flag low + while(EE_Busy()); + + TMR_Start(); +} + +void EE_ReadMemoryUINT32(uint16_t address, uint32_t *pdata) +{ + TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms + + uint32_t data; + uint8_t srcBuff[EE_BUFFER_SIZE]; + memset(srcBuff, 0, EE_BUFFER_SIZE); //Zero out srcBuff[]. byte 3 was 1??? + + srcBuff[0] = READ_MEM_ARRAY; + srcBuff[1] = address >> 8; //ADDR high + srcBuff[2] = address; //ADDR low + SPI0_SendBytes(srcBuff, 7, E2PROM); + + for(uint16_t i = 3; i < 7; i++){ + data <<= 8; + data += SPI0_xfer.rxData[i]; + } + *pdata = data; + + TMR_Start(); +} + +void EE_WriteUINT32(uint16_t address, uint32_t data) +{ + TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms + uint8_t srcBuff[EE_BUFFER_SIZE]; + + M95512_WriteEnable(); + + srcBuff[0] = WRITE_MEM_ARRAY; + srcBuff[1] = address >> 8; + srcBuff[2] = address; + srcBuff[3] = (data & 0xff000000) >> 24; + srcBuff[4] = (data & 0x00ff0000) >> 16; + srcBuff[5] = (data & 0x0000ff00) >> 8; + srcBuff[6] = (data & 0x000000ff); + SPI0_SendBytes(srcBuff, 7, E2PROM); + + //Wait for EEPROM WIP flag low + while(EE_Busy()); + + TMR_Start(); +} + +uint32_t EE_ReadUINT32(uint16_t address) +{ + TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms + + uint32_t data; + uint8_t srcBuff[EE_BUFFER_SIZE]; + memset(srcBuff, 0, EE_BUFFER_SIZE); //Zero out srcBuff[]. byte 3 was 1??? + + srcBuff[0] = READ_MEM_ARRAY; + srcBuff[1] = address >> 8; //ADDR high + srcBuff[2] = address; //ADDR low + SPI0_SendBytes(srcBuff, 7, E2PROM); + + for(uint16_t i = 3; i < 7; i++){ + data <<= 8; + data += SPI0_xfer.rxData[i]; + } + + TMR_Start(); + return data; +} + +/* Write bytes to EEPROM + * CAUTION: avoid writing across a 128 byte page boundary! This will cause rollover per the datasheet section 6.6 + */ +void EE_WriteBytes(uint16_t address, uint8_t *pdata, uint16_t numBytes) +{ + + if((address % EE_PAGE_SIZE) + numBytes > EE_PAGE_SIZE) //Prevent writing across page boundary + { + //while(1); //Use for debugging + return; + } + + TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms + + uint8_t srcBuff[SPI_XFER_BUFFER_SIZE + EE_HEADER_NUM_BYTES]; //temporary buffer for data + + M95512_WriteEnable(); + + srcBuff[0] = WRITE_MEM_ARRAY; + srcBuff[1] = address >> 8; + srcBuff[2] = address; + memcpy(&srcBuff[3], pdata, numBytes); //copy pData to srcBuf + SPI0_SendBytes(srcBuff, numBytes + EE_HEADER_NUM_BYTES, E2PROM); + + //Wait for EEPROM WIP flag low + while(EE_Busy()); + + TMR_Start(); +} + +/* Read bytes from EEPROM + * + */ +void EE_ReadBytes(uint16_t address, uint8_t *pdata, uint16_t numBytes) +{ + TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms + + uint8_t srcBuff[SPI_XFER_BUFFER_SIZE + EE_HEADER_NUM_BYTES]; + memset(srcBuff, 0, SPI_XFER_BUFFER_SIZE); //Zero out srcBuff[]. byte 3 was 1??? + + srcBuff[0] = READ_MEM_ARRAY; + srcBuff[1] = address >> 8; //ADDR high + srcBuff[2] = address; //ADDR low + SPI0_SendBytes(srcBuff, numBytes + EE_HEADER_NUM_BYTES, E2PROM); + + memcpy(pdata, &SPI0_xfer.rxData[3], numBytes); //copy received data to pdata + + TMR_Start(); +} diff --git a/source/eeprom.h b/source/eeprom.h new file mode 100644 index 0000000..7aae52c --- /dev/null +++ b/source/eeprom.h @@ -0,0 +1,88 @@ +/* + * eeprom.h + * + * Created on: Nov 11, 2022 + * Author: Keith.Lloyd + */ + +#ifndef EEPROM_H_ +#define EEPROM_H_ + +/* + * CAUTION: avoid writing across a 128 byte page boundary! This will cause rollover per the datasheet section 6.6 + */ + +//EEPROM 128 byte pages +#define EE_PAGE_SIZE 128 //Page size in bytes + +#define EE_PAGE_BL (0 * EE_PAGE_SIZE) //Bootloader data. DO NOT USE! +#define EE_PAGE_SYS (1 * EE_PAGE_SIZE) //System info +#define EE_PAGE_DATA (2 * EE_PAGE_SIZE) //Saved data +#define EE_PAGE_FREQ1 (3 * EE_PAGE_SIZE) //Frequency data page 1 +#define EE_PAGE_FREQ2 (4 * EE_PAGE_SIZE) //Frequency data page 2 +#define EE_PAGE_HW_FIXES (5 * EE_PAGE_SIZE) //END of EEPROM data. Used for EE_EraseAllData() + +/*******************************************************************************************************************/ +//SYSTEM INFO - EE_PAGE_SYS +/*******************************************************************************************************************/ +//defines are eeprom addresses in bytes +#define EE_SYS_MFG (EE_PAGE_SYS + 0) //Manufacturer string SYS_INFO_LENGTH is 24 bytes +#define EE_SYS_MODEL_NAME (EE_PAGE_SYS + 24) //Model name string SYS_INFO_LENGTH is 24 bytes +#define EE_SYS_SERIAL (EE_PAGE_SYS + 48) //Serial Number string SYS_INFO_LENGTH is 24 bytes +#define EE_SYS_MFG_DATE (EE_PAGE_SYS + 72) //Manufacture Date SYS_INFO_LENGTH is 24 bytes +#define EE_SYS_MODEL_NUMBER (EE_PAGE_SYS + 96) //Model number string SYS_INFO_LENGTH is 24 bytes +//Next available is 120 + +/*******************************************************************************************************************/ +//SAVED DATA - EE_PAGE_DATA +/*******************************************************************************************************************/ + +#define EE_DATA_FREQUENCY (EE_PAGE_DATA + 0) //Index of operating frequency UINT32 4 bytes +#define EE_DATA_MODE (EE_PAGE_DATA + 4) //Mode ( In Bytes) +#define EE_DATA_TIMER (EE_PAGE_DATA + 8) //autoShutdown Timer setting UINT32 4 bytes +#define EE_DATA_LANGUAGE (EE_PAGE_DATA + 12) //System language UINT32 4 bytes + +/*******************************************************************************************************************/ +//FREQUENCY DATA - EE_PAGE_HARDWARE_FIXES +/*******************************************************************************************************************/ + +#define EE_FREQ_NUM (EE_PAGE_FREQ1 + 0) //Number of frequencies + +//Addresses 4 through 39 reserved for future use + +#define EE_FREQ_START (EE_PAGE_FREQ1 + 40) //Start of frequency data. Freqs are save as packed UINT32 + +//Frequencies are stored as 1 packed UINT32_t per frequency, so 32 per 128 byte EEPROM page. + //21 on page1 and up to 32 on page2 gives 53 max frequencies. Need more space if storing more than that! +//If each frequency stored is a separate call to EE_WriteMemoryUINT32() it will not cause problems with EEPROM page wrap + +/*******************************************************************************************************************/ +//HARDWARE FIX DATA - EE_PAGE_FREQ +/*******************************************************************************************************************/ + +#define EE_HWFIX_INIT (EE_PAGE_HW_FIXES + 0) //Hardware fix eeprom page initialized +#define EE_HWFIX_VBATT_CAP_021 (EE_PAGE_HW_FIXES + 4) //Add cap parallel with R6 on 208021 +#define EE_HWFIX_MAIN_PCBA_PN (EE_PAGE_HW_FIXES + 8) //Main PCBA part number +//future hardware fixes go here + + + + + +void EE_LoadData(void); +bool EE_LoadFrequencies(void); +void EE_SaveData(void); // Save settings to EEPROM +void EE_EraseAllData(void); + +void EE_Test(void); +void EE_TestBytes(void); + +void EE_WriteMemoryUINT32(uint16_t address, uint32_t *pdata); +void EE_ReadMemoryUINT32(uint16_t address, uint32_t *pdata); +void EE_WriteUINT32(uint16_t address, uint32_t data); +uint32_t EE_ReadUINT32(uint16_t address); +void EE_WriteBytes(uint16_t address, uint8_t *pdata, uint16_t numBytes); +void EE_ReadBytes(uint16_t address, uint8_t *pdata, uint16_t numBytes); + + +#endif /* EEPROM_H_ */ diff --git a/source/frq.c b/source/frq.c new file mode 100644 index 0000000..6a5a07b --- /dev/null +++ b/source/frq.c @@ -0,0 +1,975 @@ +/* + * frq.c + * + * Created on: Jun 8, 2022 + * Author: Keith.Lloyd + */ +#include +#include +#include +#include "arm_math.h" +#include "spi.h" +#include "fsl_gpio.h" +#include "frq.h" +#include "LPC54114_cm4.h" +#include "display.h" +#include "utils.h" +#include "init.h" +#include "amps.h" +#include "ports.h" +#include "timer.h" +#include "mode.h" +#include "stdbool.h" +#include "eeprom.h" +#include "pwr_level.h" + +extern uint8_t Test_Mode, catch_up_flag; +extern uint8_t Taps_Flag; +extern uint32_t new_freq; +extern uint8_t frequency,Cur_Mode,LD_Flag; +extern uint8_t Dds_Pot_Val[2]; +extern uint16_t Sys_Chk_tmr; + +uint8_t Tx_mode, frq_chg_tmr,old_freq; +FREQDATA_t freq; +FREQUENCY_t freqArray[FREQ_MAX_NUM]; + +uint8_t foo[4]; //stuff the 2 16-bit values into an array of 4 uint8_t +uint8_t frq_update_flag; + + +extern uint8_t Power_Level; +extern ClampData_t clampData; +extern uint32_t systemTime; + +uint32_t Calc_Freq(uint32_t fout) // Calculate frequency word for DDS +{ +float Freg; +uint32_t Frq_result; + + Freg = fout * 268435456.0; // FREG = (Frequency * 2^28)/fclk = 12MHz normally + Frq_result = Freg/DDS_CLK + 0.5; + + return(Frq_result); + +} + +void Load_Ramp(uint32_t ramp_freq) // Sets up RAMP DDS for PWM AMP + +{ + + uint16_t ramp_hi = FREQ0_REG; //top 2 bits 0x01 for Freq0 register address + uint16_t ramp_lo = FREQ0_REG; + + + if (ramp_freq > 0) + { + Send_Ctrl_Word(RAMP_CTRL_WORD1,RAMP); // send Control word to hold setup + + ramp_lo |= (ramp_freq & 0x3fff); + ramp_freq >>= 14; + ramp_hi |= (ramp_freq & 0x3fff); + + //ramp_hi |= (ramp_freq & 0xc000) >> 14; // Preserve upper 2 bits + + + foo[0] = (uint8_t)(ramp_lo >> 8); //LS 16-bit word, MSB + foo[1] = (uint8_t)(ramp_lo & 0x00ff); //LS 16-bit word, LSB + foo[2] = (uint8_t)(ramp_hi >> 8); + foo[3] = (uint8_t)(ramp_hi & 0x00ff); + + SPI0_SendBytes(foo, 4, RAMP); + + Send_Ctrl_Word(RAMP_CTRL_WORD2,RAMP); // send Control word to release setup + } + else + { + Send_Ctrl_Word(RAMP_CTRL_WORD3,RAMP); // Control word to hold setup and put part to sleep + GPIO_PinWrite(GPIO, RAMP_PORT, RAMP_RST_GPIO_PIN, HI); //Hold RST HI + while(1); //stop + } +} + +void Load_Frq_Gen(FRQ_OUT_SELECT_t Freq_Mode, int32_t f1, int32_t f2) + +{ +uint8_t x=0; +uint16_t freq_hi = FREQ0_REG; +uint16_t freq_lo = FREQ0_REG; + + if (Freq_Mode == NULL_FREQ) + x = 1; // Switch both DDS chips OFF + + if (Freq_Mode == SINGLE) + { + x = 2; // Switch the primary DDS ON + + + Send_Ctrl_Word(FRQ_CTRL_WORD1,SIGNAL); // send Control word to hold setup + + freq_lo |= (f1 & 0x3fff); + f1 >>= 14; + freq_hi |= (f1 & 0x3fff); + + foo[0] = (uint8_t)(freq_lo >> 8); //LS 16-bit word, MSB + foo[1] = (uint8_t)(freq_lo & 0x00ff); //LS 16-bit word, LSB + foo[2] = (uint8_t)(freq_hi >> 8); + foo[3] = (uint8_t)(freq_hi & 0x00ff); + +// freq_hi |= (f1 & 0xc000) >> 14; // Preserve upper 2 bits +// freq_lo |= (f1 & 0x3fff); +// foo[0] = (uint8_t)(freq_lo >> 8); +// foo[1] = (uint8_t)(freq_lo & 0x00ff); +// foo[2] = (uint8_t)(freq_hi >> 8); +// foo[3] = (uint8_t)(freq_hi & 0x00ff); + + SPI0_SendBytes(foo, 4, SIGNAL); + + + Send_Ctrl_Word(FRQ_CTRL_WORD2,SIGNAL); // send Control word to release setup + + + + } + + if (Freq_Mode == DUAL) + { // ############---Switch both DDS chips ON SYNCHRONOUSLY--###### + + // Set RESET to hold + // Load F1 + Send_Ctrl_Word(FRQ_CTRL_WORD1,SIGNAL); // send Control word to hold setup + + freq_lo |= (f1 & 0x3fff); + f1 >>= 14; + freq_hi |= (f1 & 0x3fff); + + foo[0] = (uint8_t)(freq_lo >> 8); //LS 16-bit word, MSB + foo[1] = (uint8_t)(freq_lo & 0x00ff); //LS 16-bit word, LSB + foo[2] = (uint8_t)(freq_hi >> 8); + foo[3] = (uint8_t)(freq_hi & 0x00ff); + SPI0_SendBytes(foo, 4, SIGNAL); + + Send_Ctrl_Word(FRQ_CTRL_WORD2,SIGNAL); // send Control word to release setup + + + // Load F2 + freq_hi = FREQ0_REG; + freq_lo = FREQ0_REG; + + Send_Ctrl_Word(FRQ_CTRL_WORD1,SDSIGNAL); // send Control word to hold setup + + + + freq_lo |= (f2 & 0x3fff); + f2 >>= 14; + freq_hi |= (f2 & 0x3fff); + + foo[0] = (uint8_t)(freq_lo >> 8); //LS 16-bit word, MSB + foo[1] = (uint8_t)(freq_lo & 0x00ff); //LS 16-bit word, LSB + foo[2] = (uint8_t)(freq_hi >> 8); + foo[3] = (uint8_t)(freq_hi & 0x00ff); + SPI0_SendBytes(foo, 4, SDSIGNAL); + + + Send_Ctrl_Word(FRQ_CTRL_WORD2,SDSIGNAL); // send Control word to release setup + +// Send_Ctrl_Word(SLP_CTRL_WRD,SIGNAL); // TEST ONLY REMOVE Put unused DDS to sleep + + + +// Send_Ctrl_Word(PHASE_RESET,SIGNAL); // // Set Phase F1 to 0 + + + +// Send_Ctrl_Word(PHASE_RESET,SDSIGNAL); // Set Phase F2 to 0 + + + +// Send_Ctrl_Word(FRQ_CTRL_WORD2,BOTH_SIGNAL); // Send release code word simultaneously + + // End#. + + + // GPIO_PinWrite(GPIO, 1, 13, 1); + // Set high SD_RST + // Set high SIG_RST + + // Set up both Sine Wave generators + + // set low SD_RST + // set low SIG_RST. + } +} + +void Send_Ctrl_Word(uint16_t Control_Reg, SPI_MODE_t mode) +{ +//Set the control register Send MS Byte first then LSByte + + foo[0] = (uint8_t)(Control_Reg >> 8); // Reset bit held + foo[1] = (uint8_t)(Control_Reg & 0x00ff); + SPI0_SendBytes(foo, 2, mode); + +} + + + + +void AddFrequency(uint32_t frequency1,uint32_t frequency2, uint8_t enabled, uint8_t bc_enabled,uint8_t bc_mask,uint8_t pot,float i_lo,float i_hi,float v_lo,float v_hi) +{ + uint32_t i = freq.numFrequencies; + + freqArray[i].frequency1 = frequency1; + freqArray[i].frequency2 = frequency2; + + freqArray[i].enabled = enabled; + freqArray[i].bc_enabled = bc_enabled; + + freqArray[i].bc_Mask = bc_mask; + freqArray[i].max_pot = pot; + +// freqArray[i].v_coeff_lo = 0.876923; + freqArray[i].v_coeff_lo = v_lo; + freqArray[i].i_coeff_hi = i_hi; + freqArray[i].i_coeff_lo = i_lo; + + freq.numFrequencies++; +} + +void ClearFreqArray(void) +{ + for(uint32_t i = 0; i < FREQ_MAX_NUM; i++) + { + freqArray[i].frequency1 = 0; + freqArray[i].frequency2 = 0; + freqArray[i].enabled = 0; + freqArray[i].bc_enabled = 0; + + } +} + +void FREQ_Init(void) +{ + uint32_t tmp; + + GPIO_PinWrite(GPIO, SIGNAL_PORT, SIG_RST_GPIO_PIN, 1); // Set all RESET signals to RESET + GPIO_PinWrite(GPIO, SIGNAL_PORT, SD_RST_GPIO_PIN, 1); + GPIO_PinWrite(GPIO, SIGNAL_PORT, RAMP_RST_GPIO_PIN, 1); + Delay_Ticks(1); + GPIO_PinWrite(GPIO, SIGNAL_PORT, RAMP_RST_GPIO_PIN, 0); + GPIO_PinWrite(GPIO, SIGNAL_PORT, SIG_RST_GPIO_PIN, 0); // Set all RESET signals to RESET + GPIO_PinWrite(GPIO, SIGNAL_PORT, SD_RST_GPIO_PIN, 0); // 8/26/24 + + freq.numFrequencies = 0; + + + if(Test_Mode) // + { + FREQ_LoadFactoryDefaults(); +// frq_update_flag = false; + } + else + { + if(!EE_LoadFrequencies()) + { + FREQ_LoadFactoryDefaults(); + } + } + + Send_Ctrl_Word(SLP_CTRL_WRD,SDSIGNAL); // Put unused DDS to sleep + +// tmp = Calc_Freq(32768); +// Load_Frq_Gen(SINGLE,tmp,0); // testing only 8KHz + +// Load_Ramp(7829367); // 350KHz ramp waveform + + Load_Ramp(6710886); // 300KHz ramp waveform +// Load_Ramp(20132659); // 900KHz ramp waveform +// Load_Ramp(72370199); // 3.2352MHz ramp waveform + +} + +void FREQ_LoadFactoryDefaults(void) +{ +#if 1 //Use new function so we don't have to specify all the parameters + + //These are the FACTORY TEST Frequencies + FREQ_ClearFrequencies(); + FREQ_AddFrequency(512, 1, 1, FT_ACTIVE); + FREQ_AddFrequency(3140, 1, 1, FT_ACTIVE); + FREQ_AddFrequency(8192, 1, 1, FT_ACTIVE); + FREQ_AddFrequency(29433, 1, 1, FT_ACTIVE); + FREQ_AddFrequency(32770, 1, 1, FT_ACTIVE); + FREQ_AddFrequency(65055, 1, 1, FT_ACTIVE); + FREQ_AddFrequency(88779, 1, 1, FT_ACTIVE); + +#else //Or we can specify all the parameters + + AddFrequency(98, 0, 0, 0, 0, 0,0,0,0,0); + AddFrequency(128, 0, 0, 0, 0, 0,0,0,0,0); + AddFrequency(263, 0, 1, 0, 0, 165,0.8396,0.47,0.876923,0); + AddFrequency(440, 0, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + AddFrequency(440, 220, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + + AddFrequency(512, 0, 1, 0, 0, 180,0.8396,0.47,0.876923,0); + AddFrequency(512, 256, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + + AddFrequency(560, 0, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + AddFrequency(577, 0, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + + AddFrequency(640, 0, 0, 0, 0,180,0.8396,0.47,0.876923,0); + AddFrequency(640, 320, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + + AddFrequency(815, 0, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + AddFrequency(870, 0, 1, 0, 0, 180,0.8396,0.47,0.876923,0); + AddFrequency(870, 435, 0, 0, 0, 180,0.8396,0.47,0.876923,0); + + AddFrequency(940, 0, 0, 0, 0, 180,0.8105,0.47,0.876923,0); + AddFrequency(940, 470, 0, 0, 0, 180,0.8105,0.47,0.876923,0); + + AddFrequency(1024, 0, 0, 0, 0, 180,0.8105,0.49,0.911538,0); + + AddFrequency(1170, 0, 1, 0, 0, 180,0.8105,0.49,0.911538,0); + AddFrequency(1170, 585, 0, 0, 0, 180,0.8105,0.49,0.911538,0); + + AddFrequency(3140, 0, 1, 1, MASK_144, 180,0.8634,0.482,0.97083,0); + AddFrequency(3140, 1570, 0, 0, 0 , 180,0.8634,0.482,0.97083,0); + + AddFrequency(4096, 0, 1, 0, 0, 180,0.8634,0.482,0.97083,0); + AddFrequency(6000, 0, 1, 0, 0, 180,0.8634,0.482,0.97083,0); + AddFrequency(8010, 0, 0, 1,MASK_144, 180,0.8976,0.53,1.025,0); + AddFrequency(8192, 0, 1, 1,MASK_144, 180,0.8976,0.53,1.025,0); + AddFrequency(9820, 0, 1, 0,MASK_144, 180,0.8976,0.53,1.025,0); + + AddFrequency(29433, 0, 1, 1,MASK_58, 180,0.9534,0.69,1.043,0); + AddFrequency(32770, 0, 1, 1,MASK_58, 180,0.9581,0.713333333,1.009,0); + AddFrequency(44499, 0, 1, 1,MASK_15, 180,1,0.91,1.035,0); + AddFrequency(66055, 0, 1, 1,MASK_58, 120,1.215,1.35,1.6375,0); + AddFrequency(88779, 0, 1, 1,MASK_15, 120,1.355,1.36,1.8857,0); + AddFrequency(99037, 0, 0, 1,MASK_58, 120,1.355,01.36,0,0); + AddFrequency(200000, 0, 1, 1,MASK_144, 120,1.355,01.36,7.6,0); + AddFrequency(480000, 0, 0, 0,MASK_144, 120,4.111,2.111,7.6,0); +#endif +} + + +/* + * Pack frequency data and return + * Packed data is used for saving to FLASH + */ +uint32_t FREQ_GetPackedFrequency(uint32_t index) +{ + uint32_t packed = freqArray[index].frequency1; + //packed |= freqArray[index].type << FREQ_PACK_SHIFT_TYPE; + packed |= (uint32_t)freqArray[index].enabled << FREQ_PACK_SHIFT_ENABLED; + //packed |= (uint32_t)freqArray[index].inMenu << FREQ_PACK_SHIFT_INMENU; + + return packed; +} + +/* + * Add a frequency to the list from packed data + * Packed data is used for saving to FLASH + */ +void FREQ_AddPackedFrequency(uint32_t packedFreq) +{ + uint32_t frequency = packedFreq & FREQ_PACK_MASK_FREQ; + //FREQ_TYPE_t type = (packedFreq & FREQ_PACK_MASK_TYPE) >> FREQ_PACK_SHIFT_TYPE; + bool enabled = packedFreq & FREQ_PACK_MASK_ENABLED; + //bool inMenu = packedFreq & FREQ_PACK_MASK_INMENU; + + FREQ_AddFrequency(frequency, enabled, 1, FT_ACTIVE); //inMenu always 1, all FT_ACTIVE +} + + + +/* + * Clear the frequency list + * Zero out all data and set freq.numFrequencies to zero + */ +void FREQ_ClearFrequencies(void) +{ +// frq_update_flag = true; + for(uint32_t i = 0; i < freq.numFrequencies; i++) + { + freqArray[i].frequency1 = 0; + freqArray[i].enabled = 0; + + } + + freq.numFrequencies = 0; + + frequency = 0; +} + +/* + * Add a Frequency from UM Setup + */ +void FREQ_AddFrequency(uint32_t f1, uint8_t enabledTemp, uint8_t inMenu, FREQ_TYPE_t type) +{ + if(!inMenu) + { + return; //ignore freqs that are not in menu + } + + if((type != FT_ACTIVE) && (type != FT_LD_ACTIVE)) + { + return; //ignore RX frequency types + } + + //TODO: Calculate other things in Keith's freqArray[] here + //frequency2 for LD needs a function to determine 2nd frequency + //Doesn't matter yet since RX doesn't support LD + //scale factors + //other crap + + //f2 + uint32_t f2 = 0; + if(type == FT_LD_ACTIVE) + { + if(f1 <= FREQ_LD_SWITCH_POINT) + { + f2 = f1 * 2; + } + else if(f1 <= FREQ_LD_MAX_FREQUENCY) + { + f2 = f1 / 2; //TODO: This will break for odd frequencies since it's an integer. Need to rework freqs... + } + else + { + f2 = 0; + } + } + + //TODO: Generate values for these!!!!!!!!!! + uint32_t bc_enabledTemp = BC_Enable_Chk(f1); + uint32_t bc_maskTemp = BC_Mask_Chk(f1); //Todo remove as unused + uint32_t max_pot = Max_Pot_Chk(f1); + float32_t v_coeff_lo = V_coeff_lo_Chk(f1); + float32_t i_coeff_hi = I_coeff_hi_Chk(f1); + float32_t i_coeff_lo = I_coeff_lo_Chk(f1); + float32_t v_coeff_hi = V_coeff_hi_Chk(f1); //always 0 + + + AddFrequency(f1, f2, enabledTemp, bc_enabledTemp, bc_maskTemp, max_pot, i_coeff_lo, i_coeff_hi, v_coeff_lo, v_coeff_hi); +} + + +uint8_t BC_Enable_Chk(uint32_t f1) +{ + if((f1 >= BCAST_MIN) && (f1 < BCAST_MAX+1)) + return(1); + else + return(0); +} + +uint8_t BC_Mask_Chk(uint32_t f1) +{ + if((f1 >= BCAST_MIN) && (f1 < 9820)|| (f1 >= 200000) && (f1 <=480000)) + return(MASK_144); + else if(f1 == 29430 || f1==32768 || f1==65536 || f1==131072) + return(MASK_58); + else if(f1 == 44624 || f1== 83078) + return(MASK_15); + else + { + return 99; + } + +} + +uint8_t Max_Pot_Chk(uint32_t f1) +{ + if(f1 < 440) + return(180);//165 + if((f1 >= 440) && (f1 < 12000)) // 29430 + return(235); + + if((f1 >= 12000) && (f1 < 29430)) + return(245); + + if((f1 >= 29430)&& (f1 <= 44500)) + return(250); + if((f1 > 44624) && (f1 < 200000)) + return(200); + if(f1 == 200000) + return(140); + else + return(140); + +//TODO set up default value +} + + +float V_coeff_lo_Chk(uint32_t f1) +{ + float a; + switch(f1) + { + case 1 ... 940: + a= 0.876923; + break; + case 941 ... 1170: + a = 0.911538; + break; + case 1171 ... 6000: + a = 0.97083; + break; + + case 6001 ... 8009: + a = 1.025; + + break; + case 8010 ... 9820: + a = 1.025; + break; + case 9821 ... 29430: + a = 0.81; + break; + case 29431 ... 32768: + a = 0.81;//1.009; + break; + case 32769 ... 44100: + a = 1.035; + break; + case 44101 ... 65536: + a = 1.0; + break; + case 65537 ... 80000: + a = 1.1; + break; + case 80001 ... 199999: + a = 1.36; + break; + case 200000 ... 480000: + a = 4.5; + break; + default: + a = 0.53; + } + return(a); +} + + + +float V_coeff_hi_Chk(uint32_t f1) +{ + return(0); +} + +float I_coeff_lo_Chk(uint32_t f1) +{ + float a; +// a = freqArray[Search_for_frq(f1)].i_coeff_lo; + switch(f1) + { + case 1 ... 500: + a = 1; + break; + case 501 ... 870: + a= 0.8396; + break; + case 871 ... 1170: + a = 0.8105; + break; + case 1171 ... 3139: + a = 0.8634; + break; + case 3140 ... 6000: + a = 0.8634; + break; + case 6001 ... 8009: + a = 0.8634; + + break; + case 8010 ... 9820: + a = 0.8976; + break; + case 9821 ... 29430: + a = 0.8976; + break; + case 29431 ... 32768: + a = 0.8976; + break; + case 32769 ... 44100: + a = 0.91; + break; + case 44101 ... 65536: + a = 1.015; + break; + case 65537 ... 199999: + a = 1.255; + break; + case 200000 ... 480000: + a = 3.111; + break; + default: + a = 0.8976; + } + return(a); +} + +float I_coeff_hi_Chk(uint32_t f1) +{ + float a; + a = freqArray[Search_for_frq(f1)].i_coeff_hi; + switch(f1) + { + case 1 ... 940: + a= 0.47; + break; + case 941 ... 1170: + a = 0.49; + break; + case 1171 ... 6000: + a = 0.482; + break; + + case 6001 ... 8009: + a = 0.53; + + break; + case 8010 ... 9820: + a = 0.53; + break; + case 9821 ... 29430: + a = 0.69; + break; + case 29431 ... 32768: + a = 0.71333; + break; + case 32769 ... 44100: + a = 1.035; + break; + case 44101 ... 65536: + a = 1.35; + break; + case 65537 ... 200000: + a = 1.36; + break; + case 200001 ... 480000: + a = 2.111; + break; + default: + a = 0.53; + } + + return(a); +} + +uint8_t Search_for_frq(uint32_t f1) +{ + uint8_t i =0; + + for(i=0; i < FREQ_MAX_NUM - 1; i++) + { + if((f1 == freqArray[i].frequency1)) //(freqArray[frq_tmp].enabled > 0) + break; + + } + return(i); + +} + + + +void FREQ_ToggleEnable(uint32_t selected) //selected is same as frequency index +{ + freqArray[selected].enabled ^= 1; + +} + +FREQUENCY_t FREQ_GetFreqByIndex(uint32_t index) +{ + return freqArray[index]; +} + +uint32_t FREQ_GetNumFrequencies(void) +{ + return freq.numFrequencies; +} + + +uint8_t Next_Frequency(uint8_t frq_tmp) // increments frequency +{ + +uint8_t found = false; +uint8_t i; + + frq_tmp = frequency; + + if (frq_tmp < FREQ_MAX_NUM - 1) + frq_tmp++; + else + frq_tmp = 0; + + for(i=0; i < FREQ_MAX_NUM - 1; i++) + { + if(Check_freq_enabled(frq_tmp)) //(freqArray[frq_tmp].enabled > 0) + { + found = 1; + break; + } + if (frq_tmp < FREQ_MAX_NUM - 1) + frq_tmp++; + else + frq_tmp= 0; + } + + +return(frq_tmp); +} + +bool Check_freq_enabled(uint8_t frq_tmp) +{ + bool x; + + x = false; + + if(Cur_Mode != BROADCAST && (freqArray[frq_tmp].enabled > 0)) + x= true; + else + if ((Cur_Mode == BROADCAST) && (freqArray[frq_tmp].bc_enabled > 0) && (freqArray[frq_tmp].enabled > 0)) + x = true; + return(x); +} + + +/* Generate name for the frequency at the specified index + * @param index index in the frequency list + * @param *string pointer to the storage location for the name string + */ +void FREQ_GetFrequencyName(uint32_t index, uint8_t *string) +{ + //Generate frequency name + // < 1000Hz: "xxxHz" + // < 10kHz: "x.xxkHz" + // < 100kHz: "xx.xkHz" + // >=100kHz: "xxxkHz" + + uint32_t freqTemp = freqArray[index].frequency1; //the numeric freqTemp + + if(freqArray[index].frequency2 != 0) + { + if(freqTemp < 1000) + { + sprintf(string, "LD %dHz", freqTemp); + } + else if(freqTemp < 10000) + { + sprintf(string, "LD %.2fkHz", (float32_t)freqTemp / 1000.0); + } + else + { + sprintf(string, "ERROR"); + } + } + else + { + if(freqTemp < 1000) + { + sprintf(string, "%dHz", freqTemp); + } + else if(freqTemp < 10000) + { + sprintf(string, "%.2fkHz", (float32_t)freqTemp / 1000.0); + } + else if(freqTemp < 100000) + { + sprintf(string, "%.1fkHz", (float32_t)freqTemp / 1000.0); + } + else if(freqTemp < 500000) + { + sprintf(string, "%.0fkHz", (float32_t)freqTemp / 1000.0); + } + else + { + sprintf(string, "ERROR"); + } + } +} + + +/*while(!found && frq_tmp < FREQ_MAX_NUM) +{ + frq_tmp++; + + if(freqArray[frq_tmp].enabled > 0) + found = true; + + if(frq_tmp >= FREQ_MAX_NUM) + frq_tmp = FREQ_MIN; + +} */ + +void Update_Min_Frequency(void) +{ + +} + + + +void Update_Frequency() +{ + uint32_t tmp; + + if (Cur_Mode != BROADCAST) // IF - ! Broadcast + { + Enable_Amplifier(); // Select correct amplifier + Select_Transformer(); // Select correct transformer + + // tmp = Calc_Freq(freqArray[frequency].frequency1); + // Load_Frq_Gen(SINGLE,tmp,0); // # update the frequency generators + + Set_Selected_Freq(); + + Taps_Flag = false; + + + if((ACCY_GetConnectedAccessory(1) == ID_CLAMP) || (ACCY_GetConnectedAccessory(2) == ID_CLAMP)) + { + Get_Clamp_Value(); // Ensure correct table for Clamp amplitude + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + } + else + if ((ACCY_GetConnectedAccessory(1) == ID_CLAMP2) || (ACCY_GetConnectedAccessory(2) == ID_CLAMP2)) + { + clampData.regulate = true; + + if (freqArray[frequency].frequency1 < 800) + { + clampData.maxPower = MAX_POWER_TARGET_VLF; + } + else + if (freqArray[frequency].frequency1 < 45000) + { + clampData.maxPower = MAX_POWER_TARGET_LF; + } + else + { + clampData.maxPower = MAX_POWER_TARGET_HF; + } + + Get_Clamp_Value(); + + clampData.timeout = systemTime + CLAMP_REGULATE_DELAY; + + if (Power_Level > 0) + { + clampData.prevPowerLevel = 0; + setTestPot(); + } + + } + + // Select_Output_Port(ONE); // Switch in the correct pathway + } + else // else + { + All_Amps_Off(); // shut down Amplifiers DC connections + Disable_DC(); + Enable_BC(); // Enable BCAST circuitry using either Minimum or previously selected freq + LD_Flag = false; + + // Init_PWM(); // update PWM generators + } + old_freq = frequency; // Indicate done +} + +void Set_Selected_Freq(void) +{ + uint32_t frq1; + uint32_t frq2; + + if(LD_Flag && freqArray[frequency].frequency1 <= MAX_LD_FREQ) + { + frq1 = Calc_Freq(freqArray[frequency].frequency1); + frq2 = freqArray[frequency].frequency1; + frq2 = frq2 * 2.0; +// frq2 = 9100; // test only + frq2 = Calc_Freq(frq2); + Load_Frq_Gen(DUAL,frq1,frq2); // # update the frequency generators + + } + else + { + frq1 = Calc_Freq(freqArray[frequency].frequency1); + frq2 = 0; + Load_Frq_Gen(SINGLE,frq1,frq2); // # update the frequency generators + + Send_Ctrl_Word(SLP_CTRL_WRD,SDSIGNAL); // Put unused DDS to sleep + } +} + +void Reset_DDS(void) +{ + GPIO_PinWrite(GPIO, SIGNAL_PORT, SIG_RST_GPIO_PIN, 1); // Set all RESET signals to RESET + GPIO_PinWrite(GPIO, SIGNAL_PORT, SD_RST_GPIO_PIN, 1); + GPIO_PinWrite(GPIO, SIGNAL_PORT, RAMP_RST_GPIO_PIN, 1); + Delay_Ticks(1); + GPIO_PinWrite(GPIO, SIGNAL_PORT, RAMP_RST_GPIO_PIN, 0); + GPIO_PinWrite(GPIO, SIGNAL_PORT, SIG_RST_GPIO_PIN, 0); // Set all RESET signals to RESET +} +void Change_to_next_dc_frq(void) +{ +uint32_t tmp_frqx; +uint8_t count; + + if((ACCY_GetConnectedAccessory(1) == ID_CLAMP) || (ACCY_GetConnectedAccessory(2) == ID_CLAMP)) + { + frequency = Next_Frequency(frequency); // increment the frequency + new_freq = freqArray[frequency].frequency1; + + if(freqArray[frequency].frequency1 <= MIN_CTYPE)// is frequecny > min + { + count = 0; + + while(freqArray[frequency].frequency1 < MIN_CTYPE && count < FREQ_MAX_NUM) + { + frequency = Next_Frequency(frequency); // increment the frequency + new_freq = freqArray[frequency].frequency1; + count++; + + } + + // tmp_frqx = Search_Frequency(256); // select minimum frequency for DC Clamp operation +// if (tmp_frqx < FREQ_MAX_NUM) // set up new min freq +// { +// frequency = tmp_frqx; +// new_freq = freqArray[frequency].frequency1; +// } + } + else + { +// frequency = Next_Frequency(frequency); // increment the frequency + new_freq = freqArray[frequency].frequency1; + + } + } + else + { + frequency = Next_Frequency(frequency); // increment the frequency + new_freq = freqArray[frequency].frequency1; + Sys_Chk_tmr= DELAY_500MS; // Allow system settling before checking measurements +// catch_up_flag = true; + + } + +} + +void Change_To_Next_BC_Freq(void) +{ + uint32_t tmp_frqx; + + if(Cur_Mode == BROADCAST) // Special case only if BC mode already selected + { + if (freqArray[frequency].frequency1 < BCAST_MIN) // if (freq < min freq) ToDo + + tmp_frqx = Search_Frequency(3140); // select minimum frequency for BCAST + if (tmp_frqx < FREQ_MAX_NUM) + { + frequency = tmp_frqx; + new_freq = freqArray[frequency].frequency1; + } + } + +} diff --git a/source/frq.h b/source/frq.h new file mode 100644 index 0000000..d07bbb9 --- /dev/null +++ b/source/frq.h @@ -0,0 +1,144 @@ +/* + * frq.h + * + * Created on: Jun 8, 2022 + * Author: Keith.Lloyd + */ + +#ifndef FRQ_H_ +#define FRQ_H_ + +#include "spi.h" + +typedef enum { + NULL_FREQ, + SINGLE, + DUAL +}FRQ_OUT_SELECT_t; + + +#define TX_SYS_CLK 12000000 // 12MHZ +#define DDS_CLK TX_SYS_CLK + + +#define FREQ_MAX_NUM 50 //Max number of frequencies allowed +#define FREQ_MIN 0 +#define FREQ0_REG 0x4000 // Address of internal 9838 register +#define FRQ_CTRL_WORD1 0x2100 // Control register with Reset bit active +#define FRQ_CTRL_WORD2 0x2000 // Exit Reset Control Word +//#define FRQ_CTRL_WORD2 0x2038 // Exit Reset Control Word for PLL Test +#define PHASE_RESET 0xC000 // PHASE Register 0 = 0; + +#define RAMP_CTRL_WORD1 0x2102 +#define RAMP_CTRL_WORD2 0x2002 +#define RAMP_CTRL_WORD3 0x2002 // TODO Places wavegen in sleep mode +#define SLP_CTRL_WRD 0x2180 // Power down unused DDS +#define SLP_CTRL_WRD2 0x21C0 +#define RAMP_PORT 1 +//#define RAMP_RST_GPIO_PIN 14 +#define HI 1 +#define BCAST_MIN 3140 +#define BCAST_MAX 200000 +#define DUMMY_FRQ 250 +#define MIN_BLOCK_FREQ 20000 +#define MASK_15 0b00000000 +#define MASK_58 0b00001000 +#define MASK_144 0b00011000 +#define CLK_MASK_BITS 0b11100111 +#define MAX_LD_FREQ 10000 + +//FREQUENCY PACKING - from RX so it has extra fields +#define FREQ_PACK_MASK_FREQ 0x0007ffff //target frequency bits 0 - 18 +#define FREQ_PACK_MASK_TYPE 0x00380000 //3-bit field for FREQ_TYPE_t. bits 19 - 21 +#define FREQ_PACK_SHIFT_TYPE 19 //Frequency type shift +#define FREQ_PACK_MASK_ENABLED 0x80000000 //enabled mask +#define FREQ_PACK_SHIFT_ENABLED 31 //enabled shift bit 31 +#define FREQ_PACK_MASK_INMENU 0x40000000 //inMenu mask +#define FREQ_PACK_SHIFT_INMENU 30 //inMenu shift bit 30 + +//Locate direction (LD) +#define FREQ_LD_MAX_FREQUENCY 10000 //LD runs at or below this frequency +#define FREQ_LD_SWITCH_POINT 1500 //At or below this freq, f2 is f1 * 2. above this f2 = f1 / 2 + +#define MIN_CTYPE 263 // Minimum clamp frequency. + + +typedef enum { + FT_ACTIVE, //active + FT_LD_ACTIVE, //active w/ Locate Direction + FT_POWER, //RX ONLY individual power + FT_GROUPED_POWER, //RX ONLY Radio style grouped power + FT_CATHODIC, //RX ONLY cathodic protection - Identical to individual power except naming in frequency menu + FT_SONDE, //RX ONLY + FT_RADIO, //RX ONLY + FT_FAULT_FIND, //RX ONLY fault finder - Has it's own dedicated frequency set. frequencies are NOT user definable +}FREQ_TYPE_t; + + + + + + + +//Data for individual frequencies +typedef struct { + uint32_t frequency1; //frequency in Hz + uint32_t frequency2; + uint8_t enabled; // + uint8_t bc_enabled; + uint8_t bc_Mask; + uint8_t max_pot; + float i_coeff_lo; + float i_coeff_hi; + float v_coeff_lo; + float v_coeff_hi; + +}FREQUENCY_t; + + +//General data for frequencies module +typedef struct { + uint32_t numFrequencies; //number of frequencies in freqArray +}FREQDATA_t; + + + + + +void FREQ_Init(void); +void FREQ_LoadFactoryDefaults(void); +uint32_t FREQ_GetPackedFrequency(uint32_t index); +void FREQ_AddPackedFrequency(uint32_t packedFreq); +void FREQ_ClearFrequencies(void); +void FREQ_AddFrequency(uint32_t f1, uint8_t enabledTemp, uint8_t inMenu, FREQ_TYPE_t type); +void Load_Ramp(uint32_t ramp_freq); +void Load_Frq_Gen(FRQ_OUT_SELECT_t, int32_t, int32_t); // NONE,either or both plus two data words +//void AddFrequency(uint32_t frequency, uint32_t frequency2, uint8_t enabled, uint8_t bc_enabled, uint8_t bc_mask); +uint8_t Next_Frequency(uint8_t frequency); +void FREQ_ToggleEnable(uint32_t selected); +FREQUENCY_t FREQ_GetFreqByIndex(uint32_t index); +uint32_t FREQ_GetNumFrequencies(void); +void FREQ_GetFrequencyName(uint32_t index, uint8_t *string); +void Send_Ctrl_Word(uint16_t Control_Reg, SPI_MODE_t mode); +uint32_t Calc_Freq(uint32_t fout); // Calculate frequency word for DDS +void Update_Min_Frequency(void); +void Update_Frequency(); +void Reset_DDS(void); +void AddFrequency(uint32_t frequency1,uint32_t frequency2, uint8_t enabled, uint8_t bc_enabled,uint8_t bc_mask,uint8_t pot,float i_lo,float i_hi,float v_lo,float v_hi); +bool Check_freq_enabled(uint8_t frq_tmp); +uint8_t BC_Enable_Chk(uint32_t f1); +uint8_t BC_Mask_Chk(uint32_t f1); +uint8_t Max_Pot_Chk(uint32_t f1); +float V_coeff_lo_Chk(uint32_t f1); +float V_coeff_hi_Chk(uint32_t f1); +float I_coeff_lo_Chk(uint32_t f1); +float I_coeff_hi_Chk(uint32_t f1); +uint8_t Search_for_frq(uint32_t f1); +void Change_to_next_dc_frq(void); +void Change_To_Next_BC_Freq(void); +void Set_Selected_Freq(void); + +extern FREQUENCY_t freqArray[]; + + +#endif /* FRQ_H_ */ diff --git a/source/hwFixes.c b/source/hwFixes.c new file mode 100644 index 0000000..34599c5 --- /dev/null +++ b/source/hwFixes.c @@ -0,0 +1,87 @@ +/* + * hwFixes.c + * + * Created on: Mar 27, 2024 + * Author: Brian.Bailey + */ + + +#include +#include +#include +#include +#include + +//Drivers +#include "fsl_common.h" +#include "fsl_gpio.h" + + +#include "Fonts\fontLibrary.h" +#include "Graphics\graphicsLibrary.h" +#include "keys.h" +#include "eeprom.h" + +#include "hwFixes.h" + + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +HARDWARE_FIX_t hwf; + +extern char tempString[40]; + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +/* + * Initialize hardware fix EEPROM and read out fix data + */ +void HWF_Init(void) +{ + //Check if HWF eeprom page has been initialized + if(EE_ReadUINT32(EE_HWFIX_INIT) != 1) + { + //erase HWF sector + for(uint32_t i = EE_PAGE_HW_FIXES; i < EE_PAGE_HW_FIXES + EE_PAGE_SIZE; i++) + { + EE_WriteUINT32(i, 0x00000000); + } + + //Set HWF initialized + EE_WriteUINT32(EE_HWFIX_INIT, true); + EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, HWF_MIN_MAIN_PCBA_PN); //Default to earliest hardware + hwf.mainPcbaPN = HWF_MIN_MAIN_PCBA_PN; + } + else + { + //Read hardware fix info + hwf.vBattCap_021 = EE_ReadUINT32(EE_HWFIX_VBATT_CAP_021); + hwf.mainPcbaPN = EE_ReadUINT32(EE_HWFIX_MAIN_PCBA_PN); + + if(hwf.mainPcbaPN >= 208023) //Set vBattCap fix to true for 208023+ + { + hwf.vBattCap_021 = true; + } + } +} + + + + diff --git a/source/hwFixes.h b/source/hwFixes.h new file mode 100644 index 0000000..5deb425 --- /dev/null +++ b/source/hwFixes.h @@ -0,0 +1,24 @@ +/* + * hwFixes.h + * + * Created on: Mar 27, 2024 + * Author: Brian.Bailey + */ + +#ifndef HWFIXES_H_ +#define HWFIXES_H_ + +#define HWF_MIN_MAIN_PCBA_PN 208021 //Minimum PCBA part number +#define HWF_MAX_MAIN_PCBA_PN 208025 //Max PCBA part number - Increase this when changing hardware + +typedef struct +{ + bool vBattCap_021; + uint32_t mainPcbaPN; +}HARDWARE_FIX_t; + + + +void HWF_Init(void); + +#endif /* HWFIXES_H_ */ diff --git a/source/init.c b/source/init.c new file mode 100644 index 0000000..3f3c5b3 --- /dev/null +++ b/source/init.c @@ -0,0 +1,390 @@ +/* + * init.c + * + * Created on: May 20, 2022 + * Author: Keith.Lloyd + */ + +#include "arm_math.h" +#include +#include + +#include "init.h" +#include "taps.h" +#include "measure.h" +#include "ports.h" +#include "utils.h" +#include "frq.h" +#include "adc.h" +#include "mode.h" +#include "psu_ctrl.h" +#include "timer.h" +#include "main.h" +#include "lcd.h" +#include "menu.h" + +#include "safety_key.h" +#include "usbComms.h" +#include "flashUpdate.h" +#include "bootloader.h" +#include "eeprom.h" +#include "sys_chk.h" +#include "pwr_level.h" +#include "Graphics/icons.h" +#include "display.h" +#include "pwm.h" +#include "battery.h" +#include "keys.h" +#include "System/system.h" + +extern uint8_t OverVolts_Flag,catch_up_flag; // global OverVoltsFlag +extern ADC_t adc; +extern MODE_REC_t mode_Array[MODE_MAX_NUM]; +extern uint8_t Cur_Mode, Old_Mode; +extern uint8_t Port_State[]; +extern uint32_t what_val1, what_val2; +uint8_t Over_Voltage_Flag; +uint8_t Over_Current_Flag; +uint8_t Hardware_Error_Flag; +uint8_t Taps_Flag, psu_failed; +uint8_t Diag_Flag,LD_Flag; + +extern uint8_t init_flag,step_count; +extern uint8_t Task,Tx_Time_Out_Flag, Test_Mode,Ports_Cleared_Flag; +extern uint8_t Power_Level; +extern uint8_t old_freq, frequency, frq_chg_tmr; +extern uint8_t Bat_Type,Bcast_Pwr_Level; +extern uint16_t Port_timer, Taps_adjust_timer; +extern uint8_t Port_changed_flag,i; +extern uint8_t Safety_Select,Suspend_Step_Chk; +uint8_t Safe_Mode, Init_Done; +extern uint16_t Estop_timer,Sys_Chk_tmr,Pot_Value[],Vchktmr,Key_Lock_Out_tmr; +extern uint8_t Dds_Pot_Val[]; // 2 byte Data for SPI +float32_t Max_Power_Limit; +extern uint32_t TX_TIME[]; +extern uint32_t Sys_Timer,Tx_timer; +extern float32_t last_Ohms; +extern uint16_t PSU_Check_tmr,Power_tmr; + +void Init_vars() +{ + Taps_adjust_timer = DELAY_ONE_SECOND; + + Task = PRIMARY_TASK; +// Task = MENU_TASK; + Power_Level = 0; + Bcast_Pwr_Level = 0; + frequency = 5; + old_freq = frequency; + + Tx_Time_Out_Flag = DISABLED; // Disable time outs for now (temporary) +// Tx_timer = TX_TIME[0]; // reload the timer + + Safety_Select = false; + Over_Voltage_Flag = false; + Safe_Mode = false; + Test_Mode = false; // + + char *ver = SW_VERSION; + + for (int i=0; i < strlen(ver); ++i) + { + if (isalpha(ver[i])) + { + Test_Mode = true; + break; + } + } + + Estop_timer = 0; + Sys_Chk_tmr = 0; + Vchktmr = 0; + Key_Lock_Out_tmr = 0; + step_count = 0; + PSU_Check_tmr = PSU_DELAY; + Max_Power_Limit = 5.0; // default until battery type determined. + last_Ohms = 1; + Taps_Flag = false; + catch_up_flag= false; + Ports_Cleared_Flag = false; + psu_failed = false; + Init_Done = false; + Suspend_Step_Chk = false; + Diag_Flag = false; // default for now should be read from EEPROM + LD_Flag = false; + Power_tmr = 0; +} + +void Init_peripherals(void) +{ + timer_init(); + + SPI_Init(); + LCD_Init(); + +} + +void Init_sys(void) +{ + FREQ_Init(); + Init_PSU_Pot(); // initialize pot. + + Init_Ports(); // Ensure Ports are set to safe mode + + MENU_Init(); + +} + + +void Init_Ports() // Ensure all ports are set to safe when powering up +{ + +// [Not BYPASSED,PSU OFF, ALL AMPS SWITCHED OFF, BACKLIGHT ON.] + + Select_Estop(ON); + Port_State[TOP_SR] = 0x00; // + + Port_State[MID_SR] = 0x00; // U12 + Port_State[BOTTOM_SR] = 0x24; // U13 AMP_AB = ON, BKLITE = on PWR SW's off, AMP PSU OFF + SPI0_SendBytes(Port_State, 3, EXPANDER); + + Delay_Ticks(2); // execute short delay + +} + + + +void Clear_Flags() +{ + OverVolts_Flag = false; +} + + +void Init_Output(void) +{ + + if(adc.V_CHK < EXCEDED) // Read external voltage disable if present + { + +// Read_Tx_Ports(); // check for what's connected is controlled from timer interrupt + + Init_Mode(); // default induction mode + + + Update_Min_Frequency(); // determine frequency to be applied from last or if clamp or broadcast mode + + Init_Amplitude(); // set amplitude to minimum + +// Measure_Ohms(); // Done calculate Ohms + +// Check_Taps(); // Done determine optimum taps etc + + } // + else + Estop_Mode(); // + + +} +void Init_Mode() +{ +uint8_t i; + + // initialize until E2PROM fitted + + for(i = 0; i <= MODE_MAX_NUM; i++ ) + { + mode_Array[i].Selected = true; + mode_Array[i].Plugged = true; + + } + mode_Array[BROADCAST].Selected = true; //default BCAST always available + mode_Array[BROADCAST].Plugged = BROADCAST; + mode_Array[PORT1_A].Plugged = ID_TX_SINGLE_DIRECT; + + mode_Array[PORT1_B].Plugged = EMPTY; + + mode_Array[PORT2_A].Plugged = ID_TX_DUAL_DIRECT; + mode_Array[PORT2_B].Plugged = ID_TX_DUAL_DIRECT; + + mode_Array[PORT2_A].Selected = false; + mode_Array[PORT2_B].Selected = false; + + + + + + Cur_Mode = BROADCAST; + Old_Mode = Cur_Mode; + + Read_Tx_Ports(); // now scan external ports + +} + +void Init_Amplitude(void) // set amplitude to minimum +{ +// if(Cur_Mode != BROADCAST) +// { + Dds_Pot_Val[0] = 0; // address + Dds_Pot_Val[1] = Pot_Value[INIT_PWR_LEVEL]; // data + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); +// } + +} + + +void Init_PWM_CLKS(void) +{ + if(freqArray[frequency].bc_Mask == MASK_144) + Init_Int_Clk(); + else + Init_Ext_Clk(); +} + +void Init_Ext_Clk(void) +{ + + Port_State[TOP_SR] &= CLK_MASK_BITS; + Port_State[TOP_SR] |= freqArray[frequency].bc_Mask; + + SPI0_SendBytes(Port_State, 3, EXPANDER); + +} + +void Init_Int_Clk(void) +{ + + + +} + + + +void Init_PSU_Pot(void) // Set PSU_POT half way approx 23V +{ + Port_State[TOP_SR] = 0x0; //TODO Ensure PSU DISABLED + Port_State[MID_SR] = 0x00; //Port_State[MID_SR] | 0x04; + Port_State[BOTTOM_SR] = 0x24; + SPI0_SendBytes(Port_State, 3, EXPANDER); + + Set_PSU_Voltage(MAX_AB_PSU); //MID_POINT_PSU 18,24,27,30,36, 55 + + Delay_Ticks(2); + + Port_State[TOP_SR] = 0x0; //TODO ENABLE PSU + Port_State[MID_SR] = 0x00;//Port_State[MID_SR] & 0xfb; + Port_State[BOTTOM_SR] = 0x24; + SPI0_SendBytes(Port_State, 3, EXPANDER); + + +} + +void Normal_Init(void) +{ + + + Power_ON_OFF(ON); // Enable_Psu(); Ensure Power supply stays switched on. + Select_Estop(ON); // Ensure output is ISOLATED from connections + + + Init_vars(); + +// Init_peripherals(); 2/9/24 +// Init_sys(); 2/9/24 + + BL_ReadInfo(); + EE_LoadData(); //Read saved data + + + Display_Splash(); //Display splash screen + Delay_Ticks(200); // execute short delay + KEY_Init(); //Init keys after splash delay to prevent POWER short press on startup + +// USB_Init(); + + // Read_Tx_Ports(); // Read output ports and determine what is connected + // Select_Amplifier(); // Select correct amplifier according to frequency + + Init_Mode(); // + + //init_PWM(); + // PWM_Setup(32768, BC_Duty_Cycle);//freqArray[frequency].frequency1 + // PWM_Setup(29430, BC_Duty_Cycle); + PWM_Setup(15890, 0); // switches off PWM + + + + Safety_Check(); // Check all voltages are safe to continue in DC. + + + Check_Bat_Id(); // Check for Alkaline or Lithium and battery insertion error. + + + + + what_val1=0; + what_val2=0; + Cur_Mode = PORT2_A; + + init_flag = 0; + for( i=0; i < 15; i++); + { + Delay_Ticks(10); + // ADC_Update(); + Read_Tx_Ports(); // check for whats plugged in at the ports every 100mS. + } + + if ((adc.V_ID2 > 3.0) && (adc.V_ID1 > 3.0)) + { + Cur_Mode = BROADCAST; + Port_changed_flag= 1; + init_flag = 1; + } + + Disconnect(2); + Delay_Ticks(30); + + Check_For_Clamp_On_Pwr_Up(); + + + + Select_Output_Port(); + + + Safety_Check(); // Second time J.I.C Check all voltages are safe to continue in DC. + + + Normal_Bypass_Chk(); + + old_freq = DUMMY_FRQ; //force a frequency on initialization + frq_chg_tmr = 0; + + Update_Frequency(); +// Select_Bypass(OFF); + + Select_Estop(OFF); // Ensure output is ISOLATED from connections + + Init_Amplitude(); +} + +void Init_Pwr_Level_One(void) +{ + if(!Init_Done) + { + Delay_Ticks(10); // Wait for Current to catch up + inc_pwr(); // Set power level to 1 + Init_Done = true; + + } + + + + +} + + +void Init_LD_Sync(void) +{ + Update_Frequency(); +} + + diff --git a/source/init.h b/source/init.h new file mode 100644 index 0000000..df12c6f --- /dev/null +++ b/source/init.h @@ -0,0 +1,29 @@ +/* + * init.h + * + * Created on: May 20, 2022 + * Author: Keith.Lloyd + */ + +#ifndef INIT_H_ +#define INIT_H_ + +#define MID_POINT_PSU 128 // 25V +#define INIT_PWR_LEVEL 0 + +void Clear_Flags(void); +void Init_Output(void); +void Init_Amplitude(void); // set amplitude to minimum +void Init_PWM_CLKS(void); // select internal or Ext clocks +void Init_Mode(void); +void Init_PSU_Pot(void); // Set PSU_POT half way approx 23V +void Init_vars(void); +void Init_Ports(void); +void Init_peripherals(void); +void Init_sys(void); +void Init_Ext_Clk(void); +void Init_Int_Clk(void); +void Normal_Init(void); +void Init_Pwr_Level_One(void); +void Init_LD_Sync(void); +#endif /* INIT_H_ */ diff --git a/source/keys.c b/source/keys.c new file mode 100644 index 0000000..8f9db51 --- /dev/null +++ b/source/keys.c @@ -0,0 +1,349 @@ +/* + * keys.c + * + * Created on: Mar 7, 2022 + * Author: Brian.Bailey + */ + +#include +#include +#include +#include +#include +#include +#include "fsl_common.h" +#include "fsl_gpio.h" +#include "pin_mux.h" +#include "clock_config.h" + +#include "keys.h" +#include "timer.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +//KEY GPIO DEFINITIONS +/* +#define KEY0_PORT 1 // 208002 +#define KEY1_PORT 1 +#define KEY2_PORT 0 +#define KEY3_PORT 0 +#define KEY4_PORT 0 +#define KEY5_PORT 0 +*/ +#define KEY0_PORT 1 // 208004 +#define KEY1_PORT 0 +#define KEY2_PORT 0 +#define KEY3_PORT 0 +#define KEY4_PORT 0 +#define KEY5_PORT 0 + +/* //208002 +#define KEY0_PIN 15 //Power On/Off key //on off +#define KEY1_PIN 5 //MODE key //SFTKY0 +#define KEY2_PIN 2 //UP key //SFTKY1 +#define KEY3_PIN 3 //DOWN key //SFTKY2 +#define KEY4_PIN 8 //FREQUENCY key //SFTKY3 +#define KEY5_PIN 9 //Menu key //SFTKY4 +*/ +// 208004 +#define KEY0_PIN 15 //Power On/Off key //on off 208004 +#define KEY1_PIN 14 //MODE key //SFTKY0 +#define KEY2_PIN 2 //UP key //SFTKY1 +#define KEY3_PIN 3 //DOWN key //SFTKY2 +#define KEY4_PIN 24 //FREQUENCY key //SFTKY3 +#define KEY5_PIN 25 //Menu key //SFTKY4 + +#define KEY_UP_PIN KEY2_PIN //UP key +#define KEY_DOWN_PIN KEY3_PIN //DOWN key +#define KEY_FREQ_PIN KEY4_PIN //FREQ key + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +//Move this to header file later +typedef struct +{ + uint32_t gpioPin; //Key gpio pin within the port + uint32_t gpioPort; // Key GPIO Port + uint32_t tickCount; //number of consecutive ticks key held ON + uint32_t currentState; //Key on/off for current tick + uint32_t lastState; //key on/off last tick + uint32_t longPressDetected; //Long press + uint32_t shortPressDetected; //short press +} KEY_DATA_t; + +KEY_DATA_t keyData[KEY_NUM]; + +uint32_t key_bits; +extern uint32_t TX_TIME[]; +extern uint32_t Tx_timer; +extern TIMER_t tmr; +//TESTING +static uint32_t keyPressCount = 0; + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + +static void InitKeyData(void); + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + + + +//Assign port and pin to each key +static void InitKeyData(void) +{ + //Init keys as digital inputs, no interrupts + + //Set keyData[] gpioPins + keyData[0].gpioPin = KEY0_PIN; // ON_POLL + keyData[1].gpioPin = KEY1_PIN; // SFTKY0 + keyData[2].gpioPin = KEY2_PIN; // SFTKY1 + keyData[3].gpioPin = KEY3_PIN; // SFTKY2 + keyData[4].gpioPin = KEY4_PIN; // SFTKY3 + keyData[5].gpioPin = KEY5_PIN; // SFTKY4 + + //Set keyData[] gpioPorts + keyData[0].gpioPort = KEY0_PORT; + keyData[1].gpioPort = KEY1_PORT; + keyData[2].gpioPort = KEY2_PORT; + keyData[3].gpioPort = KEY3_PORT; + keyData[4].gpioPort = KEY4_PORT; + keyData[5].gpioPort = KEY5_PORT; +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +void KEY_Init(void) +{ + InitKeyData(); + KEY_ClearKeyPresses(); + KEY_ClearAll(); +} + +//reset all key states and timer values +void KEY_ClearAll(void) +{ + for (uint32_t i = 0; i < KEY_NUM; i++) + { + keyData[i].lastState = 0; + keyData[i].tickCount = 0; + } +} + +//Clear key presses +void KEY_ClearKeyPresses(void) +{ + key_bits = 0; +// key_bits &= !KEY_ALL; +} + +//waits for key press returns key and clears previous keys +uint32_t KEY_WaitForKeyPress(uint32_t keyMask) +{ + while(!(key_bits & keyMask)); + + uint32_t tempKeys = key_bits; + KEY_ClearKeyPresses(); + + return tempKeys; +} + +/* returns 1 if a key press event is present, 0 otherwise + * + */ +bool KEY_IsKeyPressed(uint32_t keyMask) +{ + return (key_bits & keyMask); +} + +//return the key press event bits +uint32_t KEY_GetPressed(void) +{ + uint32_t tempKeys = key_bits; + KEY_ClearKeyPresses(); + + return tempKeys; +} +uint8_t KEY_GetModeKeyHeld(void) +{ + return !GPIO_PinRead(GPIO, keyData[1].gpioPort, keyData[1].gpioPin); +} + + + +//Get current state of UP key +uint8_t KEY_GetUpKeyHeld(void) +{ + return !GPIO_PinRead(GPIO, keyData[2].gpioPort, keyData[2].gpioPin); +} + +//Get current state of DOWN key +uint8_t KEY_GetDownKeyHeld(void) +{ + return !GPIO_PinRead(GPIO, keyData[3].gpioPort, keyData[3].gpioPin); +} + +//Get current state of FREQUENCY key +uint8_t KEY_GetFrequencyKeyHeld(void) +{ + return !GPIO_PinRead(GPIO, keyData[4].gpioPort, keyData[4].gpioPin); +} + +//Get current state of DOWN key +uint8_t KEY_GetPowerKeyHeld(void) +{ + return !GPIO_PinRead(GPIO, keyData[0].gpioPort, keyData[0].gpioPin); +} + +#if 0 +//Called from gui task +void KEY_Locate(void) +{ + static uint8_t upKeyHeld = false; + static uint8_t downKeyHeld = false; + + //Increase gain repeatedly if UP key held +#if 0 + if(KEY_IsKeyPressed(KEY_UP | (KEY_UP << KEY_LONG_PRESS))) //UP key short or long press + { + upKeyHeld = true; + } +#endif + + if(upKeyHeld) + { + if(!GPIO_PinRead(KEY_GPIO, KEY_UP_PIN)) //read the port to see if key held + { + GAIN_IncreaseGain(); + } + else + { + upKeyHeld = false; + } + } + + //Decrease gain repeatedly if DOWN key held +#if 0 + if(KEY_IsKeyPressed(KEY_UP | (KEY_UP << KEY_LONG_PRESS))) //UP key short or long press + { + downKeyHeld = true; + } +#endif + + if(downKeyHeld) + { + if(!GPIO_PinRead(KEY_GPIO, KEY_DOWN_PIN)) //read DOWN key + { + GAIN_DecreaseGain(); + } + else + { + downKeyHeld = false; + } + } + + uint32_t pressed = KEY_GetPressed(); + + switch (pressed) + //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_VOLUME: + AUDIO_ChangeVolume(); + break; + case KEY_MODE: + //Change Mode / Screen + break; + case KEY_UP: + GAIN_IncreaseGain(); + break; + case (KEY_UP << KEY_LONG_PRESS): + upKeyHeld = true; //key held down, setup for repeated gain increases + break; + case KEY_DOWN: + GAIN_DecreaseGain(); + break; + case (KEY_DOWN << KEY_LONG_PRESS): + downKeyHeld = true; //key held down, setup for repeated gain decreases + break; + case KEY_FREQ: + FREQ_ChangeFrequency(); + break; + case KEY_POWER: + //Shut down + break; + case KEY_TX_CTL: + //TX Control + break; + case KEY_FA: + //Frequency Analysis + break; + case KEY_MENU: + KEY_ClearAll(); //clear all key data so it's clean for the menu + xSemaphoreGive(xSem_RunMenu); //Run the menu + xSemaphoreTake(xSem_ExitMenu, portMAX_DELAY); //Block gui task until menu done + break; + } + + KEY_ClearKeyPresses(); +} +#endif + +//Processing for key presses +//Key# corresponds to i +//This is called at intervals of KEY_TIMER_PERIOD_MS +void KEY_Update(void) +{ + + for (uint32_t i = 0; i < KEY_NUM; i++) + { + //if Key is pressed + //GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin) + if (!GPIO_PinRead(GPIO, keyData[i].gpioPort, keyData[i].gpioPin)) + { + keyData[i].currentState = 1; + keyData[i].tickCount++; + if (keyData[i].tickCount == KEY_LONG_PRESS_TICKS) + { + //Long press detected + key_bits |= ((1 << i) << KEY_LONG_PRESS);//set long press event + //Don't reset tickCount. Continue tick accumulation. when key released it won't do anything + } + + Tx_timer = TX_TIME[tmr.autoShutdown]; // reload the timer + + + } + else //Key is NOT pressed + { + //If key was pressed last time, check for valid keypress + if (keyData[i].lastState) + { + + if (keyData[i].tickCount >= KEY_SHORT_PRESS_MIN_TICKS + && keyData[i].tickCount <= KEY_SHORT_PRESS_MAX_TICKS) + { + //Short press detected + key_bits |= ((1 << i) << KEY_SHORT_PRESS);//set short press event + } + keyData[i].tickCount = 0; //reset tick count + } + } + } + + //Update lastState + for (uint32_t i = 0; i < KEY_NUM; i++) + { + keyData[i].lastState = keyData[i].currentState; + } +} + diff --git a/source/keys.h b/source/keys.h new file mode 100644 index 0000000..4024951 --- /dev/null +++ b/source/keys.h @@ -0,0 +1,87 @@ +/* + * keys.h + * + * Created on: Mar 7, 2022 + * Author: Brian.Bailey + */ + +#ifndef KEYS_H_ +#define KEYS_H_ +#include +#include +#define KEY_NUM 6 //number of keys + +/* Key event_bits structure + * bits 0 - 5 are KEY0 - 5 long presses + * bits 6 - 11 are KEY0 - 5 long presses + * KEY_SHORT_PRESS is 0 and KEY_LONG_PRESS is 6 + * Accessing key data: + * KEY3 short press would be KEY3 or (KEY3 << SHORT_PRESS) + * KEY4 long press bit would be (KEY4 << KEY_LONG_PRESS) + */ + +#define KEY0 (1 << 0) +#define KEY1 (1 << 1) +#define KEY2 (1 << 2) +#define KEY3 (1 << 3) +#define KEY4 (1 << 4) +#define KEY5 (1 << 5) + +#define KEY_SHORT_PRESS 0 +#define KEY_LONG_PRESS 6 + +#define KEY_ALL 0xfff //All short and long keypresses + +#define KEY_TIMER_PERIOD_MS 10 //pdMS_TO_TICKS(25) //25mS + +//Key Press Parameters +#define KEY_SHORT_PRESS_MIN_TICKS 5 //50mS +#define KEY_SHORT_PRESS_MAX_TICKS 49 //490mS +#define KEY_LONG_PRESS_TICKS 50 //500mS + + +//Key Aliases + +//Short Press Functions +#define KEY_VOLUME KEY0 //Change Volume +#define KEY_MODE KEY1 //Change Mode //Cancel / Back in menu +#define KEY_UP KEY2 //Increase Gain //Up in menu +#define KEY_DOWN KEY3 //Decrease Gain //Down in menu +#define KEY_FREQ KEY4 //Change Frequency //Enter / Select in menu +#define KEY_MENU KEY5 //Menu + +#if 1//Long Press Functions +#define KEY_POWER (KEY0 << KEY_LONG_PRESS) //Power ON/OFF +#endif + +//Menu Press Functions +#define KEY_BACK KEY1 //Cancel / Back in menu +#define KEY_UP KEY2 //Up in menu +#define KEY_DOWN KEY3 //Down in menu +#define KEY_SEL KEY4 //Enter / Select in menu +#define KEY_ENTER KEY4 //Enter / Select in menu + +//Keith Translations +#define ON_OFF_KEY KEY0 +#define FRQ_KEY KEY4 +#define PWR_UP_KEY KEY2 +#define PWR_DN_KEY KEY3 +#define MODE_KEY KEY1 +#define MENU_KEY KEY5 + + +void KEY_Init(void); +void KEY_ClearAll(void); +void KEY_ClearKeyPresses(void); +uint32_t KEY_WaitForKeyPress(uint32_t keyMask); +bool KEY_IsKeyPressed(uint32_t keyMask); +uint32_t KEY_GetPressed(void); +uint8_t KEY_GetModeKeyHeld(void); +uint8_t KEY_GetUpKeyHeld(void); +uint8_t KEY_GetDownKeyHeld(void); +uint8_t KEY_GetFrequencyKeyHeld(void); +uint8_t KEY_GetPowerKeyHeld(void); +void KEY_Locate(void); +void KEY_Update(void); + +#endif /* KEYS_H_ */ diff --git a/source/lcd.c b/source/lcd.c new file mode 100644 index 0000000..05d929a --- /dev/null +++ b/source/lcd.c @@ -0,0 +1,374 @@ +/* + * lcd.c + * + * Created on: May 27, 2022 + * Author: Keith.Lloyd + */ + +#include +#include +#include +#include +#include +#include + +#include "fsl_gpio.h" + +#include "spi.h" +#include "lcd.h" +#include "display.h" +#include "timer.h" +#include "mode.h" +#include "Graphics/graphicsLibrary.h" +#include "Fonts/fontLibrary.h" +#include "Graphics/testIconsMono.h" +#include "Graphics/icons.h" +#include "adc.h" +#include "main.h" +#include "ports.h" +#include "utils.h" +//Overview: +// LCD control / data line normally stays in the data state. +// Any function that changes to control MUST change the line back to data before exiting + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +//Backlight GPIO +#define LCD_BL_PORT 2 //ToDo: Update this for LPC +#define LCD_BL_GPIO_PIN 30 //ToDo: Update this for LPC +//#define LCD_CD_PORT 0 //ToDo: Update this for LPC Port0 || Port1 208002 +//#define LCD_CD_GPIO_PIN 6 //ToDo: Update this for LPC Bit position 208002 + +#define LCD_CD_PORT 1 //ToDo: Update this for LPC Port0 || Port1 208004 +#define LCD_CD_GPIO_PIN 8 //ToDo: Update this for LPC Bit position 208004 + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +// Frame buffer +//uint16_t mFrameBuffer[LCD_HEIGHT_PIXELS][LCD_WIDTH_PIXELS/16]; //y,x +//uint8_t mFrameBuffer[LCD_WIDTH_PIXELS][LCD_HEIGHT_PIXELS / 8]; //x,y +uint8_t mFrameBuffer[LCD_HEIGHT_PIXELS/8][LCD_WIDTH_PIXELS]; //x,y +extern uint8_t Power_Level, Over_Voltage_Flag, Task,Error; +extern uint8_t tempString[]; +extern uint8_t frequency, Cur_Mode, Safe_Mode; +extern ADC_t adc; +extern uint8_t Dds_Pot_Val[]; +extern uint8_t Port_State[]; +extern uint8_t Diag_Flag; +extern uint16_t Display_warning_tmr; +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ +static void SetBacklightPower(uint8_t state); +static void SetCommandDataLine(LCD_CDLINE_t state); +static void SendLcdCommand(uint8_t command, uint8_t data); + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + +//Set Backlight GPIO to 'state' +static void SetBacklightPower(uint8_t state) +{ + //ToDo This function Note backlight is now on Serial expander + GPIO_PinWrite(GPIO, LCD_BL_PORT, LCD_BL_GPIO_PIN, state); + +} + +//Set CD line GPIO high for LCD_CDLINE_DATA or low for LCD_CDLINE_CONTROL +static void SetCommandDataLine(LCD_CDLINE_t state) +{ + //ToDo This function Done !! + GPIO_PinWrite(GPIO, LCD_CD_PORT, LCD_CD_GPIO_PIN, state); +} + +//command is the #defined command +//data is optional arguments > zero if not used! +static void SendLcdCommand(uint8_t command, uint8_t data) +{ + SetCommandDataLine(LCD_CDLINE_CONTROL); + + uint8_t sendData = command | data; + SPI3_SendBytes(&sendData, 1); //send one byte via SPI + + SetCommandDataLine(LCD_CDLINE_DATA); +} + +//dedicated function for setting LCD gain and pot values +static void SetGainAndPot(uint8_t data) +{ + SetCommandDataLine(LCD_CDLINE_CONTROL); + + uint8_t sendData[2]; + sendData[0] = LCD_SET_GAIN_AND_POT; + sendData[1] = data; + + SPI3_SendBytes(&sendData[0], 2); //send one byte via SPI + + SetCommandDataLine(LCD_CDLINE_DATA); +} + +static void TestLCD(void) +{ + //Alternate setting all pixels black, then white + while(1) + { + SendLcdCommand(LCD_SET_ALL_PIXELS, 1); + + uint32_t delay = 50000000; + while(delay--); + + SendLcdCommand(LCD_SET_ALL_PIXELS, 0); + + delay = 50000000; + while(delay--); + + // Delay_Ticks(500); + } +} + +static void TestLCD2(void) +{ + + + while(1) + { + //Draw vertical stripes in frameBuffer and output to LCD + for(uint32_t y = 0; y < LCD_HEIGHT_PIXELS; y++) + { + for(uint32_t x = 0; x < LCD_WIDTH_PIXELS / 16; x++) + { + + mFrameBuffer[y][x] = 0xF0; + + } + } + + LCD_Update(); + + uint32_t delay = 50000000; + while(delay--); + + //Draw horizontal striped in frameBuffer and output to LCD + for(uint32_t y = 0; y < LCD_HEIGHT_PIXELS; y++) + { + for(uint32_t x = 0; x < LCD_WIDTH_PIXELS / 16; x++) + { + if(y % 1 == 0) //every other row + { + mFrameBuffer[y][x] = 0xF0; + } + } + } + + + LCD_Update(); + + delay = 50000000; + while(delay--); + + } +} + +void LCD_Init(void) +{ + + SendLcdCommand(0, 0); // SET COLUMN LSB + SendLcdCommand(0b00010000, 0); // SET COLUMN MSB + SendLcdCommand(0b01000000, 0); // SET START LINE + SendLcdCommand(0b00100100, 0); // SET MUX & TEMP. COMPENSATION + SendLcdCommand(0b00101101, 0); // SET POWER CONTROL + SendLcdCommand(0b10000001, 0); // SET GAIN & POTENTIOMETER + SendLcdCommand(0b10000000, 0); // SET GAIN & POTENTIOMETER (second part) + SendLcdCommand(0b10001001, 0); // RAM CONTROL + SendLcdCommand(0b10100100, 0); // ALL PIX OFF + SendLcdCommand(0b10100100, 0); // ALL PIX OFF + SendLcdCommand(0b10101111, 0); // SLEEP MODE OFF + SendLcdCommand(0b11001000, 0); // MY=1 MX=0 MSF=0 +// SendLcdCommand(0b11101010, 0); // BIAS=12 D1,D0 = BR[1:0] + SendLcdCommand(0b11101010, 0); // BIAS=12 D1,D0 + SendLcdCommand(0b10010000, 0); // fixed line + +} + + + +void Display_Update(void) +{ + + LCD_Clear(); //clear the frameBuffer + + Display_USB_Status(); + if((!Check_For_Clamp_New()) && Display_warning_tmr == 0) + Display_Over_Voltage_Status(); + + Display_Tx_Status(); + + //Display_OnScreen_Diagnostics(); // temporary for debug + +#if 0 //info + if(Diag_Flag) + Display_OnScreen_Diagnostics(); + +#endif + LCD_Update(); + +} + + +void LCD_PowerOff(void) +{ + //TODO: UC1608 Power down requirements: (see datasheet page 33) + //Reset command + //Wait 2mS + //Turn off VDD +} + +/* Output frameBuffer data to LCD + * + */ + +void LCD_Update(void) +{ + SendLcdCommand(LCD_SET_COLUMN_LSB, 0); + SendLcdCommand(LCD_SET_COLUMN_MSB, 0); + SendLcdCommand(LCD_SET_PAGE_ADDRESS, 0); + + //output framebuffer data via SPI + SPI3_SendBytes((uint8_t *)mFrameBuffer, sizeof(mFrameBuffer)); + +} + +//Clear mFrameBuffer +void LCD_Clear(void) +{ + //Clear Screen + memset(mFrameBuffer, 0, sizeof(mFrameBuffer)); +} + +//Write a pixel to the framebuffer in the specified location +void LCD_DrawPixel(int16_t x, int16_t y, LCD_DRAWMODE_t mode) +{ + //ignore if outside LCD area + if(x < 0 || x > LCD_X_MAX) + return; + if(y < 0 || y > LCD_Y_MAX) + return; + + //Flip LCD 180* + x = LCD_X_MAX - x; + y = LCD_Y_MAX - y; + + //8-bit data in frameBuffer to read > modify > write + + uint16_t page = y / LCD_Y_BITS_PER_PAGE; + uint8_t bitPosition = y%8; + uint8_t bitMask = 1 << bitPosition; + + //Draw the pixel + switch(mode) + { + case LCD_DRAW_SET: + mFrameBuffer[page][x] |= bitMask; + break; + case LCD_DRAW_CLEAR: + mFrameBuffer[page][x] &= bitMask; + break; + case LCD_DRAW_XOR: + mFrameBuffer[page][x] ^= bitMask; + break; + } + +} + +//get a pixel from the framebuffer at the specified location +//returns 1 if pixel set, 0 otherwise +uint8_t LCD_GetPixel(int16_t x, int16_t y) +{ + //Flip LCD 180* + x = LCD_X_MAX - x; + y = LCD_Y_MAX - y; + + + uint16_t page = y / LCD_Y_BITS_PER_PAGE; + uint8_t bitPosition = y%8; + uint8_t bitMask = 1 << bitPosition; + + uint8_t byte = mFrameBuffer[page][x]; + return (byte >> bitPosition) & 0x01; // right shift the bit of interest to the ones position, then mask +} + + +#if 0 //UC1608 +/****************************************************************************/ +/*** uc1608 ***/ +/****************************************************************************/ + +/** + * uc1608_send send chunk over SPI + * @param spi config + * @param command or data array ptr + * @param size of command or data to send + * @param command or data mode + * @param io pin for data/cmd mode + * @author Matthieu Barreteau + * @date 04/26/2014 + */ +int uc1608_send(struct spi_config *config,unsigned char *data, int len,uint8_t mode,uint8_t cmdPin) +{ + delayMicroseconds(10); + if(mode == UC1608_DATA) { + GPIO_SET = 1< +#include + +#include "Fonts\fontLibrary.h" +#include "Graphics\graphicsLibrary.h" +#include "spi.h" +#include "lcd.h" +#include "main.h" +#include "frq.h" +#include "pro_key.h" +#include "menu1.h" +#include "mode.h" +#include "utils.h" +#include "timer.h" +#include "over_ride.h" +#include "menu.h" +#include "sys_chk.h" +#include "amps.h" +#include "display.h" +#include "ports.h" +#include "adc.h" +#include "battery.h" +#include "mode.h" +#include "init.h" +#include "taps.h" +#include "pwm.h" +#include "safety_key.h" +#include "usbComms.h" +#include "flashUpdate.h" +#include "bootloader.h" +#include "eeprom.h" +#include "sys_chk.h" +#include "pwr_level.h" +#include "Graphics/icons.h" +#include "hwFixes.h" +//temp +#include "fsl_sctimer.h" + +extern volatile uint8_t BC_Duty_Cycle; + +uint8_t Task,Tx_Time_Out_Flag,i,Test_Mode; +extern uint8_t Power_Level,Over_Voltage_Flag,Safe_Mode; +extern uint8_t Port_State[]; +extern uint8_t old_freq, frequency, frq_chg_tmr,Cur_Mode; +extern uint8_t Bat_Type,Bcast_Pwr_Level; +extern uint16_t Port_timer, Taps_adjust_timer,Sys_Chk_tmr,Shut_down_tmr; +extern uint8_t Port_changed_flag; +extern uint16_t Low_Bat_timer,Estop_timer; +extern uint32_t what_val1, what_val2; +extern ADC_t adc; +extern uint32_t new_freq; +uint8_t init_flag,catch_up_flag; +uint8_t Selected = false; +extern uint8_t frq_update_flag,Ports_Cleared_Flag; +extern HARDWARE_FIX_t hwf; +extern uint8_t tempString[40]; // Todo move + +#define BYPASS_USB_SAFETY 0 //Use for debugging +#define DDS_PLL_TEST 0 + +ClampData_t clampData; + + +int main(void) +{ + + // indicate no slope calulated since slope will always be positive + clampData.slope = -1.0f; + + /* attach 12 MHz clock to FLEXCOMM0 (debug console) */ + CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); + + /* attach 12 MHz clock to SPI3 */ + CLOCK_AttachClk(kFRO12M_to_FLEXCOMM3); + + /* reset FLEXCOMM for SPI */ + RESET_PeripheralReset(kFC3_RST_SHIFT_RSTn); + + BOARD_InitPins(); + BOARD_BootClockPLL150M(); + CLOCK_SetupFROClocking(96000000U); // Set up high frequency FRO output for USB + POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*Turn on USB Phy */ + + + Power_ON_OFF(ON); // Enable_Psu(); Ensure Power supply stays switched on. + Select_Estop(ON); // Ensure output is ISOLATED from connections + + Init_vars(); + + Init_peripherals(); + HWF_Init(); + Init_sys(); + +//################### + Check_For_Usb(); // Set everything safe if so + + KEY_Init(); //Init keys after splash delay to prevent POWER short press on startup + + +// Display_Splash(); //Display splash screen +// Delay_Ticks(100); // execute short delay + + BL_ReadInfo(); + EE_LoadData(); //Read saved data + +#if !BYPASS_USB_SAFETY + if(GPIO_PinRead(GPIO,1,6)) + { + USB_Init(); + Display_Splash(); //Display splash screen + Delay_Ticks(100); // execute short delay + + } + while(GPIO_PinRead(GPIO,1,6)) + { + LCD_Clear(); + Display_USB(); //Display USB icon + LCD_Update(); + Delay_Ticks(1); // execute short delay + safe_key(); // process primary keys as safety menu + USB_Update(); + + } +#endif +//################### + + Display_Splash(); //Display splash screen + Delay_Ticks(100); // execute short delay + + ADC_Init2(); + ACCY_Init(); + + KEY_Init(); //Init keys after splash delay to prevent POWER short press on startup + + // Read_Tx_Ports(); // Read output ports and determine what is connected + // Select_Amplifier(); // Select correct amplifier according to frequency + + Init_Mode(); // + + //init_PWM(); + // PWM_Setup(32768, BC_Duty_Cycle);//freqArray[frequency].frequency1 + // PWM_Setup(29430, BC_Duty_Cycle); + PWM_Setup(15890, 0); // switches off PWM + Delay_Ticks(100); // execute short delay + + Safety_Check(); // Check all voltages are safe to continue in DC. + + Check_Bat_Id(); // Check for Alkaline or Lithium and battery insertion error. + + + what_val1=0; + what_val2=0; + Cur_Mode = PORT2_A; + + init_flag = 0; + for( i=0; i < 15; i++) + { + Delay_Ticks(10); +// ADC_Update(); +// Read_Tx_Ports(); // check for whats plugged in at the ports every 100mS. + } + + if ((adc.V_ID2 > 3.0) && (adc.V_ID1 > 3.0)) + { + Cur_Mode = BROADCAST; + Port_changed_flag= 1; + init_flag = 1; + } + + Disconnect(2); + Delay_Ticks(30); + + Check_For_Clamp_On_Pwr_Up(); + + Select_Output_Port(); + + Safety_Check(); // Second time J.I.C Check all voltages are safe to continue in DC. + + Normal_Bypass_Chk(); + + old_freq = DUMMY_FRQ; //force a frequency on initialization + frq_chg_tmr = 0; + + Update_Frequency(); +// Select_Bypass(OFF); // 3/14/24 + + Select_Estop(OFF); // Restore output. + + Init_Amplitude(); + + USB_Init(); + + +#if DDS_PLL_TEST +//# Insert special test code here. +uint32_t tmp; + All_Amps_Off(); + // Set OBPTEN + tmp = Calc_Freq(3500090); + Load_Frq_Gen(SINGLE,tmp,0); // # update the frequency generators + +//# End Test code +#endif + +//######################### +// if(Read_Model_type() == LEICA) // Read Model Patches erroneous boards sent to Leica 8/2/24 +// { +// sprintf(tempString, "%d", hwf.mainPcbaPN); + +// if(strncmp(tempString,"208021",6) == 0) // check for HW rev. +// { +// hwf.mainPcbaPN = 208025; +// EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN);// Change to 208025 Assembly + +// } +// } + +// Leica_Patch(); // Patches erroneous boards sent to Leica 8/2/24 + +// Umag_Patch(); +//######################## + + while(1) + { + + static uint32_t tickCount = 0; + + USB_Update(); //Update USB here so we're outside the ISR + +#if !BYPASS_USB_SAFETY + //##################### + Check_For_Usb(); + if(GPIO_PinRead(GPIO,1,6)) + { + Task = USB_SAFE_TASK; // process primary keys as safety menu + safe_key(); // process primary keys as safety menu + LCD_Clear(); + Display_USB(); //Display USB icon + LCD_Update(); + + } + else + if(!GPIO_PinRead(GPIO,1,6) && Ports_Cleared_Flag) + { + Normal_Init(); // USB is unplugged so reinitialize + } + //############################### +#endif + + + Delay_Ticks(1); //10mS delay + + +#if !BYPASS_USB_SAFETY + if((tickCount++ % 10 == 0) && !GPIO_PinRead(GPIO,1,6)) //every 10 ticks = 100mS AND !USB +#else + if(tickCount++ % 10 == 0) //every 10 ticks = 100mS +#endif + { + + + + switch (Task) + { + + case SAFETY_TASK: + safe_key(); // process primary keys as safety menu + break; + case USB_SAFE_TASK: + safe_key(); // process primary keys as safety menu + break; + case FATAL_ERROR_TASK: + safe_key(); // process primary keys as safety menu + break; + + case PRIMARY_TASK: + pro_key(); // process primary keys front 6 first menu + break; + + case MENU_TASK: // Allows user to select options + menu_key(); + Task = PRIMARY_TASK; + break; + + case MODE_TASK: // Selects between DC || BC + mode_menu(); + Task = PRIMARY_TASK; + break; + + case PWR_OFF_TASK: + Power_Down(); // Stores last settings and powers off + break; + + case OVER_RIDE_TASK: // Allows user to Over ride safe settings + Over_Ride(); // schedule Over Ride Menu + KEY_ClearKeyPresses(); + break; + + case BAT_INSERTION_ERROR: + if(Shut_down_tmr == 0); //Display_Bat_Error(); + Power_Down(); // Stores last settings and powers off + break; + + + case LOW_BATTERY_TASK: + if(Low_Bat_timer == 0) + Task = PWR_OFF_TASK; + break; + + } + +#if !DDS_PLL_TEST + + if(old_freq != frequency && frq_chg_tmr == 0 && (!frq_update_flag)) + { + Update_Frequency(); + //Port_changed_flag = true; + } + + if(Bat_Type == BAT_ERROR) + Task = BAT_INSERTION_ERROR; + + if (Port_timer == 0) + Read_Tx_Ports(); // check for whats plugged in at the ports every 100mS. + + if(Port_changed_flag) + { + Select_Output_Port(); + Update_Frequency(); + Init_Pwr_Level_One(); // Set power out level 1 + + } + if (Sys_Chk_tmr == 0) + { + System_Check(); // Check all system functions + Chk_Gain(); + + if(catch_up_flag) + { + Delay_Ticks(10); + Request_Current_Change(); // Request_Current_Change(); + catch_up_flag = false; + } + + } + + if((!Check_For_Clamp_New())) + { + Check_For_Open_Circuit(); // DC mode only + } + else + { + Port_State[MID_SR] |= BYPASS_ON; // Set relay to By Pass protection cap + SPI0_SendBytes(Port_State, 3, EXPANDER); // Send_Update_Port(); + } + + + if (Check_For_Clamp()) + { + doClampPower(); + } + + //Send_Wireless_Data(); // Send system update to Receiver. + + if (Taps_adjust_timer == 0) + Check_Taps(); // Check for optimum Taps +#endif + Display_Update(); + + } + + } + + + } + diff --git a/source/main.h b/source/main.h new file mode 100644 index 0000000..8702d22 --- /dev/null +++ b/source/main.h @@ -0,0 +1,27 @@ +/* + * main.h + * + * Created on: May 20, 2022 + * Author: Keith.Lloyd + */ + +#ifndef MAIN_H_ +#define MAIN_H_ + +#define PRIMARY_TASK 0 +#define MODE_TASK 1 +#define MENU_TASK 2 +#define PWR_OFF_TASK 3 +#define OVER_RIDE_TASK 4 +#define ESTOP_TASK 5 +#define BAT_INSERTION_ERROR 6 +#define SAFETY_TASK 7 +#define LOW_BATTERY_TASK 8 +#define USB_SAFE_TASK 9 +#define FATAL_ERROR_TASK 10 + + + + + +#endif /* MAIN_H_ */ diff --git a/source/measure.c b/source/measure.c new file mode 100644 index 0000000..9ce8a4f --- /dev/null +++ b/source/measure.c @@ -0,0 +1,54 @@ +/* + * measure.c + * + * Created on: Jun 7, 2022 + * Author: Keith.Lloyd + */ + + +#include "fsl_spi.h" +#include "pin_mux.h" +#include "board.h" +#include "fsl_debug_console.h" + +#include +#include +#include +#include +#include +#include +#include "measure.h" +#include "frq.h" +#include "ports.h" +#include "adc.h" +#include "amps.h" + +extern float32_t Volts; +extern float32_t Amps; +extern float32_t Ohms; +extern float32_t Watts,Max_Power_Limit; +extern uint8_t frequency; +extern uint8_t Port_State[]; +extern ADC_t adc; + + + + + + + + + +float Calc_Max_current(void) +{ + float a; + if(freqArray[frequency].frequency1 <= MAX_DTYPE) + a = sqrtf(Max_Power_Limit / adc.Ohms_slowfilt); + else + a = sqrtf(1/adc.Ohms_slowfilt); + + return(a); + +} + + diff --git a/source/measure.h b/source/measure.h new file mode 100644 index 0000000..3fe2661 --- /dev/null +++ b/source/measure.h @@ -0,0 +1,21 @@ +/* + * measure.h + * + * Created on: Mar 24, 2023 + * Author: Keith.Lloyd + */ + +#ifndef MEASURE_H_ +#define MEASURE_H_ + +void Measure_Volts(void); +void Measure_Current(void); + +void Calculate_Volts(void); +void Calculate_Current(void); +float Calc_Max_current(void); + +#define HI_VOLTS 7 //ADC CHannel 7 +#define EXCEDED 500 // High voltage value at port + +#endif /* MEASURE_H_ */ diff --git a/source/menu.c b/source/menu.c new file mode 100644 index 0000000..3330be7 --- /dev/null +++ b/source/menu.c @@ -0,0 +1,1098 @@ +/* + * menu.c + * + * Created on: Mar 8, 2022 + * Author: Brian.Bailey + */ + + +#include +#include +#include +#include +#include + +//Drivers +#include "fsl_common.h" +#include "fsl_gpio.h" + + +#include "Fonts\fontLibrary.h" +#include "Graphics\graphicsLibrary.h" +#include "lcd.h" +#include "keys.h" +#include "timer.h" +#include "frq.h" +#include "Graphics\icons.h" +#include "System\system.h" +#include "mode.h" +#include "adc.h" +#include "testMenu.h" +#include "hwFixes.h" + +#include "menu.h" +#include "ports.h" +#include "display.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define MENU_TIMER_PERIOD_MS (100) //100mS for 10Hz update + + + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +MENU_t menu; + +MENU_ITEM_t mainMenu[MAIN_MENU_NUM_TX10]; +MENU_ITEM_t linkMenu[LINK_MENU_NUM]; +MENU_ITEM_t langMenu[LANG_MENU_NUM]; + +extern const char *languageNames[]; + +extern char tempString[40]; +char tempstr2[10]; // Todo move + +extern SYSTEM_DATA_t sys; + +extern uint8_t Cur_Mode; + +extern ADC_t adc; +extern uint8_t frequency,psu_failed; +extern uint8_t Dds_Pot_Val[]; +extern uint8_t Port_State[]; + +extern HARDWARE_FIX_t hwf; + +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + + + +static void ClearMenuItems(MENU_ITEM_t items[], uint32_t num); + +static void DrawMenuScrollBar(uint32_t displayIndex, uint32_t numItems); + + +static void DisplaySystemInfo(void); +static void DisplayDiagnostics(void); +static void DisplayDiagnostics2(void); +static void LinkRadioMenu(void); +static void DisplayLinkRadioMenu(uint32_t selected); +static void FrequenciesMenu(void); +static void DisplayFrequenciesMenu(uint32_t selected); +static void LanguageMenu(void); +static void DisplayLanguageMenu(uint32_t selected); +static void DisplayRegulatoryInfo(void); + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + + + + +//Clear an array of MENU_ITEM_t +static void ClearMenuItems(MENU_ITEM_t items[], uint32_t num) +{ + for(uint32_t i = 0; i < num; i++) + { + items[i].pMonoIcon = 0; //Init mono icon pointer to null + + items[i].text[0] = 0; //Init first char to null + } +} + + + +//Draw menu scroll bar on right side +static void DrawMenuScrollBar(uint32_t displayIndex, uint32_t numItems) +{ + //Exit if scroll bar not needed + if(numItems <= MENU_MAX_LINES_DISPLAYED) + { + return; + } + //numItems = 30; // 18 + //vertical line + const uint32_t lineWidth = 5; + const uint32_t lineX = LCD_X_MAX - 10; + const uint32_t lineYStart = 20; + const uint32_t lineYStop = LCD_Y_MAX - 20; + const uint32_t lineHeight = lineYStop - lineYStart; + + //rectangle + const uint32_t rectWidth = 20; + const uint32_t rectX = lineX; + + uint32_t rectHeight = lineHeight * ((double)MENU_MAX_LINES_DISPLAYED / numItems); + uint32_t rectYStart = lineYStart + (lineHeight - rectHeight) * ((double)displayIndex / (numItems - MENU_MAX_LINES_DISPLAYED)); + uint32_t rectYStop = rectYStart + rectHeight; + + //Draw line + GL_DrawLine(lineX, lineYStart, lineX, lineYStop, lineWidth, LCD_DRAW_SET); + + //Draw Rectangle + GL_DrawLine(rectX, rectYStart, rectX, rectYStop, rectWidth, LCD_DRAW_SET); +} + + +static void SystemInfoMenu(void) +{ + uint32_t selected = 0; + uint32_t menuExit = 0; + + + while(1) + { + if(KEY_IsKeyPressed(KEY_ALL)) + { + //use keys to change selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + switch(pressed) //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_UP: + if(--selected > MENU_SYS_INFO_NUM) + { + selected = 0; + } + break; + case KEY_DOWN: + if(++selected >= MENU_SYS_INFO_NUM) + { + selected = MENU_SYS_INFO_NUM - 1; + } + break; + case KEY_BACK: + menuExit = true; + break; + case ON_OFF_KEY: + menu.exitToMainScreen = true; + break; + case KEY_POWER: //Look for test menu key sequence: HOLD POWER, + if(selected == 1) //Must be in Diagnostics to enter test menu + { + uint32_t mode = 0; + uint32_t up = 0; + uint32_t down = 0; + + while(KEY_GetPowerKeyHeld()) + { + if(KEY_GetModeKeyHeld()) + { + mode++; + while(KEY_GetModeKeyHeld()); + } + if(KEY_GetUpKeyHeld()) + { + up++; + while(KEY_GetUpKeyHeld()); + } + if(KEY_GetDownKeyHeld()) + { + down++; + while(KEY_GetDownKeyHeld()); + } + + Delay_Ticks(10); //100mS + } + if((mode == 2) && (up == 2) && (down == 1)) + { + TM_TestMenu(); + } + } + } + + } + +#if 1 //Update info for diagnostics screens. + //ACCEL_Update(); + //RTC_Update(); +#endif + + //Display selected screen + switch(selected) + { + case 0: + DisplaySystemInfo(); + break; + case 1: + DisplayDiagnostics(); + break; + case 2: + DisplayDiagnostics2(); + break; + default: + break; + } + + + if(menuExit || menu.exitToMainScreen) + { + return; + } + + + + Delay_Ticks(10); //100mS delay for screen display + } + +} + +static void DisplaySystemInfo(void) +{ + uint32_t xCol1 = 0; + uint32_t xCol2 = 145; + uint32_t yStart = 17;//22; + uint32_t yPos = yStart; + uint32_t yInc = 18;//7; + + LCD_Clear(); + + + //Title + FL_DrawTranslatedString("SYSTEM INFO", LCD_X_MID, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + + //Column 1 + yPos = yStart; + if(Read_Model_type() != LEICA) + FL_DrawTranslatedString(sys.manufacturer, xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + else + { +// tempstr2[10] = " 1005573"; +// sprintf(sys.manufacturer, "%s%s",sys.manufacturer,tempstr2); + FL_DrawTranslatedString(sys.manufacturer, xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + FL_DrawTranslatedString(" 1005573", xCol1 + 64, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + } + yPos += yInc; + + FL_DrawTranslatedString("Model Name", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawTranslatedString("Serial Number", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawTranslatedString("Loader Version", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawTranslatedString("Software Version", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawTranslatedString("Manufacture Date", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + + //Column 2 + yPos = yStart; + if(strncmp(sys.manufacturer, "Underground", 10) == 0 || strncmp(sys.manufacturer, "Goldenland", 9) == 0) //If MFG is "Underground...", move modelNumber to the right + { + FL_DrawString(sys.modelNumber, LCD_X_MAX, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_RIGHT); + yPos += yInc; + } + else + { + FL_DrawString(sys.modelNumber, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + } + + if(Read_Model_type() == UMAG) + FL_DrawString("10W", xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + else + FL_DrawString(sys.modelName, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + yPos += yInc; + + FL_DrawString(sys.serialNumber, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + sprintf(tempString, "%d", sys.bootloaderVersion); + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawString(SW_VERSION, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawString(sys.mfgDate, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + + + LCD_Update(); + + +} + + + +static void DisplayDiagnostics(void) +{ + uint32_t xCol1 = 2; + uint32_t xCol2 = 100; + uint32_t yStart = 25; + uint32_t yPos = yStart; + uint32_t yInc = 16; + + + LCD_Clear(); + + //Title + FL_DrawString("DIAGNOSTICS 1", LCD_X_MID, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + + //Show Main PCBA PN top right + sprintf(tempString, "%d", hwf.mainPcbaPN); + FL_DrawString(tempString, LCD_X_MAX, yStart, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_RIGHT); + + + //Column 1: Headings + yPos = yStart; + FL_DrawString("Output", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawString("Frequency", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; +#if 0 + FL_DrawString("Voltage", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawString("Current", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FL_DrawString("Power", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; +#endif + + + + yPos += yInc; + yPos += yInc; + + FL_DrawString("Ios", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //current offset + yPos += yInc; + + FL_DrawString("Vos", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //voltage offset + yPos += yInc; + + + //Column 2: values + yPos = yStart; + switch(Cur_Mode) //Show text for MODE + { + case BROADCAST: + sprintf(tempString, "INDUCTION"); + break; + case PORT1_A: + sprintf(tempString, "PORT 1A"); + break; + case PORT1_B: + sprintf(tempString, "PORT 1B"); + break; + case PORT2_A: + sprintf(tempString, "PORT 2A"); + break; + case PORT2_B: + sprintf(tempString, "PORT 1B"); + break; + default: + sprintf(tempString, "Taco"); + break; + } + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + FREQ_GetFrequencyName(frequency, tempString); + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //Frequency + yPos += yInc; +#if 0 + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //voltage + yPos += yInc; + + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //current + yPos += yInc; + + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //power + yPos += yInc; +#endif + + sprintf(tempString, "POT %d", Dds_Pot_Val[1]); + FL_DrawString(tempString, xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + if(psu_failed) + { + sprintf(tempString, "PSU Error1"); + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + } + yPos += yInc; + + if((Port_State[MID_SR] & 0x40) > 0) + sprintf(tempString, "Gain HI"); + else + sprintf(tempString, "Gain LO"); + + FL_DrawString(tempString, xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + yPos += yInc; +// yPos += yInc; + + sprintf(tempString, "%d", adc.V_OffsetAdc); + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //voltage offset + if(!adc.vosOK) + { + FL_DrawString("ERR", xCol1 + 30, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + yPos += yInc; + + sprintf(tempString, "%d", adc.I_OffsetAdc); + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); //current offset + if(!adc.iosOK) + { + FL_DrawString("ERR", xCol1 + 30, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + yPos += yInc; + + + + LCD_Update(); +} + + +static void DisplayDiagnostics2(void) +{ + uint32_t xCol1 = 2; + uint32_t xCol2 = 100; + uint32_t yStart = 25; + uint32_t yPos = yStart; + uint32_t yInc = 16; + + + LCD_Clear(); + + //Title + FL_DrawString("DIAGNOSTICS 2", LCD_X_MID, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + +#if 0 + //Column 1: Headings + yPos = yStart; + FL_DrawString("Output", xCol1, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; + + + + //Column 2: values + yPos = yStart; + switch(Cur_Mode) //Show text for MODE + { + case BROADCAST: + sprintf(tempString, "INDUCTION"); + break; + case PORT1_A: + sprintf(tempString, "PORT 1A"); + break; + case PORT1_B: + sprintf(tempString, "PORT 1B"); + break; + case PORT2_A: + sprintf(tempString, "PORT 2A"); + break; + case PORT2_B: + sprintf(tempString, "PORT 1B"); + break; + default: + sprintf(tempString, "Taco"); + break; + } + FL_DrawString(tempString, xCol2, yPos, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + yPos += yInc; +#endif + + LCD_Update(); +} + + + + +static void LinkRadioMenu(void) +{ + +} + + +static void DisplayLinkRadioMenu(uint32_t selected) +{ + +} + + + + +static void FrequenciesMenu(void) +{ + static uint32_t selected = 0; //static = menu selection persists - Is this a good thing? + uint32_t menuExit = 0; + uint32_t numFrequencies = FREQ_GetNumFrequencies(); + + //Draw screen first time + DisplayFrequenciesMenu(selected); + + while(1) + { + //use keys to change selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + switch(pressed) //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_BACK: + menuExit = true; + break; + case ON_OFF_KEY: + menu.exitToMainScreen = true; + break; + case KEY_UP: + if(--selected > numFrequencies) + { + selected = 0; + } + DisplayFrequenciesMenu(selected); + break; + case (KEY_UP << KEY_LONG_PRESS): + do + { + if(--selected > numFrequencies) + { + selected = 0; + } + DisplayFrequenciesMenu(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetUpKeyHeld()); + break; + case KEY_DOWN: + if(++selected >= numFrequencies) + { + selected = numFrequencies - 1; + } + DisplayFrequenciesMenu(selected); + break; + case (KEY_DOWN << KEY_LONG_PRESS): + do + { + if(++selected >= numFrequencies) + { + selected = numFrequencies - 1; + } + DisplayFrequenciesMenu(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetDownKeyHeld()); + break; + case KEY_ENTER: + //Toggle enable on selected frequency + FREQ_ToggleEnable(selected); //selected is same as frequency index + + + DisplayFrequenciesMenu(selected); //Redraw menu after any changes + break; + } + + if(menuExit || menu.exitToMainScreen) + { + return; + } + } + +} + + + +static void DisplayFrequenciesMenu(uint32_t selected) +{ +#if 1 + uint32_t numFrequencies = FREQ_GetNumFrequencies(); + static char displayIndex = 0; //index of first menu line to draw + LCD_Clear(); + + //Title + //FL_DrawString("FREQUENCIES", LCD_X_MID, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + //Update displayIndex + if(selected >= (displayIndex + MENU_MAX_LINES_DISPLAYED)) + { + displayIndex++; + } + else if(selected < displayIndex) + { + displayIndex--; + } + + + //Draw menu items + for(uint32_t i = displayIndex; i < displayIndex + numFrequencies; i++) //this could draw lots of frequencies off the screen but we don't care + { + + + //Frequency name + FREQ_GetFrequencyName(i, tempString); + FL_DrawString(tempString, MENU_MAIN_TEXT_X, MENU_MAIN_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + //checkBoxes + if(FREQ_GetFreqByIndex(i).enabled) + { + GL_DrawMonoBitmap(box_checked, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START +2+ (i - displayIndex)*MENU_LINE_HEIGHT, LCD_DRAW_SET); + } + else + { + GL_DrawMonoBitmap(box_unchecked, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START +2+ (i - displayIndex)*MENU_LINE_HEIGHT, LCD_DRAW_SET); + } + + } + //Draw selection bar + uint32_t selRectY0 = MENU_MAIN_TEXT_Y_START + (selected - displayIndex)*MENU_LINE_HEIGHT; + //GL_DrawFilledRoundedRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, MENU_SEL_RECT_RADIUS, LCD_DRAW_XOR); + GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1A, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); + + + //Draw menu icons + //Use DrawMenuBitmap(mainMenu[i], x, y) + + + DrawMenuScrollBar(displayIndex, numFrequencies); + + LCD_Update(); +#endif +} + + + + + + + +static void LanguageMenu(void) +{ + static uint32_t selected = 0; //static = start language menu where we left off + uint32_t menuExit = 0; + + //Draw screen first time + DisplayLanguageMenu(selected); + KEY_ClearAll(); + + while(1) + { + //use keys to changes selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + switch(pressed) //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_BACK: + menuExit = true; + break; + case ON_OFF_KEY: + menu.exitToMainScreen = true; + break; + case KEY_UP: + selected--; + if(selected > LANG_NUM) + { + selected = 0; + } + DisplayLanguageMenu(selected); + break; + case (KEY_UP << KEY_LONG_PRESS): + do + { + if(--selected > LANG_NUM) + { + selected = 0; + } + DisplayLanguageMenu(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetUpKeyHeld()); + break; + case KEY_DOWN: + selected++; + if(selected >= LANG_NUM) + { + selected = LANG_NUM - 1; + } + DisplayLanguageMenu(selected); + break; + case (KEY_DOWN << KEY_LONG_PRESS): + do + { + if(++selected >= LANG_NUM) + { + selected = LANG_NUM - 1; + } + DisplayLanguageMenu(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetDownKeyHeld()); // Bug fixed KL 6/26/24 + break; + + case KEY_ENTER: + sys.language = selected; //Change language + DisplayLanguageMenu(selected); + break; + } + + if(menuExit || menu.exitToMainScreen) + { + return; + } + } +} + +static void DisplayLanguageMenu(uint32_t selected) +{ + static char displayIndex = 0; //index of first menu line to draw + + LCD_Clear(); + + //Title + //FL_DrawString("LANGUAGE MENU", 240, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + if(selected >= (displayIndex + MENU_MAX_LINES_DISPLAYED)) + { + displayIndex++; + } + else if(selected < displayIndex) + { + displayIndex--; + } + + //Draw menu strings + uint32_t lastIndex = displayIndex + MENU_MAX_LINES_DISPLAYED; + for(uint32_t i = displayIndex; i < lastIndex; i++) + { + //Language name + if(i == LANG_CHINESE || i == LANG_KOREAN) //Simsun for Chinese and Korean + { + FL_DrawTranslatedString(languageNames[i], MENU_MAIN_TEXT_X, MENU_MAIN_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, fontSimsun, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + else + { + FL_DrawTranslatedString(languageNames[i], MENU_MAIN_TEXT_X, MENU_MAIN_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + } + + //checkBoxes + if(SYS_GetLanguage() == i) //language enum matches index + { + GL_DrawMonoBitmap(box_checked, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START +2+ (i - displayIndex)*MENU_LINE_HEIGHT, LCD_DRAW_SET); + } + else + { + GL_DrawMonoBitmap(box_unchecked, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START +2+ (i - displayIndex)*MENU_LINE_HEIGHT, LCD_DRAW_SET); + } + } + + //Draw selection bar + uint32_t selRectY0 = MENU_MAIN_TEXT_Y_START + (selected - displayIndex)*MENU_LINE_HEIGHT; + GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1A, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); + + DrawMenuScrollBar(displayIndex, LANG_MENU_NUM); + + + LCD_Update(); +} + + + + + +static void DisplayRegulatoryInfo(void) +{ + uint32_t caretX = 35; + uint32_t menuX = 50; + uint32_t menuYStart = 30; + uint32_t yInc = 30; + + + LCD_Clear(); + + //Title + FL_DrawTranslatedString("REGULATORY INFO", 240, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + + //TODO: Display radio info here (Tx25 ONLY) + + LCD_Update(); + + while(1) + { + //use keys to changes selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + if((pressed) == KEY_BACK || ON_OFF_KEY) + { + if(pressed == ON_OFF_KEY) + { + menu.exitToMainScreen = true; + } + + return; + } + } +} + + + + + + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +void MENU_Init(void) +{ + //Init testMenu + TM_Init(); + + //Clear menu items + ClearMenuItems(mainMenu, MAIN_MENU_NUM_TX10); + ClearMenuItems(langMenu, LANG_MENU_NUM); + + + //main menu + uint32_t i = 0; + mainMenu[i].pMonoIcon = 0; + strcpy(mainMenu[i++].text, "System Information"); //System info screen + + mainMenu[i].pMonoIcon = 0; + strcpy(mainMenu[i++].text, "Frequencies"); //Frequency Selection Menu + + mainMenu[i].pMonoIcon = 0; + strcpy(mainMenu[i++].text, "Auto Shutdown"); //Auto Shutdown selection + + mainMenu[i].pMonoIcon = 0; + strcpy(mainMenu[i++].text, "Language"); //Language Selection Menu +#if 0 + mainMenu[i].pMonoIcon = 0; + strcpy(mainMenu[i++].text, "Link Radio"); //Link Radio Menu + + //no regulatory info on the Tx10 + mainMenu[i].pMonoIcon = 0; + strcpy(mainMenu[i++].text, "Regulatory Info"); //Reset - Needs a new name +#endif + + //check for array over run + if(i > MAIN_MENU_NUM_TX10) + { + while(1); + } + + //language menu + i = 0; + langMenu[i].pMonoIcon = 0; + strcpy(langMenu[i].text, languageNames[i++]); + + langMenu[i].pMonoIcon = 0; + strcpy(langMenu[i].text, languageNames[i++]); + + langMenu[i].pMonoIcon = 0; + strcpy(langMenu[i].text, languageNames[i++]); + + langMenu[i].pMonoIcon = 0; + strcpy(langMenu[i].text, languageNames[i++]); + + //check for array over run + if(i > LANG_MENU_NUM) + { + while(1); + } + + +} + + +void MENU_Main(void) +{ + static uint32_t selected = 0; //static = menu selection persists - Is this a good thing? + uint32_t menuNum = MAIN_MENU_NUM_TX10; + uint32_t menuExit = 0; + + //Draw screen first time + MENU_DisplayMain(selected); + + + while(1) + { + //use keys to changes selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + switch(pressed) //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_BACK: + menuExit = true; + break; + case ON_OFF_KEY: + menu.exitToMainScreen = true; + break; + case KEY_UP: + if(--selected > menuNum) + { + selected = 0; + } + MENU_DisplayMain(selected); + break; + case (KEY_UP << KEY_LONG_PRESS): + do + { + if(--selected > menuNum) + { + selected = 0; + } + MENU_DisplayMain(selected); + + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetUpKeyHeld()); + break; + case KEY_DOWN: + if(++selected >= menuNum) + { + selected = menuNum - 1; + } + MENU_DisplayMain(selected); + break; + case (KEY_DOWN << KEY_LONG_PRESS): + do + { + if(++selected >= menuNum) + { + selected = menuNum - 1; + } + MENU_DisplayMain(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetDownKeyHeld()); + break; + case KEY_ENTER: + switch(selected) + { + case(0): //System Info Menu + SystemInfoMenu(); + break; + case(1): //Frequency menu + FrequenciesMenu(); + break; + case(2): //Auto shut down + tmr_ChangeAutoSDTimer(); + break; + case(3): //Language menu + LanguageMenu(); + break; + case(4): //Link Radio + //LinkRadioMenu(); + break; + case(5): //Regulatory + DisplayRegulatoryInfo(); + break; + default: + break; + } + if(!menu.exitToMainScreen) + { + MENU_DisplayMain(selected); //Redraw menu after any changes + } + break; + } + + if(menuExit || menu.exitToMainScreen) + { + menu.exitToMainScreen = false; + //SYS_SaveSettings(); + return; + } + } +} + +void MENU_DisplayMain(uint32_t selected) +{ + char displayIndex = 0; //index of first menu line to draw + uint32_t menuNum = MAIN_MENU_NUM_TX10; + + LCD_Clear(); + //Title + //'FL_DrawString("MAIN MENU", 240, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + //Update displayIndex + if(selected >= (displayIndex + MENU_MAX_LINES_DISPLAYED)) + { + displayIndex++; + } + else if(selected < displayIndex) + { + displayIndex--; + } + + + //Draw menu items + for(uint32_t i = displayIndex; i < displayIndex + menuNum; i++) //this can draw extra lines off the screen but we don't care + { + //Menu strings + FL_DrawTranslatedString(mainMenu[i].text, MENU_MAIN_TEXT_X, MENU_MAIN_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + //Draw item status + switch(i) + { + case(0): //System Info screen + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + case(1): //Frequency + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + case(2): //Auto Shutdown + FL_DrawTranslatedString(tmr_GetAutoSDTimerString(), MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case(3): //Language + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + case(4): //Link radio + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + + case(5): //Regulatory + + break; + case(6): //Not used + break; + default: + break; + } + } + + //Draw selection bar + uint32_t selRectY0 = MENU_MAIN_TEXT_Y_START + (selected - displayIndex)*MENU_LINE_HEIGHT; + //GL_DrawFilledRoundedRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, MENU_SEL_RECT_RADIUS, LCD_DRAW_XOR); + GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); + + //Draw menu icons + //Use DrawMenuBitmap(mainMenu[i], x, y) + + + DrawMenuScrollBar(displayIndex, menuNum); + + + LCD_Update(); +} + + + + + + diff --git a/source/menu.h b/source/menu.h new file mode 100644 index 0000000..d409d9f --- /dev/null +++ b/source/menu.h @@ -0,0 +1,84 @@ +/* + * menu.h + * + * Created on: Mar 8, 2022 + * Author: Brian.Bailey + * + * Each menu has two functions: XMenu() and DisplayXMenu(), where X is the menu type + * XMenu() handles key presses + * DisplayXMenu(line) draws the menu using the arg as the selected menu line + * + * + * + * + */ + +#ifndef MENU_MENU_H_ +#define MENU_MENU_H_ + +#include +#include + +//Menu Setup +#define MENU_SYS_INFO_NUM 3 //System info and diagnostics + +#define MAIN_MENU_NUM_TX10 4 //Tx10 +#define MAIN_MENU_NUM_TX25 6 //Tx25 has Link Radio and Regulatory menus +#define LINK_MENU_NUM 3 +#define LANG_MENU_NUM 4 //This can use LANG_NUM enum + +//Menu scrolling +#define MENU_MAX_LINES_DISPLAYED 6 +#define MENU_KEY_HOLD_SCROLL_DELAY 10 //increments of DelayTicks + +#define MENU_LINE_HEIGHT 21 + +//Main Menu drawing locations +#define MENU_MAIN_BMP_X 0 //bitmap x +#define MENU_MAIN_BMP_Y 0 //bitmap y +#define MENU_MAIN_TEXT_X 5 //main text x +#define MENU_MAIN_TEXT_Y_START 0 //main text y starting value (start + n*lines) +#define MENU_MAIN_STATUS_X 160 //x location of text describing status of the menu item +#define MENU_MAIN_STATUS_Y_OFF 4 //y offset for menu status icons + +//Submenu drawing locations - NOT USED +#define MENU_SUB_TEXT_X 5 //submenu text x +#define MENU_SUB_TEXT_Y_START 0 //submenu text y starting value (start + n*lines) +#define MENU_SUB_STATUS_X 160 //x location of text describing status of the menu item + + +#define MENU_MAX_STRING_LENGTH 20 + +#define MENU_FONT font12Bold + + + +//Selection Rectangle +#define MENU_SEL_RECT_X0 0 +#define MENU_SEL_RECT_X1 239 +#define MENU_SEL_RECT_X1A 200 + +#define MENU_SEL_RECT_RADIUS 5 + +typedef struct { + bool exitToMainScreen; +}MENU_t; + + +//Menu Item Struct +//contains pointers to both mono and color bitmaps. mono bitmap requires a color. +//each item may have a mono bitmap, a color bitmap, or no bitmap. +typedef struct { + + uint16_t * pMonoIcon; // bitmap + char text[MENU_MAX_STRING_LENGTH]; +}MENU_ITEM_t; + + +void MENU_Init(void); +void MENU_Main(void); +void MENU_DisplayMain(uint32_t selected); + + + +#endif /* MENU_MENU_H_ */ diff --git a/source/menu1.c b/source/menu1.c new file mode 100644 index 0000000..1d3fcfe --- /dev/null +++ b/source/menu1.c @@ -0,0 +1,30 @@ +/* + * menu.c + * + * Created on: Jun 27, 2022 + * Author: Keith.Lloyd + */ + + +#include + +#include "menu.h" + + + + + + +void menu_key(void) +{ + +// Display_Menu(); // "wireless on/off,link, Power down timer,language,frequencies" + MENU_Main(); + + + +} + + + + diff --git a/source/menu1.h b/source/menu1.h new file mode 100644 index 0000000..ff42b59 --- /dev/null +++ b/source/menu1.h @@ -0,0 +1,13 @@ +/* + * menu.h + * + * Created on: Jun 27, 2022 + * Author: Keith.Lloyd + */ + +#ifndef MENU1_H_ +#define MENU1_H_ + +void menu_key(void); + +#endif /* MENU1_H_ */ diff --git a/source/mode.c b/source/mode.c new file mode 100644 index 0000000..827bd7c --- /dev/null +++ b/source/mode.c @@ -0,0 +1,111 @@ +/* + * mode.c + * + * Created on: Jun 27, 2022 + * Author: Keith.Lloyd + */ + +#include "spi.h" +#include +#include +#include +#include +#include "arm_math.h" +#include "display.h" +#include "timer.h" +#include "mode.h" +#include "ports.h" + +extern uint8_t Port_State[]; +extern uint8_t LD_Flag; +uint8_t Cur_Mode, Old_Mode, Port_changed_flag; // Currently selected mode and last +MODE_REC_t mode_Array[MODE_MAX_NUM]; + +void mode_menu(void) +{ + + uint32_t value = 22370; // testing only + uint32_t tmp; + + static bool keithistan = false; + + +// Delay_Ticks(10); + keithistan ^= 1; //toggle + + Select_Next_Mode(); // + + Port_changed_flag = true; + + if(Cur_Mode == BROADCAST) + LD_Flag = false; +} + +void Select_Next_Mode() +{ + // Save currently selected mode + Old_Mode = Cur_Mode; + Cur_Mode = Next_Available_Mode(Cur_Mode); // find next Mode available + +// if(Cur_Mode != Old_Mode) +// Set_Up_New_Mode(); + +// Display_Mode(Cur_Mode); // Display the currently selected mode + + +} +void Set_Up_New_Mode() +{ + if (Old_Mode > 0) + { + mode_Array[Old_Mode].Selected = false; + mode_Array[Cur_Mode].Selected = true; + } +} + + + +uint8_t Next_Available_Mode(uint8_t mode_tmp) +{ + + uint8_t found = false; + uint8_t i; + +// mode_tmp = Cur_Mode; + + if (mode_tmp < MODE_MAX_NUM - 1) + mode_tmp++; + else + mode_tmp = 0; + + for(i=0; i < MODE_MAX_NUM - 1; i++) + { + if(mode_Array[mode_tmp].Selected > 0) + { + found = 1; + break; + } + if (mode_tmp < MODE_MAX_NUM - 1) + mode_tmp++; + else + mode_tmp= 0; + } + + return(mode_tmp); +} + +void Display_available_Modes(void) +{ +// if (DC_Available()) +// { +// } +} + +void Select_All_Modes() +{ + uint8_t i; + + for(i = 0;i < MODE_MAX_NUM-1; i++) + mode_Array[i].Selected = true; + +} diff --git a/source/mode.h b/source/mode.h new file mode 100644 index 0000000..af09f7b --- /dev/null +++ b/source/mode.h @@ -0,0 +1,41 @@ +/* + * mode.h + * + * Created on: Jun 27, 2022 + * Author: Keith.Lloyd + */ + +#ifndef MODE_H_ +#define MODE_H_ + +#define MODE_MAX_NUM 5 + +//typedef enum { +// DIRECT_CONNECT = 0, +// BROADCAST = 1 +//}CONNECT_MODE_t; + +typedef enum { + BROADCAST, + PORT1_A, + PORT1_B, + PORT2_A, + PORT2_B +}PLUG_MODE_t; + +//Data for individual frequencies +typedef struct { + uint8_t Plugged; //frequency in Hz + uint8_t Selected; +}MODE_REC_t; + + +void mode_menu(void); +void Display_available_Modes(void); +void Select_Next_Mode(void); +//void Next_Available_Mode(void); +uint8_t Next_Available_Mode(uint8_t mode_tmp); +void Init_Mode(void); +void Set_Up_New_Mode(void); + +#endif /* MODE_H_ */ diff --git a/source/over_ride.c b/source/over_ride.c new file mode 100644 index 0000000..734022f --- /dev/null +++ b/source/over_ride.c @@ -0,0 +1,16 @@ +/* + * over_ride.c + * + * Created on: Jun 30, 2022 + * Author: Keith.Lloyd + */ + + +void Over_Ride(void) +{ + // display Over ride message + + + // wait for user response + +} diff --git a/source/over_ride.h b/source/over_ride.h new file mode 100644 index 0000000..b79c42f --- /dev/null +++ b/source/over_ride.h @@ -0,0 +1,14 @@ +/* + * over_ride.h + * + * Created on: Jun 30, 2022 + * Author: Keith.Lloyd + */ + +#ifndef OVER_RIDE_H_ +#define OVER_RIDE_H_ + +void Over_Ride(void); + + +#endif /* OVER_RIDE_H_ */ diff --git a/source/ports.c b/source/ports.c new file mode 100644 index 0000000..1eadc2f --- /dev/null +++ b/source/ports.c @@ -0,0 +1,625 @@ +/* + * ports.c + * + * Created on: Mar 21, 2023 + * Author: Keith.Lloyd + */ +/* + * Return accessory associated with voltage read + */ +#include "fsl_spi.h" +#include "pin_mux.h" +#include "board.h" +#include "fsl_debug_console.h" + +#include +#include +#include "arm_math.h" +#include "ports.h" +#include "frq.h" +#include "spi.h" +#include "display.h" +#include "utils.h" +#include "adc.h" +#include "mode.h" +#include "psu_ctrl.h" +#include "timer.h" +#include "init.h" +#include "amps.h" +#include "fsl_sctimer.h" +#include "pwm.h" +#include "pwr_level.h" + +ACCESSORY_t accy1; +ACCESSORY_t accy2; +uint16_t Port_timer; +uint16_t Taps_adjust_timer; +extern uint8_t Port_changed_flag,Init_Done; +extern ADC_t adc; +extern uint8_t Port_State[],Cur_Mode,old_freq,Bcast_Pwr_Level,Bcast_LF_Value[],Bcast_HF_Value[],Power_Level; +extern MODE_REC_t mode_Array[MODE_MAX_NUM]; +extern uint8_t frequency,Over_Voltage_Flag; +extern FREQUENCY_t freqArray[FREQ_MAX_NUM]; +extern volatile uint8_t BC_Duty_Cycle; +extern uint16_t Pot_Value_AB[]; +extern uint16_t Pot_Value[]; +extern uint8_t Dds_Pot_Val[]; + + +uint8_t whatever; + +static ACCY_ID_t ReadAccessory(uint8_t port) +{ + float32_t idVoltage = 0.0; + if(port == 1) + idVoltage = adc.V_ID1; //idVoltage = ANA_GetVAccyDetect(); //TODO: Write this function + else + idVoltage = adc.V_ID2; + //ID 0 through 11. Voltage target is ID * 0.3v + + uint32_t idNumber = (uint32_t)((idVoltage * 3.3333) + 0.25); //multiply by 3.3333 and round down to nearest integer + + + return (ACCY_ID_t)idNumber; +} + +void Disconnect(uint8_t port) // called when you disconnect +{ + if (port ==1) + { + accy1.connected = ID_NONE; + accy1.consecutiveScans = 0; + accy1.isConnected = false; + + //Change Mode if this accessory was selected + if(mode_Array[PORT1_A].Selected || mode_Array[PORT1_B].Selected) + { + //disconnect port 1 from keith's struct + mode_Array[PORT1_A].Selected = 0; + mode_Array[PORT1_B].Selected = 0; + + if ((Cur_Mode > BROADCAST) && (Cur_Mode ==PORT1_A) || (Cur_Mode == PORT1_B) ) //and change mode + Cur_Mode = Next_Available_Mode(Cur_Mode); // find next Mode available + } + else + { + //disconnect port 1 from keith's struct + mode_Array[PORT1_A].Selected = 0; + mode_Array[PORT1_B].Selected = 0; + } + } + else //port 2 + { + accy2.connected = ID_NONE; + accy2.consecutiveScans = 0; + accy2.isConnected = false; + + //Change Mode if this accessory was selected + if(mode_Array[PORT2_A].Selected || mode_Array[PORT2_B].Selected) + { + //disconnect port 2 from keith's struct + mode_Array[PORT2_A].Selected = 0; + mode_Array[PORT2_B].Selected = 0; + + if ((Cur_Mode > BROADCAST) && (Cur_Mode == PORT2_A) || (Cur_Mode == PORT2_B) ) //and change mode + // Cur_Mode = Next_Available_Mode(Cur_Mode); // find next Mode available + { + if (mode_Array[PORT1_A].Selected || mode_Array[PORT1_B].Selected) //and change mode + Cur_Mode = PORT1_A; + else + Cur_Mode = Next_Available_Mode(Cur_Mode); // find next Mode available + } + // + // else +// Cur_Mode = 1; +// if (Cur_Mode > 0) +// { +// if (mode_Array[1].Selected || mode_Array[2].Selected) //and change mode +// Cur_Mode = 1; +// else +// Cur_Mode = Next_Available_Mode(Cur_Mode); // find next Mode available +// } + } + else + { + //disconnect port 1 from keith's struct + mode_Array[PORT2_A].Selected = 0; + mode_Array[PORT2_B].Selected = 0; + } + } + Port_changed_flag = true; // added 10/2/23 + Init_Done = false; // 3/20/24 Force a Power Level One change + + //Configure frequency to make sure things are setup correctly +// Tx_ConfigureFrequency(); +} +void ACCY_Init(void) +{ + accy1.connected = ID_NONE; + accy1.consecutiveScans = 0; + accy1.isConnected = false; + + accy2.connected = ID_NONE; + accy2.consecutiveScans = 0; + accy2.isConnected = false; + + Port_timer = DELAY_100MS; + Port_changed_flag = false; + + //Setup accessory for GPIO gain control +// InitAccessoryGainGPIO(); +} +//Call @ 10Hz to detect, connect, and disconnect accessories +void ACCY_Update1(void) +{ + //read ID voltage and determine connected accessory *for each port* + + //Require same accessory detected 3 consecutive updates (to de-glitch) + + //Read accessory voltage and identify accessory + + ACCY_ID_t detected = ReadAccessory(1); + + if(accy1.connected == ID_NONE) //Nothing connected. Look for accessory to connect + { + + if((detected == accy1.lastDetected) && (detected != ID_NONE)) //If detected same as last time and not ID_NONE + { + + if(++accy1.consecutiveScans == AC_NUM_SCANS_TO_CONNECT) //Connect on 3rd consecutive scan of same accessory + { + ACCY_Connect1(accy1.lastDetected); //CONNECT + } + } + else //If different than last scan + { + accy1.lastDetected = detected; //remember what was scanned last time + accy1.consecutiveScans = 0; + } + + } + else if (detected != accy1.connected) //If connected and detected reads different, disconnect + { + Disconnect(1); + } + +} +//Call @ 10Hz to detect, connect, and disconnect accessories +void ACCY_Update2(void) +{ + //read ID voltage and determine connected accessory *for each port* + + //Require same accessory detected 3 consecutive updates (to de-glitch) + + //Read accessory voltage and identify accessory + + ACCY_ID_t detected = ReadAccessory(2); + + whatever = ReadAccessory(2); + + if(accy2.connected == ID_NONE) //Nothing connected. Look for accessory to connect + { + + if((detected == accy2.lastDetected) && (detected != ID_NONE)) //If detected same as last time and not ID_NONE + { + + if(++accy2.consecutiveScans == AC_NUM_SCANS_TO_CONNECT) //Connect on 3rd consecutive scan of same accessory + { + ACCY_Connect2(accy2.lastDetected); //CONNECT + } + } + else //If different than last scan + { + accy2.lastDetected = detected; //remember what was scanned last time + accy2.consecutiveScans = 0; + } + + } + else if (detected != accy2.connected) //If connected and detected reads different, disconnect + { + Disconnect(2); + } + +} +/* + * Connect accessory + */ +void ACCY_Connect1(ACCY_ID_t id) +{ + accy1.connected = id; + accy1.isConnected = true; + + switch(id) + { + case ID_TX_SINGLE_DIRECT: + Port_changed_flag = true; //connect it + break; + case ID_TX_DUAL_DIRECT: + Port_changed_flag = true; //connect it + break; + case ID_CLAMP: + Port_changed_flag = true; //connect it + break; + case ID_CLAMP2: + Port_changed_flag = true; //connect it + break; + + + default: + accy1.connected = ID_NONE; + accy1.isConnected = false; + } + + + //Configure frequency to make sure things are setup correctly +// Tx_ConfigureFrequency(); + +} +void ACCY_Connect2(ACCY_ID_t id) +{ + accy2.connected = id; + accy2.isConnected = true; + + switch(id) + { + case ID_TX_SINGLE_DIRECT: + Port_changed_flag = true;//connect it + break; + case ID_TX_DUAL_DIRECT: + Port_changed_flag = true;//connect it + break; + case ID_CLAMP: + Port_changed_flag = true;//connect it + break; + case ID_CLAMP2: + Port_changed_flag = true;//connect it + break; + + default: + accy2.connected = ID_NONE; + accy2.isConnected = false; + } + + + //Configure frequency to make sure things are setup correctly +// Tx_ConfigureFrequency(); + +} +bool ACCY_IsConnected1(uint8_t port) +{ + if(port == 1) + return accy1.isConnected; + else + return accy2.isConnected; + +} + +ACCY_ID_t ACCY_GetConnectedAccessory(uint8_t port) +{ + if(port == 1) + return accy1.connected; + else + return accy2.connected; + +} + +ACCY_ID_t ACCY_GetActive(void) +{ + if(Cur_Mode == PORT1_A) + { + return ACCY_GetConnectedAccessory(1); + } + else + { + return ACCY_GetConnectedAccessory(2); + + } +} + + +void Read_Tx_Ports(void) // check for whats plugged in at the ports every 100mS. +{ +uint8_t chip; + + Port_timer = DELAY_100MS; + + + ACCY_Update1(); + + if((mode_Array[PORT1_A].Selected == false) && (mode_Array[PORT1_B].Selected == false) && (accy1.isConnected)) //new bit here + Cur_Mode = PORT1_A; // Something is connected to PORT1 + + switch(accy1.connected) // Find out what it is + { + case ID_TX_DUAL_DIRECT: //Transmitter accessory + mode_Array[PORT1_A].Selected = accy1.isConnected; + mode_Array[PORT1_B].Selected = accy1.isConnected; + break; + + case ID_TX_SINGLE_DIRECT: + mode_Array[PORT1_A].Selected = accy1.isConnected; + break; + + case ID_CLAMP: + mode_Array[PORT1_A].Selected = accy1.isConnected; + break; + + case ID_CLAMP2: + mode_Array[PORT1_A].Selected = accy1.isConnected; + break; + + default: //empty + mode_Array[PORT1_A].Selected = accy1.isConnected; + mode_Array[PORT1_B].Selected = accy1.isConnected; + } + + + ACCY_Update2(); + if((mode_Array[PORT2_A].Selected == false) && (mode_Array[PORT2_B].Selected == false) && (accy2.isConnected)) //new bit here + Cur_Mode = PORT2_A; + + switch(accy2.connected) + { + case ID_TX_DUAL_DIRECT: //Transmitter accessory + mode_Array[PORT2_A].Selected = accy2.isConnected; + mode_Array[PORT2_B].Selected = accy2.isConnected; + break; + + case ID_TX_SINGLE_DIRECT: + mode_Array[PORT2_A].Selected = accy2.isConnected; + break; + + case ID_CLAMP: + mode_Array[PORT2_A].Selected = accy2.isConnected; + break; + case ID_CLAMP2: + mode_Array[PORT2_A].Selected = accy2.isConnected; + break; + + default: //empty + mode_Array[PORT2_A].Selected = accy2.isConnected; + mode_Array[PORT2_B].Selected = accy2.isConnected; + + + } + +} + + + +void Select_Output_Port(void) // which DC Out port, to switch on +{ + + Port_State[MID_SR] &= OUT_RELAY_OFF_MASK; + + if (Cur_Mode != BROADCAST) + { + Delay_Ticks(DELAY_100MS); + + if(Compare_Voltage(adc.V_CHK, MAX_BYPASS_VOLTS)) + { + Over_Voltage_Flag = true; + Select_Bypass(OFF); // Force into blocked state. + Delay_Ticks(20); + + } + + Select_Estop(OFF); // Ensure output is not ISOLATED from connections + + switch (Cur_Mode) + { + case PORT1_A: + Port_State[MID_SR] |= PORT1A_ON; + break; + case PORT1_B: + Port_State[MID_SR] |= PORT1B_ON; + break; + case PORT2_A: + Port_State[MID_SR] |= PORT2A_ON; + break; + case PORT2_B: + Port_State[MID_SR] |= PORT2B_ON; + break; + default: + Port_State[MID_SR] |= PORT2B_ON; // TODO Later disconnect?? + break; + } + Disable_BC(); + Reset_Power_Gain(); + Port_changed_flag = false; + SPI0_SendBytes(Port_State, 3, EXPANDER); + } + + else + { // Assumes broadcast mode has just been selected + Disable_DC(); // Shut down Direct connect circuitry + Select_Estop(ON); // Ensure output is ISOLATED from connections + + Tx_ConfigureFrequency(); // Select correct frequency + Enable_BC(); // Enable BCAST circuitry using either Minimum or previously selected freq + + Port_changed_flag = false; + + } + +} + + +void Reset_Power_Gain(void) +{ + Power_Level = 0; + Bcast_Pwr_Level = 0; + +// if( (ACCY_GetConnectedAccessory(1) != ID_CLAMP) && (ACCY_GetConnectedAccessory(2) != ID_CLAMP)) + if(!Check_For_Clamp()) + { + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + Dds_Pot_Val[1] = Pot_Value[Power_Level]; // data + else + Dds_Pot_Val[1] = Pot_Value_AB[Power_Level]; // data + } + else + Get_Clamp_Value(); + + + + Dds_Pot_Val[0] = 0; // address + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + Delay_Ticks(30); // Set power out level 1 3/20/24 + +// Power_Level = 1; +// if(Init_Done) +// { +// Delay_Ticks(10); // Set power out level 1 3/20/24 +// Power_Level++; +// inc_pwr(); + Init_Done = false; +// } +} + + + +void Tx_ConfigureFrequency(void) +{ +uint32_t tmp_frq; + + if (freqArray[frequency].bc_enabled == false && Cur_Mode == BROADCAST) // if (freq < min freq) ToDo + { + tmp_frq = Search_BC_Frequency(); // select minimum frequency for BCAST + if (tmp_frq < FREQ_MAX_NUM) + frequency = tmp_frq; + //endif + } + +} + + +uint32_t Search_BC_Frequency(void) +{ +uint32_t idx; + idx = 0; + while (freqArray[idx].bc_enabled == false && idx < FREQ_MAX_NUM) + idx++; + + if (idx >= FREQ_MAX_NUM) + idx = FREQ_MAX_NUM; + + return(idx); +} + + +uint32_t Search_Frequency(uint32_t pattern) +{ +uint32_t idx; + idx = 0; + while (freqArray[idx].frequency1 != pattern && idx < FREQ_MAX_NUM) + idx++; + + if (idx >= FREQ_MAX_NUM) + idx = FREQ_MAX_NUM; + + return(idx); +} + +void Disable_DC(void) +{ + All_Amps_Off(); // shut down Amplifiers DC connections + // Shut off all amplifier enables + +// Reset_DDS(); // Stop all DDS chips + +// Set_PSU_Voltage(V_18V); //MID_POINT_PSU 18,24,27,30,36, 55 + // Set PSU to MIN. +} + +void Enable_BC(void) +{ + +// if((freqArray[old_freq].frequency1 >8010 ) && (freqArray[frequency].frequency1 < 8010)) +// Cycled_Freq_Change_BC(LF); +// else +// { +// if((freqArray[old_freq].frequency1 < 8010 ) && (freqArray[frequency].frequency1 > 8010)) +// Cycled_Freq_Change_BC(HF); +// } + if(freqArray[frequency].frequency1 <= 8010) + BC_Duty_Cycle = Bcast_LF_Value[Bcast_Pwr_Level]; + else + BC_Duty_Cycle = Bcast_HF_Value[Bcast_Pwr_Level]; + + + PWM_Setup(freqArray[frequency].frequency1, BC_Duty_Cycle);//freqArray[frequency].frequency1 + + + Port_State[MID_SR] |=ANT_AMP_EN; // Enable Antenna amp +// Port_State[BOTTOM_SR] |= ANT_AMP_PWR; // Enable PWR Switch + Port_State[TOP_SR] |= ANT_AMP_SW; + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + Delay_Ticks(5); + + Set_PSU_Voltage(V_27V); // Set PSU to MAX + Port_State[BOTTOM_SR] &= AMP_PSU_ON; // switch AMP PSU on + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + + +} + +void Cycled_Freq_Change_BC(uint8_t value) +{ + if(value == LF) + { + if(Bcast_Pwr_Level == MAX_BCAST_PWR) + Bcast_Pwr_Level--; + + BC_Duty_Cycle = 10; + BC_Duty_Cycle = BC_Duty_Cycle + Bcast_Pwr_Level*5; + } + else + { + BC_Duty_Cycle = 10; + BC_Duty_Cycle = BC_Duty_Cycle + Bcast_Pwr_Level*10; + + } + +} + + + +void Enable_DC(void) +{ + // Switch on correct amplifier enables + + // Switch on correct power switches + + + // Enable correct DDS chips + + // Set PSU to Medium. +} +void Disable_BC(void) +{ + Port_State[MID_SR] &=~ANT_AMP_EN; // disable Antenna amp +// Port_State[BOTTOM_SR] |=ANT_AMP_PWR; // Enable PWR Switch + Port_State[TOP_SR] &= ~ANT_AMP_SW; + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + +// Change the SCT clock back here + PWM_Setup(15890, 0); // switches off PWM // Set duty cycle to zero + + Delay_Ticks(5); + + Set_PSU_Voltage(V_24V); // Set PSU to MIN + + +// Init_PWM_CLKS(DC_CLK); // Return timer clock to internal + +} +bool Is_Clamp_Detected(void) +{ + if((ACCY_GetConnectedAccessory(1) == ID_CLAMP) || (ACCY_GetConnectedAccessory(2) == ID_CLAMP) || (ACCY_GetConnectedAccessory(1) == ID_CLAMP2) || (ACCY_GetConnectedAccessory(2) == ID_CLAMP2)) + return(true); + else + return(false); + +} diff --git a/source/ports.h b/source/ports.h new file mode 100644 index 0000000..2d545b8 --- /dev/null +++ b/source/ports.h @@ -0,0 +1,79 @@ +/* + * ports.h + * + * Created on: Mar 21, 2023 + * Author: Keith.Lloyd + */ + +#ifndef PORTS_H_ +#define PORTS_H_ + +typedef enum { + ID_ERROR = 0, //0V should never happen. Error condition + ID_TX_SINGLE_DIRECT, //Transmitter accessory + ID_TX_DUAL_DIRECT, //Transmitter accessory + ID_TX_TBD1, // + ID_CLAMP2, // + ID_CLAMP, //Receiver Clamp + ID_TBD1, // + ID_DIGITAL, //Digital Accessory - Use for EMS boot in future + ID_FAULT_PROBE, //Fault Probe + ID_TBD2, // + ID_TBD3, // + ID_NONE, //No accessory connected + ID_NUM +}ACCY_ID_t; + + +typedef struct { + bool isConnected; //Accessory is connected + ACCY_ID_t connected; //Currently connected accessory + ACCY_ID_t lastDetected; //accessory detected last scan + uint32_t consecutiveScans; //number of consecutive scans of same accessory + +}ACCESSORY_t; + +#define DELAY_100MS 10 +#define DELAY_ONE_SECOND 100 + +#define AC_NUM_SCANS_TO_CONNECT 3 //require 3 consecutive scans to connect to accessory + +#define A1_SLCT 0b00000000 +#define A2_SLCT 0b00010000 +#define B1_SLCT 0b00001000 +#define B2_SLCT 0b00011000 +#define TOP_SR 0 //0 +#define MID_SR 1 +#define BOTTOM_SR 2 //1 +#define LF false +#define HF true + +typedef enum { + ONE, + TWO, + THREE, + FOUR +}OUTPUT_SELECT_t; + + +void ACCY_Init(void); +void ACCY_Update1(void); +void ACCY_Update2(void); +void Read_Tx_Ports(void); // check for whats plugged in at the ports. +void Tx_ConfigureFrequency(void); +void ACCY_Connect1(ACCY_ID_t id); +void ACCY_Connect2(ACCY_ID_t id); +bool ACCY_IsConnected(uint8_t port); +ACCY_ID_t ACCY_GetConnectedAccessory(uint8_t port); +ACCY_ID_t ACCY_GetActive(void); +void Select_Output_Port(void); // Mutually exclusive output port selector +void Enable_BC(void); +void Disable_DC(void); +void Disable_BC(void); +void Disconnect(uint8_t port); // called when you disconnect +uint32_t Search_BC_Frequency(void); +uint32_t Search_Frequency(uint32_t pattern); +bool Is_Clamp_Detected(void); +void Cycled_Freq_Change_BC(uint8_t value); +void Reset_Power_Gain(void); +#endif /* PORTS_H_ */ diff --git a/source/pro_key.c b/source/pro_key.c new file mode 100644 index 0000000..a66c4be --- /dev/null +++ b/source/pro_key.c @@ -0,0 +1,116 @@ +/* + * pro_key.c + * + * Created on: Jun 27, 2022 + * Author: Keith.Lloyd + */ + +#include "pro_key.h" +#include +#include +#include "keys.h" +#include "frq.h" +#include "display.h" +#include "main.h" +#include "timer.h" +#include "pwr_level.h" +#include "mode.h" +#include "ports.h" +#include "utils.h" + +extern uint8_t Task,Cur_Mode,Suspend_Step_Chk,step_count; +extern uint8_t frequency,old_freq,frq_chg_tmr; +extern uint32_t new_freq; +extern uint16_t Vchktmr,Key_Lock_Out_tmr; +uint8_t keyval; +extern uint8_t Port_State[]; + +#if 1 +void pro_key(void) +{ + uint32_t tmp_frqx; + + switch(KEY_GetPressed())//(key_bits) + { + //TODO: cases need to use the key #defines from keys.c and keys.h + case ON_OFF_KEY: // Begin Primary Key + Task = PWR_OFF_TASK; + break; + + + case KEY_POWER: // Long press power Key + Task = PWR_OFF_TASK; + break; + + + case FRQ_KEY: + freq_key_process(); + break; + +// case KEY_FREQ << KEY_LONG_PRESS: //Enable/Disable CD(LD). +// LD_key_process(); +// break; + + case PWR_UP_KEY: + if(Key_Lock_Out_tmr == 0) + { + Vchktmr = LOCK_OUT_DELAY; + inc_pwr();//increment the power output + Key_Lock_Out_tmr = KEY_LOCK_TIME; + Suspend_Step_Chk = false; + step_count = 0; + } + break; + + + case PWR_DN_KEY: + if(Key_Lock_Out_tmr == 0) + { + Vchktmr = LOCK_OUT_DELAY; + dec_pwr();// decrement the power output + Key_Lock_Out_tmr = KEY_LOCK_TIME; + Suspend_Step_Chk = false; + step_count = 0; + } + break; + + + case MENU_KEY: + Task = MENU_TASK; // display the menus + break; + + + case MODE_KEY: // End Primary Key +// Task = MODE_TASK; // Display the Modes + + + #if 0 //Use mode key to toggle current gain + if(Port_State[MID_SR] & I_GAIN) + { + Port_State[MID_SR] &= ~I_GAIN; + } + else + { + Port_State[MID_SR] |= I_GAIN; + } + SPI0_SendBytes(Port_State, 3, EXPANDER); + //Sys_Chk_tmr = DELAY_1S; +#else + Task = MODE_TASK; // Display the Modes +#endif + break; + + +// break; + + + default: + + break; + + + } + + +} +#endif diff --git a/source/pro_key.h b/source/pro_key.h new file mode 100644 index 0000000..5cd9b72 --- /dev/null +++ b/source/pro_key.h @@ -0,0 +1,25 @@ +/* + * pro_key.h + * + * Created on: Jun 27, 2022 + * Author: Keith.Lloyd + */ + +#ifndef PRO_KEY_H_ +#define PRO_KEY_H_ +#include "keys.h" + + +#define BKLITE_KEY 0x0f9 +#define OPT_KEY 0x0f8 +#define OVER_RIDE_KEY 0x0f7 +#define PRIMARY_KEY 1 +#define KEY_DELAY 10 +#define TASK_PWR_DN 0x00; + + + +void pro_key(void); +void LD_key_process(void); + +#endif /* PRO_KEY_H_ */ diff --git a/source/psu_ctrl.c b/source/psu_ctrl.c new file mode 100644 index 0000000..929512b --- /dev/null +++ b/source/psu_ctrl.c @@ -0,0 +1,138 @@ +/* + * psu_ctrl.c + * + * Created on: Mar 16, 2023 + * Author: Keith.Lloyd + */ +#include "psu_ctrl.h" +#include "arm_math.h" +#include "fsl_gpio.h" +#include "spi.h" +#include "mode.h" +#include "amps.h" +#include "frq.h" +#include "adc.h" +#include "timer.h" +#include "utils.h" + +#include +#include + + + + +uint8_t PSU_Val_Limit; +uint8_t Psu_Pot_Val[2]; // 2 byte Data for SPI +extern uint8_t frequency; +uint8_t mode,psu_index; +extern uint8_t Power_Level; +uint8_t Psu_Pot_Data[5] = {V_18V,V_24V,V_27V,V_36V,V_55V}; // PSU Pot values. + +extern ADC_t adc; + + +void Set_PSU_Voltage(uint8_t value) +{ + Psu_Pot_Val[0] = 0x0; + + Psu_Pot_Val[1] = value; + + Get_Max_PSU_Limit(); // Get the maximum limit to compare to for each frequency or mode + + if (Psu_Pot_Val[1] > PSU_Val_Limit) + Psu_Pot_Val[1] = PSU_Val_Limit; + + SPI0_SendBytes(Psu_Pot_Val, 2, PSU_VCTRL); // Update the Pot + +} + +void Get_Max_PSU_Limit(void) // Set up Maximum voltage for PSU +{ + if (freqArray[frequency].frequency1 > MAX_DTYPE) + PSU_Val_Limit = MAX_AB_PSU; + else + PSU_Val_Limit = MAX_D_PSU; + + if (mode == BROADCAST) + PSU_Val_Limit = MAX_BCAST_PSU; + + if((Check_For_Clamp())) + PSU_Val_Limit = MAX_CLAMP_PSU; + +} + + + +void Adjust_Psu(uint8_t direction) +{ + + if(direction == UP) + psu_index++; + else + psu_index--; + +} + + + +void Psu_Match(void) +{// may need tap check plus current and voltage + if(freqArray[frequency].frequency1 <= MAX_DTYPE) //may need current and impedance check + { + switch (Power_Level) + { + + case 0: + Set_PSU_Voltage(V_21V); + break; + + case 1: + Set_PSU_Voltage(V_24V); + break; + + case 2: + Set_PSU_Voltage(V_27V); + break; + + case 3: + Set_PSU_Voltage(V_36V); + break; + + case 4: + Set_PSU_Voltage(V_36V); + break; + + default: + Set_PSU_Voltage(V_36V); + break; + + } + } +} + + +bool Wait_For_Psu(float32_t volt_limit) +{ +uint16_t escape_count; + + escape_count = 350; + + while(adc.V_PSU > volt_limit && escape_count > 0 ) + { + Delay_Ticks(1); + escape_count--; + + } + + if(escape_count > 0) + return(true); + else + return(false); + +} + + + + + + diff --git a/source/psu_ctrl.h b/source/psu_ctrl.h new file mode 100644 index 0000000..4ac8d89 --- /dev/null +++ b/source/psu_ctrl.h @@ -0,0 +1,41 @@ +/* + * psu_ctrl.h + * + * Created on: Mar 16, 2023 + * Author: Keith.Lloyd + */ + +#ifndef PSU_CTRL_H_ +#define PSU_CTRL_H_ + +#include +#include +#include "arm_math.h" + +#define MAX_BCAST_PSU 255 +#define MAIN_PSU_ENBL 0b00000100 // Active Low U13 D2 +#define V_18V 0 +#define V_21V 88 + +#define V_24V 118 +#define V_27V 148 +#define V_30V 171 +#define V_36V 218 +#define V_42V 250 // Clamp use only +#define V_55V 255 // Actually 45.5V +#define MAX_AB_PSU V_24V //TODO +//#define MAX_AB_PSU V_36V //TODO + +#define MAX_D_PSU V_36V +#define MAX_CLAMP_PSU 255 + +typedef enum { + DOWN = 0, + UP = 1 +}DDS_DIR_t; + +void Set_PSU_Voltage(uint8_t value); +void Get_Max_PSU_Limit(void); +bool Wait_For_Psu(float32_t volt_limit); +// Set up Maximum voltage for PSU +#endif /* PSU_CTRL_H_ */ diff --git a/source/pwm.c b/source/pwm.c new file mode 100644 index 0000000..033a451 --- /dev/null +++ b/source/pwm.c @@ -0,0 +1,243 @@ +/* + * pwm.c + * + * Created on: Jul 25, 2023 + * Author: Keith.Lloyd + */ + + +#include "pin_mux.h" +#include "board.h" +#include "fsl_sctimer.h" + +#include +#include +#include "frq.h" +#include "pwm.h" +#include "ports.h" +#include "arm_math.h" +#include "timer.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define SCTIMER_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk) +#define DEMO_SCTIMER_OUT kSCTIMER_Out_1 + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + + +/******************************************************************************* + * Variables + ******************************************************************************/ +volatile bool sctimerIsrFlag = false; +volatile bool brightnessUp = true; /* Indicate LED is brighter or dimmer */ +volatile uint8_t BC_Duty_Cycle = 10; +uint32_t eventNumberOutput; +uint32_t eventNumberOutput2; +volatile bool PWM_Update_Flag = false; +extern uint8_t Port_State[]; + +/******************************************************************************* + * Code + ******************************************************************************/ + + +//OBSOLETE - DO NOT USE +void init_PWM(void) +{ + + sctimer_config_t sctimerInfo; + sctimer_pwm_signal_param_t pwmParam; + sctimer_pwm_signal_param_t pwmParam2; //Added this for 2nd output + uint32_t sctimerClock; + + SCTIMER_GetDefaultConfig(&sctimerInfo); + +#if 0 //Testing_external_clock + sctimerClock = 16384000; //SCTIMER_CLK_FREQ; + + //change SCTimer schtuff here + sctimerInfo.clockMode = kSCTIMER_Input_ClockMode; + sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_0; //Note: 100MHz max external clock +#else + sctimerClock = SCTIMER_CLK_FREQ; + //todo: set sctimerInfo.clockMode and sctimerInfo.clockSelect for internal 144MHz clock - for changing back from external +#endif + + + /* Initialize SCTimer module */ + SCTIMER_Init(SCT0, &sctimerInfo); + + status_t status; + BC_Duty_Cycle = 10; + + uint32_t BC_Frequency = 32768; + + /* Configure PWM params with frequency 24kHZ from output */ + pwmParam.output = kSCTIMER_Out_1; //output 1 = pin 43 + pwmParam.level = kSCTIMER_HighTrue; + pwmParam.dutyCyclePercent = BC_Duty_Cycle; + status = SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, BC_Frequency, sctimerClock, &eventNumberOutput); + + // Configure 2nd PWM output pin + pwmParam2.output = kSCTIMER_Out_2; //Output 2 = pin 44 + pwmParam2.level = kSCTIMER_LowTrue; //invert polarity + pwmParam2.dutyCyclePercent = 100 - BC_Duty_Cycle; + status = SCTIMER_SetupPwm(SCT0, &pwmParam2, kSCTIMER_CenterAlignedPwm, BC_Frequency, sctimerClock, &eventNumberOutput2); + + /* Start the 32-bit unify timer */ + SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U); +} + + +/* +* Set PWM frequency and duty cycle +* Set duty to 0 to disable +* Use Flexcomm 0 outputs 1 and 2 +*/ +void PWM_Setup(uint32_t newFreq, uint32_t dutyCycle) +{ + //Error check + if(dutyCycle > 49 ) + { + dutyCycle = 49; + } + + sctimer_config_t sctimerInfo; + sctimer_pwm_signal_param_t pwmParam; + sctimer_pwm_signal_param_t pwmParam2; //Added this for 2nd output + uint32_t sctimerClock; + + SCTIMER_GetDefaultConfig(&sctimerInfo); + +#if 0 //New code Selects appropriate external oscillator. + SCTIMER_Deinit(SCT0); + + SCTIMER_GetDefaultConfig(&sctimerInfo); + + //Set up for correct clock + CLOCK_SELECT_t clock = PWM_GetBroadcastFrequencyOK(newFreq); + switch(clock) + { + case CS_EXT1: + sctimerClock = PWM_EXT1_FREQ_HZ; + sctimerInfo.clockMode = kSCTIMER_Input_ClockMode; + sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_0; //Note: 100MHz max external clock + break; + case CS_EXT2: + sctimerClock = PWM_EXT2_FREQ_HZ; + sctimerInfo.clockMode = kSCTIMER_Input_ClockMode; + sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_0; + break; + case CS_INTERNAL: + case CS_NUM: + default: + //Use internal clock. This is default setup for sctimerinfo. + sctimerClock = SCTIMER_CLK_FREQ; + break; + } + + PWM_SetExternalClockSource(clock); //Set the external clock + + +#else //Functional code using internal clock + sctimerClock = SCTIMER_CLK_FREQ; + //todo: set sctimerInfo.clockMode and sctimerInfo.clockSelect for internal 144MHz clock - for changing back from external +#endif + + + + /* Initialize SCTimer module */ + SCTIMER_Init(SCT0, &sctimerInfo); + + status_t status; + + /* Configure PWM params with frequency 24kHZ from output */ + pwmParam.output = kSCTIMER_Out_1; //output 1 = pin 43 + pwmParam.level = kSCTIMER_HighTrue; + pwmParam.dutyCyclePercent = dutyCycle; + status = SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, newFreq, sctimerClock, &eventNumberOutput); + + // Configure 2nd PWM output pin + pwmParam2.output = kSCTIMER_Out_2; //Output 2 = pin 44 + pwmParam2.level = kSCTIMER_LowTrue; //invert polarity + pwmParam2.dutyCyclePercent = 100 - dutyCycle; + status = SCTIMER_SetupPwm(SCT0, &pwmParam2, kSCTIMER_CenterAlignedPwm, newFreq, sctimerClock, &eventNumberOutput2); + + /* Start the 32-bit unify timer */ + SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U); +} + +/* +* Determine whether a frequency will work for broadcast and which clock to use +* returns CS_INTERNAL, CS_EXT1, or CS_EXT2 if one of them works +* returns the FIRST one that works +* returns CS_NUM if none of them work +*/ +CLOCK_SELECT_t PWM_GetBroadcastFrequencyOK(uint32_t newFreq) +{ + uint32_t clockFreq = 0; + uint32_t divider = 0; + float32_t testFreq = 0; + CLOCK_SELECT_t retval = (CS_NUM); + + //Check internal clock + clockFreq = SCTIMER_CLK_FREQ; + divider = (uint32_t)(clockFreq / (newFreq * 2.0)); + testFreq = clockFreq / (divider * 2.0); + if(fabs(testFreq - (float32_t)(newFreq)) <= PWM_MAX_BROADCAST_ERR_HZ) + { + return CS_INTERNAL; + } + + //Check External 2 + clockFreq = PWM_EXT2_FREQ_HZ; + divider = (uint32_t)(clockFreq / (newFreq * 2.0)); + testFreq = clockFreq / (divider * 2.0); + if(fabs(testFreq - (float32_t)(newFreq)) <= PWM_MAX_BROADCAST_ERR_HZ) + { + return CS_EXT2; + } + + //Check External 1 + clockFreq = PWM_EXT1_FREQ_HZ; + divider = (uint32_t)(clockFreq / (newFreq * 2.0)); + testFreq = clockFreq / (divider * 2.0); + if(fabs(testFreq - (float32_t)(newFreq)) <= PWM_MAX_BROADCAST_ERR_HZ) + { + return CS_EXT1; + } + + + return CS_NUM; //return this if none of the options work +} + + +void PWM_SetExternalClockSource(CLOCK_SELECT_t clock) +{ + + Port_State[TOP_SR] &= CLK_MASK_BITS; //clear external clock select bits + + switch(clock) + { + case CS_EXT1: + Port_State[TOP_SR] |= MASK_15; //15.61MHz external + break; + case CS_EXT2: + Port_State[TOP_SR] |= MASK_58; //58.98MHz external + break; + case CS_INTERNAL: + Port_State[TOP_SR] |= MASK_144; //external OFF, use 144MHz internal clock + break; + } + + SPI0_SendBytes(Port_State, 3, EXPANDER); + Delay_Ticks(1); +} + + + diff --git a/source/pwm.h b/source/pwm.h new file mode 100644 index 0000000..130923b --- /dev/null +++ b/source/pwm.h @@ -0,0 +1,28 @@ +/* + * pwm.h + * + * Created on: Jul 25, 2023 + * Author: Keith.Lloyd + */ + +#ifndef PWM_H_ +#define PWM_H_ +#define PWM_EXT1_FREQ_HZ 15618664 +#define PWM_EXT2_FREQ_HZ 58983040 +#define PWM_MAX_BROADCAST_ERR_HZ 5.0 + +typedef enum { + CS_INTERNAL = 0, + CS_EXT1, + CS_EXT2, + CS_NUM +} CLOCK_SELECT_t; + + +void PWM_UpdateDutyCycle(uint32_t dutyCycle); +void PWM_Setup(uint32_t newFreq, uint32_t dutyCycle); +CLOCK_SELECT_t PWM_GetBroadcastFrequencyOK(uint32_t newFreq); +void PWM_SetExternalClockSource(CLOCK_SELECT_t clock); + + +#endif /* PWM_H_ */ diff --git a/source/pwr_level.c b/source/pwr_level.c new file mode 100644 index 0000000..b655f40 --- /dev/null +++ b/source/pwr_level.c @@ -0,0 +1,596 @@ +/* + * pwr_level.c + * + * Created on: Jun 30, 2022 + * Author: Keith.Lloyd + */ + +#include +#include +#include +#include + + +#include "display.h" +#include "spi.h" +#include "mode.h" +#include "pwm.h" +#include "amps.h" +#include "frq.h" +#include "measure.h" +#include "adc.h" +#include "init.h" +#include "utils.h" +#include "ports.h" +#include "timer.h" +#include "sys_chk.h" +#include "battery.h" + +extern uint8_t frequency,Test_Mode,catch_up_flag; +extern ADC_t adc; +extern float32_t Milli_amps; +uint16_t Old_Pot_Val; +uint8_t Power_Level,Bcast_Pwr_Level; +float Requested_Current_Lith[5] = {10.0/1000,50.0/1000.0,150.0/1000.0,400.0/1000.0,1000.0/1000.0}; // Requested Current Output Value + +float Requested_Current_Alk[5] = {10.0/1000,50.0/1000.0,100.0/1000.0,150.0/1000.0,200.0/1000.0}; // Requested Current Output Value +float Requested_Current_HF[5] = {10.0/1000,50.0/1000.0,100.0/1000.0,150.0/1000.0,200.0/1000.0}; // Requested Current Output Value + + +uint16_t Pot_Value[5] = {23,30,45,93,180}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_New_CLAMP0[5] = {20,30,45,83,100}; // <512Hz DDS Output amplitude. (D amp) + +uint16_t Pot_Value_New_CLAMP1[5] = {20,30,45,100,200}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_New_CLAMP2[5] = {20,30,45,93,250}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_New_CLAMP3[5] = {20,30,45,93,250}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_New_CLAMP4[5] = {20,30,45,63,65}; // <512Hz DDS Output amplitude. (D amp) + +uint16_t Pot_Value_New_CLAMP_AB[5] = {5,10,45,93,150}; // DDS Output amplitude. (AB amp) +uint16_t Pot_Value_New_CLAMP_AB2[5] = {5,10,45,93,140}; // DDS Output amplitude. (AB amp) + +uint16_t Pot_Value_New_CLAMP_PK[5] = {20,25,50,60,130}; // DDS Output amplitude. (D amp) + + +uint16_t Pot_Value_CLAMP0[5] = {20,30,45,83,103}; // <512Hz DDS Output amplitude. (D amp) + +uint16_t Pot_Value_CLAMP1[5] = {20,30,45,93,120}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_CLAMP2[5] = {20,30,45,93,140}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_CLAMP3[5] = {20,30,45,65,73}; // DDS Output amplitude. (D amp) +uint16_t Pot_Value_CLAMP4[5] = {20,30,45,62,66}; // DDS Output amplitude. (D amp) + +uint16_t Pot_Value_CLAMP_AB[5] = {5,10,45,93,150}; // DDS Output amplitude. (AB amp) +uint16_t Pot_Value_CLAMP_AB2[5] = {5,10,45,93,140}; // DDS Output amplitude. (AB amp) + +uint16_t Pot_Value_CLAMP_PK[5] = {20,25,30,40,47}; // DDS Output amplitude. (D amp) + + +uint8_t Bcast_LF_Value[5] = {0,5,10,15,20}; // DDS Output amplitude. (D amp) +uint8_t Bcast_HF_Value[5] = {0,12,25,37,50}; // DDS Output amplitude. (D amp) + +uint8_t Bcast_VLF_Value_Alk[5] = {0,2,4,6,8}; // DDS Output amplitude. (D amp) +uint8_t Bcast_VLF2_Value_Alk[5] = {0,5,7,10,12}; // DDS Output amplitude. (D amp) + +//uint8_t Bcast_LF_Value_Alk[5] = {0,3,5,7,9}; // DDS Output amplitude. (D amp) +uint8_t Bcast_LF_Value_Alk[5] = {0,8,10,14,18}; // DDS Output amplitude. (D amp) +uint8_t Bcast_MLF_Value_Alk[5] = {0,12,14,18,26}; // DDS Output amplitude. (D amp) +uint8_t Bcast_MLF2_Value_Alk[5] = {0,16,24,30,36}; // DDS Output amplitude. (D amp) + +uint8_t Bcast_HF_Value_Alk[5] = {0,12,24,48,50}; // DDS Output amplitude. (D amp) + + +uint16_t Pot_Value_AB[5] = {4,10,45,93,112}; // DDS Output amplitude. (AB amp) + +uint16_t new_pot_val; + + + +//uint16_t Bcast_PwePot_Value[5] = {10,100,130,150,220}; // DDS Output amplitude. + +uint8_t Dds_Pot_Val[2]; // 2 byte Data for SPI +extern uint8_t Cur_Mode,Taps_Flag, Bat_Type; +extern volatile uint8_t BC_Duty_Cycle; +extern volatile bool PWM_Update_Flag; +extern uint16_t Sys_Chk_tmr,Taps_adjust_timer; +extern uint8_t Bat_Type; +REGULATE_t reg; + +extern uint32_t systemTime; +extern ClampData_t clampData; + + +void setTestPot(void) +{ + clampData.pot = 40; + Dds_Pot_Val[1] = clampData.pot; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); +} + +void doClampPower(void) +{ + float tmpF; + float power = 0.0f; + bool update = true; + + clampData.voltage = adc.V_OUT_FastFilt; + clampData.current = adc.I_OUT_FastFilt; + power = clampData.voltage * clampData.current; + + if (power > clampData.maxPower) + { + clampData.regulate = true; + clampData.timeout = systemTime; + } + + // calculate clamp voltage setting based on test pot value and frequency + if (clampData.regulate) + { + bool newLevel = (clampData.prevPowerLevel != Power_Level); + + clampData.impedance = clampData.voltage / clampData.current; + + if ((clampData.timeout > 0) && (systemTime >= clampData.timeout)) + { + + if (!newLevel && fabs(clampData.targetPower - power) < 0.01f) + { + // target power reached + clampData.regulate = false; + + } + else + if (!newLevel && fabs(MAX_CLAMP_VOLTAGE - clampData.voltage) < 1.0f) + { + // max clamp voltage reached + clampData.regulate = false; + } + else + if (newLevel && (clampData.prevPowerLevel == 0)) + { + setTestPot(); + clampData.timeout = systemTime + CLAMP_REGULATE_DELAY; + } + else + { + + if (clampData.pot > 0) + { + clampData.slope = clampData.voltage / (float)clampData.pot; + } + + tmpF = sqrtf(clampData.impedance * clampData.targetPower); + + if (tmpF > MAX_CLAMP_VOLTAGE) + { + tmpF = MAX_CLAMP_VOLTAGE; + } + + float pot = tmpF / clampData.slope; + + if (pot > 255) + { + clampData.pot = 255; + } + else + { + clampData.pot = (uint8_t)pot; + } + Dds_Pot_Val[1] = clampData.pot; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + clampData.timeout = systemTime + CLAMP_REGULATE_DELAY; + + + } + + clampData.prevPowerLevel = Power_Level; + } + } +} + +void inc_pwr(void) +{ + if(Cur_Mode != BROADCAST) + { + if(Power_Level < LEVEL_MAX-1) + Power_Level++; + +// if((!Test_Mode) && (ACCY_GetConnectedAccessory(1) != ID_CLAMP) && (ACCY_GetConnectedAccessory(2) != ID_CLAMP)) + if((!Check_For_Clamp())) + { + if((Power_Level == 1))// && !Block_Off) + { + //Block_Off = true; + Check_For_Connected_Volts(); + } + else + Request_Current_Change(); // Normal running no clamp + } + else + { + Dds_Pot_Val[0] = 0; // address + + + if(Power_Level ==1) + { + Check_For_Connected_Volts(); + } + + Get_Clamp_Value(); + + if (ACCY_GetActive() == ID_CLAMP) + { + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + } + else + { + clampData.regulate = true; + } + + } + } + else + { + if(Bcast_Pwr_Level < MAX_BCAST_PWR) + Increase_BC_PWR(); + } + +} + +void dec_pwr(void) +{ + if(Cur_Mode != BROADCAST) + { + + if(Power_Level > 0) + Power_Level--; + + if((!Check_For_Clamp())) + { + Request_Current_Change(); // Request_Current_Change(); + } + else + { + Dds_Pot_Val[0] = 0; // address + + Get_Clamp_Value(); + + if (ACCY_GetActive() == ID_CLAMP) + { + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + } + else + { + clampData.regulate = true; + } + } + } + else + if(Bcast_Pwr_Level > MIN_BCAST_PWR) + { + Decrease_BC_PWR(); + } + +} + +void Increase_BC_PWR(void) +{ + + Bcast_Pwr_Level++; +//uint8_t Old_Bat; +// Old_Bat = Bat_Type; +// Bat_Type = ALKALINE; // Testing Only + + if(Bat_Type == LITHIUM) + { + if(freqArray[frequency].frequency1 <= 8192) //8010 + BC_Duty_Cycle = Bcast_LF_Value[Bcast_Pwr_Level]; + else + BC_Duty_Cycle = Bcast_HF_Value[Bcast_Pwr_Level]; + } + else + BC_Duty_Cycle = Get_BC_Alk_Value(); + +// { +// if(freqArray[frequency].frequency1 <= 14000) +// { + +// if(freqArray[frequency].frequency1 <= 4000) +// BC_Duty_Cycle = Bcast_VLF_Value_Alk[Bcast_Pwr_Level]; +// else +// BC_Duty_Cycle = Bcast_LF_Value_Alk[Bcast_Pwr_Level]; +// } +// else +// BC_Duty_Cycle = Bcast_HF_Value_Alk[Bcast_Pwr_Level]; +// } + + PWM_Setup(freqArray[frequency].frequency1, BC_Duty_Cycle);//freqArray[frequency].frequency1 + +// Bat_Type = Old_Bat; // Testing Only + +} + +void Decrease_BC_PWR(void) +{ + Bcast_Pwr_Level--; + +//uint8_t Old_Bat; +// Old_Bat = Bat_Type; +// Bat_Type = ALKALINE; // Testing Only + + if(Bat_Type == LITHIUM) + { + if(freqArray[frequency].frequency1 > 8192) //8010 + BC_Duty_Cycle = Bcast_HF_Value[Bcast_Pwr_Level]; + else + BC_Duty_Cycle = Bcast_LF_Value[Bcast_Pwr_Level]; + } + else +// { + BC_Duty_Cycle = Get_BC_Alk_Value(); +// if(freqArray[frequency].frequency1 > 14000) +// { +// if(freqArray[frequency].frequency1 <= 4000) +// BC_Duty_Cycle = Bcast_VLF_Value_Alk[Bcast_Pwr_Level]; +// else +// BC_Duty_Cycle = Bcast_HF_Value_Alk[Bcast_Pwr_Level]; +// } +// else +// BC_Duty_Cycle = Bcast_LF_Value_Alk[Bcast_Pwr_Level]; +// } + + PWM_Setup(freqArray[frequency].frequency1, BC_Duty_Cycle);//freqArray[frequency].frequency1 + +// Bat_Type = Old_Bat; // Testing Only + +} + + +uint8_t Get_BC_Alk_Value(void) +{ +uint8_t BC_Duty_val; + + if(freqArray[frequency].frequency1 <= 4000) + BC_Duty_val = Bcast_VLF_Value_Alk[Bcast_Pwr_Level]; + else if(freqArray[frequency].frequency1 <= 6000) + BC_Duty_val = Bcast_VLF2_Value_Alk[Bcast_Pwr_Level]; + else if(freqArray[frequency].frequency1 <= 10000) + BC_Duty_val = Bcast_LF_Value_Alk[Bcast_Pwr_Level]; + else if(freqArray[frequency].frequency1 <= 14000) + BC_Duty_val = Bcast_MLF_Value_Alk[Bcast_Pwr_Level]; + else if(freqArray[frequency].frequency1 <= 20000) + BC_Duty_val = Bcast_MLF2_Value_Alk[Bcast_Pwr_Level]; + else + BC_Duty_val = Bcast_HF_Value_Alk[Bcast_Pwr_Level]; + + return(BC_Duty_val); +} + + +void Request_Current_Change(void) +{ + float Max_Current_Allowed,Current_Request; + + if (Power_Level == 0 || Milli_amps == 0.0) //Power_Level == 0 || + Init_Amplitude(); + else + { + Max_Current_Allowed = Calc_Max_current(); +// Current_Request = Requested_Current[Power_Level]; + Current_Request = Requested_Current(Bat_Type); + + if(Current_Request > Max_Current_Allowed) + Current_Request = Max_Current_Allowed; //make it comply} + + Old_Pot_Val = Dds_Pot_Val[1]; + new_pot_val = (Current_Request /adc.I_OUT_SlowFilt) * Dds_Pot_Val[1]; // Request divided by Pot current contents + + if(new_pot_val < 3) + new_pot_val = 3; + + if(new_pot_val < freqArray[frequency].max_pot) + Dds_Pot_Val[1] = new_pot_val; + else + Dds_Pot_Val[1] = freqArray[frequency].max_pot; + + Dds_Pot_Val[0] = 0; // address +// Adjust_Pot_Val(); + + Check_New_Pot_Volts(); + + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + + Sys_Chk_tmr= DELAY_500MS; // Allow system settling before checking measurements + Taps_Flag = false; + Taps_adjust_timer = DELAY_2S; + catch_up_flag = true; + } +} + +/* + * Initialize current regulation + */ +void InitRegulate(void) +{ + reg.state = RS_STOP; + + //set up variables: maxCurrent, maxPower, etc? +} + +/* + * Regulate current to requested target - Direct Connect Only + * Call this function @ 10Hz from the main loop + * Do not exceed voltage limit + * Do not exceed power limit + */ +void Regulate(void) +{ +// reg.requestedCurrent = Requested_Current[Power_Level]; + reg.maxCurrent = 1000; //TODO: determine max current - does this ever change? + reg.maxVoltage = 90.0; + reg.maxPower = 10.0; //TODO: determine max power by model and frequency + + + switch(reg.state) + { + case RS_STOP: + break; + case RS_START: + //initialize. Make initial guesses for pot value, taps, HV rail, etc. + break; + case RS_RUN: + //Adjust DDS pot + //look at current, voltage, power compared to target and make adjustment + break; + case RS_MAINTAIN: + //Maintain settings unless something changes + //Make sure we're not exceeding max values + //Check for current > 10% from stopping point + break; + } + +} + +void Adjust_Pot_Val(void) +{ + if(new_pot_val < Old_Pot_Val) + { + Dds_Pot_Val[1] = new_pot_val; // just send it + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + } + + Dds_Pot_Val[1] = Old_Pot_Val; + while(Old_Pot_Val < new_pot_val) + { + Old_Pot_Val++; + Dds_Pot_Val[1] = Old_Pot_Val; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + Delay_Ticks(1); + + } + +} + +void Get_Clamp_Value() +{ + if((ACCY_GetConnectedAccessory(1) == ID_CLAMP) || (ACCY_GetConnectedAccessory(2) == ID_CLAMP)) + { + if (freqArray[frequency].frequency1 > MAX_DTYPE) + Dds_Pot_Val[1] = Pot_Value_CLAMP_AB[Power_Level]; // data + + if (freqArray[frequency].frequency1 > 90000) + Dds_Pot_Val[1] = Pot_Value_CLAMP_AB2[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + Dds_Pot_Val[1] = Pot_Value_CLAMP3[Power_Level]; // data + + if ((freqArray[frequency].frequency1 < 40000) && (freqArray[frequency].frequency1 > 34000)) + Dds_Pot_Val[1] = Pot_Value_CLAMP_PK[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= 9820) + Dds_Pot_Val[1] = Pot_Value_CLAMP2[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= 3140) + Dds_Pot_Val[1] = Pot_Value_CLAMP1[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= 512) + Dds_Pot_Val[1] = Pot_Value_CLAMP0[Power_Level]; // data + if (freqArray[frequency].frequency1 < 512) + Dds_Pot_Val[1] = Pot_Value_CLAMP4[Power_Level]; // data + + } + else // Clamp 2 + { + //if (freqArray[frequency].frequency1 <= MAX_DTYPE) + { + switch (Power_Level) + { + case LEVEL1: + clampData.targetPower = clampData.maxPower / 64.0f; + break; + + case LEVEL2: + clampData.targetPower = clampData.maxPower / 16.0f; + break; + + case LEVEL3: + clampData.targetPower = clampData.maxPower / 4.0f; + break; + + case LEVEL4: + clampData.targetPower = clampData.maxPower / 1.0f; + break; + + default: + + clampData.targetPower = -1.0f; + + } + + } +#if 0 + if (freqArray[frequency].frequency1 > MAX_DTYPE) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP_AB[Power_Level]; // data + if (freqArray[frequency].frequency1 > 90000) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP_AB2[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP3[Power_Level]; // data + + if ((freqArray[frequency].frequency1 < 40000) && (freqArray[frequency].frequency1 > 34000)) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP_PK[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= 9820) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP2[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= 3140) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP1[Power_Level]; // data + + if (freqArray[frequency].frequency1 <= 512) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP0[Power_Level]; // data + + if (freqArray[frequency].frequency1 < 512) + Dds_Pot_Val[1] = Pot_Value_New_CLAMP4[Power_Level]; // data +#endif + + } +} + +void Check_New_Pot_Volts() +{ +float32_t V_Calc; // Currently set value is Old_Pot requested value is Pot_Val[] + + if(adc.V_OUT_SlowFilt > 0.0) + { + V_Calc = (adc.V_OUT_FastFilt / Old_Pot_Val); + + if(V_Calc * Dds_Pot_Val[1] > 90.0) + Dds_Pot_Val[1] = MAX_DC_VOLTAGE / adc.V_OUT_FastFilt * Old_Pot_Val; + + if(Dds_Pot_Val[1] > freqArray[frequency].max_pot) + Dds_Pot_Val[1] = freqArray[frequency].max_pot; + } + +} + +float Requested_Current(uint8_t Battery_Type) +{ + if(Battery_Type == LITHIUM || Battery_Type == EXT_DC) + { + if(freqArray[frequency].frequency1 <= MAX_DTYPE) + return (Requested_Current_Lith[Power_Level]); + else + return(Requested_Current_HF[Power_Level]); + } + else + { + if(freqArray[frequency].frequency1 <= MAX_DTYPE) + return(Requested_Current_Alk[Power_Level]); + else + return (Requested_Current_HF[Power_Level]); + + } +} +//Current_Request = Requested_Current[Power_Level]; + diff --git a/source/pwr_level.h b/source/pwr_level.h new file mode 100644 index 0000000..44970ab --- /dev/null +++ b/source/pwr_level.h @@ -0,0 +1,64 @@ +/* + * pwr_level.h + * + * Created on: Jun 30, 2022 + * Author: Keith.Lloyd + */ + +#ifndef PWR_LEVEL_H_ +#define PWR_LEVEL_H_ + +#include + +//#define MAX_POWER 4 +#define PL1_50MA 1 // for single frequency when dual frequency 1/2 each per level +#define PL2_150MA 2 +#define PL3_400MA 3 +#define PL4_1AMP 4 + +#define MIN_BCAST_PWR 0 +#define MAX_BCAST_PWR 4 + +#define RESTRICTED 3 +#define RESTRICT_CLAMP_FRQ 1170 //1KHz + + +//#define MAX_CLAMP_VOLTAGE 80.0f +#define MAX_POWER_TARGET_LF 10.0f // < 45kHz +#define MAX_POWER_TARGET_VLF 8.0f // < 800Hz (keep vibrations low) +#define MAX_POWER_TARGET_HF 1.0f // >= 45kHz + +#define CLAMP_REGULATE_DELAY 250 // milliseconds + +typedef enum { + RS_STOP = 0, //Not regulating + RS_START, //Startup + RS_RUN, //run regulation algorithm + RS_MAINTAIN //regulation has finished. either hit requestedCurrent or didn't +}REG_STATE_t; + +typedef struct { + REG_STATE_t state; + + float32_t requestedCurrent; + float32_t maxVoltage; + float32_t maxCurrent; + float32_t maxPower; + + bool targetCurrentReached; //regulation complete, target acheived + +}REGULATE_t; + +void setTestPot(void); +void doClampPower(void); +void inc_pwr(void); +void dec_pwr(void); +void Increase_BC_PWR(void); +void Decrease_BC_PWR(void); +void Request_Current_Change(void); +void Get_Clamp_Value(void); +void Adjust_Pot_Val(void); +uint8_t Get_BC_Alk_Value(void); +void Check_New_Pot_Volts(); +float Requested_Current(uint8_t Battery_Type); +#endif /* PWR_LEVEL_H_ */ diff --git a/source/radio.c b/source/radio.c new file mode 100644 index 0000000..22612f3 --- /dev/null +++ b/source/radio.c @@ -0,0 +1,12 @@ +/* + * radio.c + * + * Created on: Feb 27, 2023 + * Author: Keith.Lloyd + */ + + +void Send_Wireless_Data(void) // Send system update to Receiver. +{ + +} diff --git a/source/radio.h b/source/radio.h new file mode 100644 index 0000000..68354e4 --- /dev/null +++ b/source/radio.h @@ -0,0 +1,14 @@ +/* + * radio.h + * + * Created on: Feb 27, 2023 + * Author: Keith.Lloyd + */ + +#ifndef RADIO_H_ +#define RADIO_H_ + +void Send_Wireless_Data(void); // Send system update to Receiver. + + +#endif /* RADIO_H_ */ diff --git a/source/safety_key.c b/source/safety_key.c new file mode 100644 index 0000000..8554697 --- /dev/null +++ b/source/safety_key.c @@ -0,0 +1,42 @@ +/* + * safety_key.c + * + * Created on: Sep 1, 2023 + * Author: Keith.Lloyd + */ + +#include "pro_key.h" +#include +#include +#include "keys.h" +#include "frq.h" +#include "display.h" +#include "main.h" +#include "timer.h" +#include "pwr_level.h" +#include "utils.h" + + + +extern uint8_t Task; +extern uint8_t frequency,old_freq,frq_chg_tmr; +extern uint32_t new_freq; + +extern uint8_t keyval,Safety_Select,Safe_Mode, Over_Voltage_Flag; + + + + + +void safe_key(void) +{ +// Safe_Mode = false; // ensure safe mode operating +/// Over_Voltage_Flag = true; + + if(KEY_GetPressed() == ON_OFF_KEY)// || KEY_POWER)//(key_bits) + Power_Down(); // Stores last settings and powers off +} + + + + diff --git a/source/safety_key.h b/source/safety_key.h new file mode 100644 index 0000000..799f61f --- /dev/null +++ b/source/safety_key.h @@ -0,0 +1,13 @@ +/* + * safety_key.h + * + * Created on: Sep 1, 2023 + * Author: Keith.Lloyd + */ + +#ifndef SAFETY_KEY_H_ +#define SAFETY_KEY_H_ + +void safe_key(void); + +#endif /* SAFETY_KEY_H_ */ diff --git a/source/semihost_hardfault.c b/source/semihost_hardfault.c new file mode 100644 index 0000000..1c9c02e --- /dev/null +++ b/source/semihost_hardfault.c @@ -0,0 +1,98 @@ +// **************************************************************************** +// semihost_hardfault.c +// - Provides hard fault handler to allow semihosting code not +// to hang application when debugger not connected. +// +// **************************************************************************** +// Copyright 2017-2022 NXP +// All rights reserved. +// +// NXP Confidential. This software is owned or controlled by NXP and may only be +// used strictly in accordance with the applicable license terms. +// +// By expressly accepting such terms or by downloading, installing, activating +// and/or otherwise using the software, you are agreeing that you have read, and +// that you agree to comply with and are bound by, such license terms. +// +// If you do not agree to be bound by the applicable license terms, then you may not +// retain, install, activate or otherwise use the software. +// **************************************************************************** +// +// ===== DESCRIPTION ===== +// +// One of the issues with applications that make use of semihosting operations +// (such as printf calls) is that the code will not execute correctly when the +// debugger is not connected. Generally this will show up with the application +// appearing to just hang. This may include the application running from reset +// or powering up the board (with the application already in FLASH), and also +// as the application failing to continue to execute after a debug session is +// terminated. +// +// The problem here is that the "bottom layer" of the semihosted variants of +// the C library, semihosting is implemented by a "BKPT 0xAB" instruction. +// When the debug tools are not connected, this instruction triggers a hard +// fault - and the default hard fault handler within an application will +// typically just contains an infinite loop - causing the application to +// appear to have hang when no debugger is connected. +// +// The below code provides an example hard fault handler which instead looks +// to see what the instruction that caused the hard fault was - and if it +// was a "BKPT 0xAB", then it instead returns back to the user application. +// +// In most cases this will allow applications containing semihosting +// operations to execute (to some degree) when the debugger is not connected. +// +// == NOTE == +// +// Correct execution of the application containing semihosted operations +// which are vectored onto this hard fault handler cannot be guaranteed. This +// is because the handler may not return data or return codes that the higher +// level C library code or application code expects. This hard fault handler +// is meant as a development aid, and it is not recommended to leave +// semihosted code in a production build of your application! +// +// **************************************************************************** + +// Allow handler to be removed by setting a define (via command line) +#if !defined (__SEMIHOST_HARDFAULT_DISABLE) + +__attribute__((naked)) +void HardFault_Handler(void){ + __asm( ".syntax unified\n" + // Check which stack is in use + "MOVS R0, #4 \n" + "MOV R1, LR \n" + "TST R0, R1 \n" + "BEQ _MSP \n" + "MRS R0, PSP \n" + "B _process \n" + "_MSP: \n" + "MRS R0, MSP \n" + // Load the instruction that triggered hard fault + "_process: \n" + "LDR R1,[R0,#24] \n" + "LDRH R2,[r1] \n" + // Semihosting instruction is "BKPT 0xAB" (0xBEAB) + "LDR R3,=0xBEAB \n" + "CMP R2,R3 \n" + "BEQ _semihost_return \n" + // Wasn't semihosting instruction so enter infinite loop + "B . \n" + // Was semihosting instruction, so adjust location to + // return to by 1 instruction (2 bytes), then exit function + "_semihost_return: \n" + "ADDS R1,#2 \n" + "STR R1,[R0,#24] \n" + // Set a return value from semihosting operation. + // 32 is slightly arbitrary, but appears to allow most + // C Library IO functions sitting on top of semihosting to + // continue to operate to some degree + "MOVS R1,#32 \n" + "STR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack + // Return from hard fault handler to application + "BX LR \n" + ".syntax divided\n") ; +} + +#endif + diff --git a/source/spi.c b/source/spi.c new file mode 100644 index 0000000..6bfb2c3 --- /dev/null +++ b/source/spi.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "LPC54114_cm4.h" + +#include "fsl_spi.h" +#include "pin_mux.h" +#include "board.h" +#include "fsl_debug_console.h" + +#include +#include +#include "spi.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define SPI3_MASTER SPI3 +#define SPI3_MASTER_IRQ FLEXCOMM3_IRQn +#define SPI3_MASTER_CLK_SRC kCLOCK_Flexcomm3 +#define SPI3_MASTER_CLK_FREQ CLOCK_GetFlexCommClkFreq(3) +#define LCD_SPI_SSEL 1 +#define LCD_SPI_SPOL kSPI_Spol1ActiveHigh + +#define RADIO_SPI_SSEL 2 +//#define RADIO_SPI_SPOL kSPI_Spo2ActiveAllLow + +//SPI0 +#define SPI0_MASTER SPI0 +#define SPI0_MASTER_IRQ FLEXCOMM0_IRQn +#define SPI0_MASTER_CLK_SRC kCLOCK_Flexcomm0 +#define SPI0_MASTER_CLK_FREQ CLOCK_GetFlexCommClkFreq(3) //TODO: Which clock? +/******************************************************************************* + * Prototypes + ******************************************************************************/ + + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +//SPI3 +static uint8_t SPI3_txBuff[SPI_XFER_BUFFER_SIZE]; +static uint8_t SPI3_rxBuff[SPI_XFER_BUFFER_SIZE]; + +spi_master_config_t SPI3_config = {0}; +spi_transfer_t SPI3_xfer = {0}; + + +//SPI0 +static uint8_t SPI0_txBuff[SPI_XFER_BUFFER_SIZE]; +static uint8_t SPI0_rxBuff[SPI_XFER_BUFFER_SIZE]; + +spi_master_config_t SPI0_config = {0}; +spi_transfer_t SPI0_xfer = {0}; + +uint8_t Port_State[3]; // copy of Shift register I/O expander + +/******************************************************************************* + * Code + ******************************************************************************/ + + + +void SPI_Init(void) +{ + // Set GP CS High + SPI0_Chip_Select(CS_HIGH,SDSIGNAL); // Set SD generator high as default. + SPI0_Chip_Select(CS_HIGH,SIGNAL); // Set SD generator high as default. + SPI0_Chip_Select(CS_HIGH,RAMP); // + SPI0_Chip_Select(CS_HIGH,AMPLITUDE); // + SPI0_Chip_Select(CS_HIGH,EXPANDER); // + SPI0_Chip_Select(CS_HIGH,E2PROM); // + SPI0_Chip_Select(CS_HIGH,PSU_VCTRL); // + + + + // Initializes FC3 for LCD + uint32_t srcFreq = 0; + + /* + * userConfig.enableLoopback = false; + * userConfig.enableMaster = true; + * userConfig.polarity = kSPI_ClockPolarityActiveHigh; + * userConfig.phase = kSPI_ClockPhaseFirstEdge; + * userConfig.direction = kSPI_MsbFirst; + * + */ + + //SPI3: LCD and RADIO + SPI_MasterGetDefaultConfig(&SPI3_config); + srcFreq = SPI3_MASTER_CLK_FREQ; + SPI3_config.sselNum = (spi_ssel_t)LCD_SPI_SSEL; + SPI3_config.sselPol = (spi_spol_t)LCD_SPI_SPOL; + SPI3_config.baudRate_Bps = 500000U; + SPI_MasterInit(SPI3_MASTER, &SPI3_config, srcFreq); + + //Link Radio + + + //SPI0: other shiat + SPI_MasterGetDefaultConfig(&SPI0_config); + srcFreq = SPI0_MASTER_CLK_FREQ; + SPI0_config.baudRate_Bps = 500000U; + SPI_MasterInit(SPI0_MASTER, &SPI0_config, srcFreq); + +} + +void SPI3_Test(void) //NOT USED ANYWHERE +{ + /* Init Buffer*/ + for (uint32_t i = 0; i < SPI_XFER_BUFFER_SIZE; i++) + { + SPI3_txBuff[i] = 0xAA; + } + + while(1) + { + GPIO_PinWrite(GPIO, 0, 6, 1); + SPI3_SendBytes(SPI3_txBuff, 1); + GPIO_PinWrite(GPIO, 0, 6, 0); + uint32_t keithTWPia = 1000000; + while(keithTWPia--); + } +} + + +void SPI3_SendBytes(uint8_t *sendData, uint16_t numBytes) +{ + uint8_t throwawayBuffer[numBytes]; + + //TODO: Setup userConfig to use LCD_SPI_SSEL and LCD_SPI_SPOL + + /*Start Transfer*/ + SPI3_xfer.txData = sendData; + SPI3_xfer.rxData = throwawayBuffer; + SPI3_xfer.dataSize = numBytes; //sizeof(rxBuff); + SPI3_xfer.configFlags = kSPI_FrameAssert; + + SPI_MasterTransferBlocking(SPI3_MASTER, &SPI3_xfer); + +} + +void SPI0_SendBytes(uint8_t *sendData, uint16_t numBytes, SPI_MODE_t destination) //Extra arg +{ + uint8_t throwawayBuffer[numBytes]; + + SPI0_SetupForDDS(1, destination); //Enter DDS mode if taking to a DDS + + SPI0_Chip_Select(CS_LOW, destination); + +/*Start Transfer*/ + + SPI0_xfer.txData = sendData; + SPI0_xfer.rxData = throwawayBuffer; + SPI0_xfer.dataSize = numBytes; //sizeof(rxBuff); + SPI0_xfer.configFlags = kSPI_FrameAssert; + +#if 1 //troubleshooting + status_t status = SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer); + if(status != kStatus_Success) + { + uint32_t foo = 0; + foo++; //Code never gets here even when EEPROM test fails. + } +#else + SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer); +#endif + SPI0_Chip_Select(CS_HIGH, destination); + + SPI0_SetupForDDS(0, destination); //Exit DDS mode if talking to a DDS + +} + + +/* +* Setup SPI0 for talking to the DDS chips +* DDS chips require cpol = 1, normal state is cpol = 0 +* @arg onOff 1 = enter DDS mode, 0 = exit DDS mode (return to default setup) +* @arg destination the device we are talking to. Use to determine if talking to a DDS +*/ +void SPI0_SetupForDDS(uint32_t onOff, SPI_MODE_t destination) +{ + + if((destination == SIGNAL) || (destination == SDSIGNAL) || (destination == RAMP)) //if talking to a DDS + { + SPI_Deinit(SPI0_MASTER); + + SPI_MasterGetDefaultConfig(&SPI0_config); + SPI0_config.baudRate_Bps = 500000U; + if(onOff) //Only change required for AD9838 + { + SPI0_config.polarity = kSPI_ClockPolarityActiveLow; //activeLow = 1 + } + else + { + SPI0_config.polarity = kSPI_ClockPolarityActiveHigh; //activeHigh = 0 + } + SPI_MasterInit(SPI0_MASTER, &SPI0_config, SPI0_MASTER_CLK_FREQ); + + } +} + + + + +/*void SPI0_SendBytes(uint8_t *sendData, uint16_t numBytes, SPI_MODE_t destination) //Extra arg +{ + uint8_t throwawayBuffer[numBytes]; + + + + SPI0_Chip_Select(CS_LOW, destination); + +/*Start Transfer + + SPI0_xfer.txData = sendData; + SPI0_xfer.rxData = throwawayBuffer; + SPI0_xfer.dataSize = numBytes; //sizeof(rxBuff); + SPI0_xfer.configFlags = kSPI_FrameAssert; + +#if 1 //troubleshooting + status_t status = SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer); + if(status != kStatus_Success) + { + uint32_t foo = 0; + foo++; //Code never gets here even when EEPROM test fails. + } +#else + SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer); +#endif + SPI0_Chip_Select(CS_HIGH, destination); + +} +*/ + + +/* +void SPI0_SendPotData(uint16_t *sendData, uint16_t numWords, SPI_MODE_t destination) //Extra arg +{ + uint16_t throwawayBuffer[numWords]; + + // Reconfigure SPI to 10 bits + SPI0_config.dataWidth = kSPI_Data10Bits; + SPI_MasterInit(SPI0_MASTER, &SPI0_config, SPI3_MASTER_CLK_FREQ); + + SPI0_Chip_Select(CS_LOW, destination); + + //Start Transfer + SPI0_xfer.txData = sendData; + SPI0_xfer.rxData = throwawayBuffer; + SPI0_xfer.dataSize = numWords; //sizeof(rxBuff); + SPI0_xfer.configFlags = kSPI_FrameAssert; + + SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer); + + SPI0_Chip_Select(CS_HIGH, destination); + + // Return SPI to normal bit length. + SPI0_config.dataWidth = kSPI_Data8Bits; + SPI_MasterInit(SPI0_MASTER, &SPI0_config, SPI3_MASTER_CLK_FREQ); +} +*/ + +void SPI0_Chip_Select(uint8_t state, SPI_MODE_t destination) +{ + +switch(destination) +{ +case SIGNAL: + GPIO_PinWrite(GPIO, SIGNAL_PORT, SIG_CS_GPIO_PIN, state); + break; +case SDSIGNAL: + GPIO_PinWrite(GPIO, SIGNAL_PORT, SD_CS_GPIO_PIN, state); + break; +case BOTH_SIGNAL: + GPIO_PinWrite(GPIO, SIGNAL_PORT, SIG_CS_GPIO_PIN, state); + GPIO_PinWrite(GPIO, SIGNAL_PORT, SD_CS_GPIO_PIN, state); + break; +case RAMP: + GPIO_PinWrite(GPIO, SIGNAL_PORT, RAMP_CS_GPIO_PIN, state); + break; +case AMPLITUDE: + GPIO_PinWrite(GPIO, PORT0, POT_CS_GPIO_PIN, state); + break; +case EXPANDER: + GPIO_PinWrite(GPIO, PORT0, PORT_LE_CS_GPIO_PIN, state); + break; +case E2PROM: + GPIO_PinWrite(GPIO, PORT0, EEP_CS_GPIO_PIN, state); + break; +case PSU_VCTRL: + GPIO_PinWrite(GPIO, PORT0, POT_CS2_GPIO_PIN, state); + break; + + } +} diff --git a/source/spi.h b/source/spi.h new file mode 100644 index 0000000..4149a27 --- /dev/null +++ b/source/spi.h @@ -0,0 +1,56 @@ +/* + * spi.h + * + * Created on: May 27, 2022 + * Author: Keith.Lloyd + */ + +#ifndef SPI_H_ +#define SPI_H_ +#include +#include + + +#define SPI_XFER_BUFFER_SIZE (128) + + + +#define PORT0 0 +#define PORT1 1 +#define SIGNAL_PORT PORT1 + +#define SIG_CS_GPIO_PIN 9 +#define SIG_RST_GPIO_PIN 12 +#define SD_CS_GPIO_PIN 10 +#define SD_RST_GPIO_PIN 13 +#define RAMP_CS_GPIO_PIN 11 +#define RAMP_RST_GPIO_PIN 14 +#define POT_CS_GPIO_PIN 7 +//#define PORT_LE_CS_GPIO_PIN 5 // 208002 +#define PORT_LE_CS_GPIO_PIN 19 // 208004 + +#define EEP_CS_GPIO_PIN 10 +#define POT_CS2_GPIO_PIN 21 +#define CS_LOW 0 +#define CS_HIGH 1 + + +typedef enum { + SIGNAL, + SDSIGNAL, + RAMP, + AMPLITUDE, + EXPANDER, + E2PROM, + PSU_VCTRL, + BOTH_SIGNAL +} SPI_MODE_t; + +void SPI_Init(void); +void SPI3_Test(void); +void SPI0_SendBytes(uint8_t *sendData, uint16_t numBytes, SPI_MODE_t destination); +void SPI0_SendPotData(uint16_t *sendData, uint16_t numWords, SPI_MODE_t destination); +void SPI3_SendBytes(uint8_t *sendData, uint16_t numBytes); +void SPI0_Chip_Select(uint8_t state, SPI_MODE_t destination); +void SPI0_SetupForDDS(uint32_t onOff, SPI_MODE_t destination); +#endif /* SPI_H_ */ diff --git a/source/sys_chk.c b/source/sys_chk.c new file mode 100644 index 0000000..3f304bb --- /dev/null +++ b/source/sys_chk.c @@ -0,0 +1,408 @@ + +#include "arm_math.h" +#include "fsl_gpio.h" +#include "spi.h" + +#include "utils.h" +#include "battery.h" +#include "main.h" +#include "display.h" +#include "timer.h" +#include "lcd.h" +#include "mode.h" +#include "ports.h" +#include "utils.h" +#include "adc.h" +#include "safety_key.h" +#include "sys_chk.h" +#include "pwr_level.h" +#include "init.h" +#include "frq.h" +#include "adc.h" +#include "taps.h" +#include "amps.h" +#include "stdbool.h" + +extern uint8_t Task,Cur_Mode,Power_Level,catch_up_flag; +extern uint8_t Over_Voltage_Flag,Bat_Type,Suspend_Step_Chk; +extern uint16_t Pot_Value_CLAMP_AB[]; +extern uint16_t Pot_Value_AB[],Over_Voltage_tmr,ByPass_tmr; +extern uint8_t Dds_Pot_Val[]; // 2 byte Data for SPI +extern ADC_t adc; +extern uint16_t Vchktmr, Pot_Value[]; +//extern float Requested_Current[]; +extern uint8_t Port_State[]; +uint8_t Ports_Cleared_Flag,step_count; +extern uint8_t frequency,Over_Current_Flag, Taps_Flag; +extern FREQUENCY_t freqArray[FREQ_MAX_NUM]; +extern ADC_t adc; +extern float32_t Max_Power_Limit; +extern float32_t Watts_Filt; +uint16_t Power_tmr, Display_warning_tmr; + +void System_Check() +{ + + if(freqArray[frequency].frequency1 <= MAX_DTYPE) + { + Check_Over_Power(); // check for excessive power setting + } + else + { + if(step_count >= 10) + Check_Over_Power(); + } +// Check_Power_Monitor(); // Check for persistent condition longer than 3 seconds + +// Vchktmr = 0; + Check_Live_Voltage(); // Check Live voltage external source + + // Safety_Check(); redundant code + + Check_Over_Voltage(); // Check Direct Connect Over voltage + + Check_Clamp_OverVoltage(); + + Check_Over_Current(); // Check if current > 1 Amp 9/4/24 temp + +// Check_PSU_Short(); // Checks if PSU rail is short + +//######## temporarily removed 9/3/24 for debugging +// if(Watts_Filt > Get_Power_Limit()) +// Check_Over_Power(); // check for excessive power setting +// else +// { + if(Cur_Mode != BROADCAST && step_count < 10) +// Check_Selected_Current(); //Checks for current output > Selected Value + Chk_Selected_Current2(); +// } + //######### + + + Check_Trickle_Current(); + + Chk_Bat_Level(); +#if 1 //## 9/24/24 + if(Short_Circuit_Chk()) // Check for short in High gain. + { + Over_Current_Flag = true; + Power_Level = 0; + Cut_Signal_To_Min(); +// Update_Amp_Pot(); + } +#endif +} + +void Safety_Check(void) +{ + Check_Live_Voltage(); + if(Task == SAFETY_TASK) + { + Task = SAFETY_TASK; + LCD_Clear(); + + while(1) + { + safe_key(); + Display_Update(); + Delay_Ticks(10); + } + } +} + +void Normal_Bypass_Chk(void) +{ + if(!Over_Voltage_Flag) + Select_Bypass(ON); +} + + + +void Check_For_Open_Circuit(void) +{ + if(Open_Circuit_Chk()) // if open Circuit + { // Switch blocking Cap ON + Select_Bypass(OFF); + ByPass_tmr = DELAY_5S; + } + else if (adc.V_CHK < MAX_BYPASS_VOLTS2) // else if NOT HVP + { // Switch Blocking cap off + Delay_Ticks(10); // Check again after delay + if (adc.V_CHK < MAX_BYPASS_VOLTS2 && ByPass_tmr == 0) + { + Select_Bypass(ON); + step_count = 0; + Display_warning_tmr = DELAY_5S; // Allow voltage surge to drop before displaying warning + } + + } + + if (adc.V_CHK > MAX_BYPASS_VOLTS2) + Over_Voltage_Flag = true; + else + Over_Voltage_Flag = false; // added 1/6/25 + + if (Compare_Voltage(adc.V_CHK, MAX_OP_VOLTS)) //Potentially fatal voltage + { + Select_Estop(ON); // Fault condition disable output + Select_Bypass(OFF); // Force into blocked state. + Task = SAFETY_TASK; + } + +} + +bool Open_Circuit_Chk(void) + +{ + if(adc.I_OUT_FastFilt <= OPEN_CIRCUIT_CURRENT) + return(true); + else + return(false); + + +} + + + +void Check_For_Connected_Volts(void) +{ + Vchktmr = 0; +// Check_Live_Voltage(); // Check Live voltage external source + Safety_Check(); + if(Over_Voltage_Flag) + Select_Bypass(OFF); + else + { + Select_Bypass(ON); + + //Scale down standby pot value for frequency: compensate for blocking cap + float32_t scale = 0.6 * freqArray[frequency].frequency1 / 20000.0 + 0.4; + if(scale > 1.0) + { + scale = 1.0; + } + Dds_Pot_Val[0] = 0; // address + Dds_Pot_Val[1] = (uint8_t)(scale * Dds_Pot_Val[1]); + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + Delay_Ticks(50); + + Taps_Flag = false; + Check_Taps(); // Check for optimum Taps before making jump + Delay_Ticks(30); + +#if 0 + for(uint32_t i = 0; i < 10; i++) + { + Current1[i] = adc.I_OUT_FastFilt; + Delay_Ticks(10); //100mS to stabilize measurement after cap bypassed + } + + uint32_t moo = 0; + moo++; //place for breakpoint +#endif + } + +// if((ACCY_GetConnectedAccessory(1) != ID_CLAMP) && (ACCY_GetConnectedAccessory(2) != ID_CLAMP)) + if((!Check_For_Clamp())) + + { + Request_Current_Change(); // Normal running no clamp + } + + +} + +void Check_Trickle_Current(void) +{ +float32_t x; +uint8_t y,z; + + if(Power_Level == 0 && adc.I_OUT_SlowFilt > 0.050) + { + z = Dds_Pot_Val[1]; + x = 0.050 /adc.I_OUT_SlowFilt; + y = (Dds_Pot_Val[1]*x); + + if (y < 3) + y=3; + + Dds_Pot_Val[1] = y; + Dds_Pot_Val[0] = 0; // address +// Adjust_Pot_Val(); + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + +// Pot_Value[0] = 3; +// Init_Amplitude(); + + } +} + +void Check_Selected_Current(void) +{ + if(!Check_For_Clamp()) + { + if((!Suspend_Step_Chk) && (!Over_Voltage_Flag)) + { + if(Demand_Check() && Power_Level > 0) // + { + if(!Check_Maxed_Out()) + { + Request_Current_Change(); + catch_up_flag = false; + step_count++; + } + } + } + + } +} + + +bool Demand_Check(void) +{ +float32_t current,num; +uint8_t xval; + + xval = Dds_Pot_Val[1]; + +// num = Requested_Current[Power_Level] * 1.2; 3/8/24 + num = Requested_Current(Bat_Type); + + current = adc.I_OUT_SlowFilt; // +// if(current > (Requested_Current[Power_Level] * 1.2) && Power_Level > 0) 3/8/24 + if(current > (num * 1.1) && Power_Level > 0) + return(true); + else + {//###### +// if(current < (Requested_Current[Power_Level] * 0.8)) + if(current < (num * 0.9) && Power_Level > 0) + return(true); + else + return(false); + } +} + +void Chk_Selected_Current2(void) +{ + + if(!Check_For_Clamp() && (!Suspend_Step_Chk) && (!Over_Voltage_Flag)) + { + if(adc.I_OUT_SlowFilt > (Requested_Current(Bat_Type) * 1.05) || (Watts_Filt > Get_Power_Limit())) + { + Request_Current_Change(); // reduce current + catch_up_flag = false; + step_count++; + + } + else + { + if (adc.I_OUT_SlowFilt < (Requested_Current(Bat_Type) * 0.95)) + { + if(!Check_Maxed_Out()) + { + Request_Current_Change(); //increase current + catch_up_flag = false; + step_count++; + } + + } + } + } + +} + + + +void Check_For_Usb(void) +{ + if(GPIO_PinRead(GPIO,1,6)) + Clear_All_Bits(); + + +} + +void Clear_All_Bits(void) +{ + //clear shift registers to known state + Port_State[MID_SR] = USB_STATE_MID; // + Port_State[BOTTOM_SR] = USB_STATE_BOT; // + Port_State[TOP_SR] = USB_STATE_TOP; + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + Delay_Ticks(1); + Send_Ctrl_Word(SLP_CTRL_WRD2,SIGNAL); // Switch signal off + + Ports_Cleared_Flag = true; +} + +bool Short_Circuit_Chk(void) +{ +float32_t x; + + if((Port_State[MID_SR] & I_GAIN) > 0) + { // High Gain + if(adc.I_OUT_FastFilt > 0.05 && adc.V_OUT_FastFilt < 1 && Power_Level > 1) + return(true); + else + return(false); + } + else + { // Low GAIN + x = Get_Max_Current(); + + if(adc.I_OUT_FastFilt * 1000 > x) + return(true); + else + return(false); + + } +} + + +bool Check_Maxed_Out(void) +{ + float32_t x,Power_Limit,Current_Request; + + if (freqArray[frequency].frequency1 < MAX_DTYPE) + Power_Limit = Max_Power_Limit; + else + Power_Limit = 1.0; + + x = Get_Max_Current(); // HF 250mA LF 950mA + Current_Request = Requested_Current(Bat_Type); + + if(adc.I_OUT_FastFilt * 1000 > x) + return(true); + else if (adc.V_OUT > (MAX_DC_VOLTAGE * 0.95)) + return(true); + else if (Watts_Filt > (Power_Limit * 0.95)) + return(true); + else if ((Current_Request * adc.V_OUT_SlowFilt) > Power_Limit) + return (true); + else + return(false); + + +} + +void Check_Power_Monitor(void) +{ +#define MAX_PWR_TIME 300 // 3 Seconds + + if(Watts_Filt > Get_Power_Limit() * 1.2) + { + Power_tmr++; + if(Power_tmr > MAX_PWR_TIME) + { + Power_Level = 0; + Cut_Signal_To_Min(); + } + else + Power_tmr = 0; + } + + + +} + diff --git a/source/sys_chk.h b/source/sys_chk.h new file mode 100644 index 0000000..29952b1 --- /dev/null +++ b/source/sys_chk.h @@ -0,0 +1,30 @@ +/* + * sys_chk.h + * + * Created on: Nov 11, 2022 + * Author: Keith.Lloyd + */ + +#ifndef SYS_CHK_H_ +#define SYS_CHK_H_ +#define USB_STATE_TOP 0b00000001 +#define USB_STATE_MID 0 +#define USB_STATE_BOT 0x24 // MAIN PSU OFF BACKLIGHT ON +#define OPEN_CIRCUIT_CURRENT 0.009 // 7mA + +void System_Check(void); +void Safety_Check(void); +void Normal_Bypass_Chk(void); +void Check_For_Connected_Volts(void); +void Check_Selected_Current(void); +bool Demand_Check(void); +void Check_Trickle_Current(void); +void Check_For_Usb(void); +void Clear_All_Bits(void); +bool Short_Circuit_Chk(void); +bool Check_Maxed_Out(void); +void Chk_Selected_Current2(void); +bool Open_Circuit_Chk(void); +void Check_For_Open_Circuit(void); + +#endif /* SYS_CHK_H_ */ diff --git a/source/taps.c b/source/taps.c new file mode 100644 index 0000000..0a2ab71 --- /dev/null +++ b/source/taps.c @@ -0,0 +1,158 @@ +/* + * taps.c + * + * Created on: Mar 16, 2023 + * Author: Keith.Lloyd + */ +#include "arm_math.h" +#include "fsl_gpio.h" +#include "spi.h" + +#include "taps.h" +#include "display.h" +#include "ports.h" +#include "mode.h" +#include "frq.h" +#include "amps.h" +#include "adc.h" +#include "utils.h" + +extern ADC_t adc; +extern uint8_t Port_State[]; +extern uint8_t Cur_Mode,Test_Mode; +extern uint32_t new_freq; +extern float32_t Ohms; +extern uint16_t Taps_adjust_timer; +extern uint8_t frequency; +extern FREQUENCY_t freqArray[FREQ_MAX_NUM]; +float32_t last_Ohms; +extern uint8_t Taps_Flag; +void Check_Taps(void) +{ + Taps_adjust_timer = DELAY_ONE_SECOND; + + if(Cur_Mode != BROADCAST) + { + if (new_freq <= MAX_DTYPE) + Set_taps_LF(); + else +// Set_taps_HF(); + Set_taps_LF(); + + } +} + + + +void Set_taps_LF(void) // D' Type Amplifier +{ + uint16_t New_Ohms; + + if((!Taps_Flag) && (!Check_For_Clamp())) + +// if((!Test_Mode && (ACCY_GetConnectedAccessory(1) != ID_CLAMP) && (ACCY_GetConnectedAccessory(2) != ID_CLAMP))) + { + if(!Taps_Flag) + { + Port_State[BOTTOM_SR] &= TAPS_OFF_MASK; + New_Ohms = (adc.Ohms_slowfilt); + + switch (New_Ohms) + { + + case 0 ... 25: + Port_State[BOTTOM_SR] |= TAP1_LF_ON; + break; + + case 26 ... 50: + if (freqArray[frequency].frequency1 <= 8192) + Port_State[BOTTOM_SR] |= TAP2_LF_ON; + else + Port_State[BOTTOM_SR] |= TAP1_LF_ON; // v1.7 = TAP1 1.7X TAP2 + break; + + case 51 ... 250: + if (freqArray[frequency].frequency1 <= 29430) // 9820 + Port_State[BOTTOM_SR] |= TAP3_LF_ON;//3 + if (freqArray[frequency].frequency1 >= 29430 && freqArray[frequency].frequency1 <= MAX_DTYPE) + Port_State[BOTTOM_SR] |= TAP2_LF_ON; //1,2 + else + if(freqArray[frequency].frequency1 >= MAX_DTYPE) + Port_State[BOTTOM_SR] |= TAP2_LF_ON; + break; + + case 251 ... 500: + if (freqArray[frequency].frequency1 >= 29430 && freqArray[frequency].frequency1 <= MAX_DTYPE) + Port_State[BOTTOM_SR] |= TAP2_LF_ON; + else + Port_State[BOTTOM_SR] |= TAP4_LF_ON; + break; + + case 501 ... 1000: + if (freqArray[frequency].frequency1 == MAX_DTYPE || freqArray[frequency].frequency1 < 512) + Port_State[BOTTOM_SR] |= TAP3_LF_ON; + else + Port_State[BOTTOM_SR] |= TAP4_LF_ON; //4 1.7 =T3 1.7X =T4 + break; + + + default: + Port_State[BOTTOM_SR] |= TAP4_LF_ON; + break; + + + } + + SPI0_SendBytes(Port_State, 3, EXPANDER); + + last_Ohms = adc.Ohms_slowfilt; + Taps_Flag = true; + + } + } + else + { + Port_State[BOTTOM_SR] &= TAPS_OFF_MASK; + Port_State[BOTTOM_SR] |= TAP4_LF_ON; // Set TAPS to Fixed Test setting + SPI0_SendBytes(Port_State, 3, EXPANDER); + + } +// Port_State[BOTTOM_SR] &= TAPS_OFF_MASK; +// Port_State[BOTTOM_SR] |= TAP2_LF_ON; // force TAP 2 for new transformer test (remove later) +// SPI0_SendBytes(Port_State, 3, EXPANDER); + +} + + +void Set_taps_HF(void) // AB Amplifier +{ + if(Hys_Taps) + { + last_Ohms = adc.Ohms_slowfilt; + + if(adc.Ohms_slowfilt < 200) + + Port_State[MID_SR] &= TAP102_HF_OFF; // 1:1 + else + Port_State[MID_SR] |= TAP102_HF_ON; // 1:5 + + SPI0_SendBytes(Port_State, 3, EXPANDER); + } +} + +bool Hys_Taps(void) //Check for a +/-10% change in the impedance +{ +float32_t test; + + test = last_Ohms + last_Ohms/10; + + if(adc.Ohms_slowfilt > test ) + return(true); + + test = last_Ohms - last_Ohms/10; + + if(adc.Ohms_slowfilt < test) + return(true); + else + return(false); +} diff --git a/source/taps.h b/source/taps.h new file mode 100644 index 0000000..5ace420 --- /dev/null +++ b/source/taps.h @@ -0,0 +1,37 @@ +/* + * taps.h + * + * Created on: Mar 16, 2023 + * Author: Keith.Lloyd + */ + +#ifndef TAPS_H_ +#define TAPS_H_ + +#define LF_TAPS 0 +#define HF_TAPS 1 + +#define TAP_HF_ON1 0x00 +#define TAP_HF_ON2 0x04 + +#define TAP1D 0x18 +#define TAP2D 0x17 +#define TAP3D 0x08 +#define TAP4D 0x00 + +#define TAPS_OFF_MASK 0b11100111 +#define TAP1_LF_ON 0b00011000 +#define TAP2_LF_ON 0b00010000 +#define TAP3_LF_ON 0b00001000 +#define TAP4_LF_ON 0b00000000 + +#define TAP102_HF_OFF 0b11111011 +#define TAP102_HF_ON 0b00000100 + +void Check_Taps(void); +void Set_taps_LF(void); // D' Type Amplifier +void Set_taps_HF(void); + +void Set_Taps(uint8_t Tap, uint8_t Xfmr); +bool Hys_Taps(void); +#endif /* TAPS_H_ */ diff --git a/source/testMenu.c b/source/testMenu.c new file mode 100644 index 0000000..e2a06b3 --- /dev/null +++ b/source/testMenu.c @@ -0,0 +1,512 @@ +/* + * testMenu.c + * + * Created on: Mar 27, 2024 + * Author: Brian.Bailey + */ + + +#include +#include +#include +#include +#include + +//Drivers +#include "fsl_common.h" +#include "fsl_gpio.h" + + +#include "Fonts\fontLibrary.h" +#include "Graphics\graphicsLibrary.h" +#include "lcd.h" +#include "keys.h" +#include "timer.h" +#include "frq.h" +#include "Graphics\icons.h" +#include "System\system.h" +#include "menu.h" +#include "hwFixes.h" +#include "eeprom.h" + +#include "testMenu.h" + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + + + + +/******************************************************************************* + * Variables + ******************************************************************************/ + +MENU_ITEM_t testMenu[TEST_MENU_NUM]; +MENU_ITEM_t hwFixMenu[HWFIX_MENU_NUM]; + +uint8_t * fixStrings[] = {"NOT YET...", "DONE"}; //1 = fix done +uint8_t * onOffStrings[] = {"OFF", "ON"}; //1 = on + +extern HARDWARE_FIX_t hwf; +extern char tempString[40]; +extern uint8_t Diag_Flag; +/******************************************************************************* + * Static Function Declarations + ******************************************************************************/ + +static void ClearTestMenuItems(MENU_ITEM_t items[], uint32_t num); +static uint8_t * GetFixStatusString(uint32_t index); +static void HwFixMenu(void); +static void DisplayHwFixMenu(uint32_t selected); +static void DrawTestMenuScrollBar(uint32_t displayIndex, uint32_t numItems); + + +/******************************************************************************* + * Static Functions + ******************************************************************************/ + +//Clear an array of MENU_ITEM_t +static void ClearTestMenuItems(MENU_ITEM_t items[], uint32_t num) +{ + for(uint32_t i = 0; i < num; i++) + { + items[i].pMonoIcon = 0; //Init mono icon pointer to null + + items[i].text[0] = 0; //Init first char to null + } +} + +static uint8_t * GetFixStatusString(uint32_t index) +{ + return fixStrings[index]; +} + +static uint8_t * GetOnOffString(uint32_t index) +{ + return onOffStrings[index]; +} + +static void HwFixMenu(void) +{ + uint32_t selected = 0; + uint32_t menuNum = HWFIX_MENU_NUM; + uint32_t menuExit = 0; + + //Draw screen first time + DisplayHwFixMenu(selected); + + + while(1) + { + //use keys to changes selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + switch(pressed) //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_BACK: + menuExit = true; + break; + case ON_OFF_KEY: + //Do nothing + break; + case KEY_UP: + if(--selected > menuNum) + { + selected = 0; + } + DisplayHwFixMenu(selected); + break; + case (KEY_UP << KEY_LONG_PRESS): + do + { + if(--selected > menuNum) + { + selected = 0; + } + DisplayHwFixMenu(selected); + + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetUpKeyHeld()); + break; + case KEY_DOWN: + if(++selected >= menuNum) + { + selected = menuNum - 1; + } + DisplayHwFixMenu(selected); + break; + case (KEY_DOWN << KEY_LONG_PRESS): + do + { + if(++selected >= menuNum) + { + selected = menuNum - 1; + } + DisplayHwFixMenu(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetDownKeyHeld()); + break; + case KEY_ENTER: //SHORT Press to SET Hardware Fix + switch(selected) + { + case(0): //vBattCap_021 + EE_WriteUINT32(EE_HWFIX_VBATT_CAP_021, true); + hwf.vBattCap_021 = true; + break; + case(1): //Increase mainPcbaPN + hwf.mainPcbaPN += 2; + if(hwf.mainPcbaPN > HWF_MAX_MAIN_PCBA_PN) + { + hwf.mainPcbaPN = HWF_MAX_MAIN_PCBA_PN; + } + EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN); + break; + case(2): //Not used + + break; + default: + break; + } + DisplayHwFixMenu(selected); //Redraw menu after any changes + break; + case (KEY_ENTER << KEY_LONG_PRESS): //LONG Press to CLEAR Hardware Fix + switch(selected) + { + case(0): //vBattCap_021 + EE_WriteUINT32(EE_HWFIX_VBATT_CAP_021, false); + hwf.vBattCap_021 = false; + break; + case(1): //Decrease mainPcbaPN + hwf.mainPcbaPN -= 2; + if(hwf.mainPcbaPN < HWF_MIN_MAIN_PCBA_PN) + { + hwf.mainPcbaPN = HWF_MIN_MAIN_PCBA_PN; + } + EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN); + break; + case(2): //Not used + + break; + default: + break; + } + DisplayHwFixMenu(selected); //Redraw menu after any changes + break; + } + + if(menuExit) + { + return; + } + } +} + +static void DisplayHwFixMenu(uint32_t selected) +{ + char displayIndex = 0; //index of first menu line to draw + uint32_t menuNum = HWFIX_MENU_NUM; + + LCD_Clear(); + //Title + FL_DrawString("HARDWARE FIXES", LCD_X_MID, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + //Update displayIndex + if(selected >= (displayIndex + MENU_TEST_MAX_LINES_DISPLAYED)) + { + displayIndex++; + } + else if(selected < displayIndex) + { + displayIndex--; + } + + //Draw menu items + uint32_t lastIndex = displayIndex + MENU_TEST_MAX_LINES_DISPLAYED; //last line to draw. Limit lastIndex to max lines + if(lastIndex > menuNum) //Limit lastIndex to number of items + { + lastIndex = menuNum; + } + for(uint32_t i = displayIndex; i < lastIndex; i++) + { + //Menu strings + FL_DrawString(hwFixMenu[i].text, MENU_MAIN_TEXT_X, MENU_TEST_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + //Draw item status + switch(i) + { + case(0): //vBattCap_021 + FL_DrawString(GetFixStatusString(hwf.vBattCap_021), MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case(1): //mainPcbaPN + sprintf(tempString, "%d", hwf.mainPcbaPN); + FL_DrawString(tempString, MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case(2): // + break; + + default: + break; + } + } + + //Draw selection bar + uint32_t selRectY0 = MENU_TEST_TEXT_Y_START + (selected - displayIndex)*MENU_LINE_HEIGHT; + GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); + + + DrawTestMenuScrollBar(displayIndex, menuNum); + + + LCD_Update(); +} + + +/* Draw TEST menu scroll bar on right side + * DIFFERENT for testMenu since number of lines per screen is different + */ +static void DrawTestMenuScrollBar(uint32_t displayIndex, uint32_t numItems) +{ + //Exit if scroll bar not needed + if(numItems <= MENU_MAX_LINES_DISPLAYED) + { + return; + } + //numItems = 30; // 18 + //vertical line + const uint32_t lineWidth = 5; + const uint32_t lineX = LCD_X_MAX - 10; + const uint32_t lineYStart = 20; + const uint32_t lineYStop = LCD_Y_MAX - 20; + const uint32_t lineHeight = lineYStop - lineYStart; + + //rectangle + const uint32_t rectWidth = 20; + const uint32_t rectX = lineX; + + uint32_t rectHeight = lineHeight * ((double)MENU_TEST_MAX_LINES_DISPLAYED / numItems); + uint32_t rectYStart = lineYStart + (lineHeight - rectHeight) * ((double)displayIndex / (numItems - MENU_MAX_LINES_DISPLAYED)); + uint32_t rectYStop = rectYStart + rectHeight; + + //Draw line + GL_DrawLine(lineX, lineYStart, lineX, lineYStop, lineWidth, LCD_DRAW_SET); + + //Draw Rectangle + GL_DrawLine(rectX, rectYStart, rectX, rectYStop, rectWidth, LCD_DRAW_SET); +} + +/******************************************************************************* + * Public Functions + ******************************************************************************/ + +void TM_Init(void) +{ + //Clear menu items + ClearTestMenuItems(testMenu, TEST_MENU_NUM); + ClearTestMenuItems(hwFixMenu, HWFIX_MENU_NUM); + + + uint32_t i = 0; + + //test menu + testMenu[i].pMonoIcon = 0; + strcpy(testMenu[i++].text, "Test Mode"); + + testMenu[i].pMonoIcon = 0; + strcpy(testMenu[i++].text, "Show Details"); + + testMenu[i].pMonoIcon = 0; + strcpy(testMenu[i++].text, "Hardware Fixes"); + + testMenu[i].pMonoIcon = 0; + strcpy(testMenu[i++].text, "Frog"); + + testMenu[i].pMonoIcon = 0; + strcpy(testMenu[i++].text, "Tuna"); + + + + i = 0; + + //hwFix menu + hwFixMenu[i].pMonoIcon = 0; + strcpy(hwFixMenu[i++].text, "VBatt Cap (021)"); + + hwFixMenu[i].pMonoIcon = 0; + strcpy(hwFixMenu[i++].text, "Main PCBA PN"); + + hwFixMenu[i].pMonoIcon = 0; + strcpy(hwFixMenu[i++].text, "TBD"); +} + + +/* + * Test menu accesses through konami code + */ +void TM_TestMenu(void) +{ + uint32_t selected = 0; + uint32_t menuNum = TEST_MENU_NUM; + uint32_t menuExit = 0; + + //Draw screen first time + TM_DisplayTestMenu(selected); + + + while(1) + { + //use keys to changes selected + uint32_t pressed = KEY_WaitForKeyPress(KEY_ALL); + + switch(pressed) //This won't work if multiple keys pressed, but it'll clear them + { + case KEY_BACK: + menuExit = true; + break; + case ON_OFF_KEY: + //Do nothing + break; + case KEY_UP: + if(--selected > menuNum) + { + selected = 0; + } + TM_DisplayTestMenu(selected); + break; + case (KEY_UP << KEY_LONG_PRESS): + do + { + if(--selected > menuNum) + { + selected = 0; + } + TM_DisplayTestMenu(selected); + + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetUpKeyHeld()); + break; + case KEY_DOWN: + if(++selected >= menuNum) + { + selected = menuNum - 1; + } + TM_DisplayTestMenu(selected); + break; + case (KEY_DOWN << KEY_LONG_PRESS): + do + { + if(++selected >= menuNum) + { + selected = menuNum - 1; + } + TM_DisplayTestMenu(selected); + Delay_Ticks(MENU_KEY_HOLD_SCROLL_DELAY); + } + while(KEY_GetDownKeyHeld()); + break; + case KEY_ENTER: + switch(selected) + { + case(0): //Test Mode + //Toggle test mode flag + break; + case(1): //Show Details + Diag_Flag ^=1; //Toggle showDetails flag + break; + case(2): //Hardware Fixes + HwFixMenu(); + break; + case(3): //Not used + + break; + case(4): //Not used + + break; + case(5): //Not used + + break; + default: + break; + } + TM_DisplayTestMenu(selected); //Redraw menu after any changes + + break; + } + + if(menuExit) + { + return; + } + } +} + +void TM_DisplayTestMenu(uint32_t selected) +{ + char displayIndex = 0; //index of first menu line to draw + uint32_t menuNum = TEST_MENU_NUM; + + LCD_Clear(); + //Title + FL_DrawString("SNEAKRET MENU", LCD_X_MID, 0, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_CENTER); + + //Update displayIndex + if(selected >= (displayIndex + MENU_TEST_MAX_LINES_DISPLAYED)) + { + displayIndex++; + } + else if(selected < displayIndex) + { + displayIndex--; + } + + //Draw menu items + uint32_t lastIndex = displayIndex + MENU_TEST_MAX_LINES_DISPLAYED; //last line to draw. Limit lastIndex to max lines + if(lastIndex > menuNum) //Limit lastIndex to number of items + { + lastIndex = menuNum; + } + for(uint32_t i = displayIndex; i < lastIndex; i++) + { + //Menu strings + FL_DrawString(testMenu[i].text, MENU_MAIN_TEXT_X, MENU_TEST_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + //Draw item status + switch(i) + { + case(0): //Test Mode + FL_DrawString(GetOnOffString(0), MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case(1): //Show Details + FL_DrawString(GetOnOffString(Diag_Flag), MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i - displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + break; + case(2): //Hardware Fix Menu + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + case(3): //Frog + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + case(4): //Tuna + GL_DrawMonoBitmap(menuMore, MENU_MAIN_STATUS_X, MENU_TEST_TEXT_Y_START + (i-displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + break; + default: + break; + } + } + + //Draw selection bar + uint32_t selRectY0 = MENU_TEST_TEXT_Y_START + (selected - displayIndex)*MENU_LINE_HEIGHT; + GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); + + + DrawTestMenuScrollBar(displayIndex, menuNum); + + + LCD_Update(); +} + diff --git a/source/testMenu.h b/source/testMenu.h new file mode 100644 index 0000000..0c6d2e2 --- /dev/null +++ b/source/testMenu.h @@ -0,0 +1,24 @@ +/* + * testMenu.h + * + * Created on: Mar 27, 2024 + * Author: Brian.Bailey + */ + +#ifndef TESTMENU_H_ +#define TESTMENU_H_ + + +#define TEST_MENU_NUM 3 +#define HWFIX_MENU_NUM 3 + +#define MENU_TEST_TEXT_Y_START 21 //submenu text y starting value (start + n*lines). same as MENU_LINE_HEIGHT + +#define MENU_TEST_MAX_LINES_DISPLAYED 5 //5 lines per page for testMenu + + +void TM_Init(void); +void TM_TestMenu(void); +void TM_DisplayTestMenu(uint32_t selected); + +#endif /* TESTMENU_H_ */ diff --git a/source/timer.c b/source/timer.c new file mode 100644 index 0000000..d6cd005 --- /dev/null +++ b/source/timer.c @@ -0,0 +1,243 @@ +/* + * timer.c + * + * Created on: Jun 29, 2022 + * Author: Keith.Lloyd + */ + +/******************************************************************************* + * Includes + ******************************************************************************/ + + +#include "pin_mux.h" +#include "board.h" +#include "fsl_ctimer.h" +#include "timer.h" +#include "keys.h" +#include +#include "main.h" +#include "ports.h" +#include "adc.h" +#include "utils.h" +#include "usbComms.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define CTIMER CTIMER0 /* Timer 0 */ +#define CTIMER_MAT0_OUT kCTIMER_Match_0 /* Match output 3 */ + +#define CTIMER_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk) + + + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +void ctimer_match0_callback(uint32_t flags); + + +/* Array of function pointers for callback for each channel */ +ctimer_callback_t ctimer_callback_table[] = {ctimer_match0_callback}; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +TIMER_t tmr; + +uint8_t * autoShutdownStrings[] = {"1 HOUR", "2 HOURS", "NEVER"}; //MUST match AUTO_SHUTDOWN_t + +/* Match Configuration for Channel 0 */ +static ctimer_match_config_t matchConfig0; +ctimer_config_t config; + +//static volatile uint32_t Sys_Timer,Tx_timer; +uint32_t Sys_Timer,Tx_timer; + +extern uint8_t Task, Tx_Time_Out_Flag, frq_chg_tmr; +extern uint16_t Port_timer, Taps_adjust_timer,Sys_Chk_tmr,Display_warning_tmr; +uint16_t Low_Bat_timer,Estop_timer,Shut_down_tmr,Vchktmr, Over_Voltage_tmr,PSU_Check_tmr; +uint16_t Key_Lock_Out_tmr,ByPass_tmr; +uint32_t TX_TIME[4] = {TIME_1HR,TIME_2HR,TIME_0HR,TIME_0HR}; + +extern ADC_t adc; +uint32_t systemTime = 0; // 10mS ticks + +/******************************************************************************* + * Code + ******************************************************************************/ + + + +void ctimer_match0_callback(uint32_t flags) // ISR every 10mS +{ + static bool Test_Flg = false; + if(Test_Flg) + GPIO_PinWrite(GPIO, 0, 4, 1); //TODO remove + else + GPIO_PinWrite(GPIO, 0, 4, 0); //TODO remove + + Test_Flg ^=1; + + // Sys_Timer = 1000000; +// it goes here + + Check_Live_Voltage(); + + systemTime += 10; // increment system time by 10mS + + if (Sys_Timer > 0) + Sys_Timer--; + + if (frq_chg_tmr > 0) + frq_chg_tmr--; + + if (Low_Bat_timer > 0) + Low_Bat_timer--; + + if(Shut_down_tmr > 0) + Shut_down_tmr--; + if(Vchktmr > 0) + Vchktmr--; + + if(Over_Voltage_tmr > 0) + Over_Voltage_tmr--; + + if(PSU_Check_tmr > 0) + PSU_Check_tmr--; + + if(Key_Lock_Out_tmr > 0) + Key_Lock_Out_tmr--; + + KEY_Update(); + + Tx_TimeOut(); // Check main transmitter timer + + if( Port_timer > 0) + Port_timer--; // Port checking timer + if( Taps_adjust_timer > 0) + Taps_adjust_timer--; // Port checking timer + if(Estop_timer > 0) + Estop_timer--; + if(Sys_Chk_tmr > 0) + Sys_Chk_tmr--; + + if(ByPass_tmr > 0) + ByPass_tmr--; + + if(Display_warning_tmr > 0) + Display_warning_tmr--; + + + if(adc.measure) + { + ADC_Update(); + } +// GPIO_PinWrite(GPIO, 0, 4, 0); // TODO Whats' this for ?? Probably left over debug of timer +} + +/*! + * @brief Main function + */ +void timer_init(void) +{ +uint8_t i; + + /* Enable the asynchronous bridge */ + SYSCON->ASYNCAPBCTRL = 1; + + /* Use 12 MHz clock for some of the Ctimers */ + CLOCK_AttachClk(kFRO12M_to_ASYNC_APB); + + + CTIMER_GetDefaultConfig(&config); + + CTIMER_Init(CTIMER, &config); + + /* Configuration 0 */ + matchConfig0.enableCounterReset = true; + matchConfig0.enableCounterStop = false; + matchConfig0.matchValue = 1500000;//150MHz clock 10mS period + matchConfig0.enableInterrupt = true; + + CTIMER_RegisterCallBack(CTIMER, &ctimer_callback_table[0], kCTIMER_MultipleCallback); + CTIMER_SetupMatch(CTIMER, CTIMER_MAT0_OUT, &matchConfig0); + + CTIMER_StartTimer(CTIMER); + tmr.timerInitialized = true; + + i = tmr.autoShutdown; + Tx_timer = TX_TIME[i]; // reload the timer +} + + +void Delay_Ticks(uint32_t Delay_Interval) +{ + Sys_Timer = Delay_Interval; // load timer with multiples of 10mS + + while (Sys_Timer > 0); + +} + + + +void Tx_TimeOut(void) +{ + if (tmr.autoShutdown != SD_NEVER) + { + if (Tx_timer > 0) + { + Tx_timer--; + if (Tx_timer == 0) + Task = PWR_OFF_TASK; // schedule a PWR Down + } + } +} + + + +//Cycle through auto shutdown options +void tmr_ChangeAutoSDTimer(void) +{ + unsigned int i; + + i = tmr.autoShutdown; + + if(++tmr.autoShutdown >= SD_NUM) + { + tmr.autoShutdown = (AUTO_SHUTDOWN_t)0; + } + + Tx_timer = TX_TIME[i]; // reload the timer +} + + + +uint8_t * tmr_GetAutoSDTimerString(void) +{ + return autoShutdownStrings[tmr.autoShutdown]; +} + +/* Start CTIMER0 + * Does nothing if timer not initialized + */ +void TMR_Start(void) +{ + if(tmr.timerInitialized) + { + CTIMER_StartTimer(CTIMER); + } +} + +/* Stop CTIMER0 + * Does nothing if timer not initialized + */ +void TMR_Stop(void) +{ + if(tmr.timerInitialized) + { + CTIMER_StopTimer(CTIMER); + } +} diff --git a/source/timer.h b/source/timer.h new file mode 100644 index 0000000..452ecfe --- /dev/null +++ b/source/timer.h @@ -0,0 +1,57 @@ +/* + * timer.h + * + * Created on: Jun 29, 2022 + * Author: Keith.Lloyd + */ + +#ifndef TIMER_H_ +#define TIMER_H_ +#define TIME_1HR 360000 // should be 360000 +#define TIME_2HR 2*TIME_1HR +#define TIME_3HR 3*TIME_1HR +#define TIME_4HR 4*TIME_1HR +#define TIME_5HR 5*TIME_1HR +#define TIME_6HR 6*TIME_1HR +#define TIME_7HR 7*TIME_1HR +#define TIME_8HR 8*TIME_1HR +#define TIME_9HR 9*TIME_1HR +#define TIME_0HR 10 +#define DELAY_5S 500 +#define DELAY_1S 100 +#define DELAY_2S 200 +#define DELAY_500MS 50 +#define DELAY_250MS 25 +#define DELAY_200MS 20 +#define LOCK_OUT_DELAY DELAY_2S * 2 +#define PSU_DELAY DELAY_250MS +#define KEY_LOCK_TIME DELAY_250MS * 2 + +void timer_init(void); +void Delay_Ticks(uint32_t Delay_Interval); +void Tx_TimeOut(void); + +typedef enum { + DISABLED, + ENABLED +}TMR_MODE_t; + +typedef enum { + SD_1_HR, + SD_2_HR, + SD_NEVER, + SD_NUM +}AUTO_SHUTDOWN_t; + +typedef struct{ + AUTO_SHUTDOWN_t autoShutdown; //auto shutdown setting + bool timerInitialized; //CTIMER has been initialized +} TIMER_t; + + +void tmr_ChangeAutoSDTimer(void); +uint8_t * tmr_GetAutoSDTimerString(void); +void TMR_Start(void); +void TMR_Stop(void); + +#endif /* TIMER_H_ */ diff --git a/source/utils.c b/source/utils.c new file mode 100644 index 0000000..d80eb10 --- /dev/null +++ b/source/utils.c @@ -0,0 +1,787 @@ +/* + * utils.c + * + * Created on: Jun 7, 2022 + * Author: Keith.Lloyd + */ + +#include "arm_math.h" +#include "fsl_gpio.h" +#include "fsl_spi.h" +#include "spi.h" +#include "lcd.h" +#include "eeprom.h" +#include "display.h" +#include "utils.h" +#include "frq.h" +#include "psu_ctrl.h" +#include "amps.h" +#include "main.h" +#include "ports.h" +#include "adc.h" +#include "timer.h" +#include "mode.h" +#include "stdbool.h" +#include +#include "sys_chk.h" +#include "pro_key.h" +#include +#include "hwFixes.h" +#include "System\system.h" + + +//#define ON 1 + +uint16_t Sys_Chk_tmr; +extern uint8_t Port_State[]; +extern uint16_t Estop_timer; +extern uint8_t Over_Voltage_Flag, LD_Flag; +extern uint8_t Over_Current_Flag; +extern uint8_t Hardware_Error_Flag; +extern uint8_t frequency, Task, Cur_Mode; +extern spi_master_config_t SPI0_config; +extern ADC_t adc; +extern AMP_XFRMR_SLCT_t Amp2xfrmr; +extern uint8_t frequency,old_freq,frq_chg_tmr; + +extern float32_t Watts, Max_Power_Limit, Milli_amps,test_val2; +extern uint8_t Dds_Pot_Val[], Power_Level; +extern uint16_t Pot_Value_CLAMP1[]; +extern uint16_t Pot_Value_CLAMP_AB[]; // DDS Output amplitude. (AB amp) +extern uint16_t Pot_Value_AB[]; +extern uint16_t Pot_Value[]; +extern uint32_t new_freq,test_val1; +extern uint16_t Vchktmr, Over_Voltage_tmr; +extern float32_t Watts_Filt; +extern uint8_t Psu_Pot_Val[]; // 2 byte Data for SPI +extern uint16_t PSU_Check_tmr; +extern uint8_t tempString[40]; // +extern HARDWARE_FIX_t hwf; +extern SYSTEM_DATA_t sys; + +extern ClampData_t clampData; + +uint8_t Error, Suspend_Step_Chk; + +uint8_t Check_Output_Status(char Connector) +{ + uint32_t x = 1; + + if (Connector == 1) + x = adc.V_ID1; // Todo Don't forget limits. + else + x = adc.V_ID2; + + if (x > TGT_NOT_USED) + return (EMPTY); + if (x > CLAMP_MIN && x < CLAMP_MAX) + return (CLAMP); + if (x > DC_MIN && x < DC_MAX) + return (CONNECT_LEAD); + if (x > DDC_MIN && x < DDC_MAX) + return (DUAL_DC); + +} + +void Clear_Relays() +{ + uint8_t sendData; //ToDo SSELx will be wrong double check and fix + + Port_State[0] &= ALL_RELAYS_OFF_UPPER;// clears all relays and disconnects from outputs + + Port_State[1] &= ALL_RELAYS_OFF_LOWER; + + Send_Update_Port(); + +} + +void Send_Update_Port(void) +{ +#if 1 + SPI0_SendBytes(&Port_State[0], 3, EXPANDER); //2 bytes + +#else + GPIO_PinWrite(GPIO, 0, PORT_LE, 0); // Activate CS + + // First byte +SPI3_SendBytes(&Port_State[0], 1); //send first byte via SPI + + // Reset all relays on second port. +SPI3_SendBytes(&Port_State[1], 1); //send second byte via SPI + +GPIO_PinWrite(GPIO, 0, PORT_LE, 1); // De-select CS +#endif +} + +void Select_Bypass(RELAY_SELECT_t Bypass) // Bypass allows transmitting w/o full protection +{ + if (Bypass) + { + if ((freqArray[frequency].frequency1 < MIN_BLOCK_FREQ) && (!Over_Voltage_Flag)) + Port_State[MID_SR] |= BYPASS_ON; // Set relay to By Pass protection cap + } + else + Port_State[MID_SR] &= ~BYPASS_ON; // ReSet relay to include Cap in circuit + + SPI0_SendBytes(Port_State, 3, EXPANDER); // Send_Update_Port(); + +} + +void Select_Estop(RELAY_SELECT_t E_stop) +{ + if (E_stop) + GPIO_PinWrite(GPIO, 1, ESTOP, 0); // Isolated + else + GPIO_PinWrite(GPIO, 1, ESTOP, 1); // Not Isolated + +} +void Select_Transformer() +{ + + if (freqArray[frequency].frequency1 > MAX_LOW_FRQ)//ie. > 80K Was MAX_DTYPE + { + Port_State[MID_SR] |= SLCT_XFMR; // Switch to High freq xfrmr Taps O/P + Port_State[TOP_SR] &= ~MUX_AB_AMP; // 0 AB Amp to HF Xfrmr + } + + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + { // ie. < 44100 + Port_State[MID_SR] &= ~SLCT_XFMR; // Switch to Low freq Xfmr Taps O/P +// Port_State[TOP_SR] &= ~MUX_AB_AMP; // Switch to Low freq Xfmr + Port_State[BOTTOM_SR] &= ~SLCT_AMP; // 0 D AMP routed to LF Xfrmr + + } +// if(((freqArray[frequency].frequency1 == 65536) || (freqArray[frequency].frequency1 == 200000) || (freqArray[frequency].frequency1 == MAX_LOW_FRQ))) + if ((freqArray[frequency].frequency1 >= 60000) + && (freqArray[frequency].frequency1 <= 200000)) + { + Port_State[TOP_SR] |= MUX_AB_AMP; // 1 AB Routed Away from HF Xfrmr + Port_State[BOTTOM_SR] |= SLCT_AMP; // 1 AB AMP routed to LF Xfrmr + Port_State[MID_SR] &= ~SLCT_XFMR; // 0 LF Transformer taps output selected + } + +// Port_State[BOTTOM_SR] &= ~SLCT_AMP; // Switch to AMP D to Low freq Xfmr by default whether used + // or not + + SPI0_SendBytes(Port_State, 3, EXPANDER); +} + +void Select_Amp_Xfrmr_Rly(AMP_XFRMR_SLCT_t Amp2xfrmr) // Allows any combination of Amp and transformer +{ // NOT CURRENTLY USED + + switch (Amp2xfrmr) + + { + case LFA_LFX: + Port_State[MID_SR] &= ~XFRMR_HF_ON; // Switch path to Low freq Xfmr + Port_State[BOTTOM_SR] &= ~HF_AMP_ON;// Switch path for Low freq Amplifier to LF Xfrmr + + break; + + case HFA_LFX: + Port_State[MID_SR] &= ~XFRMR_HF_ON; // Switch path to Low freq Xfmr + Port_State[BOTTOM_SR] |= HF_AMP_ON; // Switch path for High freq Amplifier to LF Xfrmr + + break; + + case HFA_HFX: + Port_State[MID_SR] |= XFRMR_HF_ON; // Switch path to High freq Xfmr + Port_State[BOTTOM_SR] |= HF_AMP_ON; // Switch path for High freq Amplifier to LF Xfrmr + + break; + + } + +} + +void Power_ON_OFF(RELAY_SELECT_t Power) +{ + if (Power) + GPIO_PinWrite(GPIO, 1, PWR_CTL, PWR_ON); // Switch or keep power on + else + GPIO_PinWrite(GPIO, 1, PWR_CTL, PWR_OFF); // Switch power off +} + +void Check_Clamp_OverVoltage(void) +{ + if (Cur_Mode != BROADCAST) + { + + if((Check_For_Clamp())) + { + if (ACCY_GetActive() != ID_CLAMP2) + { + if (Compare_Voltage(adc.V_OUT, MAX_CLAMP_VOLTAGE)) + Adjust_Clamp_Volts(); + } + } + } +} +void Check_Live_Voltage() +{ + + bool dc1 = ((ACCY_GetConnectedAccessory(1) == ID_TX_SINGLE_DIRECT) + || (ACCY_GetConnectedAccessory(1) == ID_TX_DUAL_DIRECT)); + bool dc2 = ((ACCY_GetConnectedAccessory(2) == ID_TX_SINGLE_DIRECT) + || (ACCY_GetConnectedAccessory(2) == ID_TX_DUAL_DIRECT)); + + + if ((Power_Level == 0) && (dc1 || dc2)) + { + if (Vchktmr == 0) + { + if (Compare_Voltage(adc.V_CHK, MAX_OP_VOLTS)) //Potentially fatal voltage + { + Select_Estop(ON); // Fault condition disable output + Select_Bypass(OFF); // Force into blocked state. + // Over_Voltage_Flag = true; + // Estop_timer = DELAY_5S; + Task = SAFETY_TASK; + } + + if (Compare_Voltage(adc.V_CHK, MAX_BYPASS_VOLTS)) // damaging voltage but allow operation + { // to continue. + Over_Voltage_Flag = true; + Select_Bypass(OFF); // Force into blocked state. + } + } + } +} + +bool Compare_Voltage(float32_t source, float32_t limit) +{ + + if (source > limit) + return (true); + else + return (false); +} + +void Check_Over_Current() +{ +float x; + + x = Get_Max_Current(); + if (adc.I_OUT_FastFilt * 1000 > x) + { + Power_Level = 0; + Cut_Signal_To_Min(); + + if (ACCY_GetActive() == ID_CLAMP2) + { + Get_Clamp_Value(); + clampData.pot = 1; + } + + } +} + +float Get_Max_Current(void) +{ + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + return (MAX_CURRENT); + else + return (MAX_HF_CURRENT); +} + +void Check_Over_Power(void) +{ +//uint8_t New_Pot_Val; + if (Cur_Mode != BROADCAST) + { + if (ACCY_GetActive() != ID_CLAMP2) + { + if (freqArray[frequency].frequency1 < MAX_DTYPE) + Adjust_Output_Power(Max_Power_Limit); + else + Adjust_Output_Power(1.0); + } + } +// Delay_Ticks(100); +} + +float32_t Get_Power_Limit(void) +{ + if (freqArray[frequency].frequency1 < MAX_DTYPE) + return(Max_Power_Limit); + else + return(1.0); + +} + + +void Adjust_Output_Power(float32_t New_Power_Limit) +{ + if (Watts_Filt > New_Power_Limit) + { + uint8_t New_Pot_Val; + + New_Pot_Val = New_Power_Limit / Watts_Filt * Dds_Pot_Val[1]; + if (New_Pot_Val > freqArray[frequency].max_pot) + Dds_Pot_Val[1] = freqArray[frequency].max_pot; + else + Dds_Pot_Val[1] = New_Pot_Val; + + Dds_Pot_Val[0] = 0; // address + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + Suspend_Step_Chk = true; + } + else + Suspend_Step_Chk = false; + +} + +void Check_PSU_Short(void) // if output less than 10% of expected PSU voltage +{ // then a fault condition is present. + if (PSU_Check_tmr == 0) + { + if ((adc.V_PSU * 1.2) < Convert_Pot2_Volts(Psu_Pot_Val[1])) + { + Select_Estop(ON); // Disconnect from external threats + + Power_Level = 0; // set demand to minimum to prevent damage + // Update_Amp_Pot(); + Cut_Signal_To_Min(); + + Disable_DC(); // power off all active systems + + Disable_BC(); //Disable BC + + Port_State[BOTTOM_SR] |= ~AMP_PSU_ON; // switch AMP PSU OFF + SPI0_SendBytes(Port_State, 3, EXPANDER); // Update shift register + + Task = FATAL_ERROR_TASK; + Error = 1; + } + } +} + +void Estop_Mode(void) +{ + Select_Estop(ON); + Task = ESTOP_TASK; +} + +void Power_Down() +{ + static bool flasher = false; + + LCD_Clear(); // Clear the display. + + Display_Bye_Bye(); // Display Power down message to user + + EE_SaveData(); // Save necessary settings to E2PROM,timer freq' etc + + Controlled_Pwr_Dwn(); + Delay_Ticks(DELAY_200MS); + uint8_t count_down; + + count_down = 0; + + while (1) + { + Power_ON_OFF(OFF); // Power down system + Delay_Ticks(DELAY_200MS); + + if (count_down == 4) + { + if (flasher) + { + LCD_Clear(); + Display_USB(); + count_down = 0; + LCD_Update(); + } + else + { + LCD_Clear(); + LCD_Update(); + + } + + flasher ^= 1; //toggle + + } + else + count_down++; + + } + +} + +void Chk_Gain(void) +{ + + if (!Short_Circuit_Chk()) //Check for short condition first + { + uint32_t fre = 0; + fre++; + + if ((Port_State[MID_SR] & I_GAIN) > 0) // High gain + { + if (adc.I_OUT_SlowFilt > 0.035) + { + Port_State[MID_SR] &= ~I_GAIN; // U12 switch to low gain + SPI0_SendBytes(Port_State, 3, EXPANDER); + } + } + else + { + if (adc.I_OUT_SlowFilt < 0.025) + { + Port_State[MID_SR] |= I_GAIN; // switch to High gain + SPI0_SendBytes(Port_State, 3, EXPANDER); + + } + + } + +// Port_State[MID_SR] &= ~I_GAIN; // U12 always low gain for test +// Port_State[MID_SR]|= I_GAIN; // switch to high gain +// SPI0_SendBytes(Port_State, 3, EXPANDER); + + } + Sys_Chk_tmr = DELAY_1S; + +} + +void Count_Down_PWR_OFF(void) //Display_Bat_Error(); +{ + +} + +void Adjust_Clamp_Volts(void) // Set clamp output voltages to PL1 +{ + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + { + Dds_Pot_Val[1] = Pot_Value_CLAMP1[1]; // data + Power_Level = 1; + } + else + { + Dds_Pot_Val[1] = Pot_Value_CLAMP_AB[1]; // data + Power_Level = 1; + } + + Dds_Pot_Val[0] = 0; // address + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + +} +void Check_Over_Voltage(void) // Check Direct Connect Over voltage +{ + uint8_t New_Pot_Val; + uint8_t test1; + if (Over_Voltage_tmr == 0) + { +// if (Cur_Mode != BROADCAST && (ACCY_GetConnectedAccessory(1) != ID_CLAMP) +// && (ACCY_GetConnectedAccessory(2) != ID_CLAMP)) +// test1 = Check_For_Clamp(); + if (Cur_Mode != BROADCAST && !Check_For_Clamp()) + { + if (Compare_Voltage(adc.V_OUT_FastFilt, MAX_DC_VOLTAGE)) + { + Vchktmr = LOCK_OUT_DELAY; + New_Pot_Val = MAX_DC_VOLTAGE / adc.V_OUT_FastFilt + * Dds_Pot_Val[1]; + if (New_Pot_Val > freqArray[frequency].max_pot) + Dds_Pot_Val[1] = freqArray[frequency].max_pot; + else + Dds_Pot_Val[1] = New_Pot_Val; + + Dds_Pot_Val[0] = 0; // address + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + + // dec_pwr(); + // SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + Over_Voltage_tmr == DELAY_5S; + } + } + } +} + +void Controlled_Pwr_Dwn() +{ + uint8_t count; + uint8_t avalue; // for debugging only + + if (Cur_Mode != BROADCAST) // decrementally adjust amplitude to zero + { + count = 0; + Dds_Pot_Val[0] = 0; // address + + while (Dds_Pot_Val[1] > MIN_POT && count < SENTINAL) + { + Dds_Pot_Val[1]--; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); +// Update_Amp_Pot(); + + count++; + Delay_Ticks(1); + } + Delay_Ticks(2); + All_Amps_Off(); + + Set_PSU_Voltage(V_18V); + Delay_Ticks(20); + + } + + All_Amps_Off(); //turn off amps + Disable_BC(); // Set duty cycle to zero + + Delay_Ticks(2); + + Set_PSU_Voltage(V_18V); // switch off main psu down + Delay_Ticks(DELAY_250MS); +} + +void Update_Amp_Pot(void) +{ + uint8_t avalue; // for debugging only + Dds_Pot_Val[0] = 0; // address + + if (freqArray[frequency].frequency1 <= MAX_DTYPE) + Dds_Pot_Val[1] = Pot_Value[Power_Level]; // data + else + Dds_Pot_Val[1] = Pot_Value_AB[Power_Level]; // data + + avalue = Dds_Pot_Val[1]; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + +} + +void Check_For_Clamp_On_Pwr_Up(void) +{ + uint32_t idNumber1 = (uint32_t) ((adc.V_ID2 * 3.3333) + 0.5);//multiply by 3.3333 and round to nearest integer + uint32_t idNumber2 = (uint32_t) ((adc.V_ID1 * 3.3333) + 0.5);//multiply by 3.3333 and round to nearest integer + + uint8_t count; + + if (idNumber1 == 5 || idNumber2 == 5) +// Change_to_next_dc_frq(); + { + if (freqArray[frequency].frequency1 <= MIN_CTYPE)// is frequecny > min + { + count = 0; + + while (freqArray[frequency].frequency1 < MIN_CTYPE + && count < FREQ_MAX_NUM) + { + frequency = Next_Frequency(frequency);// increment the frequency + new_freq = freqArray[frequency].frequency1; + count++; + + } + } + } + +} +bool Check_For_Clamp_New() +{ + uint32_t idNumber1 = (uint32_t) ((adc.V_ID2 * 3.3333) + 0.25);//multiply by 3.3333 and round to nearest integer + uint32_t idNumber2 = (uint32_t) ((adc.V_ID1 * 3.3333) + 0.25);//multiply by 3.3333 and round to nearest integer + + uint8_t count; + + if (idNumber1 == ID_CLAMP || idNumber2 == ID_CLAMP || idNumber1 == ID_CLAMP2 || idNumber2 == ID_CLAMP2) + return(true); + else + return(false); +} + +void Reduce_Kick_Back(void) // reduce amplitude + +{ + uint8_t count; + count = 0; + Dds_Pot_Val[0] = 0; // address + + while (Dds_Pot_Val[1] > MIN_POT && count < SENTINAL) + { + Dds_Pot_Val[1] -= 2; + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); // reduce amplitude + + count++; + Delay_Ticks(1); + } + + Set_PSU_Voltage(V_18V); // reduce power supply voltage + Delay_Ticks(20); + // delay for catch up + + // + +} + +float32_t Convert_Pot2_Volts(uint8_t value) +{ + switch (value) + { + + case V_18V: + return (18.0); + break; + + case V_21V: + return (21.0); + break; + + case V_24V: + return (24.0); + break; + + case V_27V: + return (27.0); + break; + + case V_30V: + return (30.0); + break; + + case V_36V: + return (36.0); + break; + + case V_55V: + return (55.0); + break; + + default: + return (36.0); + + } +} +void Cut_Signal_To_Min(void) +{ + Dds_Pot_Val[0] = 0; // address + Dds_Pot_Val[1] = 2; // data + + SPI0_SendBytes(Dds_Pot_Val, 2, AMPLITUDE); + +} + +bool Check_For_Clamp(void) // Assumes BROADCAST already checked for +{ + if(Cur_Mode == PORT1_A) + { + if(ACCY_GetConnectedAccessory(1) == ID_CLAMP || ACCY_GetConnectedAccessory(1) == ID_CLAMP2) + return(true); + else + return(false); + } + else + { + if(ACCY_GetConnectedAccessory(2) == ID_CLAMP || ACCY_GetConnectedAccessory(2) == ID_CLAMP2) + return(true); + else + return(false); + + } + +} + + + + +void freq_key_process(void) +{ + uint32_t tmp_frqx; + + LD_Flag = false; + + frq_chg_tmr = KEY_DELAY; // Set timer to delay h/w update + old_freq = frequency; + + if(Cur_Mode != BROADCAST) + { + Change_to_next_dc_frq(); + } + else + { + if (freqArray[frequency].frequency1 < BCAST_MIN) // if (freq < min freq) ToDo + { + tmp_frqx = Search_Frequency(3140); // select minimum frequency for BCAST + if (tmp_frqx < FREQ_MAX_NUM) + { + frequency = tmp_frqx; + new_freq = freqArray[frequency].frequency1; + } + } + else + { + frequency = Next_Frequency(frequency); // increment the frequency + new_freq = freqArray[frequency].frequency1; + if(new_freq == 263) + { + tmp_frqx = Search_Frequency(3140); // select minimum frequency for BCAST + if (tmp_frqx < FREQ_MAX_NUM) + { + frequency = tmp_frqx; + new_freq = freqArray[frequency].frequency1; + } + } + } + } +} + +void LD_key_process(void) +{ + if(freqArray[frequency].frequency1 <= MAX_LD_FREQ && Cur_Mode != BROADCAST) + { + LD_Flag ^= 1; + + if(LD_Flag) + Init_LD_Sync(); // Set up Second frequency + else + Init_LD_Sync(); // clear the second freq + } + +} + +void Leica_Patch(void) +{ + +//######################### + if(Read_Model_type() == LEICA) // Read Model Patches erroneous boards sent to Leica 8/2/24 + { + sprintf(tempString, "%d", hwf.mainPcbaPN); + + if(strncmp(tempString,"208021",6) == 0) // check for HW rev. + { + hwf.mainPcbaPN = 208025; + EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN);// Change to 208025 Assembly + + } + } +} +//######################## + +void Umag_Patch(void) +{ + char str1[4] = "10W"; + +//######################### + if(Read_Model_type() == UMAG) // Read Model Patches erroneous boards sent to Leica 8/2/24 + strncpy(sys.modelName,str1,4); + + // sys.modelName = "10W"; + // { + // sprintf(tempString, "%d", hwf.mainPcbaPN); + + // if(strncmp(tempString,"208021",6) == 0) // check for HW rev. + // { + // hwf.mainPcbaPN = 208025; + // EE_WriteUINT32(EE_HWFIX_MAIN_PCBA_PN, hwf.mainPcbaPN);// Change to 208025 Assembly + + // } + // } +} +//######################## + +//Power_Level = 0; +//if(freqArray[frequency].frequency1 < 44100) +// Dds_Pot_Val[1] = Pot_Value[Power_Level]; // data +//else +// Dds_Pot_Val[1] = Pot_Value_AB[Power_Level]; // data +// + diff --git a/source/utils.h b/source/utils.h new file mode 100644 index 0000000..a948106 --- /dev/null +++ b/source/utils.h @@ -0,0 +1,157 @@ +/* + * utils.h + * + * Created on: Jun 9, 2022 + * Author: Keith.Lloyd + */ + +#ifndef UTILS_H_ + +#define UTILS_H_ + + +#include "arm_math.h" +#include "spi.h" +//#define CLAMP 1 // Todo Fix later +#define DDC 2 +#define MAX_CLAMP_VOLTAGE 170.0f + +#define MAX_DC_VOLTAGE 90.0 +#define CLAMP_MIN 100 //Todo Calculate correct limit values +#define CLAMP_MAX 200 +#define DC_MIN 220 +#define DC_MAX 250 +#define DDC_MIN 270 +#define DDC_MAX 300 +#define TGT_NOT_USED 330 +#define OUT_RELAY_OFF_MASK 0b11100111 + +#define PORT1A_ON 0b00001000 +#define PORT1B_ON 0b00011000 +#define PORT2A_ON 0b00000000 +#define PORT2B_ON 0b00010000 +#define XFRMR_HF_ON 0b00000010 +#define HF_AMP_ON 0b01000000 + +#define PORT_LE 5 +#define ESTOP 17 +#define BYPASS_ON 0b00000001 // +#define HFDC_ON 0b00000010 +#define LFDC_ON 0b00000000 +#define LFANT_ON 0b00000100 +#define HFANT_ON 0b10000100 +#define PWR_CTL 16 +#define PWR_ON 1 +#define PWR_OFF 0 +//#define MAX_VOLTS 800 // RAW ADC VALUE for Maximum Voltage on DConnect output +#define MAX_OP_VOLTS 180 //220.0 //1.68 Maximum VOLTS +#define MAX_BYPASS_VOLTS 95.0//0.84 +#define MAX_BYPASS_VOLTS2 110.0 +#define MAX_CURRENT 950.0 // RAW ADC VALUE for Maximum Current on DConnect output +#define MAX_HF_CURRENT 300.0 +#define VOLTAGE 7 // ADC address of voltage measurement +#define CURRENT 0 // ADC address of current measurement +#define ALL_RELAYS_OFF_UPPER 0 //ToDo +#define ALL_RELAYS_OFF_LOWER 0 // Todo +#define POT_CS 7 // Todo +#define ERROR 8 // Bit position of ERROR Signal +#define DAMP_EN_ON 0b00100000 +#define SLCT_AMPD_ON 0b00000010 +#define AMP_PSU_ON 0b11111011 +#define XFRMR_LF_ON 0b00000010 // Bit position of Xfrmr Mux. +#define SLCT_XFMR XFRMR_LF_ON +#define SLCT_AMP 0b01000000 // Matches Correct Xfrmr to Correct amplifier. +#define MUX_AB_AMP 0b00000001 +#define ANT_AMP_EN 0b10000000 +#define ANT_AMP_SW 0b00000010 +#define BC_CLK 0 +#define DC_CLK 1 +#define I_GAIN 0b01000000 +#define SENTINAL 180 +#define MIN_POT 5 + +typedef enum { + EMPTY, + CLAMP, + CONNECT_LEAD, + DUAL_DC +}OUT_CONNECT_t; + +typedef enum{ + LFA_LFX, + HFA_LFX, + HFA_HFX +} AMP_XFRMR_SLCT_t; + + +typedef enum { + OFF, + ON +}RELAY_SELECT_t; + + +typedef struct ClampData_s +{ + float slope; + uint8_t pot; + float voltage; + float current; + float impedance; + float power; + float maxPower; + float targetPower; + uint32_t timeout; + bool regulate; + uint8_t prevPowerLevel; + +} ClampData_t; + + +void Select_Estop(RELAY_SELECT_t); +void Send_Pot_Data(uint16_t Data, SPI_MODE_t destination); +void Send_Update_Port(void); +void Clear_Relays(void); + +uint8_t Check_Output_Status(char Connector); +void Power_Down(void); +void Power_ON_OFF(RELAY_SELECT_t Power); +void Check_Over_Current(); +void Check_Live_Voltage(); +//void Check_Over_Voltage(); + +void Check_PSU_Short(void); +void Estop_Mode(void); +void Select_Transformer(void); +void Select_Amp_Xfrmr_Rly(AMP_XFRMR_SLCT_t Amp2xfrmr); +void Select_Bypass(RELAY_SELECT_t Bypass); // Bypass allows transmitting w/o full protection +void Chk_Gain(void); +void Check_Over_Power(void); +void Check_Clamp_OverVoltage(void); +void Adjust_Clamp_Volts(void); +bool Compare_Voltage(float32_t source,float32_t limit); +void Check_Over_Voltage(void); +void Controlled_Pwr_Dwn(void); +void Update_Amp_Pot(void); +void Check_For_Clamp_On_Pwr_Up(void); +void Adjust_Output_Power(float32_t New_Power_Limit); +float Get_Max_Current(void); +void Reduce_Kick_Back(void); +float32_t Convert_Pot2_Volts(uint8_t value); +void Cut_Signal_To_Min(void); +bool Check_For_Clamp(); +void freq_key_process(void); +void Init_LD_Sync(void); +void Leica_Patch(void); +void Umag_Patch(void); +float32_t Get_Power_Limit(void); +bool Check_For_Clamp_New(); + + +#endif /* UTILS_H_ */ + + + + + + + diff --git a/startup/boot_multicore_slave.c b/startup/boot_multicore_slave.c new file mode 100644 index 0000000..ddbb839 --- /dev/null +++ b/startup/boot_multicore_slave.c @@ -0,0 +1,128 @@ +//***************************************************************************** +// boot_multicore_slave.c +// +// Provides functions to allow booting of slave core in multicore system +// +// Version : 151217 +// +//***************************************************************************** +// +// Copyright 2014-2015, NXP +// All rights reserved. +// +// Software that is described herein is for illustrative purposes only +// which provides customers with programming information regarding the +// LPC products. This software is supplied "AS IS" without any warranties of +// any kind, and NXP Semiconductors and its licensor disclaim any and +// all warranties, express or implied, including all implied warranties of +// merchantability, fitness for a particular purpose and non-infringement of +// intellectual property rights. NXP Semiconductors assumes no responsibility +// or liability for the use of the software, conveys no license or rights under any +// patent, copyright, mask work right, or any other intellectual property rights in +// or to any products. NXP Semiconductors reserves the right to make changes +// in the software without notification. NXP Semiconductors also makes no +// representation or warranty that such application will be suitable for the +// specified use without further testing or modification. +// +// Permission to use, copy, modify, and distribute this software and its +// documentation is hereby granted, under NXP Semiconductors' and its +// licensor's relevant copyrights in the software, without fee, provided that it +// is used in conjunction with NXP Semiconductors microcontrollers. This +// copyright, permission, and disclaimer notice must appear in all copies of +// this code. +//***************************************************************************** +#if defined (__MULTICORE_MASTER_SLAVE_M0SLAVE) || \ + defined (__MULTICORE_MASTER_SLAVE_M4SLAVE) +#if defined (__USE_LPCOPEN) +#include "chip.h" +#else +#include +#define SYSCON_BASE ((uint32_t) 0x40000000) +#if defined (__LPC5410X__) +#define CPBOOT (((volatile uint32_t *) (SYSCON_BASE + 0x304))) +#define CPSTACK (((volatile uint32_t *) (SYSCON_BASE + 0x308))) +#define CPUCTRL (((volatile uint32_t *) (SYSCON_BASE + 0x300))) +#elif defined (__LPC5411X__) +#define CPBOOT (((volatile uint32_t *) (SYSCON_BASE + 0x804))) +#define CPSTACK (((volatile uint32_t *) (SYSCON_BASE + 0x808))) +#define CPUCTRL (((volatile uint32_t *) (SYSCON_BASE + 0x800))) +#else +#error Unrecognised MCU - cannot resolve Dual-CPU related registers +#endif +#define CPUCTRL_KEY ((uint32_t)(0x0000C0C4 << 16)) +#define CM4_CLK_ENA (1<<2) +#define CM0_CLK_ENA (1<<3) +#define CM4_RESET_ENA (1<<4) +#define CM0_RESET_ENA (1<<5) +#define CM4_SLEEPCON (1<<6) + +#if defined (CORE_M4) +void Chip_CPU_CM0Boot(uint32_t *coentry, uint32_t *costackptr) +{ + volatile uint32_t *u32REG, u32Val; + + *CPSTACK = (uint32_t) costackptr; + *CPBOOT = (uint32_t) coentry; + + u32REG = (uint32_t *) CPUCTRL; + u32Val = *u32REG; + + // Enable slave clock and reset + u32Val |= (CPUCTRL_KEY | ((CM0_CLK_ENA | CM0_RESET_ENA) & 0x7F)); + *u32REG = u32Val; + + // Clear slave reset + u32Val &= ~CM0_RESET_ENA; + *u32REG = u32Val; + +} +#else // !defined CORE_M4 +void Chip_CPU_CM4Boot(uint32_t *coentry, uint32_t *costackptr) +{ + volatile uint32_t *u32REG, u32Val; + + *CPSTACK = (uint32_t) costackptr; + *CPBOOT = (uint32_t) coentry; + + u32REG = (uint32_t *) CPUCTRL; + u32Val = *u32REG; + + // Enable slave clock and reset + u32Val |= (CPUCTRL_KEY | ((CM4_CLK_ENA | CM4_RESET_ENA) & 0x7F)); + *u32REG = u32Val; + + // Clear slave reset + u32Val &= ~CM0_RESET_ENA; + *u32REG = u32Val; +} +#endif // defined CORE_M4 +#endif // __USE_LPCOPEN + +#if defined (CORE_M4) +extern uint8_t __core_m0slave_START__; +#else +extern uint8_t __core_m4slave_START__; +#endif + +void boot_multicore_slave(void) { + +#if defined (CORE_M4) + unsigned int *slavevectortable_ptr = (unsigned int *)&__core_m0slave_START__; +#else + unsigned int *slavevectortable_ptr = (unsigned int *)&__core_m4slave_START__; +#endif + + volatile unsigned int resetaddr; + volatile unsigned int spaddr; + spaddr = *slavevectortable_ptr; + resetaddr = *(slavevectortable_ptr+1); + +#if defined (CORE_M4) + Chip_CPU_CM0Boot((uint32_t *)resetaddr, (uint32_t *)spaddr); +#else + Chip_CPU_CM4Boot((uint32_t *)resetaddr, (uint32_t *)spaddr); +#endif +} +#endif // defined (__MULTICORE_MASTER_SLAVE_M0SLAVE) || + // (__MULTICORE_MASTER_SLAVE_M4SLAVE) + diff --git a/startup/boot_multicore_slave.h b/startup/boot_multicore_slave.h new file mode 100644 index 0000000..2e1f976 --- /dev/null +++ b/startup/boot_multicore_slave.h @@ -0,0 +1,46 @@ +//***************************************************************************** +// boot_multicore_slave.h +// +// Header for functions used for booting of slave core in multicore system +//***************************************************************************** +// +// Copyright 2014, NXP +// All rights reserved. +// +// Software that is described herein is for illustrative purposes only +// which provides customers with programming information regarding the +// LPC products. This software is supplied "AS IS" without any warranties of +// any kind, and NXP Semiconductors and its licensor disclaim any and +// all warranties, express or implied, including all implied warranties of +// merchantability, fitness for a particular purpose and non-infringement of +// intellectual property rights. NXP Semiconductors assumes no responsibility +// or liability for the use of the software, conveys no license or rights under any +// patent, copyright, mask work right, or any other intellectual property rights in +// or to any products. NXP Semiconductors reserves the right to make changes +// in the software without notification. NXP Semiconductors also makes no +// representation or warranty that such application will be suitable for the +// specified use without further testing or modification. +// +// Permission to use, copy, modify, and distribute this software and its +// documentation is hereby granted, under NXP Semiconductors' and its +// licensor's relevant copyrights in the software, without fee, provided that it +// is used in conjunction with NXP Semiconductors microcontrollers. This +// copyright, permission, and disclaimer notice must appear in all copies of +// this code. +//***************************************************************************** + +#ifndef BOOT_MULTICORE_SLAVE_H_ +#define BOOT_MULTICORE_SLAVE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +void boot_multicore_slave(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOOT_MULTICORE_SLAVE_H_ */ diff --git a/startup/startup_lpc5411x.c b/startup/startup_lpc5411x.c new file mode 100644 index 0000000..fd9a72f --- /dev/null +++ b/startup/startup_lpc5411x.c @@ -0,0 +1,772 @@ +//***************************************************************************** +// LPC5411x startup code for use with MCUXpresso IDE +// +// Version : 161214 +//***************************************************************************** +// +// Copyright 2016, NXP +// All rights reserved. +// +// Software that is described herein is for illustrative purposes only +// which provides customers with programming information regarding the +// LPC products. This software is supplied "AS IS" without any warranties of +// any kind, and NXP Semiconductors and its licensor disclaim any and +// all warranties, express or implied, including all implied warranties of +// merchantability, fitness for a particular purpose and non-infringement of +// intellectual property rights. NXP Semiconductors assumes no responsibility +// or liability for the use of the software, conveys no license or rights under any +// patent, copyright, mask work right, or any other intellectual property rights in +// or to any products. NXP Semiconductors reserves the right to make changes +// in the software without notification. NXP Semiconductors also makes no +// representation or warranty that such application will be suitable for the +// specified use without further testing or modification. +// +// Permission to use, copy, modify, and distribute this software and its +// documentation is hereby granted, under NXP Semiconductors' and its +// licensor's relevant copyrights in the software, without fee, provided that it +// is used in conjunction with NXP Semiconductors microcontrollers. This +// copyright, permission, and disclaimer notice must appear in all copies of +// this code. +//***************************************************************************** + +#if defined (DEBUG) +#pragma GCC push_options +#pragma GCC optimize ("Og") +#endif // (DEBUG) + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define WEAK_AV __attribute__ ((weak, section(".after_vectors"))) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +// Variable to store CRP value in. Will be placed automatically +// by the linker when "Enable Code Read Protect" selected. +// See crp.h header for more information +//***************************************************************************** +#if !defined (CORE_M0PLUS) +#include +__CRP const unsigned int CRP_WORD = CRP_NO_CRP ; +#endif + +//***************************************************************************** +// Declaration of external SystemInit function +//***************************************************************************** +#if defined (__USE_CMSIS) +extern void SystemInit(void); +#endif // (__USE_CMSIS) + +//***************************************************************************** +#if !defined (DONT_ENABLE_SWVTRACECLK) && !defined (CORE_M0PLUS) +// Allow confirmation that SWV trace has been enabled +unsigned int __SWVtrace_Enabled; +#endif + +//***************************************************************************** +// Forward declaration of the core exception handlers. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +//***************************************************************************** + void ResetISR(void); +#if defined (__MULTICORE_MASTER) +void ResetISR2(void); +#endif +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// Forward declaration of the application IRQ handlers. When the application +// defines a handler (with the same name), this will automatically take +// precedence over weak definitions below +//***************************************************************************** +// External Interrupts - Available on M0+/M4 +WEAK void WDT_BOD_IRQHandler(void); +WEAK void DMA0_IRQHandler(void); +WEAK void GINT0_IRQHandler(void); +WEAK void GINT1_IRQHandler(void); +WEAK void PIN_INT0_IRQHandler(void); +WEAK void PIN_INT1_IRQHandler(void); +WEAK void PIN_INT2_IRQHandler(void); +WEAK void PIN_INT3_IRQHandler(void); +WEAK void UTICK0_IRQHandler(void); +WEAK void MRT0_IRQHandler(void); +WEAK void CTIMER0_IRQHandler(void); +WEAK void CTIMER1_IRQHandler(void); +WEAK void SCT0_IRQHandler(void); +WEAK void CTIMER3_IRQHandler(void); +WEAK void FLEXCOMM0_IRQHandler(void); +WEAK void FLEXCOMM1_IRQHandler(void); +WEAK void FLEXCOMM2_IRQHandler(void); +WEAK void FLEXCOMM3_IRQHandler(void); +WEAK void FLEXCOMM4_IRQHandler(void); +WEAK void FLEXCOMM5_IRQHandler(void); +WEAK void FLEXCOMM6_IRQHandler(void); +WEAK void FLEXCOMM7_IRQHandler(void); +WEAK void ADC0_SEQA_IRQHandler(void); +WEAK void ADC0_SEQB_IRQHandler(void); +WEAK void ADC0_THCMP_IRQHandler(void); +WEAK void DMIC0_IRQHandler(void); +WEAK void HWVAD0_IRQHandler(void); +WEAK void USB0_NEEDCLK_IRQHandler(void); +WEAK void USB0_IRQHandler(void); +WEAK void RTC_IRQHandler(void); +WEAK void IOH_IRQHandler(void); +WEAK void MAILBOX_IRQHandler(void); +// External Interrupts - For M4 only +#if defined (CORE_M4) +WEAK void PIN_INT4_IRQHandler(void); +WEAK void PIN_INT5_IRQHandler(void); +WEAK void PIN_INT6_IRQHandler(void); +WEAK void PIN_INT7_IRQHandler(void); +WEAK void CTIMER2_IRQHandler(void); +WEAK void CTIMER4_IRQHandler(void); +WEAK void Reserved54_IRQHandler(void); +WEAK void SPIFI0_IRQHandler(void); +#endif + +//***************************************************************************** +// Forward declaration of the driver IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the driver +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +//***************************************************************************** +// External Interrupts - Available on M0+/M4 +void WDT_BOD_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void GINT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UTICK0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void MRT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM4_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM5_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM6_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FLEXCOMM7_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQA_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQB_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_THCMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMIC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void HWVAD0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USB0_NEEDCLK_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USB0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void IOH_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void MAILBOX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +// External Interrupts - For M4 only +#if defined (CORE_M4) +void PIN_INT4_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT5_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT6_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT7_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER4_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved54_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SPIFI0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +#endif + +//***************************************************************************** +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); + +//***************************************************************************** +// External declaration for the pointer to the stack top from the Linker Script +//***************************************************************************** +extern void _vStackTop(void); + +//***************************************************************************** +// +// External declaration for LPC MCU vector table checksum from Linker Script +// +//***************************************************************************** +WEAK extern void __valid_user_code_checksum(); + +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif + +//***************************************************************************** +// The vector table. +// This relies on the linker script to place at correct location in memory. +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +extern void * __Vectors __attribute__ ((alias ("g_pfnVectors"))); + +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { +#if defined (CORE_M4) + // Core Level - CM4 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + __valid_user_code_checksum, // LPC MCU Checksum + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler +#else + // Core Level - CM0plus + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + 0, // Reserved + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler +#endif + + // External Interrupts - Available on M0+/M4 + WDT_BOD_IRQHandler, // 16: Windowed watchdog timer / Brownout detect + DMA0_IRQHandler, // 17: DMA controller + GINT0_IRQHandler, // 18: GPIO group 0 + GINT1_IRQHandler, // 19: GPIO group 1 + PIN_INT0_IRQHandler, // 20: Pin interrupt 0 or pattern match engine slice 0 + PIN_INT1_IRQHandler, // 21: Pin interrupt 1or pattern match engine slice 1 + PIN_INT2_IRQHandler, // 22: Pin interrupt 2 or pattern match engine slice 2 + PIN_INT3_IRQHandler, // 23: Pin interrupt 3 or pattern match engine slice 3 + UTICK0_IRQHandler, // 24: Micro-tick Timer + MRT0_IRQHandler, // 25: Multi-rate timer + CTIMER0_IRQHandler, // 26: Standard counter/timer CTIMER0 + CTIMER1_IRQHandler, // 27: Standard counter/timer CTIMER1 + SCT0_IRQHandler, // 28: SCTimer/PWM + CTIMER3_IRQHandler, // 29: Standard counter/timer CTIMER3 + FLEXCOMM0_IRQHandler, // 30: Flexcomm Interface 0 (USART + FLEXCOMM1_IRQHandler, // 31: Flexcomm Interface 1 (USART + FLEXCOMM2_IRQHandler, // 32: Flexcomm Interface 2 (USART + FLEXCOMM3_IRQHandler, // 33: Flexcomm Interface 3 (USART + FLEXCOMM4_IRQHandler, // 34: Flexcomm Interface 4 (USART + FLEXCOMM5_IRQHandler, // 35: Flexcomm Interface 5 (USART + FLEXCOMM6_IRQHandler, // 36: Flexcomm Interface 6 (USART + FLEXCOMM7_IRQHandler, // 37: Flexcomm Interface 7 (USART + ADC0_SEQA_IRQHandler, // 38: ADC0 sequence A completion + ADC0_SEQB_IRQHandler, // 39: ADC0 sequence B completion + ADC0_THCMP_IRQHandler, // 40: ADC0 threshold compare and error + DMIC0_IRQHandler, // 41: Digital microphone and DMIC subsystem + HWVAD0_IRQHandler, // 42: Hardware Voice Activity Detector + USB0_NEEDCLK_IRQHandler, // 43: USB Activity Wake-up Interrupt + USB0_IRQHandler, // 44: USB device + RTC_IRQHandler, // 45: RTC alarm and wake-up interrupts + IOH_IRQHandler, // 46: IOH + MAILBOX_IRQHandler, // 47: Mailbox interrupt (present on selected devices) + // External Interrupts - For M4 only +#if defined (CORE_M4) + PIN_INT4_IRQHandler, // 48: Pin interrupt 4 or pattern match engine slice 4 int + PIN_INT5_IRQHandler, // 49: Pin interrupt 5 or pattern match engine slice 5 int + PIN_INT6_IRQHandler, // 50: Pin interrupt 6 or pattern match engine slice 6 int + PIN_INT7_IRQHandler, // 51: Pin interrupt 7 or pattern match engine slice 7 int + CTIMER2_IRQHandler, // 52: Standard counter/timer CTIMER2 + CTIMER4_IRQHandler, // 53: Standard counter/timer CTIMER4 + Reserved54_IRQHandler, // 54: Reserved interrupt + SPIFI0_IRQHandler, // 55: SPI flash interface +#endif + +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors.init_data"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors.init_bss"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** + +#if defined (__MULTICORE_MASTER) +//#define cpu_ctrl 0x40000800 +//#define coproc_boot 0x40000804 +//#define set coproc_stack 0x40000808 +__attribute__ ((naked, section(".after_vectors.reset"))) +void ResetISR(void) { + asm volatile( + ".set cpu_ctrl, 0x40000800\t\n" + ".set coproc_boot, 0x40000804\t\n" + ".set coproc_stack, 0x40000808\t\n" + "MOVS R5, #1\t\n" + "LDR R0, =0xE000ED00\t\n" + "LDR R1, [R0]\t\n" // READ CPUID register + "LDR R2,=0x410CC601\t\n" // CM0 R0p1 identifier + "EORS R1,R1,R2\t\n" // XOR to see if we are C0 + "LDR R3, =cpu_ctrl\t\n" // get address of CPU_CTRL + "LDR R1,[R3]\t\n" // read cpu_ctrl reg into R1 + "BEQ.N cm0_boot\t\n" + "cm4_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m4\t\n" // if zero in boot reg, we just branch to real reset + "BX R0\t\n" // otherwise, we branch to boot address + "commonboot:\t\n" + "LDR R0, =ResetISR2\t\n" // Jump to 'real' reset handler + "BX R0\t\n" + "cm0_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m0\t\n" // if zero in boot reg, we just branch to real reset + "LDR R1,=coproc_stack\t\n" // pickup coprocesor stackpointer (from syscon CPSTACK) + "LDR R1,[R1]\t\n" + "MOV SP,R1\t\n" + "BX R0\t\n" // goto boot address + "check_master_m0:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BEQ.N commonboot\t\n" // if we get 0, that means we are masters + "B.N goto_sleep_pending_reset\t\n" // Otherwise, there is no startup vector for slave, so we go to sleep + "check_master_m4:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BNE.N commonboot\t\n" // if we get 1, that means we are masters + "goto_sleep_pending_reset:\t\n" + "MOV SP,R5\t\n" // load 0x1 into SP so that any stacking (eg on NMI) will not cause us to wakeup + // and write to uninitialised Stack area (instead it will LOCK us up before we cause damage) + // this code should only be reached if debugger bypassed ROM or we changed master without giving + // correct start address, the only way out of this is through a debugger change of SP and PC + "sleepo:\t\n" + "WFI\t\n" // go to sleep + "B.N sleepo\t\n" + ); +} + +void ResetISR2(void) { + +#else +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR(void) { +#endif + + // Disable interrupts + __asm volatile ("cpsid i"); + + // If this is not the CM0+ core... +#if !defined (CORE_M0PLUS) + // If this is not a slave project... +#if !defined (__MULTICORE_M0SLAVE) + // Optionally enable RAM banks that may be off by default at reset +#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) + volatile unsigned int *SYSCON_AHBCLKCTRLSET0 = (unsigned int *) 0x40000220; + // Ensure that SRAM2(4) in SYSAHBCLKCTRL0 set + *SYSCON_AHBCLKCTRLSET0 = (1 << 4); +#endif +#endif +#endif + +#if defined (__USE_CMSIS) +// If __USE_CMSIS defined, then call CMSIS SystemInit code + SystemInit(); +#endif // (__USE_CMSIS) + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + + // Optionally enable Cortex-M4 SWV trace (off by default at reset) + // Note - your board support must also set up pinmuxing such that + // SWO is output on GPIO PIO0-15 (FUNC2) or PIO1_1 (FUNC2). +#if !defined (DONT_ENABLE_SWVTRACECLK) && !defined (CORE_M0PLUS) + volatile unsigned int *TRACECLKDIV = (unsigned int *) 0x40000304; + volatile unsigned int *SYSAHBCLKCTRLSET = (unsigned int *) 0x40000220; + volatile unsigned int *SYSAHBCLKCTRL = (unsigned int *) 0x40000200; + // Write 0x00000000 to TRACECLKDIV - Trace divider + *TRACECLKDIV = 0; + // Enable IOCON peripheral clock (for SWO on PIO0-15 or PIO1_1) + // by setting bit13 via SYSAHBCLKCTRLSET[0] + *SYSAHBCLKCTRLSET = 1 << 13; // 0x2000 + // Read SYSAHBCLKCTRL[0] and check bit 13 + __SWVtrace_Enabled = ((*SYSAHBCLKCTRL & 1 << 13) == 1 << 13); +#endif + +#if !defined (__USE_CMSIS) +// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code +// will enable the FPU +#if defined (__VFP_FP__) && !defined (__SOFTFP__) + // + // Code to enable the Cortex-M4 FPU only included + // if appropriate build options have been selected. + // Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) + // + // Read CPACR (located at address 0xE000ED88) + // Set bits 20-23 to enable CP10 and CP11 coprocessors + // Write back the modified value to the CPACR + asm volatile ("LDR.W R0, =0xE000ED88\n\t" + "LDR R1, [R0]\n\t" + "ORR R1, R1, #(0xF << 20)\n\t" + "STR R1, [R0]"); +#endif // (__VFP_FP__) && !(__SOFTFP__) +#endif // (__USE_CMSIS) + +#if !defined (__USE_CMSIS) +// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code +// will setup the VTOR register + + // Check to see if we are running the code from a non-zero + // address (eg RAM, external flash), in which case we need + // to modify the VTOR register to tell the CPU that the + // vector table is located at a non-0x0 address. + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) { + *pSCB_VTOR = (unsigned int)g_pfnVectors; + } +#endif // (__USE_CMSIS) + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + + // Reenable interrupts + __asm volatile ("cpsie i"); + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main() ; +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default core exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +WEAK_AV void NMI_Handler(void) +{ while(1) {} +} + +WEAK_AV void HardFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void SVC_Handler(void) +{ while(1) {} +} + +WEAK_AV void PendSV_Handler(void) +{ while(1) {} +} + +WEAK_AV void SysTick_Handler(void) +{ while(1) {} +} + +// Core Level Interrupts - For M4 only +#if defined (CORE_M4) +WEAK_AV void MemManage_Handler(void) +{ while(1) {} +} + +WEAK_AV void BusFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void UsageFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void DebugMon_Handler(void) +{ while(1) {} +} +#endif // External Interrupts - For M4 only + +//***************************************************************************** +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +//***************************************************************************** +WEAK_AV void IntDefaultHandler(void) +{ while(1) {} +} + +//***************************************************************************** +// Default application exception handlers. Override the ones here by defining +// your own handler routines in your application code. These routines call +// driver exception handlers or IntDefaultHandler() if no driver exception +// handler is included. +//***************************************************************************** +WEAK void WDT_BOD_IRQHandler(void) +{ WDT_BOD_DriverIRQHandler(); +} + +WEAK void DMA0_IRQHandler(void) +{ DMA0_DriverIRQHandler(); +} + +WEAK void GINT0_IRQHandler(void) +{ GINT0_DriverIRQHandler(); +} + +WEAK void GINT1_IRQHandler(void) +{ GINT1_DriverIRQHandler(); +} + +WEAK void PIN_INT0_IRQHandler(void) +{ PIN_INT0_DriverIRQHandler(); +} + +WEAK void PIN_INT1_IRQHandler(void) +{ PIN_INT1_DriverIRQHandler(); +} + +WEAK void PIN_INT2_IRQHandler(void) +{ PIN_INT2_DriverIRQHandler(); +} + +WEAK void PIN_INT3_IRQHandler(void) +{ PIN_INT3_DriverIRQHandler(); +} + +WEAK void UTICK0_IRQHandler(void) +{ UTICK0_DriverIRQHandler(); +} + +WEAK void MRT0_IRQHandler(void) +{ MRT0_DriverIRQHandler(); +} + +WEAK void CTIMER0_IRQHandler(void) +{ CTIMER0_DriverIRQHandler(); +} + +WEAK void CTIMER1_IRQHandler(void) +{ CTIMER1_DriverIRQHandler(); +} + +WEAK void SCT0_IRQHandler(void) +{ SCT0_DriverIRQHandler(); +} + +WEAK void CTIMER3_IRQHandler(void) +{ CTIMER3_DriverIRQHandler(); +} + +WEAK void FLEXCOMM0_IRQHandler(void) +{ FLEXCOMM0_DriverIRQHandler(); +} + +WEAK void FLEXCOMM1_IRQHandler(void) +{ FLEXCOMM1_DriverIRQHandler(); +} + +WEAK void FLEXCOMM2_IRQHandler(void) +{ FLEXCOMM2_DriverIRQHandler(); +} + +WEAK void FLEXCOMM3_IRQHandler(void) +{ FLEXCOMM3_DriverIRQHandler(); +} + +WEAK void FLEXCOMM4_IRQHandler(void) +{ FLEXCOMM4_DriverIRQHandler(); +} + +WEAK void FLEXCOMM5_IRQHandler(void) +{ FLEXCOMM5_DriverIRQHandler(); +} + +WEAK void FLEXCOMM6_IRQHandler(void) +{ FLEXCOMM6_DriverIRQHandler(); +} + +WEAK void FLEXCOMM7_IRQHandler(void) +{ FLEXCOMM7_DriverIRQHandler(); +} + +WEAK void ADC0_SEQA_IRQHandler(void) +{ ADC0_SEQA_DriverIRQHandler(); +} + +WEAK void ADC0_SEQB_IRQHandler(void) +{ ADC0_SEQB_DriverIRQHandler(); +} + +WEAK void ADC0_THCMP_IRQHandler(void) +{ ADC0_THCMP_DriverIRQHandler(); +} + +WEAK void DMIC0_IRQHandler(void) +{ DMIC0_DriverIRQHandler(); +} + +WEAK void HWVAD0_IRQHandler(void) +{ HWVAD0_DriverIRQHandler(); +} + +WEAK void USB0_NEEDCLK_IRQHandler(void) +{ USB0_NEEDCLK_DriverIRQHandler(); +} + +WEAK void USB0_IRQHandler(void) +{ USB0_DriverIRQHandler(); +} + +WEAK void RTC_IRQHandler(void) +{ RTC_DriverIRQHandler(); +} + +WEAK void IOH_IRQHandler(void) +{ IOH_DriverIRQHandler(); +} + +WEAK void MAILBOX_IRQHandler(void) +{ MAILBOX_DriverIRQHandler(); +} + +// External Interrupts - For M4 only +#if defined (CORE_M4) +WEAK void PIN_INT4_IRQHandler(void) +{ PIN_INT4_DriverIRQHandler(); +} + +WEAK void PIN_INT5_IRQHandler(void) +{ PIN_INT5_DriverIRQHandler(); +} + +WEAK void PIN_INT6_IRQHandler(void) +{ PIN_INT6_DriverIRQHandler(); +} + +WEAK void PIN_INT7_IRQHandler(void) +{ PIN_INT7_DriverIRQHandler(); +} + +WEAK void CTIMER2_IRQHandler(void) +{ CTIMER2_DriverIRQHandler(); +} + +WEAK void CTIMER4_IRQHandler(void) +{ CTIMER4_DriverIRQHandler(); +} + +WEAK void Reserved54_IRQHandler(void) +{ Reserved54_DriverIRQHandler(); +} + +WEAK void SPIFI0_IRQHandler(void) +{ SPIFI0_DriverIRQHandler(); +} +#endif // External Interrupts - For M4 only + +//***************************************************************************** + +#if defined (DEBUG) +#pragma GCC pop_options +#endif // (DEBUG) diff --git a/usb/device/class/cdc/usb_device_cdc_acm.c b/usb/device/class/cdc/usb_device_cdc_acm.c new file mode 100644 index 0000000..f9f22ce --- /dev/null +++ b/usb/device/class/cdc/usb_device_cdc_acm.c @@ -0,0 +1,878 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016, 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if USB_DEVICE_CONFIG_CDC_ACM +#include "usb_device_cdc_acm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define USB_CDC_ACM_ENTER_CRITICAL() \ + OSA_SR_ALLOC(); \ + OSA_ENTER_CRITICAL() + +#define USB_CDC_ACM_EXIT_CRITICAL() OSA_EXIT_CRITICAL() + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* CDC ACM device instance */ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_cdc_acm_struct_t + g_cdcAcmHandle[USB_DEVICE_CONFIG_CDC_ACM]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocates the CDC ACM device handle. + * + * This function allocates the CDC ACM device handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmAllocateHandle(usb_device_cdc_acm_struct_t **handle) +{ + uint32_t count; + for (count = 0; count < (uint32_t)USB_DEVICE_CONFIG_CDC_ACM; count++) + { + if (NULL == g_cdcAcmHandle[count].handle) + { + *handle = &g_cdcAcmHandle[count]; + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +/*! + * @brief Frees the CDC ACM device handle. + * + * This function frees the CDC ACM device handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmFreeHandle(usb_device_cdc_acm_struct_t *handle) +{ + handle->handle = NULL; + handle->configStruct = NULL; + handle->configuration = 0; + handle->alternate = 0; + return kStatus_USB_Success; +} + +/*! + * @brief Responds to the interrupt in endpoint event. + * + * This function responds to the interrupt in endpoint event. + * + * @param handle The device handle of the CDC ACM device. + * @param message The pointer to the message of the endpoint callback. + * @param callbackParam The pointer to the parameter of the callback. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam; + if (NULL == cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle->interruptIn.isBusy = 0U; + + if ((NULL != cdcAcmHandle->configStruct) && (NULL != cdcAcmHandle->configStruct->classCallback)) + { + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSerialStateNotif, message); + } + return error; +} + +/*! + * @brief Responds to the bulk in endpoint event. + * + * This function responds to the bulk in endpoint event. + * + * @param handle The device handle of the CDC ACM device. + * @param message The pointer to the message of the endpoint callback. + * @param callbackParam The pointer to the parameter of the callback. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t status = kStatus_USB_Error; + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam; + + if (NULL == cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle->bulkIn.isBusy = 0; + + if ((NULL != cdcAcmHandle->configStruct) && (NULL != cdcAcmHandle->configStruct->classCallback)) + { + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSendResponse, message); + } + return status; +} + +/*! + * @brief Responds to the bulk out endpoint event. + * + * This function responds to the bulk out endpoint event. + * + * @param handle The device handle of the CDC ACM device. + * @param message The pointer to the message of the endpoint callback. + * @param callbackParam The pointer to the parameter of the callback. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t status = kStatus_USB_Error; + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam; + + if (NULL == cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle->bulkOut.isBusy = 0U; + + if ((NULL != cdcAcmHandle->configStruct) && (NULL != cdcAcmHandle->configStruct->classCallback)) + { + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventRecvResponse, message); + } + return status; +} + +/*! + * @brief Initializes the endpoints in CDC ACM class. + * + * This function initializes the endpoints in CDC ACM class. + * + * @param cdcAcmHandle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmEndpointsInit(usb_device_cdc_acm_struct_t *cdcAcmHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = NULL; + usb_status_t error = kStatus_USB_Error; + uint32_t count; + uint32_t index; + + if (NULL == cdcAcmHandle) + { + return error; + } + + /* return error when configuration is invalid (0 or more than the configuration number) */ + if ((cdcAcmHandle->configuration == 0U) || + (cdcAcmHandle->configuration > cdcAcmHandle->configStruct->classInfomation->configurations)) + { + return error; + } + + interfaceList = &cdcAcmHandle->configStruct->classInfomation->interfaceList[cdcAcmHandle->configuration - 1U]; + + for (count = 0; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == cdcAcmHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + cdcAcmHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (NULL == interface) + { + return error; + } + cdcAcmHandle->commInterfaceHandle = interface; + for (count = 0; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) && + (USB_ENDPOINT_INTERRUPT == epInitStruct.transferType)) + { + cdcAcmHandle->interruptIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + cdcAcmHandle->interruptIn.isBusy = 0; + cdcAcmHandle->interruptIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER; + cdcAcmHandle->interruptIn.pipeStall = 0U; + cdcAcmHandle->interruptIn.pipeDataLen = 0U; + epCallback.callbackFn = USB_DeviceCdcAcmInterruptIn; + } + + epCallback.callbackParam = cdcAcmHandle; + + error = USB_DeviceInitEndpoint(cdcAcmHandle->handle, &epInitStruct, &epCallback); + if (kStatus_USB_Success != error) + { + return error; + } + } + + for (count = 0; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == cdcAcmHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + break; + } + } + + cdcAcmHandle->dataInterfaceHandle = interface; + + for (count = 0; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) && + (USB_ENDPOINT_BULK == epInitStruct.transferType)) + { + cdcAcmHandle->bulkIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + cdcAcmHandle->bulkIn.isBusy = 0; + cdcAcmHandle->bulkIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER; + cdcAcmHandle->bulkIn.pipeStall = 0U; + cdcAcmHandle->bulkIn.pipeDataLen = 0U; + epCallback.callbackFn = USB_DeviceCdcAcmBulkIn; + } + else if ((USB_OUT == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) && + (USB_ENDPOINT_BULK == epInitStruct.transferType)) + { + cdcAcmHandle->bulkOut.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + cdcAcmHandle->bulkOut.isBusy = 0; + cdcAcmHandle->bulkOut.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER; + cdcAcmHandle->bulkOut.pipeStall = 0U; + cdcAcmHandle->bulkOut.pipeDataLen = 0U; + epCallback.callbackFn = USB_DeviceCdcAcmBulkOut; + } + else + { + /*no action*/ + } + epCallback.callbackParam = cdcAcmHandle; + + error = USB_DeviceInitEndpoint(cdcAcmHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initializes the endpoints in CDC ACM class. + * + * This function de-initializes the endpoints in CDC ACM class. + * + * @param cdcAcmHandle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmEndpointsDeinit(usb_device_cdc_acm_struct_t *cdcAcmHandle) +{ + usb_status_t status = kStatus_USB_Error; + uint32_t count; + + if ((NULL == cdcAcmHandle->commInterfaceHandle) || (NULL == cdcAcmHandle->dataInterfaceHandle)) + { + return status; + } + for (count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++) + { + status = USB_DeviceDeinitEndpoint( + cdcAcmHandle->handle, cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + for (count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++) + { + status = USB_DeviceDeinitEndpoint( + cdcAcmHandle->handle, cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + cdcAcmHandle->commInterfaceHandle = NULL; + cdcAcmHandle->dataInterfaceHandle = NULL; + + return status; +} + +/*! + * @brief Handles the CDC ACM class event. + * + * This function responses to various events including the common device events and the class specific events. + * For class specific events, it calls the class callback defined in the application to deal with the class specific + * event. + * + * @param handle The class handle of the CDC ACM class. + * @param event The event type. + * @param param The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmEvent(void *handle, uint32_t event, void *param) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_device_cdc_acm_request_param_struct_t reqParam; + usb_status_t error = kStatus_USB_Error; + uint32_t count; + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + usb_device_class_event_t eventCode = (usb_device_class_event_t)event; + if ((NULL == param) || (NULL == handle)) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + switch (eventCode) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + cdcAcmHandle->configuration = 0; + break; + case kUSB_DeviceClassEventSetConfiguration: + temp8 = ((uint8_t *)param); + if (NULL == cdcAcmHandle->configStruct) + { + break; + } + if (*temp8 == cdcAcmHandle->configuration) + { + break; + } + + error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle); + cdcAcmHandle->configuration = *temp8; + cdcAcmHandle->alternate = 0U; + error = USB_DeviceCdcAcmEndpointsInit(cdcAcmHandle); + if (kStatus_USB_Success != error) + { +#ifdef DEBUG + (void)usb_echo("kUSB_DeviceClassEventSetConfiguration, USB_DeviceInitEndpoint fail\r\n"); +#endif + } + break; + case kUSB_DeviceClassEventSetInterface: + if (NULL == cdcAcmHandle->configStruct) + { + break; + } + + interfaceAlternate = *((uint16_t *)param); + alternate = (uint8_t)(interfaceAlternate & 0xFFU); + + if (cdcAcmHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8U))) + { + break; + } + if (alternate == cdcAcmHandle->alternate) + { + break; + } + error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle); + cdcAcmHandle->alternate = alternate; + error = USB_DeviceCdcAcmEndpointsInit(cdcAcmHandle); + if (kStatus_USB_Success != error) + { +#ifdef DEBUG + (void)usb_echo("kUSB_DeviceClassEventSetInterface, USB_DeviceInitEndpoint fail\r\n"); +#endif + } + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if ((NULL == cdcAcmHandle->configStruct) || (NULL == cdcAcmHandle->commInterfaceHandle) || + (NULL == cdcAcmHandle->dataInterfaceHandle)) + { + break; + } + temp8 = ((uint8_t *)param); + for (count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + cdcAcmHandle->interruptIn.pipeStall = 1U; + error = USB_DeviceStallEndpoint(cdcAcmHandle->handle, *temp8); + } + } + for (count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + cdcAcmHandle->bulkIn.pipeStall = 1U; + } + else + { + cdcAcmHandle->bulkOut.pipeStall = 1U; + } + error = USB_DeviceStallEndpoint(cdcAcmHandle->handle, *temp8); + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if ((NULL == cdcAcmHandle->configStruct) || (NULL == cdcAcmHandle->commInterfaceHandle) || + (NULL == cdcAcmHandle->dataInterfaceHandle)) + { + break; + } + temp8 = ((uint8_t *)param); + for (count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + error = USB_DeviceUnstallEndpoint(cdcAcmHandle->handle, *temp8); + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (0U != cdcAcmHandle->interruptIn.pipeStall) + { + cdcAcmHandle->interruptIn.pipeStall = 0U; + if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != cdcAcmHandle->interruptIn.pipeDataBuffer) + { + error = USB_DeviceSendRequest(cdcAcmHandle->handle, (cdcAcmHandle->interruptIn.ep), + cdcAcmHandle->interruptIn.pipeDataBuffer, + cdcAcmHandle->interruptIn.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = cdcAcmHandle->interruptIn.pipeDataBuffer; + endpointCallbackMessage.length = cdcAcmHandle->interruptIn.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + (void)USB_DeviceCdcAcmBulkIn(cdcAcmHandle->handle, (void *)&endpointCallbackMessage, + handle); + } + cdcAcmHandle->interruptIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER; + cdcAcmHandle->interruptIn.pipeDataLen = 0U; + } + } + } + } + } + for (count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + error = USB_DeviceUnstallEndpoint(cdcAcmHandle->handle, *temp8); + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (0U != cdcAcmHandle->bulkIn.pipeStall) + { + cdcAcmHandle->bulkIn.pipeStall = 0U; + if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != cdcAcmHandle->bulkIn.pipeDataBuffer) + { + error = USB_DeviceSendRequest(cdcAcmHandle->handle, (cdcAcmHandle->bulkIn.ep), + cdcAcmHandle->bulkIn.pipeDataBuffer, + cdcAcmHandle->bulkIn.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = cdcAcmHandle->bulkIn.pipeDataBuffer; + endpointCallbackMessage.length = cdcAcmHandle->bulkIn.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + (void)USB_DeviceCdcAcmBulkIn(cdcAcmHandle->handle, (void *)&endpointCallbackMessage, + handle); + } + cdcAcmHandle->bulkIn.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER; + cdcAcmHandle->bulkIn.pipeDataLen = 0U; + } + } + } + else + { + if (0U != cdcAcmHandle->bulkOut.pipeStall) + { + cdcAcmHandle->bulkOut.pipeStall = 0U; + if ((uint8_t *)USB_INVALID_TRANSFER_BUFFER != cdcAcmHandle->bulkOut.pipeDataBuffer) + { + error = USB_DeviceRecvRequest(cdcAcmHandle->handle, (cdcAcmHandle->bulkOut.ep), + cdcAcmHandle->bulkOut.pipeDataBuffer, + cdcAcmHandle->bulkOut.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = cdcAcmHandle->bulkOut.pipeDataBuffer; + endpointCallbackMessage.length = cdcAcmHandle->bulkOut.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + (void)USB_DeviceCdcAcmBulkOut(cdcAcmHandle->handle, + (void *)&endpointCallbackMessage, handle); + } + cdcAcmHandle->bulkOut.pipeDataBuffer = (uint8_t *)USB_INVALID_TRANSFER_BUFFER; + cdcAcmHandle->bulkOut.pipeDataLen = 0U; + } + } + } + } + } + break; + case kUSB_DeviceClassEventClassRequest: + + { + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + + if ((controlRequest->setup->wIndex & 0xFFU) != cdcAcmHandle->interfaceNumber) + { + break; + } + /* Standard CDC request */ + if (USB_REQUEST_TYPE_TYPE_CLASS == (controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK)) + { + reqParam.buffer = &(controlRequest->buffer); + reqParam.length = &(controlRequest->length); + reqParam.interfaceIndex = controlRequest->setup->wIndex; + reqParam.setupValue = controlRequest->setup->wValue; + reqParam.isSetup = controlRequest->isSetup; + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSendEncapsulatedCommand, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventGetEncapsulatedResponse, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSetCommFeature, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventGetCommFeature, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventClearCommFeature, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventGetLineCoding, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSetLineCoding, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSetControlLineState, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SEND_BREAK: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSendBreak, &reqParam); + break; + default: + error = kStatus_USB_InvalidRequest; + break; + } + } + } + break; + default: + /*no action*/ + break; + } + return error; +} + +/*! + * @brief Initializes the USB CDC ACM class. + * + * This function obtains a usb device handle according to the controller id, initializes the CDC ACM class + * with the class configure parameters and creates the mutex for each pipe. + * + * @param controllerId The id of the controller. The value can be choosen from kUSB_ControllerKhci0, + * kUSB_ControllerKhci1, kUSB_ControllerEhci0 or kUSB_ControllerEhci1. + * @param config The user configuration structure of type usb_device_class_config_struct_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @param handle It is out parameter. The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error; + + error = USB_DeviceCdcAcmAllocateHandle(&cdcAcmHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + error = USB_DeviceClassGetDeviceHandle(controllerId, &cdcAcmHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (NULL == cdcAcmHandle->handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle->configStruct = config; + cdcAcmHandle->configuration = 0; + cdcAcmHandle->alternate = 0xFF; + + cdcAcmHandle->bulkIn.mutex = (osa_mutex_handle_t)&cdcAcmHandle->bulkIn.mutexBuffer[0]; + if (KOSA_StatusSuccess != OSA_MutexCreate((cdcAcmHandle->bulkIn.mutex))) + { +#ifdef DEBUG + (void)usb_echo("mutex create error!"); +#endif + } + cdcAcmHandle->bulkOut.mutex = (osa_mutex_handle_t)&cdcAcmHandle->bulkOut.mutexBuffer[0]; + if (KOSA_StatusSuccess != OSA_MutexCreate((cdcAcmHandle->bulkOut.mutex))) + { +#ifdef DEBUG + (void)usb_echo("mutex create error!"); +#endif + } + cdcAcmHandle->interruptIn.mutex = (osa_mutex_handle_t)&cdcAcmHandle->interruptIn.mutexBuffer[0]; + if (KOSA_StatusSuccess != OSA_MutexCreate((cdcAcmHandle->interruptIn.mutex))) + { +#ifdef DEBUG + (void)usb_echo("mutex create error!"); +#endif + } + *handle = (class_handle_t)cdcAcmHandle; + return error; +} + +/*! + * @brief De-Initializes the USB CDC ACM class. + * + * This function destroys the mutex for each pipe, deinit each endpoint of the CDC ACM class and free + * the CDC ACM class handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmDeinit(class_handle_t handle) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error; + + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + if (NULL == cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + if (KOSA_StatusSuccess != OSA_MutexDestroy((cdcAcmHandle->bulkIn.mutex))) + { +#ifdef DEBUG + (void)usb_echo("mutex destroy error!"); +#endif + } + if (KOSA_StatusSuccess != OSA_MutexDestroy((cdcAcmHandle->bulkOut.mutex))) + { +#ifdef DEBUG + (void)usb_echo("mutex destroy error!"); +#endif + } + if (KOSA_StatusSuccess != OSA_MutexDestroy((cdcAcmHandle->interruptIn.mutex))) + { +#ifdef DEBUG + (void)usb_echo("mutex destroy error!"); +#endif + } + error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle); + (void)USB_DeviceCdcAcmFreeHandle(cdcAcmHandle); + return error; +} + +/*! + * @brief Prime the endpoint to send packet to host. + * + * This function checks whether the endpoint is sending packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t status = kStatus_USB_Error; + usb_device_cdc_acm_pipe_t *cdcAcmPipe = NULL; + + if (NULL == handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + if (cdcAcmHandle->bulkIn.ep == ep) + { + cdcAcmPipe = &(cdcAcmHandle->bulkIn); + } + else if (cdcAcmHandle->interruptIn.ep == ep) + { + cdcAcmPipe = &(cdcAcmHandle->interruptIn); + } + else + { + /*no action*/ + } + + if (NULL != cdcAcmPipe) + { + if (1U == cdcAcmPipe->isBusy) + { + return kStatus_USB_Busy; + } + cdcAcmPipe->isBusy = 1U; + + if (0u != cdcAcmPipe->pipeStall) + { + cdcAcmPipe->pipeDataBuffer = buffer; + cdcAcmPipe->pipeDataLen = length; + return kStatus_USB_Success; + } + + status = USB_DeviceSendRequest(cdcAcmHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != status) + { + cdcAcmPipe->isBusy = 0U; + } + } + return status; +} + +/*! + * @brief Prime the endpoint to receive packet from host. + * + * This function checks whether the endpoint is receiving packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t status; + if (NULL == handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + if (1U == cdcAcmHandle->bulkOut.isBusy) + { + return kStatus_USB_Busy; + } + cdcAcmHandle->bulkOut.isBusy = 1U; + + if (0U != cdcAcmHandle->bulkOut.pipeStall) + { + cdcAcmHandle->bulkOut.pipeDataBuffer = buffer; + cdcAcmHandle->bulkOut.pipeDataLen = length; + return kStatus_USB_Success; + } + + status = USB_DeviceRecvRequest(cdcAcmHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != status) + { + cdcAcmHandle->bulkOut.isBusy = 0U; + } + return status; +} + +#endif /* USB_DEVICE_CONFIG_CDC_ACM */ diff --git a/usb/device/class/cdc/usb_device_cdc_acm.h b/usb/device/class/cdc/usb_device_cdc_acm.h new file mode 100644 index 0000000..1577c80 --- /dev/null +++ b/usb/device/class/cdc/usb_device_cdc_acm.h @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016,2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _USB_DEVICE_CDC_ACM_H_ +#define _USB_DEVICE_CDC_ACM_H_ + +/*! + * @addtogroup cdc_acm + * @{ + */ + +/******************************************************************************* +* Definitions +******************************************************************************/ +#define USB_DEVICE_CONFIG_CDC_ACM_MAX_INSTANCE (1U) /*!< The maximum number of CDC device instance. */ +#define USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE (0x02U) /*!< The CDC communication class code. */ +#define USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE (0x0AU) /*!< The CDC data class code. */ + +#define USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND \ + (0x00) /*!< The CDC class request code for SEND_ENCAPSULATED_COMMAND. */ +#define USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE \ + (0x01) /*!< The CDC class request code for GET_ENCAPSULATED_RESPONSE. */ +#define USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE (0x02) /*!< The CDC class request code for SET_COMM_FEATURE. */ +#define USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE (0x03) /*!< The CDC class request code for GET_COMM_FEATURE. */ +#define USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE (0x04) /*!< The CDC class request code for CLEAR_COMM_FEATURE. */ +#define USB_DEVICE_CDC_REQUEST_SET_AUX_LINE_STATE (0x10) /*!< The CDC class request code for SET_AUX_LINE_STATE. */ +#define USB_DEVICE_CDC_REQUEST_SET_HOOK_STATE (0x11) /*!< The CDC class request code for SET_HOOK_STATE. */ +#define USB_DEVICE_CDC_REQUEST_PULSE_SETUP (0x12) /*!< The CDC class request code for PULSE_SETUP. */ +#define USB_DEVICE_CDC_REQUEST_SEND_PULSE (0x13) /*!< The CDC class request code for SEND_PULSE. */ +#define USB_DEVICE_CDC_REQUEST_SET_PULSE_TIME (0x14) /*!< The CDC class request code for SET_PULSE_TIME. */ +#define USB_DEVICE_CDC_REQUEST_RING_AUX_JACK (0x15) /*!< The CDC class request code for RING_AUX_JACK. */ +#define USB_DEVICE_CDC_REQUEST_SET_LINE_CODING (0x20) /*!< The CDC class request code for SET_LINE_CODING. */ +#define USB_DEVICE_CDC_REQUEST_GET_LINE_CODING (0x21) /*!< The CDC class request code for GET_LINE_CODING. */ +#define USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE \ + (0x22) /*!< The CDC class request code for SET_CONTROL_LINE_STATE. */ +#define USB_DEVICE_CDC_REQUEST_SEND_BREAK (0x23) /*!< The CDC class request code for SEND_BREAK. */ +#define USB_DEVICE_CDC_REQUEST_SET_RINGER_PARAMS (0x30) /*!< The CDC class request code for SET_RINGER_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_GET_RINGER_PARAMS (0x31) /*!< The CDC class request code for GET_RINGER_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_SET_OPERATION_PARAM (0x32) /*!< The CDC class request code for SET_OPERATION_PARAM. */ +#define USB_DEVICE_CDC_REQUEST_GET_OPERATION_PARAM (0x33) /*!< The CDC class request code for GET_OPERATION_PARAM. */ +#define USB_DEVICE_CDC_REQUEST_SET_LINE_PARAMS (0x34) /*!< The CDC class request code for SET_LINE_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_GET_LINE_PARAMS (0x35) /*!< The CDC class request code for GET_LINE_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_DIAL_DIGITS (0x36) /*!< The CDC class request code for DIAL_DIGITS. */ +#define USB_DEVICE_CDC_REQUEST_SET_UNIT_PARAMETER (0x37) /*!< The CDC class request code for SET_UNIT_PARAMETER. */ +#define USB_DEVICE_CDC_REQUEST_GET_UNIT_PARAMETER (0x38) /*!< The CDC class request code for GET_UNIT_PARAMETER. */ +#define USB_DEVICE_CDC_REQUEST_CLEAR_UNIT_PARAMETER \ + (0x39) /*!< The CDC class request code for CLEAR_UNIT_PARAMETER. */ +#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS \ + (0x40) /*!< The CDC class request code for SET_ETHERNET_MULTICAST_FILTERS. */ +#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_POW_PATTER_FILTER \ + (0x41) /*!< The CDC class request code for SET_ETHERNET_POW_PATTER_FILTER. */ +#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_POW_PATTER_FILTER \ + (0x42) /*!< The CDC class request code for GET_ETHERNET_POW_PATTER_FILTER. */ +#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_PACKET_FILTER \ + (0x43) /*!< The CDC class request code for SET_ETHERNET_PACKET_FILTER. */ +#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_STATISTIC \ + (0x44) /*!< The CDC class request code for GET_ETHERNET_STATISTIC. */ +#define USB_DEVICE_CDC_REQUEST_SET_ATM_DATA_FORMAT (0x50) /*!< The CDC class request code for SET_ATM_DATA_FORMAT. */ +#define USB_DEVICE_CDC_REQUEST_GET_ATM_DEVICE_STATISTICS \ + (0x51) /*!< The CDC class request code for GET_ATM_DEVICE_STATISTICS. */ +#define USB_DEVICE_CDC_REQUEST_SET_ATM_DEFAULT_VC (0x52) /*!< The CDC class request code for SET_ATM_DEFAULT_VC. */ +#define USB_DEVICE_CDC_REQUEST_GET_ATM_VC_STATISTICS \ + (0x53) /*!< The CDC class request code for GET_ATM_VC_STATISTICS. */ +#define USB_DEVICE_CDC_REQUEST_MDLM_SPECIFIC_REQUESTS_MASK \ + (0x7F) /*!< The CDC class request code for MDLM_SPECIFIC_REQUESTS_MASK. */ + +#define USB_DEVICE_CDC_NOTIF_NETWORK_CONNECTION (0x00) /*!< The CDC class notify code for NETWORK_CONNECTION. */ +#define USB_DEVICE_CDC_NOTIF_RESPONSE_AVAIL (0x01) /*!< The CDC class notify code for RESPONSE_AVAIL. */ +#define USB_DEVICE_CDC_NOTIF_AUX_JACK_HOOK_STATE (0x08) /*!< The CDC class notify code for AUX_JACK_HOOK_STATE. */ +#define USB_DEVICE_CDC_NOTIF_RING_DETECT (0x09) /*!< The CDC class notify code for RING_DETECT. */ +#define USB_DEVICE_CDC_NOTIF_SERIAL_STATE (0x20) /*!< The CDC class notify code for SERIAL_STATE. */ +#define USB_DEVICE_CDC_NOTIF_CALL_STATE_CHANGE (0x28) /*!< The CDC class notify code for CALL_STATE_CHANGE. */ +#define USB_DEVICE_CDC_NOTIF_LINE_STATE_CHANGE (0x29) /*!< The CDC class notify code for LINE_STATE_CHANGE. */ +#define USB_DEVICE_CDC_NOTIF_CONNECTION_SPEED_CHANGE \ + (0x2A) /*!< The CDC class notify code for CONNECTION_SPEED_CHANGE. */ + +#define USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE (0x01) /*!< The CDC class feature select code for ABSTRACT_STATE. */ +#define USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING (0x02) /*!< The CDC class feature select code for COUNTRY_SETTING. */ + +#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION \ + (0x02) /*!< The CDC class control signal bitmap value for CARRIER_ACTIVATION. */ +#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE \ + (0x01) /*!< The CDC class control signal bitmap value for DTE_PRESENCE. */ +#define USB_DEVICE_CDC_UART_STATE_RX_CARRIER (0x01) /*!< The UART state bitmap value of RX_CARRIER. */ +#define USB_DEVICE_CDC_UART_STATE_TX_CARRIER (0x02) /*!< The UART state bitmap value of TX_CARRIER. */ +#define USB_DEVICE_CDC_UART_STATE_BREAK (0x04) /*!< The UART state bitmap value of BREAK. */ +#define USB_DEVICE_CDC_UART_STATE_RING_SIGNAL (0x08) /*!< The UART state bitmap value of RING_SIGNAL. */ +#define USB_DEVICE_CDC_UART_STATE_FRAMING (0x10) /*!< The UART state bitmap value of FRAMING. */ +#define USB_DEVICE_CDC_UART_STATE_PARITY (0x20) /*!< The UART state bitmap value of PARITY. */ +#define USB_DEVICE_CDC_UART_STATE_OVERRUN (0x40) /*!< The UART state bitmap value of OVERRUN. */ + +/*! @brief Definition of CDC class event. */ +typedef enum _usb_device_cdc_acm_event +{ + kUSB_DeviceCdcEventSendResponse = 0x01, /*!< This event indicates the bulk send transfer is complete or cancelled etc. */ + kUSB_DeviceCdcEventRecvResponse, /*!< This event indicates the bulk receive transfer is complete or cancelled etc.. */ + kUSB_DeviceCdcEventSerialStateNotif, /*!< This event indicates the serial state has been sent to the host. */ + kUSB_DeviceCdcEventSendEncapsulatedCommand, /*!< This event indicates the device received the + SEND_ENCAPSULATED_COMMAND request. */ + kUSB_DeviceCdcEventGetEncapsulatedResponse, /*!< This event indicates the device received the + GET_ENCAPSULATED_RESPONSE request. */ + kUSB_DeviceCdcEventSetCommFeature, /*!< This event indicates the device received the SET_COMM_FEATURE request. */ + kUSB_DeviceCdcEventGetCommFeature, /*!< This event indicates the device received the GET_COMM_FEATURE request. */ + kUSB_DeviceCdcEventClearCommFeature, /*!< This event indicates the device received the CLEAR_COMM_FEATURE request. + */ + kUSB_DeviceCdcEventGetLineCoding, /*!< This event indicates the device received the GET_LINE_CODING request. */ + kUSB_DeviceCdcEventSetLineCoding, /*!< This event indicates the device received the SET_LINE_CODING request. */ + kUSB_DeviceCdcEventSetControlLineState, /*!< This event indicates the device received the SET_CONTRL_LINE_STATE + request. */ + kUSB_DeviceCdcEventSendBreak /*!< This event indicates the device received the SEND_BREAK request. */ +} usb_device_cdc_acm_event_t; + +/*! @brief Definition of parameters for CDC ACM request. */ +typedef struct _usb_device_cdc_acm_request_param_struct +{ + uint8_t **buffer; /*!< The pointer to the address of the buffer for CDC class request. */ + uint32_t *length; /*!< The pointer to the length of the buffer for CDC class request. */ + uint16_t interfaceIndex; /*!< The interface index of the setup packet. */ + uint16_t setupValue; /*!< The wValue field of the setup packet. */ + uint8_t isSetup; /*!< The flag indicates if it is a setup packet, 1: yes, 0: no. */ +} usb_device_cdc_acm_request_param_struct_t; + +/*! @brief Definition of pipe structure. */ +typedef struct _usb_device_cdc_acm_pipe +{ + osa_mutex_handle_t mutex; /*!< The mutex of the pipe. */ + uint32_t mutexBuffer[(OSA_MUTEX_HANDLE_SIZE + 3)/4]; + uint8_t *pipeDataBuffer; /*!< pipe data buffer backup when stall */ + uint32_t pipeDataLen; /*!< pipe data length backup when stall */ + uint8_t pipeStall; /*!< pipe is stall */ + uint8_t ep; /*!< The endpoint number of the pipe. */ + uint8_t isBusy; /*!< 1: The pipe is transferring packet, 0: The pipe is idle. */ +} usb_device_cdc_acm_pipe_t; + +/*! @brief Definition of structure for CDC ACM device. */ +typedef struct _usb_device_cdc_acm_struct +{ + usb_device_handle handle; /*!< The handle of the USB device. */ + usb_device_class_config_struct_t *configStruct; /*!< The class configure structure. */ + usb_device_interface_struct_t *commInterfaceHandle; /*!< The CDC communication interface handle. */ + usb_device_interface_struct_t *dataInterfaceHandle; /*!< The CDC data interface handle. */ + usb_device_cdc_acm_pipe_t bulkIn; /*!< The bulk in pipe for sending packet to host. */ + usb_device_cdc_acm_pipe_t bulkOut; /*!< The bulk out pipe for receiving packet from host. */ + usb_device_cdc_acm_pipe_t interruptIn; /*!< The interrupt in pipe for notifying the device state to host. */ + uint8_t configuration; /*!< The current configuration value. */ + uint8_t interfaceNumber; /*!< The current interface number. */ + uint8_t alternate; /*!< The alternate setting value of the interface. */ + uint8_t hasSentState; /*!< 1: The device has primed the state in interrupt pipe, 0: Not primed the state. */ +} usb_device_cdc_acm_struct_t; + +/******************************************************************************* +* API +******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB CDC ACM Class Driver + * @{ + */ +/*! + * @brief Initializes the USB CDC ACM class. + * + * This function obtains a USB device handle according to the controller ID, initializes the CDC ACM class + * with the class configure parameters and creates the mutex for each pipe. + * + * @param controllerId The ID of the controller. The value can be chosen from the kUSB_ControllerKhci0, + * kUSB_ControllerKhci1, kUSB_ControllerEhci0, or kUSB_ControllerEhci1. + * @param config The user configuration structure of type usb_device_class_config_struct_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @param handle It is out parameter. The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The CDC ACM class is initialized successfully. + * @retval kStatus_USB_Busy No CDC ACM device handle available for allocation. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle allocation failure. + * @retval kStatus_USB_InvalidParameter The USB device handle allocation failure. + */ +extern usb_status_t USB_DeviceCdcAcmInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); +/*! + * @brief Deinitializes the USB CDC ACM class. + * + * This function destroys the mutex for each pipe, deinitializes each endpoint of the CDC ACM class and frees + * the CDC ACM class handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The CDC ACM class is de-initialized successfully. + * @retval kStatus_USB_Error The endpoint deinitialization failure. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number of the CDC ACM class handle is invalid. + */ +extern usb_status_t USB_DeviceCdcAcmDeinit(class_handle_t handle); +/*! + * @brief Handles the CDC ACM class event. + * + * This function responds to various events including the common device events and the class-specific events. + * For class-specific events, it calls the class callback defined in the application to deal with the class-specific + * event. + * + * @param handle The class handle of the CDC ACM class. + * @param event The event type. + * @param param The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The CDC ACM class is de-initialized successfully. + * @retval kStatus_USB_Error The configure structure of the CDC ACM class handle is invalid. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number of the CDC ACM class handle is invalid. + * @retval Others The error code returned by class callback in application. + */ +extern usb_status_t USB_DeviceCdcAcmEvent(void *handle, uint32_t event, void *param); + +/*! + * @brief Primes the endpoint to send packet to host. + * + * This function checks whether the endpoint is sending packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prime to send packet successfully. + * @retval kStatus_USB_Busy The endpoint is busy in transferring. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is invalid. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); +/*! + * @brief Primes the endpoint to receive packet from host. + * + * This function checks whether the endpoint is receiving packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prime to receive packet successfully. + * @retval kStatus_USB_Busy The endpoint is busy in transferring. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is invalid. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _USB_DEVICE_CDC_ACM_H_ */ diff --git a/usb/device/class/usb_device_class.c b/usb/device/class/usb_device_class.c new file mode 100644 index 0000000..71e4049 --- /dev/null +++ b/usb/device/class/usb_device_class.c @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016, 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" +#include "usb_device_ch9.h" +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) +/* Include the class drivers according to the usb_device_config.h. */ +#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U)) +#include "usb_device_hid.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U)) +#include "usb_device_cdc_acm.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) +#include "usb_device_msc.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U)) +#include "usb_device_mtp.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U)) +#include "usb_device_audio.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_PHDC)) && (USB_DEVICE_CONFIG_PHDC > 0U)) +#include "usb_device_phdc.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_VIDEO)) && (USB_DEVICE_CONFIG_VIDEO > 0U)) +#include "usb_device_video.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U)) +#include "usb_device_printer.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_DFU)) && (USB_DEVICE_CONFIG_DFU > 0U)) +#include "usb_device_dfu.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_CCID)) && (USB_DEVICE_CONFIG_CCID > 0U)) +#include "usb_device_ccid.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle); +static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId); +static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId, + usb_device_common_class_struct_t **handle); +static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle, + usb_device_common_class_struct_t **handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* The device class driver list. */ +static const usb_device_class_map_t s_UsbDeviceClassInterfaceMap[] = { +#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U)) + {USB_DeviceHidInit, USB_DeviceHidDeinit, USB_DeviceHidEvent, kUSB_DeviceClassTypeHid}, +#endif + +#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U)) + {USB_DeviceCdcAcmInit, USB_DeviceCdcAcmDeinit, USB_DeviceCdcAcmEvent, kUSB_DeviceClassTypeCdc}, +#endif + +#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) + {USB_DeviceMscInit, USB_DeviceMscDeinit, USB_DeviceMscEvent, kUSB_DeviceClassTypeMsc}, +#endif + +#if ((defined(USB_DEVICE_CONFIG_MTP)) && (USB_DEVICE_CONFIG_MTP > 0U)) + {USB_DeviceMtpInit, USB_DeviceMtpDeinit, USB_DeviceMtpEvent, kUSB_DeviceClassTypeMtp}, +#endif + +#if ((defined USB_DEVICE_CONFIG_AUDIO) && (USB_DEVICE_CONFIG_AUDIO > 0U)) + {USB_DeviceAudioInit, USB_DeviceAudioDeinit, USB_DeviceAudioEvent, kUSB_DeviceClassTypeAudio}, +#endif + +#if ((defined USB_DEVICE_CONFIG_PHDC) && (USB_DEVICE_CONFIG_PHDC > 0U)) + {USB_DevicePhdcInit, USB_DevicePhdcDeinit, USB_DevicePhdcEvent, kUSB_DeviceClassTypePhdc}, +#endif + +#if ((defined USB_DEVICE_CONFIG_VIDEO) && (USB_DEVICE_CONFIG_VIDEO > 0U)) + {USB_DeviceVideoInit, USB_DeviceVideoDeinit, USB_DeviceVideoEvent, kUSB_DeviceClassTypeVideo}, +#endif + +#if ((defined USB_DEVICE_CONFIG_PRINTER) && (USB_DEVICE_CONFIG_PRINTER > 0U)) + {USB_DevicePrinterInit, USB_DevicePrinterDeinit, USB_DevicePrinterEvent, kUSB_DeviceClassTypePrinter}, +#endif + +#if ((defined USB_DEVICE_CONFIG_DFU) && (USB_DEVICE_CONFIG_DFU > 0U)) + {USB_DeviceDfuInit, USB_DeviceDfuDeinit, USB_DeviceDfuEvent, kUSB_DeviceClassTypeDfu}, +#endif + +#if ((defined USB_DEVICE_CONFIG_CCID) && (USB_DEVICE_CONFIG_CCID > 0U)) + {USB_DeviceCcidInit, USB_DeviceCcidDeinit, USB_DeviceCcidEvent, kUSB_DeviceClassTypeCcid}, +#endif + + /* please make sure the following member is in the end of s_UsbDeviceClassInterfaceMap*/ + {(usb_device_class_init_call_t)NULL, (usb_device_class_deinit_call_t)NULL, (usb_device_class_event_callback_t)NULL, + (usb_device_class_type_t)0}, +}; + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_common_class_struct_t + s_UsbDeviceCommonClassStruct[USB_DEVICE_CONFIG_NUM]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t + s_UsbDeviceSetupBuffer[USB_DEVICE_CONFIG_NUM][USB_DATA_ALIGN_SIZE_MULTIPLE(USB_SETUP_PACKET_SIZE)]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device common class handle. + * + * This function allocates a a device common class handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device common class handle to the + * caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a common class handle. + * @retval kStatus_USB_Error The common class has been initialized. + */ +static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle) +{ + uint32_t count; + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + /* Check the controller is initialized or not. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + } + /* Get a free common class handle. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (NULL == s_UsbDeviceCommonClassStruct[count].handle) + { + s_UsbDeviceCommonClassStruct[count].controllerId = controllerId; + s_UsbDeviceCommonClassStruct[count].setupBuffer = s_UsbDeviceSetupBuffer[count]; + *handle = &s_UsbDeviceCommonClassStruct[count]; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + + OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device common class handle. + * + * This function frees a device common class handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The common class can not be found. + */ +static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId) +{ + uint32_t count = 0U; + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + s_UsbDeviceCommonClassStruct[count].handle = NULL; + s_UsbDeviceCommonClassStruct[count].configList = (usb_device_class_config_list_struct_t *)NULL; + s_UsbDeviceCommonClassStruct[count].controllerId = 0U; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + OSA_EXIT_CRITICAL(); + + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Get the device common class handle according to the controller id. + * + * This function gets the device common class handle according to the controller id. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device common class handle to the + * caller. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The common class can not be found. + */ +static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId, + usb_device_common_class_struct_t **handle) +{ + uint32_t count = 0U; + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + *handle = &s_UsbDeviceCommonClassStruct[count]; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + OSA_EXIT_CRITICAL(); + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Get the device common class handle according to the device handle. + * + * This function gets the device common class handle according to the device handle. + * + * @param deviceHandle The device handle, got from the USB_DeviceInit. + * @param handle It is out parameter, is used to return pointer of the device common class handle to the + * caller. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The common class can not be found. + */ +static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle, + usb_device_common_class_struct_t **handle) +{ + uint32_t count = 0U; + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (deviceHandle == s_UsbDeviceCommonClassStruct[count].handle) + { + *handle = &s_UsbDeviceCommonClassStruct[count]; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + OSA_EXIT_CRITICAL(); + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Get the device handle according to the controller id. + * + * This function gets the device handle according to the controller id. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + */ +usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle) +{ + uint32_t count = 0U; + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + *handle = s_UsbDeviceCommonClassStruct[count].handle; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + OSA_EXIT_CRITICAL(); + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Handle the event passed to the class drivers. + * + * This function handles the event passed to the class drivers. + * + * @param handle The device handle, got from the USB_DeviceInit. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success A valid request has been handled. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param) +{ + usb_device_common_class_struct_t *classHandle; + uint8_t mapIndex; + uint8_t classIndex; + usb_status_t errorReturn; + usb_status_t status = kStatus_USB_Error; + + if (NULL == param) + { + return kStatus_USB_InvalidParameter; + } + + /* Get the common class handle according to the device handle. */ + errorReturn = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle); + if (kStatus_USB_Success != errorReturn) + { + return kStatus_USB_InvalidParameter; + } + + for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++) + { + for (mapIndex = 0U; mapIndex < (ARRAY_SIZE(s_UsbDeviceClassInterfaceMap) - 1U); mapIndex++) + { + if (s_UsbDeviceClassInterfaceMap[mapIndex].type == + classHandle->configList->config[classIndex].classInfomation->type) + { + /* Call class event callback of supported class */ + errorReturn = s_UsbDeviceClassInterfaceMap[mapIndex].classEventCallback( + (void *)classHandle->configList->config[classIndex].classHandle, event, param); + /* Return the error code kStatus_USB_InvalidRequest immediately, when a class returns + * kStatus_USB_InvalidRequest. */ + if (kStatus_USB_InvalidRequest == errorReturn) + { + return kStatus_USB_InvalidRequest; + } + /* For composite device, it should return kStatus_USB_Success once a valid request has been handled */ + if (kStatus_USB_Success == errorReturn) + { + status = kStatus_USB_Success; + } + break; + } + } + } + + return status; +} + +/*! + * @brief Handle the common class callback. + * + * This function handles the common class callback. + * + * @param handle The device handle, got from the USB_DeviceInit. + * @param event The event codes. Please refer to the enumeration usb_device_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t status; + + /* Get the common class handle according to the device handle. */ + status = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle); + if (kStatus_USB_Success != status) + { + return status; + } + + if ((uint32_t)kUSB_DeviceEventBusReset == event) + { + /* Initialize the control pipes */ + (void)USB_DeviceControlPipeInit(handle, classHandle); + + /* Notify the classes the USB bus reset signal detected. */ + (void)USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle); + } + + /* Call the application device callback function. deviceCallback is from the second parameter of + USB_DeviceClassInit */ + status = classHandle->configList->deviceCallback(handle, event, param); + return status; +} + +/*! + * @brief Initialize the common class and the supported classes. + * + * This function is used to initialize the common class and the supported classes. + * + * @param[in] controllerId The controller id of the USB IP. Please refer to the enumeration #usb_controller_index_t. + * @param[in] configList The class configurations. The pointer must point to the global variable. + * Please refer to the structure #usb_device_class_config_list_struct_t. + * @param[out] handle It is out parameter, is used to return pointer of the device handle to the caller. + * The value of parameter is a pointer points the device handle, and this design is used to + * make simple device align with composite device. For composite device, there are many + * kinds of class handle, but there is only one device handle. So the handle points to + * a device instead of a class. And the class handle can be got from the + * #usb_device_class_config_struct_t::classHandle after the function successfully. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassInit( + uint8_t controllerId, /*!< [IN] Controller ID */ + usb_device_class_config_list_struct_t *configList, /*!< [IN] Pointer to class configuration list */ + usb_device_handle *handle /*!< [OUT] Pointer to the device handle */ +) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error; + uint8_t mapIndex; + uint8_t classIndex; + + if ((NULL == handle) || (NULL == configList) || ((usb_device_callback_t)NULL == configList->deviceCallback)) + { + return kStatus_USB_InvalidParameter; + } + + /* Allocate a common class driver handle. */ + error = USB_DeviceClassAllocateHandle(controllerId, &classHandle); + if (kStatus_USB_Success != error) + { + return error; + } + /* Save the configuration list */ + classHandle->configList = configList; + + /* Initialize the device stack. */ + error = USB_DeviceInit(controllerId, USB_DeviceClassCallback, &classHandle->handle); + + if (kStatus_USB_Success != error) + { + (void)USB_DeviceDeinit(classHandle->handle); + (void)USB_DeviceClassFreeHandle(controllerId); + return error; + } + + /* Initialize the all supported classes according to the configuration list. */ + for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++) + { + for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t)); + mapIndex++) + { + if (classHandle->configList->config[classIndex].classInfomation->type == + s_UsbDeviceClassInterfaceMap[mapIndex].type) + { + (void)s_UsbDeviceClassInterfaceMap[mapIndex].classInit( + controllerId, &classHandle->configList->config[classIndex], + &classHandle->configList->config[classIndex].classHandle); + } + } + } + + *handle = classHandle->handle; + return error; +} + +/*! + * @brief De-initialize the common class and the supported classes. + * + * This function is used to de-initialize the common class and the supported classes. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassDeinit(uint8_t controllerId /*!< [IN] Controller ID */ +) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error; + uint8_t mapIndex; + uint8_t classIndex; + + /* Get the common class handle according to the controller id. */ + error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* De-initialize the all supported classes according to the configuration list. */ + for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++) + { + for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t)); + mapIndex++) + { + if (classHandle->configList->config[classIndex].classInfomation->type == + s_UsbDeviceClassInterfaceMap[mapIndex].type) + { + (void)s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit( + classHandle->configList->config[classIndex].classHandle); + } + } + } + + /* De-initialize the USB device stack. */ + error = USB_DeviceDeinit(classHandle->handle); + if (kStatus_USB_Success == error) + { + /* Free the common class handle. */ + (void)USB_DeviceClassFreeHandle(controllerId); + } + return error; +} + +/*! + * @brief Get the USB bus speed. + * + * This function is used to get the USB bus speed. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param speed It is an OUT parameter, return current speed of the controller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, /*!< [IN] Controller ID */ + uint8_t *speed /*!< [OUT] Current speed */ +) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error; + + /* Get the common class handle according to the controller id. */ + error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the current speed. */ + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSpeed, speed); + + return error; +} + +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) +/*! + * @brief Get the USB SOF count. + * + * This function is used to get the USB SOF count. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param currentFrameCount It is an OUT parameter, return current sof count of the controller. + * HS: micro frame count, FS: frame count + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId, /*!< [IN] Controller ID */ + uint32_t *currentFrameCount /*!< [OUT] Current frame count */ +) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error; + + /* Get the common class handle according to the controller id. */ + error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the current frame count. */ + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusGetCurrentFrameCount, currentFrameCount); + + return error; +} +#endif /* USB_DEVICE_CONFIG_GET_SOF_COUNT */ + +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/usb/device/class/usb_device_class.h b/usb/device/class/usb_device_class.h new file mode 100644 index 0000000..6589ccc --- /dev/null +++ b/usb/device/class/usb_device_class.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_CLASS_H__ +#define __USB_DEVICE_CLASS_H__ + +/*! + * @addtogroup usb_device_class_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Macro to define class handle */ +typedef void *class_handle_t; + +/*! @brief Available class types. */ +typedef enum _usb_usb_device_class_type +{ + kUSB_DeviceClassTypeHid = 1U, + kUSB_DeviceClassTypeCdc, + kUSB_DeviceClassTypeMsc, + kUSB_DeviceClassTypeMtp, + kUSB_DeviceClassTypeAudio, + kUSB_DeviceClassTypePhdc, + kUSB_DeviceClassTypeVideo, + kUSB_DeviceClassTypePrinter, + kUSB_DeviceClassTypeDfu, + kUSB_DeviceClassTypeCcid, +} usb_device_class_type_t; + +/*! @brief Available common class events. */ +typedef enum _usb_device_class_event +{ + kUSB_DeviceClassEventClassRequest = 1U, + kUSB_DeviceClassEventDeviceReset, + kUSB_DeviceClassEventSetConfiguration, + kUSB_DeviceClassEventSetInterface, + kUSB_DeviceClassEventSetEndpointHalt, + kUSB_DeviceClassEventClearEndpointHalt, +} usb_device_class_event_t; + +/*! + * @brief Obtains the endpoint data structure. + * + * Define the endpoint data structure. + * + */ +typedef struct _usb_device_endpoint_struct +{ + uint8_t endpointAddress; /*!< Endpoint address*/ + uint8_t transferType; /*!< Endpoint transfer type*/ + uint16_t maxPacketSize; /*!< Endpoint maximum packet size */ + uint8_t interval; /*!< Endpoint interval*/ +} usb_device_endpoint_struct_t; + +/*! + * @brief Obtains the endpoint group. + * + * Structure representing endpoints and the number of endpoints that the user wants. + * + */ +typedef struct _usb_device_endpoint_list +{ + uint8_t count; /*!< How many endpoints in current interface*/ + usb_device_endpoint_struct_t *endpoint; /*!< Endpoint structure list*/ +} usb_device_endpoint_list_t; + +/*! + * @brief Obtains the interface list data structure. + * + * Structure representing an interface. + * + */ +typedef struct _usb_device_interface_struct +{ + uint8_t alternateSetting; /*!< Alternate setting number*/ + usb_device_endpoint_list_t endpointList; /*!< Endpoints of the interface*/ + void *classSpecific; /*!< Class specific structure handle*/ +} usb_device_interface_struct_t; + +/*! + * @brief Obtains the interface data structure. + * + * Structure representing interface. + * + */ +typedef struct _usb_device_interfaces_struct +{ + uint8_t classCode; /*!< Class code of the interface*/ + uint8_t subclassCode; /*!< Subclass code of the interface*/ + uint8_t protocolCode; /*!< Protocol code of the interface*/ + uint8_t interfaceNumber; /*!< Interface number*/ + usb_device_interface_struct_t *interface; /*!< Interface structure list*/ + uint8_t count; /*!< Number of interfaces in the current interface*/ +} usb_device_interfaces_struct_t; + +/*! + * @brief Obtains the interface group. + * + * Structure representing how many interfaces in one class type. + * + */ +typedef struct _usb_device_interface_list +{ + uint8_t count; /*!< Number of interfaces of the class*/ + usb_device_interfaces_struct_t *interfaces; /*!< All interfaces*/ +} usb_device_interface_list_t; + +/*! + * @brief Obtains the class data structure. + * + * Structure representing how many configurations in one class type. + * + */ +typedef struct _usb_device_class_struct +{ + usb_device_interface_list_t *interfaceList; /*!< Interfaces of the class*/ + usb_device_class_type_t type; /*!< Class type*/ + uint8_t configurations; /*!< Number of configurations of the class*/ +} usb_device_class_struct_t; + +/*callback function pointer structure for application to provide class parameters*/ +typedef usb_status_t (*usb_device_class_callback_t)(class_handle_t classHandle, + uint32_t callbackEvent, + void *eventParam); + +/*! + * @brief Obtains the device class information structure. + * + * Structure representing the device class information. This structure only can be stored in RAM space. + * + */ +typedef struct _usb_device_class_config_struct +{ + usb_device_class_callback_t classCallback; /*!< Class callback function to handle the device status-related event + for the specified type of class*/ + class_handle_t classHandle; /*!< The class handle of the class, filled by the common driver.*/ + usb_device_class_struct_t *classInfomation; /*!< Detailed information of the class*/ +} usb_device_class_config_struct_t; + +/*! + * @brief Obtains the device class configuration structure. + * + * Structure representing the device class configuration information. + * + */ +typedef struct _usb_device_class_config_list_struct +{ + usb_device_class_config_struct_t *config; /*!< Array of class configuration structures */ + usb_device_callback_t deviceCallback; /*!< Device callback function */ + uint8_t count; /*!< Number of class supported */ +} usb_device_class_config_list_struct_t; + +/*! + * @brief Obtains the control request structure. + * + * This structure is used to pass the control request information. + * The structure is used in following two cases. + * 1. Case one, the host wants to send data to the device in the control data stage: @n + * a. If a setup packet is received, the structure is used to pass the setup packet data and wants to get the + * buffer to receive data sent from the host. + * The field isSetup is 1. + * The length is the requested buffer length. + * The buffer is filled by the class or application by using the valid buffer address. + * The setup is the setup packet address. + * b. If the data received is sent by the host, the structure is used to pass the data buffer address and the + * data + * length sent by the host. + * In this way, the field isSetup is 0. + * The buffer is the address of the data sent from the host. + * The length is the received data length. + * The setup is the setup packet address. @n + * 2. Case two, the host wants to get data from the device in control data stage: @n + * If the setup packet is received, the structure is used to pass the setup packet data and wants to get the + * data buffer address to send data to the host. + * The field isSetup is 1. + * The length is the requested data length. + * The buffer is filled by the class or application by using the valid buffer address. + * The setup is the setup packet address. + * + */ +typedef struct _usb_device_control_request_struct +{ + usb_setup_struct_t *setup; /*!< The pointer of the setup packet data. */ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length or requested length. */ + uint8_t isSetup; /*!< Indicates whether a setup packet is received. */ +} usb_device_control_request_struct_t; + +/*! @brief Obtains the control get descriptor request common structure. */ +typedef struct _usb_device_get_descriptor_common_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_descriptor_common_struct_t; + +/*! @brief Obtains the control get device descriptor request structure. */ +typedef struct _usb_device_get_device_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_device_descriptor_struct_t; + +/*! @brief Obtains the control get device qualifier descriptor request structure. */ +typedef struct _usb_device_get_device_qualifier_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_device_qualifier_descriptor_struct_t; + +/*! @brief Obtains the control get configuration descriptor request structure. */ +typedef struct _usb_device_get_configuration_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t configuration; /*!< The configuration number. */ +} usb_device_get_configuration_descriptor_struct_t; + +/*! @brief Obtains the control get bos descriptor request structure. */ +typedef struct _usb_device_get_bos_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_bos_descriptor_struct_t; + +/*! @brief Obtains the control get string descriptor request structure. */ +typedef struct _usb_device_get_string_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint16_t languageId; /*!< Language ID. */ + uint8_t stringIndex; /*!< String index. */ +} usb_device_get_string_descriptor_struct_t; + +/*! @brief Obtains the control get HID descriptor request structure. */ +typedef struct _usb_device_get_hid_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t interfaceNumber; /*!< The interface number. */ +} usb_device_get_hid_descriptor_struct_t; + +/*! @brief Obtains the control get HID report descriptor request structure. */ +typedef struct _usb_device_get_hid_report_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t interfaceNumber; /*!< The interface number. */ +} usb_device_get_hid_report_descriptor_struct_t; + +/*! @brief Obtains the control get HID physical descriptor request structure. */ +typedef struct _usb_device_get_hid_physical_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t index; /*!< Physical index */ + uint8_t interfaceNumber; /*!< The interface number. */ +} usb_device_get_hid_physical_descriptor_struct_t; + +/*! @brief Obtains the control get descriptor request common union. */ +typedef union _usb_device_get_descriptor_common_union +{ + usb_device_get_descriptor_common_struct_t commonDescriptor; /*!< Common structure. */ + usb_device_get_device_descriptor_struct_t deviceDescriptor; /*!< The structure to get device descriptor. */ + usb_device_get_device_qualifier_descriptor_struct_t + deviceQualifierDescriptor; /*!< The structure to get device qualifier descriptor. */ + usb_device_get_configuration_descriptor_struct_t + configurationDescriptor; /*!< The structure to get configuration descriptor. */ + usb_device_get_string_descriptor_struct_t stringDescriptor; /*!< The structure to get string descriptor. */ + usb_device_get_hid_descriptor_struct_t hidDescriptor; /*!< The structure to get HID descriptor. */ + usb_device_get_hid_report_descriptor_struct_t + hidReportDescriptor; /*!< The structure to get HID report descriptor. */ + usb_device_get_hid_physical_descriptor_struct_t + hidPhysicalDescriptor; /*!< The structure to get HID physical descriptor. */ +} usb_device_get_descriptor_common_union_t; + +/*! @brief Define function type for class device instance initialization */ +typedef usb_status_t (*usb_device_class_init_call_t)(uint8_t controllerId, + usb_device_class_config_struct_t *classConfig, + class_handle_t *classHandle); +/*! @brief Define function type for class device instance deinitialization, internal */ +typedef usb_status_t (*usb_device_class_deinit_call_t)(class_handle_t handle); +/*! @brief Define function type for class device instance Event change */ +typedef usb_status_t (*usb_device_class_event_callback_t)(void *classHandle, uint32_t event, void *param); + +/*! @brief Define class driver interface structure. */ +typedef struct _usb_device_class_map +{ + usb_device_class_init_call_t classInit; /*!< Class driver initialization- entry of the class driver */ + usb_device_class_deinit_call_t classDeinit; /*!< Class driver de-initialization*/ + usb_device_class_event_callback_t classEventCallback; /*!< Class driver event callback*/ + usb_device_class_type_t type; /*!< Class type*/ +} usb_device_class_map_t; + +/*! @brief Structure holding common class state information */ +typedef struct _usb_device_common_class_struct +{ + usb_device_handle handle; /*!< USB device handle*/ + usb_device_class_config_list_struct_t *configList; /*!< USB device configure list*/ + uint8_t *setupBuffer; /*!< Setup packet data buffer*/ + uint16_t standardTranscationBuffer; /*!< + * This variable is used in: + * get status request + * get configuration request + * get interface request + * set interface request + * get sync frame request + */ + uint8_t controllerId; /*!< Controller ID*/ +} usb_device_common_class_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the common class and the supported classes. + * + * This function is used to initialize the common class and the supported classes. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] configList The class configurations. The pointer must point to the global variable. + * See the structure #usb_device_class_config_list_struct_t. + * @param[out] handle A parameter used to return pointer of the device handle to the caller. + * The value of the parameter is a pointer to the device handle. This design is used to + * make a simple device align with the composite device. For the composite device, there are + * many + * kinds of class handles. However, there is only one device handle. Therefore, the handle + * points to + * a device instead of a class. The class handle can be received from the + * #usb_device_class_config_struct_t::classHandle after the function successfully. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassInit(uint8_t controllerId, + usb_device_class_config_list_struct_t *configList, + usb_device_handle *handle); + +/*! + * @brief Deinitializes the common class and the supported classes. + * + * This function is used to deinitialize the common class and the supported classes. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassDeinit(uint8_t controllerId); + +/*! + * @brief Gets the USB bus speed. + * + * This function is used to get the USB bus speed. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[out] speed It is an OUT parameter, which returns the current speed of the controller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, uint8_t *speed); + +/*! + * @brief Handles the event passed to the class drivers. + * + * This function handles the event passed to the class drivers. + * + * @param[in] handle The device handle received from the #USB_DeviceInit. + * @param[in] event The event codes. See the enumeration #usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success A valid request has been handled. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe is stalled by the caller. + */ +usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param); + +/*! + * @brief Handles the common class callback. + * + * This function handles the common class callback. + * + * @param[in] handle The device handle received from the #USB_DeviceInit. + * @param[in] event The event codes. See the enumeration #usb_device_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param); + +/*! + * @brief Gets the device handle according to the controller ID. + * + * This function gets the device handle according to the controller ID. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[out] handle An out parameter used to return the pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Get device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle can't be found. + */ +usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle); + +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) +/*! + * @brief Get the USB SOF count. + * + * This function is used to get the USB SOF count. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param currentFrameCount It is an OUT parameter, return current sof count of the controller. + * HS: micro frame count, FS: frame count + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassGetCurrentFrameCount(uint8_t controllerId, /*!< [IN] Controller ID */ + uint32_t *currentFrameCount /*!< [OUT] Current frame count */ +); +#endif + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_CLASS_H__ */ diff --git a/usb/device/include/usb_device.h b/usb/device/include/usb_device.h new file mode 100644 index 0000000..30fa740 --- /dev/null +++ b/usb/device/include/usb_device.h @@ -0,0 +1,658 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_H__ +#define __USB_DEVICE_H__ + +/*! + * @addtogroup usb_device_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines Get/Set status Types */ +typedef enum _usb_device_status +{ + kUSB_DeviceStatusTestMode = 1U, /*!< Test mode */ + kUSB_DeviceStatusSpeed, /*!< Current speed */ + kUSB_DeviceStatusOtg, /*!< OTG status */ + kUSB_DeviceStatusDevice, /*!< Device status */ + kUSB_DeviceStatusEndpoint, /*!< Endpoint state usb_device_endpoint_status_t */ + kUSB_DeviceStatusDeviceState, /*!< Device state */ + kUSB_DeviceStatusAddress, /*!< Device address */ + kUSB_DeviceStatusSynchFrame, /*!< Current frame */ + kUSB_DeviceStatusBus, /*!< Bus status */ + kUSB_DeviceStatusBusSuspend, /*!< Bus suspend */ + kUSB_DeviceStatusBusSleep, /*!< Bus suspend */ + kUSB_DeviceStatusBusResume, /*!< Bus resume */ + kUSB_DeviceStatusRemoteWakeup, /*!< Remote wakeup state */ + kUSB_DeviceStatusBusSleepResume, /*!< Bus resume */ +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) + kUSB_DeviceStatusGetCurrentFrameCount, /*!< Get current frame count */ +#endif +} usb_device_status_t; + +/*! @brief Defines USB 2.0 device state */ +typedef enum _usb_device_state +{ + kUSB_DeviceStateConfigured = 0U, /*!< Device state, Configured*/ + kUSB_DeviceStateAddress, /*!< Device state, Address*/ + kUSB_DeviceStateDefault, /*!< Device state, Default*/ + kUSB_DeviceStateAddressing, /*!< Device state, Address setting*/ + kUSB_DeviceStateTestMode, /*!< Device state, Test mode*/ +} usb_device_state_t; + +/*! @brief Defines endpoint state */ +typedef enum _usb_endpoint_status +{ + kUSB_DeviceEndpointStateIdle = 0U, /*!< Endpoint state, idle*/ + kUSB_DeviceEndpointStateStalled, /*!< Endpoint state, stalled*/ +} usb_device_endpoint_status_t; + +/*! @brief Control endpoint index */ +#define USB_CONTROL_ENDPOINT (0U) +/*! @brief Control endpoint maxPacketSize */ +#define USB_CONTROL_MAX_PACKET_SIZE (64U) + +#if (USB_DEVICE_CONFIG_EHCI && (USB_CONTROL_MAX_PACKET_SIZE != (64U))) +#error For high speed, USB_CONTROL_MAX_PACKET_SIZE must be 64!!! +#endif + +/*! @brief The setup packet size of USB control transfer. */ +#define USB_SETUP_PACKET_SIZE (8U) +/*! @brief USB endpoint mask */ +#define USB_ENDPOINT_NUMBER_MASK (0x0FU) + +/*! @brief uninitialized value */ +#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFFU) + +/*! @brief the endpoint callback length of cancelled transfer */ +#define USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) + +/*! @brief invalid tranfer buffer addresss */ +#define USB_INVALID_TRANSFER_BUFFER (0xFFFFFFFEU) + +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) +/* USB device IP3511 max frame count */ +#define USB_DEVICE_IP3511_MAX_FRAME_COUNT (0x000007FFU) +/* USB device EHCI max frame count */ +#define USB_DEVICE_EHCI_MAX_FRAME_COUNT (0x00003FFFU) +/* USB device EHCI max frame count */ +#define USB_DEVICE_KHCI_MAX_FRAME_COUNT (0x000007FFU) + +/*! @brief usb device controller max frame count */ +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +#define USB_DEVICE_MAX_FRAME_COUNT (USB_DEVICE_KHCI_MAX_FRAME_COUNT) +#elif (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#define USB_DEVICE_MAX_FRAME_COUNT (USB_DEVICE_IP3511_MAX_FRAME_COUNT) +#elif ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +#define USB_DEVICE_MAX_FRAME_COUNT (USB_DEVICE_EHCI_MAX_FRAME_COUNT) +#endif +#endif + +/*! @brief Available common EVENT types in device callback */ +typedef enum _usb_device_event +{ + kUSB_DeviceEventBusReset = 1U, /*!< USB bus reset signal detected */ + kUSB_DeviceEventSuspend, /*!< USB bus suspend signal detected */ + kUSB_DeviceEventResume, /*!< USB bus resume signal detected. The resume signal is driven by itself or a host */ + kUSB_DeviceEventSleeped, /*!< USB bus LPM suspend signal detected */ + kUSB_DeviceEventLPMResume, /*!< USB bus LPM resume signal detected. The resume signal is driven by itself or a host + */ + kUSB_DeviceEventError, /*!< An error is happened in the bus. */ + kUSB_DeviceEventDetach, /*!< USB device is disconnected from a host. */ + kUSB_DeviceEventAttach, /*!< USB device is connected to a host. */ + kUSB_DeviceEventSetConfiguration, /*!< Set configuration. */ + kUSB_DeviceEventSetInterface, /*!< Set interface. */ + + kUSB_DeviceEventGetDeviceDescriptor, /*!< Get device descriptor. */ + kUSB_DeviceEventGetConfigurationDescriptor, /*!< Get configuration descriptor. */ + kUSB_DeviceEventGetStringDescriptor, /*!< Get string descriptor. */ + kUSB_DeviceEventGetHidDescriptor, /*!< Get HID descriptor. */ + kUSB_DeviceEventGetHidReportDescriptor, /*!< Get HID report descriptor. */ + kUSB_DeviceEventGetHidPhysicalDescriptor, /*!< Get HID physical descriptor. */ + kUSB_DeviceEventGetBOSDescriptor, /*!< Get configuration descriptor. */ + kUSB_DeviceEventGetDeviceQualifierDescriptor, /*!< Get device qualifier descriptor. */ + kUSB_DeviceEventVendorRequest, /*!< Vendor request. */ + kUSB_DeviceEventSetRemoteWakeup, /*!< Enable or disable remote wakeup function. */ + kUSB_DeviceEventGetConfiguration, /*!< Get current configuration index */ + kUSB_DeviceEventGetInterface, /*!< Get current interface alternate setting value */ + kUSB_DeviceEventSetBHNPEnable, +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) + kUSB_DeviceEventDcdDetectionfinished, /*!< The DCD detection finished */ +#endif +} usb_device_event_t; + +/*! @brief Endpoint callback message structure */ +typedef struct _usb_device_endpoint_callback_message_struct +{ + uint8_t *buffer; /*!< Transferred buffer */ + uint32_t length; /*!< Transferred data length */ + uint8_t isSetup; /*!< Is in a setup phase */ +} usb_device_endpoint_callback_message_struct_t; + +/*! + * @brief Endpoint callback function typedef. + * + * This callback function is used to notify the upper layer what the transfer result is. + * This callback pointer is passed when a specified endpoint is initialized by calling API #USB_DeviceInitEndpoint. + * + * @param handle The device handle. It equals to the value returned from #USB_DeviceInit. + * @param message The result of a transfer, which includes transfer buffer, transfer length, and whether is in a + * setup phase. + * phase for control pipe. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_device_endpoint_callback_t)(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); + +/*! + * @brief Device callback function typedef. + * + * This callback function is used to notify the upper layer that the device status has changed. + * This callback pointer is passed by calling API #USB_DeviceInit. + * + * @param handle The device handle. It equals the value returned from #USB_DeviceInit. + * @param callbackEvent The callback event type. See enumeration #usb_device_event_t. + * @param eventParam The event parameter for this callback. The parameter type is determined by the callback event. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_device_callback_t)(usb_device_handle handle, uint32_t callbackEvent, void *eventParam); + +/*! @brief Endpoint callback structure */ +typedef struct _usb_device_endpoint_callback_struct +{ + usb_device_endpoint_callback_t callbackFn; /*!< Endpoint callback function*/ + void *callbackParam; /*!< Parameter for callback function*/ + uint8_t isBusy; +} usb_device_endpoint_callback_struct_t; + +/*! @brief Endpoint initialization structure */ +typedef struct _usb_device_endpoint_init_struct +{ + uint16_t maxPacketSize; /*!< Endpoint maximum packet size */ + uint8_t endpointAddress; /*!< Endpoint address*/ + uint8_t transferType; /*!< Endpoint transfer type*/ + uint8_t zlt; /*!< ZLT flag*/ + uint8_t interval; /*!< Endpoint interval*/ +} usb_device_endpoint_init_struct_t; + +/*! @brief Endpoint status structure */ +typedef struct _usb_device_endpoint_status_struct +{ + uint8_t endpointAddress; /*!< Endpoint address */ + uint16_t endpointStatus; /*!< Endpoint status : idle or stalled */ +} usb_device_endpoint_status_struct_t; + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @name USB device APIs + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the USB device stack. + * + * This function initializes the USB device module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] deviceCallback Function pointer of the device callback. + * @param[out] handle It is an out parameter used to return the pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success The device is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id. + * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invalid. There is an empty + * interface entity. + * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than the IP's endpoint number. + * Or, the device has been initialized. + * Or, the mutex or message queue is created failed. + */ +extern usb_status_t USB_DeviceInit(uint8_t controllerId, + usb_device_callback_t deviceCallback, + usb_device_handle *handle); + +/*! + * @brief Enables the device functionality. + * + * The function enables the device functionality, so that the device can be recognized by the host when the device + * detects that it has been connected to a host. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceRun(usb_device_handle handle); + +/*! + * @brief Disables the device functionality. + * + * The function disables the device functionality. After this function called, even if the device is detached to the + * host, + * it can't work. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceStop(usb_device_handle handle); + +/*! + * @brief De-initializes the device controller. + * + * The function de-initializes the device controller specified by the handle. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceDeinit(usb_device_handle handle); + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. The function is not reentrant. + * @param[in] length The data length need to be sent. + * + * @retval kStatus_USB_Success The send request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value indicates whether the sending request is successful or not. The transfer done is notified by + * the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue on the application level. + * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +extern usb_status_t USB_DeviceSendRequest(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. The function is not reentrant. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @retval kStatus_USB_Success The receive request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by + * the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue on the application level. + * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +extern usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The transfer is cancelled. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Initializes a specified endpoint. + * + * The function is used to initialize a specified endpoint. The corresponding endpoint callback is also initialized. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] epInit Endpoint initialization structure. See the structure usb_device_endpoint_init_struct_t. + * @param[in] epCallback Endpoint callback structure. See the structure + * usb_device_endpoint_callback_struct_t. + * + * @retval kStatus_USB_Success The endpoint is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is + * more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle, + usb_device_endpoint_init_struct_t *epInit, + usb_device_endpoint_callback_struct_t *epCallback); + +/*! + * @brief Deinitializes a specified endpoint. + * + * The function is used to deinitializes a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is de-initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Stalls a specified endpoint. + * + * The function is used to stall a specified endpoint. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to unstall a specified endpoint. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is un-stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Gets the status of the selected item. + * + * The function is used to get the status of the selected item. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] type The selected item. See the structure #usb_device_status_t. + * @param[out] param The parameter type is determined by the selected item. + * + * @retval kStatus_USB_Success Get status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The parameter is NULL pointer. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type. + */ +extern usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param); + +/*! + * @brief Sets the status of the selected item. + * + * The function is used to set the status of the selected item. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] type The selected item. See the structure #usb_device_status_t. + * @param[in] param The parameter type is determined by the selected item. + * + * @retval kStatus_USB_Success Set status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type or the parameter is NULL pointer. + */ +extern usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param); + +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +/*! + * @brief Enable the device dcd module. + * + * The function enable the device dcd module. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device could run. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceDcdEnable(usb_device_handle handle); + +/*! + * @brief Disable the device dcd module. + * + * The function disable the device dcd module. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The dcd is reset and stopped. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceDcdDisable(usb_device_handle handle); +#endif + +#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) +/*! + * @brief Device task function. + * + * The function is used to handle the controller message. + * This function should not be called in the application directly. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceTaskFunction(void *deviceHandle); +#endif + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) +/*! + * @brief Device KHCI task function. + * + * The function is used to handle the KHCI controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceKhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) +/*! + * @brief Device EHCI task function. + * + * The function is used to handle the EHCI controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceEhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +/*! + * @brief Device ehci DCD ISR function. + * + * The function is the ehci DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceEhciIsrHSDCDFunction(void *deviceHandle); +#endif +#endif +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#if ((defined(USB_DEVICE_CONFIG_USE_TASK)) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) +/*! + * @brief Device LPC ip3511 controller task function. + * + * The function is used to handle the LPC ip3511 controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceLpcIp3511TaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +/*! + * @brief Device IP3511 DCD ISR function. + * + * The function is the IP3511 DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceLpcIp3511IsrDCDFunction(void *deviceHandle); +#endif +#endif +#endif + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/*! + * @brief Device KHCI ISR function. + * + * The function is the KHCI interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceKhciIsrFunction(void *deviceHandle); +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +#if (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) +#if 0U /* it is not implemented yet */ +/*! + * @brief Device KHCI DCD ISR function. + * + * The function is the KHCI DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDcdIsrFunction(void *deviceHandle); +#endif +#endif +#endif +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! + * @brief Device EHCI ISR function. + * + * The function is the EHCI interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceEhciIsrFunction(void *deviceHandle); +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/*! + * @brief Device LPC USB ISR function. + * + * The function is the LPC USB interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle); +#endif + +#if (((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U))) +/*! + * @brief Device USB DWC3 ISR function. + * + * The function is the USB interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDwc3IsrFunction(void *deviceHandle); +#endif + +/*! + * @brief Gets the device stack version function. + * + * The function is used to get the device stack version. + * + * @param[out] version The version structure pointer to keep the device stack version. + * + */ +extern void USB_DeviceGetVersion(uint32_t *version); + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) || \ + (((defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)))) +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] tick Current hardware tick(uint is ms). + * + */ +extern usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick); +#endif + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* __USB_DEVICE_H__ */ diff --git a/usb/device/source/lpcip3511/usb_device_lpcip3511.c b/usb/device/source/lpcip3511/usb_device_lpcip3511.c new file mode 100644 index 0000000..3600e3e --- /dev/null +++ b/usb/device/source/lpcip3511/usb_device_lpcip3511.c @@ -0,0 +1,2489 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017,2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" +#include "fsl_device_registers.h" +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) +#include "usb_hsdcd.h" +#endif +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) +#if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U)) +#include "usb_phy.h" +#endif +#endif +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#include "usb_device_dci.h" +#include "usb_device_lpcip3511.h" + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + +#define USB_LPC3511IP_INTSTAT_DEV_INT_MASK USBHSD_INTSTAT_DEV_INT_MASK +#define USB_LPC3511IP_INTSTAT_FRAME_INT_MASK USBHSD_INTSTAT_FRAME_INT_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK USBHSD_DEVCMDSTAT_INTONNAK_AO_MASK +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK USBHSD_DEVCMDSTAT_INTONNAK_AI_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK USBHSD_DEVCMDSTAT_LPM_REWP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT USBHSD_DEVCMDSTAT_LPM_REWP_SHIFT + +#define USB_LPC3511IP_DEVCMDSTAT_Speed_MASK USBHSD_DEVCMDSTAT_Speed_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_DCON_MASK USBHSD_DEVCMDSTAT_DCON_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK USBHSD_DEVCMDSTAT_DEV_EN_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK USBHSD_DEVCMDSTAT_LPM_SUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK USBHSD_DEVCMDSTAT_FORCE_NEEDCLK_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK USBHSD_DEVCMDSTAT_LPM_SUS_MASK + +#define USB_LPC3511IP_USB_LPM_HIRD_SW USBHSD_LPM_HIRD_SW + +#define USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK USBHSD_DEVCMDSTAT_DEV_ADDR_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK USBHSD_DEVCMDSTAT_DSUS_MASK +#define USB_LPC3511IP_INFO_ERR_CODE_MASK USBHSD_INFO_ERR_CODE_MASK +#define USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK USBHSD_DEVCMDSTAT_SETUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DRES_C_MASK USBHSD_DEVCMDSTAT_DRES_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_C_MASK USBHSD_DEVCMDSTAT_DSUS_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DCON_C_MASK USBHSD_DEVCMDSTAT_DCON_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_VBUS_DEBOUNCED_MASK USBHSD_DEVCMDSTAT_VBUS_DEBOUNCED_MASK +#define USB_LPC3511IP_INFO_FRAME_NR_MASK USBHSD_INFO_FRAME_NR_MASK +#define USB_LPC3511IP_INFO_FRAME_NR_SHIFT USBHSD_INFO_FRAME_NR_SHIFT +#else +#define USB_LPC3511IP_INTSTAT_DEV_INT_MASK USB_INTSTAT_DEV_INT_MASK +#define USB_LPC3511IP_INTSTAT_FRAME_INT_MASK USB_INTSTAT_FRAME_INT_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK USB_DEVCMDSTAT_INTONNAK_AO_MASK +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK USB_DEVCMDSTAT_INTONNAK_AI_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK USB_DEVCMDSTAT_LPM_REWP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT USB_DEVCMDSTAT_LPM_REWP_SHIFT + +#define USB_LPC3511IP_DEVCMDSTAT_DCON_MASK USB_DEVCMDSTAT_DCON_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK USB_DEVCMDSTAT_DEV_EN_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK USB_DEVCMDSTAT_LPM_SUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK USB_DEVCMDSTAT_FORCE_NEEDCLK_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK USB_DEVCMDSTAT_LPM_SUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK USB_DEVCMDSTAT_LPM_SUS_MASK + +#define USB_LPC3511IP_USB_LPM_HIRD_SW USB_LPM_HIRD_SW + +#define USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK USB_DEVCMDSTAT_DEV_ADDR_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK USB_DEVCMDSTAT_DSUS_MASK +#define USB_LPC3511IP_INFO_ERR_CODE_MASK USB_INFO_ERR_CODE_MASK +#define USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK USB_DEVCMDSTAT_SETUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DRES_C_MASK USB_DEVCMDSTAT_DRES_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_C_MASK USB_DEVCMDSTAT_DSUS_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DCON_C_MASK USB_DEVCMDSTAT_DCON_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_VBUS_DEBOUNCED_MASK USB_DEVCMDSTAT_VBUSDEBOUNCED_MASK +#define USB_LPC3511IP_INFO_FRAME_NR_MASK USB_INFO_FRAME_NR_MASK +#define USB_LPC3511IP_INFO_FRAME_NR_SHIFT USB_INFO_FRAME_NR_SHIFT +#endif + +#define USB_LPC3511IP_USB_LPM_ADPPROBE_MASK (0x00100000u) + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* on Aruba IP3511 (USB0 FS), there are 8 physical EPs, on IP3511 HS (USB1 FS), there are 10 physical EPs. */ +#define USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK (0xFFFFu) + +/*! @brief endpoint command status, buffer address offset */ +#define USB_LPC3511IPHS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK (0x000007FFu) +#define USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_SHIFT (11) +#define USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_MASK (0x03FFF800u) +#define USB_LPC3511IPFS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK (0x0000FFFFu) +#define USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT (16) +#define USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_MASK (0x03FF0000u) + +#define USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK (0x01UL << 26) +#define USB_LPC3511IP_ENDPOINT_RFTV_MASK (0x01UL << 27) +#define USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK (0x01UL << 28) +#define USB_LPC3511IP_ENDPOINT_STALL_MASK (0x01UL << 29) +#define USB_LPC3511IP_ENDPOINT_STALL_SHIFT (29) +#define USB_LPC3511IP_ENDPOINT_DISABLE_MASK (0x01UL << 30) +#define USB_LPC3511IP_ENDPOINT_ACTIVE_MASK (0x01UL << 31) +#define USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT (26) + +#define USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK (0x0F000000u) + +#define USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND(lpcState, index, odd, value) \ + *((volatile uint32_t *)(((uint32_t)((lpcState)->epCommandStatusList)) | ((uint32_t)(index) << 3) | \ + ((((uint32_t)(odd)) & 1UL) << 2U))) &= (value) + +/*! @brief Set endpoint command/status value */ +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#define USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpcState, index, odd, value, NBytes, address) \ + \ + *((volatile uint32_t *)(((uint32_t)((lpcState)->epCommandStatusList)) | ((uint32_t)(index) << 3) | \ + (((((uint32_t)(odd)) & 1UL)) << 2U))) = \ + ((0U != lpc3511IpState->controllerSpeed) ? \ + \ + ((uint32_t)(value) | ((uint32_t)(NBytes) << USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_SHIFT) | \ + (((uint32_t)(address) >> 6) & USB_LPC3511IPHS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK)) : \ + \ + ((uint32_t)(value) | ((uint32_t)(NBytes) << USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT) | \ + (((uint32_t)(address) >> 6) & USB_LPC3511IPFS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK))) +#else +#define USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpcState, index, odd, value, NBytes, address) \ + \ + *((volatile uint32_t *)(((uint32_t)((lpcState)->epCommandStatusList)) | ((uint32_t)(index) << 3) | \ + (((((uint32_t)(odd)) & 1U)) << 2U))) = \ + ((uint32_t)(value) | ((uint32_t)(NBytes) << USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT) | \ + (((uint32_t)(address) >> 6) & USB_LPC3511IPFS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK)) +#endif + +#define USB_LPC3511IP_ENDPOINT_DES_INDEX(endpoint) \ + (((((endpoint)) & 0x0FU) << 1) + \ + ((0U != ((endpoint)&USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)) ? (1U) : (0U))) + +#define USB_LPC3511IP_GET_MULTIPLE_OF_64(n) ((((uint32_t)n) + 63U) & 0xFFFFFFC0U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static usb_status_t USB_DeviceLpc3511IpTransaction(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex); +static usb_status_t USB_DeviceLpc3511IpControlPreSetDeviceAddress(usb_device_controller_handle controllerHandle, + void *param); +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* define the reserved buffer for endpoint max packet copy */ + +#define SETUP_TRANSFER_DATA_OFFSET (0U) +#define CONTROL_TRANSFER_DATA_OFFSET ((USB_DATA_ALIGN_SIZE_MULTIPLE(8U) >> 2)) +#define ZERO_TRANSFER_DATA_OFFSET ((USB_DATA_ALIGN_SIZE_MULTIPLE(8U) >> 2) + (USB_DATA_ALIGN_SIZE_MULTIPLE(64U) >> 2)) +#define RESERVED_EP_DATA_OFFSET \ + ((USB_DATA_ALIGN_SIZE_MULTIPLE(8U) >> 2) + (USB_DATA_ALIGN_SIZE_MULTIPLE(64U) >> 2) + \ + (USB_DATA_ALIGN_SIZE_MULTIPLE(4U) >> 2)) + +#if defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint32_t + s_SetupAndEpReservedData[USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY] + [USB_DATA_ALIGN_SIZE_MULTIPLE((USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE >> 2)) + + RESERVED_EP_DATA_OFFSET]; +#else +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint32_t + s_SetupAndEpReservedData[USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS][RESERVED_EP_DATA_OFFSET]; +#endif + +static usb_device_lpc3511ip_state_struct_t + s_UsbDeviceLpc3511IpState[USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS]; + +/* LPC3511IP controller driver instances and endpoint command/status list, EPLISTSTART's value is the buffer pointer. */ +#if ((USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) == 1U) +USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static uint32_t + s_EpCommandStatusList1[((USB_DEVICE_IP3511_ENDPOINTS_NUM)) * 4]; +#define LPC_CONTROLLER_ENDPOINT_LIST_ARRAY \ + { \ + &s_EpCommandStatusList1[0] \ + } + +#elif ((USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) == 2U) +USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static uint32_t + s_EpCommandStatusList1[(USB_DEVICE_IP3511_ENDPOINTS_NUM)*4]; +USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static uint32_t + s_EpCommandStatusList2[(USB_DEVICE_IP3511_ENDPOINTS_NUM)*4]; +#define LPC_CONTROLLER_ENDPOINT_LIST_ARRAY \ + { \ + &s_EpCommandStatusList1[0], &s_EpCommandStatusList2[0] \ + } + +#else +#error "increase the instance count." +#endif + +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) +#if (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)) +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 1U +#elif ((USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511FS) && \ + (!USB_DEVICE_CONFIG_LPCIP3511HS)) +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 1U +#elif ((USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511HS) && \ + (!USB_DEVICE_CONFIG_LPCIP3511FS)) +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 1U +#else +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 0U +#endif + +#else +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 0U + +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) + +static inline uint8_t USB_DeviceLpcIp3511MaxPacketNeedCopy(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ +#if (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == (USB_DEVICE_CONFIG_LPCIP3511HS + USB_DEVICE_CONFIG_LPCIP3511FS)) + return 1U; +#elif (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511HS) + return (lpc3511IpState->controllerSpeed); +#elif (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511FS) +#if (defined USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS) + if (0U != lpc3511IpState->controllerSpeed) + { + return 0U; + } + else + { + return 1U; + } +#else + return 1U; +#endif +#endif +} + +static uint8_t *USB_DeviceLpcIp3511MallocMaxPacketBuffer(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + uint32_t multile64) +{ + uint32_t bitsIndex; + uint32_t numIndex; + OSA_SR_ALLOC(); + + multile64 = ((multile64 + 63U) / 64U); + bitsIndex = 0U; + OSA_ENTER_CRITICAL(); + do + { + numIndex = 0U; + for (; numIndex < multile64; ++numIndex) + { + if (bitsIndex >= USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER) + { + OSA_EXIT_CRITICAL(); + return NULL; /* fail */ + } + if (0U != (lpc3511IpState->epReservedBufferBits[(bitsIndex / 8U)] & + (uint8_t)(0x01U << (bitsIndex & 0x00000007U)))) /* has allocated */ + { + bitsIndex++; + break; + } + bitsIndex++; + } + } while (numIndex < multile64); + + if (numIndex >= multile64) + { + /* set the bits */ + for (numIndex = 0U; numIndex < multile64; ++numIndex) + { + lpc3511IpState->epReservedBufferBits[((bitsIndex - multile64 + numIndex) / 8U)] |= + (uint8_t)(0x01U << ((bitsIndex - multile64 + numIndex) & 0x00000007U)); + } + OSA_EXIT_CRITICAL(); + return lpc3511IpState->epReservedBuffer + ((bitsIndex - multile64) * 64U); + } + else + { + OSA_EXIT_CRITICAL(); + return NULL; + } +} + +static void USB_DeviceLpcIp3511ReleaseMaxPacketBuffer(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + uint8_t *buffer, + uint32_t bufferSize) +{ + uint32_t bitsIndex; + int32_t temp; + uint8_t bitsNum; + OSA_SR_ALLOC(); + + if ((buffer < lpc3511IpState->epReservedBuffer) || + (buffer >= (lpc3511IpState->epReservedBuffer + USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE))) + { + return; + } + /*misra 10.8*/ + temp = ((buffer - lpc3511IpState->epReservedBuffer) / 64); + bitsIndex = (uint32_t)temp; + + OSA_ENTER_CRITICAL(); + for (bitsNum = 0; bitsNum < ((bufferSize + 63U) / 64U); ++bitsNum) + { + lpc3511IpState->epReservedBufferBits[((bitsIndex + bitsNum) / 8U)] &= + (uint8_t)(~(0x01U << ((bitsIndex + bitsNum) & 0x00000007U))); /* clear the bit */ + } + OSA_EXIT_CRITICAL(); +} +#endif + +static usb_device_lpc3511ip_endpoint_state_struct_t *USB_DeviceLpc3511IpGetEndpointStateStruct( + usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t endpointIndex) +{ + if (endpointIndex <= ((uint32_t)USB_DEVICE_IP3511_ENDPOINTS_NUM * 2U)) + { + return &(lpc3511IpState->endpointState[endpointIndex]); + } + + return NULL; +} + +/*! + * @brief Write the command/status entry to start a transfer. + * + * The function is used to start a transfer by writing the command/status entry. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param endpoint Endpoint number. + * @param direction The direction of the endpoint, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address to save the received data, or the memory address to hold the data need to + * be sent. + * @param length The length of the data. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointPrime(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex, + uint8_t *buffer, + uint32_t length) +{ + uint8_t odd; + + OSA_SR_ALLOC(); + + /* Enter critical */ + OSA_ENTER_CRITICAL(); + + /* Flag the endpoint is busy. */ + epState->stateUnion.stateBitField.transferring = 1U; + + /* update the endpoint status */ + epState->transferPrimedLength += length; +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if ((endpointIndex >> 1U) != USB_ENDPOINT_CONTROL) + { + odd = (uint8_t)epState->stateUnion.stateBitField.producerOdd; + epState->stateUnion.stateBitField.doubleBufferBusy++; + epState->stateUnion.stateBitField.producerOdd ^= 1U; + } + else +#endif + { + odd = 0U; + } + epState->epBufferStatusUnion[odd].epBufferStatusField.transactionLength = (uint16_t)length; + + /* when receive the zero length packet, the controller will set 4 bytes buffer as 0x00 */ + if (buffer == NULL) + { + buffer = lpc3511IpState->zeroTransactionData; + } + + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, odd, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT) | + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK, + length, (uint32_t)buffer); + if (0U != (epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT))) + { + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); + } + /* Exit critical */ + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +#if 0 +/*! + * @brief Prime a next setup transfer. + * + * The function is used to prime a buffer in control out pipe to wait for receiving the host's setup packet. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpPrimeNextSetup(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, 0, 1, 0, 8, lpc3511IpState->setupData); +} +#endif + +/*! + * @brief reset ip3511. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpSetDefaultState(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + uint32_t index = 0; + uint8_t usbAddress; + usb_status_t error = kStatus_USB_Error; + /* zero the command/status list buffer and disable all endpoints */ + for (index = 0; index < 4U; ++index) + { + lpc3511IpState->epCommandStatusList[index] = 0x00000000U; + } + for (index = 4U; index < (uint32_t)USB_DEVICE_IP3511_ENDPOINTS_NUM * 4U; ++index) + { + lpc3511IpState->epCommandStatusList[index] = USB_LPC3511IP_ENDPOINT_DISABLE_MASK; + } + + /* set address as 0 */ + usbAddress = 0U; + error = USB_DeviceLpc3511IpControlPreSetDeviceAddress(lpc3511IpState, &usbAddress); + if (kStatus_USB_Success == error) + { + /*no action, just for misra4.7*/ + } + lpc3511IpState->registerBase->EPLISTSTART = (uint32_t)lpc3511IpState->epCommandStatusList; +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if (0U != lpc3511IpState->controllerSpeed) + { + if ((USBHSD_DATABUFSTART_DA_BUF_MASK & (uint32_t)lpc3511IpState->setupData) != + lpc3511IpState->registerBase->DATABUFSTART) + { + /* please use the dedicated ram */ + } + } + else +#endif + { + /* all data buffer is in the same 4M range with this setup data buffer */ + lpc3511IpState->registerBase->DATABUFSTART = (uint32_t)lpc3511IpState->setupData; + } + /* reset registers */ + lpc3511IpState->registerBase->EPINUSE = 0x0; + lpc3511IpState->registerBase->EPSKIP = 0x0; +/* enable all double-buffer */ +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + lpc3511IpState->registerBase->EPBUFCFG = USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK; +#else + lpc3511IpState->registerBase->EPBUFCFG = 0x00000000U; +#endif + /* clear interrupts + * don't clear DEV_INT because the vbus valid interrupt may occurs with keeping usb connected and reseting device. + */ + lpc3511IpState->registerBase->INTSTAT = + (USB_LPC3511IP_INTSTAT_FRAME_INT_MASK | USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK); + /* enable interrupts */ + lpc3511IpState->registerBase->INTEN = USB_LPC3511IP_INTSTAT_DEV_INT_MASK | USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK; + + /* Clear reset flag */ + lpc3511IpState->isResetting = 0U; +} + +/* Config and Enable endpoint */ +static usb_status_t USB_DeviceLpc3511IpEndpointInit(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_endpoint_init_struct_t *epInit) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(epInit->endpointAddress); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + uint16_t maxPacketSize = epInit->maxPacketSize; + uint32_t allocateLength; + + /* clear the endpoint status bits */ + epState->stateUnion.state = 0x00000000U; + lpc3511IpState->registerBase->EPINUSE &= (~((uint32_t)(0x01UL << endpointIndex))); + /* Save the max packet size of the endpoint */ + epState->stateUnion.stateBitField.maxPacketSize = maxPacketSize; + /* Set the ZLT field */ + epState->stateUnion.stateBitField.zlt = epInit->zlt; + epState->stateUnion.stateBitField.endpointType = epInit->transferType; + + /* get the endpoint default control value */ + if (USB_ENDPOINT_ISOCHRONOUS == epInit->transferType) + { + epState->stateUnion.stateBitField.epControlDefault = + (USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + } +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + else if ( +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + (0U == (lpc3511IpState->hsInterruptIssue)) && +#endif + (0U != lpc3511IpState->controllerSpeed) && (USB_ENDPOINT_INTERRUPT == epInit->transferType)) + { + epState->stateUnion.stateBitField.epControlDefault = + ((USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK | USB_LPC3511IP_ENDPOINT_RFTV_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + } +#endif +#endif + else + { + epState->stateUnion.stateBitField.epControlDefault = 0x00U; + } + /* set the command/status value */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, 0U, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT), 0U, 0U); + if ((epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK) == USB_CONTROL_ENDPOINT) + { + if (0U == (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)) + { + /* Prime setup packet when the endpoint is control out endpoint. */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, 0U, 1U, 0U, 0U, (uint32_t)lpc3511IpState->setupData); + } + } + else + { + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, 1U, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT), 0U, + 0U); + } + if ((endpointIndex >> 1) != USB_CONTROL_ENDPOINT) + { + /* toggle reset for the toggle */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + } + + epState->epPacketBuffer = NULL; + if ((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT) /* control endpoint */ + { + epState->epPacketBuffer = lpc3511IpState->controlData; + } +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) + else + { + if (0U != USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) + { +#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \ + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) + if ((USB_ENDPOINT_BULK == epInit->transferType) && ((endpointIndex & 0x01U) == 0x00U)) + { + allocateLength = USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX; + } + else + { + allocateLength = USB_LPC3511IP_GET_MULTIPLE_OF_64(maxPacketSize); + } +#else + allocateLength = USB_LPC3511IP_GET_MULTIPLE_OF_64(maxPacketSize); +#endif +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + allocateLength *= 2U; +#endif + uint8_t *maxPacketBuffer = USB_DeviceLpcIp3511MallocMaxPacketBuffer(lpc3511IpState, allocateLength); + if (maxPacketBuffer == NULL) + { + return kStatus_USB_AllocFail; + } + epState->epPacketBuffer = maxPacketBuffer; + } + } +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize a specified endpoint. + * + * The function is used to de-initialize a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be disabled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointDeinit(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t ep) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Cancel the transfer of the endpoint */ + (void)USB_DeviceLpc3511IpCancel(lpc3511IpState, ep); + +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) + if (0U != USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) + { + if ((endpointIndex >> 1U) != USB_CONTROL_ENDPOINT) /* control endpoint */ + { +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) +#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \ + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) + if ((USB_ENDPOINT_BULK == epState->stateUnion.stateBitField.endpointType) && + ((endpointIndex & 0x01U) == 0x00U)) + { + USB_DeviceLpcIp3511ReleaseMaxPacketBuffer( + lpc3511IpState, epState->epPacketBuffer, + USB_LPC3511IP_GET_MULTIPLE_OF_64(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX * 2U)); + } + else + { + USB_DeviceLpcIp3511ReleaseMaxPacketBuffer( + lpc3511IpState, epState->epPacketBuffer, + USB_LPC3511IP_GET_MULTIPLE_OF_64(epState->stateUnion.stateBitField.maxPacketSize) * 2U); + } +#else + USB_DeviceLpcIp3511ReleaseMaxPacketBuffer( + lpc3511IpState, epState->epPacketBuffer, + USB_LPC3511IP_GET_MULTIPLE_OF_64(epState->stateUnion.stateBitField.maxPacketSize) * 2U); +#endif +#else + USB_DeviceLpcIp3511ReleaseMaxPacketBuffer(lpc3511IpState, epState->epPacketBuffer, + epState->stateUnion.stateBitField.maxPacketSize); +#endif + } + epState->epPacketBuffer = NULL; + } +#endif + + /* reset the double buffer */ + lpc3511IpState->registerBase->EPINUSE &= ~((uint32_t)(0x01UL << endpointIndex)); + /* Disable the endpoint */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, endpointIndex, 0U, USB_LPC3511IP_ENDPOINT_DISABLE_MASK, 0U, 0U); + /* Clear the max packet size */ + epState->stateUnion.stateBitField.maxPacketSize = 0U; + + return kStatus_USB_Success; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointStall(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t ep) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Set endpoint stall flag. */ + epState->stateUnion.stateBitField.stalled = 1U; + /* lpc3511IpState->registerBase->EPINUSE &= (~(0x01u << endpointIndex)); */ + /* stall the endpoint */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, endpointIndex, 0U, USB_LPC3511IP_ENDPOINT_STALL_MASK, 0U, 0U); + if ((ep & USB_ENDPOINT_NUMBER_MASK) != USB_CONTROL_ENDPOINT) + { + /* toggle reset for the toggle */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, endpointIndex, 1U, USB_LPC3511IP_ENDPOINT_STALL_MASK, 0U, + 0U); + } +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) && \ + (!(defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))) +#else +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + if (0U != lpc3511IpState->hsInterruptIssue) + { +#endif + if ((0U != lpc3511IpState->controllerSpeed) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType)) + { + lpc3511IpState->registerBase->DEVCMDSTAT |= + (USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK | USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK); + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK | USB_LPC3511IP_ENDPOINT_RFTV_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); + } +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + } +#endif +#endif +#endif + + /* cancel the transfer in the endpoint */ + (void)USB_DeviceLpc3511IpCancel(lpc3511IpState, ep); + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointUnstall(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t ep) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Clear the endpoint stall state, the hardware resets the endpoint + * toggle to one for both directions when a setup token is received */ + epState->stateUnion.stateBitField.stalled = 0U; + + /* unstall the endpoint for double buffers */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND(lpc3511IpState, endpointIndex, 0, (~USB_LPC3511IP_ENDPOINT_STALL_MASK)); + if ((ep & USB_ENDPOINT_NUMBER_MASK) != USB_CONTROL_ENDPOINT) + { + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND(lpc3511IpState, endpointIndex, 1, (~USB_LPC3511IP_ENDPOINT_STALL_MASK)); + + /* toggle reset for the toggle */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) && \ + (!(defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))) +#else +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + if (0U != lpc3511IpState->hsInterruptIssue) + { +#endif + if ((0U != lpc3511IpState->controllerSpeed) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType)) + { + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK | USB_LPC3511IP_ENDPOINT_RFTV_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); + } +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + } +#endif +#endif +#endif + } + + if (0U != epState->stateUnion.stateBitField.stallPrimed) + { + epState->stateUnion.stateBitField.stallPrimed = 0u; + (void)USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); + } + /* cancel the transfer in the endpoint */ + (void)USB_DeviceLpc3511IpCancel(lpc3511IpState, ep); + return kStatus_USB_Success; +} + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpInterruptSuspend(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = (uint8_t)kUSB_DeviceNotifySuspend; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB suspend signal detected. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpInterruptResume(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = (uint8_t)kUSB_DeviceNotifyResume; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB suspend signal detected. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + + return kStatus_USB_Success; +} +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpInterruptLPMSleep(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = &lpc3511IpState->lpmRemoteWakeUp; + message.code = (uint8_t)kUSB_DeviceNotifyLPMSleep; + message.length = 0U; + message.isSetup = 0U; + + lpc3511IpState->lpmRemoteWakeUp = + (uint8_t)((lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK) >> + USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT); + + /* Notify up layer the USB suspend signal detected. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + + return kStatus_USB_Success; +} + +#endif +#endif + +/* need copy the data before the trasaction buffer is used again */ +static void USB_DeviceLpc3511IpDoPreviousTransactionMemcpy(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint32_t length, + uint8_t endpointIndex, + uint8_t odd) +{ + uint8_t *destBuffer; + uint8_t *sourceBuffer; + +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) + /*control out doesn't support buffer toggle*/ + if (0U == endpointIndex) + { + odd = 0u; + } +#if USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER + if ((0U != epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed) && (length > 0U) && + ((endpointIndex & 0x01U) == 0U)) +#else + if ((0U != USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) && + (0U != epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed) && (length > 0U) && + ((endpointIndex & 0x01U) == 0U)) +#endif +#else + /* control data buffer align is used */ + if (((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT) && + (epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed) && (length > 0U) && + ((endpointIndex & 0x01u) == 0U)) +#endif + { +#if ((defined(USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER)) && (USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER > 0U)) + destBuffer = &(epState->transferBuffer[epState->transferDone - length]); +#else + destBuffer = &(epState->transferBuffer[epState->transferDone]); +#endif +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) +#if (defined USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX) && \ + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX) + if ((USB_ENDPOINT_BULK == epState->stateUnion.stateBitField.endpointType) && ((endpointIndex & 0x01U) == 0x00U)) + { + sourceBuffer = epState->epPacketBuffer + odd * USB_LPC3511IP_GET_MULTIPLE_OF_64( + USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX); + } + else + { + sourceBuffer = epState->epPacketBuffer + + odd * USB_LPC3511IP_GET_MULTIPLE_OF_64(epState->stateUnion.stateBitField.maxPacketSize); + } +#else + sourceBuffer = epState->epPacketBuffer + + odd * USB_LPC3511IP_GET_MULTIPLE_OF_64(epState->stateUnion.stateBitField.maxPacketSize); +#endif +#else + sourceBuffer = epState->epPacketBuffer; +#endif + (void)memcpy(destBuffer, sourceBuffer, length); + } +} + +static uint32_t USB_DeviceLpc3511IpTokenUpdate(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex, + uint8_t changedOdd) +{ + uint32_t length; + uint8_t odd; + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if (0U != changedOdd) + { + odd = (uint8_t)epState->stateUnion.stateBitField.consumerOdd; + epState->stateUnion.stateBitField.consumerOdd ^= 1U; + epState->stateUnion.stateBitField.doubleBufferBusy--; + } + else +#endif + { + odd = 0U; + } + +/* for OUT packet, compute the actual packet size. */ +#if ((defined(FSL_FEATURE_USB_VERSION) && (FSL_FEATURE_USB_VERSION >= 200U)) || \ + (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U))) +#else + if ((endpointIndex & 0x01U) == 0x00u) /* OUT */ +#endif + { + /* get the transaction length */ + length = *(lpc3511IpState->epCommandStatusList + endpointIndex * 2U + odd); + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if (0U != lpc3511IpState->controllerSpeed) + { + length = + (length & USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_MASK) >> USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_SHIFT; + } + else +#endif + { + length = + (length & USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_MASK) >> USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT; + } + length = epState->epBufferStatusUnion[odd].epBufferStatusField.transactionLength - length; + } +#if ((defined(FSL_FEATURE_USB_VERSION) && (FSL_FEATURE_USB_VERSION >= 200U)) || \ + (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U))) +#else + else /* for IN packet, if there is no error, the packet lenght is the primed length. */ + { + /* don't judge the actual packet size */ + length = epState->epBufferStatusUnion[odd].epBufferStatusField.transactionLength; + } +#endif + +#if !((defined(USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER)) && (USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER > 0U)) + USB_DeviceLpc3511IpDoPreviousTransactionMemcpy(lpc3511IpState, epState, length, endpointIndex, odd); +#endif + /* update the transferred length */ + epState->transferDone += length; + + return length; +} + +static void USB_DeviceLpc3511IpInterruptToken(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + uint8_t endpointIndex, + uint8_t isSetup, + uint32_t errorStatus) +{ + usb_device_callback_message_struct_t message; + uint32_t length; + uint32_t remainLength; + usb_setup_struct_t *setupPacket; + void *temp; + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + uint32_t len = 0; +#endif + +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) && \ + (!(defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))) +#else +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + if (0U != lpc3511IpState->hsInterruptIssue) + { +#endif + if ((0U != (epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT))) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType) && + (0U != lpc3511IpState->controllerSpeed) && + (0U != (lpc3511IpState->epCommandStatusList[epState->stateUnion.stateBitField.consumerOdd + + (((uint32_t)endpointIndex) * 2U)] & + USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK))) + { + if (0U == (lpc3511IpState->registerBase->EPTOGGLE & ((uint32_t)(0x01UL << endpointIndex)))) + { + uint32_t index; + length = 0U; + for (index = 0U; index < ((uint32_t)USB_DEVICE_IP3511_ENDPOINTS_NUM) * 4U; ++index) + { + if ((0U != + (lpc3511IpState->epCommandStatusList[index] & USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK)) && + (USB_ENDPOINT_INTERRUPT == + lpc3511IpState->endpointState[index / 2U].stateUnion.stateBitField.endpointType)) + { + length++; + } + } + + if (length <= 1U) + { + lpc3511IpState->registerBase->DEVCMDSTAT &= + ~(USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK | USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK); + } + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + /* high-speed */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_RFTV_MASK | USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + (void)USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); +#endif + } + return; + } +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + } +#endif +#endif +#endif + + if ((0U == isSetup) && (0U == epState->stateUnion.stateBitField.transferring)) + { + return; + } + if (0U != isSetup) + { + message.length = 8U; + message.buffer = (lpc3511IpState->setupData); + /* clear the primed control transactions */ + if (0U != (epState->stateUnion.stateBitField.transferring)) + { + epState->stateUnion.stateBitField.transferring = 0U; + if (0U != (lpc3511IpState->epCommandStatusList[0] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK)) + { + (void)USB_DeviceLpc3511IpCancel(lpc3511IpState, USB_CONTROL_ENDPOINT); + } + } + if (0U != (lpc3511IpState->endpointState[1].stateUnion.stateBitField.transferring)) + { + lpc3511IpState->endpointState[1].stateUnion.stateBitField.transferring = 0U; + if (0U != (lpc3511IpState->epCommandStatusList[2] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK)) + { + (void)USB_DeviceLpc3511IpCancel(lpc3511IpState, (0x80u | USB_CONTROL_ENDPOINT)); + } + } + + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 0, 0, (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 1, 0, (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + + lpc3511IpState->registerBase->INTSTAT = 0x03u; /* clear interrupt */ + /* W1 to clear the setup flag */ + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK; + } + else + { + length = 0U; +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if (0U != (lpc3511IpState->epCommandStatusList[epState->stateUnion.stateBitField.consumerOdd + + (((uint32_t)endpointIndex) * 2U)] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK)) + { + return; + } +#else + if (0U != (lpc3511IpState->epCommandStatusList[endpointIndex * 2U] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK)) + { + return; + } +#endif + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if ((endpointIndex >> 1U) != USB_CONTROL_ENDPOINT) + { + len = USB_DeviceLpc3511IpTokenUpdate(lpc3511IpState, epState, endpointIndex, 1U); + length += len; + + if ((epState->stateUnion.stateBitField.doubleBufferBusy > 0U) && + (0U == (lpc3511IpState->epCommandStatusList[epState->stateUnion.stateBitField.consumerOdd + + (((uint32_t)endpointIndex) * 2U)] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))) + { +#if ((defined(USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER)) && (USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER > 0U)) + USB_DeviceLpc3511IpDoPreviousTransactionMemcpy( + lpc3511IpState, epState, len, endpointIndex, + (uint8_t)(epState->stateUnion.stateBitField.consumerOdd ^ 1U)); +#endif + len = USB_DeviceLpc3511IpTokenUpdate(lpc3511IpState, epState, endpointIndex, 1U); + length += len; + } + } + else +#endif + { + length = USB_DeviceLpc3511IpTokenUpdate(lpc3511IpState, epState, endpointIndex, 0U); + len = length; + } + + /* update remaining length */ + remainLength = epState->transferLength - epState->transferDone; + + /* Whether the transfer is completed or not. + * The transfer is completed when one of the following conditions meet: + * 1. The remaining length is zero. + * 2. The length of current tansaction is not the multiple of max packet size. + */ + if ((length > 0U) && (0U == (length % epState->stateUnion.stateBitField.maxPacketSize)) && (remainLength > 0U)) + { + (void)USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); +#if ((defined(USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER)) && (USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER > 0U)) + USB_DeviceLpc3511IpDoPreviousTransactionMemcpy( + lpc3511IpState, epState, len, endpointIndex, + (uint8_t)(epState->stateUnion.stateBitField.consumerOdd ^ 1U)); +#endif + return; + } + else + { + epState->stateUnion.stateBitField.transferring = 0U; + message.length = epState->transferDone; + message.buffer = epState->transferBuffer; + + /* process ZLT + * 1. IN endpoint; + * 2. transfer length is the multiple of max packet size. + */ + if ((0U != (endpointIndex & 0x01U)) && (0U != length) && + (0U == (length % epState->stateUnion.stateBitField.maxPacketSize))) + { + if ((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT) + { + temp = (void *)(&(lpc3511IpState->setupData[0])); + setupPacket = (usb_setup_struct_t *)temp; + /* + * Send ZLT transaction if setup transfer and the required length is longer than actual length + */ + if (USB_SHORT_FROM_LITTLE_ENDIAN(setupPacket->wLength) > epState->transferLength) + { + (void)USB_DeviceLpc3511IpEndpointPrime(lpc3511IpState, epState, 1U, NULL, 0U); + return; + } + } + else if ((0U != epState->stateUnion.stateBitField.zlt)) + { + (void)USB_DeviceLpc3511IpEndpointPrime(lpc3511IpState, epState, endpointIndex, NULL, 0U); + return; + } + else + { + /*no action*/ + } + } + } + } + + message.isSetup = isSetup; + message.code = ((uint8_t)(endpointIndex >> 1) | (uint8_t)(((endpointIndex & 0x01U) << 0x07U))); + +#if ((defined(USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER)) && (USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER > 0U)) + USB_DeviceLpc3511IpDoPreviousTransactionMemcpy(lpc3511IpState, epState, len, endpointIndex, + (uint8_t)(epState->stateUnion.stateBitField.consumerOdd ^ 1U)); +#endif + /* Notify the up layer the controller status changed. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} + +/*! + * @brief Handle the USB bus reset interrupt. + * + * The function is used to handle the USB bus reset interrupt. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpInterruptReset(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + /* Set reset flag */ + lpc3511IpState->isResetting = 1U; + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if (0U != lpc3511IpState->controllerSpeed) + { + if (((lpc3511IpState->registerBase->DEVCMDSTAT & USBHSD_DEVCMDSTAT_Speed_MASK) >> + USBHSD_DEVCMDSTAT_Speed_SHIFT) == 0x02U) + { + lpc3511IpState->deviceSpeed = USB_SPEED_HIGH; + } + else if (((lpc3511IpState->registerBase->DEVCMDSTAT & USBHSD_DEVCMDSTAT_Speed_MASK) >> + USBHSD_DEVCMDSTAT_Speed_SHIFT) == 0x01U) + { + lpc3511IpState->deviceSpeed = USB_SPEED_FULL; + } + else + { + /*no action*/ + } + } + else +#endif + { + lpc3511IpState->deviceSpeed = USB_SPEED_FULL; + } + + message.buffer = (uint8_t *)NULL; + message.code = (uint8_t)kUSB_DeviceNotifyBusReset; + message.length = 0U; + message.isSetup = 0U; + /* Notify up layer the USB bus reset signal detected. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE)) +/*! + * @brief Handle detach interrupt. + * + * The function is used to handle the detach interrupt. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpInterruptDetach(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = (uint8_t)kUSB_DeviceNotifyDetach; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB VBUS falling signal detected. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} + +/*! + * @brief Handle Attach interrupt. + * + * The function is used to handle the attach interrupt. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpInterruptAttach(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = (uint8_t)kUSB_DeviceNotifyAttach; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB VBUS rising signal detected. */ + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} +#endif +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +/* The device dcd callback */ +static usb_hsdcd_status_t USB_DeviceLpcIp3511IsrHSDCDCallback(void *handle, uint32_t event, void *param) +{ + usb_hsdcd_status_t error = kStatus_hsdcd_Success; + usb_device_callback_message_struct_t message; + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)handle; + + if (lpc3511IpState == NULL) + { + return kStatus_hsdcd_Error; + } + + /*messsgae buffer contain event information*/ + message.buffer = (uint8_t *)param; + message.length = 0U; + message.isSetup = 0U; + message.code = (uint8_t)kUSB_DeviceNotifyDcdDetectFinished; + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + return error; +} + +void USB_DeviceLpcIp3511IsrDCDFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_lpc3511ip_state_struct_t *lpc3511IpState; + if (NULL == deviceHandle) + { + return; + } + lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)(handle->controllerHandle); + USB_HSDcdIsrFunction(lpc3511IpState->dcdHandle); +} +#endif +usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = NULL; +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) + uint32_t ip3511FsBases[] = USB_BASE_ADDRS; +#endif + uint32_t *endpointListArray[] = LPC_CONTROLLER_ENDPOINT_LIST_ARRAY; + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + uint32_t hsdcd_base[] = USBHSDCD_BASE_ADDRS; + USBHSDCD_Type *base; + usb_hsdcd_config_struct_t dcdParamConfig; + usb_hsdcd_status_t dcdError = kStatus_hsdcd_Success; +#endif + + uint32_t ip3511HsBases[] = USBHSD_BASE_ADDRS; + if ((controllerId >= (uint8_t)kUSB_ControllerLpcIp3511Hs0) && + (controllerId <= (uint8_t)kUSB_ControllerLpcIp3511Hs1)) + { + if (((uint32_t)controllerId - (uint32_t)kUSB_ControllerLpcIp3511Hs0) >= + (sizeof(ip3511HsBases) / sizeof(uint32_t))) + { + return kStatus_USB_ControllerNotFound; + } + lpc3511IpState = &s_UsbDeviceLpc3511IpState[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0 + + USB_DEVICE_CONFIG_LPCIP3511FS]; + lpc3511IpState->controlData = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0 + + USB_DEVICE_CONFIG_LPCIP3511FS][CONTROL_TRANSFER_DATA_OFFSET]; + lpc3511IpState->setupData = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0 + + USB_DEVICE_CONFIG_LPCIP3511FS][SETUP_TRANSFER_DATA_OFFSET]; + lpc3511IpState->zeroTransactionData = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0 + + USB_DEVICE_CONFIG_LPCIP3511FS][ZERO_TRANSFER_DATA_OFFSET]; + /* set the endpoint list */ + lpc3511IpState->epCommandStatusList = + endpointListArray[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; + /* get the ip base address */ + lpc3511IpState->registerBase = + (USB_LPC3511IP_Type *)ip3511HsBases[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0]; +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + base = (USBHSDCD_Type *)hsdcd_base[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0]; + dcdParamConfig.dcdCallback = USB_DeviceLpcIp3511IsrHSDCDCallback; + dcdParamConfig.dcdCallbackParam = (void *)lpc3511IpState; + dcdError = USB_HSDCD_Init(base, &dcdParamConfig, &lpc3511IpState->dcdHandle); + if (kStatus_hsdcd_Success != dcdError) + { + return kStatus_USB_Error; + } +#endif + } + else +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) + { + /* get the controller instance */ + if ((controllerId < (uint8_t)kUSB_ControllerLpcIp3511Fs0) || + ((controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0) >= (uint8_t)USB_DEVICE_CONFIG_LPCIP3511FS) || + (((uint32_t)controllerId - (uint32_t)kUSB_ControllerLpcIp3511Fs0) >= + (sizeof(ip3511FsBases) / sizeof(uint32_t)))) + { + return kStatus_USB_ControllerNotFound; + } + lpc3511IpState = &s_UsbDeviceLpc3511IpState[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0]; + lpc3511IpState->controlData = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0] + [CONTROL_TRANSFER_DATA_OFFSET]; + lpc3511IpState->setupData = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0] + [SETUP_TRANSFER_DATA_OFFSET]; + lpc3511IpState->zeroTransactionData = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0] + [ZERO_TRANSFER_DATA_OFFSET]; + /* set the endpoint list */ + lpc3511IpState->epCommandStatusList = endpointListArray[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0]; + /* get the ip base address */ + lpc3511IpState->registerBase = + (USB_LPC3511IP_Type *)ip3511FsBases[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0]; + } +#else + { + return kStatus_USB_ControllerNotFound; + } +#endif + + lpc3511IpState->controllerId = controllerId; +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if ((lpc3511IpState->controllerId >= (uint8_t)kUSB_ControllerLpcIp3511Hs0) && + (lpc3511IpState->controllerId <= (uint8_t)kUSB_ControllerLpcIp3511Hs1)) + { + lpc3511IpState->controllerSpeed = 1U; +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + lpc3511IpState->hsInterruptIssue = ((Chip_GetVersion() == FSL_ROM_VERSION_1B) ? 0U : 1U); +#endif + } + else + { + lpc3511IpState->controllerSpeed = 0U; + } +#endif + +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) + /* this controller need max packet buffer copy */ + if (0U != USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) + { +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + /* fix coverity and misra 14.3 */ + if (controllerId >= (uint8_t)kUSB_ControllerLpcIp3511Hs0) + { +#if (USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER) + /* for allocating the max packet buffer */ + lpc3511IpState->epReservedBuffer = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0 + + USB_DEVICE_CONFIG_LPCIP3511FS][RESERVED_EP_DATA_OFFSET]; +#else + lpc3511IpState->epReservedBuffer = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0] + [RESERVED_EP_DATA_OFFSET]; +#endif + } + else +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) + { + lpc3511IpState->epReservedBuffer = + (uint8_t *)&s_SetupAndEpReservedData[controllerId - (uint8_t)kUSB_ControllerLpcIp3511Fs0] + [RESERVED_EP_DATA_OFFSET]; + } +#else + { + /* no action */ + } +#endif + } + for (controllerId = 0; controllerId < ((USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER + 7U) / 8U); ++controllerId) + { + lpc3511IpState->epReservedBufferBits[controllerId] = 0U; + } +#endif + + /* disable the controller */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + (~(USB_LPC3511IP_DEVCMDSTAT_DCON_MASK | USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK | + USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK)); + /* reset and enalbe the controller */ + USB_DeviceLpc3511IpSetDefaultState(lpc3511IpState); + /* enable USB */ + lpc3511IpState->registerBase->DEVCMDSTAT |= (USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#else + | USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK +#endif + ); +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK; + lpc3511IpState->registerBase->LPM |= USB_LPC3511IP_USB_LPM_HIRD_SW(4); + lpc3511IpState->registerBase->DEVCMDSTAT &= ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK); +#endif + lpc3511IpState->deviceHandle = handle; + *controllerHandle = lpc3511IpState; + + return kStatus_USB_Success; +} + +usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + uint32_t usbAddress; + usb_status_t status = kStatus_USB_Success; + if (controllerHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + /* Clear all interrupt flags. */ + lpc3511IpState->registerBase->INTSTAT = (USB_LPC3511IP_INTSTAT_DEV_INT_MASK | USB_LPC3511IP_INTSTAT_FRAME_INT_MASK | + USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK); + /* Disable all interrupts. */ + lpc3511IpState->registerBase->INTEN = 0U; + /* Clear device address. */ + usbAddress = 0U; + status = USB_DeviceLpc3511IpControlPreSetDeviceAddress(controllerHandle, &usbAddress); + if (kStatus_USB_Success == status) + { + /*no action, just for misra4.7*/ + } +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + lpc3511IpState->registerBase->DEVCMDSTAT &= ~USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK; +#endif + /* disable the controller */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + (~(USB_LPC3511IP_DEVCMDSTAT_DCON_MASK | USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK | + USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK)); +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + (void)USB_HSDCD_Deinit(lpc3511IpState->dcdHandle); +#endif + + return status; +} + +static usb_status_t USB_DeviceLpc3511IpGetActualBufferAndPrime(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex, + uint8_t changedOdd) +{ + uint8_t *destBuffer; + uint8_t *actualBuffer; + uint32_t length; + uint8_t odd; + uint8_t index; + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if (0U != changedOdd) + { + odd = (uint8_t)epState->stateUnion.stateBitField.producerOdd; + } + else +#endif + { + odd = 0; + } + actualBuffer = epState->transferBuffer + epState->transferPrimedLength; + length = epState->transferLength - epState->transferPrimedLength; + /* Data length needs to less than max packet size. */ +#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \ + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) + if ((USB_ENDPOINT_BULK == epState->stateUnion.stateBitField.endpointType) && ((endpointIndex & 0x01U) == 0x00U)) + { + if (length > USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX) + { + length = USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX; + } + } + else + { + if (length > epState->stateUnion.stateBitField.maxPacketSize) + { + length = epState->stateUnion.stateBitField.maxPacketSize; + } + } +#else + if (length > epState->stateUnion.stateBitField.maxPacketSize) + { + length = epState->stateUnion.stateBitField.maxPacketSize; + } +#endif + + epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed = 0; + + index = (endpointIndex & 0x01u); /* index mean IN endpoint here */ + if (length > 0U) + { +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) +/* if all the enabled IP support the reserved buffer, then don't need the judgement. */ +#if (!USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER) +#define USB_DEVICE_IP3511_NEED_CHECK_BUFFER (1u) + /* lengt > 0 && ((buffer not align with 64) || (buffer is not in the deticated ram))) */ + if (USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) +#endif +#else +#define USB_DEVICE_IP3511_NEED_CHECK_BUFFER (1u) + /* align the buffer for control transfer */ + if (((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT)) +#endif + { +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if ((defined(FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) && (FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) + uint32_t bufferValue = (uint32_t)actualBuffer; +#if ((defined(__SAUREGION_PRESENT)) && (__SAUREGION_PRESENT > 0U)) + bufferValue &= (0xEFFFFFFFu); /* bit28 is the secure address label */ +#endif +#endif +#endif + /* not 64 bytes align || not in the dedicated ram || ( OUT && not mutiple of 4 ) */ + if ((((uint32_t)actualBuffer & 0x0000003FU) != 0U) || +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if ((defined(FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) && (FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) + ( +#endif +#endif + (((uint32_t)actualBuffer & 0xFFC00000U) != + (lpc3511IpState->registerBase->DATABUFSTART & 0xFFC00000U)) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if ((defined(FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) && (FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) + + || ((0U != lpc3511IpState->controllerSpeed) && + ((bufferValue < (uint32_t)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS) || + (bufferValue > + ((uint32_t)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS + (uint32_t)FSL_FEATURE_USBHSD_USB_RAM)))) +#endif +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if ((defined(FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) && (FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)) + ) +#endif +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ((0U != lpc3511IpState->controllerSpeed) && (0U == index) && + (length != epState->stateUnion.stateBitField.maxPacketSize))) +#else + ) +#endif + { + epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed = 1U; +/* usb copy buffer for this packet */ +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) +#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \ + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) + if ((USB_ENDPOINT_BULK == epState->stateUnion.stateBitField.endpointType) && + ((endpointIndex & 0x01U) == 0x00U)) + { + destBuffer = (uint8_t *)(epState->epPacketBuffer + + (odd * USB_LPC3511IP_GET_MULTIPLE_OF_64( + USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX))); + } + else + { + destBuffer = (uint8_t *)(epState->epPacketBuffer + + (odd * USB_LPC3511IP_GET_MULTIPLE_OF_64( + epState->stateUnion.stateBitField.maxPacketSize))); + } +#else + destBuffer = + (uint8_t *)(epState->epPacketBuffer + (odd * USB_LPC3511IP_GET_MULTIPLE_OF_64( + epState->stateUnion.stateBitField.maxPacketSize))); +#endif +#else + destBuffer = (uint8_t *)(epState->epPacketBuffer); +#endif + if (0U != index) /* USB_IN */ + { + (void)memcpy(destBuffer, actualBuffer, length); + } + else + { +#if ((defined(FSL_FEATURE_USB_VERSION) && (FSL_FEATURE_USB_VERSION >= 200U)) || \ + (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U))) +#else +#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && \ + (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) + if (length < epState->stateUnion.stateBitField.maxPacketSize) + { + length = epState->stateUnion.stateBitField.maxPacketSize; + } + else + { + length = ((length + epState->stateUnion.stateBitField.maxPacketSize - 1) / + epState->stateUnion.stateBitField.maxPacketSize) * + (epState->stateUnion.stateBitField.maxPacketSize); + } +#else + length = epState->stateUnion.stateBitField.maxPacketSize; +#endif +#endif + } + actualBuffer = destBuffer; + } + } +#if (defined USB_DEVICE_IP3511_NEED_CHECK_BUFFER) && (USB_DEVICE_IP3511_NEED_CHECK_BUFFER) + else /* cannot do memory copy */ + { + /* not 64 bytes align || not in the dedicated ram || ( OUT && HS && not mutiple of 4 ) */ + if ((((uint32_t)actualBuffer & 0x0000003FU) != 0U) || + (((uint32_t)actualBuffer & 0xFFC00000U) != (lpc3511IpState->registerBase->DATABUFSTART & 0xFFC00000U)) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ((0U != lpc3511IpState->controllerSpeed) && (0U == index) && ((length & 0x00000003u) != 0U))) +#else + ) +#endif + { + return kStatus_USB_Error; + } + } +#endif + } + + /* Send/Receive data when the device is not resetting. */ + if (0U == lpc3511IpState->isResetting) + { + return USB_DeviceLpc3511IpEndpointPrime(lpc3511IpState, epState, endpointIndex, actualBuffer, length); + } + else + { + return kStatus_USB_Error; + } +} +static usb_status_t USB_DeviceLpc3511IpTransaction(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex) +{ + usb_status_t status = kStatus_USB_Error; + OSA_SR_ALLOC(); + +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) && \ + (!(defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))) +#else +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + if (lpc3511IpState->hsInterruptIssue) + { +#endif + /* high-speed */ + if ((0U != (epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT))) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType) && + (0U != lpc3511IpState->controllerSpeed)) + { + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + OSA_ENTER_CRITICAL(); + + lpc3511IpState->registerBase->DEVCMDSTAT |= + (USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK | USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK); + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, epState->stateUnion.stateBitField.producerOdd, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT) | + (epState->stateUnion.stateBitField.stalled << USB_LPC3511IP_ENDPOINT_STALL_SHIFT), + 0U, (uint32_t)lpc3511IpState->zeroTransactionData); +#else + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, 0, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT) | + (epState->stateUnion.stateBitField.stalled << USB_LPC3511IP_ENDPOINT_STALL_SHIFT), + 0U, (uint32_t)lpc3511IpState->zeroTransactionData); +#endif + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + } +#endif +#endif +#endif + + /* Enter critical */ + OSA_ENTER_CRITICAL(); + if (0U != epState->stateUnion.stateBitField.stalled) + { + if ((endpointIndex >> 1U) != USB_ENDPOINT_CONTROL) + { + epState->stateUnion.stateBitField.stallPrimed = 1u; + status = kStatus_USB_Success; + } + status = kStatus_USB_Error; + OSA_EXIT_CRITICAL(); + return status; + } + OSA_EXIT_CRITICAL(); + + /* 1. transfer size is 0; 2. All are primed */ + if ((epState->transferLength <= epState->transferPrimedLength) && (epState->transferLength != 0U)) + { + return kStatus_USB_Success; + } +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if ((endpointIndex >> 1U) != USB_CONTROL_ENDPOINT) + { + /* disable endpoint interrupts, users can use NVIC to disable/enable the USB interrupt to improve the system + * performance */ + OSA_ENTER_CRITICAL(); + /* lpc3511IpState->registerBase->INTEN &= (uint32_t)(~(USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK)); */ +#if ((defined(USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER)) && (USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER > 0U)) + /* for out endpoint,only use buffer toggle, disable prime double buffer at the same time*/ + /*host send data less than maxpacket size and in endpoint prime length more more than maxpacketsize, there will + * be state mismtach*/ + if (0U == (endpointIndex & 0x1U)) + { + status = USB_DeviceLpc3511IpGetActualBufferAndPrime(lpc3511IpState, epState, endpointIndex, 1U); + } + else +#endif + { + do + { + status = USB_DeviceLpc3511IpGetActualBufferAndPrime(lpc3511IpState, epState, endpointIndex, 1U); + if (status != kStatus_USB_Success) + { + break; + } + } while ((epState->transferLength > epState->transferPrimedLength) && + (epState->stateUnion.stateBitField.doubleBufferBusy < 2U)); + } + /* enable endpoint interrupt again, users can use NVIC to disable/enable the USB interrupt to improve the system + * performance */ + OSA_EXIT_CRITICAL(); + } + else +#endif + { + status = USB_DeviceLpc3511IpGetActualBufferAndPrime(lpc3511IpState, epState, endpointIndex, 0U); + } + return status; +} + +usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(endpointAddress); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + if (1U == epState->stateUnion.stateBitField.transferring) + { + return kStatus_USB_Error; + } + + /* Save the transfer information */ + epState->transferDone = 0U; + epState->transferBuffer = buffer; + epState->transferLength = length; + epState->transferPrimedLength = 0U; + + return USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); + +/* prime the control setup transfer if it is control in endpoint and data length is zero + * For IP3511 there is no need to prime, the buffer is always in the command/status list + */ +#if 0 + if ((0U == length) && (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_DeviceLpc3511IpPrimeNextSetup(lpc3511IpState); + } +#endif +} + +usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + return USB_DeviceLpc3511IpSend(controllerHandle, endpointAddress, buffer, length); +} + +usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep) +{ + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + OSA_SR_ALLOC(); + + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + usb_device_callback_message_struct_t message; + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* disable endpoint interrupts, users can use NVIC to disable/enable the USB interrupt to improve the system + * performance */ + OSA_ENTER_CRITICAL(); + /* Cancel the transfer and notify the up layer when the endpoint is busy. */ + if ((0U != epState->stateUnion.stateBitField.transferring) +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) && \ + (!(defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))) +#else +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ( +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + (0U != lpc3511IpState->hsInterruptIssue) && +#endif + (0U != (epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT))) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType) && + (0U != lpc3511IpState->controllerSpeed) && + (0U != (lpc3511IpState->epCommandStatusList[epState->stateUnion.stateBitField.consumerOdd + + (((uint32_t)endpointIndex) * 2U)] & + USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK)) && + (0U == (lpc3511IpState->registerBase->EPTOGGLE & ((uint32_t)(0x01UL << endpointIndex))))) +#endif +#endif + ) + { +#if (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U)) && \ + (!(defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK))) +#else +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + if (0U != lpc3511IpState->hsInterruptIssue) + { +#endif + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + } +#endif +#endif +#endif + if ((((lpc3511IpState->epCommandStatusList[(uint32_t)endpointIndex * 2U] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) != 0U) && + ((lpc3511IpState->epCommandStatusList[(uint32_t)endpointIndex * 2U] & + USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) != 0U)) || + (((lpc3511IpState->epCommandStatusList[(uint32_t)endpointIndex * 2U + 1U] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) != 0U) && + ((lpc3511IpState->epCommandStatusList[(uint32_t)endpointIndex * 2U + 1U] & + USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) != 0U))) + { + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + } + + if ((lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DCON_MASK) != 0U) + { + while (1U == 1U) + { + if ((lpc3511IpState->epCommandStatusList[(uint32_t)endpointIndex * 2U + + ((lpc3511IpState->registerBase->EPINUSE & + (((uint32_t)0x00000001U << endpointIndex))) >> + endpointIndex)] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) != 0U) + { + /* cancel the transfer in the endpoint command/status */ + lpc3511IpState->registerBase->EPSKIP |= ((uint32_t)0x00000001U << endpointIndex); + while (((lpc3511IpState->registerBase->EPSKIP & ((uint32_t)0x00000001U << endpointIndex)) != 0U) && + ((lpc3511IpState->epCommandStatusList[(uint32_t)endpointIndex * 2U + + ((lpc3511IpState->registerBase->EPINUSE & + (((uint32_t)0x00000001U << endpointIndex))) >> + endpointIndex)] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) != 0U)) + { + } + if ((lpc3511IpState->registerBase->EPSKIP & ((uint32_t)0x00000001U << endpointIndex)) != 0U) + { + lpc3511IpState->registerBase->EPSKIP &= (~((uint32_t)0x00000001U << endpointIndex)); + } + } + + if (((lpc3511IpState->epCommandStatusList[endpointIndex * 2U] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) != + 0U) || + ((lpc3511IpState->epCommandStatusList[endpointIndex * 2U + 1U] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) != 0U)) + { + if ((lpc3511IpState->registerBase->EPINUSE & (((uint32_t)0x00000001U << endpointIndex))) != 0U) + { + lpc3511IpState->registerBase->EPINUSE &= ~((uint32_t)0x00000001U << endpointIndex); + } + else + { + lpc3511IpState->registerBase->EPINUSE |= ((uint32_t)0x00000001U << endpointIndex); + } + } + else + { + break; + } + } + } + else + { + /* Make sure the device is detached from host, host will not send any transaction to device. + * Then the endpoint status entry can be modified directly by software. + */ + lpc3511IpState->epCommandStatusList[endpointIndex * 2U] = USB_LPC3511IP_ENDPOINT_DISABLE_MASK; + lpc3511IpState->epCommandStatusList[endpointIndex * 2U + 1U] = USB_LPC3511IP_ENDPOINT_DISABLE_MASK; + } + + epState->stateUnion.stateBitField.transferring = 0U; + epState->stateUnion.stateBitField.producerOdd = + ((lpc3511IpState->registerBase->EPINUSE & ((uint32_t)((uint32_t)0x00000001U << endpointIndex))) >> + endpointIndex); + epState->stateUnion.stateBitField.consumerOdd = + ((lpc3511IpState->registerBase->EPINUSE & ((uint32_t)((uint32_t)0x00000001U << endpointIndex))) >> + endpointIndex); + epState->stateUnion.stateBitField.doubleBufferBusy = 0U; + /* clear interrupt status, enable endpoint interrupt again */ + lpc3511IpState->registerBase->INTSTAT = ((uint32_t)0x00000001U << endpointIndex); + + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + OSA_EXIT_CRITICAL(); + + message.length = USB_CANCELLED_TRANSFER_LENGTH; + message.buffer = epState->transferBuffer; + message.code = ep; + message.isSetup = 0U; + (void)USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + } + else + { + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + OSA_EXIT_CRITICAL(); + } + return kStatus_USB_Success; +} + +/*seperate this function from USB_DeviceLpc3511IpControl for misra17.2 recursive */ +static usb_status_t USB_DeviceLpc3511IpControlPreSetDeviceAddress(usb_device_controller_handle controllerHandle, + void *param) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + usb_status_t error = kStatus_USB_Error; + uint32_t tmp32Value; + uint8_t tmp8Value; + if (NULL != param) + { + tmp8Value = *((uint8_t *)param); + tmp32Value = lpc3511IpState->registerBase->DEVCMDSTAT; + tmp32Value &= (~USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK); + tmp32Value |= ((uint32_t)tmp8Value & USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK); + lpc3511IpState->registerBase->DEVCMDSTAT = tmp32Value; + error = kStatus_USB_Success; + } + return error; +} + +usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle, + usb_device_control_type_t type, + void *param) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + usb_status_t error = kStatus_USB_Error; + uint32_t tmp32Value; + uint8_t tmp8Value; +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) + uint32_t *tmp32Pointer; +#endif + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; +#endif + usb_device_lpc3511ip_endpoint_state_struct_t *epState; + + if (controllerHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + deviceHandle = (usb_device_struct_t *)lpc3511IpState->deviceHandle; +#endif + + switch (type) + { + case kUSB_DeviceControlRun: + lpc3511IpState->registerBase->DEVCMDSTAT |= (USB_LPC3511IP_DEVCMDSTAT_DCON_MASK); + lpc3511IpState->registerBase->DEVCMDSTAT &= ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK); + break; + + case kUSB_DeviceControlStop: + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK; + lpc3511IpState->registerBase->DEVCMDSTAT &= (~USB_LPC3511IP_DEVCMDSTAT_DCON_MASK); + break; + + case kUSB_DeviceControlEndpointInit: + if (NULL != param) + { + error = USB_DeviceLpc3511IpEndpointInit(lpc3511IpState, (usb_device_endpoint_init_struct_t *)param); + } + break; + + case kUSB_DeviceControlEndpointDeinit: + if (NULL != param) + { + tmp8Value = *((uint8_t *)param); + error = USB_DeviceLpc3511IpEndpointDeinit(lpc3511IpState, tmp8Value); + } + break; + + case kUSB_DeviceControlEndpointStall: + if (NULL != param) + { + tmp8Value = *((uint8_t *)param); + error = USB_DeviceLpc3511IpEndpointStall(lpc3511IpState, tmp8Value); + } + break; + + case kUSB_DeviceControlEndpointUnstall: + if (NULL != param) + { + tmp8Value = *((uint8_t *)param); + error = USB_DeviceLpc3511IpEndpointUnstall(lpc3511IpState, tmp8Value); + } + break; + + case kUSB_DeviceControlGetDeviceStatus: + if (NULL != param) + { + *((uint16_t *)param) = + (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT)) +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + | ((uint16_t)(((uint32_t)deviceHandle->remotewakeup) + << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT))) +#endif + ; + error = kStatus_USB_Success; + } + break; + + case kUSB_DeviceControlGetEndpointStatus: + if (NULL != param) + { + usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param; + + if ((((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK)) < + (uint8_t)USB_DEVICE_IP3511_ENDPOINTS_NUM) + { + epState = USB_DeviceLpc3511IpGetEndpointStateStruct( + lpc3511IpState, USB_LPC3511IP_ENDPOINT_DES_INDEX(endpointStatus->endpointAddress)); + endpointStatus->endpointStatus = + (uint16_t)((epState->stateUnion.stateBitField.stalled == 1U) ? kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle); + error = kStatus_USB_Success; + } + } + break; + + case kUSB_DeviceControlPreSetDeviceAddress: + error = USB_DeviceLpc3511IpControlPreSetDeviceAddress(controllerHandle, param); + if (kStatus_USB_Success == error) + { + /*no action, just for misra4.7*/ + } + break; + + case kUSB_DeviceControlSetDeviceAddress: + error = kStatus_USB_Success; + break; + + case kUSB_DeviceControlGetSynchFrame: + break; + +#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U) + case kUSB_DeviceControlResume: + /* todo: turn on USB clock and enable the USB clock source */ + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK; + lpc3511IpState->registerBase->DEVCMDSTAT &= ~USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK; + while (0U != (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK)) + { + } + /* the W1C bits */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK | USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK); + error = kStatus_USB_Success; + break; +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + case kUSB_DeviceControlSleepResume: + /* todo: turn on USB clock and enable the USB clock source */ + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK; + lpc3511IpState->registerBase->DEVCMDSTAT &= ~USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK; + while (0U != (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK)) + { + __NOP(); + } + /* the W1C bits */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK | USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK); + error = kStatus_USB_Success; + break; +#endif + case kUSB_DeviceControlGetRemoteWakeUp: + *((uint8_t *)param) = + (uint8_t)((lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK) >> + USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT); + break; +#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */ + + case kUSB_DeviceControlSetDefaultStatus: + for (tmp32Value = 0U; tmp32Value < (uint32_t)USB_DEVICE_IP3511_ENDPOINTS_NUM; tmp32Value++) + { + (void)USB_DeviceLpc3511IpEndpointDeinit(lpc3511IpState, (uint8_t)(tmp32Value | (USB_IN << 0x07U))); + (void)USB_DeviceLpc3511IpEndpointDeinit(lpc3511IpState, (uint8_t)(tmp32Value | (USB_OUT << 0x07U))); + } + USB_DeviceLpc3511IpSetDefaultState(lpc3511IpState); + error = kStatus_USB_Success; + break; + + case kUSB_DeviceControlGetSpeed: + if (NULL != param) + { + *((uint8_t *)param) = lpc3511IpState->deviceSpeed; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetOtgStatus: + break; + case kUSB_DeviceControlSetOtgStatus: + break; +#if (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceControlSetTestMode: + if (NULL != param) + { + tmp8Value = *((uint8_t *)param); +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + lpc3511IpState->registerBase->DEVCMDSTAT |= + ((uint32_t)(tmp8Value) << USBHSD_DEVCMDSTAT_PHY_TEST_MODE_SHIFT); +#endif + error = kStatus_USB_Success; + } + break; +#endif +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + case kUSB_DeviceControlDcdEnable: + if (kStatus_hsdcd_Success == USB_HSDCD_Control(lpc3511IpState->dcdHandle, kUSB_DeviceHSDcdEnable, NULL)) + { + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlDcdDisable: + if (kStatus_hsdcd_Success == USB_HSDCD_Control(lpc3511IpState->dcdHandle, kUSB_DeviceHSDcdDisable, NULL)) + { + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlUpdateHwTick: + /*udpate 1ms time tick*/ + error = kStatus_USB_Success; + break; + +#endif +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) + case kUSB_DeviceControlGetCurrentFrameCount: + if (NULL != param) + { + tmp32Pointer = (uint32_t *)param; + if (USB_SPEED_HIGH == lpc3511IpState->deviceSpeed) /* if high speed, change to use microframe count */ + { + *tmp32Pointer = + ((uint32_t)(((lpc3511IpState->registerBase->INFO >> USB_LPC3511IP_INFO_FRAME_NR_SHIFT) & + USB_LPC3511IP_INFO_FRAME_NR_MASK) & + (USB_DEVICE_MAX_FRAME_COUNT))) * + 8U; + } + else + { + *tmp32Pointer = + ((uint32_t)(((lpc3511IpState->registerBase->INFO >> USB_LPC3511IP_INFO_FRAME_NR_SHIFT) & + USB_LPC3511IP_INFO_FRAME_NR_MASK) & + (USB_DEVICE_MAX_FRAME_COUNT))); + } + error = kStatus_USB_Success; + } + break; +#endif + default: + /*no action*/ + break; + } + + return error; +} + +void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_lpc3511ip_state_struct_t *lpc3511IpState; + uint32_t interruptStatus; + uint32_t usbErrorCode; + uint32_t devState; + + if (NULL == deviceHandle) + { + return; + } + + lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)(handle->controllerHandle); + /* get and clear interrupt status */ + interruptStatus = lpc3511IpState->registerBase->INTSTAT; + lpc3511IpState->registerBase->INTSTAT = interruptStatus; + interruptStatus &= lpc3511IpState->registerBase->INTEN; + + usbErrorCode = (lpc3511IpState->registerBase->INFO & USB_LPC3511IP_INFO_ERR_CODE_MASK); + + /* device status change interrupt */ + if (0U != (interruptStatus & USB_LPC3511IP_INTSTAT_DEV_INT_MASK)) + { + /* get and clear device state change status */ + devState = lpc3511IpState->registerBase->DEVCMDSTAT; + devState &= ~(USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK); + lpc3511IpState->registerBase->DEVCMDSTAT = (devState | USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK); + + /* For HS: there is interrupt with DEV_INT=1, OTG_C=1 and ADPPROBE=1 when vbus rising. + * For FS: there is no interrupt when vbus rising. The only way is: check the VBUS_DEBOUNCED in the DRES_C + * interrupt with DCON set. + */ +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE)) + if ((0U == lpc3511IpState->deviceState) && + ((0U != (devState & USB_LPC3511IP_DEVCMDSTAT_VBUS_DEBOUNCED_MASK)) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ((0U != (lpc3511IpState->registerBase->LPM & USB_LPC3511IP_USB_LPM_ADPPROBE_MASK)) && + (1U == lpc3511IpState->controllerSpeed)) +#endif + )) + { +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if ((defined(USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT)) && \ + (USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT > 0U)) + /* add one little debounce for HS's attach detection because ADPPROBE is undebounced value */ + uint32_t debounceCount = USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT; + if (1U == lpc3511IpState->controllerSpeed) + { + while ((0U != debounceCount) && (0U == (devState & USB_LPC3511IP_DEVCMDSTAT_VBUS_DEBOUNCED_MASK))) + { + if (0U == (lpc3511IpState->registerBase->LPM & USB_LPC3511IP_USB_LPM_ADPPROBE_MASK)) + { + break; + } + debounceCount--; + } + } + + if ((debounceCount == 0U) || (0U != (devState & USB_LPC3511IP_DEVCMDSTAT_VBUS_DEBOUNCED_MASK))) +#endif +#endif + { + lpc3511IpState->deviceState = 1U; + USB_DeviceLpc3511IpInterruptAttach(lpc3511IpState); +#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \ + (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) + (void)USB_HSDCD_Control(lpc3511IpState->dcdHandle, kUSB_DeviceHSDcdRun, NULL); +#endif + } + } + /* For HS: there is interrupt with DEV_INT=1, OTG_C=1 and ADPPROBE=0 when vbus falling. + * For HS and FS: there is interrupt when vbus falling if DCON is set. + */ + else if ((1U == lpc3511IpState->deviceState) && + (((0U != (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DCON_MASK)) && + (0U == (devState & USB_LPC3511IP_DEVCMDSTAT_VBUS_DEBOUNCED_MASK))) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ((0U == (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DCON_MASK)) && + (0U == (lpc3511IpState->registerBase->LPM & USB_LPC3511IP_USB_LPM_ADPPROBE_MASK)) && + (1U == lpc3511IpState->controllerSpeed)) +#endif + )) + { +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) +#if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U)) +#if ((defined USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE) && (USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE > 0U)) + uint32_t delay = 100000U; +#endif +#endif +#endif + lpc3511IpState->deviceState = 0U; +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) +#if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U)) +#if ((defined USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE) && (USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE > 0U)) + /* wait at least 125us to let the host to detect the detach */ + USB_PhyDeviceForceEnterFSMode(lpc3511IpState->controllerId, 1); + while (delay--) + { + __NOP(); + } + USB_PhyDeviceForceEnterFSMode(lpc3511IpState->controllerId, 0); +#endif +#endif +#endif + USB_DeviceLpc3511IpInterruptDetach(lpc3511IpState); + } + else + { + /*no action*/ + } +#endif + + /* reset change */ + if (0U != (devState & USB_LPC3511IP_DEVCMDSTAT_DRES_C_MASK)) + { + USB_DeviceLpc3511IpInterruptReset(lpc3511IpState); + } + +/* Suspend/Resume */ +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + if (0U != (devState & USB_LPC3511IP_DEVCMDSTAT_DSUS_C_MASK)) + { + if (0U != (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK)) + { + (void)USB_DeviceLpc3511IpInterruptSuspend(lpc3511IpState); + } +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + else if (0U != (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK)) + { + (void)USB_DeviceLpc3511IpInterruptLPMSleep(lpc3511IpState); + } +#endif + else + { + (void)USB_DeviceLpc3511IpInterruptResume(lpc3511IpState); + } + } + +#endif + +#if 0U /* some soc don't support this bit, need check according to the feature macro */ + /* OTG Status change */ + if (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_OTG_C_MASK) + { + } +#endif + } + + /* endpoint transfers interrupt */ + if (0U != (interruptStatus & USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK)) + { + devState = 0; /* devState means index here */ + if (0U != (interruptStatus & 0x01U)) /* control OUT */ + { + if (0U != (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK)) + { + devState = 2U; + if ((lpc3511IpState->endpointState[0].stateUnion.stateBitField.stalled == 1U) || + (lpc3511IpState->endpointState[1].stateUnion.stateBitField.stalled == 1U)) + { + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 0, 0, + (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 1, 0, + (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + lpc3511IpState->endpointState[0].stateUnion.stateBitField.stalled = 0U; + lpc3511IpState->endpointState[1].stateUnion.stateBitField.stalled = 0U; + } + + /* todo: setup token interrupt */ + USB_DeviceLpc3511IpInterruptToken(lpc3511IpState, 0U, 1, usbErrorCode); + } + } + + for (; devState < ((uint32_t)USB_DEVICE_IP3511_ENDPOINTS_NUM * 2U); ++devState) + { + /* check the endpoint interrupt */ + if (0U != (interruptStatus & (0x01UL << devState))) + { + USB_DeviceLpc3511IpInterruptToken(lpc3511IpState, (uint8_t)devState, 0U, usbErrorCode); + } + } + } + +#if 0U + if (interruptStatus & USB_LPC3511IP_INTSTAT_FRAME_INT_MASK) + { + } +#endif +} + +#endif diff --git a/usb/device/source/lpcip3511/usb_device_lpcip3511.h b/usb/device/source/lpcip3511/usb_device_lpcip3511.h new file mode 100644 index 0000000..e7a98b8 --- /dev/null +++ b/usb/device/source/lpcip3511/usb_device_lpcip3511.h @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_LPC3511IP_H__ +#define __USB_DEVICE_LPC3511IP_H__ + +#include "fsl_device_registers.h" + +/*! + * @addtogroup usb_device_controller_lpcip3511_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* For bulk out endpoint in high speed mode, use long length data transfer to decrease the Ping packet count to increase bulk bandwidth */ +/* The bigger this macro's value is, the higher bandwidth bulk out endpoint has. However, you need to set a reasonable value for this macro based on USB RAM size of Soc. If this macro's value is too big, link may be failed. */ +/* Note that please set this value as integral multiple of 512U */ +#if (((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) && ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#define USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX (0U) +#endif + +/*! @brief The reserved buffer size, the buffer is for the memory copy if the application transfer buffer is + ((not 64 bytes alignment) || (not in the same 64K ram) || (HS && OUT && not multiple of 4)) */ +#if ((defined(USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX)) && (USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX > 0U)) +/* if use USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX (>0U), need to increase the reserved buffer size */ +#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE ((5U + ((USB_DEVICE_IP3511HS_BULK_OUT_ONE_TIME_TRANSFER_SIZE_MAX - 512U) / 512U)) * 1024U) +#else +#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE (5U * 1024U) +#endif +/*! @brief Use one bit to represent one reserved 64 bytes to allocate the buffer by uint of 64 bytes. */ +#define USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER ((USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE + 63U) / 64U) +/*! @brief How many IPs support the reserved buffer */ +#define USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) +/*! @brief Prime all the double endpoint buffer at the same time, if the transfer length is larger than max packet size. + */ +#define USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE (1U) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#define USB_LPC3511IP_Type USBHSD_Type +#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USBHSD_EP_NUM +#else +#define USB_LPC3511IP_Type USB_Type +#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USB_EP_NUM +#endif + +/* for out endpoint,only use buffer toggle, disable prime double buffer at the same time*/ +/*host send data less than maxpacket size and in endpoint prime length more more than maxpacketsize, there will be state + * mismtach*/ +#if USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE +#define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (1U) +#else +#define USB_DEVICE_IP3511_DISABLE_OUT_DOUBLE_BUFFER (0U) +#endif + +#define USB_DEVICE_IP3511HS_LPM_ADPPROBE_ATTACH_DEBOUNCE_COUNT (3) + +/* if FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE is true: + * Enable this macro to exit HS mode automatically if the user case is: + * host and device keep cable connected, and host turn off vbus to simulate detachment. + * If user disconnects the cable, there is no issue and don't need enable this macro. + * There is one delay in the isr if enable this macro. + */ +#define USB_DEVICE_IP3511HS_FORCE_EXIT_HS_MODE_ENABLE (0u) + +/*! @brief Endpoint state structure */ +typedef struct _usb_device_lpc3511ip_endpoint_state_struct +{ + uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */ + uint32_t transferLength; /*!< Length of data to transmit. */ + uint32_t transferDone; /*!< The data length has been transferred*/ + uint32_t transferPrimedLength; /*!< it may larger than transferLength, because the primed length may larger than the + transaction length. */ + uint8_t *epPacketBuffer; /*!< The max packet buffer for copying*/ + union + { + uint32_t state; /*!< The state of the endpoint */ + struct + { + uint32_t maxPacketSize : 11U; /*!< The maximum packet size of the endpoint */ + uint32_t stalled : 1U; /*!< The endpoint is stalled or not */ + uint32_t transferring : 1U; /*!< The endpoint is transferring */ + uint32_t zlt : 1U; /*!< zlt flag */ + uint32_t stallPrimed : 1U; + uint32_t epPacketCopyed : 1U; /*!< whether use the copy buffer */ + uint32_t epControlDefault : 5u; /*!< The EP command/status 26~30 bits */ + uint32_t doubleBufferBusy : 2U; /*!< How many buffers are primed, for control endpoint it is not used */ + uint32_t producerOdd : 1U; /*!< When priming one transaction, prime to this endpoint buffer */ + uint32_t consumerOdd : 1U; /*!< When transaction is done, read result from this endpoint buffer */ + uint32_t endpointType : 2U; + uint32_t reserved1 : 5U; + } stateBitField; + } stateUnion; + union + { + uint16_t epBufferStatus; + /* If double buff is disable, only epBufferStatusUnion[0] is used; + For control endpoint, only epBufferStatusUnion[0] is used. */ + struct + { + uint16_t transactionLength : 15U; + uint16_t epPacketCopyed : 1U; + } epBufferStatusField; + } epBufferStatusUnion[2]; +} usb_device_lpc3511ip_endpoint_state_struct_t; + +/*! @brief LPC USB controller (IP3511) state structure */ +typedef struct _usb_device_lpc3511ip_state_struct +{ + /*!< control data buffer, must align with 64 */ + uint8_t *controlData; + /*!< 8 bytes' setup data, must align with 64 */ + uint8_t *setupData; + /*!< 4 bytes for zero length transaction, must align with 64 */ + uint8_t *zeroTransactionData; + /* Endpoint state structures */ + usb_device_lpc3511ip_endpoint_state_struct_t endpointState[(USB_DEVICE_IP3511_ENDPOINTS_NUM * 2)]; + usb_device_handle deviceHandle; /*!< (4 bytes) Device handle used to identify the device object belongs to */ + USB_LPC3511IP_Type *registerBase; /*!< (4 bytes) ip base address */ + volatile uint32_t *epCommandStatusList; /* endpoint list */ +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + void *dcdHandle; /*!< Dcd handle used to identify the device object belongs to */ +#endif + uint8_t controllerId; /*!< Controller ID */ + uint8_t isResetting; /*!< Is doing device reset or not */ + uint8_t deviceSpeed; /*!< some controller support the HS */ +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) + uint8_t *epReservedBuffer; + uint8_t epReservedBufferBits[(USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER + 7) / 8]; +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + uint8_t controllerSpeed; +#endif +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE)) + uint8_t deviceState; /*!< Is device attached,1 attached,0 detached */ +#endif +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + uint8_t lpmRemoteWakeUp; +#endif +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#if (defined(FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK) && \ + (FSL_FEATURE_USBHSD_INTERRUPT_DATAX_ISSUE_VERSION_CHECK)) + uint8_t hsInterruptIssue; +#endif +#endif +} usb_device_lpc3511ip_state_struct_t; + +/*! + * @name USB device controller (IP3511) functions + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the USB device controller instance. + * + * This function initializes the USB device controller module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t. + * @param[in] handle Pointer of the device handle used to identify the device object belongs to. + * @param[out] controllerHandle An out parameter used to return the pointer of the device controller handle to the + * caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle); + +/*! + * @brief Deinitializes the USB device controller instance. + * + * This function deinitializes the USB device controller module. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle); + +/*! + * @brief Sends data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value indicates whether the sending request is successful or not. The transfer completion is + * notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * This function receives data through a specified endpoint. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer completion is + * notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] controllerHandle ointer of the device controller handle. + * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep); + +/*! + * @brief Controls the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * @param[in] type The selected item. Please refer to enumeration type usb_device_control_type_t. + * @param[in,out] param The parameter type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle, + usb_device_control_type_t type, + void *param); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __USB_DEVICE_LPC3511IP_H__ */ diff --git a/usb/device/source/usb_device_ch9.c b/usb/device/source/usb_device_ch9.c new file mode 100644 index 0000000..bb753d9 --- /dev/null +++ b/usb/device/source/usb_device_ch9.c @@ -0,0 +1,964 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" +#include "usb_device_dci.h" +#include "usb_device_class.h" +#include "usb_device_ch9.h" +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Standard request callback function typedef. + * + * This function is used to handle the standard request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_standard_request_callback_t)(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); + +static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* The function list to handle the standard request. */ +static const usb_standard_request_callback_t s_UsbDeviceStandardRequest[] = { + USB_DeviceCh9GetStatus, + USB_DeviceCh9SetClearFeature, + (usb_standard_request_callback_t)NULL, + USB_DeviceCh9SetClearFeature, + (usb_standard_request_callback_t)NULL, + USB_DeviceCh9SetAddress, + USB_DeviceCh9GetDescriptor, + (usb_standard_request_callback_t)NULL, + USB_DeviceCh9GetConfiguration, + USB_DeviceCh9SetConfiguration, + USB_DeviceCh9GetInterface, + USB_DeviceCh9SetInterface, + USB_DeviceCh9SynchFrame, +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Handle get status request. + * + * This function is used to handle get status request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state)) + { + return error; + } + + if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) + { +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + if (setup->wIndex == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR) + { + error = + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusOtg, &classHandle->standardTranscationBuffer); + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + /* The device status length must be USB_DEVICE_STATUS_SIZE. */ + *length = 1; + } + else /* Get the device status */ + { +#endif + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDevice, + &classHandle->standardTranscationBuffer); + classHandle->standardTranscationBuffer = + classHandle->standardTranscationBuffer & USB_GET_STATUS_DEVICE_MASK; + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + /* The device status length must be USB_DEVICE_STATUS_SIZE. */ + *length = USB_DEVICE_STATUS_SIZE; +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + } +#endif + } + else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + /* Get the interface status */ + error = kStatus_USB_Success; + classHandle->standardTranscationBuffer = 0U; + /* The interface status length must be USB_INTERFACE_STATUS_SIZE. */ + *length = USB_INTERFACE_STATUS_SIZE; + } + else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) + { + /* Get the endpoint status */ + usb_device_endpoint_status_struct_t endpointStatus; + endpointStatus.endpointAddress = (uint8_t)setup->wIndex; + endpointStatus.endpointStatus = (uint16_t)kUSB_DeviceEndpointStateIdle; + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus); + classHandle->standardTranscationBuffer = endpointStatus.endpointStatus & USB_GET_STATUS_ENDPOINT_MASK; + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + /* The endpoint status length must be USB_INTERFACE_STATUS_SIZE. */ + *length = USB_ENDPOINT_STATUS_SIZE; + } + else + { + /*no action*/ + } + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + + return error; +} + +/*! + * @brief Handle set or clear device feature request. + * + * This function is used to handle set or clear device feature request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + uint8_t isSet = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state)) + { + return error; + } + + /* Identify the request is set or clear the feature. */ + if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest) + { + isSet = 1U; + } + + if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) + { + /* Set or Clear the device feature. */ + if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue) + { +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusRemoteWakeup, &isSet); +#endif + /* Set or Clear the device remote wakeup feature. */ + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetRemoteWakeup, &isSet); + } +#if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue) + { + state = kUSB_DeviceStateTestMode; + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + } +#endif +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE == setup->wValue) + { + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetBHNPEnable, &isSet); + } +#endif + else + { + } + } + else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) + { + /* Set or Clear the endpoint feature. */ + if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue) + { + if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) + { + /* Set or Clear the control endpoint status(halt or not). */ + if (0U != isSet) + { + (void)USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex); + } + else + { + (void)USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex); + } + } + + /* Set or Clear the endpoint status feature. */ + if (0U != isSet) + { + error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetEndpointHalt, &setup->wIndex); + } + else + { + error = + USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventClearEndpointHalt, &setup->wIndex); + } + } + else + { + /*no action*/ + } + } + else + { + /*no action*/ + } + + return error; +} + +/*! + * @brief Handle set address request. + * + * This function is used to handle set address request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state. + */ +static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (((uint8_t)kUSB_DeviceStateAddressing != state) && ((uint8_t)kUSB_DeviceStateAddress != state) && + ((uint8_t)kUSB_DeviceStateDefault != state) && ((uint8_t)kUSB_DeviceStateConfigured != state)) + { + return error; + } + + if ((uint8_t)kUSB_DeviceStateAddressing != state) + { + /* If the device address is not setting, pass the address and the device state will change to + * kUSB_DeviceStateAddressing internally. */ + state = (uint8_t)(setup->wValue & 0xFFU); + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, &state); + } + else + { + /* If the device address is setting, set device address and the address will be write into the controller + * internally. */ + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, NULL); + /* And then change the device state to kUSB_DeviceStateAddress. */ + if (kStatus_USB_Success == error) + { + state = (uint8_t)kUSB_DeviceStateAddress; + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + } + } + + return error; +} + +/*! + * @brief Handle get descriptor request. + * + * This function is used to handle get descriptor request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_device_get_descriptor_common_union_t commonDescriptor; + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + uint8_t descriptorType = (uint8_t)((setup->wValue & 0xFF00U) >> 8U); + uint8_t descriptorIndex = (uint8_t)((setup->wValue & 0x00FFU)); + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state) && + ((uint8_t)kUSB_DeviceStateDefault != state)) + { + return error; + } + commonDescriptor.commonDescriptor.length = setup->wLength; + if (USB_DESCRIPTOR_TYPE_DEVICE == descriptorType) + { + /* Get the device descriptor */ + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetDeviceDescriptor, + &commonDescriptor.deviceDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_CONFIGURE == descriptorType) + { + /* Get the configuration descriptor */ + commonDescriptor.configurationDescriptor.configuration = descriptorIndex; + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetConfigurationDescriptor, + &commonDescriptor.configurationDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_STRING == descriptorType) + { + /* Get the string descriptor */ + commonDescriptor.stringDescriptor.stringIndex = descriptorIndex; + commonDescriptor.stringDescriptor.languageId = setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetStringDescriptor, + &commonDescriptor.stringDescriptor); + } +#if (defined(USB_DEVICE_CONFIG_HID) && (USB_DEVICE_CONFIG_HID > 0U)) + else if (USB_DESCRIPTOR_TYPE_HID == descriptorType) + { + /* Get the hid descriptor */ + commonDescriptor.hidDescriptor.interfaceNumber = (uint8_t)setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidDescriptor, + &commonDescriptor.hidDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_HID_REPORT == descriptorType) + { + /* Get the hid report descriptor */ + commonDescriptor.hidReportDescriptor.interfaceNumber = (uint8_t)setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidReportDescriptor, + &commonDescriptor.hidReportDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_HID_PHYSICAL == descriptorType) + { + /* Get the hid physical descriptor */ + commonDescriptor.hidPhysicalDescriptor.index = descriptorIndex; + commonDescriptor.hidPhysicalDescriptor.interfaceNumber = (uint8_t)setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidPhysicalDescriptor, + &commonDescriptor.hidPhysicalDescriptor); + } +#endif +#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U)) + else if (USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER == descriptorType) + { + /* Get the device descriptor */ + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetDeviceQualifierDescriptor, + &commonDescriptor.deviceDescriptor); + } +#endif +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + else if (USB_DESCRIPTOR_TYPE_BOS == descriptorType) + { + /* Get the configuration descriptor */ + commonDescriptor.configurationDescriptor.configuration = descriptorIndex; + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetBOSDescriptor, + &commonDescriptor.configurationDescriptor); + } +#endif + else + { + } + *buffer = commonDescriptor.commonDescriptor.buffer; + *length = commonDescriptor.commonDescriptor.length; + return error; +} + +/*! + * @brief Handle get current configuration request. + * + * This function is used to handle get current configuration request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (((uint8_t)kUSB_DeviceStateAddress != state) && (((uint8_t)kUSB_DeviceStateConfigured != state))) + { + return kStatus_USB_InvalidRequest; + } + + *length = USB_CONFIGURE_SIZE; + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + return USB_DeviceClassCallback(classHandle->handle, (uint8_t)kUSB_DeviceEventGetConfiguration, + &classHandle->standardTranscationBuffer); +} + +/*! + * @brief Handle set current configuration request. + * + * This function is used to handle set current configuration request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state)) + { + return kStatus_USB_InvalidRequest; + } + + /* The device state is changed to kUSB_DeviceStateConfigured */ + state = (uint8_t)kUSB_DeviceStateConfigured; + (void)USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + if (0U == setup->wValue) + { + /* If the new configuration is zero, the device state is changed to kUSB_DeviceStateAddress */ + state = (uint8_t)kUSB_DeviceStateAddress; + (void)USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + } + + /* Notify the class layer the configuration is changed */ + (void)USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue); + /* Notify the application the configuration is changed */ + return USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetConfiguration, &setup->wValue); +} + +/*! + * @brief Handle get the alternate setting of a interface request. + * + * This function is used to handle get the alternate setting of a interface request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (state != (uint8_t)kUSB_DeviceStateConfigured) + { + return error; + } + *length = USB_INTERFACE_SIZE; + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + classHandle->standardTranscationBuffer = (uint16_t)(((uint32_t)setup->wIndex & 0xFFU) << 8U); + /* The Bit[15~8] is used to save the interface index, and the alternate setting will be saved in Bit[7~0] by + * application. */ + error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetInterface, + &classHandle->standardTranscationBuffer); + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + return error; +} + +/*! + * @brief Handle set the alternate setting of a interface request. + * + * This function is used to handle set the alternate setting of a interface request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (state != (uint8_t)kUSB_DeviceStateConfigured) + { + return kStatus_USB_InvalidRequest; + } + classHandle->standardTranscationBuffer = ((setup->wIndex & 0xFFU) << 8U) | (setup->wValue & 0xFFU); + /* Notify the class driver the alternate setting of the interface is changed. */ + /* The Bit[15~8] is used to save the interface index, and the alternate setting is saved in Bit[7~0]. */ + (void)USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface, + &classHandle->standardTranscationBuffer); + /* Notify the application the alternate setting of the interface is changed. */ + /* The Bit[15~8] is used to save the interface index, and the alternate setting will is saved in Bit[7~0]. */ + return USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetInterface, + &classHandle->standardTranscationBuffer); +} + +/*! + * @brief Handle get sync frame request. + * + * This function is used to handle get sync frame request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + + (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (state != (uint8_t)kUSB_DeviceStateConfigured) + { + return error; + } + + classHandle->standardTranscationBuffer = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex); + /* Get the sync frame value */ + error = + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSynchFrame, &classHandle->standardTranscationBuffer); + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + *length = sizeof(classHandle->standardTranscationBuffer); + + return error; +} + +/*! + * @brief Send the response to the host. + * + * This function is used to send the response to the host. + * + * There are two cases this function will be called. + * Case one when a setup packet is received in control endpoint callback function: + * 1. If there is not data phase in the setup transfer, the function will prime an IN transfer with the data + * length is zero for status phase. + * 2. If there is an IN data phase, the function will prime an OUT transfer with the actual length to need to + * send for data phase. And then prime an IN transfer with the data length is zero for status phase. + * 3. If there is an OUT data phase, the function will prime an IN transfer with the actual length to want to + * receive for data phase. + * + * Case two when is not a setup packet received in control endpoint callback function: + * 1. The function will prime an IN transfer with data length is zero for status phase. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param error The error code returned from the standard request function. + * @param stage The stage of the control transfer. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceControlCallbackFeedback(usb_device_handle handle, + usb_setup_struct_t *setup, + usb_status_t error, + usb_device_control_read_write_sequence_t stage, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t status; + uint8_t direction = USB_IN; + + if (kStatus_USB_InvalidRequest == error) + { + /* Stall the control pipe when the request is unsupported. */ + if ((!((setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)) && + ((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) && + (0U != setup->wLength) && (kUSB_DeviceControlPipeSetupStage == stage)) + { + direction = USB_OUT; + } + status = USB_DeviceStallEndpoint( + handle, + (USB_CONTROL_ENDPOINT) | (uint8_t)((uint32_t)direction << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + } + else + { + if (*length > setup->wLength) + { + *length = setup->wLength; + } + status = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), *buffer, *length); + + if ((kStatus_USB_Success == status) && + (USB_REQUEST_TYPE_DIR_IN == (setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK))) + { + status = USB_DeviceRecvRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U); + } + } + return status; +} + +/*! + * @brief Control endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when a specified endpoint initialized by calling API USB_DeviceInitEndpoint. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of a transfer, includes transfer buffer, transfer length and whether is in setup + * phase for control pipe. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceControlCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_setup_struct_t *deviceSetup, *setup; + usb_device_common_class_struct_t *classHandle; + uint8_t *buffer = (uint8_t *)NULL; + uint32_t length = 0U; + void *temp; + usb_status_t status = kStatus_USB_InvalidRequest; + uint8_t state = 0U; + + /* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */ + if ((USB_CANCELLED_TRANSFER_LENGTH == message->length) || (NULL == callbackParam)) + { + return status; + } + + classHandle = (usb_device_common_class_struct_t *)callbackParam; + temp = (void *)&classHandle->setupBuffer[0]; + deviceSetup = (usb_setup_struct_t *)temp; + (void)USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state); + + if (0U != message->isSetup) + { + if ((USB_SETUP_PACKET_SIZE != message->length) || (NULL == message->buffer)) + { + /* If a invalid setup is received, the control pipes should be de-init and init again. + * Due to the IP can not meet this require, it is reserved for feature. + */ + /* + USB_DeviceDeinitEndpoint(handle, + USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + USB_DeviceDeinitEndpoint(handle, + USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + USB_DeviceControlPipeInit(handle, callbackParam); + */ + return status; + } + /* Receive a setup request */ + temp = (void *)(message->buffer); + setup = (usb_setup_struct_t *)temp; + + /* Copy the setup packet to the application buffer */ + deviceSetup->wValue = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wValue); + deviceSetup->wIndex = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex); + deviceSetup->wLength = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wLength); + deviceSetup->bRequest = setup->bRequest; + deviceSetup->bmRequestType = setup->bmRequestType; + + if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD) + { + /* Handle the standard request, only handle the request in request array. */ + if (deviceSetup->bRequest < (sizeof(s_UsbDeviceStandardRequest) / 4U)) + { + if (s_UsbDeviceStandardRequest[deviceSetup->bRequest] != (usb_standard_request_callback_t)NULL) + { + status = + s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length); + } + } + } + else + { + if ((0U != deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT)) + { + /* Class or vendor request with the OUT data phase. */ + if ((0U != deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS)) + { + /* Get data buffer to receive the data from the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else if ((0U != deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR)) + { + /* Get data buffer to receive the data from the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else + { + /*no action*/ + } + if (kStatus_USB_Success == status) + { + /* Prime an OUT transfer */ + status = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, deviceSetup->wLength); + return status; + } + } + else + { + /* Class or vendor request with the IN data phase. */ + if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS)) + { + /* Get data buffer to response the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR)) + { + /* Get data buffer to response the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else + { + /*no action*/ + } + } + } + /* Send the response to the host. */ + status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, status, kUSB_DeviceControlPipeSetupStage, + &buffer, &length); + } + else if ((uint8_t)kUSB_DeviceStateAddressing == state) + { + /* Set the device address to controller. */ + status = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length); + } +#if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + else if ((uint8_t)kUSB_DeviceStateTestMode == state) + { + uint8_t portTestControl = (uint8_t)(deviceSetup->wIndex >> 8); + /* Set the controller.into test mode. */ + status = USB_DeviceSetStatus(handle, kUSB_DeviceStatusTestMode, &portTestControl); + } +#endif + else if ((0U != message->length) && (0U != deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT)) + { + if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS)) + { + /* Data received in OUT phase, and notify the class driver. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = message->buffer; + controlRequest.isSetup = 0U; + controlRequest.setup = deviceSetup; + controlRequest.length = message->length; + status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest); + } + else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR)) + { + /* Data received in OUT phase, and notify the application. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = message->buffer; + controlRequest.isSetup = 0U; + controlRequest.setup = deviceSetup; + controlRequest.length = message->length; + status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest); + } + else + { + /*no action*/ + } + /* Send the response to the host. */ + status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, status, kUSB_DeviceControlPipeDataStage, + &buffer, &length); + } + else + { + /*no action*/ + } + return status; +} + +/*! + * @brief Control endpoint initialization function. + * + * This callback function is used to initialize the control pipes. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param param The up layer handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param) +{ + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + usb_status_t status; + + epCallback.callbackFn = USB_DeviceControlCallback; + epCallback.callbackParam = param; + + epInitStruct.zlt = 1U; + epInitStruct.transferType = USB_ENDPOINT_CONTROL; + epInitStruct.interval = 0; + epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + epInitStruct.maxPacketSize = USB_CONTROL_MAX_PACKET_SIZE; + /* Initialize the control IN pipe */ + status = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback); + + if (kStatus_USB_Success != status) + { + return status; + } + epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + /* Initialize the control OUT pipe */ + status = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback); + + if (kStatus_USB_Success != status) + { + (void)USB_DeviceDeinitEndpoint( + handle, USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + return status; + } + + return kStatus_USB_Success; +} +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/usb/device/source/usb_device_ch9.h b/usb/device/source/usb_device_ch9.h new file mode 100644 index 0000000..e26d357 --- /dev/null +++ b/usb/device/source/usb_device_ch9.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_CH9_H__ +#define __USB_DEVICE_CH9_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @addtogroup usb_device_ch9 + * @{ + */ +/*! @brief Defines USB device status size when the host request to get device status */ +#define USB_DEVICE_STATUS_SIZE (0x02U) + +/*! @brief Defines USB device interface status size when the host request to get interface status */ +#define USB_INTERFACE_STATUS_SIZE (0x02U) + +/*! @brief Defines USB device endpoint status size when the host request to get endpoint status */ +#define USB_ENDPOINT_STATUS_SIZE (0x02U) + +/*! @brief Defines USB device configuration size when the host request to get current configuration */ +#define USB_CONFIGURE_SIZE (0X01U) + +/*! @brief Defines USB device interface alternate setting size when the host request to get interface alternate setting + */ +#define USB_INTERFACE_SIZE (0X01U) + +/*! @brief Defines USB device status mask */ +#define USB_GET_STATUS_DEVICE_MASK (0x03U) + +/*! @brief Defines USB device interface status mask */ +#define USB_GET_STATUS_INTERFACE_MASK (0x03U) + +/*! @brief Defines USB device endpoint status mask */ +#define USB_GET_STATUS_ENDPOINT_MASK (0x03U) + +/*! @brief Control read and write sequence */ +typedef enum _usb_device_control_read_write_sequence +{ + kUSB_DeviceControlPipeSetupStage = 0U, /*!< Setup stage */ + kUSB_DeviceControlPipeDataStage, /*!< Data stage */ + kUSB_DeviceControlPipeStatusStage, /*!< status stage */ +} usb_device_control_read_write_sequence_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the control pipes. + * + * The function is used to initialize the control pipes. This function should be called when event + * kUSB_DeviceEventBusReset is received. + * + * @param[in] handle The device handle. + * @param[in] param The event parameter. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_CH9_H__ */ diff --git a/usb/device/source/usb_device_dci.c b/usb/device/source/usb_device_dci.c new file mode 100644 index 0000000..4bd7910 --- /dev/null +++ b/usb/device/source/usb_device_dci.c @@ -0,0 +1,1399 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017,2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" +#include "usb_device_dci.h" + +#include "fsl_device_registers.h" + +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +#include "usb_device_khci.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +#include "usb_device_ehci.h" +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#include "usb_device_lpcip3511.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) +#include "usb_device_dwc3.h" +#endif + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) +#include "fsl_cache.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "middleware.usb.device_stack" +#endif + +#if defined __CORTEX_M && (__CORTEX_M == 7U) +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) +#warning USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE is not supported. +#endif +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle); +static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle); +static usb_status_t USB_DeviceGetControllerInterface( + uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface); +static usb_status_t USB_DeviceTransfer(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); +static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param); +static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); + +#endif +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) +static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#endif +static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device handle. + * + * This function allocates a device handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_Error The device has been initialized. + */ +static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle) +{ + uint32_t count; + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + /* Check the controller is initialized or not. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId)) + { + OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + } + /* Get a free device handle. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (NULL == s_UsbDevice[count].controllerHandle) + { + s_UsbDevice[count].controllerId = controllerId; + *handle = &s_UsbDevice[count]; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device handle. + * + * This function frees a device handle. + * + * @param handle The device handle. + * + * @retval kStatus_USB_Success Free device handle successfully. + */ +static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle) +{ + OSA_SR_ALLOC(); + + OSA_ENTER_CRITICAL(); + handle->controllerHandle = NULL; + handle->controllerId = 0U; + OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/* KHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = { + USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend, + USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl}; +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = { + USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend, + USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl}; +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceLpc3511IpInterface = { + USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend, + USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl}; +#endif + +#if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceDwc3Interface = { + USB_DeviceDwc3Init, USB_DeviceDwc3Deinit, USB_DeviceDwc3Send, + USB_DeviceDwc3Recv, USB_DeviceDwc3Cancel, USB_DeviceDwc3Control}; +#endif + +/*! + * @brief Get the controller interface handle. + * + * This function is used to get the controller interface handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param controllerInterface It is out parameter, is used to return pointer of the device controller handle to the + * caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_ControllerNotFound The controller id is invalid. + */ +static usb_status_t USB_DeviceGetControllerInterface( + uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface) +{ + usb_status_t error = kStatus_USB_ControllerNotFound; + usb_controller_index_t controlerIndex = (usb_controller_index_t)controllerId; + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + /* Get the KHCI controller driver interface */ + if ((kUSB_ControllerKhci0 == controlerIndex) || (kUSB_ControllerKhci1 == controlerIndex)) + { + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface; + error = kStatus_USB_Success; + } +#endif +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) + /* Get the EHCI controller driver interface */ + if ((kUSB_ControllerEhci0 == controlerIndex) || (kUSB_ControllerEhci1 == controlerIndex)) + { + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface; + error = kStatus_USB_Success; + } +#endif +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) + /* Get the EHCI controller driver interface */ + if ((kUSB_ControllerLpcIp3511Fs0 == controlerIndex) || (kUSB_ControllerLpcIp3511Fs1 == controlerIndex) || + (kUSB_ControllerLpcIp3511Hs0 == controlerIndex) || (kUSB_ControllerLpcIp3511Hs1 == controlerIndex)) + { + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceLpc3511IpInterface; + error = kStatus_USB_Success; + } +#endif +#if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) + /* Get the EHCI controller driver interface */ + if ((kUSB_ControllerDwc30 == controlerIndex) || (kUSB_ControllerDwc31 == controlerIndex)) + { + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceDwc3Interface; + error = kStatus_USB_Success; + } +#endif + + return error; +} + +/*! + * @brief Start a new transfer. + * + * This function is used to start a new transfer. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param endpointAddress Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address to be transferred, or the memory address to hold the data need to be + * sent. + * @param length The length of the data. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_InvalidHandle The device handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is not found. + * @retval kStatus_USB_Error The device is doing reset. + */ +static usb_status_t USB_DeviceTransfer(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t status; + uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + OSA_SR_ALLOC(); + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + if (0U != deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy) + { + return kStatus_USB_Busy; + } + OSA_ENTER_CRITICAL(); + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 1U; + OSA_EXIT_CRITICAL(); + if (0U != (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)) + { +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + if (0U != length) + { + DCACHE_CleanByRange((uint32_t)buffer, length); + } +#endif + /* Call the controller send interface, the callbackFn is initialized in + USB_DeviceGetControllerInterface */ + status = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress, + buffer, length); + } + else + { +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + if (length) + { + DCACHE_CleanInvalidateByRange((uint32_t)buffer, length); + } +#endif + /* Call the controller receive interface, the callbackFn is initialized in + USB_DeviceGetControllerInterface */ + status = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress, + buffer, length); + } + if (kStatus_USB_Success != status) + { + OSA_ENTER_CRITICAL(); + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + OSA_EXIT_CRITICAL(); + } + } + else + { + status = kStatus_USB_ControllerNotFound; + } + return status; +} + +/*! + * @brief Control the status of the selected item. + * + * This function is used to control the status of the selected item.. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param type The control type, please refer to the enumeration usb_device_control_type_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_InvalidHandle The device handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is not found. + * @retval kStatus_USB_Error Unsupported type. + * Or, the param is NULL pointer. + */ +static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t status; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + /* Call the controller control interface. the controllerInterface is initialized in + USB_DeviceGetControllerInterface */ + status = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param); + } + else + { + status = kStatus_USB_ControllerNotFound; + } + return status; +} + +/*! + * @brief Handle the reset notification. + * + * This function is used to handle the reset notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @retval kStatus_USB_Success Get a device handle successfully. + */ +static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + uint32_t count; + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + OSA_SR_ALLOC(); +#endif + + handle->isResetting = 1U; + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + /* Clear remote wakeup feature */ + handle->remotewakeup = 0U; +#endif + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + OSA_ENTER_CRITICAL(); + handle->epCallbackDirectly = 1U; + OSA_EXIT_CRITICAL(); +#endif + /* Set the controller to default status. */ + (void)USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL); +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + OSA_ENTER_CRITICAL(); + handle->epCallbackDirectly = 0U; + OSA_EXIT_CRITICAL(); +#endif + + handle->state = (uint8_t)kUSB_DeviceStateDefault; + handle->deviceAddress = 0U; + + for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++) + { + handle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL; + handle->epCallback[count].callbackParam = NULL; + handle->epCallback[count].isBusy = 0U; + } + + /* Call device callback to notify the application that the USB bus reset signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + (void)handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL); + + handle->isResetting = 0U; + return kStatus_USB_Success; +} + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Handle the suspend notification. + * + * This function is used to handle the suspend notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + + return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL); +} + +/*! + * @brief Handle the resume notification. + * + * This function is used to handle the resume notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus resume signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL); +} +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +/*! + * @brief Handle the suspend notification. + * + * This function is used to handle the suspend notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + + (void)USB_DeviceSetStatus(handle, kUSB_DeviceStatusRemoteWakeup, message->buffer); + + return handle->deviceCallback(handle, kUSB_DeviceEventSleeped, NULL); +} +#endif + +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +#if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)) +static usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus error signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL); +} +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) +/*! + * @brief Handle the detach notification. + * + * This function is used to handle the detach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device is disconnected from a host. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL); +} + +/*! + * @brief Handle the attach notification. + * + * This function is used to handle the attach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device is connected to a host. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL); +} +#endif + +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) + +/*! + * @brief Handle the DCP detection finished notification. + * + * This function is used to notify detection notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ + +static usb_status_t USB_DeviceDcdDetectFinihsedNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the DCP facility is detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventDcdDetectionfinished, message->buffer); +} +#endif + +/*! + * @brief Handle the attach notification. + * + * This function is used to handle the attach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message) +{ + uint8_t endpoint = message->code & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + usb_status_t status = kStatus_USB_Error; + usb_device_notification_t deviceNotify = (usb_device_notification_t)message->code; + switch (deviceNotify) + { + case kUSB_DeviceNotifyBusReset: + status = USB_DeviceResetNotification(handle, message); + break; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + case kUSB_DeviceNotifySuspend: + status = USB_DeviceSuspendNotification(handle, message); + break; + case kUSB_DeviceNotifyResume: + status = USB_DeviceResumeNotification(handle, message); + break; +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + case kUSB_DeviceNotifyLPMSleep: + status = USB_DeviceSleepNotification(handle, message); + break; +#endif +#endif + +#if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)) + case kUSB_DeviceNotifyError: + status = USB_DeviceErrorNotification(handle, message); + break; +#endif + +#if USB_DEVICE_CONFIG_DETACH_ENABLE + case kUSB_DeviceNotifyDetach: + status = USB_DeviceDetachNotification(handle, message); + break; + case kUSB_DeviceNotifyAttach: + status = USB_DeviceAttachNotification(handle, message); + break; +#endif +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) + case kUSB_DeviceNotifyDcdDetectFinished: + status = USB_DeviceDcdDetectFinihsedNotification(handle, message); + break; +#endif + + default: + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + if (NULL != handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = message->buffer; + endpointCallbackMessage.length = message->length; + endpointCallbackMessage.isSetup = message->isSetup; + if (0U != message->isSetup) + { + handle->epCallback[0].isBusy = 0U; + handle->epCallback[1].isBusy = 0U; + } + else + { + handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + /* Call endpoint callback, callbackFn is in the third parameter of USB_DeviceInitEndpoint */ + status = handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn( + handle, &endpointCallbackMessage, + handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam); + } + } + break; + } + return status; +} + +/*! + * @brief Notify the device that the controller status changed. + * + * This function is used to notify the device that the controller status changed. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg; + + if ((NULL == msg) || (NULL == handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* The device callback is invalid or not. */ + if (NULL == deviceHandle->deviceCallback) + { + return kStatus_USB_Error; + } + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + if (0U != deviceHandle->epCallbackDirectly) + { + if ((0U != (message->code & USB_ENDPOINT_NUMBER_MASK)) && (0U == (message->code & 0x70U))) + { + return USB_DeviceNotification(deviceHandle, message); + } + } + + /* Add the message to message queue when the device task is enabled. */ + if (KOSA_StatusSuccess != OSA_MsgQPut(deviceHandle->notificationQueue, (osa_msg_handle_t)message)) + { + return kStatus_USB_Busy; + } + return kStatus_USB_Success; +#else + /* Handle the notification by calling USB_DeviceNotification. */ + return USB_DeviceNotification(deviceHandle, message); +#endif +} + +/*! + * @brief Initialize the USB device stack. + * + * This function initializes the USB device module specified by the controllerId. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param deviceCallback Function pointer of the device callback. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success The device is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id. + * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invaild, There is an empty + * interface entity. + * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number. + * Or, the device has been initialized. + * Or, the message queue is created failed. + */ +usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle) +{ + usb_device_struct_t *deviceHandle = NULL; + usb_status_t error; + uint32_t count; + + if (NULL == handle) + { + return kStatus_USB_InvalidHandle; + } + + /* Allocate a device handle by using the controller id. */ + error = USB_DeviceAllocateHandle(controllerId, &deviceHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Save the device callback */ + deviceHandle->deviceCallback = deviceCallback; + /* Save the controller id */ + deviceHandle->controllerId = controllerId; + /* Clear the device address */ + deviceHandle->deviceAddress = 0U; + /* Clear the device reset state */ + deviceHandle->isResetting = 0U; + + /* Initialize the endpoints */ + for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++) + { + deviceHandle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL; + deviceHandle->epCallback[count].callbackParam = NULL; + deviceHandle->epCallback[count].isBusy = 0U; + } + + /* Get the controller interface according to the controller id */ + error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface); + if (kStatus_USB_Success != error) + { + (void)USB_DeviceFreeHandle(deviceHandle); + return error; + } + if (NULL == deviceHandle->controllerInterface) + { + (void)USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_ControllerNotFound; + } + if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) || + ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) || + ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) || + ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) || + ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) || + ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl)) + { + (void)USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_InvalidControllerInterface; + } + +#if USB_DEVICE_CONFIG_USE_TASK + /* Create a message queue when the device handle is enabled. */ + deviceHandle->notificationQueue = (osa_msgq_handle_t)&deviceHandle->notificationQueueBuffer[0]; + if (KOSA_StatusSuccess != + OSA_MsgQCreate(deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES, USB_DEVICE_MESSAGES_SIZE)) + { + (void)USB_DeviceDeinit(deviceHandle); + return kStatus_USB_Error; + } +#endif + + *handle = deviceHandle; + + /* Initialize the controller, the callbackFn is initialized in USB_DeviceGetControllerInterface */ + error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle); + if (kStatus_USB_Success != error) + { + (void)USB_DeviceDeinit(deviceHandle); + *handle = NULL; + return error; + } + /* Set the device to deafult state */ + deviceHandle->state = (uint8_t)kUSB_DeviceStateDefault; + + return error; +} + +/*! + * @brief Enable the device functionality. + * + * The function enables the device functionality, so that the device can be recognized by the host when the device + * detects that it has been connected to a host. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceRun(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL); +} +/*! + * @brief Disable the device functionality. + * + * The function disables the device functionality, after this function called, even the device is detached to the host, + * and the device can't work. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + */ +usb_status_t USB_DeviceStop(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL); +} +/*! + * @brief De-initialize the device controller. + * + * The function de-initializes the device controller specified by the handle. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + */ +usb_status_t USB_DeviceDeinit(usb_device_handle handle) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + /* De-initialize the controller */ + if (NULL != deviceHandle->controllerInterface) + { + /* the callbackFn is initialized in USB_DeviceGetControllerInterface */ + (void)deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle); + deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL; + } + +#if USB_DEVICE_CONFIG_USE_TASK + /* Destroy the message queue. */ + if (NULL != deviceHandle->notificationQueue) + { + (void)OSA_MsgQDestroy(deviceHandle->notificationQueue); + deviceHandle->notificationQueue = NULL; + } +#endif + + /* Free the device handle. */ + (void)USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_Success; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @retval kStatus_USB_Success The send request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate dtds for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length) +{ + return USB_DeviceTransfer( + handle, + (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @retval kStatus_USB_Success The receive request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate dtds for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length) +{ + return USB_DeviceTransfer( + handle, + (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Cancel the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The transfer is cancelled. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t status; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + /* the callbackFn is initialized in USB_DeviceGetControllerInterface */ + status = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress); + } + else + { + status = kStatus_USB_ControllerNotFound; + } + return status; +} + +/*! + * @brief Initialize a specified endpoint. + * + * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized. + * + * @param handle The device handle got from USB_DeviceInit. + * @param epInit Endpoint initialization structure. Please refer to the structure usb_device_endpoint_init_struct_t. + * @param epCallback Endpoint callback structure. Please refer to the structure + * usb_device_endpoint_callback_struct_t. + * + * @retval kStatus_USB_Success The endpoint is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is + * not less than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle, + usb_device_endpoint_init_struct_t *epInit, + usb_device_endpoint_callback_struct_t *epCallback) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + uint8_t endpoint; + uint8_t direction; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if ((NULL == epInit) || (NULL == epCallback)) + { + return kStatus_USB_InvalidParameter; + } + + endpoint = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK; + direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = epCallback->callbackFn; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = + epCallback->callbackParam; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + else + { + return kStatus_USB_InvalidParameter; + } + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit); +} + +/*! + * @brief De-initizlize a specified endpoint. + * + * The function is used to de-initizlize a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is de-initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + usb_status_t status; +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + OSA_SR_ALLOC(); +#endif + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + OSA_ENTER_CRITICAL(); + deviceHandle->epCallbackDirectly = 1U; + OSA_EXIT_CRITICAL(); +#endif + status = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress); +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + OSA_ENTER_CRITICAL(); + deviceHandle->epCallbackDirectly = 0U; + OSA_EXIT_CRITICAL(); +#endif + + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = + (usb_device_endpoint_callback_t)NULL; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + else + { + return kStatus_USB_InvalidParameter; + } + return status; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress); + } + else + { + return kStatus_USB_InvalidParameter; + } +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is un-stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress); + } + else + { + return kStatus_USB_InvalidParameter; + } +} + +/*! + * @brief Get the status of the selected item. + * + * The function is used to get the status of the selected item. + * + * @param handle The device handle got from USB_DeviceInit. + * @param type The selected item. Please refer to the structure usb_device_status_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Get status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The param is NULL pointer. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type. + */ +usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param) +{ + uint8_t *temp8; + usb_status_t status = kStatus_USB_Error; + + if (NULL == param) + { + return kStatus_USB_InvalidParameter; + } + switch (type) + { +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) + case kUSB_DeviceStatusGetCurrentFrameCount: + status = USB_DeviceControl(handle, kUSB_DeviceControlGetCurrentFrameCount, param); + break; +#endif + case kUSB_DeviceStatusSpeed: + status = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param); + break; + case kUSB_DeviceStatusOtg: + status = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param); + break; + case kUSB_DeviceStatusDeviceState: + temp8 = (uint8_t *)param; + status = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->state; + break; + case kUSB_DeviceStatusAddress: + temp8 = (uint8_t *)param; + status = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->deviceAddress; + break; + case kUSB_DeviceStatusDevice: + status = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param); + break; + case kUSB_DeviceStatusEndpoint: + status = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param); + break; + case kUSB_DeviceStatusSynchFrame: + status = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param); + break; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + case kUSB_DeviceStatusRemoteWakeup: + temp8 = (uint8_t *)param; + status = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->remotewakeup; + break; +#endif + default: + /*no action*/ + break; + } + return status; +} + +/*! + * @brief Set the status of the selected item. + * + * The function is used to set the status of the selected item. + * + * @param handle The device handle got from USB_DeviceInit. + * @param type The selected item. Please refer to the structure usb_device_status_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Set status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type, or the param is NULL pointer. + */ +usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param) +{ + usb_status_t status = kStatus_USB_Error; + switch (type) + { +#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceStatusTestMode: + status = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param); + break; +#endif + case kUSB_DeviceStatusOtg: + status = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param); + break; + case kUSB_DeviceStatusDeviceState: + if (NULL != param) + { + status = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param); + } + break; + case kUSB_DeviceStatusAddress: + if ((uint8_t)kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state) + { + if (NULL != param) + { + status = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param); + ((usb_device_struct_t *)handle)->state = (uint8_t)kUSB_DeviceStateAddressing; + status = USB_DeviceControl(handle, kUSB_DeviceControlPreSetDeviceAddress, + &((usb_device_struct_t *)handle)->deviceAddress); + } + } + else + { + status = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress, + &((usb_device_struct_t *)handle)->deviceAddress); + } + break; + case kUSB_DeviceStatusBusResume: + status = USB_DeviceControl(handle, kUSB_DeviceControlResume, param); + break; + case kUSB_DeviceStatusBusSleepResume: + status = USB_DeviceControl(handle, kUSB_DeviceControlSleepResume, param); + break; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + case kUSB_DeviceStatusRemoteWakeup: + if (NULL != param) + { + status = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->remotewakeup = (uint8_t)(*(uint8_t *)param); + } + break; +#endif + case kUSB_DeviceStatusBusSuspend: + status = USB_DeviceControl(handle, kUSB_DeviceControlSuspend, param); + break; + case kUSB_DeviceStatusBusSleep: + status = USB_DeviceControl(handle, kUSB_DeviceControlSleep, param); + break; + default: + /*no action*/ + break; + } + return status; +} + +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +/*! + * @brief Enable the device dcd module. + * + * The function enable the device dcd module. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device could run. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceDcdEnable(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlDcdEnable, NULL); +} +/*! + * @brief Disable the device dcd module. + * + * The function disable the device dcd module. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The dcd is reset and stopped. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceDcdDisable(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlDcdDisable, NULL); +} +#endif + +#if USB_DEVICE_CONFIG_USE_TASK +/*! + * @brief Device task function. + * + * The function is used to handle controller message. + * This function should not be called in application directly. + * + * @param handle The device handle got from USB_DeviceInit. + */ +void USB_DeviceTaskFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_callback_message_struct_t message; + + if (NULL != deviceHandle) + { + message.buffer = NULL; + message.length = 0U; + message.code = 0U; + message.isSetup = 0U; + /* Get the message from the queue */ + if (KOSA_StatusSuccess == + OSA_MsgQGet(handle->notificationQueue, (osa_msg_handle_t)&message, USB_OSA_WAIT_TIMEOUT)) + { + /* Handle the message */ + (void)USB_DeviceNotification(handle, &message); + } + } +} +#endif + +/*! + * @brief Get device stack version function. + * + * The function is used to get device stack version. + * + * @param[out] version The version structure pointer to keep the device stack version. + * + */ +void USB_DeviceGetVersion(uint32_t *version) +{ + if (NULL != version) + { + *version = + (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX); + } +} + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) || \ + (((defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)))) +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] tick Current hardware tick. + * + */ +usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick) +{ + usb_device_struct_t *deviceHandle; + usb_status_t status = kStatus_USB_Success; +#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \ + (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +#elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)) + /* fix misra 11.8 */ + uint64_t tempValue; +#endif + + if (handle == NULL) + { + return kStatus_USB_InvalidHandle; + } + deviceHandle = (usb_device_struct_t *)handle; + + deviceHandle->hwTick = tick; +#if (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) && \ + (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) +#ifndef USBHSDCD_IRQS + status = USB_DeviceControl(handle, kUSB_DeviceControlUpdateHwTick, (void *)(&deviceHandle->hwTick)); +#endif +#elif (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) && \ + (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)) + tempValue = deviceHandle->hwTick; + status = USB_DeviceControl(handle, kUSB_DeviceControlUpdateHwTick, (void *)(&tempValue)); +#endif + return status; +} +#endif +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/usb/device/source/usb_device_dci.h b/usb/device/source/usb_device_dci.h new file mode 100644 index 0000000..d8f9555 --- /dev/null +++ b/usb/device/source/usb_device_dci.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_DCI_H__ +#define __USB_DEVICE_DCI_H__ + +/*! + * @addtogroup usb_device_controller_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Macro to define controller handle */ +#define usb_device_controller_handle usb_device_handle +#define USB_DEVICE_MESSAGES_SIZE \ + (sizeof(uint32_t) * (1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t))) +/*! @brief Available notify types for device notification */ +typedef enum _usb_device_notification +{ + kUSB_DeviceNotifyBusReset = 0x10U, /*!< Reset signal detected */ + kUSB_DeviceNotifySuspend, /*!< Suspend signal detected */ + kUSB_DeviceNotifyResume, /*!< Resume signal detected */ + kUSB_DeviceNotifyLPMSleep, /*!< LPM signal detected */ + kUSB_DeviceNotifyLPMResume, /*!< Resume signal detected */ + kUSB_DeviceNotifyError, /*!< Errors happened in bus */ + kUSB_DeviceNotifyDetach, /*!< Device disconnected from a host */ + kUSB_DeviceNotifyAttach, /*!< Device connected to a host */ +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) + kUSB_DeviceNotifyDcdDetectFinished, /*!< Device charger detection finished */ +#endif +} usb_device_notification_t; + +/*! @brief Device notification message structure */ +typedef struct _usb_device_callback_message_struct +{ + uint8_t *buffer; /*!< Transferred buffer */ + uint32_t length; /*!< Transferred data length */ + uint8_t code; /*!< Notification code */ + uint8_t isSetup; /*!< Is in a setup phase */ +} usb_device_callback_message_struct_t; + +/*! @brief Control type for controller */ +typedef enum _usb_device_control_type +{ + kUSB_DeviceControlRun = 0U, /*!< Enable the device functionality */ + kUSB_DeviceControlStop, /*!< Disable the device functionality */ + kUSB_DeviceControlEndpointInit, /*!< Initialize a specified endpoint */ + kUSB_DeviceControlEndpointDeinit, /*!< De-initialize a specified endpoint */ + kUSB_DeviceControlEndpointStall, /*!< Stall a specified endpoint */ + kUSB_DeviceControlEndpointUnstall, /*!< Un-stall a specified endpoint */ + kUSB_DeviceControlGetDeviceStatus, /*!< Get device status */ + kUSB_DeviceControlGetEndpointStatus, /*!< Get endpoint status */ + kUSB_DeviceControlSetDeviceAddress, /*!< Set device address */ + kUSB_DeviceControlGetSynchFrame, /*!< Get current frame */ + kUSB_DeviceControlResume, /*!< Drive controller to generate a resume signal in USB bus */ + kUSB_DeviceControlSleepResume, /*!< Drive controller to generate a LPM resume signal in USB bus */ + kUSB_DeviceControlSuspend, /*!< Drive controller to enter into suspend mode */ + kUSB_DeviceControlSleep, /*!< Drive controller to enter into sleep mode */ + kUSB_DeviceControlSetDefaultStatus, /*!< Set controller to default status */ + kUSB_DeviceControlGetSpeed, /*!< Get current speed */ + kUSB_DeviceControlGetOtgStatus, /*!< Get OTG status */ + kUSB_DeviceControlSetOtgStatus, /*!< Set OTG status */ + kUSB_DeviceControlSetTestMode, /*!< Drive xCHI into test mode */ + kUSB_DeviceControlGetRemoteWakeUp, /*!< Get flag of LPM Remote Wake-up Enabled by USB host. */ +#if (defined(USB_DEVICE_CONFIG_CHARGER_DETECT) && (USB_DEVICE_CONFIG_CHARGER_DETECT > 0U)) + kUSB_DeviceControlDcdDisable, /*!< disable dcd module function. */ + kUSB_DeviceControlDcdEnable, /*!< enable dcd module function. */ +#endif + kUSB_DeviceControlPreSetDeviceAddress, /*!< Pre set device address */ + kUSB_DeviceControlUpdateHwTick, /*!< update hardware tick */ +#if defined(USB_DEVICE_CONFIG_GET_SOF_COUNT) && (USB_DEVICE_CONFIG_GET_SOF_COUNT > 0U) + kUSB_DeviceControlGetCurrentFrameCount, /*!< Get current frame count */ +#endif +} usb_device_control_type_t; + +/*! @brief USB device controller initialization function typedef */ +typedef usb_status_t (*usb_device_controller_init_t)(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle); + +/*! @brief USB device controller de-initialization function typedef */ +typedef usb_status_t (*usb_device_controller_deinit_t)(usb_device_controller_handle controllerHandle); + +/*! @brief USB device controller send data function typedef */ +typedef usb_status_t (*usb_device_controller_send_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! @brief USB device controller receive data function typedef */ +typedef usb_status_t (*usb_device_controller_recv_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! @brief USB device controller cancel transfer function in a specified endpoint typedef */ +typedef usb_status_t (*usb_device_controller_cancel_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress); + +/*! @brief USB device controller control function typedef */ +typedef usb_status_t (*usb_device_controller_control_t)(usb_device_controller_handle controllerHandle, + usb_device_control_type_t command, + void *param); + +/*! @brief USB device controller interface structure */ +typedef struct _usb_device_controller_interface_struct +{ + usb_device_controller_init_t deviceInit; /*!< Controller initialization */ + usb_device_controller_deinit_t deviceDeinit; /*!< Controller de-initialization */ + usb_device_controller_send_t deviceSend; /*!< Controller send data */ + usb_device_controller_recv_t deviceRecv; /*!< Controller receive data */ + usb_device_controller_cancel_t deviceCancel; /*!< Controller cancel transfer */ + usb_device_controller_control_t deviceControl; /*!< Controller control */ +} usb_device_controller_interface_struct_t; + +/*! @brief USB device status structure */ +typedef struct _usb_device_struct +{ +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) || \ + (defined(FSL_FEATURE_SOC_USB_ANALOG_COUNT) && (FSL_FEATURE_SOC_USB_ANALOG_COUNT > 0U)) + volatile uint64_t hwTick; /*!< Current hw tick(ms)*/ +#endif + usb_device_controller_handle controllerHandle; /*!< Controller handle */ + const usb_device_controller_interface_struct_t *controllerInterface; /*!< Controller interface handle */ +#if USB_DEVICE_CONFIG_USE_TASK + OSA_MSGQ_HANDLE_DEFINE(notificationQueueBuffer, + USB_DEVICE_CONFIG_MAX_MESSAGES, + USB_DEVICE_MESSAGES_SIZE); /*!< Message queue buffer*/ + osa_msgq_handle_t notificationQueue; /*!< Message queue*/ +#endif + usb_device_callback_t deviceCallback; /*!< Device callback function pointer */ + usb_device_endpoint_callback_struct_t + epCallback[USB_DEVICE_CONFIG_ENDPOINTS << 1U]; /*!< Endpoint callback function structure */ + uint8_t deviceAddress; /*!< Current device address */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t state; /*!< Current device state */ +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + uint8_t remotewakeup; /*!< Remote wakeup is enabled or not */ +#endif + uint8_t isResetting; /*!< Is doing device reset or not */ +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + uint8_t epCallbackDirectly; /*!< Whether call ep callback directly when the task is enabled */ +#endif +} usb_device_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ +/*! + * @brief Notify the device that the controller status changed. + * + * This function is used to notify the device that the controller status changed. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg); +/*! @}*/ + +#endif /* __USB_DEVICE_DCI_H__ */ diff --git a/usb/example/usb_device_cdc_vcom/inf/cdc.cat b/usb/example/usb_device_cdc_vcom/inf/cdc.cat new file mode 100644 index 0000000..6cfae5c Binary files /dev/null and b/usb/example/usb_device_cdc_vcom/inf/cdc.cat differ diff --git a/usb/example/usb_device_cdc_vcom/inf/fsl_ucwxp.inf b/usb/example/usb_device_cdc_vcom/inf/fsl_ucwxp.inf new file mode 100644 index 0000000..2a75830 --- /dev/null +++ b/usb/example/usb_device_cdc_vcom/inf/fsl_ucwxp.inf @@ -0,0 +1,109 @@ +; +; Copyright 2016 - 2018 NXP +; All rights reserved. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +CatalogFile=%MFGFILENAME%.cat +DriverVer=02/16/2011,1.0 + +[Manufacturer] +%MFGNAME%=DeviceList, NTamd64 + +[DestinationDirs] +DefaultDestDir=12 + + +;------------------------------------------------------------------------------ +; Windows 2000/XP/Vista-32bit Sections +;------------------------------------------------------------------------------ + +[DriverInstall.nt] +include=mdmcpq.inf +AddReg=DriverInstall.nt.AddReg + +[DriverInstall.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,%DRIVERFILENAME%.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.nt.Services] +AddService=usbser, 0x00000002, DriverService.nt + +[DriverService.nt] +DisplayName=%SERVICE% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\%DRIVERFILENAME%.sys + +;------------------------------------------------------------------------------ +; Vista-64bit Sections +;------------------------------------------------------------------------------ + +[DriverInstall.NTamd64] +include=mdmcpq.inf +AddReg=DriverInstall.NTamd64.AddReg + +[DriverInstall.NTamd64.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,%DRIVERFILENAME%.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.NTamd64.Services] +AddService=usbser, 0x00000002, DriverService.NTamd64 + +[DriverService.NTamd64] +DisplayName=%SERVICE% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\%DRIVERFILENAME%.sys + + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ +[SourceDisksFiles] +[SourceDisksNames] +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_0094 +%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_009E&MI_00 +%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_009F&MI_00 +%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_00A3&MI_00 +%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_00A6&MI_03 +%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_00A7&MI_04 + +[DeviceList.NTamd64] +%DESCRIPTION% = DriverInstall, USB\VID_1FC9&PID_0094 +%DESCRIPTION% = DriverInstall, USB\VID_1FC9&PID_009E&MI_00 +%DESCRIPTION% = DriverInstall, USB\VID_1FC9&PID_009F&MI_00 +%DESCRIPTION% = DriverInstall, USB\VID_1FC9&PID_00A3&MI_00 +%DESCRIPTION% = DriverInstall, USB\VID_1FC9&PID_00A6&MI_03 +%DESCRIPTION% = DriverInstall, USB\VID_1FC9&PID_00A7&MI_04 + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGFILENAME="CDC" +DRIVERFILENAME ="usbser" +MFGNAME="NXP" +INSTDISK="NXP CDC Driver Installer" +DESCRIPTION="Virtual Com Port" +SERVICE="NXP Virtual COM Driver" + diff --git a/usb/include/usb.h b/usb/include/usb.h new file mode 100644 index 0000000..b95dcb4 --- /dev/null +++ b/usb/include/usb.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_H__ +#define __USB_H__ + +#include +#include +#include "fsl_common.h" +#include "fsl_os_abstraction.h" +#include "usb_misc.h" +#include "usb_spec.h" + +/*! + * @addtogroup usb_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Defines USB stack major version */ +#define USB_STACK_VERSION_MAJOR (2UL) +/*! @brief Defines USB stack minor version */ +#define USB_STACK_VERSION_MINOR (7UL) +/*! @brief Defines USB stack bugfix version */ +#define USB_STACK_VERSION_BUGFIX (0U) + +/*! @brief USB stack version definition */ +#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/*! @brief USB stack component version definition, changed with component in yaml together */ +#define USB_STACK_COMPONENT_VERSION \ + MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX) + +/* + * Component ID used by tools + * + * FSL_COMPONENT_ID "middleware.usb.stack_common" + */ + +/*! @brief USB error code */ +typedef enum _usb_status +{ + kStatus_USB_Success = 0x00U, /*!< Success */ + kStatus_USB_Error, /*!< Failed */ + + kStatus_USB_Busy, /*!< Busy */ + kStatus_USB_InvalidHandle, /*!< Invalid handle */ + kStatus_USB_InvalidParameter, /*!< Invalid parameter */ + kStatus_USB_InvalidRequest, /*!< Invalid request */ + kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */ + kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */ + + kStatus_USB_NotSupported, /*!< Configuration is not supported */ + kStatus_USB_Retry, /*!< Enumeration get configuration retry */ + kStatus_USB_TransferStall, /*!< Transfer stalled */ + kStatus_USB_TransferFailed, /*!< Transfer failed */ + kStatus_USB_AllocFail, /*!< Allocation failed */ + kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */ + kStatus_USB_TransferCancel, /*!< The transfer cancelled */ + kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */ + kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */ + kStatus_USB_EHCIAttached, + kStatus_USB_EHCIDetached, + kStatus_USB_DataOverRun, /*!< The amount of data returned by the endpoint exceeded + either the size of the maximum data packet allowed + from the endpoint or the remaining buffer size. */ +} usb_status_t; + +/*! @brief USB host handle type define */ +typedef void *usb_host_handle; + +/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the + * attached device instance handle*/ +typedef void *usb_device_handle; + +/*! @brief USB OTG handle type define */ +typedef void *usb_otg_handle; + +/*! @brief USB controller ID */ +typedef enum _usb_controller_index +{ + kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */ + kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved + to be used in the future. */ + kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */ + kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */ + kUSB_ControllerLpcIp3511Fs1 = 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511 + IPs, this is reserved to be used in the future. */ + + kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */ + kUSB_ControllerLpcIp3511Hs1 = 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511 + IPs, this is reserved to be used in the future. */ + + kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */ + kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */ + kUSB_ControllerIp3516Hs1 = 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs, + this is reserved to be used in the future. */ + kUSB_ControllerDwc30 = 12U, /*!< DWC3 0U */ + kUSB_ControllerDwc31 = 13U, /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved + to be used in the future.*/ +} usb_controller_index_t; + +/** + * @brief USB stack version fields + */ +typedef struct _usb_version +{ + uint8_t major; /*!< Major */ + uint8_t minor; /*!< Minor */ + uint8_t bugfix; /*!< Bug fix */ +} usb_version_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! @} */ + +#endif /* __USB_H__ */ diff --git a/usb/include/usb_misc.h b/usb/include/usb_misc.h new file mode 100644 index 0000000..a04f615 --- /dev/null +++ b/usb/include/usb_misc.h @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016, 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_MISC_H__ +#define __USB_MISC_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Define big endian */ +#define USB_BIG_ENDIAN (0U) +/*! @brief Define little endian */ +#define USB_LITTLE_ENDIAN (1U) + +/*! @brief Define current endian */ +#ifndef ENDIANNESS +#define ENDIANNESS USB_LITTLE_ENDIAN +#endif +/*! @brief Define default timeout value */ +#if (defined(USE_RTOS) && (USE_RTOS > 0)) +#define USB_OSA_WAIT_TIMEOUT (osaWaitForever_c) +#else +#define USB_OSA_WAIT_TIMEOUT (0U) +#endif /* (defined(USE_RTOS) && (USE_RTOS > 0)) */ + +/*! @brief Define USB printf */ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +extern int DbgConsole_Printf(const char *fmt_s, ...); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#if defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE < 1) +#define usb_echo printf +#else +#define usb_echo DbgConsole_Printf +#endif + +#if defined(__ICCARM__) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED __packed +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED +#endif + +#elif defined(__GNUC__) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED __attribute__((__packed__)) +#endif + +#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION)) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED _Pragma("pack(1U)") +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED _Pragma("pack()") +#endif + +#elif (defined(__DSC__) || defined(__CW__)) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED __attribute__((packed)) +#endif +#endif + +#define USB_SHORT_GET_LOW(x) (((uint16_t)x) & 0xFFU) +#define USB_SHORT_GET_HIGH(x) ((uint8_t)(((uint16_t)x) >> 8U) & 0xFFU) + +#define USB_LONG_GET_BYTE0(x) ((uint8_t)(((uint32_t)(x))) & 0xFFU) +#define USB_LONG_GET_BYTE1(x) ((uint8_t)(((uint32_t)(x)) >> 8U) & 0xFFU) +#define USB_LONG_GET_BYTE2(x) ((uint8_t)(((uint32_t)(x)) >> 16U) & 0xFFU) +#define USB_LONG_GET_BYTE3(x) ((uint8_t)(((uint32_t)(x)) >> 24U) & 0xFFU) + +#define USB_MEM4_ALIGN_MASK (0x03U) + +/* accessory macro */ +#define USB_MEM4_ALIGN(n) ((n + 3U) & (0xFFFFFFFCu)) +#define USB_MEM32_ALIGN(n) ((n + 31U) & (0xFFFFFFE0u)) +#define USB_MEM64_ALIGN(n) ((n + 63U) & (0xFFFFFFC0u)) + +/* big/little endian */ +#define SWAP2BYTE_CONST(n) ((((n)&0x00FFU) << 8U) | (((n)&0xFF00U) >> 8U)) +#define SWAP4BYTE_CONST(n) \ + ((((n)&0x000000FFU) << 24U) | (((n)&0x0000FF00U) << 8U) | (((n)&0x00FF0000U) >> 8U) | (((n)&0xFF000000U) >> 24U)) + +#define USB_ASSIGN_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = *((uint8_t *)&(m)); \ + *((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \ + *((uint8_t *)&(n) + 2) = *((uint8_t *)&(m) + 2); \ + *((uint8_t *)&(n) + 3) = *((uint8_t *)&(m) + 3); \ + } + +#define USB_ASSIGN_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = *((uint8_t *)&(m)); \ + *((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \ + } + +#define USB_ASSIGN_MACRO_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = (uint8_t)m; \ + *((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \ + *((uint8_t *)&(n) + 2) = (uint8_t)(m >> 16); \ + *((uint8_t *)&(n) + 3) = (uint8_t)(m >> 24); \ + } + +#define USB_ASSIGN_MACRO_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = (uint8_t)m; \ + *((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \ + } + +#if (ENDIANNESS == USB_BIG_ENDIAN) + +#define USB_SHORT_TO_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_TO_LITTLE_ENDIAN(n) SWAP4BYTE_CONST(n) +#define USB_SHORT_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) + +#define USB_SHORT_TO_BIG_ENDIAN(n) (n) +#define USB_LONG_TO_BIG_ENDIAN(n) (n) +#define USB_SHORT_FROM_BIG_ENDIAN(n) (n) +#define USB_LONG_FROM_BIG_ENDIAN(n) (n) + +#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[3] = (uint8_t)((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[2] = (uint8_t)((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[1] = (uint8_t)((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (uint8_t)(((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint32_t)n[3]) << 24U) | (((uint32_t)n[2]) << 16U) | (((uint32_t)n[1]) << 8U) | \ + (((uint32_t)n[0]) << 0U))) + +#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[3] = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint32_t)n[0]) << 24U) | (((uint32_t)n[1]) << 16U) | (((uint32_t)n[2]) << 8U) | \ + (((uint32_t)n[3]) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[1]) << 8U) | (((uint16_t)n[0]) << 0U))) + +#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[1] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[0]) << 8U) | (((uint16_t)n[1]) << 0U))) + +#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + *((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + *((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint32_t)(((uint32_t)(*((uint8_t *)&(n) + 3)) << 24U) | ((uint32_t)(*((uint8_t *)&(n) + 2)) << 16U) | \ + ((uint32_t)(*((uint8_t *)&(n) + 1)) << 8U) | ((uint32_t)(*((uint8_t *)&(n))) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint16_t)((uint16_t)(*((uint8_t *)&(n) + 1)) << 8U) | ((uint16_t)(*((uint8_t *)&(n))))) + +#else + +#define USB_SHORT_TO_LITTLE_ENDIAN(n) (n) +#define USB_LONG_TO_LITTLE_ENDIAN(n) (n) +#define USB_SHORT_FROM_LITTLE_ENDIAN(n) (n) +#define USB_LONG_FROM_LITTLE_ENDIAN(n) (n) + +#define USB_SHORT_TO_BIG_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_TO_BIG_ENDIAN(n) SWAP4BYTE_CONST(n) +#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n) + +#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[3] = (uint8_t)((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[2] = (uint8_t)((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[1] = (uint8_t)((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (uint8_t)(((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint32_t)n[3]) << 24U) | (((uint32_t)n[2]) << 16U) | (((uint32_t)n[1]) << 8U) | \ + (((uint32_t)n[0]) << 0U))) + +#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[3] = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint32_t)n[0]) << 24U) | (((uint32_t)n[1]) << 16U) | (((uint32_t)n[2]) << 8U) | \ + (((uint32_t)n[3]) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[1]) << 8U) | (((uint16_t)n[0]) << 0U))) + +#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[1] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint16_t)((((uint16_t)n[0]) << 8U) | (((uint16_t)n[1]) << 0U))) + +#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + *((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + *((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint32_t)(((uint32_t)(*((uint8_t *)&(n) + 3)) << 24U) | ((uint32_t)(*((uint8_t *)&(n) + 2)) << 16U) | \ + ((uint32_t)(*((uint8_t *)&(n) + 1)) << 8U) | ((uint32_t)(*((uint8_t *)&(n))) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint16_t)(((uint16_t)(*(((uint8_t *)&(n)) + 1)) << 8U) | ((uint16_t)(*((uint8_t *)&(n)))))) + +#endif + +/* + * The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALIGNMENT, etc) are only used for USB device stack. + * The USB device global variables are put into the section m_usb_global and m_usb_bdt + * by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device + * global variables can be linked into USB dedicated RAM by USB_STACK_USE_DEDICATED_RAM. + * The MACRO USB_STACK_USE_DEDICATED_RAM is used to decide the USB stack uses dedicated RAM or not. The value of + * the macro can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT. + * The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL means USB device global variables, including USB_BDT and + * USB_GLOBAL, are put into the USB dedicated RAM. This feature can only be enabled when the USB dedicated RAM + * is not less than 2K Bytes. + * The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT means USB device global variables, only including USB_BDT, are put + * into the USB dedicated RAM, the USB_GLOBAL will be put into .bss section. This feature is used for some SOCs, + * the USB dedicated RAM size is not more than 512 Bytes. + */ +#define USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL 1 +#define USB_STACK_DEDICATED_RAM_TYPE_BDT 2 + +#if defined(__ICCARM__) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +/* disable misra 19.13 */ +_Pragma("diag_suppress=Pm120") +#define USB_ALIGN_PRAGMA(x) _Pragma(#x) + _Pragma("diag_default=Pm120") + +#define USB_RAM_ADDRESS_ALIGNMENT(n) USB_ALIGN_PRAGMA(data_alignment = n) + _Pragma("diag_suppress=Pm120") +#define USB_LINK_SECTION_PART(str) _Pragma(#str) +#define USB_LINK_DMA_INIT_DATA(sec) USB_LINK_SECTION_PART(location = #sec) +#define USB_LINK_USB_GLOBAL _Pragma("location = \"m_usb_global\"") +#define USB_LINK_USB_BDT _Pragma("location = \"m_usb_bdt\"") +#define USB_LINK_USB_GLOBAL_BSS +#define USB_LINK_USB_BDT_BSS + _Pragma("diag_default=Pm120") +#define USB_LINK_DMA_NONINIT_DATA _Pragma("location = \"m_usb_dma_noninit_data\"") +#define USB_LINK_NONCACHE_NONINIT_DATA _Pragma("location = \"NonCacheable\"") +#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION)) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec))) +#if defined(__CC_ARM) +#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init)) +#else +#define USB_LINK_USB_GLOBAL __attribute__((section(".bss.m_usb_global"))) +#endif +#if defined(__CC_ARM) +#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init)) +#else +#define USB_LINK_USB_BDT __attribute__((section(".bss.m_usb_bdt"))) +#endif +#define USB_LINK_USB_GLOBAL_BSS +#define USB_LINK_USB_BDT_BSS +#if defined(__CC_ARM) +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data"))) __attribute__((zero_init)) +#else +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section(".bss.m_usb_dma_noninit_data"))) +#endif +#if defined(__CC_ARM) +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable"))) __attribute__((zero_init)) +#else +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section(".bss.NonCacheable"))) +#endif + +#elif defined(__GNUC__) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec))) +#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global, \"aw\", %nobits @"))) +#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt, \"aw\", %nobits @"))) +#define USB_LINK_USB_GLOBAL_BSS +#define USB_LINK_USB_BDT_BSS +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data, \"aw\", %nobits @"))) +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable, \"aw\", %nobits @"))) + +#elif (defined(__DSC__) && defined(__CW__)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_USB_BDT_BSS +#define USB_LINK_USB_GLOBAL_BSS +#else +#error The tool-chain is not supported. +#endif + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + +#if ((defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) && (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) +#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#elif (defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) +#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, 0) +#elif (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)) +#define USB_CACHE_LINESIZE MAX(0, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#else +#define USB_CACHE_LINESIZE 4U +#endif + +#else +#define USB_CACHE_LINESIZE 4U +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#define USB_DATA_ALIGN 64U +#else +#define USB_DATA_ALIGN 4U +#endif + +#if (USB_CACHE_LINESIZE > USB_DATA_ALIGN) +#define USB_DATA_ALIGN_SIZE USB_CACHE_LINESIZE +#else +#define USB_DATA_ALIGN_SIZE USB_DATA_ALIGN +#endif + +#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) (((n) + USB_DATA_ALIGN_SIZE - 1U) & (~(USB_DATA_ALIGN_SIZE - 1U))) + +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL) + +#define USB_GLOBAL USB_LINK_USB_GLOBAL +#define USB_BDT USB_LINK_USB_BDT + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE)) +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA USB_LINK_USB_GLOBAL +#endif +#endif + +#elif defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT) + +#define USB_BDT USB_LINK_USB_BDT + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE)) +#define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA +#endif +#endif + +#else + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + +#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA +#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA + +#else + +#if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE)) +#define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA +#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS +#define USB_BDT USB_LINK_USB_BDT_BSS +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA +#endif + +#endif + +#endif + +#define USB_DMA_NONINIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_INIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_INIT_SUB + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_DMA_DATA_NONCACHEABLE USB_LINK_NONCACHE_NONINIT_DATA + +#else +#define USB_DMA_DATA_NONCACHEABLE +#endif + +#define USB_GLOBAL_DEDICATED_RAM USB_LINK_USB_GLOBAL + +/* #define USB_RAM_ADDRESS_NONCACHEREG_ALIGNMENT(n, var) AT_NONCACHEABLE_SECTION_ALIGN(var, n) */ +/* #define USB_RAM_ADDRESS_NONCACHEREG(var) AT_NONCACHEABLE_SECTION(var) */ + +#endif /* __USB_MISC_H__ */ diff --git a/usb/include/usb_spec.h b/usb/include/usb_spec.h new file mode 100644 index 0000000..a642bd5 --- /dev/null +++ b/usb/include/usb_spec.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_SPEC_H__ +#define __USB_SPEC_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* USB speed (the value cannot be changed because EHCI QH use the value directly)*/ +#define USB_SPEED_FULL (0x00U) +#define USB_SPEED_LOW (0x01U) +#define USB_SPEED_HIGH (0x02U) +#define USB_SPEED_SUPER (0x04U) + +/* Set up packet structure */ +typedef struct _usb_setup_struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} usb_setup_struct_t; + +/* USB standard descriptor endpoint type */ +#define USB_ENDPOINT_CONTROL (0x00U) +#define USB_ENDPOINT_ISOCHRONOUS (0x01U) +#define USB_ENDPOINT_BULK (0x02U) +#define USB_ENDPOINT_INTERRUPT (0x03U) + +/* USB standard descriptor transfer direction (cannot change the value because iTD use the value directly) */ +#define USB_OUT (0U) +#define USB_IN (1U) + +/* USB standard descriptor length */ +#define USB_DESCRIPTOR_LENGTH_DEVICE (0x12U) +#define USB_DESCRIPTOR_LENGTH_CONFIGURE (0x09U) +#define USB_DESCRIPTOR_LENGTH_INTERFACE (0x09U) +#define USB_DESCRIPTOR_LENGTH_ENDPOINT (0x07U) +#define USB_DESCRIPTOR_LENGTH_ENDPOINT_COMPANION (0x06U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER (0x0AU) +#define USB_DESCRIPTOR_LENGTH_OTG_DESCRIPTOR (5U) +#define USB_DESCRIPTOR_LENGTH_BOS_DESCRIPTOR (5U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_USB20_EXTENSION (0x07U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_SUPERSPEED (0x0AU) + +/* USB Device Capability Type Codes */ +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_WIRELESS (0x01U) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_USB20_EXTENSION (0x02U) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_SUPERSPEED (0x03U) + +/* USB standard descriptor type */ +#define USB_DESCRIPTOR_TYPE_DEVICE (0x01U) +#define USB_DESCRIPTOR_TYPE_CONFIGURE (0x02U) +#define USB_DESCRIPTOR_TYPE_STRING (0x03U) +#define USB_DESCRIPTOR_TYPE_INTERFACE (0x04U) +#define USB_DESCRIPTOR_TYPE_ENDPOINT (0x05U) +#define USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER (0x06U) +#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION (0x07U) +#define USB_DESCRIPTOR_TYPE_INTERFAACE_POWER (0x08U) +#define USB_DESCRIPTOR_TYPE_OTG (0x09U) +#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION (0x0BU) +#define USB_DESCRIPTOR_TYPE_BOS (0x0F) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY (0x10) + +#define USB_DESCRIPTOR_TYPE_HID (0x21U) +#define USB_DESCRIPTOR_TYPE_HID_REPORT (0x22U) +#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL (0x23U) + +#define USB_DESCRIPTOR_TYPE_ENDPOINT_COMPANION (0x30U) + +/* USB standard request type */ +#define USB_REQUEST_TYPE_DIR_MASK (0x80U) +#define USB_REQUEST_TYPE_DIR_SHIFT (7U) +#define USB_REQUEST_TYPE_DIR_OUT (0x00U) +#define USB_REQUEST_TYPE_DIR_IN (0x80U) + +#define USB_REQUEST_TYPE_TYPE_MASK (0x60U) +#define USB_REQUEST_TYPE_TYPE_SHIFT (5U) +#define USB_REQUEST_TYPE_TYPE_STANDARD (0U) +#define USB_REQUEST_TYPE_TYPE_CLASS (0x20U) +#define USB_REQUEST_TYPE_TYPE_VENDOR (0x40U) + +#define USB_REQUEST_TYPE_RECIPIENT_MASK (0x1FU) +#define USB_REQUEST_TYPE_RECIPIENT_SHIFT (0U) +#define USB_REQUEST_TYPE_RECIPIENT_DEVICE (0x00U) +#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE (0x01U) +#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT (0x02U) +#define USB_REQUEST_TYPE_RECIPIENT_OTHER (0x03U) + +/* USB standard request */ +#define USB_REQUEST_STANDARD_GET_STATUS (0x00U) +#define USB_REQUEST_STANDARD_CLEAR_FEATURE (0x01U) +#define USB_REQUEST_STANDARD_SET_FEATURE (0x03U) +#define USB_REQUEST_STANDARD_SET_ADDRESS (0x05U) +#define USB_REQUEST_STANDARD_GET_DESCRIPTOR (0x06U) +#define USB_REQUEST_STANDARD_SET_DESCRIPTOR (0x07U) +#define USB_REQUEST_STANDARD_GET_CONFIGURATION (0x08U) +#define USB_REQUEST_STANDARD_SET_CONFIGURATION (0x09U) +#define USB_REQUEST_STANDARD_GET_INTERFACE (0x0AU) +#define USB_REQUEST_STANDARD_SET_INTERFACE (0x0BU) +#define USB_REQUEST_STANDARD_SYNCH_FRAME (0x0CU) + +/* USB standard request GET Status */ +#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT (0U) +#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT (1U) + +#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_MASK (0x01U) +#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_SHIFT (0U) + +#define USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR (0xF000U) + +/* USB standard request CLEAR/SET feature */ +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT (0U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE (2U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE (3U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_HNP_SUPPORT (4U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_ALT_HNP_SUPPORT (5U) + +/* USB standard descriptor configure bmAttributes */ +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK (0x80U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_SHIFT (7U) + +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK (0x40U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT (6U) + +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_MASK (0x20U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT (5U) + +/* USB standard descriptor endpoint bmAttributes */ +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK (0x80U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT (7U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT (0U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN (0x80U) + +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK (0x0FU) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_SHFIT (0U) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK (0x03U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_NUMBER_SHFIT (0U) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_MASK (0x0CU) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SHFIT (2U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_NO_SYNC (0x00U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ASYNC (0x04U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ADAPTIVE (0x08U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SYNC (0x0CU) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_MASK (0x30U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_SHFIT (4U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_DATA_ENDPOINT (0x00U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_FEEDBACK_ENDPOINT (0x10U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_IMPLICIT_FEEDBACK_DATA_ENDPOINT (0x20U) + +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK (0x07FFu) +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK (0x1800u) +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT (11U) + +/* USB standard descriptor otg bmAttributes */ +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_SRP_MASK (0x01u) +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_HNP_MASK (0x02u) +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_ADP_MASK (0x04u) + +/* USB standard descriptor device capability usb20 extension bmAttributes */ +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_MASK (0x02U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_SHIFT (1U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_MASK (0x04U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_SHIFT (2U) + +/* Language structure */ +typedef struct _usb_language +{ + uint8_t **string; /* The Strings descriptor array */ + uint32_t *length; /* The strings descriptor length array */ + uint16_t languageId; /* The language id of current language */ +} usb_language_t; + +typedef struct _usb_language_list +{ + uint8_t *languageString; /* The String 0U pointer */ + uint32_t stringLength; /* The String 0U Length */ + usb_language_t *languageList; /* The language list */ + uint8_t count; /* The language count */ +} usb_language_list_t; + +typedef struct _usb_descriptor_common +{ + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* DEVICE Descriptor Type */ + uint8_t bData[1]; /* Data */ +} usb_descriptor_common_t; + +typedef struct _usb_descriptor_device +{ + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* DEVICE Descriptor Type */ + uint8_t bcdUSB[2]; /* UUSB Specification Release Number in Binary-Coded Decimal, e.g. 0x0200U */ + uint8_t bDeviceClass; /* Class code */ + uint8_t bDeviceSubClass; /* Sub-Class code */ + uint8_t bDeviceProtocol; /* Protocol code */ + uint8_t bMaxPacketSize0; /* Maximum packet size for endpoint zero */ + uint8_t idVendor[2]; /* Vendor ID (assigned by the USB-IF) */ + uint8_t idProduct[2]; /* Product ID (assigned by the manufacturer) */ + uint8_t bcdDevice[2]; /* Device release number in binary-coded decimal */ + uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */ + uint8_t iProduct; /* Index of string descriptor describing product */ + uint8_t iSerialNumber; /* Index of string descriptor describing the device serial number */ + uint8_t bNumConfigurations; /* Number of possible configurations */ +} usb_descriptor_device_t; + +typedef struct _usb_descriptor_configuration +{ + uint8_t bLength; /* Descriptor size in bytes = 9U */ + uint8_t bDescriptorType; /* CONFIGURATION type = 2U or 7U */ + uint8_t wTotalLength[2]; /* Length of concatenated descriptors */ + uint8_t bNumInterfaces; /* Number of interfaces, this configuration. */ + uint8_t bConfigurationValue; /* Value to set this configuration. */ + uint8_t iConfiguration; /* Index to configuration string */ + uint8_t bmAttributes; /* Configuration characteristics */ + uint8_t bMaxPower; /* Maximum power from bus, 2 mA units */ +} usb_descriptor_configuration_t; + +typedef struct _usb_descriptor_interface +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_descriptor_interface_t; + +typedef struct _usb_descriptor_endpoint +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint8_t wMaxPacketSize[2]; + uint8_t bInterval; +} usb_descriptor_endpoint_t; + +typedef struct _usb_descriptor_endpoint_companion +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bMaxBurst; + uint8_t bmAttributes; + uint8_t wBytesPerInterval[2]; +} usb_descriptor_endpoint_companion_t; + +typedef struct _usb_descriptor_binary_device_object_store +{ + uint8_t bLength; /* Descriptor size in bytes = 5U */ + uint8_t bDescriptorType; /* BOS Descriptor type = 0FU*/ + uint8_t wTotalLength[2]; /*Length of this descriptor and all of its sub descriptors*/ + uint8_t bNumDeviceCaps; /*The number of separate device capability descriptors in the BOS*/ +} usb_descriptor_bos_t; + +typedef struct _usb_descriptor_usb20_extension +{ + uint8_t bLength; /* Descriptor size in bytes = 7U */ + uint8_t bDescriptorType; /* DEVICE CAPABILITY Descriptor type = 0x10U*/ + uint8_t bDevCapabilityType; /*Length of this descriptor and all of its sub descriptors*/ + uint8_t bmAttributes[4]; /*Bitmap encoding of supported device level features.*/ +} usb_descriptor_usb20_extension_t; +typedef struct _usb_descriptor_super_speed_device_capability +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t bmAttributes; + uint8_t wSpeedsSupported[2]; + uint8_t bFunctionalitySupport; + uint8_t bU1DevExitLat; + uint8_t wU2DevExitLat[2]; +} usb_bos_device_capability_susperspeed_desc_t; +typedef union _usb_descriptor_union +{ + usb_descriptor_common_t common; /* Common descriptor */ + usb_descriptor_device_t device; /* Device descriptor */ + usb_descriptor_configuration_t configuration; /* Configuration descriptor */ + usb_descriptor_interface_t interface; /* Interface descriptor */ + usb_descriptor_endpoint_t endpoint; /* Endpoint descriptor */ + usb_descriptor_endpoint_companion_t endpointCompanion; /* Endpoint companion descriptor */ +} usb_descriptor_union_t; + +#endif /* __USB_SPEC_H__ */ diff --git a/utilities/fsl_assert.c b/utilities/fsl_assert.c new file mode 100644 index 0000000..d2cbe28 --- /dev/null +++ b/utilities/fsl_assert.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_debug_console.h" + +#ifndef NDEBUG +#if (defined(__CC_ARM)) || (defined(__ARMCC_VERSION)) || (defined(__ICCARM__)) +void __aeabi_assert(const char *failedExpr, const char *file, int line) +{ +#if SDK_DEBUGCONSOLE == DEBUGCONSOLE_DISABLE + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line); +#else + (void)PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line); +#endif + + for (;;) + { + __BKPT(0); + } +} +#elif (defined(__GNUC__)) +#if defined(__REDLIB__) +void __assertion_failed(char *failedExpr) +{ + (void)PRINTF("ASSERT ERROR \" %s \n", failedExpr); + for (;;) + { + __BKPT(0); + } +} +#else +void __assert_func(const char *file, int line, const char *func, const char *failedExpr) +{ + (void)PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, + func); + for (;;) + { + __BKPT(0); + } +} +#endif /* defined(__REDLIB__) */ +#endif /* (defined(__CC_ARM) || (defined(__ICCARM__)) || (defined(__ARMCC_VERSION)) */ +#endif /* NDEBUG */ diff --git a/utilities/fsl_debug_console.c b/utilities/fsl_debug_console.c new file mode 100644 index 0000000..d2a0e23 --- /dev/null +++ b/utilities/fsl_debug_console.c @@ -0,0 +1,1821 @@ +/* + * Copyright 2017-2018, 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include +#include +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +#include +#endif +#include +#include "fsl_debug_console.h" +#include "fsl_adapter_uart.h" + +/*! @brief Keil: suppress ellipsis warning in va_arg usage below. */ +#if defined(__CC_ARM) +#pragma diag_suppress 1256 +#endif /* __CC_ARM */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief This definition is maximum line that debugconsole can scanf each time.*/ +#define IO_MAXLINE 20U + +/*! @brief The overflow value.*/ +#ifndef HUGE_VAL +#define HUGE_VAL (99.e99) +#endif /* HUGE_VAL */ + +/*! @brief State structure storing debug console. */ +typedef struct DebugConsoleState +{ + uint8_t uartHandleBuffer[HAL_UART_HANDLE_SIZE]; + hal_uart_status_t (*putChar)(hal_uart_handle_t handle, + const uint8_t *data, + size_t length); /*!< put char function pointer */ + hal_uart_status_t (*getChar)(hal_uart_handle_t handle, + uint8_t *data, + size_t length); /*!< get char function pointer */ + serial_port_type_t type; /*!< The initialized port of the debug console. */ +} debug_console_state_t; + +/*! @brief Type of KSDK printf function pointer. */ +typedef int (*PUTCHAR_FUNC)(int a); + +#if PRINTF_ADVANCED_ENABLE +/*! @brief Specification modifier flags for printf. */ +enum _debugconsole_printf_flag +{ + kPRINTF_Minus = 0x01U, /*!< Minus FLag. */ + kPRINTF_Plus = 0x02U, /*!< Plus Flag. */ + kPRINTF_Space = 0x04U, /*!< Space Flag. */ + kPRINTF_Zero = 0x08U, /*!< Zero Flag. */ + kPRINTF_Pound = 0x10U, /*!< Pound Flag. */ + kPRINTF_LengthChar = 0x20U, /*!< Length: Char Flag. */ + kPRINTF_LengthShortInt = 0x40U, /*!< Length: Short Int Flag. */ + kPRINTF_LengthLongInt = 0x80U, /*!< Length: Long Int Flag. */ + kPRINTF_LengthLongLongInt = 0x100U, /*!< Length: Long Long Int Flag. */ +}; +#endif /* PRINTF_ADVANCED_ENABLE */ + +/*! @brief Specification modifier flags for scanf. */ +enum _debugconsole_scanf_flag +{ + kSCANF_Suppress = 0x2U, /*!< Suppress Flag. */ + kSCANF_DestMask = 0x7cU, /*!< Destination Mask. */ + kSCANF_DestChar = 0x4U, /*!< Destination Char Flag. */ + kSCANF_DestString = 0x8U, /*!< Destination String FLag. */ + kSCANF_DestSet = 0x10U, /*!< Destination Set Flag. */ + kSCANF_DestInt = 0x20U, /*!< Destination Int Flag. */ + kSCANF_DestFloat = 0x30U, /*!< Destination Float Flag. */ + kSCANF_LengthMask = 0x1f00U, /*!< Length Mask Flag. */ +#if SCANF_ADVANCED_ENABLE + kSCANF_LengthChar = 0x100U, /*!< Length Char Flag. */ + kSCANF_LengthShortInt = 0x200U, /*!< Length ShortInt Flag. */ + kSCANF_LengthLongInt = 0x400U, /*!< Length LongInt Flag. */ + kSCANF_LengthLongLongInt = 0x800U, /*!< Length LongLongInt Flag. */ +#endif /* SCANF_ADVANCED_ENABLE */ +#if PRINTF_FLOAT_ENABLE + kSCANF_LengthLongLongDouble = 0x1000U, /*!< Length LongLongDuoble Flag. */ +#endif /*PRINTF_FLOAT_ENABLE */ + kSCANF_TypeSinged = 0x2000U, /*!< TypeSinged Flag. */ +}; + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Debug UART state information. */ +static debug_console_state_t s_debugConsole; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if SDK_DEBUGCONSOLE +static int DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr, const char *fmt, va_list ap); +static int DbgConsole_ScanfFormattedData(const char *line_ptr, char *format, va_list args_ptr); +#endif /* SDK_DEBUGCONSOLE */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/ + +#if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) +/* See fsl_debug_console.h for documentation of this function. */ +status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq) +{ + hal_uart_config_t usrtConfig; + + if (kSerialPort_Uart != device) + { + return kStatus_Fail; + } + + /* Set debug console to initialized to avoid duplicated initialized operation. */ + s_debugConsole.type = device; + + usrtConfig.srcClock_Hz = clkSrcFreq; + usrtConfig.baudRate_Bps = baudRate; + usrtConfig.parityMode = kHAL_UartParityDisabled; + usrtConfig.stopBitCount = kHAL_UartOneStopBit; + usrtConfig.enableRx = 1U; + usrtConfig.enableTx = 1U; + usrtConfig.enableRxRTS = 0U; + usrtConfig.enableTxCTS = 0U; + usrtConfig.instance = instance; +#if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u)) + usrtConfig.txFifoWatermark = 0U; + usrtConfig.rxFifoWatermark = 0U; +#endif + /* Enable clock and initial UART module follow user configure structure. */ + (void)HAL_UartInit((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], &usrtConfig); + /* Set the function pointer for send and receive for this kind of device. */ + s_debugConsole.putChar = HAL_UartSendBlocking; + s_debugConsole.getChar = HAL_UartReceiveBlocking; + + return kStatus_Success; +} + +/* See fsl_debug_console.h for documentation of this function. */ +status_t DbgConsole_Deinit(void) +{ + if (kSerialPort_None == s_debugConsole.type) + { + return kStatus_Success; + } + + (void)HAL_UartDeinit((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0]); + + s_debugConsole.type = kSerialPort_None; + + return kStatus_Success; +} +#endif /* DEBUGCONSOLE_REDIRECT_TO_SDK */ + +#if SDK_DEBUGCONSOLE +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Printf(const char *fmt_s, ...) +{ + va_list ap; + int result; + + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + va_start(ap, fmt_s); + result = DbgConsole_PrintfFormattedData(DbgConsole_Putchar, fmt_s, ap); + va_end(ap); + + return result; +} + +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Putchar(int ch) +{ + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ch), 1); + + return 1; +} + +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Scanf(char *fmt_ptr, ...) +{ + /* Plus one to store end of string char */ + char temp_buf[IO_MAXLINE + 1]; + va_list ap; + int32_t i; + char result; + + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + va_start(ap, fmt_ptr); + temp_buf[0] = '\0'; + + i = 0; + while (true) + { + if (i >= (int32_t)IO_MAXLINE) + { + break; + } + + result = (char)DbgConsole_Getchar(); + temp_buf[i] = result; + + if ((result == '\r') || (result == '\n')) + { + /* End of Line. */ + if (i == 0) + { + temp_buf[i] = '\0'; + i = -1; + } + else + { + break; + } + } + + i++; + } + + if ((i == (int32_t)IO_MAXLINE)) + { + temp_buf[i] = '\0'; + } + else + { + temp_buf[i + 1] = '\0'; + } + result = (char)DbgConsole_ScanfFormattedData(temp_buf, fmt_ptr, ap); + va_end(ap); + + return (int)result; +} + +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Getchar(void) +{ + char ch; + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + while (kStatus_HAL_UartSuccess != + s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ch), 1)) + { + return -1; + } + + return (int)ch; +} + +/*************Code for process formatted data*******************************/ +/*! + * @brief Scanline function which ignores white spaces. + * + * @param[in] s The address of the string pointer to update. + * @return String without white spaces. + */ +static uint32_t DbgConsole_ScanIgnoreWhiteSpace(const char **s) +{ + uint8_t count = 0; + char c; + + c = **s; + while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f')) + { + count++; + (*s)++; + c = **s; + } + return count; +} + +/*! + * @brief This function puts padding character. + * + * @param[in] c Padding character. + * @param[in] curlen Length of current formatted string . + * @param[in] width Width of expected formatted string. + * @param[in] count Number of characters. + * @param[in] func_ptr Function to put character out. + */ +static void DbgConsole_PrintfPaddingCharacter( + char c, int32_t curlen, int32_t width, int32_t *count, PUTCHAR_FUNC func_ptr) +{ + int32_t i; + + for (i = curlen; i < width; i++) + { + (void)func_ptr(c); + (*count)++; + } +} + +/*! + * @brief Converts a radix number to a string and return its length. + * + * @param[in] numstr Converted string of the number. + * @param[in] nump Pointer to the number. + * @param[in] neg Polarity of the number. + * @param[in] radix The radix to be converted to. + * @param[in] use_caps Used to identify %x/X output format. + + * @return Length of the converted string. + */ +static int32_t DbgConsole_ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps) +{ +#if PRINTF_ADVANCED_ENABLE + int64_t a; + int64_t b; + int64_t c; + + uint64_t ua; + uint64_t ub; + uint64_t uc; +#else + int32_t a; + int32_t b; + int32_t c; + + uint32_t ua; + uint32_t ub; + uint32_t uc; +#endif /* PRINTF_ADVANCED_ENABLE */ + + int32_t nlen; + char *nstrp; + + nlen = 0; + nstrp = numstr; + *nstrp++ = '\0'; + + if (0 != neg) + { +#if PRINTF_ADVANCED_ENABLE + a = *(int64_t *)nump; +#else + a = *(int32_t *)nump; +#endif /* PRINTF_ADVANCED_ENABLE */ + if (a == 0) + { + *nstrp = '0'; + ++nlen; + return nlen; + } + while (a != 0) + { +#if PRINTF_ADVANCED_ENABLE + b = (int64_t)a / (int64_t)radix; + c = (int64_t)a - ((int64_t)b * (int64_t)radix); + if (c < 0) + { + c = (int64_t)'0' - c; + } +#else + b = a / radix; + c = a - (b * radix); + if (c < 0) + { + c = (int32_t)'0' - c; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + else + { + c = c + '0'; + } + a = b; + *nstrp++ = (char)c; + ++nlen; + } + } + else + { +#if PRINTF_ADVANCED_ENABLE + ua = *(uint64_t *)nump; +#else + ua = *(uint32_t *)nump; +#endif /* PRINTF_ADVANCED_ENABLE */ + if (ua == 0U) + { + *nstrp = '0'; + ++nlen; + return nlen; + } + while (ua != 0U) + { +#if PRINTF_ADVANCED_ENABLE + ub = (uint64_t)ua / (uint64_t)radix; + uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix); +#else + ub = ua / (uint32_t)radix; + uc = ua - (ub * (uint32_t)radix); +#endif /* PRINTF_ADVANCED_ENABLE */ + + if (uc < 10U) + { + uc = uc + '0'; + } + else + { + uc = uc - 10U + (use_caps ? 'A' : 'a'); + } + ua = ub; + *nstrp++ = (char)uc; + ++nlen; + } + } + return nlen; +} + +#if PRINTF_FLOAT_ENABLE +/*! + * @brief Converts a floating radix number to a string and return its length. + * + * @param[in] numstr Converted string of the number. + * @param[in] nump Pointer to the number. + * @param[in] radix The radix to be converted to. + * @param[in] precision_width Specify the precision width. + + * @return Length of the converted string. + */ +static int32_t DbgConsole_ConvertFloatRadixNumToString(char *numstr, + void *nump, + int32_t radix, + uint32_t precision_width) +{ + int32_t a; + int32_t b; + int32_t c; + uint32_t i; + double fa; + double dc; + double fb; + double r; + double fractpart; + double intpart; + + int32_t nlen; + char *nstrp; + nlen = 0; + nstrp = numstr; + *nstrp++ = '\0'; + r = *(double *)nump; + if (0.0 == r) + { + *nstrp = '0'; + ++nlen; + return nlen; + } + fractpart = modf((double)r, (double *)&intpart); + /* Process fractional part. */ + for (i = 0; i < precision_width; i++) + { + fractpart *= (double)radix; + } + if (r >= 0.0) + { + fa = fractpart + (double)0.5; + if (fa >= pow((double)10, (double)precision_width)) + { + intpart++; + } + } + else + { + fa = fractpart - (double)0.5; + if (fa <= -pow((double)10, (double)precision_width)) + { + intpart--; + } + } + for (i = 0; i < precision_width; i++) + { + fb = fa / (double)radix; + dc = (fa - (double)(int64_t)fb * (double)radix); + c = (int32_t)dc; + if (c < 0) + { + c = (int32_t)'0' - c; + } + else + { + c = c + '0'; + } + fa = fb; + *nstrp++ = (char)c; + ++nlen; + } + *nstrp++ = (char)'.'; + ++nlen; + a = (int32_t)intpart; + if (a == 0) + { + *nstrp++ = '0'; + ++nlen; + } + else + { + while (a != 0) + { + b = (int32_t)a / (int32_t)radix; + c = (int32_t)a - ((int32_t)b * (int32_t)radix); + if (c < 0) + { + c = (int32_t)'0' - c; + } + else + { + c = c + '0'; + } + a = b; + *nstrp++ = (char)c; + ++nlen; + } + } + return nlen; +} +#endif /* PRINTF_FLOAT_ENABLE */ + +/*! + * @brief This function outputs its parameters according to a formatted string. + * + * @note I/O is performed by calling given function pointer using following + * (*func_ptr)(c); + * + * @param[in] func_ptr Function to put character out. + * @param[in] fmt_ptr Format string for printf. + * @param[in] args_ptr Arguments to printf. + * + * @return Number of characters + */ +static int DbgConsole_PrintfFormattedData(PUTCHAR_FUNC func_ptr, const char *fmt, va_list ap) +{ + /* va_list ap; */ + const char *p; + char c; + + char vstr[33]; + char *vstrp = NULL; + int32_t vlen = 0; + + bool done; + int32_t count = 0; + + uint32_t field_width; + uint32_t precision_width; + char *sval; + int32_t cval; + bool use_caps; + uint8_t radix = 0; + +#if PRINTF_ADVANCED_ENABLE + uint32_t flags_used; + char schar; + bool dschar; + int64_t ival; + uint64_t uval = 0; + bool valid_precision_width; +#else + int32_t ival; + uint32_t uval = 0; +#endif /* PRINTF_ADVANCED_ENABLE */ + +#if PRINTF_FLOAT_ENABLE + double fval; +#endif /* PRINTF_FLOAT_ENABLE */ + + /* Start parsing apart the format string and display appropriate formats and data. */ + p = fmt; + while (true) + { + if ('\0' == *p) + { + break; + } + c = *p; + /* + * All formats begin with a '%' marker. Special chars like + * '\n' or '\t' are normally converted to the appropriate + * character by the __compiler__. Thus, no need for this + * routine to account for the '\' character. + */ + if (c != '%') + { + (void)func_ptr(c); + count++; + p++; + /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */ + continue; + } + + use_caps = true; + +#if PRINTF_ADVANCED_ENABLE + /* First check for specification modifier flags. */ + flags_used = 0; + done = false; + while (!done) + { + switch (*++p) + { + case '-': + flags_used |= (uint32_t)kPRINTF_Minus; + break; + case '+': + flags_used |= (uint32_t)kPRINTF_Plus; + break; + case ' ': + flags_used |= (uint32_t)kPRINTF_Space; + break; + case '0': + flags_used |= (uint32_t)kPRINTF_Zero; + break; + case '#': + flags_used |= (uint32_t)kPRINTF_Pound; + break; + default: + /* We've gone one char too far. */ + --p; + done = true; + break; + } + } +#endif /* PRINTF_ADVANCED_ENABLE */ + + /* Next check for minimum field width. */ + field_width = 0; + done = false; + while (!done) + { + c = *++p; + if ((c >= '0') && (c <= '9')) + { + field_width = (field_width * 10U) + ((uint32_t)c - (uint32_t)'0'); + } +#if PRINTF_ADVANCED_ENABLE + else if (c == '*') + { + field_width = (uint32_t)va_arg(ap, uint32_t); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + else + { + /* We've gone one char too far. */ + --p; + done = true; + } + } + /* Next check for the width and precision field separator. */ +#if (PRINTF_ADVANCED_ENABLE || PRINTF_FLOAT_ENABLE) + precision_width = 6U; /* MISRA C-2012 Rule 2.2 */ +#endif +#if PRINTF_ADVANCED_ENABLE + valid_precision_width = false; +#endif /* PRINTF_ADVANCED_ENABLE */ + if (*++p == '.') + { + /* Must get precision field width, if present. */ + precision_width = 0U; + done = false; + while (!done) + { + c = *++p; + if ((c >= '0') && (c <= '9')) + { + precision_width = (precision_width * 10U) + ((uint32_t)c - (uint32_t)'0'); +#if PRINTF_ADVANCED_ENABLE + valid_precision_width = true; +#endif /* PRINTF_ADVANCED_ENABLE */ + } +#if PRINTF_ADVANCED_ENABLE + else if (c == '*') + { + precision_width = (uint32_t)va_arg(ap, uint32_t); + valid_precision_width = true; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + else + { + /* We've gone one char too far. */ + --p; + done = true; + } + } + } + else + { + /* We've gone one char too far. */ + --p; + } +#if PRINTF_ADVANCED_ENABLE + /* + * Check for the length modifier. + */ + switch (/* c = */ *++p) + { + case 'h': + if (*++p != 'h') + { + flags_used |= (uint32_t)kPRINTF_LengthShortInt; + --p; + } + else + { + flags_used |= (uint32_t)kPRINTF_LengthChar; + } + break; + case 'l': + if (*++p != 'l') + { + flags_used |= (uint32_t)kPRINTF_LengthLongInt; + --p; + } + else + { + flags_used |= (uint32_t)kPRINTF_LengthLongLongInt; + } + break; + default: + /* we've gone one char too far */ + --p; + break; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + /* Now we're ready to examine the format. */ + c = *++p; + { + if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') || + (c == 'b') || (c == 'p') || (c == 'u')) + { + if ((c == 'd') || (c == 'i')) + { +#if PRINTF_ADVANCED_ENABLE + if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongLongInt)) + { + ival = (int64_t)va_arg(ap, int64_t); + } + else +#endif /* PRINTF_ADVANCED_ENABLE */ + { + ival = (int32_t)va_arg(ap, int32_t); + } + vlen = DbgConsole_ConvertRadixNumToString(vstr, &ival, 1, 10, use_caps); + vstrp = &vstr[vlen]; +#if PRINTF_ADVANCED_ENABLE + if (ival < 0) + { + schar = '-'; + ++vlen; + } + else + { + if (0U != (flags_used & (uint32_t)kPRINTF_Plus)) + { + schar = '+'; + ++vlen; + } + else + { + if (0U != (flags_used & (uint32_t)kPRINTF_Space)) + { + schar = ' '; + ++vlen; + } + else + { + schar = '\0'; + } + } + } + dschar = false; + /* Do the ZERO pad. */ + if (0U != (flags_used & (uint32_t)kPRINTF_Zero)) + { + if ('\0' != schar) + { + (void)func_ptr(schar); + count++; + } + dschar = true; + + DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr); + vlen = (int32_t)field_width; + } + else + { + if (0U == (flags_used & (uint32_t)kPRINTF_Minus)) + { + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + if ('\0' != schar) + { + (void)func_ptr(schar); + count++; + } + dschar = true; + } + } + /* The string was built in reverse order, now display in correct order. */ + if ((!dschar) && ('\0' != schar)) + { + (void)func_ptr(schar); + count++; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + +#if PRINTF_FLOAT_ENABLE + if ((c == 'f') || (c == 'F')) + { + fval = (double)va_arg(ap, double); + vlen = DbgConsole_ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width); + vstrp = &vstr[vlen]; + +#if PRINTF_ADVANCED_ENABLE + if (fval < 0.0) + { + schar = '-'; + ++vlen; + } + else + { + if (0U != (flags_used & (uint32_t)kPRINTF_Plus)) + { + schar = '+'; + ++vlen; + } + else + { + if (0U != (flags_used & (uint32_t)kPRINTF_Space)) + { + schar = ' '; + ++vlen; + } + else + { + schar = '\0'; + } + } + } + dschar = false; + if (0U != (flags_used & (uint32_t)kPRINTF_Zero)) + { + if ('\0' != schar) + { + (void)func_ptr(schar); + count++; + } + dschar = true; + DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr); + vlen = (int32_t)field_width; + } + else + { + if (0U == (flags_used & (uint32_t)kPRINTF_Minus)) + { + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + if (schar) + { + (void)func_ptr(schar); + count++; + } + dschar = true; + } + } + if ((!dschar) && schar) + { + (void)func_ptr(schar); + count++; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } +#endif /* PRINTF_FLOAT_ENABLE */ + if ((c == 'X') || (c == 'x')) + { + if (c == 'x') + { + use_caps = false; + } +#if PRINTF_ADVANCED_ENABLE + if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongLongInt)) + { + uval = (uint64_t)va_arg(ap, uint64_t); + } + else +#endif /* PRINTF_ADVANCED_ENABLE */ + { + uval = (uint32_t)va_arg(ap, uint32_t); + } + vlen = DbgConsole_ConvertRadixNumToString(vstr, &uval, 0, 16, use_caps); + vstrp = &vstr[vlen]; + +#if PRINTF_ADVANCED_ENABLE + dschar = false; + if (0U != (flags_used & (uint32_t)kPRINTF_Zero)) + { + if (0U != (flags_used & (uint32_t)kPRINTF_Pound)) + { + (void)func_ptr('0'); + (void)func_ptr((use_caps ? 'X' : 'x')); + count += 2; + /*vlen += 2;*/ + dschar = true; + } + DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr); + vlen = (int32_t)field_width; + } + else + { + if (0U == (flags_used & (uint32_t)kPRINTF_Pound)) + { + if (0U != (flags_used & (uint32_t)kPRINTF_Pound)) + { + vlen += 2; + } + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + if (0U != (flags_used & (uint32_t)kPRINTF_Pound)) + { + (void)func_ptr('0'); + (void)func_ptr(use_caps ? 'X' : 'x'); + count += 2; + + dschar = true; + } + } + } + + if ((0U != (flags_used & (uint32_t)kPRINTF_Pound)) && (!dschar)) + { + (void)func_ptr('0'); + (void)func_ptr(use_caps ? 'X' : 'x'); + count += 2; + vlen += 2; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u')) + { +#if PRINTF_ADVANCED_ENABLE + if (0U != (flags_used & (uint32_t)kPRINTF_LengthLongLongInt)) + { + uval = (uint64_t)va_arg(ap, uint64_t); + } + else +#endif /* PRINTF_ADVANCED_ENABLE */ + { + uval = (uint32_t)va_arg(ap, uint32_t); + } + switch (c) + { + case 'o': + radix = 8; + break; + case 'b': + radix = 2; + break; + case 'p': + radix = 16; + break; + case 'u': + radix = 10; + break; + default: + /* MISRA C-2012 Rule 16.4 */ + break; + } + vlen = DbgConsole_ConvertRadixNumToString(vstr, &uval, 0, (int32_t)radix, use_caps); + vstrp = &vstr[vlen]; +#if PRINTF_ADVANCED_ENABLE + if (0U != (flags_used & (uint32_t)kPRINTF_Zero)) + { + DbgConsole_PrintfPaddingCharacter('0', vlen, (int32_t)field_width, &count, func_ptr); + vlen = (int32_t)field_width; + } + else + { + if (0U == (flags_used & (uint32_t)kPRINTF_Minus)) + { + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + } + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } +#if !PRINTF_ADVANCED_ENABLE + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); +#endif /* !PRINTF_ADVANCED_ENABLE */ + if (vstrp != NULL) + { + while ('\0' != *vstrp) + { + (void)func_ptr(*vstrp--); + count++; + } + } +#if PRINTF_ADVANCED_ENABLE + if (0U != (flags_used & (uint32_t)kPRINTF_Minus)) + { + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + else if (c == 'c') + { + cval = (int32_t)va_arg(ap, uint32_t); + (void)func_ptr(cval); + count++; + } + else if (c == 's') + { + sval = (char *)va_arg(ap, char *); + if (NULL != sval) + { +#if PRINTF_ADVANCED_ENABLE + if (valid_precision_width) + { + vlen = (int32_t)precision_width; + } + else + { + vlen = (int32_t)strlen(sval); + } +#else + vlen = (int32_t)strlen(sval); +#endif /* PRINTF_ADVANCED_ENABLE */ +#if PRINTF_ADVANCED_ENABLE + if (0U == (flags_used & (uint32_t)kPRINTF_Minus)) +#endif /* PRINTF_ADVANCED_ENABLE */ + { + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + } + +#if PRINTF_ADVANCED_ENABLE + if (valid_precision_width) + { + while (('\0' != *sval) && (vlen > 0)) + { + (void)func_ptr(*sval++); + count++; + vlen--; + } + /* In case that vlen sval is shorter than vlen */ + vlen = (int32_t)precision_width - vlen; + } + else + { +#endif /* PRINTF_ADVANCED_ENABLE */ + while ('\0' != *sval) + { + (void)func_ptr(*sval++); + count++; + } +#if PRINTF_ADVANCED_ENABLE + } +#endif /* PRINTF_ADVANCED_ENABLE */ + +#if PRINTF_ADVANCED_ENABLE + if (0U != (flags_used & (uint32_t)kPRINTF_Minus)) + { + DbgConsole_PrintfPaddingCharacter(' ', vlen, (int32_t)field_width, &count, func_ptr); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + } + else + { + (void)func_ptr(c); + count++; + } + } + p++; + } + return count; +} + +/*! + * @brief Converts an input line of ASCII characters based upon a provided + * string format. + * + * @param[in] line_ptr The input line of ASCII data. + * @param[in] format Format first points to the format string. + * @param[in] args_ptr The list of parameters. + * + * @return Number of input items converted and assigned. + * @retval IO_EOF When line_ptr is empty string "". + */ +static int DbgConsole_ScanfFormattedData(const char *line_ptr, char *format, va_list args_ptr) +{ + uint8_t base; + int8_t neg; + /* Identifier for the format string. */ + char *c = format; + char temp; + char *buf; + /* Flag telling the conversion specification. */ + uint32_t flag = 0; + /* Filed width for the matching input streams. */ + uint32_t field_width; + /* How many arguments are assigned except the suppress. */ + uint32_t nassigned = 0; + bool match_failure = false; + /* How many characters are read from the input streams. */ + uint32_t n_decode = 0; + + int32_t val; + + const char *s; + /* Identifier for the input string. */ + const char *p = line_ptr; + +#if SCANF_FLOAT_ENABLE + double fnum = 0.0; +#endif /* SCANF_FLOAT_ENABLE */ + + /* Return EOF error before any conversion. */ + if (*p == '\0') + { + return -1; + } + + /* Decode directives. */ + while (('\0' != (*c)) && ('\0' != (*p))) + { + /* Ignore all white-spaces in the format strings. */ + if (0U != DbgConsole_ScanIgnoreWhiteSpace((const char **)(void *)&c)) + { + n_decode += DbgConsole_ScanIgnoreWhiteSpace(&p); + } + else if ((*c != '%') || ((*c == '%') && (*(c + 1) == '%'))) + { + /* Ordinary characters. */ + c++; + if (*p == *c) + { + n_decode++; + p++; + c++; + } + else + { + /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream. + * However, it is deserted now. */ + break; + } + } + else + { + /* convernsion specification */ + c++; + /* Reset. */ + flag = 0; + field_width = 0; + base = 0; + + /* Loop to get full conversion specification. */ + while (('\0' != *c) && (0U == (flag & (uint32_t)kSCANF_DestMask))) + { + switch (*c) + { +#if SCANF_ADVANCED_ENABLE + case '*': + if (0U != (flag & (uint32_t)kSCANF_Suppress)) + { + /* Match failure. */ + match_failure = true; + break; + } + flag |= (uint32_t)kSCANF_Suppress; + c++; + break; + case 'h': + if (0U != (flag & (uint32_t)kSCANF_LengthMask)) + { + /* Match failure. */ + match_failure = true; + break; + } + + if (c[1] == 'h') + { + flag |= (uint32_t)kSCANF_LengthChar; + c++; + } + else + { + flag |= (uint32_t)kSCANF_LengthShortInt; + } + c++; + break; + case 'l': + if (0U != (flag & (uint32_t)kSCANF_LengthMask)) + { + /* Match failure. */ + match_failure = true; + break; + } + + if (c[1] == 'l') + { + flag |= (uint32_t)kSCANF_LengthLongLongInt; + c++; + } + else + { + flag |= (uint32_t)kSCANF_LengthLongInt; + } + c++; + break; +#endif /* SCANF_ADVANCED_ENABLE */ +#if SCANF_FLOAT_ENABLE + case 'L': + if (flag & (uint32_t)kSCANF_LengthMask) + { + /* Match failure. */ + match_failure = true; + break; + } + flag |= (uint32_t)kSCANF_LengthLongLongDouble; + c++; + break; +#endif /* SCANF_FLOAT_ENABLE */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (0U != field_width) + { + /* Match failure. */ + match_failure = true; + break; + } + do + { + field_width = field_width * 10U + ((uint32_t)*c - (uint32_t)'0'); + c++; + } while ((*c >= '0') && (*c <= '9')); + break; + case 'd': + base = 10; + flag |= (uint32_t)kSCANF_TypeSinged; + flag |= (uint32_t)kSCANF_DestInt; + c++; + break; + case 'u': + base = 10; + flag |= (uint32_t)kSCANF_DestInt; + c++; + break; + case 'o': + base = 8; + flag |= (uint32_t)kSCANF_DestInt; + c++; + break; + case 'x': + case 'X': + base = 16; + flag |= (uint32_t)kSCANF_DestInt; + c++; + break; + case 'i': + base = 0; + flag |= (uint32_t)kSCANF_DestInt; + c++; + break; +#if SCANF_FLOAT_ENABLE + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + flag |= kSCANF_DestFloat; + c++; + break; +#endif /* SCANF_FLOAT_ENABLE */ + case 'c': + flag |= (uint32_t)kSCANF_DestChar; + if (0U == field_width) + { + field_width = 1; + } + c++; + break; + case 's': + flag |= (uint32_t)kSCANF_DestString; + c++; + break; + default: + /* Match failure. */ + match_failure = true; + break; + } + + /* Match failure. */ + if (match_failure) + { + return (int)nassigned; + } + } + + if (0U == (flag & (uint32_t)kSCANF_DestMask)) + { + /* Format strings are exhausted. */ + return (int)nassigned; + } + + if (0U == field_width) + { + /* Large than length of a line. */ + field_width = 99; + } + + /* Matching strings in input streams and assign to argument. */ + switch (flag & (uint32_t)kSCANF_DestMask) + { + case (uint32_t)kSCANF_DestChar: + s = (const char *)p; + buf = va_arg(args_ptr, char *); + while (((field_width--) > 0U) && ('\0' != *p)) + { + if (0U == (flag & (uint32_t)kSCANF_Suppress)) + { + *buf++ = *p++; + } + else + { + p++; + } + n_decode++; + } + + if ((0U == (flag & (uint32_t)kSCANF_Suppress)) && (s != p)) + { + nassigned++; + } + break; + case (uint32_t)kSCANF_DestString: + n_decode += DbgConsole_ScanIgnoreWhiteSpace(&p); + s = p; + buf = va_arg(args_ptr, char *); + while ((field_width-- > 0U) && (*p != '\0') && (*p != ' ') && (*p != '\t') && (*p != '\n') && + (*p != '\r') && (*p != '\v') && (*p != '\f')) + { + if (0U != (flag & (uint32_t)kSCANF_Suppress)) + { + p++; + } + else + { + *buf++ = *p++; + } + n_decode++; + } + + if ((0U == (flag & (uint32_t)kSCANF_Suppress)) && (s != p)) + { + /* Add NULL to end of string. */ + *buf = '\0'; + nassigned++; + } + break; + case (uint32_t)kSCANF_DestInt: + n_decode += DbgConsole_ScanIgnoreWhiteSpace(&p); + s = p; + val = 0; + if ((base == 0U) || (base == 16U)) + { + if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) + { + base = 16U; + if (field_width >= 1U) + { + p += 2; + n_decode += 2U; + field_width -= 2U; + } + } + } + + if (base == 0U) + { + if (s[0] == '0') + { + base = 8U; + } + else + { + base = 10U; + } + } + + neg = 1; + switch (*p) + { + case '-': + neg = -1; + n_decode++; + p++; + field_width--; + break; + case '+': + neg = 1; + n_decode++; + p++; + field_width--; + break; + default: + /* MISRA C-2012 Rule 16.4 */ + break; + } + + while ((field_width-- > 0U) && (*p > '\0')) + { + if ((*p <= '9') && (*p >= '0')) + { + temp = *p - '0' + (char)0; + } + else if ((*p <= 'f') && (*p >= 'a')) + { + temp = *p - 'a' + (char)10; + } + else if ((*p <= 'F') && (*p >= 'A')) + { + temp = *p - 'A' + (char)10; + } + else + { + temp = (char)base; + } + + if ((uint8_t)temp >= base) + { + break; + } + else + { + val = (int32_t)base * val + (int32_t)temp; + } + p++; + n_decode++; + } + val *= neg; + if (0U == (flag & (uint32_t)kSCANF_Suppress)) + { +#if SCANF_ADVANCED_ENABLE + switch (flag & (uint32_t)kSCANF_LengthMask) + { + case (uint32_t)kSCANF_LengthChar: + if (0U != (flag & (uint32_t)kSCANF_TypeSinged)) + { + *va_arg(args_ptr, signed char *) = (signed char)val; + } + else + { + *va_arg(args_ptr, unsigned char *) = (unsigned char)val; + } + break; + case (uint32_t)kSCANF_LengthShortInt: + if (0U != (flag & (uint32_t)kSCANF_TypeSinged)) + { + *va_arg(args_ptr, signed short *) = (signed short)val; + } + else + { + *va_arg(args_ptr, unsigned short *) = (unsigned short)val; + } + break; + case (uint32_t)kSCANF_LengthLongInt: + if (0U != (flag & (uint32_t)kSCANF_TypeSinged)) + { + *va_arg(args_ptr, signed long int *) = (signed long int)val; + } + else + { + *va_arg(args_ptr, unsigned long int *) = (unsigned long int)val; + } + break; + case (uint32_t)kSCANF_LengthLongLongInt: + if (0U != (flag & (uint32_t)kSCANF_TypeSinged)) + { + *va_arg(args_ptr, signed long long int *) = (signed long long int)val; + } + else + { + *va_arg(args_ptr, unsigned long long int *) = (unsigned long long int)val; + } + break; + default: + /* The default type is the type int. */ + if (0U != (flag & (uint32_t)kSCANF_TypeSinged)) + { + *va_arg(args_ptr, signed int *) = (signed int)val; + } + else + { + *va_arg(args_ptr, unsigned int *) = (unsigned int)val; + } + break; + } +#else + /* The default type is the type int. */ + if (0U != (flag & (uint32_t)kSCANF_TypeSinged)) + { + *va_arg(args_ptr, signed int *) = (signed int)val; + } + else + { + *va_arg(args_ptr, unsigned int *) = (unsigned int)val; + } +#endif /* SCANF_ADVANCED_ENABLE */ + nassigned++; + } + break; +#if SCANF_FLOAT_ENABLE + case (uint32_t)kSCANF_DestFloat: + n_decode += DbgConsole_ScanIgnoreWhiteSpace(&p); + fnum = strtod(p, (char **)&s); + + if ((fnum >= HUGE_VAL) || (fnum <= -HUGE_VAL)) + { + break; + } + + n_decode += (int)(s) - (int)(p); + p = s; + if (0U == (flag & (uint32_t)kSCANF_Suppress)) + { + if (0U != (flag & (uint32_t)kSCANF_LengthLongLongDouble)) + { + *va_arg(args_ptr, double *) = fnum; + } + else + { + *va_arg(args_ptr, float *) = (float)fnum; + } + nassigned++; + } + break; +#endif /* SCANF_FLOAT_ENABLE */ + default: + /* Match failure. */ + match_failure = true; + break; + } + + /* Match failure. */ + if (match_failure) + { + return (int)nassigned; + } + } + } + return (int)nassigned; +} +#endif /* SDK_DEBUGCONSOLE */ + +/*************Code to support toolchain's printf, scanf *******************************/ +/* These function __write and __read is used to support IAR toolchain to printf and scanf*/ +#if (defined(__ICCARM__)) +#if defined(SDK_DEBUGCONSOLE_UART) +#pragma weak __write +size_t __write(int handle, const unsigned char *buffer, size_t size); +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t ret; + if (NULL == buffer) + { + /* + * This means that we should flush internal buffers. Since we don't we just return. + * (Remember, "handle" == -1 means that all handles should be flushed.) + */ + ret = (size_t)0; + } + else if ((handle != 1) && (handle != 2)) + { + /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. + */ + ret = (size_t)-1; + } + else if (kSerialPort_None == s_debugConsole.type) + { + /* Do nothing if the debug UART is not initialized. */ + ret = (size_t)-1; + } + else + { + /* Send data. */ + (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], buffer, size); + ret = size; + } + return ret; +} + +#pragma weak __read +size_t __read(int handle, unsigned char *buffer, size_t size); +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + size_t ret; + /* This function only reads from "standard in", for all other file handles it returns failure. */ + if (handle != 0) + { + ret = ((size_t)-1); + } + else if (kSerialPort_None == s_debugConsole.type) + { + /* Do nothing if the debug UART is not initialized. */ + ret = ((size_t)-1); + } + else + { + /* Receive data. */ + (void)s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], buffer, size); + ret = size; + } + return ret; +} +#endif /* SDK_DEBUGCONSOLE_UART */ + +/* support LPC Xpresso with RedLib */ +#elif (defined(__REDLIB__)) + +#if (defined(SDK_DEBUGCONSOLE_UART)) +int __attribute__((weak)) __sys_write(int handle, char *buffer, int size) +{ + if (NULL == buffer) + { + /* return -1 if error. */ + return -1; + } + + /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ + if ((handle != 1) && (handle != 2)) + { + return -1; + } + + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + + /* Send data. */ + (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size); + + return 0; +} + +int __attribute__((weak)) __sys_readc(void) +{ + char tmp; + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + + /* Receive data. */ + s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)&tmp, sizeof(tmp)); + + return tmp; +} +#endif /* SDK_DEBUGCONSOLE_UART */ + +/* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/ +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +#if defined(SDK_DEBUGCONSOLE_UART) +#if defined(__CC_ARM) +struct __FILE +{ + int handle; + /* + * Whatever you require here. If the only file you are using is standard output using printf() for debugging, + * no file handling is required. + */ +}; +#endif + +/* FILE is typedef in stdio.h. */ +#pragma weak __stdout +#pragma weak __stdin +FILE __stdout; +FILE __stdin; + +#pragma weak fputc +int fputc(int ch, FILE *f) +{ + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + + /* Send data. */ + (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ch), 1); + return 1; +} + +#pragma weak fgetc +int fgetc(FILE *f) +{ + char ch; + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + + /* Receive data. */ + s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ch), 1); + return ch; +} + +/* + * Terminate the program, passing a return code back to the user. + * This function may not return. + */ +void _sys_exit(int returncode) +{ + while (1) + { + } +} + +/* + * Writes a character to the output channel. This function is used + * for last-resort error message output. + */ +void _ttywrch(int ch) +{ + char ench = ch; + /* Send data. */ + s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)(&ench), 1); +} + +char *_sys_command_string(char *cmd, int len) +{ + return (cmd); +} +#endif /* SDK_DEBUGCONSOLE_UART */ + +/* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/ +#elif (defined(__GNUC__)) + +#if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \ + (defined(__MCUXPRESSO) && (defined(SDK_DEBUGCONSOLE_UART)))) +int __attribute__((weak)) _write(int handle, char *buffer, int size); +int __attribute__((weak)) _write(int handle, char *buffer, int size) +{ + if (NULL == buffer) + { + /* return -1 if error. */ + return -1; + } + + /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ + if ((handle != 1) && (handle != 2)) + { + return -1; + } + + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + + /* Send data. */ + (void)s_debugConsole.putChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size); + + return size; +} + +int __attribute__((weak)) _read(int handle, char *buffer, int size); +int __attribute__((weak)) _read(int handle, char *buffer, int size) +{ + /* This function only reads from "standard in", for all other file handles it returns failure. */ + if (handle != 0) + { + return -1; + } + + /* Do nothing if the debug UART is not initialized. */ + if (kSerialPort_None == s_debugConsole.type) + { + return -1; + } + + /* Receive data. */ + (void)s_debugConsole.getChar((hal_uart_handle_t)&s_debugConsole.uartHandleBuffer[0], (uint8_t *)buffer, size); + return size; +} +#endif + +#endif /* __ICCARM__ */ diff --git a/utilities/fsl_debug_console.h b/utilities/fsl_debug_console.h new file mode 100644 index 0000000..755b434 --- /dev/null +++ b/utilities/fsl_debug_console.h @@ -0,0 +1,224 @@ +/* + * Copyright 2017-2018, 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Debug console shall provide input and output functions to scan and print formatted data. + * o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier" + * - [flags] :'-', '+', '#', ' ', '0' + * - [width]: number (0,1...) + * - [.precision]: number (0,1...) + * - [length]: do not support + * - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n' + * o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier" + * - [*]: is supported. + * - [width]: number (0,1...) + * - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t') + * - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's' + */ + +#ifndef _FSL_DEBUGCONSOLE_H_ +#define _FSL_DEBUGCONSOLE_H_ + +#include "fsl_common.h" + +/* + * @addtogroup debugconsole + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Definition select redirect toolchain printf, scanf to uart or not. */ +#define DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN 0U /*!< Select toolchain printf and scanf. */ +#define DEBUGCONSOLE_REDIRECT_TO_SDK 1U /*!< Select SDK version printf, scanf. */ +#define DEBUGCONSOLE_DISABLE 2U /*!< Disable debugconsole function. */ + +/*! @brief Definition to select sdk or toolchain printf, scanf. */ +#ifndef SDK_DEBUGCONSOLE +#define SDK_DEBUGCONSOLE DEBUGCONSOLE_REDIRECT_TO_SDK +#endif + +#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE) +#include +#endif + +/*! @brief Definition to printf the float number. */ +#ifndef PRINTF_FLOAT_ENABLE +#define PRINTF_FLOAT_ENABLE 0U +#endif /* PRINTF_FLOAT_ENABLE */ + +/*! @brief Definition to scanf the float number. */ +#ifndef SCANF_FLOAT_ENABLE +#define SCANF_FLOAT_ENABLE 0U +#endif /* SCANF_FLOAT_ENABLE */ + +/*! @brief Definition to support advanced format specifier for printf. */ +#ifndef PRINTF_ADVANCED_ENABLE +#define PRINTF_ADVANCED_ENABLE 0U +#endif /* PRINTF_ADVANCED_ENABLE */ + +/*! @brief Definition to support advanced format specifier for scanf. */ +#ifndef SCANF_ADVANCED_ENABLE +#define SCANF_ADVANCED_ENABLE 0U +#endif /* SCANF_ADVANCED_ENABLE */ + +/*! @brief Definition to select redirect toolchain printf, scanf to uart or not. + * + * if SDK_DEBUGCONSOLE defined to 0,it represents select toolchain printf, scanf. + * if SDK_DEBUGCONSOLE defined to 1,it represents select SDK version printf, scanf. + * if SDK_DEBUGCONSOLE defined to 2,it represents disable debugconsole function. + */ +#if SDK_DEBUGCONSOLE == DEBUGCONSOLE_DISABLE /* Disable debug console */ +#define PRINTF +#define SCANF +#define PUTCHAR +#define GETCHAR +#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK /* Select printf, scanf, putchar, getchar of SDK version. */ +#define PRINTF DbgConsole_Printf +#define SCANF DbgConsole_Scanf +#define PUTCHAR DbgConsole_Putchar +#define GETCHAR DbgConsole_Getchar +#elif SDK_DEBUGCONSOLE == \ + DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN /* Select printf, scanf, putchar, getchar of toolchain. \ */ +#define PRINTF printf +#define SCANF scanf +#define PUTCHAR putchar +#define GETCHAR getchar +#endif /* SDK_DEBUGCONSOLE */ + +typedef enum _serial_port_type +{ + kSerialPort_None = 0U, /*!< Serial port is none */ + kSerialPort_Uart = 1U, /*!< Serial port UART */ +} serial_port_type_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! @name Initialization*/ +/* @{ */ + +#if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) +/*! + * @brief Initializes the peripheral used for debug messages. + * + * Call this function to enable debug log messages to be output via the specified peripheral, + * frequency of peripheral source clock, and base address at the specified baud rate. + * After this function has returned, stdout and stdin are connected to the selected peripheral. + * + * @param instance The instance of the module.If the device is kSerialPort_Uart, + * the instance is UART peripheral instance. The UART hardware peripheral + * type is determined by UART adapter. For example, if the instance is 1, + * if the lpuart_adapter.c is added to the current project, the UART periheral + * is LPUART1. + * If the uart_adapter.c is added to the current project, the UART periheral + * is UART1. + * @param baudRate The desired baud rate in bits per second. + * @param device Low level device type for the debug console, can be one of the following. + * @arg kSerialPort_Uart. + * @param clkSrcFreq Frequency of peripheral source clock. + * + * @return Indicates whether initialization was successful or not. + * @retval kStatus_Success Execution successfully + * @retval kStatus_Fail Execution failure + */ +status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq); + +/*! + * @brief De-initializes the peripheral used for debug messages. + * + * Call this function to disable debug log messages to be output via the specified peripheral + * base address and at the specified baud rate. + * + * @return Indicates whether de-initialization was successful or not. + */ +status_t DbgConsole_Deinit(void); + +#else +/*! + * Use an error to replace the DbgConsole_Init when SDK_DEBUGCONSOLE is not DEBUGCONSOLE_REDIRECT_TO_SDK and + * SDK_DEBUGCONSOLE_UART is not defined. + */ +static inline status_t DbgConsole_Init(uint8_t instance, + uint32_t baudRate, + serial_port_type_t device, + uint32_t clkSrcFreq) +{ + (void)instance; + (void)baudRate; + (void)device; + (void)clkSrcFreq; + return (status_t)kStatus_Fail; +} +/*! + * Use an error to replace the DbgConsole_Deinit when SDK_DEBUGCONSOLE is not DEBUGCONSOLE_REDIRECT_TO_SDK and + * SDK_DEBUGCONSOLE_UART is not defined. + */ +static inline status_t DbgConsole_Deinit(void) +{ + return (status_t)kStatus_Fail; +} + +#endif /* ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) */ + +#if SDK_DEBUGCONSOLE +/*! + * @brief Writes formatted output to the standard output stream. + * + * Call this function to write a formatted output to the standard output stream. + * + * @param fmt_s Format control string. + * @return Returns the number of characters printed or a negative value if an error occurs. + */ +int DbgConsole_Printf(const char *fmt_s, ...); + +/*! + * @brief Writes a character to stdout. + * + * Call this function to write a character to stdout. + * + * @param ch Character to be written. + * @return Returns the character written. + */ +int DbgConsole_Putchar(int ch); + +/*! + * @brief Reads formatted data from the standard input stream. + * + * Call this function to read formatted data from the standard input stream. + * + * @param fmt_ptr Format control string. + * @return Returns the number of fields successfully converted and assigned. + */ +int DbgConsole_Scanf(char *fmt_ptr, ...); + +/*! + * @brief Reads a character from standard input. + * + * Call this function to read a character from standard input. + * + * @return Returns the character read. + */ +int DbgConsole_Getchar(void); + +#endif /* SDK_DEBUGCONSOLE */ + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_DEBUGCONSOLE_H_ */