From ea9c2280a2659ffd849a785f0e267da33556af39 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Fri, 16 Jun 2023 18:02:50 -0500 Subject: [PATCH 01/26] Preliminary drivers working (boundary tests 7-9 failing) --- Examples/MAX78000/QSPI/.cproject | 88 ++++ Examples/MAX78000/QSPI/.project | 26 ++ .../QSPI/.settings/language.settings.xml | 15 + .../org.eclipse.cdt.codan.core.prefs | 93 ++++ .../QSPI/.settings/org.eclipse.cdt.core.prefs | 15 + Examples/MAX78000/QSPI/.vscode/README.md | 422 ++++++++++++++++++ .../QSPI/.vscode/c_cpp_properties.json | 53 +++ Examples/MAX78000/QSPI/.vscode/flash.gdb | 15 + Examples/MAX78000/QSPI/.vscode/launch.json | 133 ++++++ Examples/MAX78000/QSPI/.vscode/settings.json | 82 ++++ Examples/MAX78000/QSPI/.vscode/tasks.json | 106 +++++ Examples/MAX78000/QSPI/Makefile | 395 ++++++++++++++++ Examples/MAX78000/QSPI/N01S830HA.c | 167 +++++++ Examples/MAX78000/QSPI/N01S830HA.h | 72 +++ Examples/MAX78000/QSPI/QSPI.launch | 62 +++ Examples/MAX78000/QSPI/README.md | 61 +++ Examples/MAX78000/QSPI/fastspi.c | 385 ++++++++++++++++ Examples/MAX78000/QSPI/fastspi.h | 59 +++ Examples/MAX78000/QSPI/fastspi.old | 359 +++++++++++++++ Examples/MAX78000/QSPI/fastspi_config.h | 49 ++ Examples/MAX78000/QSPI/main.c | 254 +++++++++++ Examples/MAX78000/QSPI/project.mk | 10 + 22 files changed, 2921 insertions(+) create mode 100644 Examples/MAX78000/QSPI/.cproject create mode 100644 Examples/MAX78000/QSPI/.project create mode 100644 Examples/MAX78000/QSPI/.settings/language.settings.xml create mode 100644 Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.codan.core.prefs create mode 100644 Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.core.prefs create mode 100755 Examples/MAX78000/QSPI/.vscode/README.md create mode 100755 Examples/MAX78000/QSPI/.vscode/c_cpp_properties.json create mode 100755 Examples/MAX78000/QSPI/.vscode/flash.gdb create mode 100755 Examples/MAX78000/QSPI/.vscode/launch.json create mode 100755 Examples/MAX78000/QSPI/.vscode/settings.json create mode 100755 Examples/MAX78000/QSPI/.vscode/tasks.json create mode 100644 Examples/MAX78000/QSPI/Makefile create mode 100644 Examples/MAX78000/QSPI/N01S830HA.c create mode 100644 Examples/MAX78000/QSPI/N01S830HA.h create mode 100644 Examples/MAX78000/QSPI/QSPI.launch create mode 100644 Examples/MAX78000/QSPI/README.md create mode 100644 Examples/MAX78000/QSPI/fastspi.c create mode 100644 Examples/MAX78000/QSPI/fastspi.h create mode 100644 Examples/MAX78000/QSPI/fastspi.old create mode 100644 Examples/MAX78000/QSPI/fastspi_config.h create mode 100644 Examples/MAX78000/QSPI/main.c create mode 100644 Examples/MAX78000/QSPI/project.mk diff --git a/Examples/MAX78000/QSPI/.cproject b/Examples/MAX78000/QSPI/.cproject new file mode 100644 index 00000000000..d3a2a23288d --- /dev/null +++ b/Examples/MAX78000/QSPI/.cproject @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/MAX78000/QSPI/.project b/Examples/MAX78000/QSPI/.project new file mode 100644 index 00000000000..1c1629a8fcc --- /dev/null +++ b/Examples/MAX78000/QSPI/.project @@ -0,0 +1,26 @@ + + + QSPI + + + + + + 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/Examples/MAX78000/QSPI/.settings/language.settings.xml b/Examples/MAX78000/QSPI/.settings/language.settings.xml new file mode 100644 index 00000000000..d32717b6f37 --- /dev/null +++ b/Examples/MAX78000/QSPI/.settings/language.settings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.codan.core.prefs b/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 00000000000..59c0b37ba75 --- /dev/null +++ b/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,93 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.codan.checkers.errnoreturn=Warning +org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false} +org.eclipse.cdt.codan.checkers.errreturnvalue=Error +org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"} +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=Error +org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false} +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"} +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"} +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"} +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"} +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\\")"} +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},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=Warning +org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"} +org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning +org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},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=Error +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=Error +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},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=Error +org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"} +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"} +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"} +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"} +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},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.NamingConventionFunctionChecker=-Info +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"} +org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error +org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"} +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"} +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"} +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"} +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"} +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false} +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false} +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"} +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},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=Error +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},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\\")"} +org.eclipse.cdt.qt.core.qtproblem=Warning +org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>null} diff --git a/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.core.prefs b/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 00000000000..185749df71d --- /dev/null +++ b/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,15 @@ +eclipse.preferences.version=1 +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/BOARD/delimiter=; +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/BOARD/operation=append +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/BOARD/value=EvKit_V1 +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/GCC_PREFIX/delimiter=; +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/GCC_PREFIX/operation=replace +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/GCC_PREFIX/value=arm-none-eabi- +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/PROJECT/delimiter=; +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/PROJECT/operation=append +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/PROJECT/value=QSPI +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/TARGET/delimiter=; +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/TARGET/operation=append +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/TARGET/value=MAX78000 +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/append=true +environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1028364529/appendContributed=true diff --git a/Examples/MAX78000/QSPI/.vscode/README.md b/Examples/MAX78000/QSPI/.vscode/README.md new file mode 100755 index 00000000000..8b58b503892 --- /dev/null +++ b/Examples/MAX78000/QSPI/.vscode/README.md @@ -0,0 +1,422 @@ +# VSCode-Maxim + +_(If you're viewing this document from within Visual Studio Code you can press `CTRL+SHIFT+V` to open a Markdown preview window.)_ + +## Quick Links + +* [MSDK User Guide](https://analog-devices-msdk.github.io/msdk/USERGUIDE/) + * If it's not in the README, check the UG. + * If it's not in the UG, open a ticket! +* [VSCode-Maxim Github](https://github.com/Analog-Devices-MSDK/VSCode-Maxim) + +## Introduction + +VSCode-Maxim is a set of [Visual Studio Code](https://code.visualstudio.com/) project configurations and utilities for enabling embedded development for [Analog Device's MSDK](https://github.com/Analog-Devices-MSDK/msdk) and the [MAX32xxx/MAX78xxx microcontrollers](https://www.analog.com/en/product-category/microcontrollers.html). + +The following features are supported: + +* Code editing with intellisense down to the register level +* Code compilation with the ability to easily re-target a project for different microcontrollers and boards +* Flashing programs +* GUI and command-line debugging + +## Dependencies + +* [Visual Studio Code](https://code.visualstudio.com/) + * [C/C++ VSCode Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) + * [Cortex-Debug Extension](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) +* [Analog Devices MSDK](https://www.analog.com/en/design-center/evaluation-hardware-and-software/software/software-download?swpart=SFW0010820A) + +## Installation + +The steps below are also available in video form in "Understanding Artificial Intelligence Episode 8.5 - Visual Studio Code" [here](https://www.analog.com/en/education/education-library/videos/6313212752112.html). + +1. Download and install the Analog Devices MSDK for your OS from the links below. For more detailed instructions on installing the MSDK, see the [MSDK User Guide](https://analog-devices-msdk.github.io/msdk/USERGUIDE/) + * [Windows](https://www.analog.com/en/design-center/evaluation-hardware-and-software/software/software-download?swpart=SFW0010820A) + * [Linux (Ubuntu)](https://www.analog.com/en/design-center/evaluation-hardware-and-software/software/software-download?swpart=SFW0018720A) + * [MacOS](https://www.analog.com/en/design-center/evaluation-hardware-and-software/software/software-download?swpart=SFW0018610A) + +2. Run the installer executable, and ensure that "Visual Studio Code Support" is enabled for your installation. + + ![Selected Components](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/installer_components.JPG) + +3. Finish the MSDK installation, taking note of where the MSDK was installed. + +4. Download & install Visual Studio Code for your OS [here](https://code.visualstudio.com/Download). + +5. Launch Visual Studio Code. + +6. Install the Microsoft [C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools). + +7. Install the [Cortex-Debug Extension](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) + +8. Use `CTRL + SHIFT + P` (or `COMMAND + SHIFT + P` on MacOS) to open the developer prompt. + +9. Type "open settings json" and select the "Preferences: Open Settings (JSON)" option (_not_ the "Preferences: Open _Default_ Settings (JSON)"). This will open your user settings.json file in VS Code's editor. + + ![Open Settings JSON Command](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/open_settings_json.jpg) + +10. Add the entries below into your user settings.json file. + + ```json + { + // There may be other settings up here... + + "MAXIM_PATH":"C:/MaximSDK", // Set this to the installed location of the Analog Devices MSDK. Only use forward slashes '/' when setting this path! + "update.mode": "manual", + "extensions.autoUpdate": false, + + // There may be other settings down here... + } + ``` + +11. Save your changes to the file with `CTRL + S` and restart VS Code. + +12. That's it! You're ready to start using Visual Studio Code to develop with Analog Devices MAX-series Microcontrollers. The MSDK examples come pre-populated with .vscode project folders, and the `Tools/VSCode-Maxim` folder of the MSDK contains documentation and templates. See [Usage](#usage) below for more details. + +## Usage + +This section covers basic usage of the VSCode-Maxim project files. For documentation on Visual Studio Code itself, please refer to the official docs [here](https://code.visualstudio.com/Docs). + +### Opening Projects + +Visual Studio Code is built around a "working directory" paradigm. The editor is always rooted in a working directory, and the main mechanism for changing that directory is `File -> Open Folder...`. + +![File -> Open Folder](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/file_openfolder.JPG) + +As a result, you'll notice that there is no "New Project" mechanism. A "project" in VS Code is simply a folder. It will look inside of the opened folder for a `.vscode` _sub_-folder to load project-specific settings from. + +A project that is configured for VS Code will have, at minimum, a .vscode sub-folder and a Makefile in its directory _(Note: You may need to enable viewing of hidden items in your file explorer to see the .vscode sub-folder)_. + +Ex: + +![Example Directory Contents](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/opening_projects_2.jpg) + +### Where to Find Projects + +The [Examples](https://github.com/Analog-Devices-MSDK/msdk/tree/main/Examples) in the MSDK come with with pre-configured .vscode project folders. These projects can be opened "out of the box", but it's good practice to copy example folders _outside_ of the MSDK so that the original copies are kept as clean references. The examples can be freely moved to any location _without a space in its path_. + +Additionally, empty project templates and a drag-and-drop folder for "injecting" a VSCode-Maxim project can be found under `Tools/VSCode-Maxim` in the MSDK installation. + +### Build Tasks + +Once a project is opened 4 available build tasks will become available via `Terminal > Run Build task...` or the shortcut `Ctrl+Shift+B`. These tasks are configured by the `.vscode/task.json` file. + +![Build Tasks Image](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/buildtasks.JPG) + +#### Build + +* Compiles the code with a `make all` command. +* Additional options are passed into Make on the command-line based on the project's settings.json file. +* The `./build` directory will be created and will contain the output binary, as well as all intermediary object files. + +#### Clean + +* Cleans the build output, removing the `./build` directory and all of its contents. + +#### Clean-Periph + +* This task is the same as 'clean', but it also removes the build output for the MSDK's peripheral drivers. +* Use this if you would like to recompile the peripheral drivers from source on the next build. + +#### Flash + +* Launching this task automatically runs the `Build` task first. Then, it flashes the output binary to the microcontroller. +* It uses the GDB `load` and `compare-sections` commands, and handles launching an OpenOCD internally via a pipe connection. +* The flashed program will be halted until the microcontroller is reset, power cycled, or a debugger is connected. +* A debugger must be connected correctly to use this task. Refer to the datasheet of your microcontroller's evaluation board for instructions. + +#### Flash & Run + +* This is the same as the `Flash` task, but it also will launch execution of the program once flashing is complete. + +#### Erase Flash + +* Completely erases all of the application code in the flash memory bank. +* Once complete, the target microcontroller will be effectively "blank". +* This can be useful for recovering from Low-Power (LP) lockouts, bad firmware, etc. + +### Debugging + +![Debug Window](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/debugger.JPG) + +Debugging is enabled by Visual Studio Code's integrated debugger. Launch configurations can be found in the `.vscode/launch.json` file. + +* Note: **Flashing does not happen automatically when launching the debugger.** Run the "Flash" [build task](#build-tasks) for your program _before_ debugging. + +#### Debugger Limitations + +In general, the MAX-series microcontrollers have the following debugger limitations at the hardware level: + +* The debugger can not be connected _while_ the device is in reset. + +* The device can not be debugged while the device is in Sleep, Low Power Mode, Micro Power Mode, Standby, Backup, or Shutdown mode. These modes shut down the SWD clock. + +* These limitations can sometimes make the device difficult or impossible to connect to if firmware has locked out the debugger. In such cases, the ["Erase Flash"](#erase-flash) task can be used to recover the part. + +#### Launching the Debugger + +1. Attach your debugger to the SWD port on the target microcontroller. (Refer to the datasheet of your evaluation board for instructions on connecting a debugger) + +2. Flash the program to the microcontroller with the "Flash" [Build Task](#build-tasks). **Flashing does not happen automatically when launching the debugger.** + +3. Launch the debugger with `Run > Start Debugging`, with the shortcut `F5`, or via the `Run and Debug` window (Ctrl + Shift + D) and the green "launch" arrow. + + ![Debug Tab](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/debugger_window.JPG) + +4. The debugger will launch a GDB client & OpenOCD server, reset the microcontroller, and should break on entry into `main`. + + ![Debugger Break on Main](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/debugger_breakmain.JPG) + +#### Using the Debugger + +* For full usage details, please refer to the [official VS Code debugger documentation](https://code.visualstudio.com/docs/editor/debugging). + +The main interface for the debugger is the debugger control bar: + +![Debugger Control Bar Image](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/debugger_bar.JPG) + +`Continue | Step Over | Step Into | Step Out | Restart | Stop` + +Breakpoints can be set by clicking in the space next to the line number in a source code file. A red dot indicates a line to break on. Breakpoints can be removed by clicking on them again. Ex: + +![Breakpoint](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/breakpoint.JPG) + +## Project Configuration + +### Project Settings + +`.vscode/settings.json` is the main project configuration file. Values set here are parsed into the other .json config files. + +**When a change is made to this file, VS Code should be reloaded with CTRL+SHIFT+P -> Reload Window (or alternatively restarted completely) to force a re-parse.** + +![Reload Window](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/reload_window.JPG) + +The default project configuration should work for most use cases as long as `"target"` and `"board"` are set correctly. + +Any field from `settings.json` can be referenced from any other config file (including itself) with `"${config:[fieldname]}"` + +The following configuration options are available: + +### Basic Config Options + +#### `"target"` + +* This sets the target microcontroller for the project. +* It sets the `TARGET` [Build Configuration](#build-configuration) variable. +* Supported values: + * `"MAX32520"` + * `"MAX32570"` + * `"MAX32650"` + * `"MAX32655"` + * `"MAX32660"` + * `"MAX32662"` + * `"MAX32665"` (for MAX32665-MAX32668) + * `"MAX32670"` + * `"MAX32672"` + * `"MAX32675"` + * `"MAX32680"` + * `"MAX32690"` + * `"MAX78000"` + * `"MAX78002"` + +#### `"board"` + +* This sets the target board for the project (ie. Evaluation Kit, Feather board, etc.) +* Supported values: + * ... can be found in the `Libraries/Boards` folder of the MSDK + * For example, the supported options for the MAX78000 are `"EvKit_V1"`, `"FTHR_RevA"`, and `"MAXREFDES178"`. + + ![MAX78000 Boards](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/main/img/78000_boards.JPG) + +### Advanced Config Options + +#### `"MAXIM_PATH"` + +* This option must point to the root installation directory of the MSDK. +* It should be placed in the _global_ user settings.json file during first-time VSCode-Maxim setup. See [Installation](#installation). + +#### `"terminal.integrated.env.[platform]:Path"` + +* This prepends the location of the MSDK toolchain binaries to the system `Path` used by VSCode's integrated terminal. +* The Path is not sanitized by default, which means that the terminal inherits the system path. +* Don't touch unless you know what you're doing :) + +#### `"project_name"` + +* Sets the name of project. This is used in other config options such as `program_file`. +* Default value: `"${workspaceFolderBasename}"` + +#### `"program_file"` + +* Sets the name of the file to flash and debug. This is provided in case it's needed, but for most use cases should be left at its default. +* File extension must be included. +* Default value: `"${config:project_name}.elf"` + +#### `"symbol_file"` + +* Sets the name of the file that GDB will load debug symbols from. +* File extension must be included. +* Default value: `"${config:program_file}"` + +#### `"M4_OCD_interface_file"` + +* Sets the OpenOCD interface file to use to connect to the Arm M4 core. This should match the debugger being used for the M4 core. +* The `MaximSDK/Tools/OpenOCD/scripts/interface` folder is searched for the file specified by this setting. +* `.cfg` file extension must be included. +* Default value: `"cmsis-dap.cfg"` + +#### `"M4_OCD_target_file"` + +* Sets the OpenOCD target file to use for the Arm M4 core. This should match the target microcontroller. +* `.cfg` file extension must be included. +* The `MaximSDK/Tools/OpenOCD/scripts/target` folder is searched for the file specified by this setting. +* Default value: `"${config:target}.cfg"` + +#### `"RV_OCD_interface_file"` + +* Sets the OpenOCD interface file to use to connect to the RISC-V core. This should match the debugger being used for the RISC-V core. +* The `MaximSDK/Tools/OpenOCD/scripts/interface` folder is searched for the file specified by this setting. +* `.cfg` file extension must be included. +* Default value: `"ftdi/olimex-arm-usb-ocd-h.cfg"` + +#### `"RV_OCD_target_file"` + +* Sets the OpenOCD target file to use for the RISC-V core. +* The `MaximSDK/Tools/OpenOCD/scripts/target` folder is searched for the file specified by this setting. +* `.cfg` file extension must be included. +* Default value: `"${config:target}_riscv.cfg"` + +#### `"v_Arm_GCC"` + +* Sets the version of the Arm Embedded GCC to use, including toolchain binaries and the standard library version. +* This gets parsed into `ARM_GCC_path`. +* Default value: `"10.3"` + +#### `"v_xPack_GCC"` + +* Sets the version of the xPack RISC-V GCC to use. +* This gets parsed into `xPack_GCC_path`. +* Default value: `"10.2.0-1.2"` + +#### `"OCD_path"` + +* Where to find the OpenOCD. +* Default value: `"${config:MAXIM_PATH}/Tools/OpenOCD"` + +#### `"ARM_GCC_path"` + +* Where to find the Arm Embedded GCC Toolchain. +* Default value: `"${config:MAXIM_PATH}/Tools/GNUTools/${config:v_Arm_GCC}"` + +#### `"xPack_GCC_path"` + +* Where to find the RISC-V GCC Toolchain. +* Default value: `"${config:MAXIM_PATH}/Tools/xPack/riscv-none-embed-gcc/${config:v_xPack_GCC}"` + +#### `"Make_path"` + +* Where to find Make binaries (only used on Windows) +* Default value: `"${config:MAXIM_PATH}/Tools/MSYS2/usr/bin"` + +#### `"C_Cpp.default.includePath"` + +* Which paths to search to find header (.h) files. +* Does not recursively search by default. To recursively search, use `/**`. + +#### `"C_Cpp.default.browse.path"` + +* Which paths to search to find source (.c) files. +* Does not recursively search by default. To recursively search, use `/**`. + +#### `"C_Cpp.default.defines"` + +* Sets the compiler definitions to use for the intellisense engine. +* Most definitions should be defined in header files, but if a definition is missing it can be entered here to get the intellisense engine to recognize it. + +### Setting Search Paths for Intellisense + +VS Code's intellisense engine must be told where to find the header files for your source code. By default, the MSDK's peripheral drivers, the C standard libraries, and all of the sub-directories of the workspace will be searched for header files to use with Intellisense. If VS Code throws an error on an `#include` statement (and the file exists), then a search path is most likely missing. + +To add additional search paths : + +1. Open the `.vscode/settings.json` file. + +2. Add the include path(s) to the `C_Cpp.default.includePath` list. The paths set here should contain header files, and will be searched by the Intellisense engine and when using "Go to Declaration" in the editor. + +3. Add the path(s) to any relevant implementation files to the `C_Cpp.default.browse.path` list. This list contains the paths that will be searched when using "Go to Definition". + +## Build Configuration + +A project's build system is managed by two files found in the project's root directory. These files are used alongside the [GNU Make](https://www.gnu.org/software/make/) program (which is a part of the MSDK toolchain) to locate and build a project's source code for the correct microcontroller. + +* `Makefile` +* `project.mk` + +![Files are located in the root directory](https://raw.githubusercontent.com/Analog-Devices-MSDK/VSCode-Maxim/65af7c61800c7039956f3c1971ffd7915008668d/img/projectmk.JPG) + +When the command... + +```shell +make +``` + +... is run, the program `make` will load settings from these two files. Then, it will use them to build the project's source code. VSCode-Maxim is a "wrapper" around this Makefile system. + +**See the [MSDK User Guide](https://analog-devices-msdk.github.io/msdk/USERGUIDE/#build-system) for full documentation on how to configure the build system.** + +## Project Creation + +### Option 1. Copying a Pre-Made Project + +Copying a pre-made example project is a great way to get rolling quickly, and is currently the recommended method for creating new projects. + +The release package for this project (Located at Tools/VSCode-Maxim in the Analog Devices MSDK) contains a `New_Project` folder designed for such purposes. Additionally, any of the VS Code-enabled Example projects can be copied from the MSDK. + +1. Copy the existing project folder to an accessible location. This will be the location of your new project. + +2. (Optional) Rename the folder. For example, I might rename the folder to `MyProject`. + +3. Open the project in VS Code (`File -> Open Folder...`) + +4. Set your target microcontroller and board correctly. See [Basic Config Options](#basic-config-options) + +5. `CTRL+SHIFT+P -> Reload Window` to re-parse the project settings. + +6. That's it! The existing project is ready to build, debug, and modify. + +### Option 2 - Injecting + +VSCode-Maxim releases provide the `Inject` folder for "injecting" into an existing folder. If you want to start from scratch or use the project files with existing source code, take this option. + +1. Create your project folder if necessary. For example, I might create a new project in a workspace folder with the path: `C:\Users\Jake.Carter\workspace\MyNewProject`. + +2. Copy the **contents** of the `Inject` folder into the project folder from step 1. The contents to copy include a `.vscode` folder, a `Makefile`, and a `project.mk` file. For this example, the contents of the 'MyProject' folder would be the following: + + ```shell + C:\Users\Jake.Carter\workspace\MyNewProject + |- .vscode + |- Makefile + |- project.mk + ``` + +3. Open the project in VS Code (`File -> Open Folder...`) + +4. Set your target microcontroller correctly. See [Basic Config Options](#basic-config-options). + +5. `CTRL+SHIFT+P -> Reload Window` to re-parse the project settings. + +6. Configure the [build system](https://analog-devices-msdk.github.io/msdk/USERGUIDE/#build-system) for use with any pre-existing source code. + +7. That's it! Your new empty project can now be opened with `File > Open Folder` from within VS Code. + +## Issue Tracker + +Bug reports, feature requests, and contributions are welcome via the [issues](https://github.com/Analog-Devices-MSDK/VSCode-Maxim/issues) tracker on Github. + +New issues should contain _at minimum_ the following information: + +* Visual Studio Code version #s (see `Help -> About`) +* C/C++ Extension version # +* Target microcontroller and evaluation platform +* The projects `.vscode` folder and `Makefile` (where applicable). Standard compression formats such as `.zip`, `.rar`, `.tar.gz`, etc. are all acceptable. diff --git a/Examples/MAX78000/QSPI/.vscode/c_cpp_properties.json b/Examples/MAX78000/QSPI/.vscode/c_cpp_properties.json new file mode 100755 index 00000000000..dfbed47b581 --- /dev/null +++ b/Examples/MAX78000/QSPI/.vscode/c_cpp_properties.json @@ -0,0 +1,53 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${default}" + ], + "defines": [ + "${default}" + ], + "intelliSenseMode": "gcc-arm", + "compilerPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gcc.exe", + "browse": { + "path": [ + "${default}" + ] + } + }, + { + "name": "Linux", + "includePath": [ + "${default}" + ], + "defines": [ + "${default}" + ], + "intelliSenseMode": "gcc-arm", + "compilerPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gcc", + "browse": { + "path": [ + "${default}" + ] + } + }, + { + "name": "Mac", + "includePath": [ + "${default}" + ], + "defines": [ + "${default}" + ], + "intelliSenseMode": "gcc-arm", + "compilerPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gcc", + "browse": { + "path": [ + "${default}" + ] + } + } + ], + "version": 4 +} \ No newline at end of file diff --git a/Examples/MAX78000/QSPI/.vscode/flash.gdb b/Examples/MAX78000/QSPI/.vscode/flash.gdb new file mode 100755 index 00000000000..fc627ae86a3 --- /dev/null +++ b/Examples/MAX78000/QSPI/.vscode/flash.gdb @@ -0,0 +1,15 @@ +define flash_m4 + set architecture armv7e-m + target remote | openocd -c "gdb_port pipe;log_output flash.log" -s $arg0/scripts -f interface/$arg1 -f target/$arg2 -c "init; reset halt" + load + compare-sections + monitor reset halt +end + +define flash_m4_run + set architecture armv7e-m + target remote | openocd -c "gdb_port pipe;log_output flash.log" -s $arg0/scripts -f interface/$arg1 -f target/$arg2 -c "init; reset halt" + load + compare-sections + monitor resume +end \ No newline at end of file diff --git a/Examples/MAX78000/QSPI/.vscode/launch.json b/Examples/MAX78000/QSPI/.vscode/launch.json new file mode 100755 index 00000000000..af0d6f650c7 --- /dev/null +++ b/Examples/MAX78000/QSPI/.vscode/launch.json @@ -0,0 +1,133 @@ +{ + "configurations": [ + { + "name": "Debug Arm (Cortex-debug)", + "cwd":"${workspaceRoot}", + "executable": "${workspaceFolder}/build/${config:program_file}", + "loadFiles": ["${workspaceFolder}/build/${config:program_file}"], + "symbolFiles": [{ + "file": "${workspaceFolder}/build/${config:symbol_file}" + }], + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "linux": { + "gdbPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gdb", + "serverpath": "${config:OCD_path}/openocd", + }, + "windows": { + "gdbPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gdb.exe", + "serverpath": "${config:OCD_path}/openocd.exe", + }, + "osx": { + "gdbPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gdb", + "serverpath": "${config:OCD_path}/openocd", + }, + "searchDir": ["${config:OCD_path}/scripts"], + "configFiles": ["interface/${config:M4_OCD_interface_file}", "target/${config:M4_OCD_target_file}"], + "interface": "swd", + "runToEntryPoint": "main", + "svdFile": "${config:MAXIM_PATH}/Libraries/CMSIS/Device/Maxim/${config:target}/Include/${config:target}.svd" + }, + { + "name": "GDB (Arm M4)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/${config:program_file}", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "linux": { + "miDebuggerPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gdb", + "debugServerPath": "${config:OCD_path}/openocd", + }, + "windows": { + "miDebuggerPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gdb.exe", + "debugServerPath": "${config:OCD_path}/openocd.exe", + }, + "osx": { + "miDebuggerPath": "${config:ARM_GCC_path}/bin/arm-none-eabi-gdb", + "debugServerPath": "${config:OCD_path}/bin/openocd", + }, + "logging": { + "exceptions": true, + "trace": false, + "traceResponse": false, + "engineLogging": false + }, + "miDebuggerServerAddress": "localhost:3333", + "debugServerArgs": "-s ${config:OCD_path}/scripts -f interface/${config:M4_OCD_interface_file} -f target/${config:M4_OCD_target_file} -c \"init; reset halt\"", + "serverStarted": "Info : Listening on port 3333 for gdb connections", + "filterStderr": true, + "targetArchitecture": "arm", + "customLaunchSetupCommands": [ + {"text":"-list-features"} + ], + "setupCommands": [ + { "text":"set logging overwrite on"}, + { "text":"set logging file debug-arm.log"}, + { "text":"set logging on"}, + { "text":"cd ${workspaceFolder}" }, + { "text":"exec-file build/${config:program_file}" }, + { "text":"symbol-file build/${config:symbol_file}" }, + { "text":"target remote localhost:3333" }, + { "text":"monitor reset halt" }, + { "text":"set $pc=Reset_Handler"}, + { "text":"b main" } + ] + }, + { + "name": "GDB (RISC-V)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/buildrv/${config:program_file}", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "linux": { + "miDebuggerPath": "${config:xPack_GCC_path}/bin/riscv-none-embed-gdb", + "debugServerPath": "${config:OCD_path}/openocd", + }, + "windows": { + "miDebuggerPath": "${config:xPack_GCC_path}/bin/riscv-none-embed-gdb.exe", + "debugServerPath": "${config:OCD_path}/openocd.exe", + }, + "osx": { + "miDebuggerPath": "${config:xPack_GCC_path}/bin/riscv-none-embed-gdb", + "debugServerPath": "${config:OCD_path}/bin/openocd", + }, + "logging": { + "exceptions": true, + "trace": false, + "traceResponse": false, + "engineLogging": false + }, + "miDebuggerServerAddress": "localhost:3334", + "debugServerArgs": "-c \"gdb_port 3334\" -s ${config:OCD_path}/scripts -f interface/${config:RV_OCD_interface_file} -f target/${config:RV_OCD_target_file}", + "serverStarted": "Info : Listening on port 3334 for gdb connections", + "filterStderr": true, + "customLaunchSetupCommands": [ + {"text":"-list-features"} + ], + "targetArchitecture": "arm", + "setupCommands": [ + { "text":"set logging overwrite on"}, + { "text":"set logging file debug-riscv.log"}, + { "text":"set logging on"}, + { "text":"cd ${workspaceFolder}" }, + { "text": "set architecture riscv:rv32", "ignoreFailures": false }, + { "text":"exec-file build/${config:program_file}", "ignoreFailures": false }, + { "text":"symbol-file buildrv/${config:symbol_file}", "ignoreFailures": false }, + { "text":"target remote localhost:3334" }, + { "text":"b main" }, + { "text": "set $pc=Reset_Handler","ignoreFailures": false } + ] + } + ] +} \ No newline at end of file diff --git a/Examples/MAX78000/QSPI/.vscode/settings.json b/Examples/MAX78000/QSPI/.vscode/settings.json new file mode 100755 index 00000000000..c391addc04c --- /dev/null +++ b/Examples/MAX78000/QSPI/.vscode/settings.json @@ -0,0 +1,82 @@ +{ + "terminal.integrated.env.windows": { + "Path":"${config:OCD_path};${config:ARM_GCC_path}/bin;${config:xPack_GCC_path}/bin;${config:Make_path};${env:PATH}", + "MAXIM_PATH":"${config:MAXIM_PATH}" + }, + "terminal.integrated.defaultProfile.windows": "Command Prompt", + + "terminal.integrated.env.linux": { + "PATH":"${config:OCD_path}:${config:ARM_GCC_path}/bin:${config:xPack_GCC_path}/bin:${env:PATH}", + "MAXIM_PATH":"${config:MAXIM_PATH}" + }, + "terminal.integrated.env.osx": { + "PATH":"${config:OCD_path}/bin:${config:ARM_GCC_path}/bin:${config:xPack_GCC_path}/bin:${env:PATH}", + "MAXIM_PATH":"${config:MAXIM_PATH}" + }, + + "target":"MAX78000", + "board":"FTHR_RevA", + + "project_name":"${workspaceFolderBasename}", + + "program_file":"${config:project_name}.elf", + "symbol_file":"${config:program_file}", + + "M4_OCD_interface_file":"cmsis-dap.cfg", + "M4_OCD_target_file":"max78000.cfg", + "RV_OCD_interface_file":"ftdi/olimex-arm-usb-ocd-h.cfg", + "RV_OCD_target_file":"${config:target}_riscv.cfg", + + "v_Arm_GCC":"10.3", + "v_xPack_GCC":"12.2.0-3.1", + + "OCD_path":"${config:MAXIM_PATH}/Tools/OpenOCD", + "ARM_GCC_path":"${config:MAXIM_PATH}/Tools/GNUTools/${config:v_Arm_GCC}", + "xPack_GCC_path":"${config:MAXIM_PATH}/Tools/xPack/riscv-none-elf-gcc/${config:v_xPack_GCC}", + "Make_path":"${config:MAXIM_PATH}/Tools/MSYS2/usr/bin", + + "C_Cpp.default.includePath": [ + "${workspaceFolder}", + "${workspaceFolder}/**", + "${config:MAXIM_PATH}/Libraries/Boards/${config:target}/Include", + "${config:MAXIM_PATH}/Libraries/Boards/${config:target}/${config:board}/Include", + "${config:MAXIM_PATH}/Libraries/CMSIS/Device/Maxim/${config:target}/Include", + "${config:MAXIM_PATH}/Libraries/CMSIS/Include", + "${config:ARM_GCC_path}/arm-none-eabi/include", + "${config:ARM_GCC_path}/lib/gcc/arm-none-eabi/${config:v_Arm_GCC}/include", + "${config:MAXIM_PATH}/Libraries/PeriphDrivers/Include/${config:target}", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/Camera", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/Display", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/ExtMemory", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/LED", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/PMIC", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/PushButton", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/Touchscreen", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/CODEC" + ], + "C_Cpp.default.browse.path": [ + "${workspaceFolder}", + "${config:MAXIM_PATH}/Libraries/Boards/${config:target}/Source", + "${config:MAXIM_PATH}/Libraries/Boards/${config:target}/${config:board}/Source", + "${config:MAXIM_PATH}/Libraries/PeriphDrivers/Source", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/Camera", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/Display", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/LED", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/PMIC", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/PushButton", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/Touchscreen", + "${config:MAXIM_PATH}/Libraries/MiscDrivers", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/ADC", + "${config:MAXIM_PATH}/Libraries/MiscDrivers/CODEC" + ], + "C_Cpp.default.defines": [ + "${config:board}", + "TARGET=${config:target}", + "TARGET_REV=0x4131", + "__GNUC__" + ], + "C_Cpp.default.forcedInclude": [ + "${workspaceFolder}/build/project_defines.h" + ] +} + diff --git a/Examples/MAX78000/QSPI/.vscode/tasks.json b/Examples/MAX78000/QSPI/.vscode/tasks.json new file mode 100755 index 00000000000..23f00049c4e --- /dev/null +++ b/Examples/MAX78000/QSPI/.vscode/tasks.json @@ -0,0 +1,106 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "make -r -j 8 --output-sync=target --no-print-directory TARGET=${config:target} BOARD=${config:board} MAXIM_PATH=${config:MAXIM_PATH} MAKE=make PROJECT=${config:project_name}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "clean", + "type": "shell", + "command": "make -j 8 clean --output-sync=target --no-print-directory TARGET=${config:target} BOARD=${config:board} MAXIM_PATH=${config:MAXIM_PATH} MAKE=make PROJECT=${config:project_name}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "clean-periph", + "type": "shell", + "command": "make -j 8 distclean --output-sync=target --no-print-directory TARGET=${config:target} BOARD=${config:board} MAXIM_PATH=${config:MAXIM_PATH} MAKE=make PROJECT=${config:project_name}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "flash", + "type": "shell", + "command": "arm-none-eabi-gdb", + "args": [ + "--cd=\"${workspaceFolder}\"", + "--se=\"build/${config:program_file}\"", + "--symbols=build/${config:symbol_file}", + "-x=\"${workspaceFolder}/.vscode/flash.gdb\"", + "--ex=\"flash_m4 ${config:OCD_path} ${config:M4_OCD_interface_file} ${config:M4_OCD_target_file}\"", + "--batch" + ], + "group": "build", + "problemMatcher": [], + "dependsOn":["build"] + }, + { + "label": "flash & run", + "type": "shell", + "command": "arm-none-eabi-gdb", + "args": [ + "--cd=\"${workspaceFolder}\"", + "--se=\"build/${config:program_file}\"", + "--symbols=build/${config:symbol_file}", + "-x=\"${workspaceFolder}/.vscode/flash.gdb\"", + "--ex=\"flash_m4_run ${config:OCD_path} ${config:M4_OCD_interface_file} ${config:M4_OCD_target_file}\"", + "--batch" + ], + "group": "build", + "problemMatcher": [], + "dependsOn":["build"] + }, + { + "label": "erase flash", + "type": "shell", + "command": "openocd", + "args": [ + "-s", "${config:OCD_path}/scripts", + "-f", "interface/${config:M4_OCD_interface_file}", + "-f", "target/${config:M4_OCD_target_file}", + "-c", "\"init; reset halt; max32xxx mass_erase 0;\"", + "-c", "exit" + ], + "group":"build", + "problemMatcher": [], + "dependsOn":[] + }, + { + "label": "openocd (m4)", + "type": "shell", + "command": "openocd", + "args": [ + "-s", + "${config:OCD_path}/scripts", + "-f", + "interface/${config:M4_OCD_interface_file}", + "-f", + "target/${config:M4_OCD_target_file}", + "-c", + "\"init; reset halt\"" + ], + "problemMatcher": [], + "dependsOn":[] + }, + { + "label": "gdb (m4)", + "type": "shell", + "command": "arm-none-eabi-gdb", + "args": [ + "--ex=\"cd ${workspaceFolder}\"", + "--se=\"build/${config:program_file}\"", + "--symbols=build/${config:symbol_file}", + "--ex=\"target remote localhost:3333\"", + "--ex=\"monitor reset halt\"", + "--ex=\"b main\"", + "--ex=\"c\"" + ], + "problemMatcher": [], + "dependsOn":[] + }, + ] +} \ No newline at end of file diff --git a/Examples/MAX78000/QSPI/Makefile b/Examples/MAX78000/QSPI/Makefile new file mode 100644 index 00000000000..e28d58f8f45 --- /dev/null +++ b/Examples/MAX78000/QSPI/Makefile @@ -0,0 +1,395 @@ +################################################################################ + # Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + # + # Permission is hereby granted, free of charge, to any person obtaining a + # copy of this software and associated documentation files (the "Software"), + # to deal in the Software without restriction, including without limitation + # the rights to use, copy, modify, merge, publish, distribute, sublicense, + # and/or sell copies of the Software, and to permit persons to whom the + # Software is furnished to do so, subject to the following conditions: + # + # The above copyright notice and this permission notice shall be included + # in all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + # IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + # OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + # OTHER DEALINGS IN THE SOFTWARE. + # + # Except as contained in this notice, the name of Maxim Integrated + # Products, Inc. shall not be used except as stated in the Maxim Integrated + # Products, Inc. Branding Policy. + # + # The mere transfer of this software does not imply any licenses + # of trade secrets, proprietary technology, copyrights, patents, + # trademarks, maskwork rights, or any other form of intellectual + # property whatsoever. Maxim Integrated Products, Inc. retains all + # ownership rights. + # +############################################################################### + +# ** Readme! ** +# Don't edit this file! This is the core Makefile for a MaximSDK +# project. The available configuration options can be overridden +# in "project.mk", on the command-line, or with system environment +# variables. + +# See https://analog-devices-msdk.github.io/msdk/USERGUIDE/#build-system +# for more detailed instructions on how to use this system. + +# The detailed instructions mentioned above are easier to read than +# this file, but the comments found in this file also outline the +# available configuration variables. This file is organized into +# sub-sections, some of which expose config variables. + + +# ******************************************************************************* +# Set the target microcontroller and board to compile for. + +# Every TARGET microcontroller has some Board Support Packages (BSPs) that are +# available for it under the MaximSDK/Libraries/Boards/TARGET folder. The BSP +# that gets selected is MaximSDK/Libraries/Boards/TARGET/BOARD. + +# Configuration Variables: +# - TARGET : Override the default target microcontroller. Ex: TARGET=MAX78000 +# - BOARD : Override the default BSP (case sensitive). Ex: BOARD=EvKit_V1, BOARD=FTHR_RevA + + +ifeq "$(TARGET)" "" +# Default target microcontroller +TARGET := MAX78000 +TARGET_UC := MAX78000 +TARGET_LC := max78000 +else +# "TARGET" has been overridden in the environment or on the command-line. +# We need to calculate an upper and lowercase version of the part number, +# because paths on Linux and MacOS are case-sensitive. +TARGET_UC := $(subst m,M,$(subst a,A,$(subst x,X,$(TARGET)))) +TARGET_LC := $(subst M,m,$(subst A,a,$(subst X,x,$(TARGET)))) +endif + +# Default board. +BOARD ?= EvKit_V1 + +# ******************************************************************************* +# Locate the MaximSDK + +# This Makefile needs to know where to find the MaximSDK, and the MAXIM_PATH variable +# should point to the root directory of the MaximSDK installation. Setting this manually +# is usually only required if you're working on the command-line. + +# If MAXIM_PATH is not specified, we assume the project still lives inside of the MaximSDK +# and move up from this project's original location. + +# Configuration Variables: +# - MAXIM_PATH : Tell this Makefile where to find the MaximSDK. Ex: MAXIM_PATH=C:/MaximSDK + + +ifneq "$(MAXIM_PATH)" "" +# Sanitize MAXIM_PATH for backslashes +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +# Locate some other useful paths... +LIBS_DIR := $(abspath $(MAXIM_PATH)/Libraries) +CMSIS_ROOT := $(LIBS_DIR)/CMSIS +endif + +# ******************************************************************************* +# Include project Makefile. We do this after formulating TARGET, BOARD, and MAXIM_PATH +# in case project.mk needs to reference those values. However, we also include +# this as early as possible in the Makefile so that it can append to or override +# the variables below. + + +PROJECTMK ?= $(abspath ./project.mk) +include $(PROJECTMK) +$(info Loaded project.mk) +# PROJECTMK is also used by implicit rules and other libraries to add project.mk as a watch file + +# ******************************************************************************* +# Final path sanitization and re-calculation. No options here. + +ifeq "$(MAXIM_PATH)" "" +# MAXIM_PATH is still not defined... +DEPTH := ../../../ +MAXIM_PATH := $(abspath $(DEPTH)) +$(warning Warning: MAXIM_PATH is not set! Set MAXIM_PATH in your environment or in project.mk to clear this warning.) +$(warning Warning: Attempting to use $(MAXIM_PATH) calculated from relative path) +else +# Sanitize MAXIM_PATH for backslashes +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +endif + +# Final recalculation of LIBS_DIR/CMSIS_ROOT +LIBS_DIR := $(abspath $(MAXIM_PATH)/Libraries) +CMSIS_ROOT := $(LIBS_DIR)/CMSIS + +# One final UC/LC check in case user set TARGET in project.mk +TARGET_UC := $(subst m,M,$(subst a,A,$(subst x,X,$(TARGET)))) +TARGET_LC := $(subst M,m,$(subst A,a,$(subst X,x,$(TARGET)))) + +export TARGET +export TARGET_UC +export TARGET_LC +export CMSIS_ROOT +# TODO: Remove dependency on exports for these variables. + +# ******************************************************************************* +# Set up search paths, and auto-detect all source code on those paths. + +# The following paths are searched by default, where "./" is the project directory. +# ./ +# |- *.h +# |- *.c +# |-include (optional) +# |- *.h +# |-src (optional) +# |- *.c + +# Configuration Variables: +# - VPATH : Tell this Makefile to search additional locations for source (.c) files. +# You should use the "+=" operator with this option. +# Ex: VPATH += your/new/path +# - IPATH : Tell this Makefile to search additional locations for header (.h) files. +# You should use the "+=" operator with this option. +# Ex: VPATH += your/new/path +# - SRCS : Tell this Makefile to explicitly add a source (.c) file to the build. +# This is really only useful if you want to add a source file that isn't +# on any VPATH, in which case you can add the full path to the file here. +# You should use the "+=" operator with this option. +# Ex: SRCS += your/specific/source/file.c +# - AUTOSEARCH : Set whether this Makefile should automatically detect .c files on +# VPATH and add them to the build. This is enabled by default. Set +# to 0 to disable. If autosearch is disabled, source files must be +# manually added to SRCS. +# Ex: AUTOSEARCH = 0 + + +# Where to find source files for this project. +VPATH += . +VPATH += src +VPATH := $(VPATH) + +# Where to find header files for this project +IPATH += . +IPATH += include +IPATH := $(IPATH) + +AUTOSEARCH ?= 1 +ifeq ($(AUTOSEARCH), 1) +# Auto-detect all C/C++ source files on VPATH +SRCS += $(wildcard $(addsuffix /*.c, $(VPATH))) +SRCS += $(wildcard $(addsuffix /*.cpp, $(VPATH))) +endif + +# Collapse SRCS before passing them on to the next stage +SRCS := $(SRCS) + +# ******************************************************************************* +# Set the output filename + +# Configuration Variables: +# - PROJECT : Override the default output filename. Ex: PROJECT=MyProject + + +# The default value creates a file named after the target micro. Ex: MAX78000.elf +PROJECT ?= $(TARGET_LC) + +# ******************************************************************************* +# Compiler options + +# Configuration Variables: +# - DEBUG : Set DEBUG=1 to build explicitly for debugging. This adds some additional +# symbols and sets -Og as the default optimization level. +# - MXC_OPTIMIZE_CFLAGS : Override the default compiler optimization level. +# Ex: MXC_OPTIMIZE_CFLAGS = -O2 +# - PROJ_CFLAGS : Add additional compiler flags to the build. +# You should use the "+=" operator with this option. +# Ex: PROJ_CFLAGS += -Wextra +# - MFLOAT_ABI : Set the floating point acceleration level. +# The only options are "hard", "soft", or "softfp". +# Ex: MFLOAT_ABI = hard +# - LINKERFILE : Override the default linkerfile. +# Ex: LINKERFILE = customlinkerfile.ld +# - LINKERPATH : Override the default search location for $(LINKERFILE) +# The default search location is $(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/GCC +# If $(LINKERFILE) cannot be found at this path, then the root project +# directory will be used as a fallback. + +# Select 'GCC' or 'IAR' compiler +ifeq "$(COMPILER)" "" +COMPILER := GCC +endif + +# Set default compiler optimization levels +ifeq "$(MAKECMDGOALS)" "release" +# Default optimization level for "release" builds (make release) +MXC_OPTIMIZE_CFLAGS ?= -O2 +DEBUG = 0 +endif + +ifeq ($(DEBUG),1) +# Optimizes for debugging as recommended +# by GNU for code-edit-debug cycles +# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options +MXC_OPTIMIZE_CFLAGS := -Og +endif + +# Default level if not building for release or explicitly for debug +MXC_OPTIMIZE_CFLAGS ?= -O2 + +# Set compiler flags +PROJ_CFLAGS += -Wall # Enable warnings +PROJ_CFLAGS += -DMXC_ASSERT_ENABLE + +# Set hardware floating point acceleration. +# Options are: +# - hard +# - soft +# - softfp (default if MFLOAT_ABI is not set) +MFLOAT_ABI ?= softfp +# MFLOAT_ABI must be exported to other Makefiles +export MFLOAT_ABI + +# This path contains system-level intialization files for the target micro. Add to the build. +VPATH += $(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source + +# ******************************************************************************* +# Secure Boot Tools (SBT) + +# This section integrates the Secure Boot Tools. It's intended for use with +# microcontrollers that have a secure bootloader. + +# Enabling SBT integration will add some special rules, such as "make sla", "make scpa", etc. + +# Configuration variables: +# SBT : Toggle SBT integration. Set to 1 to enable, or 0 +# to disable +# MAXIM_SBT_DIR : Specify the location of the SBT tool binaries. This defaults to +# Tools/SBT in the MaximSDK. The standalone SBT installer will override +# this via an environment variable. +# TARGET_SEC : Specify the part number to be passed into the SBT. This should match +# the secure variant part #. The default value will depend on TARGET. +# For example, TARGET=MAX32650 will result in TARGET_SEC=MAX32651, and +# the default selection happens in Tools/SBT/SBT-config. +# However, if there are multiple secure part #s for the target +# microcontroller this variable may need to be changed. + +SBT ?= 0 +ifeq ($(SBT), 1) +MAXIM_SBT_DIR ?= $(MAXIM_PATH)/Tools/SBT +MAXIM_SBT_DIR := $(subst \,/,$(MAXIM_SBT_DIR)) +# ^ Must sanitize path for \ on Windows, since this may come from an environment +# variable. + +export MAXIM_SBT_DIR # SBTs must have this environment variable defined to work + +# SBT-config.mk and SBT-rules.mk are included further down this Makefile. + +endif # SBT + +# ******************************************************************************* +# Default goal selection. This section allows you to override the default goal +# that will run if no targets are specified on the command-line. +# (ie. just running 'make' instead of 'make all') + +# Configuration variables: +# .DEFAULT_GOAL : Set the default goal if no targets were specified on the +# command-line +# ** "override" must be used with this variable. ** +# Ex: "override .DEFAULT_GOAL = mygoal" + +ifeq "$(.DEFAULT_GOAL)" "" +ifeq ($(SBT),1) +override .DEFAULT_GOAL := sla +else +override .DEFAULT_GOAL := all +endif +endif + +# Developer note: 'override' is used above for legacy Makefile compatibility. +# gcc.mk/gcc_riscv.mk need to hard-set 'all' internally, so this new system +# uses 'override' to come in over the top without breaking old projects. + +# It's also necessary to explicitly set MAKECMDGOALS... +ifeq "$(MAKECMDGOALS)" "" +MAKECMDGOALS:=$(.DEFAULT_GOAL) +endif + +# Enable colors when --sync-output is used. +# See https://www.gnu.org/software/make/manual/make.html#Terminal-Output (section 13.2) +ifneq ($(MAKE_TERMOUT),) +PROJ_CFLAGS += -fdiagnostics-color=always +endif + +ifneq ($(FORCE_COLOR),) +PROJ_CFLAGS += -fdiagnostics-color=always +endif + +# ******************************************************************************* +# Include SBT config. We need to do this here because it needs to know +# the current MAKECMDGOAL. +ifeq ($(SBT),1) +include $(MAXIM_PATH)/Tools/SBT/SBT-config.mk +endif + +# ******************************************************************************* +# Libraries + +# This section offers "toggle switches" to include or exclude the libraries that +# are available in the MaximSDK. Set a configuration variable to 1 to include the +# library in the build, or 0 to exclude. + +# Each library may also have its own library specific configuration variables. See +# Libraries/libs.mk for more details. + +# Configuration variables: +# - LIB_BOARD : Include the Board-Support Package (BSP) library. (Enabled by default) +# - LIB_PERIPHDRIVERS : Include the peripheral driver library. (Enabled by default) +# - LIB_CMSIS_DSP : Include the CMSIS-DSP library. +# - LIB_CORDIO : Include the Cordio BLE library +# - LIB_FCL : Include the Free Cryptographic Library (FCL) +# - LIB_FREERTOS : Include the FreeRTOS and FreeRTOS-Plus-CLI libraries +# - LIB_LC3 : Include the Low Complexity Communication Codec (LC3) library +# - LIB_LITTLEFS : Include the "little file system" (littleFS) library +# - LIB_LWIP : Include the lwIP library +# - LIB_MAXUSB : Include the MAXUSB library +# - LIB_SDHC : Include the SDHC library + +include $(LIBS_DIR)/libs.mk + + +# ******************************************************************************* +# Rules + +# Include the rules for building for this target. All other makefiles should be +# included before this one. +include $(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/$(COMPILER)/$(TARGET_LC).mk + +# Include the rules that integrate the SBTs. SBTs are a special case that must be +# include after the core gcc rules to extend them. +ifeq ($(SBT), 1) +include $(MAXIM_PATH)/Tools/SBT/SBT-rules.mk +endif + + +# Get .DEFAULT_GOAL working. +ifeq "$(MAKECMDGOALS)" "" +MAKECMDGOALS:=$(.DEFAULT_GOAL) +endif + + +all: +# Extend the functionality of the "all" recipe here + arm-none-eabi-size --format=berkeley $(BUILD_DIR)/$(PROJECT).elf + +libclean: + $(MAKE) -f ${PERIPH_DRIVER_DIR}/periphdriver.mk clean.periph + +clean: +# Extend the functionality of the "clean" recipe here + +# The rule to clean out all the build products. +distclean: clean libclean diff --git a/Examples/MAX78000/QSPI/N01S830HA.c b/Examples/MAX78000/QSPI/N01S830HA.c new file mode 100644 index 00000000000..ad9b842f6b8 --- /dev/null +++ b/Examples/MAX78000/QSPI/N01S830HA.c @@ -0,0 +1,167 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ +#include +#include // For memset +#include "N01S830HA.h" +#include "mxc_errors.h" +#include "mxc_delay.h" +#include "fastspi.h" +#include "tmr.h" +#include + +enum MODE { STANDARD_MODE, QUAD_MODE }; +typedef enum MODE MODE_t; +MODE_t g_current_mode; + +inline void _parse_spi_header(uint8_t cmd, uint32_t address, uint8_t *out) +{ + out[0] = cmd; + out[1] = (address >> 16) & 0xFF; // MSB first + out[2] = (address >> 8) & 0xFF; + out[3] = (address & 0xFF); +} + +int _transmit_spi_header(uint8_t cmd, uint32_t address) +{ + int err = E_NO_ERROR; + // SPI reads and writes will always start with 4 bytes. + // A command byte, then a 24-bit address (MSB first) + uint8_t header[4]; + _parse_spi_header(cmd, address, header); + + // Transmit header, but keep Chip Select asserted. + spi_transmit(header, 4, NULL, 0, false, true, true); + return err; +} + +int ram_init() +{ + int err = E_NO_ERROR; + err = spi_init(); + if (err) + return err; + + err = ram_exit_quadmode(); // Protect against quad-mode lock-up + if (err) + return err; + + // Set the hold pin to the HIGH state. + // This is required for normal SPI operations to work reliably + MXC_GPIO_Config(&hold_pin); + MXC_GPIO_OutSet(hold_pin.port, hold_pin.mask); + + err = ram_write_mode_reg(0x01); // Disable hold function + if (err) + return err; + + // Validate that we were able to write to the mode register + // This is the closest thing we have to a "read id" or + // communication verification for this SRAM chip. + uint8_t mode_reg; + err = ram_read_mode_reg(&mode_reg); + if (err) + return err; + + if (mode_reg != 0x01) { + return E_NO_DEVICE; + } + + // Re-configure SPI pins now that the hold function has been disabled. + err = MXC_GPIO_Config(&spi_pins); + return err; +} + +int ram_enter_quadmode() +{ + int err = E_NO_ERROR; + uint8_t tx_data = CMD_ENABLE_QUAD_IO; + + MXC_SPI_SetWidth(SPI, SPI_WIDTH_STANDARD); + spi_transmit(&tx_data, 1, NULL, 0, true, true, true); + MXC_SPI_SetWidth(SPI, SPI_WIDTH_QUAD); + + g_current_mode = QUAD_MODE; + + return err; +} + +int ram_exit_quadmode() +{ + int err = E_NO_ERROR; + uint8_t tx_data = CMD_RESET_IO; + + MXC_SPI_SetWidth(SPI, SPI_WIDTH_QUAD); + spi_transmit(&tx_data, 1, NULL, 0, true, true, true); + MXC_SPI_SetWidth(SPI, SPI_WIDTH_STANDARD); + + g_current_mode = STANDARD_MODE; + + return err; +} + +int ram_read(uint32_t address, uint8_t *out, unsigned int len) +{ + if (g_current_mode == STANDARD_MODE) { + _transmit_spi_header(CMD_READ, address); + } else if (g_current_mode == QUAD_MODE) { + // QUAD mode requires 1 dummy byte. + uint8_t header[5]; // (1 byte cmd + 3 byte address + 1 dummy) + memset(header, 0xFF, 5); + _parse_spi_header(CMD_READ, address, header); + spi_transmit(header, 5, NULL, 0, false, true, true); + } + + return spi_transmit(NULL, 0, out, len, true, true, true); +} + +int ram_write(uint32_t address, uint8_t *data, unsigned int len) +{ + _transmit_spi_header(CMD_WRITE, address); + return spi_transmit(data, len, NULL, 0, true, true, true); +} + +int ram_write_mode_reg(uint8_t val) +{ + uint8_t data[2] = { CMD_WRITE_MODE_REG, val }; + return spi_transmit(data, 2, NULL, 0, true, true, true); +} + +int ram_read_mode_reg(uint8_t* out) +{ + int err = E_NO_ERROR; + uint8_t cmd = CMD_READ_MODE_REG; + err = spi_transmit(&cmd, 1, NULL, 0, false, true, true); + if (err) + return err; + return spi_transmit(NULL, 0, out, 1, true, true, true); +} diff --git a/Examples/MAX78000/QSPI/N01S830HA.h b/Examples/MAX78000/QSPI/N01S830HA.h new file mode 100644 index 00000000000..4cd0e6a1550 --- /dev/null +++ b/Examples/MAX78000/QSPI/N01S830HA.h @@ -0,0 +1,72 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ +#ifndef EXAMPLES_MAX78000_QSPI_N01S830HA_H_ +#define EXAMPLES_MAX78000_QSPI_N01S830HA_H_ + +#include +#include "gpio.h" +#include "max78000.h" + +#define CMD_READ 0x03 +#define CMD_WRITE 0x02 +#define CMD_ENABLE_QUAD_IO 0x38 +#define CMD_ENABLE_DUAL_IO 0x3B +#define CMD_RESET_IO 0xFF +#define CMD_READ_MODE_REG 0x05 +#define CMD_WRITE_MODE_REG 0x01 + +// P0.9 on MAX78000FTHR is routed to HOLD pin +#define HOLD_PIN_PORT MXC_GPIO0 +#define HOLD_PIN_MASK MXC_GPIO_PIN_9 + +static const mxc_gpio_cfg_t hold_pin = { .port = HOLD_PIN_PORT, + .mask = HOLD_PIN_MASK, + .func = MXC_GPIO_FUNC_OUT, + .pad = MXC_GPIO_PAD_WEAK_PULL_UP, + .vssel = MXC_GPIO_VSSEL_VDDIOH }; + +int ram_init(); + +int ram_enter_quadmode(); + +int ram_exit_quadmode(); + +int ram_read(uint32_t address, uint8_t *out, unsigned int len); + +int ram_write(uint32_t address, uint8_t *data, unsigned int len); + +int ram_write_mode_reg(uint8_t val); + +int ram_read_mode_reg(uint8_t* out); + +#endif // EXAMPLES_MAX78000_QSPI_N01S830HA_H_ diff --git a/Examples/MAX78000/QSPI/QSPI.launch b/Examples/MAX78000/QSPI/QSPI.launch new file mode 100644 index 00000000000..82eba3a536a --- /dev/null +++ b/Examples/MAX78000/QSPI/QSPI.launch @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/MAX78000/QSPI/README.md b/Examples/MAX78000/QSPI/README.md new file mode 100644 index 00000000000..8e9e76b5f3a --- /dev/null +++ b/Examples/MAX78000/QSPI/README.md @@ -0,0 +1,61 @@ +## Description + +This example demonstrates QSPI communication in drivers written for the APS6404 external SRAM IC on the MAX78002EVKIT. It also excercises the APS6404 by reading and validating various test patterns and demonstrates the speed increases using QSPI vs traditional SPI. + +## Software + +### Project Usage + +Universal instructions on building, flashing, and debugging this project can be found in the **[MSDK User Guide](https://analog-devices-msdk.github.io/msdk/USERGUIDE/)**. + +### Project-Specific Build Notes + +(None - this project builds and runs as a standard example) + +## Expected Output + +```shell +QSPI SRAM Test: + Test Address: 0x0 + Test size: 640 bytes + Test count: 480 rows + Test speed: 24000000 Hz +Reading ID... +RAM ID: + MFID: 0x0d + KGD: 0x5d + Density: 0x02 + EID: 0x576c8d0d +(Benchmark) Wrote 640 bytes to internal SRAM in 5us +Test 1: Standard SPI write... + Done (640 bytes in 202us) +Test 2: Validate w/ standard SPI... + Read finished (640 bytes in 204us) + Checking for mismatches... + Done +Test 3: Validate w/ QSPI... + Read finished (640 bytes in 87us) + Checking for mismatches... + Done +Test 4: QSPI Write... + Done (640 bytes in 94us) +Test 5: Validate w/ standard SPI... + Read finished (640 bytes in 220us) + Checking for mismatches... + Done +Test 6: Validate w/ QSPI... + Read finished (640 bytes in 87us) + Checking for mismatches... + Done +Test 7: QSPI Writing across page boundaries... + Wrote 307200 bytes in 45408us +Test 8: Validating with standard SPI... + Success +Test 9: Validating with QSPI... + Success +Success! +``` + +## Required Connections + +- Connect a USB cable between the PC and the CN2 (USB/PWR) connector and connect a serial terminal at 115200 BAUD rate (8-N-1) to view the console output. diff --git a/Examples/MAX78000/QSPI/fastspi.c b/Examples/MAX78000/QSPI/fastspi.c new file mode 100644 index 00000000000..98022a65aa7 --- /dev/null +++ b/Examples/MAX78000/QSPI/fastspi.c @@ -0,0 +1,385 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ + +#include +#include +#include +#include "fastspi.h" +#include "gpio.h" +#include "mxc_sys.h" +#include "spi.h" +#include "dma.h" +#include "nvic_table.h" +#include "mxc_delay.h" + +int g_tx_channel; +int g_rx_channel; +int g_fill_dummy_bytes = 0; +int g_dummy_len = 0; +uint8_t g_dummy_byte = 0xFF; +bool g_use_dma = false; + +bool g_dma_initialized = false; + +uint8_t *g_rx_buffer; +uint8_t *g_tx_buffer; +uint32_t g_rx_len; +uint32_t g_tx_len; + +// A macro to convert a DMA channel number to an IRQn number +#define GetIRQnForDMAChannel(x) \ + ((IRQn_Type)(((x) == 0) ? DMA0_IRQn : \ + ((x) == 1) ? DMA1_IRQn : \ + ((x) == 2) ? DMA2_IRQn : \ + DMA3_IRQn)) + +void DMA_TX_IRQHandler() +{ + volatile mxc_dma_ch_regs_t *ch = + &MXC_DMA->ch[g_tx_channel]; // Cast the pointer for readability in this ISR + uint32_t status = ch->status; + + if (status & MXC_F_DMA_STATUS_CTZ_IF) { // Count-to-Zero (DMA TX complete) + g_tx_done = 1; + ch->status |= MXC_F_DMA_STATUS_CTZ_IF; + } + + if (status & MXC_F_DMA_STATUS_BUS_ERR) { // Bus Error + ch->status |= MXC_F_DMA_STATUS_BUS_ERR; + } +} + +void DMA_RX_IRQHandler() +{ + volatile mxc_dma_ch_regs_t *ch = + &MXC_DMA->ch[g_rx_channel]; // Cast the pointer for readability in this ISR + uint32_t status = ch->status; + + if (status & MXC_F_DMA_STATUS_CTZ_IF) { // Count-to-Zero (DMA RX complete) + g_rx_done = 1; + ch->status |= MXC_F_DMA_STATUS_CTZ_IF; + } + + if (status & MXC_F_DMA_STATUS_BUS_ERR) { // Bus Error + ch->status |= MXC_F_DMA_STATUS_BUS_ERR; + } +} + +void processSPI() +{ + // Unload any SPI data that has come in + while (g_rx_buffer && (SPI->dma & MXC_F_SPI_DMA_RX_LVL) && g_rx_len > 0) { + *g_rx_buffer++ = SPI->fifo8[0]; + g_rx_len--; + } + + if (g_rx_len <= 0) { + g_rx_done = 1; + } + + // Write any pending bytes out. + while (g_tx_buffer && + (((SPI->dma & MXC_F_SPI_DMA_TX_LVL) >> MXC_F_SPI_DMA_TX_LVL_POS) < MXC_SPI_FIFO_DEPTH) && + g_tx_len > 0) { + SPI->fifo8[0] = *g_tx_buffer++; + g_tx_len--; + } + + if (g_tx_len <= 0) { + g_tx_done = 1; + } +} + +void SPI_IRQHandler() +{ + uint32_t status = SPI->intfl; + + if (status & MXC_F_SPI_INTFL_MST_DONE) { // Master done (TX complete) + g_master_done = 1; + SPI->intfl |= MXC_F_SPI_INTFL_MST_DONE; // Clear flag + } + + if (status & MXC_F_SPI_INTFL_RX_THD) { + SPI->intfl |= MXC_F_SPI_INTFL_RX_THD; + if (!g_use_dma) { + // RX threshold has been crossed, there's data to unload from the FIFO + processSPI(); + } + } + + if (status & MXC_F_SPI_INTFL_TX_THD) { + SPI->intfl |= MXC_F_SPI_INTFL_TX_THD; + if (!g_use_dma) { + // TX threshold has been crossed, we need to refill the FIFO + processSPI(); + } + } +} + +int dma_init() +{ + if (g_dma_initialized) + return E_NO_ERROR; + + int err = MXC_DMA_Init(); + // If we get a bad state error here it means DMA has already been + // initialized. The drivers do a good job of handling this case, + // so it's safe to continue + if (err && (err != E_BAD_STATE)) + return err; + + g_tx_channel = MXC_DMA_AcquireChannel(); + g_rx_channel = MXC_DMA_AcquireChannel(); + if (g_tx_channel < 0 || g_rx_channel < 0) { + return E_NONE_AVAIL; // Failed to acquire DMA channels + } + + // TX Channel + MXC_DMA->ch[g_tx_channel].ctrl &= ~(MXC_F_DMA_CTRL_EN); + MXC_DMA->ch[g_tx_channel].ctrl = + MXC_F_DMA_CTRL_SRCINC | + (0x2F + << MXC_F_DMA_CTRL_REQUEST_POS); // Enable incrementing the src address pointer, set destination to SPI0 TX FIFO (REQSEL = 0x2F) + MXC_DMA->ch[g_tx_channel].ctrl |= + (MXC_F_DMA_CTRL_CTZ_IE | MXC_F_DMA_CTRL_DIS_IE); // Enable CTZ and DIS interrupts + MXC_DMA->inten |= (1 << g_tx_channel); // Enable DMA interrupts + + // RX Channel + MXC_DMA->ch[g_rx_channel].ctrl &= ~(MXC_F_DMA_CTRL_EN); + MXC_DMA->ch[g_rx_channel].ctrl = + MXC_F_DMA_CTRL_DSTINC | + (0x0F + << MXC_F_DMA_CTRL_REQUEST_POS); // Enable incrementing the dest address pointer, set to source to SPI0 RX FIFO (REQSEL = 0x0F) + MXC_DMA->ch[g_rx_channel].ctrl |= + (MXC_F_DMA_CTRL_CTZ_IE | MXC_F_DMA_CTRL_DIS_IE); // Enable CTZ and DIS interrupts + MXC_DMA->inten |= (1 << g_rx_channel); // Enable DMA interrupts + + MXC_NVIC_SetVector(GetIRQnForDMAChannel(g_tx_channel), DMA_TX_IRQHandler); + NVIC_EnableIRQ(GetIRQnForDMAChannel(g_tx_channel)); + NVIC_SetPriority(GetIRQnForDMAChannel(g_tx_channel), 0); + + MXC_NVIC_SetVector(GetIRQnForDMAChannel(g_rx_channel), DMA_RX_IRQHandler); + NVIC_EnableIRQ(GetIRQnForDMAChannel(g_rx_channel)); + NVIC_SetPriority(GetIRQnForDMAChannel(g_tx_channel), 0); + + g_dma_initialized = true; + + return E_NO_ERROR; +} + +int spi_init() +{ + // TODO(Jake): Add software-controlled slave select functionality + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0); + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI0); + + int err = MXC_GPIO_Config(&spi_pins); + if (err) + return err; + + err = MXC_GPIO_Config(&spi_ss_pin); + if (err) + return err; + + // Set strongest possible drive strength for SPI pins + spi_pins.port->ds0 |= spi_pins.mask; + spi_pins.port->ds1 |= spi_pins.mask; + + // TODO(Jake): Expose some of the config options below + // TODO(Jake): Move QSPI-SRAM specific options into aps6404.c + + SPI->ctrl0 = (0b0100 << MXC_F_SPI_CTRL0_SS_ACTIVE_POS) | // Set SSEL = SS2 + MXC_F_SPI_CTRL0_MST_MODE | // Select controller mode + MXC_F_SPI_CTRL0_EN; // Enable SPI + + SPI->ctrl2 = (8 << MXC_F_SPI_CTRL2_NUMBITS_POS); // Set 8 bits per character + + SPI->sstime = + (1 << MXC_F_SPI_SSTIME_PRE_POS) | // Remove any delay time between SSEL and SCLK edges + (128 << MXC_F_SPI_SSTIME_POST_POS) | (1 << MXC_F_SPI_SSTIME_INACT_POS); + + SPI->dma = MXC_F_SPI_DMA_TX_FIFO_EN | // Enable TX FIFO + (31 << MXC_F_SPI_DMA_TX_THD_VAL_POS) | // Set TX threshold to 31 + MXC_F_SPI_DMA_DMA_TX_EN; // Enable DMA for the TX FIFO + + SPI->inten |= MXC_F_SPI_INTFL_MST_DONE; // Enable the "Transaction complete" interrupt + + SPI->intfl = SPI->intfl; // Clear any any interrupt flags that may already be set + + err = MXC_SPI_SetFrequency(SPI, SPI_SPEED); + if (err) + return err; + + NVIC_EnableIRQ(MXC_SPI_GET_IRQ(MXC_SPI_GET_IDX(SPI))); + MXC_NVIC_SetVector(MXC_SPI_GET_IRQ(MXC_SPI_GET_IDX(SPI)), SPI_IRQHandler); + NVIC_SetPriority(MXC_SPI_GET_IRQ(MXC_SPI_GET_IDX(SPI)), 0); + + err = dma_init(); + + return err; +} + +int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert, + bool use_dma, bool block) +{ + g_tx_done = 0; + g_rx_done = 0; + g_master_done = 0; + mxc_spi_width_t width = MXC_SPI_GetWidth(SPI); + + // Set the number of bytes to transmit/receive for the SPI transaction + if (width == SPI_WIDTH_STANDARD) { + if (rxlen > txlen) { + /* + In standard 4-wire mode, the RX_NUM_CHAR field of ctrl1 is ignored. + The number of bytes to transmit AND receive is set by TX_NUM_CHAR, + because the hardware always assume full duplex. Therefore extra + dummy bytes must be transmitted to support half duplex. + */ + g_dummy_len = rxlen - txlen; + SPI->ctrl1 = ((txlen + g_dummy_len) << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS); + } else { + SPI->ctrl1 = txlen << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS; + } + } else { // width != SPI_WIDTH_STANDARD + SPI->ctrl1 = (txlen << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS) | + (rxlen << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS); + } + + SPI->dma &= ~(MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN | MXC_F_SPI_DMA_RX_FIFO_EN | + MXC_F_SPI_DMA_DMA_RX_EN); // Disable FIFOs before clearing as recommended by UG + SPI->dma |= (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH); // Clear the FIFOs + + if (use_dma) { + g_use_dma = true; + // TX + if (txlen > 1) { + // Configure TX DMA channel to fill the SPI TX FIFO + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN | + (31 << MXC_F_SPI_DMA_TX_THD_VAL_POS)); + SPI->fifo8[0] = src[0]; + // ^ Hardware requires writing the first byte into the FIFO manually. + MXC_DMA->ch[g_tx_channel].src = (uint32_t)(src + 1); + MXC_DMA->ch[g_tx_channel].cnt = txlen - 1; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_SRCINC; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } else if (txlen == 1) { + // Workaround for single-length transactions not triggering CTZ + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); + SPI->fifo8[0] = src[0]; // Write first byte into FIFO + g_tx_done = 1; + } else if (txlen == 0 && width == SPI_WIDTH_STANDARD) { + // Configure TX DMA channel to retransmit a dummy byte + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); + MXC_DMA->ch[g_tx_channel].src = (uint32_t)&g_dummy_byte; + MXC_DMA->ch[g_tx_channel].cnt = rxlen; + MXC_DMA->ch[g_tx_channel].ctrl &= ~MXC_F_DMA_CTRL_SRCINC; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } + + // RX + if (rxlen > 0) { + // Configure RX DMA channel to unload the SPI RX FIFO + SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN | MXC_F_SPI_DMA_DMA_RX_EN); + MXC_DMA->ch[g_rx_channel].dst = (uint32_t)dest; + MXC_DMA->ch[g_rx_channel].cnt = rxlen; + MXC_DMA->ch[g_rx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } + + } else { // !use_dma + g_use_dma = false; + g_rx_buffer = dest; + g_tx_buffer = src; + g_rx_len = rxlen; + g_tx_len = txlen; + + SPI->inten |= MXC_F_SPI_INTEN_MST_DONE; + + if (txlen > 0) { + // Enable TX FIFO & TX Threshold crossed interrupt + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN); + SPI->inten |= MXC_F_SPI_INTEN_TX_THD; + } + + if (rxlen > 0) { + // Enable RX FIFO & RX Threshold crossed interrupt + SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN); + SPI->inten |= MXC_F_SPI_INTEN_RX_THD; + } + + /* + This processSPI call fills the TX FIFO as much as possible + before launching the transaction. Subsequent FIFO management will + be handled from the SPI_IRQHandler. + */ + processSPI(); + } + + // Start the SPI transaction + SPI->ctrl0 |= MXC_F_SPI_CTRL0_START; + + /* + Handle slave-select (SS) deassertion. This must be done AFTER launching the transaction + to avoid a glitch on the SS line if: + - The SS line is asserted + - We want to deassert the line as part of this transaction + + As soon as the SPI hardware receives CTRL0->START it seems to reinitialize the SS pin based + on the value of CTRL->SS_CTRL, which causes the glitch. + */ + if (deassert) + SPI->ctrl0 &= ~MXC_F_SPI_CTRL0_SS_CTRL; + else + SPI->ctrl0 |= MXC_F_SPI_CTRL0_SS_CTRL; + + if (block) { + while (!((g_tx_done && g_master_done) && (src != NULL && txlen > 0)) && + !(g_rx_done && (dest != NULL && rxlen > 0))) { + /* + The following polling is a safety fallback to catch any missed interrupts. + This is especially common with extremely short transactions, where all 3 + interrupts may fire almost simultaneously. + */ + if ((src != NULL && txlen > 0) && SPI->intfl & MXC_F_SPI_INTFL_MST_DONE) + g_master_done = 1; + if ((src != NULL && txlen > 0) && + MXC_DMA->ch[g_tx_channel].status & MXC_F_DMA_STATUS_CTZ_IF) + g_tx_done = 1; + if ((dest != NULL && rxlen > 0) && + MXC_DMA->ch[g_rx_channel].status & MXC_F_DMA_STATUS_CTZ_IF) + g_rx_done = 1; + } + } + + return E_SUCCESS; +} diff --git a/Examples/MAX78000/QSPI/fastspi.h b/Examples/MAX78000/QSPI/fastspi.h new file mode 100644 index 00000000000..80b4f5f6929 --- /dev/null +++ b/Examples/MAX78000/QSPI/fastspi.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ +#ifndef EXAMPLES_MAX78002_QSPI_FASTSPI_H_ +#define EXAMPLES_MAX78002_QSPI_FASTSPI_H_ + +#include "fastspi_config.h" + +static volatile bool g_tx_done = 0; +static volatile bool g_rx_done = 0; +static volatile bool g_master_done = 0; + +static const mxc_gpio_cfg_t spi_ss_pin = { .port = SPI_SS_PORT, + .mask = SPI_SS_PIN, + .func = MXC_GPIO_FUNC_ALT2, // ALT2 for SS2 + .pad = MXC_GPIO_PAD_WEAK_PULL_UP, + .vssel = MXC_GPIO_VSSEL_VDDIOH }; + +static const mxc_gpio_cfg_t spi_pins = { .port = SPI_PINS_PORT, + .mask = SPI_PINS_MASK, + .func = MXC_GPIO_FUNC_ALT1, + .pad = MXC_GPIO_PAD_NONE, + .vssel = MXC_GPIO_VSSEL_VDDIOH }; + +// TODO(Jake): Generalize to multiple SPI instances +int spi_init(); +int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert, + bool use_dma, bool block); + +#endif // EXAMPLES_MAX78002_QSPI_FASTSPI_H_ diff --git a/Examples/MAX78000/QSPI/fastspi.old b/Examples/MAX78000/QSPI/fastspi.old new file mode 100644 index 00000000000..981a3a60e84 --- /dev/null +++ b/Examples/MAX78000/QSPI/fastspi.old @@ -0,0 +1,359 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ +#include +#include +#include +#include "fastspi.h" +#include "gpio.h" +#include "mxc_sys.h" +#include "spi.h" +#include "dma.h" +#include "nvic_table.h" +#include "mxc_delay.h" + +int g_tx_channel; +int g_rx_channel; +int g_fill_dummy_bytes = 0; +int g_dummy_len = 0; +uint8_t g_dummy_byte = 0xFF; +bool g_use_dma = false; + +uint8_t *g_rx_buffer; +uint8_t *g_tx_buffer; +uint32_t g_rx_len; +uint32_t g_tx_len; + +// A macro to convert a DMA channel number to an IRQn number +#define GetIRQnForDMAChannel(x) \ + ((IRQn_Type)(((x) == 0) ? DMA0_IRQn : \ + ((x) == 1) ? DMA1_IRQn : \ + ((x) == 2) ? DMA2_IRQn : \ + DMA3_IRQn)) + +void DMA_TX_IRQHandler() +{ + volatile mxc_dma_ch_regs_t *ch = + &MXC_DMA->ch[g_tx_channel]; // Cast the pointer for readability in this ISR + uint32_t status = ch->status; + + if (status & MXC_F_DMA_STATUS_CTZ_IF) { // Count-to-Zero (DMA TX complete) + g_tx_done = 1; + ch->status |= MXC_F_DMA_STATUS_CTZ_IF; + } + + if (status & MXC_F_DMA_STATUS_BUS_ERR) { // Bus Error + ch->status |= MXC_F_DMA_STATUS_BUS_ERR; + } +} + +void DMA_RX_IRQHandler() +{ + volatile mxc_dma_ch_regs_t *ch = + &MXC_DMA->ch[g_rx_channel]; // Cast the pointer for readability in this ISR + uint32_t status = ch->status; + + if (status & MXC_F_DMA_STATUS_CTZ_IF) { // Count-to-Zero (DMA RX complete) + g_rx_done = 1; + ch->status |= MXC_F_DMA_STATUS_CTZ_IF; + } + + if (status & MXC_F_DMA_STATUS_BUS_ERR) { // Bus Error + ch->status |= MXC_F_DMA_STATUS_BUS_ERR; + } +} + +void processSPI() +{ + // Unload any SPI data that has come in + while (g_rx_buffer && (SPI->dma & MXC_F_SPI_DMA_RX_LVL) && g_rx_len > 0) { + *g_rx_buffer++ = SPI->fifo8[0]; + g_rx_len--; + } + + if (g_rx_len <= 0) { + g_rx_done = 1; + } + + // Write any pending bytes out. + while (g_tx_buffer && + (((SPI->dma & MXC_F_SPI_DMA_TX_LVL) >> MXC_F_SPI_DMA_TX_LVL_POS) < MXC_SPI_FIFO_DEPTH) && + g_tx_len > 0) { + SPI->fifo8[0] = *g_tx_buffer++; + g_tx_len--; + } + + if (g_tx_len <= 0) { + g_tx_done = 1; + } +} + +void SPI_IRQHandler() +{ + uint32_t status = SPI->intfl; + + if (status & MXC_F_SPI_INTFL_MST_DONE) { // Master done (TX complete) + g_master_done = 1; + SPI->intfl |= MXC_F_SPI_INTFL_MST_DONE; // Clear flag + } + + if (status & MXC_F_SPI_INTFL_RX_THD) { + SPI->intfl |= MXC_F_SPI_INTFL_RX_THD; + if (!g_use_dma) { + // RX threshold has been crossed, there's data to unload from the FIFO + processSPI(); + } + } + + if (status & MXC_F_SPI_INTFL_TX_THD) { + SPI->intfl |= MXC_F_SPI_INTFL_TX_THD; + if (!g_use_dma) { + // TX threshold has been crossed, we need to refill the FIFO + processSPI(); + } + } +} + +int dma_init() +{ + int err = MXC_DMA_Init(); + if (err) + return err; + + g_tx_channel = MXC_DMA_AcquireChannel(); + g_rx_channel = MXC_DMA_AcquireChannel(); + if (g_tx_channel < 0 || g_rx_channel < 0) { + return E_NONE_AVAIL; // Failed to acquire DMA channels + } + + // TX Channel + MXC_DMA->ch[g_tx_channel].ctrl &= ~(MXC_F_DMA_CTRL_EN); + MXC_DMA->ch[g_tx_channel].ctrl = + MXC_F_DMA_CTRL_SRCINC | + (0x2F + << MXC_F_DMA_CTRL_REQUEST_POS); // Enable incrementing the src address pointer, set destination to SPI0 TX FIFO (REQSEL = 0x2F) + MXC_DMA->ch[g_tx_channel].ctrl |= + (MXC_F_DMA_CTRL_CTZ_IE | MXC_F_DMA_CTRL_DIS_IE); // Enable CTZ and DIS interrupts + MXC_DMA->inten |= (1 << g_tx_channel); // Enable DMA interrupts + + // RX Channel + MXC_DMA->ch[g_rx_channel].ctrl &= ~(MXC_F_DMA_CTRL_EN); + MXC_DMA->ch[g_rx_channel].ctrl = + MXC_F_DMA_CTRL_DSTINC | + (0x0F + << MXC_F_DMA_CTRL_REQUEST_POS); // Enable incrementing the dest address pointer, set to source to SPI0 RX FIFO (REQSEL = 0x0F) + MXC_DMA->ch[g_rx_channel].ctrl |= + (MXC_F_DMA_CTRL_CTZ_IE | MXC_F_DMA_CTRL_DIS_IE); // Enable CTZ and DIS interrupts + MXC_DMA->inten |= (1 << g_rx_channel); // Enable DMA interrupts + + MXC_NVIC_SetVector(GetIRQnForDMAChannel(g_tx_channel), DMA_TX_IRQHandler); + NVIC_EnableIRQ(GetIRQnForDMAChannel(g_tx_channel)); + NVIC_SetPriority(GetIRQnForDMAChannel(g_tx_channel), 0); + + MXC_NVIC_SetVector(GetIRQnForDMAChannel(g_rx_channel), DMA_RX_IRQHandler); + NVIC_EnableIRQ(GetIRQnForDMAChannel(g_rx_channel)); + NVIC_SetPriority(GetIRQnForDMAChannel(g_tx_channel), 0); + + return err; +} + +int spi_init() +{ + // TODO(Jake): Add software-controlled slave select functionality + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0); + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI0); + + int err = MXC_GPIO_Config(&spi_pins); + if (err) + return err; + + err = MXC_GPIO_Config(&spi_ss_pin); + if (err) + return err; + + // Set strongest possible drive strength for SPI pins + spi_pins.port->ds0 |= spi_pins.mask; + spi_pins.port->ds1 |= spi_pins.mask; + + // TODO(Jake): Expose some of the config options below + // TODO(Jake): Move QSPI-SRAM specific options into aps6404.c + + SPI->ctrl0 = (0b100 << MXC_F_SPI_CTRL0_SS_ACTIVE_POS) | // Set SSEL = SS2 + MXC_F_SPI_CTRL0_MST_MODE | // Select controller mode + MXC_F_SPI_CTRL0_EN; // Enable SPI + + SPI->ctrl2 = (8 << MXC_F_SPI_CTRL2_NUMBITS_POS); // Set 8 bits per character + + SPI->sstime = + (1 << MXC_F_SPI_SSTIME_PRE_POS) | // Remove any delay time between SSEL and SCLK edges + (128 << MXC_F_SPI_SSTIME_POST_POS) | (1 << MXC_F_SPI_SSTIME_INACT_POS); + + SPI->dma = MXC_F_SPI_DMA_TX_FIFO_EN | // Enable TX FIFO + (31 << MXC_F_SPI_DMA_TX_THD_VAL_POS) | // Set TX threshold to 31 + MXC_F_SPI_DMA_DMA_TX_EN; // Enable DMA for the TX FIFO + + SPI->inten |= MXC_F_SPI_INTFL_MST_DONE; // Enable the "Transaction complete" interrupt + + SPI->intfl = SPI->intfl; // Clear any any interrupt flags that may already be set + + err = MXC_SPI_SetFrequency(SPI, SPI_SPEED); + if (err) + return err; + + NVIC_EnableIRQ(MXC_SPI_GET_IRQ(MXC_SPI_GET_IDX(SPI))); + MXC_NVIC_SetVector(MXC_SPI_GET_IRQ(MXC_SPI_GET_IDX(SPI)), SPI_IRQHandler); + NVIC_SetPriority(MXC_SPI_GET_IRQ(MXC_SPI_GET_IDX(SPI)), 1); + + err = dma_init(); + + return err; +} + +int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert, + bool use_dma, bool block) +{ + g_tx_done = 0; + g_rx_done = 0; + g_master_done = 0; + mxc_spi_width_t width = MXC_SPI_GetWidth(SPI); + + // Set the number of bytes to transmit/receive for the SPI transaction + if (width == SPI_WIDTH_STANDARD) { + if (rxlen > txlen) { + /* + In standard 4-wire mode, the RX_NUM_CHAR field of ctrl1 is ignored. + The number of bytes to transmit AND receive is set by TX_NUM_CHAR, + because the hardware always assume full duplex. Therefore extra + dummy bytes must be transmitted to support half duplex. + */ + g_dummy_len = rxlen - txlen; + SPI->ctrl1 = ((txlen + g_dummy_len) << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS); + } else { + SPI->ctrl1 = txlen << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS; + } + } else { // width != SPI_WIDTH_STANDARD + SPI->ctrl1 = (txlen << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS) | + (rxlen << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS); + } + + SPI->dma &= ~(MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN | MXC_F_SPI_DMA_RX_FIFO_EN | + MXC_F_SPI_DMA_DMA_RX_EN); // Disable FIFOs before clearing as recommended by UG + SPI->dma |= (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH); // Clear the FIFOs + + if (use_dma) { + g_use_dma = true; + // TX + if (txlen > 1) { + // Configure TX DMA channel to fill the SPI TX FIFO + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN | + (31 << MXC_F_SPI_DMA_TX_THD_VAL_POS)); + SPI->fifo8[0] = src[0]; + // ^ Hardware requires writing the first byte into the FIFO manually. + MXC_DMA->ch[g_tx_channel].src = (uint32_t)(src + 1); + MXC_DMA->ch[g_tx_channel].cnt = txlen - 1; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_SRCINC; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } else if (txlen == 1) { + // Workaround for single-length transactions not triggering CTZ + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); + SPI->fifo8[0] = src[0]; // Write first byte into FIFO + g_tx_done = 1; + } else if (txlen == 0 && width == SPI_WIDTH_STANDARD) { + // Configure TX DMA channel to retransmit a dummy byte + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); + MXC_DMA->ch[g_tx_channel].src = (uint32_t)&g_dummy_byte; + MXC_DMA->ch[g_tx_channel].cnt = rxlen; + MXC_DMA->ch[g_tx_channel].ctrl &= ~MXC_F_DMA_CTRL_SRCINC; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } + + // RX + if (rxlen > 0) { + // Configure RX DMA channel to unload the SPI RX FIFO + SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN | MXC_F_SPI_DMA_DMA_RX_EN); + MXC_DMA->ch[g_rx_channel].dst = (uint32_t)dest; + MXC_DMA->ch[g_rx_channel].cnt = rxlen; + MXC_DMA->ch[g_rx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } + + } else { // !use_dma + g_use_dma = false; + g_rx_buffer = dest; + g_tx_buffer = src; + g_rx_len = rxlen; + g_tx_len = txlen; + + SPI->inten |= MXC_F_SPI_INTEN_MST_DONE; + + if (txlen > 0) { + // Enable TX FIFO & TX Threshold crossed interrupt + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN); + SPI->inten |= MXC_F_SPI_INTEN_TX_THD; + } + + if (rxlen > 0) { + // Enable RX FIFO & RX Threshold crossed interrupt + SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN); + SPI->inten |= MXC_F_SPI_INTEN_RX_THD; + } + + /* + This processSPI call fills the TX FIFO as much as possible + before launching the transaction. Subsequent FIFO management will + be handled from the SPI_IRQHandler. + */ + processSPI(); + } + + // Start the SPI transaction + SPI->ctrl0 |= MXC_F_SPI_CTRL0_START; + + /* + Handle slave-select (SS) deassertion. This must be done AFTER launching the transaction + to avoid a glitch on the SS line if: + - The SS line is asserted + - We want to deassert the line as part of this transaction + + As soon as the SPI hardware receives CTRL0->START it seems to reinitialize the SS pin based + on the value of CTRL->SS_CTRL, which causes the glitch. + */ + if (deassert) + SPI->ctrl0 &= ~MXC_F_SPI_CTRL0_SS_CTRL; + else + SPI->ctrl0 |= MXC_F_SPI_CTRL0_SS_CTRL; + + if (block) + while (!((g_tx_done && g_master_done) && (src != NULL && txlen > 0)) && + !(g_rx_done && (dest != NULL && rxlen > 0))) {} + + return E_SUCCESS; +} diff --git a/Examples/MAX78000/QSPI/fastspi_config.h b/Examples/MAX78000/QSPI/fastspi_config.h new file mode 100644 index 00000000000..c5c63d1bf45 --- /dev/null +++ b/Examples/MAX78000/QSPI/fastspi_config.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ +#ifndef EXAMPLES_MAX78002_QSPI_FASTSPI_CONFIG_H_ +#define EXAMPLES_MAX78002_QSPI_FASTSPI_CONFIG_H_ + +#include "spi.h" +#include "gpio.h" + +// TODO(Jake): Config struct +#define SPI MXC_SPI0 +#define SPI_SPEED 2000000 +// #define SPI_SPEED 1000000 +#define SPI_PINS_PORT MXC_GPIO0 +#define SPI_PINS_MASK \ + (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8 | MXC_GPIO_PIN_9) +#define SPI_SS_PORT MXC_GPIO0 +#define SPI_SS_PIN MXC_GPIO_PIN_10 // (SS2) + +#endif // EXAMPLES_MAX78002_QSPI_FASTSPI_CONFIG_H_ diff --git a/Examples/MAX78000/QSPI/main.c b/Examples/MAX78000/QSPI/main.c new file mode 100644 index 00000000000..972d0db19a8 --- /dev/null +++ b/Examples/MAX78000/QSPI/main.c @@ -0,0 +1,254 @@ +/****************************************************************************** + * Copyright (C) 2022 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ + +/** + * @file main.c + * @brief Hello World! + * @details This example uses the UART to print to a terminal and flashes an LED. + */ + +/***** Includes *****/ +#include +#include +#include +#include +#include "mxc_device.h" +#include "led.h" +#include "board.h" +#include "mxc_delay.h" +#include "spi.h" +#include "tmr.h" +#include "dma.h" +#include "nvic_table.h" +#include "fastspi.h" +#include "N01S830HA.h" + +/***** Definitions *****/ +#define TEST_SIZE 640 +#define TEST_COUNT 480 +#define TEST_VALUE 0x00 +#define TEST_ADDR 0x000 + +/***** Globals *****/ + +/***** Functions *****/ + +// ***************************************************************************** +int main(void) +{ + int err = E_NO_ERROR; + unsigned int elapsed = 0; + int fail_count = 0; + + MXC_Delay(MXC_DELAY_SEC(2)); + + // Set the Internal Primary Oscillator for the fastest system clock speed + MXC_SYS_Clock_Select(MXC_SYS_CLOCK_IPO); + + printf("QSPI SRAM Test:\n"); + printf("\tTest Address: 0x%x\n", TEST_ADDR); + printf("\tTest size: %i bytes\n", TEST_SIZE); + printf("\tTest count: %i rows\n", TEST_COUNT); + printf("\tTest speed: %i Hz\n", SPI_SPEED); + + if (ram_init() != E_NO_ERROR) + printf("RAM init failed!\n"); + + // Time the measurement overhead of our measurement functions + MXC_TMR_SW_Start(MXC_TMR0); + int sw_overhead = MXC_TMR_SW_Stop(MXC_TMR0); + + uint8_t tx_buffer[TEST_SIZE]; + uint8_t rx_buffer[TEST_SIZE]; + memset(rx_buffer, 0, TEST_SIZE); + + // Time tx_buffer initialization as benchmark + MXC_TMR_SW_Start(MXC_TMR0); + memset(tx_buffer, TEST_VALUE, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("(Benchmark) Wrote %i bytes to internal SRAM in %ius\n", TEST_SIZE, elapsed); + + // Benchmark standard-width SPI write to external SRAM + printf("Test 1: Standard SPI write...\n"); + MXC_TMR_SW_Start(MXC_TMR0); + ram_write(TEST_ADDR, tx_buffer, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tDone (%i bytes in %ius)\n", TEST_SIZE, elapsed); + + // Read and validate + printf("Test 2: Validate w/ standard SPI...\n"); + MXC_TMR_SW_Start(MXC_TMR0); + ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); + printf("\tChecking for mismatches...\n"); + for (int i = 0; i < TEST_SIZE; i++) { + if (rx_buffer[i] != tx_buffer[i]) { + fail_count++; + printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, + tx_buffer[i], rx_buffer[i]); + } + } + printf("\tDone\n"); + + printf("Test 3: Validate w/ QSPI...\n"); + ram_enter_quadmode(); + MXC_TMR_SW_Start(MXC_TMR0); + ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); + printf("\tChecking for mismatches...\n"); + for (int i = 0; i < TEST_SIZE; i++) { + if (rx_buffer[i] != tx_buffer[i]) { + fail_count++; + printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, + tx_buffer[i], rx_buffer[i]); + } + } + printf("\tDone\n"); + + // Invert test pattern - this ensures every bit has to be updated in the next write + memset(tx_buffer, ~(TEST_VALUE), TEST_SIZE); + // memset(tx_buffer, 0x00, TEST_SIZE); + memset(rx_buffer, 0, TEST_SIZE); + + // Benchmark QSPI write to external SRAM + printf("Test 4: QSPI Write...\n"); + MXC_TMR_SW_Start(MXC_TMR0); + err = ram_write(TEST_ADDR, tx_buffer, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tDone (%i bytes in %ius)\n", TEST_SIZE, elapsed); + + // Read and validate + printf("Test 5: Validate w/ standard SPI...\n"); + ram_exit_quadmode(); + MXC_TMR_SW_Start(MXC_TMR0); + ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); + printf("\tChecking for mismatches...\n"); + for (int i = 0; i < TEST_SIZE; i++) { + if (rx_buffer[i] != tx_buffer[i]) { + fail_count++; + printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, + tx_buffer[i], rx_buffer[i]); + } + } + printf("\tDone\n"); + + memset(rx_buffer, 0, TEST_SIZE); + + // Read and validate + printf("Test 6: Validate w/ QSPI...\n"); + ram_enter_quadmode(); + MXC_TMR_SW_Start(MXC_TMR0); + ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); + printf("\tChecking for mismatches...\n"); + for (int i = 0; i < TEST_SIZE; i++) { + if (rx_buffer[i] != tx_buffer[i]) { + fail_count++; + printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, + tx_buffer[i], rx_buffer[i]); + } + } + printf("\tDone\n"); + + // Generate a new more interesting test pattern + for (int i = 0; i < TEST_SIZE; i++) { + tx_buffer[i] = i % 256; + } + memset(rx_buffer, 0, TEST_SIZE); + + // Benchmark writing across multiple pages boundaries. + int address = TEST_ADDR; + printf("Test 7: QSPI Writing across page boundaries...\n", TEST_SIZE, TEST_COUNT); + MXC_TMR_SW_Start(MXC_TMR0); + for (int i = 0; i < TEST_COUNT; i++) { + ram_write(address, tx_buffer, TEST_SIZE); + address += TEST_SIZE; + } + elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("\tWrote %i bytes in %ius\n", TEST_SIZE * TEST_COUNT, elapsed); + + printf("Test 8: Validating with standard SPI...\n"); + ram_exit_quadmode(); + address = TEST_ADDR; + int temp = fail_count; + for (int i = 0; i < TEST_COUNT; i++) { + ram_read(address, rx_buffer, TEST_SIZE); + for (int j = 0; j < TEST_SIZE; j++) { + if (rx_buffer[j] != tx_buffer[j]) { + fail_count++; + } + } + address += TEST_SIZE; + memset(rx_buffer, 0, TEST_SIZE); + } + if (fail_count != temp) { + printf("\tFailed (%i) mismatches\n", fail_count - temp); + } else { + printf("\tSuccess\n"); + } + + // Validate + printf("Test 9: Validating with QSPI...\n"); + ram_enter_quadmode(); + address = TEST_ADDR; + temp = fail_count; + for (int i = 0; i < TEST_COUNT; i++) { + ram_read(address, rx_buffer, TEST_SIZE); + for (int j = 0; j < TEST_SIZE; j++) { + if (rx_buffer[j] != tx_buffer[j]) { + fail_count++; + } + } + address += TEST_SIZE; + memset(rx_buffer, 0, TEST_SIZE); + } + if (fail_count != temp) { + printf("\tFailed (%i) mismatches\n", fail_count - temp); + } else { + printf("\tSuccess\n"); + } + + if (fail_count > 0) { + printf("\nFailed with %i mismatches (%.2f%%)!\n", fail_count, + 100 * (((float)fail_count) / (TEST_SIZE * TEST_COUNT))); + return E_FAIL; + } + + printf("Success!\n"); + return err; +} diff --git a/Examples/MAX78000/QSPI/project.mk b/Examples/MAX78000/QSPI/project.mk new file mode 100644 index 00000000000..f068448db8a --- /dev/null +++ b/Examples/MAX78000/QSPI/project.mk @@ -0,0 +1,10 @@ +# This file can be used to set build configuration +# variables. These variables are defined in a file called +# "Makefile" that is located next to this one. + +# For instructions on how to use this system, see +# https://analog-devices-msdk.github.io/msdk/USERGUIDE/#build-system + +# ********************************************************** + +# Add your config here! From 939fbca0cd32a290d2e7406c5ed36d595c230a87 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Fri, 16 Jun 2023 18:07:44 -0500 Subject: [PATCH 02/26] Update project files --- Examples/MAX78000/QSPI/README.md | 44 +++---------------------------- Examples/MAX78000/QSPI/project.mk | 6 ++++- 2 files changed, 8 insertions(+), 42 deletions(-) diff --git a/Examples/MAX78000/QSPI/README.md b/Examples/MAX78000/QSPI/README.md index 8e9e76b5f3a..c5ec0156bec 100644 --- a/Examples/MAX78000/QSPI/README.md +++ b/Examples/MAX78000/QSPI/README.md @@ -1,6 +1,6 @@ ## Description -This example demonstrates QSPI communication in drivers written for the APS6404 external SRAM IC on the MAX78002EVKIT. It also excercises the APS6404 by reading and validating various test patterns and demonstrates the speed increases using QSPI vs traditional SPI. +This example demonstrates QSPI communication in drivers written for the N01S830HA external SRAM IC on the MAX78000FTHR. It also excercises the N01S830HA by reading and validating various test patterns and demonstrates the speed increases using QSPI vs traditional SPI. ## Software @@ -15,47 +15,9 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ```shell -QSPI SRAM Test: - Test Address: 0x0 - Test size: 640 bytes - Test count: 480 rows - Test speed: 24000000 Hz -Reading ID... -RAM ID: - MFID: 0x0d - KGD: 0x5d - Density: 0x02 - EID: 0x576c8d0d -(Benchmark) Wrote 640 bytes to internal SRAM in 5us -Test 1: Standard SPI write... - Done (640 bytes in 202us) -Test 2: Validate w/ standard SPI... - Read finished (640 bytes in 204us) - Checking for mismatches... - Done -Test 3: Validate w/ QSPI... - Read finished (640 bytes in 87us) - Checking for mismatches... - Done -Test 4: QSPI Write... - Done (640 bytes in 94us) -Test 5: Validate w/ standard SPI... - Read finished (640 bytes in 220us) - Checking for mismatches... - Done -Test 6: Validate w/ QSPI... - Read finished (640 bytes in 87us) - Checking for mismatches... - Done -Test 7: QSPI Writing across page boundaries... - Wrote 307200 bytes in 45408us -Test 8: Validating with standard SPI... - Success -Test 9: Validating with QSPI... - Success -Success! +TODO ``` ## Required Connections -- Connect a USB cable between the PC and the CN2 (USB/PWR) connector and connect a serial terminal at 115200 BAUD rate (8-N-1) to view the console output. +TODO diff --git a/Examples/MAX78000/QSPI/project.mk b/Examples/MAX78000/QSPI/project.mk index f068448db8a..acbe04494c8 100644 --- a/Examples/MAX78000/QSPI/project.mk +++ b/Examples/MAX78000/QSPI/project.mk @@ -7,4 +7,8 @@ # ********************************************************** -# Add your config here! +BOARD = FTHR_RevA + +ifneq "$(BOARD)" "FTHR_RevA" +$(error ERR_NOTSUPPORTED: This example is only supported on the MAX78000FTHR board! See https://analog-devices-msdk.github.io/msdk/USERGUIDE/#board-support-packages) +endif From 31c557aa9524595a400e752622cc82e5f6a4d8ed Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 18:49:47 -0600 Subject: [PATCH 03/26] Improve drivers - Modularize transport layer - Set burst mode for drivers to fix transactions across page boundaries - Increase SPI speed to 25Mhz - Simplify example --- Examples/MAX78000/QSPI/N01S830HA.c | 127 +++++++------ Examples/MAX78000/QSPI/N01S830HA.h | 153 +++++++++++++-- Examples/MAX78000/QSPI/N01S830HA_config.h | 33 ++++ Examples/MAX78000/QSPI/fastspi.c | 148 ++++++--------- Examples/MAX78000/QSPI/fastspi.h | 5 +- Examples/MAX78000/QSPI/fastspi_config.h | 3 +- Examples/MAX78000/QSPI/main.c | 218 +++++++--------------- 7 files changed, 373 insertions(+), 314 deletions(-) create mode 100644 Examples/MAX78000/QSPI/N01S830HA_config.h diff --git a/Examples/MAX78000/QSPI/N01S830HA.c b/Examples/MAX78000/QSPI/N01S830HA.c index ad9b842f6b8..73763730faa 100644 --- a/Examples/MAX78000/QSPI/N01S830HA.c +++ b/Examples/MAX78000/QSPI/N01S830HA.c @@ -43,6 +43,17 @@ enum MODE { STANDARD_MODE, QUAD_MODE }; typedef enum MODE MODE_t; MODE_t g_current_mode; +// ============================================================================= +// GLOBALS + +// global error variable +int _g_err = E_NO_ERROR; +// Error checking macro that can be used inside functions with an 'int' return +// type +#define ERR_CHECK(x) if ((_g_err = (x)) != E_NO_ERROR) { return (_g_err); } + +// ============================================================================= + inline void _parse_spi_header(uint8_t cmd, uint32_t address, uint8_t *out) { out[0] = cmd; @@ -51,85 +62,96 @@ inline void _parse_spi_header(uint8_t cmd, uint32_t address, uint8_t *out) out[3] = (address & 0xFF); } -int _transmit_spi_header(uint8_t cmd, uint32_t address) +inline int _transmit_spi_header(uint8_t cmd, uint32_t address) { - int err = E_NO_ERROR; // SPI reads and writes will always start with 4 bytes. // A command byte, then a 24-bit address (MSB first) uint8_t header[4]; _parse_spi_header(cmd, address, header); // Transmit header, but keep Chip Select asserted. - spi_transmit(header, 4, NULL, 0, false, true, true); - return err; + ERR_CHECK(spi_transmit(header, 4, NULL, 0, false)); + return E_NO_ERROR; } -int ram_init() -{ - int err = E_NO_ERROR; - err = spi_init(); - if (err) - return err; - - err = ram_exit_quadmode(); // Protect against quad-mode lock-up - if (err) - return err; +int N01S830HA_init() +{ + ERR_CHECK(spi_init()); + ERR_CHECK(N01S830HA_exit_quadmode()); // Protect against quad-mode lock-up + // The first thing we need to do is disable the HOLD function, which + // is enabled by default. There is a hardware (hold pin) and software + // (hold bit) component to this. + // Set the hold pin to the HIGH state. - // This is required for normal SPI operations to work reliably - MXC_GPIO_Config(&hold_pin); - MXC_GPIO_OutSet(hold_pin.port, hold_pin.mask); + ERR_CHECK(MXC_GPIO_Config(&N01S830HA_hold_pin)); + MXC_GPIO_OutSet(N01S830HA_hold_pin.port, N01S830HA_hold_pin.mask); - err = ram_write_mode_reg(0x01); // Disable hold function - if (err) - return err; + ERR_CHECK(N01S830HA_write_mode_reg(0b1)); // Disable hold function - // Validate that we were able to write to the mode register + // Now, validate that we were able to write to the mode register // This is the closest thing we have to a "read id" or // communication verification for this SRAM chip. uint8_t mode_reg; - err = ram_read_mode_reg(&mode_reg); - if (err) - return err; - + ERR_CHECK(N01S830HA_read_mode_reg(&mode_reg)); if (mode_reg != 0x01) { return E_NO_DEVICE; } + // Set burst mode (mode reg bits [7:6]) + // [7:6] = 0b00 -> word mode + // [7:6] = 0b10 -> page mode + // [7:6] = 0b01 -> burst mode (*) + // [7:6] = 0b11 - > reserved + + // Burst mode allows writing across the 8-bit word and + // 32-word page boundaries by automatically incrementing and + // wrapping the address pointer. + mode_reg &= ~(0b11 << 6); + mode_reg |= (0b01 << 6); + ERR_CHECK(N01S830HA_write_mode_reg(mode_reg)); + + // Validate the mode reg is updated successfully. + uint8_t validate = 0; + ERR_CHECK(N01S830HA_read_mode_reg(&validate)); + if (validate != mode_reg) { + printf("Expected %i, received %i\n", mode_reg, validate); + return E_COMM_ERR; + } + // Re-configure SPI pins now that the hold function has been disabled. - err = MXC_GPIO_Config(&spi_pins); - return err; + // This allows us to use QSPI. + ERR_CHECK(MXC_GPIO_Config(&spi_pins)); + + return E_NO_ERROR; } -int ram_enter_quadmode() +int N01S830HA_enter_quadmode() { - int err = E_NO_ERROR; uint8_t tx_data = CMD_ENABLE_QUAD_IO; - MXC_SPI_SetWidth(SPI, SPI_WIDTH_STANDARD); - spi_transmit(&tx_data, 1, NULL, 0, true, true, true); - MXC_SPI_SetWidth(SPI, SPI_WIDTH_QUAD); + ERR_CHECK(spi_exit_quadmode()); + ERR_CHECK(spi_transmit(&tx_data, 1, NULL, 0, true)); + ERR_CHECK(spi_enter_quadmode()); g_current_mode = QUAD_MODE; - return err; + return E_NO_ERROR; } -int ram_exit_quadmode() -{ - int err = E_NO_ERROR; +int N01S830HA_exit_quadmode() { uint8_t tx_data = CMD_RESET_IO; - MXC_SPI_SetWidth(SPI, SPI_WIDTH_QUAD); - spi_transmit(&tx_data, 1, NULL, 0, true, true, true); - MXC_SPI_SetWidth(SPI, SPI_WIDTH_STANDARD); + ERR_CHECK(spi_enter_quadmode()); + ERR_CHECK(spi_transmit(&tx_data, 1, NULL, 0, true)); + ERR_CHECK(spi_exit_quadmode()); g_current_mode = STANDARD_MODE; - return err; + return E_NO_ERROR; } -int ram_read(uint32_t address, uint8_t *out, unsigned int len) +int N01S830HA_read(uint32_t address, uint8_t *out, unsigned int len) { if (g_current_mode == STANDARD_MODE) { _transmit_spi_header(CMD_READ, address); @@ -138,30 +160,29 @@ int ram_read(uint32_t address, uint8_t *out, unsigned int len) uint8_t header[5]; // (1 byte cmd + 3 byte address + 1 dummy) memset(header, 0xFF, 5); _parse_spi_header(CMD_READ, address, header); - spi_transmit(header, 5, NULL, 0, false, true, true); + ERR_CHECK(spi_transmit(header, 5, NULL, 0, false)); } - return spi_transmit(NULL, 0, out, len, true, true, true); + return spi_transmit(NULL, 0, out, len, true); } -int ram_write(uint32_t address, uint8_t *data, unsigned int len) +int N01S830HA_write(uint32_t address, uint8_t *data, unsigned int len) { _transmit_spi_header(CMD_WRITE, address); - return spi_transmit(data, len, NULL, 0, true, true, true); + return spi_transmit(data, len, NULL, 0, true); } -int ram_write_mode_reg(uint8_t val) +int N01S830HA_write_mode_reg(uint8_t val) { uint8_t data[2] = { CMD_WRITE_MODE_REG, val }; - return spi_transmit(data, 2, NULL, 0, true, true, true); + ERR_CHECK(spi_transmit(data, 2, NULL, 0, true)); + MXC_Delay(MXC_DELAY_USEC(100)); // Some small delay after updating the mode reg appears to be necessary. + return E_NO_ERROR; } -int ram_read_mode_reg(uint8_t* out) +int N01S830HA_read_mode_reg(uint8_t* out) { - int err = E_NO_ERROR; uint8_t cmd = CMD_READ_MODE_REG; - err = spi_transmit(&cmd, 1, NULL, 0, false, true, true); - if (err) - return err; - return spi_transmit(NULL, 0, out, 1, true, true, true); + ERR_CHECK(spi_transmit(&cmd, 1, NULL, 0, false)); + return spi_transmit(NULL, 0, out, 1, true); } diff --git a/Examples/MAX78000/QSPI/N01S830HA.h b/Examples/MAX78000/QSPI/N01S830HA.h index 4cd0e6a1550..152c17b1cc9 100644 --- a/Examples/MAX78000/QSPI/N01S830HA.h +++ b/Examples/MAX78000/QSPI/N01S830HA.h @@ -34,8 +34,8 @@ #define EXAMPLES_MAX78000_QSPI_N01S830HA_H_ #include -#include "gpio.h" -#include "max78000.h" +#include +#include "N01S830HA_config.h" #define CMD_READ 0x03 #define CMD_WRITE 0x02 @@ -45,28 +45,147 @@ #define CMD_READ_MODE_REG 0x05 #define CMD_WRITE_MODE_REG 0x01 -// P0.9 on MAX78000FTHR is routed to HOLD pin -#define HOLD_PIN_PORT MXC_GPIO0 -#define HOLD_PIN_MASK MXC_GPIO_PIN_9 +// ======================================================================================= -static const mxc_gpio_cfg_t hold_pin = { .port = HOLD_PIN_PORT, - .mask = HOLD_PIN_MASK, - .func = MXC_GPIO_FUNC_OUT, - .pad = MXC_GPIO_PAD_WEAK_PULL_UP, - .vssel = MXC_GPIO_VSSEL_VDDIOH }; +// EXTERNAL PIN DEFINITIONS +// - Must be supplied externally (!) +// - Default can be found in N01S830HA_config.h -int ram_init(); +extern const mxc_gpio_cfg_t N01S830HA_hold_pin; -int ram_enter_quadmode(); +// ======================================================================================= -int ram_exit_quadmode(); +// SPI TRANSPORT LAYER +// - Must be implemented externally (!) -int ram_read(uint32_t address, uint8_t *out, unsigned int len); +/** + * @brief Initializes the SPI (Serial Peripheral Interface) module. + * + * This function initializes the SPI module with default settings. It must be + * called before any SPI transactions are performed. + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during initialization. + */ +extern int spi_init(); -int ram_write(uint32_t address, uint8_t *data, unsigned int len); +/** + * @brief Transmits and receives data using the SPI module. + * + * This function performs a full-duplex SPI transaction. It transmits data from + * the source buffer and receives data into the destination buffer. The lengths + * of the transmit and receive buffers are specified by txlen and rxlen + * parameters, respectively. + * + * @param[in] src Pointer to the source buffer containing data to be transmitted. + * @param[in] txlen Length of the data to be transmitted, in bytes. + * @param[out] dest Pointer to the destination buffer to store received data. + * @param[in] rxlen Length of the data to be received, in bytes. + * @param[in] deassert Boolean indicating whether to deassert the CS (Chip Select) line + * after the transaction (true) or keep it asserted (false). + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during the SPI transaction. + */ +extern int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert); -int ram_write_mode_reg(uint8_t val); +/** + * @brief Exits the quad mode for SPI (Serial Peripheral Interface) communication. + * + * This function is used to exit the quad mode in SPI, if previously enabled. + * Quad mode typically allows for faster data transfer rates by utilizing + * multiple data lines for both input and output. + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during the quad mode exit process. + */ +extern int spi_exit_quadmode(); -int ram_read_mode_reg(uint8_t* out); +/** + * @brief Enters the quad mode for SPI (Serial Peripheral Interface) communication. + * + * This function is used to enter the quad mode in SPI, enabling the use of + * multiple data lines for both input and output, which can result in faster + * data transfer rates. + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during the quad mode entry process. + */ +extern int spi_enter_quadmode(); + +// ======================================================================================= + +// DRIVER FUNCTIONS + +/** + * @brief Initialize the N01S830HA SRAM. + * + * This function initializes the N01S830HA SRAM, setting up necessary configurations + * for proper operation. It should be called before any other driver functions. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_init(); + +/** + * @brief Enter Quad Mode for the N01S830HA SRAM. + * + * This function puts the N01S830HA SRAM into Quad Mode for enhanced data transfer + * capabilities. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_enter_quadmode(); + +/** + * @brief Exit Quad Mode for the N01S830HA SRAM. + * + * This function exits Quad Mode for the N01S830HA SRAM, returning to normal operation. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_exit_quadmode(); + +/** + * @brief Read data from the N01S830HA SRAM. + * + * @param address The 24-bit memory address to read from. + * @param out Pointer to the buffer where the read data will be stored. + * @param len Number of bytes to read. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_read(uint32_t address, uint8_t *out, unsigned int len); + +/** + * @brief Write data to the N01S830HA SRAM. + * + * This function writes data to the specified address in the N01S830HA SRAM. + * + * @param address The 24-bit memory address to write to. + * @param data Pointer to the buffer containing the data to be written. + * @param len Number of bytes to write. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_write(uint32_t address, uint8_t *data, unsigned int len); + +/** + * @brief Write to the Mode Register of the N01S830HA SRAM. + * + * @param val The value to be written to the Mode Register. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_write_mode_reg(uint8_t val); + +/** + * @brief Read the Mode Register of the N01S830HA SRAM. + * + * @param[out] out Pointer to the variable where the read value will be stored. + * + * @return 0 on success, or an error code on failure. + */ +int N01S830HA_read_mode_reg(uint8_t* out); #endif // EXAMPLES_MAX78000_QSPI_N01S830HA_H_ diff --git a/Examples/MAX78000/QSPI/N01S830HA_config.h b/Examples/MAX78000/QSPI/N01S830HA_config.h new file mode 100644 index 00000000000..d9538a2832d --- /dev/null +++ b/Examples/MAX78000/QSPI/N01S830HA_config.h @@ -0,0 +1,33 @@ +#ifndef N01S830HA_CONFIG_H +#define N01S830HA_CONFIG_H + +#include "N01S830HA.h" +#include "gpio.h" +#include "mxc_device.h" + +#ifndef N01S830HA_HOLD_PIN_PORT +#define N01S830HA_HOLD_PIN_PORT MXC_GPIO0 +#endif + +#ifndef N01S830HA_HOLD_PIN_MASK +#define N01S830HA_HOLD_PIN_MASK MXC_GPIO_PIN_9 +#endif + +#ifndef N01S830HA_VSSEL +#define N01S830HA_VSSEL MXC_GPIO_VSSEL_VDDIOH +#endif + +#ifndef N01S830HA_HOLD_PIN +#define N01S830HA_HOLD_PIN +// N01S830HA_HOLD_PIN can be defined by other files to completely re-define the +// hold pin struct if necessary. Otherwise, the hold pin will be defined here using +// the port, pin, and vssel definitions above. + +static const mxc_gpio_cfg_t N01S830HA_hold_pin = { .port = N01S830HA_HOLD_PIN_PORT, + .mask = N01S830HA_HOLD_PIN_MASK, + .func = MXC_GPIO_FUNC_OUT, + .pad = MXC_GPIO_PAD_WEAK_PULL_UP, + .vssel = N01S830HA_VSSEL }; +#endif + +#endif // N01S830HA_CONFIG_H \ No newline at end of file diff --git a/Examples/MAX78000/QSPI/fastspi.c b/Examples/MAX78000/QSPI/fastspi.c index 98022a65aa7..3bf215d2a93 100644 --- a/Examples/MAX78000/QSPI/fastspi.c +++ b/Examples/MAX78000/QSPI/fastspi.c @@ -47,7 +47,6 @@ int g_rx_channel; int g_fill_dummy_bytes = 0; int g_dummy_len = 0; uint8_t g_dummy_byte = 0xFF; -bool g_use_dma = false; bool g_dma_initialized = false; @@ -131,18 +130,10 @@ void SPI_IRQHandler() if (status & MXC_F_SPI_INTFL_RX_THD) { SPI->intfl |= MXC_F_SPI_INTFL_RX_THD; - if (!g_use_dma) { - // RX threshold has been crossed, there's data to unload from the FIFO - processSPI(); - } } if (status & MXC_F_SPI_INTFL_TX_THD) { SPI->intfl |= MXC_F_SPI_INTFL_TX_THD; - if (!g_use_dma) { - // TX threshold has been crossed, we need to refill the FIFO - processSPI(); - } } } @@ -249,8 +240,7 @@ int spi_init() return err; } -int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert, - bool use_dma, bool block) +int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert) { g_tx_done = 0; g_rx_done = 0; @@ -280,69 +270,38 @@ int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bo MXC_F_SPI_DMA_DMA_RX_EN); // Disable FIFOs before clearing as recommended by UG SPI->dma |= (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH); // Clear the FIFOs - if (use_dma) { - g_use_dma = true; - // TX - if (txlen > 1) { - // Configure TX DMA channel to fill the SPI TX FIFO - SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN | - (31 << MXC_F_SPI_DMA_TX_THD_VAL_POS)); - SPI->fifo8[0] = src[0]; - // ^ Hardware requires writing the first byte into the FIFO manually. - MXC_DMA->ch[g_tx_channel].src = (uint32_t)(src + 1); - MXC_DMA->ch[g_tx_channel].cnt = txlen - 1; - MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_SRCINC; - MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA - } else if (txlen == 1) { - // Workaround for single-length transactions not triggering CTZ - SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); - SPI->fifo8[0] = src[0]; // Write first byte into FIFO - g_tx_done = 1; - } else if (txlen == 0 && width == SPI_WIDTH_STANDARD) { - // Configure TX DMA channel to retransmit a dummy byte - SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); - MXC_DMA->ch[g_tx_channel].src = (uint32_t)&g_dummy_byte; - MXC_DMA->ch[g_tx_channel].cnt = rxlen; - MXC_DMA->ch[g_tx_channel].ctrl &= ~MXC_F_DMA_CTRL_SRCINC; - MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA - } - - // RX - if (rxlen > 0) { - // Configure RX DMA channel to unload the SPI RX FIFO - SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN | MXC_F_SPI_DMA_DMA_RX_EN); - MXC_DMA->ch[g_rx_channel].dst = (uint32_t)dest; - MXC_DMA->ch[g_rx_channel].cnt = rxlen; - MXC_DMA->ch[g_rx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA - } - - } else { // !use_dma - g_use_dma = false; - g_rx_buffer = dest; - g_tx_buffer = src; - g_rx_len = rxlen; - g_tx_len = txlen; - - SPI->inten |= MXC_F_SPI_INTEN_MST_DONE; - - if (txlen > 0) { - // Enable TX FIFO & TX Threshold crossed interrupt - SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN); - SPI->inten |= MXC_F_SPI_INTEN_TX_THD; - } - - if (rxlen > 0) { - // Enable RX FIFO & RX Threshold crossed interrupt - SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN); - SPI->inten |= MXC_F_SPI_INTEN_RX_THD; - } + // TX + if (txlen > 1) { + // Configure TX DMA channel to fill the SPI TX FIFO + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN | + (31 << MXC_F_SPI_DMA_TX_THD_VAL_POS)); + SPI->fifo8[0] = src[0]; + // ^ Hardware requires writing the first byte into the FIFO manually. + MXC_DMA->ch[g_tx_channel].src = (uint32_t)(src + 1); + MXC_DMA->ch[g_tx_channel].cnt = txlen - 1; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_SRCINC; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } else if (txlen == 1) { + // Workaround for single-length transactions not triggering CTZ + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); + SPI->fifo8[0] = src[0]; // Write first byte into FIFO + g_tx_done = 1; + } else if (txlen == 0 && width == SPI_WIDTH_STANDARD) { + // Configure TX DMA channel to retransmit a dummy byte + SPI->dma |= (MXC_F_SPI_DMA_TX_FIFO_EN | MXC_F_SPI_DMA_DMA_TX_EN); + MXC_DMA->ch[g_tx_channel].src = (uint32_t)&g_dummy_byte; + MXC_DMA->ch[g_tx_channel].cnt = rxlen; + MXC_DMA->ch[g_tx_channel].ctrl &= ~MXC_F_DMA_CTRL_SRCINC; + MXC_DMA->ch[g_tx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA + } - /* - This processSPI call fills the TX FIFO as much as possible - before launching the transaction. Subsequent FIFO management will - be handled from the SPI_IRQHandler. - */ - processSPI(); + // RX + if (rxlen > 0) { + // Configure RX DMA channel to unload the SPI RX FIFO + SPI->dma |= (MXC_F_SPI_DMA_RX_FIFO_EN | MXC_F_SPI_DMA_DMA_RX_EN); + MXC_DMA->ch[g_rx_channel].dst = (uint32_t)dest; + MXC_DMA->ch[g_rx_channel].cnt = rxlen; + MXC_DMA->ch[g_rx_channel].ctrl |= MXC_F_DMA_CTRL_EN; // Start the DMA } // Start the SPI transaction @@ -362,24 +321,33 @@ int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bo else SPI->ctrl0 |= MXC_F_SPI_CTRL0_SS_CTRL; - if (block) { - while (!((g_tx_done && g_master_done) && (src != NULL && txlen > 0)) && - !(g_rx_done && (dest != NULL && rxlen > 0))) { - /* - The following polling is a safety fallback to catch any missed interrupts. - This is especially common with extremely short transactions, where all 3 - interrupts may fire almost simultaneously. - */ - if ((src != NULL && txlen > 0) && SPI->intfl & MXC_F_SPI_INTFL_MST_DONE) - g_master_done = 1; - if ((src != NULL && txlen > 0) && - MXC_DMA->ch[g_tx_channel].status & MXC_F_DMA_STATUS_CTZ_IF) - g_tx_done = 1; - if ((dest != NULL && rxlen > 0) && - MXC_DMA->ch[g_rx_channel].status & MXC_F_DMA_STATUS_CTZ_IF) - g_rx_done = 1; - } + // Wait for the transaction to complete. + while (!((g_tx_done && g_master_done) && (src != NULL && txlen > 0)) && + !(g_rx_done && (dest != NULL && rxlen > 0))) { + /* + The following polling is a safety fallback to catch any missed interrupts. + This is especially common with extremely short transactions, where all 3 + interrupts may fire almost simultaneously. + */ + if ((src != NULL && txlen > 0) && SPI->intfl & MXC_F_SPI_INTFL_MST_DONE) + g_master_done = 1; + if ((src != NULL && txlen > 0) && + MXC_DMA->ch[g_tx_channel].status & MXC_F_DMA_STATUS_CTZ_IF) + g_tx_done = 1; + if ((dest != NULL && rxlen > 0) && + MXC_DMA->ch[g_rx_channel].status & MXC_F_DMA_STATUS_CTZ_IF) + g_rx_done = 1; } return E_SUCCESS; } + +int spi_exit_quadmode() +{ + return MXC_SPI_SetWidth(SPI, SPI_WIDTH_STANDARD); +} + +int spi_enter_quadmode() +{ + return MXC_SPI_SetWidth(SPI, SPI_WIDTH_QUAD); +} diff --git a/Examples/MAX78000/QSPI/fastspi.h b/Examples/MAX78000/QSPI/fastspi.h index 80b4f5f6929..7e04568adbe 100644 --- a/Examples/MAX78000/QSPI/fastspi.h +++ b/Examples/MAX78000/QSPI/fastspi.h @@ -53,7 +53,8 @@ static const mxc_gpio_cfg_t spi_pins = { .port = SPI_PINS_PORT, // TODO(Jake): Generalize to multiple SPI instances int spi_init(); -int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert, - bool use_dma, bool block); +int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert); +int spi_exit_quadmode(); +int spi_enter_quadmode(); #endif // EXAMPLES_MAX78002_QSPI_FASTSPI_H_ diff --git a/Examples/MAX78000/QSPI/fastspi_config.h b/Examples/MAX78000/QSPI/fastspi_config.h index c5c63d1bf45..0e8e26bf948 100644 --- a/Examples/MAX78000/QSPI/fastspi_config.h +++ b/Examples/MAX78000/QSPI/fastspi_config.h @@ -38,8 +38,7 @@ // TODO(Jake): Config struct #define SPI MXC_SPI0 -#define SPI_SPEED 2000000 -// #define SPI_SPEED 1000000 +#define SPI_SPEED 25000000 #define SPI_PINS_PORT MXC_GPIO0 #define SPI_PINS_MASK \ (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8 | MXC_GPIO_PIN_9) diff --git a/Examples/MAX78000/QSPI/main.c b/Examples/MAX78000/QSPI/main.c index 972d0db19a8..f910726e5d6 100644 --- a/Examples/MAX78000/QSPI/main.c +++ b/Examples/MAX78000/QSPI/main.c @@ -54,21 +54,29 @@ #include "N01S830HA.h" /***** Definitions *****/ -#define TEST_SIZE 640 -#define TEST_COUNT 480 -#define TEST_VALUE 0x00 -#define TEST_ADDR 0x000 +#define TEST_SIZE 4096 +#define TEST_ADDR 0x00000 +// ^ Max address is 0x1FFFF /***** Globals *****/ +int g_sw_overhead = 0; +#define TIME(x, output) {MXC_TMR_SW_Start(MXC_TMR0);(x);(elapsed) = MXC_TMR_SW_Stop(MXC_TMR0) - g_sw_overhead;} /***** Functions *****/ +bool validate(uint8_t *expected, uint8_t *received, int len) +{ + return memcmp(expected, received, len) == 0; +} + // ***************************************************************************** int main(void) { int err = E_NO_ERROR; unsigned int elapsed = 0; - int fail_count = 0; + + uint8_t tx_buffer[TEST_SIZE]; + uint8_t rx_buffer[TEST_SIZE]; MXC_Delay(MXC_DELAY_SEC(2)); @@ -78,177 +86,87 @@ int main(void) printf("QSPI SRAM Test:\n"); printf("\tTest Address: 0x%x\n", TEST_ADDR); printf("\tTest size: %i bytes\n", TEST_SIZE); - printf("\tTest count: %i rows\n", TEST_COUNT); printf("\tTest speed: %i Hz\n", SPI_SPEED); - if (ram_init() != E_NO_ERROR) - printf("RAM init failed!\n"); - // Time the measurement overhead of our measurement functions MXC_TMR_SW_Start(MXC_TMR0); - int sw_overhead = MXC_TMR_SW_Stop(MXC_TMR0); + g_sw_overhead = MXC_TMR_SW_Stop(MXC_TMR0); - uint8_t tx_buffer[TEST_SIZE]; - uint8_t rx_buffer[TEST_SIZE]; + // Benchmark internal memory write + TIME( + memset(tx_buffer, 0, TEST_SIZE), + elapsed + ); + printf("(Benchmark) Wrote %i bytes to internal SRAM in %ius\n", TEST_SIZE, elapsed); + + // Initialize test pattern + for (int i = 0; i < TEST_SIZE; i++) { + tx_buffer[i] = i % 256; + } memset(rx_buffer, 0, TEST_SIZE); - // Time tx_buffer initialization as benchmark - MXC_TMR_SW_Start(MXC_TMR0); - memset(tx_buffer, TEST_VALUE, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; - printf("(Benchmark) Wrote %i bytes to internal SRAM in %ius\n", TEST_SIZE, elapsed); + // ===================================================== + // SRAM Init + if ((err = N01S830HA_init()) != E_NO_ERROR) { + printf("RAM init failed! Error %i\n", err); + return err; + } - // Benchmark standard-width SPI write to external SRAM + // ===================================================== + // Standard SPI printf("Test 1: Standard SPI write...\n"); - MXC_TMR_SW_Start(MXC_TMR0); - ram_write(TEST_ADDR, tx_buffer, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + TIME( + N01S830HA_write(TEST_ADDR, tx_buffer, TEST_SIZE), // SRAM Write + elapsed + ); printf("\tDone (%i bytes in %ius)\n", TEST_SIZE, elapsed); // Read and validate - printf("Test 2: Validate w/ standard SPI...\n"); - MXC_TMR_SW_Start(MXC_TMR0); - ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("Test 2: Standard SPI read...\n"); + TIME( + N01S830HA_read(TEST_ADDR, rx_buffer, TEST_SIZE), // SRAM Read + elapsed + ) printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); printf("\tChecking for mismatches...\n"); - for (int i = 0; i < TEST_SIZE; i++) { - if (rx_buffer[i] != tx_buffer[i]) { - fail_count++; - printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, - tx_buffer[i], rx_buffer[i]); - } + if (!validate(rx_buffer, tx_buffer, TEST_SIZE)) { + printf("\tValidation failed!\n"); + return E_FAIL; } - printf("\tDone\n"); + printf("\tSuccess.\n"); + // ===================================================== - printf("Test 3: Validate w/ QSPI...\n"); - ram_enter_quadmode(); - MXC_TMR_SW_Start(MXC_TMR0); - ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; - printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); - printf("\tChecking for mismatches...\n"); + // Invert test pattern - this ensures every bit has to be updated in the next write for (int i = 0; i < TEST_SIZE; i++) { - if (rx_buffer[i] != tx_buffer[i]) { - fail_count++; - printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, - tx_buffer[i], rx_buffer[i]); - } + tx_buffer[i] = ~tx_buffer[i]; } - printf("\tDone\n"); - // Invert test pattern - this ensures every bit has to be updated in the next write - memset(tx_buffer, ~(TEST_VALUE), TEST_SIZE); - // memset(tx_buffer, 0x00, TEST_SIZE); - memset(rx_buffer, 0, TEST_SIZE); + // ===================================================== + // QSPI + printf("Test 3: QSPI write...\n"); - // Benchmark QSPI write to external SRAM - printf("Test 4: QSPI Write...\n"); - MXC_TMR_SW_Start(MXC_TMR0); - err = ram_write(TEST_ADDR, tx_buffer, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + N01S830HA_enter_quadmode(); // Enter quad mode + + TIME( + N01S830HA_write(TEST_ADDR, tx_buffer, TEST_SIZE), // SRAM Write + elapsed + ); printf("\tDone (%i bytes in %ius)\n", TEST_SIZE, elapsed); // Read and validate - printf("Test 5: Validate w/ standard SPI...\n"); - ram_exit_quadmode(); - MXC_TMR_SW_Start(MXC_TMR0); - ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; - printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); - printf("\tChecking for mismatches...\n"); - for (int i = 0; i < TEST_SIZE; i++) { - if (rx_buffer[i] != tx_buffer[i]) { - fail_count++; - printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, - tx_buffer[i], rx_buffer[i]); - } - } - printf("\tDone\n"); - - memset(rx_buffer, 0, TEST_SIZE); - - // Read and validate - printf("Test 6: Validate w/ QSPI...\n"); - ram_enter_quadmode(); - MXC_TMR_SW_Start(MXC_TMR0); - ram_read(TEST_ADDR, rx_buffer, TEST_SIZE); - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; + printf("Test 4: QSPI read...\n"); + TIME( + N01S830HA_read(TEST_ADDR, rx_buffer, TEST_SIZE), // SRAM Read + elapsed + ) printf("\tRead finished (%i bytes in %ius)\n", TEST_SIZE, elapsed); printf("\tChecking for mismatches...\n"); - for (int i = 0; i < TEST_SIZE; i++) { - if (rx_buffer[i] != tx_buffer[i]) { - fail_count++; - printf("Value mismatch at addr %i, expected 0x%x but got 0x%x\n", TEST_ADDR + i, - tx_buffer[i], rx_buffer[i]); - } - } - printf("\tDone\n"); - - // Generate a new more interesting test pattern - for (int i = 0; i < TEST_SIZE; i++) { - tx_buffer[i] = i % 256; - } - memset(rx_buffer, 0, TEST_SIZE); - - // Benchmark writing across multiple pages boundaries. - int address = TEST_ADDR; - printf("Test 7: QSPI Writing across page boundaries...\n", TEST_SIZE, TEST_COUNT); - MXC_TMR_SW_Start(MXC_TMR0); - for (int i = 0; i < TEST_COUNT; i++) { - ram_write(address, tx_buffer, TEST_SIZE); - address += TEST_SIZE; - } - elapsed = MXC_TMR_SW_Stop(MXC_TMR0) - sw_overhead; - printf("\tWrote %i bytes in %ius\n", TEST_SIZE * TEST_COUNT, elapsed); - - printf("Test 8: Validating with standard SPI...\n"); - ram_exit_quadmode(); - address = TEST_ADDR; - int temp = fail_count; - for (int i = 0; i < TEST_COUNT; i++) { - ram_read(address, rx_buffer, TEST_SIZE); - for (int j = 0; j < TEST_SIZE; j++) { - if (rx_buffer[j] != tx_buffer[j]) { - fail_count++; - } - } - address += TEST_SIZE; - memset(rx_buffer, 0, TEST_SIZE); - } - if (fail_count != temp) { - printf("\tFailed (%i) mismatches\n", fail_count - temp); - } else { - printf("\tSuccess\n"); - } - - // Validate - printf("Test 9: Validating with QSPI...\n"); - ram_enter_quadmode(); - address = TEST_ADDR; - temp = fail_count; - for (int i = 0; i < TEST_COUNT; i++) { - ram_read(address, rx_buffer, TEST_SIZE); - for (int j = 0; j < TEST_SIZE; j++) { - if (rx_buffer[j] != tx_buffer[j]) { - fail_count++; - } - } - address += TEST_SIZE; - memset(rx_buffer, 0, TEST_SIZE); - } - if (fail_count != temp) { - printf("\tFailed (%i) mismatches\n", fail_count - temp); - } else { - printf("\tSuccess\n"); - } - - if (fail_count > 0) { - printf("\nFailed with %i mismatches (%.2f%%)!\n", fail_count, - 100 * (((float)fail_count) / (TEST_SIZE * TEST_COUNT))); + if (!validate(rx_buffer, tx_buffer, TEST_SIZE)) { + printf("\tValidation failed!\n"); return E_FAIL; } + printf("\tSuccess.\n"); + // ===================================================== - printf("Success!\n"); - return err; + return E_NO_ERROR; } From cdf8943264ce1bc457f83993930b48e51b4c5162 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 18:59:02 -0600 Subject: [PATCH 04/26] Add vssel to fastspi --- Examples/MAX78000/QSPI/fastspi.c | 19 ++++++------------- Examples/MAX78000/QSPI/fastspi.h | 5 ++--- Examples/MAX78000/QSPI/fastspi_config.h | 2 +- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/Examples/MAX78000/QSPI/fastspi.c b/Examples/MAX78000/QSPI/fastspi.c index 3bf215d2a93..c634da53801 100644 --- a/Examples/MAX78000/QSPI/fastspi.c +++ b/Examples/MAX78000/QSPI/fastspi.c @@ -55,13 +55,6 @@ uint8_t *g_tx_buffer; uint32_t g_rx_len; uint32_t g_tx_len; -// A macro to convert a DMA channel number to an IRQn number -#define GetIRQnForDMAChannel(x) \ - ((IRQn_Type)(((x) == 0) ? DMA0_IRQn : \ - ((x) == 1) ? DMA1_IRQn : \ - ((x) == 2) ? DMA2_IRQn : \ - DMA3_IRQn)) - void DMA_TX_IRQHandler() { volatile mxc_dma_ch_regs_t *ch = @@ -175,13 +168,13 @@ int dma_init() (MXC_F_DMA_CTRL_CTZ_IE | MXC_F_DMA_CTRL_DIS_IE); // Enable CTZ and DIS interrupts MXC_DMA->inten |= (1 << g_rx_channel); // Enable DMA interrupts - MXC_NVIC_SetVector(GetIRQnForDMAChannel(g_tx_channel), DMA_TX_IRQHandler); - NVIC_EnableIRQ(GetIRQnForDMAChannel(g_tx_channel)); - NVIC_SetPriority(GetIRQnForDMAChannel(g_tx_channel), 0); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(g_tx_channel), DMA_TX_IRQHandler); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(g_tx_channel)); + NVIC_SetPriority(MXC_DMA_CH_GET_IRQ(g_tx_channel), 0); - MXC_NVIC_SetVector(GetIRQnForDMAChannel(g_rx_channel), DMA_RX_IRQHandler); - NVIC_EnableIRQ(GetIRQnForDMAChannel(g_rx_channel)); - NVIC_SetPriority(GetIRQnForDMAChannel(g_tx_channel), 0); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(g_rx_channel), DMA_RX_IRQHandler); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(g_rx_channel)); + NVIC_SetPriority(MXC_DMA_CH_GET_IRQ(g_tx_channel), 0); g_dma_initialized = true; diff --git a/Examples/MAX78000/QSPI/fastspi.h b/Examples/MAX78000/QSPI/fastspi.h index 7e04568adbe..d473c110b23 100644 --- a/Examples/MAX78000/QSPI/fastspi.h +++ b/Examples/MAX78000/QSPI/fastspi.h @@ -43,15 +43,14 @@ static const mxc_gpio_cfg_t spi_ss_pin = { .port = SPI_SS_PORT, .mask = SPI_SS_PIN, .func = MXC_GPIO_FUNC_ALT2, // ALT2 for SS2 .pad = MXC_GPIO_PAD_WEAK_PULL_UP, - .vssel = MXC_GPIO_VSSEL_VDDIOH }; + .vssel = SPI_VSSEL }; static const mxc_gpio_cfg_t spi_pins = { .port = SPI_PINS_PORT, .mask = SPI_PINS_MASK, .func = MXC_GPIO_FUNC_ALT1, .pad = MXC_GPIO_PAD_NONE, - .vssel = MXC_GPIO_VSSEL_VDDIOH }; + .vssel = SPI_VSSEL }; -// TODO(Jake): Generalize to multiple SPI instances int spi_init(); int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert); int spi_exit_quadmode(); diff --git a/Examples/MAX78000/QSPI/fastspi_config.h b/Examples/MAX78000/QSPI/fastspi_config.h index 0e8e26bf948..63936f963e6 100644 --- a/Examples/MAX78000/QSPI/fastspi_config.h +++ b/Examples/MAX78000/QSPI/fastspi_config.h @@ -36,10 +36,10 @@ #include "spi.h" #include "gpio.h" -// TODO(Jake): Config struct #define SPI MXC_SPI0 #define SPI_SPEED 25000000 #define SPI_PINS_PORT MXC_GPIO0 +#define SPI_VSSEL MXC_GPIO_VSSEL_VDDIOH #define SPI_PINS_MASK \ (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8 | MXC_GPIO_PIN_9) #define SPI_SS_PORT MXC_GPIO0 From b2c1bd219e48b81e5067c0ed31b3cce98b661728 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 19:02:28 -0600 Subject: [PATCH 05/26] Reinitialize spi instead of calling GPIO config --- Examples/MAX78000/QSPI/N01S830HA.c | 2 +- Examples/MAX78000/QSPI/fastspi.c | 8 ++++---- Examples/MAX78000/QSPI/fastspi.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Examples/MAX78000/QSPI/N01S830HA.c b/Examples/MAX78000/QSPI/N01S830HA.c index 73763730faa..c255584cfc9 100644 --- a/Examples/MAX78000/QSPI/N01S830HA.c +++ b/Examples/MAX78000/QSPI/N01S830HA.c @@ -121,7 +121,7 @@ int N01S830HA_init() // Re-configure SPI pins now that the hold function has been disabled. // This allows us to use QSPI. - ERR_CHECK(MXC_GPIO_Config(&spi_pins)); + ERR_CHECK(spi_init()); return E_NO_ERROR; } diff --git a/Examples/MAX78000/QSPI/fastspi.c b/Examples/MAX78000/QSPI/fastspi.c index c634da53801..093217114bf 100644 --- a/Examples/MAX78000/QSPI/fastspi.c +++ b/Examples/MAX78000/QSPI/fastspi.c @@ -187,17 +187,17 @@ int spi_init() MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0); MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI0); - int err = MXC_GPIO_Config(&spi_pins); + int err = MXC_GPIO_Config(&fastspi_spi_pins); if (err) return err; - err = MXC_GPIO_Config(&spi_ss_pin); + err = MXC_GPIO_Config(&fastspi_ss_pin); if (err) return err; // Set strongest possible drive strength for SPI pins - spi_pins.port->ds0 |= spi_pins.mask; - spi_pins.port->ds1 |= spi_pins.mask; + fastspi_spi_pins.port->ds0 |= fastspi_spi_pins.mask; + fastspi_spi_pins.port->ds1 |= fastspi_spi_pins.mask; // TODO(Jake): Expose some of the config options below // TODO(Jake): Move QSPI-SRAM specific options into aps6404.c diff --git a/Examples/MAX78000/QSPI/fastspi.h b/Examples/MAX78000/QSPI/fastspi.h index d473c110b23..623c23f4182 100644 --- a/Examples/MAX78000/QSPI/fastspi.h +++ b/Examples/MAX78000/QSPI/fastspi.h @@ -39,13 +39,13 @@ static volatile bool g_tx_done = 0; static volatile bool g_rx_done = 0; static volatile bool g_master_done = 0; -static const mxc_gpio_cfg_t spi_ss_pin = { .port = SPI_SS_PORT, +static const mxc_gpio_cfg_t fastspi_ss_pin = { .port = SPI_SS_PORT, .mask = SPI_SS_PIN, .func = MXC_GPIO_FUNC_ALT2, // ALT2 for SS2 .pad = MXC_GPIO_PAD_WEAK_PULL_UP, .vssel = SPI_VSSEL }; -static const mxc_gpio_cfg_t spi_pins = { .port = SPI_PINS_PORT, +static const mxc_gpio_cfg_t fastspi_spi_pins = { .port = SPI_PINS_PORT, .mask = SPI_PINS_MASK, .func = MXC_GPIO_FUNC_ALT1, .pad = MXC_GPIO_PAD_NONE, From 751db2c43f124972f3f067f6bcc7842ff95b8c01 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 19:13:21 -0600 Subject: [PATCH 06/26] Improve fastspi abstraction --- Examples/MAX78000/QSPI/N01S830HA.c | 3 +- Examples/MAX78000/QSPI/N01S830HA_config.h | 1 + Examples/MAX78000/QSPI/fastspi.c | 6 ++ Examples/MAX78000/QSPI/fastspi.h | 95 +++++++++++++++++------ Examples/MAX78000/QSPI/fastspi_config.h | 21 +++++ 5 files changed, 102 insertions(+), 24 deletions(-) diff --git a/Examples/MAX78000/QSPI/N01S830HA.c b/Examples/MAX78000/QSPI/N01S830HA.c index c255584cfc9..ff78a28541b 100644 --- a/Examples/MAX78000/QSPI/N01S830HA.c +++ b/Examples/MAX78000/QSPI/N01S830HA.c @@ -31,13 +31,12 @@ * ******************************************************************************/ #include +#include #include // For memset #include "N01S830HA.h" #include "mxc_errors.h" #include "mxc_delay.h" -#include "fastspi.h" #include "tmr.h" -#include enum MODE { STANDARD_MODE, QUAD_MODE }; typedef enum MODE MODE_t; diff --git a/Examples/MAX78000/QSPI/N01S830HA_config.h b/Examples/MAX78000/QSPI/N01S830HA_config.h index d9538a2832d..fea24d8ed2a 100644 --- a/Examples/MAX78000/QSPI/N01S830HA_config.h +++ b/Examples/MAX78000/QSPI/N01S830HA_config.h @@ -4,6 +4,7 @@ #include "N01S830HA.h" #include "gpio.h" #include "mxc_device.h" +#include "fastspi.h" #ifndef N01S830HA_HOLD_PIN_PORT #define N01S830HA_HOLD_PIN_PORT MXC_GPIO0 diff --git a/Examples/MAX78000/QSPI/fastspi.c b/Examples/MAX78000/QSPI/fastspi.c index 093217114bf..46adcec2347 100644 --- a/Examples/MAX78000/QSPI/fastspi.c +++ b/Examples/MAX78000/QSPI/fastspi.c @@ -55,6 +55,12 @@ uint8_t *g_tx_buffer; uint32_t g_rx_len; uint32_t g_tx_len; +// Polling flags the application code can optionally +static volatile bool g_tx_done = 0; +static volatile bool g_rx_done = 0; +static volatile bool g_master_done = 0; + + void DMA_TX_IRQHandler() { volatile mxc_dma_ch_regs_t *ch = diff --git a/Examples/MAX78000/QSPI/fastspi.h b/Examples/MAX78000/QSPI/fastspi.h index 623c23f4182..179e57ad74c 100644 --- a/Examples/MAX78000/QSPI/fastspi.h +++ b/Examples/MAX78000/QSPI/fastspi.h @@ -33,27 +33,78 @@ #ifndef EXAMPLES_MAX78002_QSPI_FASTSPI_H_ #define EXAMPLES_MAX78002_QSPI_FASTSPI_H_ -#include "fastspi_config.h" - -static volatile bool g_tx_done = 0; -static volatile bool g_rx_done = 0; -static volatile bool g_master_done = 0; - -static const mxc_gpio_cfg_t fastspi_ss_pin = { .port = SPI_SS_PORT, - .mask = SPI_SS_PIN, - .func = MXC_GPIO_FUNC_ALT2, // ALT2 for SS2 - .pad = MXC_GPIO_PAD_WEAK_PULL_UP, - .vssel = SPI_VSSEL }; - -static const mxc_gpio_cfg_t fastspi_spi_pins = { .port = SPI_PINS_PORT, - .mask = SPI_PINS_MASK, - .func = MXC_GPIO_FUNC_ALT1, - .pad = MXC_GPIO_PAD_NONE, - .vssel = SPI_VSSEL }; - -int spi_init(); -int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert); -int spi_exit_quadmode(); -int spi_enter_quadmode(); +/** + * @file fastspi.h + * @brief "fast" and optimized DMA SPI drivers for use alongside external SRAM drivers + */ + +#include "fastspi_config.h" // <-- must be implemented for each Board Support Package + +#ifndef SPI +#error Missing fastspi_config.h definition 'SPI' to select SPI instance +#endif + +#ifndef SPI_SPEED +#error Missing fastspi_config.h definition 'SPI_SPEED' to set SPI clock frequency +#endif + +// These pin definitions should also be provided in the "fastspi_config.h" file +extern const mxc_gpio_cfg_t fastspi_ss_pin; +extern const mxc_gpio_cfg_t fastspi_spi_pins; + +/** + * @brief Initializes the SPI (Serial Peripheral Interface) module. + * + * This function initializes the SPI module with default settings. It must be + * called before any SPI transactions are performed. + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during initialization. + */ +extern int spi_init(); + +/** + * @brief Transmits and receives data using the SPI module. + * + * This function performs a full-duplex SPI transaction. It transmits data from + * the source buffer and receives data into the destination buffer. The lengths + * of the transmit and receive buffers are specified by txlen and rxlen + * parameters, respectively. + * + * @param[in] src Pointer to the source buffer containing data to be transmitted. + * @param[in] txlen Length of the data to be transmitted, in bytes. + * @param[out] dest Pointer to the destination buffer to store received data. + * @param[in] rxlen Length of the data to be received, in bytes. + * @param[in] deassert Boolean indicating whether to deassert the CS (Chip Select) line + * after the transaction (true) or keep it asserted (false). + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during the SPI transaction. + */ +extern int spi_transmit(uint8_t *src, uint32_t txlen, uint8_t *dest, uint32_t rxlen, bool deassert); + +/** + * @brief Exits the quad mode for SPI (Serial Peripheral Interface) communication. + * + * This function is used to exit the quad mode in SPI, if previously enabled. + * Quad mode typically allows for faster data transfer rates by utilizing + * multiple data lines for both input and output. + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during the quad mode exit process. + */ +extern int spi_exit_quadmode(); + +/** + * @brief Enters the quad mode for SPI (Serial Peripheral Interface) communication. + * + * This function is used to enter the quad mode in SPI, enabling the use of + * multiple data lines for both input and output, which can result in faster + * data transfer rates. + * + * @return An integer status code. 0 indicates success, while a non-zero value + * indicates an error during the quad mode entry process. + */ +extern int spi_enter_quadmode(); #endif // EXAMPLES_MAX78002_QSPI_FASTSPI_H_ diff --git a/Examples/MAX78000/QSPI/fastspi_config.h b/Examples/MAX78000/QSPI/fastspi_config.h index 63936f963e6..40ecef2ca61 100644 --- a/Examples/MAX78000/QSPI/fastspi_config.h +++ b/Examples/MAX78000/QSPI/fastspi_config.h @@ -33,11 +33,19 @@ #ifndef EXAMPLES_MAX78002_QSPI_FASTSPI_CONFIG_H_ #define EXAMPLES_MAX78002_QSPI_FASTSPI_CONFIG_H_ +/** + * @file fastspi_config.c + * @brief "fastspi" configuration file for MAX78000FTHR board + */ + #include "spi.h" #include "gpio.h" +// (*) Required definitions: #define SPI MXC_SPI0 #define SPI_SPEED 25000000 + +// Optional definitions to make GPIO creation easier: #define SPI_PINS_PORT MXC_GPIO0 #define SPI_VSSEL MXC_GPIO_VSSEL_VDDIOH #define SPI_PINS_MASK \ @@ -45,4 +53,17 @@ #define SPI_SS_PORT MXC_GPIO0 #define SPI_SS_PIN MXC_GPIO_PIN_10 // (SS2) +// (*) Required GPIO definitions: +static const mxc_gpio_cfg_t fastspi_ss_pin = { .port = SPI_SS_PORT, + .mask = SPI_SS_PIN, + .func = MXC_GPIO_FUNC_ALT2, // ALT2 for SS2 + .pad = MXC_GPIO_PAD_WEAK_PULL_UP, + .vssel = SPI_VSSEL }; + +static const mxc_gpio_cfg_t fastspi_spi_pins = { .port = SPI_PINS_PORT, + .mask = SPI_PINS_MASK, + .func = MXC_GPIO_FUNC_ALT1, + .pad = MXC_GPIO_PAD_NONE, + .vssel = SPI_VSSEL }; + #endif // EXAMPLES_MAX78002_QSPI_FASTSPI_CONFIG_H_ From f056907487f14580bdf05c30f0aa54ba2d5ee43f Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 19:20:46 -0600 Subject: [PATCH 07/26] Move SRAM drivers to MiscDrivers, move fastspi_config.h to BSP --- .../Boards/MAX78000/FTHR_RevA/Include}/fastspi_config.h | 0 Libraries/Boards/MAX78000/FTHR_RevA/board.mk | 4 ++++ .../MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/N01S830HA.c | 0 .../MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/N01S830HA.h | 0 .../QSPI => Libraries/MiscDrivers/SRAM}/N01S830HA_config.h | 0 .../MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/fastspi.c | 0 .../MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/fastspi.h | 4 +++- 7 files changed, 7 insertions(+), 1 deletion(-) rename {Examples/MAX78000/QSPI => Libraries/Boards/MAX78000/FTHR_RevA/Include}/fastspi_config.h (100%) rename {Examples/MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/N01S830HA.c (100%) rename {Examples/MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/N01S830HA.h (100%) rename {Examples/MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/N01S830HA_config.h (100%) rename {Examples/MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/fastspi.c (100%) rename {Examples/MAX78000/QSPI => Libraries/MiscDrivers/SRAM}/fastspi.h (96%) diff --git a/Examples/MAX78000/QSPI/fastspi_config.h b/Libraries/Boards/MAX78000/FTHR_RevA/Include/fastspi_config.h similarity index 100% rename from Examples/MAX78000/QSPI/fastspi_config.h rename to Libraries/Boards/MAX78000/FTHR_RevA/Include/fastspi_config.h diff --git a/Libraries/Boards/MAX78000/FTHR_RevA/board.mk b/Libraries/Boards/MAX78000/FTHR_RevA/board.mk index 398bb26db84..97a8d786611 100644 --- a/Libraries/Boards/MAX78000/FTHR_RevA/board.mk +++ b/Libraries/Boards/MAX78000/FTHR_RevA/board.mk @@ -65,6 +65,8 @@ SRCS += ov7692.c SRCS += sccb.c SRCS += max20303.c SRCS += max9867.c +SRCS += N01S830HA.c +SRCS += fastspi.c PROJ_CFLAGS+=-DCAMERA_OV7692 @@ -80,6 +82,7 @@ VPATH += $(MISC_DRIVERS_DIR)/PushButton VPATH += $(MISC_DRIVERS_DIR)/PMIC VPATH += $(MISC_DRIVERS_DIR)/Touchscreen VPATH += $(MISC_DRIVERS_DIR)/CODEC +VPATH += $(MISC_DRIVERS_DIR)/SRAM # Where to find BSP header files IPATH += $(BOARD_DIR)/Include @@ -91,5 +94,6 @@ IPATH += $(MISC_DRIVERS_DIR)/PushButton IPATH += $(MISC_DRIVERS_DIR)/PMIC IPATH += $(MISC_DRIVERS_DIR)/Touchscreen IPATH += $(MISC_DRIVERS_DIR)/CODEC +IPATH += $(MISC_DRIVERS_DIR)/SRAM include $(MISC_DRIVERS_DIR)/Display/fonts/fonts.mk diff --git a/Examples/MAX78000/QSPI/N01S830HA.c b/Libraries/MiscDrivers/SRAM/N01S830HA.c similarity index 100% rename from Examples/MAX78000/QSPI/N01S830HA.c rename to Libraries/MiscDrivers/SRAM/N01S830HA.c diff --git a/Examples/MAX78000/QSPI/N01S830HA.h b/Libraries/MiscDrivers/SRAM/N01S830HA.h similarity index 100% rename from Examples/MAX78000/QSPI/N01S830HA.h rename to Libraries/MiscDrivers/SRAM/N01S830HA.h diff --git a/Examples/MAX78000/QSPI/N01S830HA_config.h b/Libraries/MiscDrivers/SRAM/N01S830HA_config.h similarity index 100% rename from Examples/MAX78000/QSPI/N01S830HA_config.h rename to Libraries/MiscDrivers/SRAM/N01S830HA_config.h diff --git a/Examples/MAX78000/QSPI/fastspi.c b/Libraries/MiscDrivers/SRAM/fastspi.c similarity index 100% rename from Examples/MAX78000/QSPI/fastspi.c rename to Libraries/MiscDrivers/SRAM/fastspi.c diff --git a/Examples/MAX78000/QSPI/fastspi.h b/Libraries/MiscDrivers/SRAM/fastspi.h similarity index 96% rename from Examples/MAX78000/QSPI/fastspi.h rename to Libraries/MiscDrivers/SRAM/fastspi.h index 179e57ad74c..e995161d678 100644 --- a/Examples/MAX78000/QSPI/fastspi.h +++ b/Libraries/MiscDrivers/SRAM/fastspi.h @@ -38,7 +38,9 @@ * @brief "fast" and optimized DMA SPI drivers for use alongside external SRAM drivers */ -#include "fastspi_config.h" // <-- must be implemented for each Board Support Package +#include "fastspi_config.h" +// NOTE: "fastspi_config.h should be implemented for each Board Support Package and placed in +// its include folder in Libraries/Boards #ifndef SPI #error Missing fastspi_config.h definition 'SPI' to select SPI instance From aaa49a0775e197157c1c03469c1c5866b3790b10 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 19:26:20 -0600 Subject: [PATCH 08/26] Rename example to FTHR_SRAM, update README --- .../MAX78000/{QSPI => FTHR_SRAM}/.cproject | 0 .../MAX78000/{QSPI => FTHR_SRAM}/.project | 0 .../.settings/language.settings.xml | 0 .../org.eclipse.cdt.codan.core.prefs | 0 .../.settings/org.eclipse.cdt.core.prefs | 0 .../{QSPI => FTHR_SRAM}/.vscode/README.md | 0 .../.vscode/c_cpp_properties.json | 0 .../{QSPI => FTHR_SRAM}/.vscode/flash.gdb | 2 + .../{QSPI => FTHR_SRAM}/.vscode/launch.json | 0 .../{QSPI => FTHR_SRAM}/.vscode/settings.json | 0 .../{QSPI => FTHR_SRAM}/.vscode/tasks.json | 0 .../MAX78000/{QSPI => FTHR_SRAM}/Makefile | 0 .../MAX78000/{QSPI => FTHR_SRAM}/QSPI.launch | 0 Examples/MAX78000/FTHR_SRAM/README.md | 40 +++++++++++++++++++ .../MAX78000/{QSPI => FTHR_SRAM}/fastspi.old | 0 Examples/MAX78000/{QSPI => FTHR_SRAM}/main.c | 0 .../MAX78000/{QSPI => FTHR_SRAM}/project.mk | 0 Examples/MAX78000/QSPI/README.md | 23 ----------- 18 files changed, 42 insertions(+), 23 deletions(-) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.cproject (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.project (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.settings/language.settings.xml (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.settings/org.eclipse.cdt.codan.core.prefs (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.settings/org.eclipse.cdt.core.prefs (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.vscode/README.md (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.vscode/c_cpp_properties.json (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.vscode/flash.gdb (90%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.vscode/launch.json (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.vscode/settings.json (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/.vscode/tasks.json (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/Makefile (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/QSPI.launch (100%) create mode 100644 Examples/MAX78000/FTHR_SRAM/README.md rename Examples/MAX78000/{QSPI => FTHR_SRAM}/fastspi.old (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/main.c (100%) rename Examples/MAX78000/{QSPI => FTHR_SRAM}/project.mk (100%) delete mode 100644 Examples/MAX78000/QSPI/README.md diff --git a/Examples/MAX78000/QSPI/.cproject b/Examples/MAX78000/FTHR_SRAM/.cproject similarity index 100% rename from Examples/MAX78000/QSPI/.cproject rename to Examples/MAX78000/FTHR_SRAM/.cproject diff --git a/Examples/MAX78000/QSPI/.project b/Examples/MAX78000/FTHR_SRAM/.project similarity index 100% rename from Examples/MAX78000/QSPI/.project rename to Examples/MAX78000/FTHR_SRAM/.project diff --git a/Examples/MAX78000/QSPI/.settings/language.settings.xml b/Examples/MAX78000/FTHR_SRAM/.settings/language.settings.xml similarity index 100% rename from Examples/MAX78000/QSPI/.settings/language.settings.xml rename to Examples/MAX78000/FTHR_SRAM/.settings/language.settings.xml diff --git a/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.codan.core.prefs b/Examples/MAX78000/FTHR_SRAM/.settings/org.eclipse.cdt.codan.core.prefs similarity index 100% rename from Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.codan.core.prefs rename to Examples/MAX78000/FTHR_SRAM/.settings/org.eclipse.cdt.codan.core.prefs diff --git a/Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.core.prefs b/Examples/MAX78000/FTHR_SRAM/.settings/org.eclipse.cdt.core.prefs similarity index 100% rename from Examples/MAX78000/QSPI/.settings/org.eclipse.cdt.core.prefs rename to Examples/MAX78000/FTHR_SRAM/.settings/org.eclipse.cdt.core.prefs diff --git a/Examples/MAX78000/QSPI/.vscode/README.md b/Examples/MAX78000/FTHR_SRAM/.vscode/README.md similarity index 100% rename from Examples/MAX78000/QSPI/.vscode/README.md rename to Examples/MAX78000/FTHR_SRAM/.vscode/README.md diff --git a/Examples/MAX78000/QSPI/.vscode/c_cpp_properties.json b/Examples/MAX78000/FTHR_SRAM/.vscode/c_cpp_properties.json similarity index 100% rename from Examples/MAX78000/QSPI/.vscode/c_cpp_properties.json rename to Examples/MAX78000/FTHR_SRAM/.vscode/c_cpp_properties.json diff --git a/Examples/MAX78000/QSPI/.vscode/flash.gdb b/Examples/MAX78000/FTHR_SRAM/.vscode/flash.gdb similarity index 90% rename from Examples/MAX78000/QSPI/.vscode/flash.gdb rename to Examples/MAX78000/FTHR_SRAM/.vscode/flash.gdb index fc627ae86a3..6ee441b889e 100755 --- a/Examples/MAX78000/QSPI/.vscode/flash.gdb +++ b/Examples/MAX78000/FTHR_SRAM/.vscode/flash.gdb @@ -1,5 +1,6 @@ define flash_m4 set architecture armv7e-m + set remotetimeout 10 target remote | openocd -c "gdb_port pipe;log_output flash.log" -s $arg0/scripts -f interface/$arg1 -f target/$arg2 -c "init; reset halt" load compare-sections @@ -8,6 +9,7 @@ end define flash_m4_run set architecture armv7e-m + set remotetimeout 10 target remote | openocd -c "gdb_port pipe;log_output flash.log" -s $arg0/scripts -f interface/$arg1 -f target/$arg2 -c "init; reset halt" load compare-sections diff --git a/Examples/MAX78000/QSPI/.vscode/launch.json b/Examples/MAX78000/FTHR_SRAM/.vscode/launch.json similarity index 100% rename from Examples/MAX78000/QSPI/.vscode/launch.json rename to Examples/MAX78000/FTHR_SRAM/.vscode/launch.json diff --git a/Examples/MAX78000/QSPI/.vscode/settings.json b/Examples/MAX78000/FTHR_SRAM/.vscode/settings.json similarity index 100% rename from Examples/MAX78000/QSPI/.vscode/settings.json rename to Examples/MAX78000/FTHR_SRAM/.vscode/settings.json diff --git a/Examples/MAX78000/QSPI/.vscode/tasks.json b/Examples/MAX78000/FTHR_SRAM/.vscode/tasks.json similarity index 100% rename from Examples/MAX78000/QSPI/.vscode/tasks.json rename to Examples/MAX78000/FTHR_SRAM/.vscode/tasks.json diff --git a/Examples/MAX78000/QSPI/Makefile b/Examples/MAX78000/FTHR_SRAM/Makefile similarity index 100% rename from Examples/MAX78000/QSPI/Makefile rename to Examples/MAX78000/FTHR_SRAM/Makefile diff --git a/Examples/MAX78000/QSPI/QSPI.launch b/Examples/MAX78000/FTHR_SRAM/QSPI.launch similarity index 100% rename from Examples/MAX78000/QSPI/QSPI.launch rename to Examples/MAX78000/FTHR_SRAM/QSPI.launch diff --git a/Examples/MAX78000/FTHR_SRAM/README.md b/Examples/MAX78000/FTHR_SRAM/README.md new file mode 100644 index 00000000000..86a735c18ba --- /dev/null +++ b/Examples/MAX78000/FTHR_SRAM/README.md @@ -0,0 +1,40 @@ +## Description + +This example demonstrates with the N01S830HA external SRAM IC on the MAX78000FTHR. It also excercises the N01S830HA by reading and validating various test patterns and demonstrates the speed increases using QSPI vs traditional SPI. + +## Software + +### Project Usage + +Universal instructions on building, flashing, and debugging this project can be found in the **[MSDK User Guide](https://analog-devices-msdk.github.io/msdk/USERGUIDE/)**. + +### Project-Specific Build Notes + +* This project is only supported on the MAX78000FTHR board. + +## Required Connections + +- Connect a USB cable between the PC and the CN1 (USB/PWR) connector. +- Open a terminal application on the PC and connect to the EV kit's console UART at 115200, 8-N-1. + +## Expected Output + +```shell +QSPI SRAM Test: + Test Address: 0x0 + Test size: 4096 bytes + Test speed: 25000000 Hz +(Benchmark) Wrote 4096 bytes to internal SRAM in 20us +Test 1: Standard SPI write... + Done (4096 bytes in 1364us) +Test 2: Standard SPI read... + Read finished (4096 bytes in 1363us) + Checking for mismatches... + Success. +Test 3: QSPI write... + Done (4096 bytes in 544us) +Test 4: QSPI read... + Read finished (4096 bytes in 377us) + Checking for mismatches... + Success. +``` diff --git a/Examples/MAX78000/QSPI/fastspi.old b/Examples/MAX78000/FTHR_SRAM/fastspi.old similarity index 100% rename from Examples/MAX78000/QSPI/fastspi.old rename to Examples/MAX78000/FTHR_SRAM/fastspi.old diff --git a/Examples/MAX78000/QSPI/main.c b/Examples/MAX78000/FTHR_SRAM/main.c similarity index 100% rename from Examples/MAX78000/QSPI/main.c rename to Examples/MAX78000/FTHR_SRAM/main.c diff --git a/Examples/MAX78000/QSPI/project.mk b/Examples/MAX78000/FTHR_SRAM/project.mk similarity index 100% rename from Examples/MAX78000/QSPI/project.mk rename to Examples/MAX78000/FTHR_SRAM/project.mk diff --git a/Examples/MAX78000/QSPI/README.md b/Examples/MAX78000/QSPI/README.md deleted file mode 100644 index c5ec0156bec..00000000000 --- a/Examples/MAX78000/QSPI/README.md +++ /dev/null @@ -1,23 +0,0 @@ -## Description - -This example demonstrates QSPI communication in drivers written for the N01S830HA external SRAM IC on the MAX78000FTHR. It also excercises the N01S830HA by reading and validating various test patterns and demonstrates the speed increases using QSPI vs traditional SPI. - -## Software - -### Project Usage - -Universal instructions on building, flashing, and debugging this project can be found in the **[MSDK User Guide](https://analog-devices-msdk.github.io/msdk/USERGUIDE/)**. - -### Project-Specific Build Notes - -(None - this project builds and runs as a standard example) - -## Expected Output - -```shell -TODO -``` - -## Required Connections - -TODO From 74d87bd21bb6dd126faa6a0e55ef0939870f8960 Mon Sep 17 00:00:00 2001 From: Jake Carter Date: Mon, 20 Nov 2023 19:35:10 -0600 Subject: [PATCH 09/26] Update project files --- Examples/MAX78000/FTHR_SRAM/.cproject | 7 +- Examples/MAX78000/FTHR_SRAM/.project | 2 +- .../.settings/org.eclipse.cdt.core.prefs | 4 +- Examples/MAX78000/FTHR_SRAM/.vscode/README.md | 383 +----------------- Examples/MAX78000/FTHR_SRAM/.vscode/flash.gdb | 2 +- .../MAX78000/FTHR_SRAM/.vscode/launch.json | 8 +- .../MAX78000/FTHR_SRAM/.vscode/settings.json | 28 +- .../MAX78000/FTHR_SRAM/.vscode/tasks.json | 9 + Examples/MAX78000/FTHR_SRAM/FTHR_SRAM.launch | 62 +++ Examples/MAX78000/FTHR_SRAM/Makefile | 26 +- 10 files changed, 129 insertions(+), 402 deletions(-) create mode 100644 Examples/MAX78000/FTHR_SRAM/FTHR_SRAM.launch diff --git a/Examples/MAX78000/FTHR_SRAM/.cproject b/Examples/MAX78000/FTHR_SRAM/.cproject index d3a2a23288d..570fd5b8321 100644 --- a/Examples/MAX78000/FTHR_SRAM/.cproject +++ b/Examples/MAX78000/FTHR_SRAM/.cproject @@ -34,12 +34,15 @@ + + +