1
0
forked from me/IronOS

Bring in sdk as its broken

Far, Far to much crap to fix with regex now
This commit is contained in:
Ben V. Brown
2022-04-02 18:17:52 +11:00
parent f004fab4c5
commit 03a7cb4dd3
6148 changed files with 9666393 additions and 1 deletions

Submodule source/Core/BSP/Magic/bl_mcu_sdk deleted from 8742503a9e

View File

@@ -0,0 +1,171 @@
# clang-format configuration file. Intended for clang-format >= 11.0
#
# For more information, see:
#
# https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
---
# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
# BasedOnStyle: LLVM
# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4
# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: Align
# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: false
# 对齐位域
AlignConsecutiveBitFields: true
# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: false
# 连续宏时,进行对齐
AlignConsecutiveMacros: true
# 左对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Left
# 水平对齐二元和三元表达式的操作数
AlignOperands: true
# 对齐连续的尾随的注释
AlignTrailingComments: true
# 允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false
# 允许短的块放在同一行
AllowShortBlocksOnASingleLine: false
# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: false
# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: None
# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: false
# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: false
# 总是在定义返回类型后换行(deprecated)
AlwaysBreakAfterDefinitionReturnType: None
# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数),
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None
# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false
# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: false
# false表示函数实参要么都在同一行要么都各自一行
BinPackArguments: true
# false表示所有形参要么都在同一行要么都各自一行
BinPackParameters: true
# 大括号换行只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false # Unknown to clang-format-5.0
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true # Unknown to clang-format-4.0
SplitEmptyRecord: true # Unknown to clang-format-4.0
SplitEmptyNamespace: true # Unknown to clang-format-4.0
# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
# 在三元运算符前换行
BreakBeforeTernaryOperators: false
# 在构造函数的初始化列表的逗号前换行
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
# 每行字符的限制0表示没有限制
ColumnLimit: 0
# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false # Unknown to clang-format-4.0
# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false
# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4
# 延续的行的缩进宽度
ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: false
# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false
# 关闭格式化
DisableFormat: false
ForEachMacros:
- 'SHELL_EXPORT_CMD'
# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental)
ExperimentalAutoDetectBinPacking: false
# 缩进case标签
IndentCaseLabels: true
# 缩进宽度
IndentWidth: 4
# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: false
# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: false
# 开始一个块的宏的正则表达式
MacroBlockBegin: ''
# 结束一个块的宏的正则表达式
MacroBlockEnd: ''
# 连续空行的最大数量
MaxEmptyLinesToKeep: 1
# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: None
# 使用ObjC块时缩进宽度
ObjCBlockIndentWidth: 4
# 在ObjC的@property后添加一个空格
ObjCSpaceAfterProperty: false
# 在ObjC的protocol列表前添加一个空格
ObjCSpaceBeforeProtocolList: true
# 在call(后对函数调用换行的penalty
PenaltyBreakBeforeFirstCallParameter: 30
# 在一个注释中引入换行的penalty
PenaltyBreakComment: 10
# 第一次在<<前换行的penalty
PenaltyBreakFirstLessLess: 0
# 在一个字符串字面量中引入换行的penalty
PenaltyBreakString: 10
# 对于每个在行字符数限制之外的字符的penalty
PenaltyExcessCharacter: 100
# 将函数的返回类型放到它自己的行的penalty
PenaltyReturnTypeOnItsOwnLine: 60
# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Right
# 允许重新排版注释
ReflowComments: false
# 允许排序#include
SortIncludes: false
# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false
# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true
# 开圆括号之前添加一个空格: Never, ControlStatements, Always
SpaceBeforeParens: ControlStatements
# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false
# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1
# 在尖括号的<后和>前添加空格
SpacesInAngles: false
# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: false
# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false
# 在圆括号的(后和)前添加空格
SpacesInParentheses: false
# 在方括号的[后和]前添加空格lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false
# 标准: Cpp03, Cpp11, Auto
Standard: Cpp03
# tab宽度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never
...

View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072" name="Default" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072.1792346702" name="/" resourcePath="">
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.497065614" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.1352229726" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" value="riscv64-unknown-elf-" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.suffix.1688033986" name="Suffix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.suffix"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.1872432415" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" value="gcc" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.2078105401" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" value="g++" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1831101806" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" value="ar" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1448757246" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" value="objcopy" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1075129316" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" value="objdump" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1742672886" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" value="size" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.1314958796" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" value="make" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.1915887520" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" value="rm" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.useglobalpath.1924003386" name="Use global path" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.useglobalpath"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.path.704067905" name="Path" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.path"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.627202708" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1219461309" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.907545928" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1015262120" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1306384982" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1489908576" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.fp.165133640" name="Floating point" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.fp"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1875289751" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.492284435" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.fp.1841793115" name="Floating point ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.fp"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune.1108911638" name="Tuning" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.tune"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel.1594234601" name="Code model" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.codemodel"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.smalldatalimit.1532183408" name="Small data limit" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.smalldatalimit"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.align.1487992932" name="Align" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.align"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.saverestore.641693495" name="Small prologue/epilogue (-msave-restore)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.saverestore"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.memcpy.1612253810" name="Force string operations to call library functions (-mmemcpy)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.memcpy"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.plt.327409451" name="Allow use of PLTs (-mplt)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.plt"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.fdiv.471747874" name="Floating-point divide/sqrt instructions (-mfdiv)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.fdiv"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.div.1454578867" name="Integer divide instructions (-mdiv)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.div"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.other.2061222983" name="Other target flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.other"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.444746854" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1137303046" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.1261641000" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.1037457578" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.505001509" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon.993751625" name="No common unitialized (-fno-common)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.noinlinefunctions.756959633" name="Do not inline functions (-fno-inline-functions)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.noinlinefunctions"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.freestanding.1590959906" name="Assume freestanding environment (-ffreestanding)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.freestanding"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nobuiltin.1042039327" name="Disable builtin (-fno-builtin)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nobuiltin"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.spconstant.1039548956" name="Single precision constants (-fsingle-precision-constant)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.spconstant"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.PIC.1985811521" name="Position independent code (-fPIC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.PIC"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.lto.1051530800" name="Link-time optimizer (-flto)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.lto"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nomoveloopinvariants.1205914795" name="Disable loop invariant move (-fno-move-loop-invariants)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nomoveloopinvariants"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.other.1954151846" name="Other optimization flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.other"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1744383700" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" value="RISC-V GCC/Newlib" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.493085227" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id" value="2262347901" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.syntaxonly.258175649" name="Check syntax only (-fsyntax-only)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.syntaxonly"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.pedantic.1226214321" name="Pedantic (-pedantic)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.pedantic"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.pedanticerrors.110062487" name="Pedantic warnings as errors (-pedantic-errors)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.pedanticerrors"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.nowarn.1919671717" name="Inhibit all warnings (-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.nowarn"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1821427624" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.292398014" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.allwarn.1309277289" name="Enable all common warnings (-Wall)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.allwarn"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.extrawarn.1558226400" name="Enable extra warnings (-Wextra)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.extrawarn"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.missingdeclaration.586697590" name="Warn on undeclared global function (-Wmissing-declaration)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.missingdeclaration"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.conversion.954958860" name="Warn on implicit conversions (-Wconversion)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.conversion"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.pointerarith.563944459" name="Warn if pointer arithmetic (-Wpointer-arith)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.pointerarith"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.padded.1545777759" name="Warn if padding is included (-Wpadded)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.padded"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.shadow.1629270130" name="Warn if shadowed variable (-Wshadow)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.shadow"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.logicalop.658467865" name="Warn if suspicious logical ops (-Wlogical-op)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.logicalop"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.agreggatereturn.971552745" name="Warn if struct is returned (-Wagreggate-return)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.agreggatereturn"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.floatequal.1598374590" name="Warn if floats are compared as equal (-Wfloat-equal)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.floatequal"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.toerrors.1396465302" name="Generate errors instead of warnings (-Werror)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.toerrors"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.other.1062181782" name="Other warning flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.other"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1738140850" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.792481645" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.prof.953900793" name="Generate prof information (-p)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.prof"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.gprof.202548387" name="Generate gprof information (-pg)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.gprof"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.other.1881550968" name="Other debugging flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.other"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.showDevicesTab.975549113" name="showDevicesTab" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.1497718471" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<builder autoBuildTarget="all" cleanBuildTarget="clean" command="make" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1100306583" incrementalBuildTarget="BOARD=BL702_EVB APP=hellowd SAPP=helloworld" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1060786402" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.154864423" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1096558861" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.952554633" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.141010239" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1200181396" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler">
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.input.1522176966" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.734083223" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections.528465909" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.2027828701" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections.1009157025" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.input.807068426" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1266046767" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1181214240" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1777652181" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source.1728454125" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.503927789" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.603185590" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.1295754826" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.312765386" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.964975723" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format.795673591" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format" useByScannerDiscovery="false"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="bl_mcu_sdk.null.805808530" name="bl_mcu_sdk"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072;ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072.1792346702;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1200181396;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.input.1522176966">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072;ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.base.528944072.1792346702;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.952554633;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.141010239">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/bl_mcu_sdk"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="bl_make" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>build BOARD=bl706_iot</buildArguments>
<buildTarget>APP=helloworld</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="bl_clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="download" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>INTERFACE=uart COMx=com49</buildArguments>
<buildTarget>download</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>bl_mcu_sdk</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.15)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/tools/cmake/riscv64-unknown-elf-gcc.cmake)
include(${CMAKE_SOURCE_DIR}/drivers/${CHIP}_driver/cpu_flags.cmake)
include(${CMAKE_SOURCE_DIR}/tools/cmake/compiler_flags.cmake)
include(${CMAKE_SOURCE_DIR}/tools/cmake/tools.cmake)
PROJECT(${BOARD} C CXX ASM)
# set(CMAKE_VERBOSE_MAKEFILE ON)
ENABLE_LANGUAGE(ASM)
include_directories(${CMAKE_SOURCE_DIR}/bsp/bsp_common/platform)
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/bsp/board/${CHIP})
include_directories(${CMAKE_SOURCE_DIR}/bsp/board/${CHIP})
else()
message(FATAL_ERROR "${CMAKE_SOURCE_DIR}/bsp/board/${CHIP} is not exist")
endif()
search_application(${CMAKE_SOURCE_DIR}/${APP_DIR})

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2020] [BOUFFALO LAB (NANJING) CO., LTD.]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,72 @@
#common config
BOARD?=bl706_iot
CHIP?=bl702
APP_DIR?=examples
APP?=helloworld
CPU_ID?=none
#bootrom config,users do not need it
BOOTROM?=n
#format config
FORMAT_DIR?=.
# The command to remove a file.
RM = cmake -E remove_directory
#flash tool config
INTERFACE?=uart
COMx?=
BAUDRATE ?=2000000
ifeq ($(INTERFACE),uart)
FLASH_DOWNLOAD_CONFIG:=--chipname=$(CHIP) --interface=uart --port=$(COMx) --baudrate=$(BAUDRATE)
else
FLASH_DOWNLOAD_CONFIG:=--chipname=$(CHIP) --interface=$(INTERFACE)
endif
#option config to use
SUPPORT_FLOAT?=n
SUPPORT_ROMAPI?=y
SUPPORT_HALAPI?=y
SUPPORT_USB_HS?=n
SUPPORT_HW_SEC_ENG_DISABLE?=n
SUPPORT_BLECONTROLLER_LIB?=
#cmake definition config
cmake_definition+= -DCHIP=$(CHIP)
cmake_definition+= -DCPU_ID=$(CPU_ID)
cmake_definition+= -DBOARD=$(BOARD)
cmake_definition+= -DAPP_DIR=$(APP_DIR)
cmake_definition+= -DAPP=$(APP)
cmake_definition+= -DBOOTROM=$(BOOTROM)
cmake_definition+= -DCONFIG_ROMAPI=$(SUPPORT_ROMAPI)
cmake_definition+= -DCONFIG_HALAPI=$(SUPPORT_HALAPI)
cmake_definition+= -DCONFIG_PRINT_FLOAT=$(SUPPORT_FLOAT)
cmake_definition+= -DCONFIG_USB_HS=$(SUPPORT_USB_HS)
cmake_definition+= -DCONFIG_HW_SEC_ENG_DISABLE=$(SUPPORT_HW_SEC_ENG_DISABLE)
cmake_definition+= -DCONFIG_BLECONTROLLER_LIB=$(SUPPORT_BLECONTROLLER_LIB)
build:Makefile
cmake -S . -B build -G "Unix Makefiles" $(cmake_definition)
cd build && make -j4
help:
@echo "Welcome to MCU SDK cmake build system,commands are as follows:"
@echo ""
@echo "make clean - Remove all cmake caches and output files"
@echo "make SUPPORT_FLOAT=y - Enable float print"
@echo "make SUPPORT_USB_HS=y - Enable usb high speed"
@echo "make SUPPORT_BLECONTROLLER_LIB=value - Select blecontroller lib,value can be m0s1、m0s1s、std or empty"
download:
./tools/bflb_flash_tool/bflb_mcu_tool $(FLASH_DOWNLOAD_CONFIG)
format:
find $(FORMAT_DIR)/ -name "*.c" -o -name "*.h" -o -name "*.cc" -o -name "*.cpp"| xargs clang-format -style=file -i
clean:
$(RM) out
$(RM) build
.PHONY:build clean download format help

View File

@@ -0,0 +1,245 @@
[![License](https://img.shields.io/badge/License-Apache--2.0-brightgreen)](LICENSE)
[![Release](https://img.shields.io/github/v/tag/bouffalolab/bl_mcu_sdk?color=s&label=release)]()
[中文版](README_zh.md)
# Introduction
**bl mcu sdk** is an MCU software development kit provided by the Bouffalo Lab Team for BL602/BL604, BL702/BL704/BL706 and other series of chips in the future.
## Code Framework
```
bl_mcu_sdk
├── bsp
│ ├── board
│ │ ├── bl602
│ │ └── bl702
│ └── bsp_common
├── build
├── common
│ ├── bl_math
│ ├── device
│ ├── list
│ ├── memheap
│ ├── misc
│ ├── partition
│ ├── pid
│ ├── ring_buffer
│ ├── soft_crc
│ └── timestamp
├── components
│ ├── ble
│ ├── fatfs
│ ├── freertos
│ ├── lvgl
│ ├── lwip
│ ├── mbedtls
│ ├── nmsis
│ ├── romfs
│ ├── rt-thread
│ ├── shell
│ ├── tflite
│ ├── tiny_jpeg
│ ├── usb_stack
│ └── xz
├── docs
│ ├── chipSpecification
│ ├── development_guide
│ └── development_guide_en
├── drivers
│ ├── bl602_driver
│ └── bl702_driver
├── examples
│ ├── acomp
│ ├── adc
│ ├── audio_cube
│ ├── ble
│ ├── boot2_iap
│ ├── camera
│ ├── coremark
│ ├── cxx
│ ├── dac
│ ├── dma
│ ├── dsp
│ ├── emac
│ ├── flash
│ ├── freertos
│ ├── gpio
│ ├── hellowd
│ ├── i2c
│ ├── i2s
│ ├── keyscan
│ ├── lvgl
│ ├── mbedtls
│ ├── memheap
│ ├── nn
│ ├── pka
│ ├── pm
│ ├── psram
│ ├── pwm
│ ├── qdec
│ ├── rt-thread
│ ├── rtc
│ ├── shell
│ ├── spi
│ ├── systick
│ ├── tensorflow
│ ├── timer
│ ├── uart
│ └── usb
├── out
└── tools
├── bflb_flash_tool
├── cdk_flashloader
├── cmake
└── openocd
```
- **bsp/board** : store the board-level description file such as `clock_config.h` (describes the clock configuration file) `pinmux_config.h` (describes the io function file) `peripheral_config.h` (describes the default configuration file of the peripheral) , These files together describe the board hardware information.
- **bsp/bsp_common** : store some common peripheral driver codes related to the board.
- **common** : store some common functions and macros that chip drivers will need.
- **components** : store the third-party library public component library.
- **drivers** : store bouffalo series of chip drivers.
- **examples** : store the official sample code.
- **tools** : store toolkits related to compiling and downloading.
- **docs** : store tutorial documents and other help information.
- **build** : store cmake cache files.
- **out** : store the bin and map file generated after compiling and linking.
## Hierarchy
[![Hierarchy](https://z3.ax1x.com/2021/06/18/RpUVoj.png)](https://imgtu.com/i/RpUVoj)
# Resources
## Hardware Resources
- BL706 IOT Development board
[![BL706_IOT](https://z3.ax1x.com/2021/08/06/fnPcLT.png)](https://imgtu.com/i/fnPcLT)
- BL706 AVB Development Board
[![BL706_AVB](https://z3.ax1x.com/2021/11/16/IWPuVJ.png)](https://imgtu.com/i/IWPuVJ)
There is currently no official purchase channel. If you want to get the above development board, you can apply for it in [Forum post](https://bbs.bouffalolab.com/d/88).
## Chip Manual
**Chip Reference Manual** and **Chip Data Manual** are listed on [document](https://dev.bouffalolab.com/document)
## Documentation Tutorial
To get more bl mcu sdk documentation tutorial, like api manual or peripheral demo and so on, please visit:
- [bl mcu sdk documentation tutorial](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_en/index.html)
## Video Tutorial
- [BL706 MCU Development Series Video Tutorial](https://www.bilibili.com/video/BV1xK4y1P7ur)
## Development Tools
### Command Line Development
For the tools needed for command line development, please refer to [linux development guide](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_en/get_started/Linux_quick_start_ubuntu.html)
- [cmake 3.19](https://cmake.org/files/v3.19/), cmake compilation tool, it is recommended to use cmake v3.15 or above
- [riscv64-unknown-elf-gcc](https://gitee.com/bouffalolab/toolchain_gcc_sifive_linux), risc-v linux toolchaindownload command:
```
git clone https://gitee.com/bouffalolab/toolchain_gcc_sifive_linux.git
```
### Eclipse Development
For the tools needed for Eclipse development, please refer to [Eclipse Development Guide](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_en/get_started/Windows_quick_start_eclipse.html)
- [Eclipse](https://dev.bouffalolab.com/media/upload/download/BouffaloLab_eclipse_x86_64_win.zip) eclipse development free installation package under Windows
- [riscv64-unknown-elf-gcc](https://gitee.com/bouffalolab/toolchain_gcc_sifive_windows), risc-v windows toolchaindownload command:
```
git clone https://gitee.com/bouffalolab/toolchain_gcc_sifive_windows.git
```
- [J-Link v10](https://www.segger.com/downloads/jlink), J-Link debugger, used to debug the chip online, it is recommended to use the hardware of J-Link V10 or above, and the software driver is recommended to use V6 .98 version
### CDK Development
For tools needed for CDK development, please refer to [CDK Development Guide](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_en/get_started/Windows_quick_start_cdk.html)
- [CDK](https://occ.t-head.cn/development/activities/cdk), Jianchi CDK integrated development environment of T-Head , it is recommended to use CDK v2.8.4 or above
### Flash Tool
In addition to using CK-link, J-link and command line programming, it also supports graphical programming tools.
Graphical programming tools provided by Bouffalolab:
- [Bouffalo Lab Dev Cube](https://dev.bouffalolab.com/download)
### Board Config Wizard
We provide [BL Config Wizard](https://dev.bouffalolab.com/media/config/index.html) to generate `clock_config.h``pinmux_config.h` and `peripheral_config.h` file online.
## How to make sdk as submodule
First add bl_mcu_sdk to your own project using the add submodule command, and then commit the gitmodules file to the remote repo.
```
git submodule add https://gitee.com/bouffalolab/bl_mcu_sdk.git bl_mcu_sdk
cd bl_mcu_sdk
git pull --rebase
cd ..
git add .gitmodules
git add bl_mcu_sdk
git commit -m "xxx"
git push
```
The final catalog presents the following results:
```
.
├── hardware
├── xxxx
├── xxxx
├── xxxx
├── bl_mcu_sdk
├── user_code
│ └── gpio
│ ├── gpio_blink
│ ├── gpio_dht11
│ └── gpio_int
```
### Command Line compile
```
cd bl_mcu_sdk
make APP=xxx APP_DIR=../user_code
```
## Forum
Bouffalolab Developer Forum: [https://bbs.bouffalolab.com/](https://bbs.bouffalolab.com/)
# License
**bl mcu sdk** is completely open source and follows the Apache License 2.0 open source license agreement. It can be used in commercial products for free and does not require public private code.
```
/*
* Copyright (c) 2021 Bouffalolab team
*
* SPDX-License-Identifier: Apache-2.0
*/
```

View File

@@ -0,0 +1,245 @@
[![License](https://img.shields.io/badge/License-Apache--2.0-brightgreen)](LICENSE)
[![Release](https://img.shields.io/github/v/tag/bouffalolab/bl_mcu_sdk?color=s&label=release)]()
[English Version](README.md)
# 简介
**bl mcu sdk** 是博流智能科技团队专为 BL602/BL604,BL702/BL704/BL706 以及未来其他系列芯片提供的 MCU 软件开发包。
## 代码框架
```
bl_mcu_sdk
├── bsp
│ ├── board
│ │ ├── bl602
│ │ └── bl702
│ └── bsp_common
├── build
├── common
│ ├── bl_math
│ ├── device
│ ├── list
│ ├── memheap
│ ├── misc
│ ├── partition
│ ├── pid
│ ├── ring_buffer
│ ├── soft_crc
│ └── timestamp
├── components
│ ├── ble
│ ├── fatfs
│ ├── freertos
│ ├── lvgl
│ ├── lwip
│ ├── mbedtls
│ ├── nmsis
│ ├── romfs
│ ├── rt-thread
│ ├── shell
│ ├── tflite
│ ├── tiny_jpeg
│ ├── usb_stack
│ └── xz
├── docs
│ ├── chipSpecification
│ ├── development_guide
│ └── development_guide_en
├── drivers
│ ├── bl602_driver
│ └── bl702_driver
├── examples
│ ├── acomp
│ ├── adc
│ ├── audio_cube
│ ├── ble
│ ├── boot2_iap
│ ├── camera
│ ├── coremark
│ ├── cxx
│ ├── dac
│ ├── dma
│ ├── dsp
│ ├── emac
│ ├── flash
│ ├── freertos
│ ├── gpio
│ ├── hellowd
│ ├── i2c
│ ├── i2s
│ ├── keyscan
│ ├── lvgl
│ ├── mbedtls
│ ├── memheap
│ ├── nn
│ ├── pka
│ ├── pm
│ ├── psram
│ ├── pwm
│ ├── qdec
│ ├── rt-thread
│ ├── rtc
│ ├── shell
│ ├── spi
│ ├── systick
│ ├── tensorflow
│ ├── timer
│ ├── uart
│ └── usb
├── out
└── tools
├── bflb_flash_tool
├── cdk_flashloader
├── cmake
└── openocd
```
- **bsp/board** : 存放板级描述文件 `clock_config.h`(描述时钟配置文件) `pinmux_config.h`(描述io功能文件) `peripheral_config.h` (描述外设默认配置文件) 这几个文件共同形成 board 文件夹描述特定应用的所有硬件信息。
- **bsp/bsp_common** : 存放一些板级相关的常用外设驱动代码
- **common** : 存放一些常用的函数和宏(芯片驱动需要)
- **components** : 存放第三方库公共组件
- **drivers** : 存放博流智能系列芯片驱动
- **examples** : 存放官方提供的示例代码
- **tools** : 存放编译下载相关的工具包
- **docs** : 存放教程文档以及其他帮助信息
- **build**: 存放 cmake 缓存文件
- **out** : 中间文件用来存放编译链接后的产生的bin文件
## 层次结构
[![层次结构](https://z3.ax1x.com/2021/06/18/RpUVoj.png)](https://imgtu.com/i/RpUVoj)
# 资源
## 硬件资源
- BL706 IOT 开发板
[![BL706_IOT](https://z3.ax1x.com/2021/08/06/fnPcLT.png)](https://imgtu.com/i/fnPcLT)
- BL706 AVB 开发板
[![BL706_AVB](https://z3.ax1x.com/2021/11/16/IWPuVJ.png)](https://imgtu.com/i/IWPuVJ)
目前暂时没有提供官方的购买渠道,如果想获得上述开发板,可到[论坛申请贴](https://bbs.bouffalolab.com/d/88)申请。
## 芯片手册
芯片数据手册和参考手册见 [文档](https://dev.bouffalolab.com/document)。
## 文档教程
获取更多 bl mcu sdk 开发相关的教程,如 api 手册、外设 demo 等,请参考:
- [bl mcu sdk 文档教程](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_zh/index.html)
## 视频教程
- [BL706 MCU 开发系列视频教程](https://www.bilibili.com/video/BV1xK4y1P7ur)
## 开发工具
### 命令行开发
命令行开发需要的工具,具体使用方法参考 [linux 开发指南](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_zh/get_started/Linux_quick_start_ubuntu.html)
- [cmake 3.19](https://cmake.org/files/v3.19/) cmake 编译工具,建议使用 cmake v3.15 以上版本
- [riscv64-unknown-elf-gcc](https://gitee.com/bouffalolab/toolchain_gcc_sifive_linux), risc-v linux 端工具链,下载方式:
```
git clone https://gitee.com/bouffalolab/toolchain_gcc_sifive_linux.git
```
### Eclipse开发
Eclipse 开发需要的工具,具体使用方法参考 [Eclipse 开发指南](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_zh/get_started/Windows_quick_start_eclipse.html)
- [Eclipse](https://dev.bouffalolab.com/media/upload/download/BouffaloLab_eclipse_x86_64_win.zip) Windows 下 eclipse 开发免安装包
- [riscv64-unknown-elf-gcc](https://gitee.com/bouffalolab/toolchain_gcc_sifive_windows), risc-v windows 端工具链,下载方式:
```
git clone https://gitee.com/bouffalolab/toolchain_gcc_sifive_windows.git
```
- [J-Link v10](https://www.segger.com/downloads/jlink) J-Link 调试器,用于在线调试芯片,建议使用 J-Link V10 以上版本硬件,软件驱动建议使用 V6.98 版本
### CDK开发
CDK 开发需要的工具,具体使用方法参考 [CDK 开发指南](https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_zh/get_started/Windows_quick_start_cdk.html)
- [CDK](https://occ.t-head.cn/development/activities/cdk),平头哥剑池 CDK 集成开发环境,建议使用 CDK v2.8.4 以上版本
### 烧写工具
除了可以使用 CK-link、J-link 以及命令行烧写以外,还支持图形化的烧写工具。
博流提供的图形化烧写工具:
- [Bouffalo Lab Dev Cube](https://dev.bouffalolab.com/download)
### Board Config Wizard
我们提供了[BL Config Wizard](https://dev.bouffalolab.com/media/config/index.html),可以在线生成 `clock_config.h``pinmux_config.h``peripheral_config.h` 文件。
## 如何将 SDK 作为 submodule 使用
首先使用添加子模块的命令添加到你自己的工程下,然后将 gitmodules 文件提交到远程仓库。
```
git submodule add https://gitee.com/bouffalolab/bl_mcu_sdk.git bl_mcu_sdk
cd bl_mcu_sdk
git pull --rebase
cd ..
git add .gitmodules
git add bl_mcu_sdk
git commit -m "xxx"
git push
```
最终目录呈现的结果如下:
```
.
├── hardware
├── xxxx
├── xxxx
├── xxxx
├── bl_mcu_sdk
├── user_code
│ └── gpio
│ ├── gpio_blink
│ ├── gpio_dht11
│ └── gpio_int
```
### 命令行编译方式
```
cd bl_mcu_sdk
make APP=xxx APP_DIR=../user_code
```
## 论坛
博流开发者交流论坛: [https://bbs.bouffalolab.com/](https://bbs.bouffalolab.com/)
# 许可协议
**bl mcu sdk** 完全开源,遵循 Apache License 2.0 开源许可协议,可以免费在商业产品中使用,并且不需要公开私有代码。
```
/*
* Copyright (c) 2021 Bouffalolab team
*
* SPDX-License-Identifier: Apache-2.0
*/
```

View File

@@ -0,0 +1,235 @@
bl mcu sdk Release Notes
----------------------------
此文件包含 bl mcu sdk 软件开发包的发行说明。
每个版本的文字说明与发布时的说明保持一致(可能会有错别字的勘误)。
bl mcu sdk Release V1.4.2
----------------------------
新增功能说明:
1. 重构 dac、dma 驱动,更新 dac、dma doc
2. 新增 arch_ffsll、arch_ctzll、arch_clzll 等函数
3. 优化 usb 协议栈 log 信息msc 新增 sense code for requestSense command
修复问题说明:
1. 补充完整 xxx_close 函数,复位相关寄存器
2. 删除 drivers 下头文件部分依赖
3. 优化 usb 驱动中 端点0 设置 ack 的位置(放置中断中),防止重复设置。
bl mcu sdk Release V1.4.1
----------------------------
新增功能说明:
1. 新增 aes、ble pds31、freertos tickless、audio cube demo
2. 新增 usb 同步传输中断方式
3. 新增 lwip 组件以及对应 emac demo
4. 新增 pds31 快速唤醒功能
5. 文档更新包含flash、usb、fatfs、pm、emac、ble
修复问题说明:
1. pwm demo 文档中分频值修正
2. 修正 mtimer 获取 div 函数
3. 修正 dma 链表配置,当传输长度为 4095 时会配置错误,优化 if 判断
4. switch 禁用跳表选项 C flag 中添加 -fno-jump-tables
5. 部分 cdk 工程增加 syscall.c对系统函数重定向否则会进 M mode 异常
6. 修正 gpio func macro value该值对配置 gpio 为 uart 时会有问题,出现覆盖问题
7. 补全 calloc 函数,浮点打印会使用
8. 从驱动库文件移除 bflb_platform.h 文件,减少只使用 std drv 时的依赖项
bl mcu sdk Release V1.4.0
----------------------------
新增功能说明:
1. 新增 mbedtls、rt-thread、nmsis 组件,新增 rt-thread msh、mfcc、nn、dsp demo
2. 新增 flash 模拟u盘升级、 c++、adc 中断读取、boot2 usb iap、prng demo
3. 修改 makefile 调用 cmake 执行命令
4. usb 协议栈新增 usb hs 功能
5. freertos 新增 tickless 功能
6. 重构芯片驱动的公用头文件包含、删除 flash 的相关 api
7. cdk 工程源文件更新
8. fatfs port接口新增 flash 读写usb msc中可以使用
9. 使能所有外设的 BSP_USING_XXX 宏
10. ble 新增 oad 功能,带加密功能
11. mmheap 组件更新,链表式的内存管理减少了 ram 的使用,但是会增加 malloc 和 free 时间
修复问题说明:
1. 修复 ble 在 pc上连接失败的问题修改 capcode 可以解决
2. fatfs 中 FS_MAX_SS 参数需要适配其他种类的扇区,修复多个驱动注册到 fatfs 时,参数覆盖的 bug
3. bl706_avb 文件删除其他 demo 的 pinmux只留 camera + lcd 的配置,同理 bl706_iot 文件只留 i2s + usb + adc + pwm 配置
4. 修正 adc_read 函数,只读取了一个 fifo 数值,影响 adc 采样效率
5. 修正 usb_dc_ep_set_stall 在 端点 stall 时没有开启下一次的端点接收的问题
bl mcu sdk Release V1.3.0
----------------------------
新增功能说明:
1. 新增 acomp、rtc、boot2、wdt、pm hal driver 和 demo
2. 新增 romfs demo、usb 麦克风和扬声器双声道 demo、带 tinyjpeg 组件的 spi lcd 显示 demo
3. 重构 boot2_iap demo统一接口
4. 使能 romapi减少 codesize
5. 新增 flash 自动识别和配置功能,适配不同的 flash 芯片
6. 重构 mcu lcd 驱动层,适配多种 mcu lcd 驱动
7. 新增 ssd1306 spi 和 i2c 驱动,新增 ws2812 、wm8978 驱动
8. shell 新增颜色显示和自定义打印接口(使用各种终端工具可以查看)
9. bl602 和 bl702 驱动库相关更新
10. 新增外部 cmake 工程编译方式,从而让 sdk 作为 submodule 使用
11. ld 文件的更新
12. ble lib 文件更新(需要使用最新的 toolchainsifive才能编译 ble demo
修复问题说明:
1. 修复 eclipse openocd 调试时openocd 版本太低导致无法调试
2. case 运行异常时,需要添加死循环
3. 驱动库的一些 bug fix
4. 开关外设中断的重名名
5. fix 重复定义的宏带来的 warning
bl mcu sdk Release V1.2.6
----------------------------
新增功能说明:
1. 重构 board 系统目录结构
2. 删除 SUPPORT_XXX 功能,改成 cmake 自动识别组件库并参与编译,识别参数为 TARGET_REQUIRED_LIBS
3. 删除 device_register 中 flag 选项
4. 重构 timer hal 层, clock tree 和 demo
5. 添加 自动识别内外部 flash 并切换引脚功能
6. 添加 2线 flash 下载支持
7. 默认使能 cpu 浮点支持(非打印浮点支持)
8. 添加 bl702 qfn32 的 board 文件
9. 添加 boot2 hal 封装层
10. 添加 pid 算法
11. 添加 qdec hal 和 demo
修复问题说明:
1. 修复 开关全局中断嵌套带来的问题
2. 修复 使用 shell 功能时编译报错
3. memcpy 改用 romapi
4. 修复 cdk 中编译 ble demo 编译报错,未添加 board 支持
5. 修复 pwm demo 相关宏书写错误
6. 修复 std 和 hal 中 switch case 返回的一些 bug
7. cdk 相关 demo 改用 bl706_iot board
8. 修改 keyscan 默认时钟和分频
bl mcu sdk Release V1.2.5
----------------------------
新增功能说明:
1. 添加 tensorflow lite 支持
2. gpio_set_mode 添加高阻模式
3. 添加 keyscan hal 驱动
4. 新增 shell 文件系统
5. 更新 clock tree 宏定义、更新 board.c 中 pinmux 初始化配置
6. es8388 驱动增加双通道支持
7. il9341 增加字库,支持大字号显示
修复问题说明:
1. 修复 usb msc 中 interface num 为 0
2. 修复 uart 和 spi 开关 dma 时未设置 oflag 状态
3. 修改 CPU_ID 默认值,当不使用多核时默认为 none
4. 修复 adc 浮点输出问题
5. 修复 hal pwm 相关宏书写错误
bl mcu sdk Release V1.2.4
----------------------------
新增功能说明:
1. 增加部分 math 库函数对 arm dsp api 的兼容,以及优化 math 库效率
2. 增加 bl702 adc、camera 中断,重定义 clock tree 的相关宏,
3. 删除 GPIO32-GPIO37更新 GPIO 初始化和读写函数,更新 sf flash 引脚初始化
4. 增加 i2s 双通道支持
5. 增加 adc、pwm、camera 相关 api
6. 增加 camera pingpong buffer case
7. cdk 工程更新
8. 更新 openocd cfg 文件,适配 openocd 0.11 版本
修复问题说明:
1. 对 pwm readme 说明修改
2. 修复 hal_usb 中对端点 0 状态的判断逻辑
3. 修复 flash 擦除扇区时多擦除扇区的问题
4. ble、lvgl、usb、boot2iap、adc 相关 demo 的修改
bl mcu sdk Release V1.2.3
----------------------------
新增功能说明:
1. 增加 case 输出成功和失败的 log 提示
2. 更新 cdk 工程,使用 minilibc 替代本地 libc
3. 更新 usb api 及其他文档说明
修复问题说明:
1. 修改 bl702_flash.ld 文件中 ram 的实际大小
2. 修复 main 函数返回时一直重入的问题
3. 删除 hal driver 中不需要的内容
4. 修复 cdk 工程中编译 camera case 存在的问题
bl mcu sdk Release V1.2.2
----------------------------
新增功能说明:
1. 新增 pwm 驱动 dc motor 和 step motor、dht11、custom hid 、shell demo
2. 为所有的 examples 添加 cdk 工程
3. 为 cdk 工程添加 openocd 支持
4. 更新文档
5. 使用 clang-format 格式化代码
修复问题说明:
1. 修复 __riscv_float_abi_single 未定义带来的 warning
2. 修改 bl702_flash.ld 中 heap 的 分配方式
3. 更新 shell 组件,添加使用时删除中间字符的功能
bl mcu sdk Release V1.2.1
----------------------------
新增功能说明:
1. 新增 readme for demo command line build
2. 更新 cmake 运行顺序
3. 更新 cdk flashloader 和 openocd cfg
4. 更新文档
修复问题说明:
1. 修复 board.c 中 ADC 的引脚初始化
2. 修复 ble 静态库依赖问题
bl mcu sdk Release V1.2.0
----------------------------
新增功能说明:
1. 新增 xz、ble 组件
2. usb_stack 中新增 usb video、hid、audio 驱动
3. 新增 bl602 driver 和 bl602_iot board
4. 为 examples 补全 cdk 工程
5. 新增 ble、psram、camera、boot2_iap、emac、usb_video、usb_audio、usb_hid、gpio_int、pwm_it、flash读写、lowpower、pka、systick、timer demo
6. 更新 flash Tools
7. 更新 cmake 文件
8. 更新 mtimer 时钟频率为1M便于计算
9. 文档更新
修复问题说明:
1. 修复若干已知问题
bl mcu sdk Release V1.1.0
----------------------------
新增功能说明:
1. 新增 lvgl 组件以及基本 demo
2. 新增 freertos 702 port 以及基本 demo
3. 新增 usb 转串口标准驱动 demo支持博流自定义 DTR、RTS 流控协议;
4. 文件系统添加命令行功能;
5. hal 层添加强转宏,从而用户可以在程序内修改;
修复问题说明:
1. 修正 usb 设备描述符初始化宏,添加协议类代码初始化;
2. 修复 hal 层驱动。
bl mcu sdk Release V1.0.0
----------------------------
初始化项目。该项目基于 cmake 构建,包含 bl702/bl704/bl706 系列 mcu 底层驱动、基本外设例程、common 驱动以及第三方组件。
支持 bl706_avb、bl706_iot 开发板的开发工作;
该项目也支持使用 CDK、eclipse 编译、烧写、调试代码;
该项目中还包含烧录工具、调试脚本、flash 算法文件以及构建 cmake 需要的一些工具。

View File

@@ -0,0 +1,55 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_40M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_160M
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_160M
#define BSP_UART_CLOCK_DIV 3
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 0
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL
#define BSP_DAC_CLOCK_DIV 1
#endif
#endif

View File

@@ -0,0 +1,232 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
#define BSP_USING_UART0
#define BSP_USING_UART1
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 16, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 64, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,144 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_UNUSED
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_UNUSED
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_UNUSED
// <q> GPIO3 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_QDEC]
// <i> config gpio3 function
#define CONFIG_GPIO3_FUNC GPIO_FUN_UNUSED
// <q> GPIO4 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio4 function
#define CONFIG_GPIO4_FUNC GPIO_FUN_UNUSED
// <q> GPIO5 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_QDEC]
// <i> config gpio5 function
#define CONFIG_GPIO5_FUNC GPIO_FUN_UNUSED
// <q> GPIO6 <2> [GPIO_FUN_UNUSED//GPIO_FUN_CLK_OUT//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_QDEC]
// <i> config gpio6 function
#define CONFIG_GPIO6_FUNC GPIO_FUN_UNUSED
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_UART0_RX
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_UNUSED
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_UNUSED
// <q> GPIO10 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio10 function
#define CONFIG_GPIO10_FUNC GPIO_FUN_UNUSED
// <q> GPIO11 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio11 function
#define CONFIG_GPIO11_FUNC GPIO_FUN_UNUSED
// <q> GPIO12 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio12 function
#define CONFIG_GPIO12_FUNC GPIO_FUN_UNUSED
// <q> GPIO13 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio13 function
#define CONFIG_GPIO13_FUNC GPIO_FUN_UNUSED
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_UNUSED
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UNUSED
// <q> GPIO16 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio16 function
#define CONFIG_GPIO16_FUNC GPIO_FUN_UART0_TX
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UART1_TX
// <q> GPIO18 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio18 function
#define CONFIG_GPIO18_FUNC GPIO_FUN_UNUSED
// <q> GPIO19 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio19 function
#define CONFIG_GPIO19_FUNC GPIO_FUN_UNUSED
// <q> GPIO20 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio20 function
#define CONFIG_GPIO20_FUNC GPIO_FUN_UNUSED
// <q> GPIO21 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio21 function
#define CONFIG_GPIO21_FUNC GPIO_FUN_UNUSED
// <q> GPIO22 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio22 function
#define CONFIG_GPIO22_FUNC GPIO_FUN_UNUSED
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
#endif

View File

@@ -0,0 +1,39 @@
/**
* @file bl602_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __BL602_CONFIG_H__
#define __BL602_CONFIG_H__
#if defined(bl602_iot)
#include "bl602_iot/peripheral_config.h"
#include "bl602_iot/clock_config.h"
#include "bl602_iot/pinmux_config.h"
#elif defined(bl602_boot2)
#include "bl602_boot2/peripheral_config.h"
#include "bl602_boot2/clock_config.h"
#include "bl602_boot2/pinmux_config.h"
#else
#error "do not find board,please check your board name"
#endif
#endif

View File

@@ -0,0 +1,55 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_40M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_160M
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_160M
#define BSP_UART_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 0
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL
#define BSP_DAC_CLOCK_DIV 1
#endif
#endif

View File

@@ -0,0 +1,243 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
#define BSP_USING_UART0
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DAC0
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_DAC0)
#ifndef DAC_CONFIG
#define DAC_CONFIG \
{ \
.channels = DAC_CHANNEL_0, \
.sample_freq = DAC_SAMPLE_FREQ_500KHZ, \
.vref = DAC_VREF_INTERNAL, \
}
#endif
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 0, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 63, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,144 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_UNUSED
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_UNUSED
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_UNUSED
// <q> GPIO3 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_QDEC]
// <i> config gpio3 function
#define CONFIG_GPIO3_FUNC GPIO_FUN_UNUSED
// <q> GPIO4 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio4 function
#define CONFIG_GPIO4_FUNC GPIO_FUN_UNUSED
// <q> GPIO5 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_QDEC]
// <i> config gpio5 function
#define CONFIG_GPIO5_FUNC GPIO_FUN_UNUSED
// <q> GPIO6 <2> [GPIO_FUN_UNUSED//GPIO_FUN_CLK_OUT//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_QDEC]
// <i> config gpio6 function
#define CONFIG_GPIO6_FUNC GPIO_FUN_UNUSED
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_UART0_RX
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_UNUSED
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_UNUSED
// <q> GPIO10 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio10 function
#define CONFIG_GPIO10_FUNC GPIO_FUN_UNUSED
// <q> GPIO11 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio11 function
#define CONFIG_GPIO11_FUNC GPIO_FUN_UNUSED
// <q> GPIO12 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio12 function
#define CONFIG_GPIO12_FUNC GPIO_FUN_UNUSED
// <q> GPIO13 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio13 function
#define CONFIG_GPIO13_FUNC GPIO_FUN_ANALOG
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_ANALOG
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UNUSED
// <q> GPIO16 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio16 function
#define CONFIG_GPIO16_FUNC GPIO_FUN_UART0_TX
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UNUSED
// <q> GPIO18 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio18 function
#define CONFIG_GPIO18_FUNC GPIO_FUN_UNUSED
// <q> GPIO19 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio19 function
#define CONFIG_GPIO19_FUNC GPIO_FUN_UNUSED
// <q> GPIO20 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio20 function
#define CONFIG_GPIO20_FUNC GPIO_FUN_UNUSED
// <q> GPIO21 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio21 function
#define CONFIG_GPIO21_FUNC GPIO_FUN_UNUSED
// <q> GPIO22 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio22 function
#define CONFIG_GPIO22_FUNC GPIO_FUN_UNUSED
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
#endif

View File

@@ -0,0 +1,224 @@
/**
* @file board.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_gpio.h"
#include "hal_clock.h"
#include "bl602_glb.h"
#include "bl602_config.h"
#include "bflb_platform.h"
struct pin_mux_cfg {
uint8_t pin;
uint16_t func;
};
static const struct pin_mux_cfg af_pin_table[] = {
#ifdef CONFIG_GPIO0_FUNC
{ .pin = GPIO_PIN_0,
.func = CONFIG_GPIO0_FUNC },
#endif
#ifdef CONFIG_GPIO1_FUNC
{ .pin = GPIO_PIN_1,
.func = CONFIG_GPIO1_FUNC },
#endif
#ifdef CONFIG_GPIO2_FUNC
{ .pin = GPIO_PIN_2,
.func = CONFIG_GPIO2_FUNC },
#endif
#ifdef CONFIG_GPIO3_FUNC
{ .pin = GPIO_PIN_3,
.func = CONFIG_GPIO3_FUNC },
#endif
#ifdef CONFIG_GPIO4_FUNC
{ .pin = GPIO_PIN_4,
.func = CONFIG_GPIO4_FUNC },
#endif
#ifdef CONFIG_GPIO5_FUNC
{ .pin = GPIO_PIN_5,
.func = CONFIG_GPIO5_FUNC },
#endif
#ifdef CONFIG_GPIO6_FUNC
{ .pin = GPIO_PIN_6,
.func = CONFIG_GPIO6_FUNC },
#endif
#ifdef CONFIG_GPIO7_FUNC
{ .pin = GPIO_PIN_7,
.func = CONFIG_GPIO7_FUNC },
#endif
#ifdef CONFIG_GPIO8_FUNC
{ .pin = GPIO_PIN_8,
.func = CONFIG_GPIO8_FUNC },
#endif
#ifdef CONFIG_GPIO9_FUNC
{ .pin = GPIO_PIN_9,
.func = CONFIG_GPIO9_FUNC },
#endif
#ifdef CONFIG_GPIO10_FUNC
{ .pin = GPIO_PIN_10,
.func = CONFIG_GPIO10_FUNC },
#endif
#ifdef CONFIG_GPIO11_FUNC
{ .pin = GPIO_PIN_11,
.func = CONFIG_GPIO11_FUNC },
#endif
#ifdef CONFIG_GPIO12_FUNC
{ .pin = GPIO_PIN_12,
.func = CONFIG_GPIO12_FUNC },
#endif
#ifdef CONFIG_GPIO13_FUNC
{ .pin = GPIO_PIN_13,
.func = CONFIG_GPIO13_FUNC },
#endif
#ifdef CONFIG_GPIO14_FUNC
{ .pin = GPIO_PIN_14,
.func = CONFIG_GPIO14_FUNC },
#endif
#ifdef CONFIG_GPIO15_FUNC
{ .pin = GPIO_PIN_15,
.func = CONFIG_GPIO15_FUNC },
#endif
#ifdef CONFIG_GPIO16_FUNC
{ .pin = GPIO_PIN_16,
.func = CONFIG_GPIO16_FUNC },
#endif
#ifdef CONFIG_GPIO17_FUNC
{ .pin = GPIO_PIN_17,
.func = CONFIG_GPIO17_FUNC },
#endif
#ifdef CONFIG_GPIO18_FUNC
{ .pin = GPIO_PIN_18,
.func = CONFIG_GPIO18_FUNC },
#endif
#ifdef CONFIG_GPIO19_FUNC
{ .pin = GPIO_PIN_19,
.func = CONFIG_GPIO19_FUNC },
#endif
#ifdef CONFIG_GPIO20_FUNC
{ .pin = GPIO_PIN_20,
.func = CONFIG_GPIO20_FUNC },
#endif
#ifdef CONFIG_GPIO21_FUNC
{ .pin = GPIO_PIN_21,
.func = CONFIG_GPIO21_FUNC },
#endif
#ifdef CONFIG_GPIO22_FUNC
{ .pin = GPIO_PIN_22,
.func = CONFIG_GPIO22_FUNC },
#endif
#ifdef CONFIG_GPIO23_FUNC
{ .pin = GPIO_PIN_23,
.func = CONFIG_GPIO23_FUNC },
#endif
#ifdef CONFIG_GPIO24_FUNC
{ .pin = GPIO_PIN_24,
.func = CONFIG_GPIO24_FUNC },
#endif
#ifdef CONFIG_GPIO25_FUNC
{ .pin = GPIO_PIN_25,
.func = CONFIG_GPIO25_FUNC },
#endif
#ifdef CONFIG_GPIO26_FUNC
{ .pin = GPIO_PIN_26,
.func = CONFIG_GPIO26_FUNC },
#endif
#ifdef CONFIG_GPIO27_FUNC
{ .pin = GPIO_PIN_27,
.func = CONFIG_GPIO27_FUNC },
#endif
#ifdef CONFIG_GPIO28_FUNC
{ .pin = GPIO_PIN_28,
.func = CONFIG_GPIO28_FUNC },
#endif
};
static void board_pin_mux_init(void)
{
GLB_GPIO_Cfg_Type gpio_cfg;
gpio_cfg.drive = 0;
gpio_cfg.smtCtrl = 1;
for (int i = 0; i < sizeof(af_pin_table) / sizeof(af_pin_table[0]); i++) {
gpio_cfg.gpioMode = GPIO_MODE_AF;
gpio_cfg.pullType = GPIO_PULL_UP;
gpio_cfg.gpioPin = af_pin_table[i].pin;
gpio_cfg.gpioFun = af_pin_table[i].func;
if (af_pin_table[i].func == GPIO_FUN_UNUSED) {
continue;
} else if (af_pin_table[i].func == GPIO_FUN_PWM) {
gpio_cfg.pullType = GPIO_PULL_DOWN;
}
// else if((af_pin_table[i].func == GPIO_FUN_DAC)|| (af_pin_table[i].func == GPIO_FUN_ADC))
// {
// gpio_cfg.gpioFun = GPIO_FUN_ANALOG;
// gpio_cfg.gpioMode = GPIO_MODE_ANALOG;
// }
else if ((af_pin_table[i].func & 0x70) == 0x70) {
gpio_cfg.gpioFun = GPIO_FUN_UART;
uint8_t uart_func = af_pin_table[i].func & 0x07;
uint8_t uart_sig = gpio_cfg.gpioPin % 8;
/*link to one uart sig*/
GLB_UART_Fun_Sel((GLB_UART_SIG_Type)uart_sig, (GLB_UART_SIG_FUN_Type)uart_func);
GLB_UART_Fun_Sel((GLB_UART_SIG_Type)uart_func, (GLB_UART_SIG_FUN_Type)uart_sig);
}
GLB_GPIO_Init(&gpio_cfg);
}
}
static void board_clock_init(void)
{
system_clock_init();
peripheral_clock_init();
}
void bl_show_info(void)
{
MSG("\r\n");
MSG(" ____ __ __ _ _ _ \r\n");
MSG(" | _ \\ / _|/ _| | | | | | | \r\n");
MSG(" | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__ \r\n");
MSG(" | _ < / _ \\| | | | _| _/ _` | |/ _ \\| |/ _` | '_ \\ \r\n");
MSG(" | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |\r\n");
MSG(" |____/ \\___/ \\__,_|_| |_| \\__,_|_|\\___/|_|\\__,_|_.__/ \r\n");
MSG("\r\n");
MSG("Build:%s,%s\r\n", __TIME__, __DATE__);
MSG("Copyright (c) 2021 Bouffalolab team\r\n");
#if 0
MSG("root clock:%dM\r\n", system_clock_get(SYSTEM_CLOCK_ROOT_CLOCK) / 1000000);
MSG("fclk clock:%dM\r\n", system_clock_get(SYSTEM_CLOCK_FCLK) / 1000000);
MSG("bclk clock:%dM\r\n", system_clock_get(SYSTEM_CLOCK_BCLK) / 1000000);
MSG("uart clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_UART) / 1000000);
MSG("spi clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_SPI) / 1000000);
MSG("i2c clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_I2C) / 1000000);
#endif
}
void board_init(void)
{
board_clock_init();
board_pin_mux_init();
}

View File

@@ -0,0 +1,89 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_32M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_144M
#define BSP_AUDIO_PLL_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_ROOT_CLOCK_SOURCE)
#define BSP_HCLK_DIV 0
#define BSP_BCLK_DIV 1
#endif
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_UART_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 9
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER0)
#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER0_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER1)
#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER1_CLOCK_DIV 0
#endif
#if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5)
#define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_PWM_CLOCK_DIV 0
#endif
#if defined(BSP_USING_IR)
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_IR_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2S0)
#define BSP_I2S_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_I2S_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 2
#endif
#if defined(BSP_USING_CAM)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3
#endif
#if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) || defined(BSP_USING_KEYSCAN)
#define BSP_QDEC_KEYSCAN_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_QDEC_KEYSCAN_CLOCK_DIV 31
#endif
#endif

View File

@@ -0,0 +1,465 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
//#define BSP_USING_ADC0
//#define BSP_USING_DAC0
#define BSP_USING_UART0
#define BSP_USING_UART1
//#define BSP_USING_SPI0
//#define BSP_USING_I2C0
//#define BSP_USING_I2S0
#define BSP_USING_USB
//#define BSP_USING_PWM_CH2
//#define BSP_USING_TIMER0
//#define BSP_USING_TIMER1
//#define BSP_USING_CAM
//#define BSP_USING_KEYSCAN
//#define BSP_USING_QDEC0
//#define BSP_USING_QDEC1
//#define BSP_USING_QDEC2
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32, \
.vref = ADC_VREF_3V2, \
.continuous_conv_mode = DISABLE, \
.differential_mode = DISABLE, \
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE, \
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE, \
.gain = ADC_GAIN_1 \
}
#endif
#endif
#if defined(BSP_USING_DAC0)
#ifndef DAC_CONFIG
#define DAC_CONFIG \
{ \
.channels = DAC_CHANNEL_0, \
.sample_freq = DAC_SAMPLE_FREQ_500KHZ, \
.vref = DAC_VREF_INTERNAL, \
}
#endif
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 1, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 64, \
}
#endif
#endif
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 36000000, \
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 4, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH0)
#ifndef PWM_CH0_CONFIG
#define PWM_CH0_CONFIG \
{ \
.ch = 0, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH1)
#ifndef PWM_CH1_CONFIG
#define PWM_CH1_CONFIG \
{ \
.ch = 1, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH3)
#ifndef PWM_CH3_CONFIG
#define PWM_CH3_CONFIG \
{ \
.ch = 3, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_I2S0)
#ifndef I2S0_CONFIG
#define I2S0_CONFIG \
{ \
.id = 0, \
.iis_mode = I2S_MODE_MASTER, \
.interface_mode = I2S_MODE_LEFT, \
.sampl_freq_hz = 16 * 1000, \
.channel_num = I2S_FS_CHANNELS_NUM_MONO, \
.frame_size = I2S_FRAME_LEN_16, \
.data_size = I2S_DATA_LEN_16, \
.fifo_threshold = 8, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE, \
.phase = 15, \
}
#endif
#endif
#if defined(BSP_USING_TIMER0)
#ifndef TIMER0_CONFIG
#define TIMER0_CONFIG \
{ \
.id = 0, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP2, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_TIMER1)
#ifndef TIMER1_CONFIG
#define TIMER1_CONFIG \
{ \
.id = 1, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP0, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_KEYSCAN)
#ifndef KEYSCAN_CONFIG
#define KEYSCAN_CONFIG \
{ \
.col_num = COL_NUM_4, \
.row_num = ROW_NUM_4, \
.deglitch_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC0)
#ifndef QDEC0_CONFIG
#define QDEC0_CONFIG \
{ \
.id = 0, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC1)
#ifndef QDEC1_CONFIG
#define QDEC1_CONFIG \
{ \
.id = 1, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC2)
#ifndef QDEC2_CONFIG
#define QDEC2_CONFIG \
{ \
.id = 2, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,152 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_UNUSED
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_UNUSED
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_UNUSED
// <q> GPIO3 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_QDEC]
// <i> config gpio3 function
#define CONFIG_GPIO3_FUNC GPIO_FUN_UNUSED
// <q> GPIO4 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio4 function
#define CONFIG_GPIO4_FUNC GPIO_FUN_UNUSED
// <q> GPIO5 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_QDEC]
// <i> config gpio5 function
#define CONFIG_GPIO5_FUNC GPIO_FUN_UNUSED
// <q> GPIO6 <2> [GPIO_FUN_UNUSED//GPIO_FUN_CLK_OUT//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_QDEC]
// <i> config gpio6 function
#define CONFIG_GPIO6_FUNC GPIO_FUN_UNUSED
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_USB
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_USB
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_UNUSED
// <q> GPIO10 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio10 function
#define CONFIG_GPIO10_FUNC GPIO_FUN_UNUSED
// <q> GPIO11 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio11 function
#define CONFIG_GPIO11_FUNC GPIO_FUN_UNUSED
// <q> GPIO12 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio12 function
#define CONFIG_GPIO12_FUNC GPIO_FUN_UNUSED
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
// <q> GPIO16 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio16 function
#define CONFIG_GPIO16_FUNC GPIO_FUN_UNUSED
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UART1_TX
// <q> GPIO18 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio18 function
#define CONFIG_GPIO18_FUNC GPIO_FUN_UNUSED
// <q> GPIO19 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio19 function
#define CONFIG_GPIO19_FUNC GPIO_FUN_UNUSED
// <q> GPIO20 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio20 function
#define CONFIG_GPIO20_FUNC GPIO_FUN_UNUSED
// <q> GPIO21 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio21 function
#define CONFIG_GPIO21_FUNC GPIO_FUN_UNUSED
// <q> GPIO22 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio22 function
#define CONFIG_GPIO22_FUNC GPIO_FUN_UNUSED
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
// <q> GPIO29 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio29 function
#define CONFIG_GPIO29_FUNC GPIO_FUN_UNUSED
// <q> GPIO30 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio30 function
#define CONFIG_GPIO30_FUNC GPIO_FUN_UNUSED
// <q> GPIO31 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio31 function
#define CONFIG_GPIO31_FUNC GPIO_FUN_UNUSED
#endif

View File

@@ -0,0 +1,51 @@
/**
* @file bl702_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __BL702_CONFIG_H__
#define __BL702_CONFIG_H__
#if defined(bl706_avb)
#include "bl706_avb/peripheral_config.h"
#include "bl706_avb/clock_config.h"
#include "bl706_avb/pinmux_config.h"
#elif defined(bl706_iot)
#include "bl706_iot/peripheral_config.h"
#include "bl706_iot/clock_config.h"
#include "bl706_iot/pinmux_config.h"
#elif defined(bl706_lp)
#include "bl706_lp/peripheral_config.h"
#include "bl706_lp/clock_config.h"
#include "bl706_lp/pinmux_config.h"
#elif defined(bl702_boot2)
#include "bl702_boot2/peripheral_config.h"
#include "bl702_boot2/clock_config.h"
#include "bl702_boot2/pinmux_config.h"
#elif defined(bl702_iot)
#include "bl702_iot/peripheral_config.h"
#include "bl702_iot/clock_config.h"
#include "bl702_iot/pinmux_config.h"
#else
#error "do not find board,please check your board name"
#endif
#endif

View File

@@ -0,0 +1,84 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_32M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_144M
#define BSP_AUDIO_PLL_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_UART_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 0
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER0)
#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER0_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER1)
#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER1_CLOCK_DIV 0
#endif
#if defined(BSP_USING_WDT)
#define BSP_WDT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_WDT_CLOCK_DIV 0
#endif
#if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5)
#define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK
#define BSP_PWM_CLOCK_DIV 31
#endif
#if defined(BSP_USING_IR)
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_IR_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 2
#endif
#if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3
#endif
#if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) || defined(BSP_USING_KEYSCAN)
#define BSP_QDEC_KEYSCAN_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_QDEC_KEYSCAN_CLOCK_DIV 31
#endif
#endif

View File

@@ -0,0 +1,499 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
#define BSP_USING_ADC0
#define BSP_USING_DAC0
#define BSP_USING_UART0
#define BSP_USING_UART1
#define BSP_USING_SPI0
#define BSP_USING_I2C0
#define BSP_USING_I2S0
#define BSP_USING_PWM_CH0
#define BSP_USING_PWM_CH1
#define BSP_USING_PWM_CH2
#define BSP_USING_PWM_CH3
#define BSP_USING_PWM_CH4
#define BSP_USING_TIMER0
#define BSP_USING_TIMER1
#define BSP_USING_WDT
#define BSP_USING_KEYSCAN
#define BSP_USING_QDEC0
#define BSP_USING_QDEC1
#define BSP_USING_QDEC2
#define BSP_USING_USB
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32, \
.vref = ADC_VREF_3V2, \
.continuous_conv_mode = DISABLE, \
.differential_mode = DISABLE, \
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE, \
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE, \
.gain = ADC_GAIN_1 \
}
#endif
#endif
#if defined(BSP_USING_DAC0)
#ifndef DAC_CONFIG
#define DAC_CONFIG \
{ \
.channels = DAC_CHANNEL_0, \
.sample_freq = DAC_SAMPLE_FREQ_500KHZ, \
.vref = DAC_VREF_INTERNAL, \
}
#endif
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 0, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 63, \
}
#endif
#endif
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 18000000, \
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 1, \
.pin_swap_enable = 1, \
.delitch_cnt = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH0)
#ifndef PWM_CH0_CONFIG
#define PWM_CH0_CONFIG \
{ \
.ch = 0, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH1)
#ifndef PWM_CH1_CONFIG
#define PWM_CH1_CONFIG \
{ \
.ch = 1, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH3)
#ifndef PWM_CH3_CONFIG
#define PWM_CH3_CONFIG \
{ \
.ch = 3, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH4)
#ifndef PWM_CH4_CONFIG
#define PWM_CH4_CONFIG \
{ \
.ch = 4, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_I2S0)
#ifndef I2S0_CONFIG
#define I2S0_CONFIG \
{ \
.id = 0, \
.iis_mode = I2S_MODE_MASTER, \
.interface_mode = I2S_MODE_LEFT, \
.sampl_freq_hz = 16 * 1000, \
.channel_num = I2S_FS_CHANNELS_NUM_MONO, \
.frame_size = I2S_FRAME_LEN_16, \
.data_size = I2S_DATA_LEN_16, \
.fifo_threshold = 8, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE, \
.phase = 15, \
}
#endif
#endif
#if defined(BSP_USING_TIMER0)
#ifndef TIMER0_CONFIG
#define TIMER0_CONFIG \
{ \
.id = 0, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP2, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_TIMER1)
#ifndef TIMER1_CONFIG
#define TIMER1_CONFIG \
{ \
.id = 1, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP0, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_WDT)
#ifndef WDT_CONFIG
#define WDT_CONFIG \
{ \
.id = 0, \
.wdt_timeout = 6000, \
}
#endif
#endif
#if defined(BSP_USING_KEYSCAN)
#ifndef KEYSCAN_CONFIG
#define KEYSCAN_CONFIG \
{ \
.col_num = COL_NUM_4, \
.row_num = ROW_NUM_4, \
.deglitch_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC0)
#ifndef QDEC0_CONFIG
#define QDEC0_CONFIG \
{ \
.id = 0, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC1)
#ifndef QDEC1_CONFIG
#define QDEC1_CONFIG \
{ \
.id = 1, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC2)
#ifndef QDEC2_CONFIG
#define QDEC2_CONFIG \
{ \
.id = 2, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,88 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_UNUSED
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_UNUSED
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_UNUSED
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_USB
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_USB
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_UNUSED
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UNUSED
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_USB//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
#endif

View File

@@ -0,0 +1,88 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_32M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_144M
#define BSP_AUDIO_PLL_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_UART_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 9
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER0)
#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER0_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER1)
#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER1_CLOCK_DIV 0
#endif
#if defined(BSP_USING_WDT)
#define BSP_WDT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_WDT_CLOCK_DIV 0
#endif
#if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5)
#define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_PWM_CLOCK_DIV 0
#endif
#if defined(BSP_USING_IR)
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_IR_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2S0)
#define BSP_I2S_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_I2S_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 2
#endif
#if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3
#endif
#if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) || defined(BSP_USING_KEYSCAN)
#define BSP_QDEC_KEYSCAN_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_QDEC_KEYSCAN_CLOCK_DIV 31
#endif
#endif

View File

@@ -0,0 +1,518 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
#define BSP_USING_ADC0
#define BSP_USING_DAC0
#define BSP_USING_UART0
#define BSP_USING_UART1
#define BSP_USING_SPI0
#define BSP_USING_I2C0
#define BSP_USING_I2S0
#define BSP_USING_PWM_CH0
#define BSP_USING_PWM_CH1
#define BSP_USING_PWM_CH2
#define BSP_USING_PWM_CH3
#define BSP_USING_PWM_CH4
#define BSP_USING_TIMER0
#define BSP_USING_TIMER1
#define BSP_USING_WDT
#define BSP_USING_KEYSCAN
#define BSP_USING_QDEC0
#define BSP_USING_QDEC1
#define BSP_USING_QDEC2
#define BSP_USING_USB
#define BSP_USING_CAM0
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32, \
.vref = ADC_VREF_3V2, \
.continuous_conv_mode = DISABLE, \
.differential_mode = DISABLE, \
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE, \
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE, \
.gain = ADC_GAIN_1 \
}
#endif
#endif
#if defined(BSP_USING_DAC0)
#ifndef DAC_CONFIG
#define DAC_CONFIG \
{ \
.channels = DAC_CHANNEL_0, \
.sample_freq = DAC_SAMPLE_FREQ_500KHZ, \
.vref = DAC_VREF_INTERNAL, \
}
#endif
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 0, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 63, \
}
#endif
#endif
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 36000000, \
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 3, \
.pin_swap_enable = 1, \
.delitch_cnt = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH0)
#ifndef PWM_CH0_CONFIG
#define PWM_CH0_CONFIG \
{ \
.ch = 0, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH1)
#ifndef PWM_CH1_CONFIG
#define PWM_CH1_CONFIG \
{ \
.ch = 1, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH3)
#ifndef PWM_CH3_CONFIG
#define PWM_CH3_CONFIG \
{ \
.ch = 3, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH4)
#ifndef PWM_CH4_CONFIG
#define PWM_CH4_CONFIG \
{ \
.ch = 4, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_I2S0)
#ifndef I2S0_CONFIG
#define I2S0_CONFIG \
{ \
.id = 0, \
.iis_mode = I2S_MODE_MASTER, \
.interface_mode = I2S_MODE_LEFT, \
.sampl_freq_hz = 16 * 1000, \
.channel_num = I2S_FS_CHANNELS_NUM_MONO, \
.frame_size = I2S_FRAME_LEN_16, \
.data_size = I2S_DATA_LEN_16, \
.fifo_threshold = 7, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE, \
.phase = 15, \
}
#endif
#endif
#if defined(BSP_USING_TIMER0)
#ifndef TIMER0_CONFIG
#define TIMER0_CONFIG \
{ \
.id = 0, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP2, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_TIMER1)
#ifndef TIMER1_CONFIG
#define TIMER1_CONFIG \
{ \
.id = 1, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP0, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_WDT)
#ifndef WDT_CONFIG
#define WDT_CONFIG \
{ \
.id = 0, \
.wdt_timeout = 6000, \
}
#endif
#endif
#if defined(BSP_USING_KEYSCAN)
#ifndef KEYSCAN_CONFIG
#define KEYSCAN_CONFIG \
{ \
.col_num = COL_NUM_4, \
.row_num = ROW_NUM_4, \
.deglitch_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC0)
#ifndef QDEC0_CONFIG
#define QDEC0_CONFIG \
{ \
.id = 0, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC1)
#ifndef QDEC1_CONFIG
#define QDEC1_CONFIG \
{ \
.id = 1, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC2)
#ifndef QDEC2_CONFIG
#define QDEC2_CONFIG \
{ \
.id = 2, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_CAM0)
#ifndef CAM0_CONFIG
#define CAM0_CONFIG \
{ \
.id = 0, \
.software_mode = CAM_AUTO_MODE, \
.frame_mode = CAM_FRAME_INTERLEAVE_MODE, \
.yuv_format = CAM_YUV_FORMAT_YUV422, \
.hsp = CAM_HSPOLARITY_LOW, \
.vsp = CAM_VSPOLARITY_LOW, \
.cam_write_ram_addr = 0, \
.cam_write_ram_size = 0, \
.cam_frame_size = 0, \
.cam_write_ram_addr1 = 0, \
.cam_write_ram_size1 = 0, \
.cam_frame_size1 = 0, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,152 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_CAM
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_CAM
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_CAM
// <q> GPIO3 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_QDEC]
// <i> config gpio3 function
#define CONFIG_GPIO3_FUNC GPIO_FUN_CAM
// <q> GPIO4 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio4 function
#define CONFIG_GPIO4_FUNC GPIO_FUN_CAM
// <q> GPIO5 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_QDEC]
// <i> config gpio5 function
#define CONFIG_GPIO5_FUNC GPIO_FUN_CAM
// <q> GPIO6 <2> [GPIO_FUN_UNUSED//GPIO_FUN_CLK_OUT//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_QDEC]
// <i> config gpio6 function
#define CONFIG_GPIO6_FUNC GPIO_FUN_CAM
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_USB
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_USB
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_CLK_OUT
// <q> GPIO10 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio10 function
#define CONFIG_GPIO10_FUNC GPIO_FUN_UNUSED
// <q> GPIO11 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio11 function
#define CONFIG_GPIO11_FUNC GPIO_FUN_I2C
// <q> GPIO12 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio12 function
#define CONFIG_GPIO12_FUNC GPIO_FUN_CAM
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
// <q> GPIO16 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio16 function
#define CONFIG_GPIO16_FUNC GPIO_FUN_I2C
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UNUSED
// <q> GPIO18 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio18 function
#define CONFIG_GPIO18_FUNC GPIO_FUN_ADC
// <q> GPIO19 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio19 function
#define CONFIG_GPIO19_FUNC GPIO_FUN_SPI
// <q> GPIO20 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio20 function
#define CONFIG_GPIO20_FUNC GPIO_FUN_SPI
// <q> GPIO21 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio21 function
#define CONFIG_GPIO21_FUNC GPIO_FUN_SPI
// <q> GPIO22 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio22 function
#define CONFIG_GPIO22_FUNC GPIO_FUN_UNUSED
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
// <q> GPIO29 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio29 function
#define CONFIG_GPIO29_FUNC GPIO_FUN_CAM
// <q> GPIO30 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio30 function
#define CONFIG_GPIO30_FUNC GPIO_FUN_CAM
// <q> GPIO31 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio31 function
#define CONFIG_GPIO31_FUNC GPIO_FUN_CAM
#endif

View File

@@ -0,0 +1,84 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_32M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_144M
#define BSP_AUDIO_PLL_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_UART_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 0
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER0)
#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER0_CLOCK_DIV 0
#endif
#if defined(BSP_USING_TIMER1)
#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_TIMER1_CLOCK_DIV 0
#endif
#if defined(BSP_USING_WDT)
#define BSP_WDT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
#define BSP_WDT_CLOCK_DIV 0
#endif
#if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5)
#define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK
#define BSP_PWM_CLOCK_DIV 31
#endif
#if defined(BSP_USING_IR)
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_IR_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 2
#endif
#if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3
#endif
#if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) || defined(BSP_USING_KEYSCAN)
#define BSP_QDEC_KEYSCAN_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_QDEC_KEYSCAN_CLOCK_DIV 31
#endif
#endif

View File

@@ -0,0 +1,499 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
#define BSP_USING_ADC0
#define BSP_USING_DAC0
#define BSP_USING_UART0
#define BSP_USING_UART1
#define BSP_USING_SPI0
#define BSP_USING_I2C0
#define BSP_USING_I2S0
#define BSP_USING_PWM_CH0
#define BSP_USING_PWM_CH1
#define BSP_USING_PWM_CH2
#define BSP_USING_PWM_CH3
#define BSP_USING_PWM_CH4
#define BSP_USING_TIMER0
#define BSP_USING_TIMER1
#define BSP_USING_WDT
#define BSP_USING_KEYSCAN
#define BSP_USING_QDEC0
#define BSP_USING_QDEC1
#define BSP_USING_QDEC2
#define BSP_USING_USB
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32, \
.vref = ADC_VREF_3V2, \
.continuous_conv_mode = DISABLE, \
.differential_mode = DISABLE, \
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE, \
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE, \
.gain = ADC_GAIN_1 \
}
#endif
#endif
#if defined(BSP_USING_DAC0)
#ifndef DAC_CONFIG
#define DAC_CONFIG \
{ \
.channels = DAC_CHANNEL_0, \
.sample_freq = DAC_SAMPLE_FREQ_500KHZ, \
.vref = DAC_VREF_INTERNAL, \
}
#endif
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 0, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 63, \
}
#endif
#endif
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 18000000, \
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 0, \
.pin_swap_enable = 1, \
.delitch_cnt = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH0)
#ifndef PWM_CH0_CONFIG
#define PWM_CH0_CONFIG \
{ \
.ch = 0, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH1)
#ifndef PWM_CH1_CONFIG
#define PWM_CH1_CONFIG \
{ \
.ch = 1, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH3)
#ifndef PWM_CH3_CONFIG
#define PWM_CH3_CONFIG \
{ \
.ch = 3, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH4)
#ifndef PWM_CH4_CONFIG
#define PWM_CH4_CONFIG \
{ \
.ch = 4, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_I2S0)
#ifndef I2S0_CONFIG
#define I2S0_CONFIG \
{ \
.id = 0, \
.iis_mode = I2S_MODE_MASTER, \
.interface_mode = I2S_MODE_LEFT, \
.sampl_freq_hz = 16 * 1000, \
.channel_num = I2S_FS_CHANNELS_NUM_MONO, \
.frame_size = I2S_FRAME_LEN_16, \
.data_size = I2S_DATA_LEN_16, \
.fifo_threshold = 7, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE, \
.phase = 15, \
}
#endif
#endif
#if defined(BSP_USING_TIMER0)
#ifndef TIMER0_CONFIG
#define TIMER0_CONFIG \
{ \
.id = 0, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP2, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_TIMER1)
#ifndef TIMER1_CONFIG
#define TIMER1_CONFIG \
{ \
.id = 1, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.trigger = TIMER_PRELOAD_TRIGGER_COMP0, \
.reload = 0, \
.timeout1 = 1000000, \
.timeout2 = 2000000, \
.timeout3 = 3000000, \
}
#endif
#endif
#if defined(BSP_USING_WDT)
#ifndef WDT_CONFIG
#define WDT_CONFIG \
{ \
.id = 0, \
.wdt_timeout = 6000, \
}
#endif
#endif
#if defined(BSP_USING_KEYSCAN)
#ifndef KEYSCAN_CONFIG
#define KEYSCAN_CONFIG \
{ \
.col_num = COL_NUM_4, \
.row_num = ROW_NUM_4, \
.deglitch_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC0)
#ifndef QDEC0_CONFIG
#define QDEC0_CONFIG \
{ \
.id = 0, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC1)
#ifndef QDEC1_CONFIG
#define QDEC1_CONFIG \
{ \
.id = 1, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#if defined(BSP_USING_QDEC2)
#ifndef QDEC2_CONFIG
#define QDEC2_CONFIG \
{ \
.id = 2, \
.acc_mode = QDEC_ACC_CONTINUE_ACCUMULATE, \
.sample_mode = QDEC_SAMPLE_SINGLE_MOD, \
.sample_period = QDEC_SAMPLE_PERIOD_256US, \
.report_mode = QDEC_REPORT_TIME_MOD, \
.report_period = 2000, \
.led_en = ENABLE, \
.led_swap = DISABLE, \
.led_period = 7, \
.deglitch_en = DISABLE, \
.deglitch_strength = 0x0, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,152 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_UNUSED
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_UNUSED
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC_LED]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_UNUSED
// <q> GPIO3 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_QDEC]
// <i> config gpio3 function
#define CONFIG_GPIO3_FUNC GPIO_FUN_I2S
// <q> GPIO4 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio4 function
#define CONFIG_GPIO4_FUNC GPIO_FUN_I2S
// <q> GPIO5 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_QDEC_LED]
// <i> config gpio5 function
#define CONFIG_GPIO5_FUNC GPIO_FUN_UNUSED
// <q> GPIO6 <2> [GPIO_FUN_UNUSED//GPIO_FUN_CLK_OUT//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_QDEC]
// <i> config gpio6 function
#define CONFIG_GPIO6_FUNC GPIO_FUN_CLK_OUT
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_USB
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC_LED]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_USB
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_UNUSED
// <q> GPIO10 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio10 function
#define CONFIG_GPIO10_FUNC GPIO_FUN_UNUSED
// <q> GPIO11 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC_LED]
// <i> config gpio11 function
#define CONFIG_GPIO11_FUNC GPIO_FUN_I2C
// <q> GPIO12 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio12 function
#define CONFIG_GPIO12_FUNC GPIO_FUN_ADC
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC_LED]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
// <q> GPIO16 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio16 function
#define CONFIG_GPIO16_FUNC GPIO_FUN_I2C
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC_LED]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UNUSED
// <q> GPIO18 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio18 function
#define CONFIG_GPIO18_FUNC GPIO_FUN_UNUSED
// <q> GPIO19 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio19 function
#define CONFIG_GPIO19_FUNC GPIO_FUN_SPI
// <q> GPIO20 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC_LED]
// <i> config gpio20 function
#define CONFIG_GPIO20_FUNC GPIO_FUN_SPI
// <q> GPIO21 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio21 function
#define CONFIG_GPIO21_FUNC GPIO_FUN_SPI
// <q> GPIO22 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio22 function
#define CONFIG_GPIO22_FUNC GPIO_FUN_PWM
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC_LED]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC_LED]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
// <q> GPIO29 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC_LED]
// <i> config gpio29 function
#define CONFIG_GPIO29_FUNC GPIO_FUN_I2S
// <q> GPIO30 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio30 function
#define CONFIG_GPIO30_FUNC GPIO_FUN_I2S
// <q> GPIO31 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio31 function
#define CONFIG_GPIO31_FUNC GPIO_FUN_UNUSED
#endif

View File

@@ -0,0 +1,72 @@
/**
* @file clock_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _CLOCK_CONFIG_H
#define _CLOCK_CONFIG_H
#define XTAL_TYPE EXTERNAL_XTAL_32M
#define XTAL_32K_TYPE INTERNAL_RC_32K
#define BSP_ROOT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_144M
#define BSP_AUDIO_PLL_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_FCLK_DIV 0
#define BSP_BCLK_DIV 1
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)
#define BSP_UART_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_UART_CLOCK_DIV 0
#endif
#if defined(BSP_USING_I2C0)
#define BSP_I2C_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_I2C_CLOCK_DIV 0
#endif
#if defined(BSP_USING_SPI0)
#define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK
#define BSP_SPI_CLOCK_DIV 0
#endif
#if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5)
#define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK
#define BSP_PWM_CLOCK_DIV 32
#endif
#if defined(BSP_USING_IR)
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_IR_CLOCK_DIV 0
#endif
#if defined(BSP_USING_ADC0)
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0
#endif
#if defined(BSP_USING_DAC0)
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 1
#endif
#if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3
#endif
#if defined(BSP_USING_QDEC) || defined(BSP_USING_KEYSCAN)
#define BSP_QDEC_KEYSCAN_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_QDEC_KEYSCAN_CLOCK_DIV 0
#endif
#endif

View File

@@ -0,0 +1,380 @@
/**
* @file peripheral_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PERIPHERAL_CONFIG_H_
#define _PERIPHERAL_CONFIG_H_
/* PERIPHERAL USING LIST */
#define BSP_USING_UART0
/* ----------------------*/
/* PERIPHERAL With DMA LIST */
#define BSP_USING_DMA0_CH0
#define BSP_USING_DMA0_CH1
#define BSP_USING_DMA0_CH2
#define BSP_USING_DMA0_CH3
#define BSP_USING_DMA0_CH4
#define BSP_USING_DMA0_CH5
#define BSP_USING_DMA0_CH6
#define BSP_USING_DMA0_CH7
/* PERIPHERAL CONFIG */
#if defined(BSP_USING_ADC0)
#ifndef ADC0_CONFIG
#define ADC0_CONFIG \
{ \
.clk_div = ADC_CLOCK_DIV_32, \
.vref = ADC_VREF_3V2, \
.continuous_conv_mode = DISABLE, \
.differential_mode = DISABLE, \
.data_width = ADC_DATA_WIDTH_16B_WITH_256_AVERAGE, \
.fifo_threshold = ADC_FIFO_THRESHOLD_1BYTE, \
.gain = ADC_GAIN_1 \
}
#endif
#endif
#if defined(BSP_USING_DAC0)
#ifndef DAC_CONFIG
#define DAC_CONFIG \
{ \
.channels = DAC_CHANNEL_0, \
.sample_freq = DAC_SAMPLE_FREQ_500KHZ, \
.vref = DAC_VREF_INTERNAL, \
}
#endif
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 0, \
}
#endif
#endif
#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \
{ \
.id = 1, \
.baudrate = 2000000, \
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 63, \
}
#endif
#endif
#if defined(BSP_USING_SPI0)
#ifndef SPI0_CONFIG
#define SPI0_CONFIG \
{ \
.id = 0, \
.clk = 18000000, \
.mode = SPI_MASTER_MODE, \
.direction = SPI_MSB_BYTE0_DIRECTION_FIRST, \
.clk_polaraity = SPI_POLARITY_LOW, \
.clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH0)
#ifndef PWM_CH0_CONFIG
#define PWM_CH0_CONFIG \
{ \
.ch = 0, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH1)
#ifndef PWM_CH1_CONFIG
#define PWM_CH1_CONFIG \
{ \
.ch = 1, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH2)
#ifndef PWM_CH2_CONFIG
#define PWM_CH2_CONFIG \
{ \
.ch = 2, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_PWM_CH3)
#ifndef PWM_CH3_CONFIG
#define PWM_CH3_CONFIG \
{ \
.ch = 3, \
.polarity_invert_mode = DISABLE, \
.period = 0, \
.threshold_low = 0, \
.threshold_high = 0, \
.it_pulse_count = 0, \
}
#endif
#endif
#if defined(BSP_USING_I2S0)
#ifndef I2S0_CONFIG
#define I2S0_CONFIG \
{ \
.id = 0, \
.iis_mode = I2S_MODE_MASTER, \
.interface_mode = I2S_MODE_LEFT, \
.sampl_freq_hz = 16 * 1000, \
.channel_num = I2S_FS_CHANNELS_NUM_MONO, \
.frame_size = I2S_FRAME_LEN_16, \
.data_size = I2S_DATA_LEN_16, \
.fifo_threshold = 7, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH0)
#ifndef DMA0_CH0_CONFIG
#define DMA0_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH1)
#ifndef DMA0_CH1_CONFIG
#define DMA0_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_4BYTE, \
.dst_burst_size = DMA_BURST_4BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH2)
#ifndef DMA0_CH2_CONFIG
#define DMA0_CH2_CONFIG \
{ \
.id = 0, \
.ch = 2, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_UART1_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH3)
#ifndef DMA0_CH3_CONFIG
#define DMA0_CH3_CONFIG \
{ \
.id = 0, \
.ch = 3, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_SPI0_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH4)
#ifndef DMA0_CH4_CONFIG
#define DMA0_CH4_CONFIG \
{ \
.id = 0, \
.ch = 4, \
.direction = DMA_PERIPH_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_SPI0_RX, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_8BIT, \
.dst_width = DMA_TRANSFER_WIDTH_8BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH5)
#ifndef DMA0_CH5_CONFIG
#define DMA0_CH5_CONFIG \
{ \
.id = 0, \
.ch = 5, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH6)
#ifndef DMA0_CH6_CONFIG
#define DMA0_CH6_CONFIG \
{ \
.id = 0, \
.ch = 6, \
.direction = DMA_MEMORY_TO_PERIPH, \
.transfer_mode = DMA_LLI_CYCLE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_I2S_TX, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_16BIT, \
.dst_width = DMA_TRANSFER_WIDTH_16BIT, \
}
#endif
#endif
#if defined(BSP_USING_DMA0_CH7)
#ifndef DMA0_CH7_CONFIG
#define DMA0_CH7_CONFIG \
{ \
.id = 0, \
.ch = 7, \
.direction = DMA_MEMORY_TO_MEMORY, \
.transfer_mode = DMA_LLI_ONCE_MODE, \
.src_req = DMA_REQUEST_NONE, \
.dst_req = DMA_REQUEST_NONE, \
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE, \
.src_burst_size = DMA_BURST_1BYTE, \
.dst_burst_size = DMA_BURST_1BYTE, \
.src_width = DMA_TRANSFER_WIDTH_32BIT, \
.dst_width = DMA_TRANSFER_WIDTH_32BIT, \
}
#endif
#endif
#if defined(BSP_USING_I2C0)
#ifndef I2C0_CONFIG
#define I2C0_CONFIG \
{ \
.id = 0, \
.mode = I2C_HW_MODE, \
.phase = 15, \
}
#endif
#endif
#if defined(BSP_USING_TIMER_CH0)
#ifndef TIMER_CH0_CONFIG
#define TIMER_CH0_CONFIG \
{ \
.id = 0, \
.ch = 0, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.pl_trig_src = TIMER_PL_TRIG_COMP0, \
}
#endif
#endif
#if defined(BSP_USING_TIMER_CH1)
#ifndef TIMER_CH1_CONFIG
#define TIMER_CH1_CONFIG \
{ \
.id = 0, \
.ch = 1, \
.cnt_mode = TIMER_CNT_PRELOAD, \
.pl_trig_src = TIMER_PL_TRIG_COMP2, \
}
#endif
#endif
#endif

View File

@@ -0,0 +1,152 @@
/**
* @file pinmux_config.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _PINMUX_CONFIG_H
#define _PINMUX_CONFIG_H
// <<< Use Configuration Wizard in Context Menu >>>
// <q> GPIO0 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio0 function
#define CONFIG_GPIO0_FUNC GPIO_FUN_UNUSED
// <q> GPIO1 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio1 function
#define CONFIG_GPIO1_FUNC GPIO_FUN_UNUSED
// <q> GPIO2 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio2 function
#define CONFIG_GPIO2_FUNC GPIO_FUN_UNUSED
// <q> GPIO3 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_QDEC]
// <i> config gpio3 function
#define CONFIG_GPIO3_FUNC GPIO_FUN_UNUSED
// <q> GPIO4 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio4 function
#define CONFIG_GPIO4_FUNC GPIO_FUN_UNUSED
// <q> GPIO5 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_CTS//GPIO_FUN_UART1_CTS//GPIO_FUN_QDEC]
// <i> config gpio5 function
#define CONFIG_GPIO5_FUNC GPIO_FUN_UNUSED
// <q> GPIO6 <2> [GPIO_FUN_UNUSED//GPIO_FUN_CLK_OUT//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_TX//GPIO_FUN_UART1_TX//GPIO_FUN_QDEC]
// <i> config gpio6 function
#define CONFIG_GPIO6_FUNC GPIO_FUN_WAKEUP
// <q> GPIO7 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RX//GPIO_FUN_UART1_RX//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio7 function
#define CONFIG_GPIO7_FUNC GPIO_FUN_UNUSED
// <q> GPIO8 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_USB//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio8 function
#define CONFIG_GPIO8_FUNC GPIO_FUN_UNUSED
// <q> GPIO9 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio9 function
#define CONFIG_GPIO9_FUNC GPIO_FUN_UNUSED
// <q> GPIO10 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio10 function
#define CONFIG_GPIO10_FUNC GPIO_FUN_GPIO_EXTI_FALLING_EDGE
// <q> GPIO11 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio11 function
#define CONFIG_GPIO11_FUNC GPIO_FUN_ADC
// <q> GPIO12 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio12 function
#define CONFIG_GPIO12_FUNC GPIO_FUN_WAKEUP
// <q> GPIO14 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio14 function
#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
// <q> GPIO15 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio15 function
#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
// <q> GPIO16 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio16 function
#define CONFIG_GPIO16_FUNC GPIO_FUN_UNUSED
// <q> GPIO17 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio17 function
#define CONFIG_GPIO17_FUNC GPIO_FUN_UNUSED
// <q> GPIO18 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio18 function
#define CONFIG_GPIO18_FUNC GPIO_FUN_UNUSED
// <q> GPIO19 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio19 function
#define CONFIG_GPIO19_FUNC GPIO_FUN_UNUSED
// <q> GPIO20 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio20 function
#define CONFIG_GPIO20_FUNC GPIO_FUN_UNUSED
// <q> GPIO21 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ADC//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio21 function
#define CONFIG_GPIO21_FUNC GPIO_FUN_UNUSED
// <q> GPIO22 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio22 function
#define CONFIG_GPIO22_FUNC GPIO_FUN_UNUSED
// <q> GPIO23 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_ANALOG//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio23 function
#define CONFIG_GPIO23_FUNC GPIO_FUN_UNUSED
// <q> GPIO24 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio24 function
#define CONFIG_GPIO24_FUNC GPIO_FUN_UNUSED
// <q> GPIO25 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio25 function
#define CONFIG_GPIO25_FUNC GPIO_FUN_UNUSED
// <q> GPIO26 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio26 function
#define CONFIG_GPIO26_FUNC GPIO_FUN_UNUSED
// <q> GPIO27 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio27 function
#define CONFIG_GPIO27_FUNC GPIO_FUN_UNUSED
// <q> GPIO28 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_ETHER_MAC//GPIO_FUN_QDEC]
// <i> config gpio28 function
#define CONFIG_GPIO28_FUNC GPIO_FUN_UNUSED
// <q> GPIO29 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio29 function
#define CONFIG_GPIO29_FUNC GPIO_FUN_UNUSED
// <q> GPIO30 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio30 function
#define CONFIG_GPIO30_FUNC GPIO_FUN_UNUSED
// <q> GPIO31 <2> [GPIO_FUN_UNUSED//GPIO_FUN_I2S//GPIO_FUN_SPI//GPIO_FUN_I2C//GPIO_FUN_PWM//GPIO_FUN_CAM//GPIO_FUN_UART0_RTS//GPIO_FUN_UART1_RTS//GPIO_FUN_QDEC]
// <i> config gpio31 function
#define CONFIG_GPIO31_FUNC GPIO_FUN_UNUSED
#endif

View File

@@ -0,0 +1,329 @@
/**
* @file board.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_gpio.h"
#include "hal_clock.h"
#include "bl702_glb.h"
#include "bl702_config.h"
#include "bflb_platform.h"
struct pin_mux_cfg {
uint8_t pin;
uint16_t func;
};
static const struct pin_mux_cfg af_pin_table[] = {
#ifdef CONFIG_GPIO0_FUNC
{ .pin = GPIO_PIN_0,
.func = CONFIG_GPIO0_FUNC },
#endif
#ifdef CONFIG_GPIO1_FUNC
{ .pin = GPIO_PIN_1,
.func = CONFIG_GPIO1_FUNC },
#endif
#ifdef CONFIG_GPIO2_FUNC
{ .pin = GPIO_PIN_2,
.func = CONFIG_GPIO2_FUNC },
#endif
#ifdef CONFIG_GPIO3_FUNC
{ .pin = GPIO_PIN_3,
.func = CONFIG_GPIO3_FUNC },
#endif
#ifdef CONFIG_GPIO4_FUNC
{ .pin = GPIO_PIN_4,
.func = CONFIG_GPIO4_FUNC },
#endif
#ifdef CONFIG_GPIO5_FUNC
{ .pin = GPIO_PIN_5,
.func = CONFIG_GPIO5_FUNC },
#endif
#ifdef CONFIG_GPIO6_FUNC
{ .pin = GPIO_PIN_6,
.func = CONFIG_GPIO6_FUNC },
#endif
#ifdef CONFIG_GPIO7_FUNC
{ .pin = GPIO_PIN_7,
.func = CONFIG_GPIO7_FUNC },
#endif
#ifdef CONFIG_GPIO8_FUNC
{ .pin = GPIO_PIN_8,
.func = CONFIG_GPIO8_FUNC },
#endif
#ifdef CONFIG_GPIO9_FUNC
{ .pin = GPIO_PIN_9,
.func = CONFIG_GPIO9_FUNC },
#endif
#ifdef CONFIG_GPIO10_FUNC
{ .pin = GPIO_PIN_10,
.func = CONFIG_GPIO10_FUNC },
#endif
#ifdef CONFIG_GPIO11_FUNC
{ .pin = GPIO_PIN_11,
.func = CONFIG_GPIO11_FUNC },
#endif
#ifdef CONFIG_GPIO12_FUNC
{ .pin = GPIO_PIN_12,
.func = CONFIG_GPIO12_FUNC },
#endif
#ifdef CONFIG_GPIO13_FUNC
{ .pin = GPIO_PIN_13,
.func = CONFIG_GPIO13_FUNC },
#endif
#ifdef CONFIG_GPIO14_FUNC
{ .pin = GPIO_PIN_14,
.func = CONFIG_GPIO14_FUNC },
#endif
#ifdef CONFIG_GPIO15_FUNC
{ .pin = GPIO_PIN_15,
.func = CONFIG_GPIO15_FUNC },
#endif
#ifdef CONFIG_GPIO16_FUNC
{ .pin = GPIO_PIN_16,
.func = CONFIG_GPIO16_FUNC },
#endif
#ifdef CONFIG_GPIO17_FUNC
{ .pin = GPIO_PIN_17,
.func = CONFIG_GPIO17_FUNC },
#endif
#ifdef CONFIG_GPIO18_FUNC
{ .pin = GPIO_PIN_18,
.func = CONFIG_GPIO18_FUNC },
#endif
#ifdef CONFIG_GPIO19_FUNC
{ .pin = GPIO_PIN_19,
.func = CONFIG_GPIO19_FUNC },
#endif
#ifdef CONFIG_GPIO20_FUNC
{ .pin = GPIO_PIN_20,
.func = CONFIG_GPIO20_FUNC },
#endif
#ifdef CONFIG_GPIO21_FUNC
{ .pin = GPIO_PIN_21,
.func = CONFIG_GPIO21_FUNC },
#endif
#ifdef CONFIG_GPIO22_FUNC
{ .pin = GPIO_PIN_22,
.func = CONFIG_GPIO22_FUNC },
#endif
#ifdef CONFIG_GPIO23_FUNC
{ .pin = GPIO_PIN_23,
.func = CONFIG_GPIO23_FUNC },
#endif
#ifdef CONFIG_GPIO24_FUNC
{ .pin = GPIO_PIN_24,
.func = CONFIG_GPIO24_FUNC },
#endif
#ifdef CONFIG_GPIO25_FUNC
{ .pin = GPIO_PIN_25,
.func = CONFIG_GPIO25_FUNC },
#endif
#ifdef CONFIG_GPIO26_FUNC
{ .pin = GPIO_PIN_26,
.func = CONFIG_GPIO26_FUNC },
#endif
#ifdef CONFIG_GPIO27_FUNC
{ .pin = GPIO_PIN_27,
.func = CONFIG_GPIO27_FUNC },
#endif
#ifdef CONFIG_GPIO28_FUNC
{ .pin = GPIO_PIN_28,
.func = CONFIG_GPIO28_FUNC },
#endif
#ifdef CONFIG_GPIO29_FUNC
{ .pin = GPIO_PIN_29,
.func = CONFIG_GPIO29_FUNC },
#endif
#ifdef CONFIG_GPIO30_FUNC
{ .pin = GPIO_PIN_30,
.func = CONFIG_GPIO30_FUNC },
#endif
#ifdef CONFIG_GPIO31_FUNC
{ .pin = GPIO_PIN_31,
.func = CONFIG_GPIO31_FUNC },
#endif
};
static void board_pin_mux_init(void)
{
GLB_GPIO_Cfg_Type gpio_cfg;
uint32_t tmpVal;
gpio_cfg.drive = 0;
gpio_cfg.smtCtrl = 1;
uint8_t hbn_gpio_mask = 0x1f;
uint8_t hbn_aon_ie = 0;
for (int i = 0; i < sizeof(af_pin_table) / sizeof(af_pin_table[0]); i++) {
gpio_cfg.gpioMode = GPIO_MODE_AF;
gpio_cfg.pullType = GPIO_PULL_UP;
gpio_cfg.gpioPin = af_pin_table[i].pin;
gpio_cfg.gpioFun = af_pin_table[i].func;
/*if using gpio9-gpio12 and func is not analog and output ,should set reg_aon_pad_ie_smt corresponding bit = 1*/
if ((af_pin_table[i].pin > GPIO_PIN_8) && (af_pin_table[i].pin < GPIO_PIN_13)) {
if ((af_pin_table[i].func != 10) && ((af_pin_table[i].func < GPIO_FUN_GPIO_OUTPUT_UP) || (af_pin_table[i].func > GPIO_FUN_GPIO_OUTPUT_NONE)))
hbn_aon_ie |= (1 << (af_pin_table[i].pin - 9));
}
/*if reset state*/
if (af_pin_table[i].func == GPIO_FUN_UNUSED) {
continue;
} else if (af_pin_table[i].func == GPIO_FUN_WAKEUP) {
/*if hbn or pds gpio wakeup func*/
if (af_pin_table[i].pin < GPIO_PIN_8) {
/*enable pds gpio wakeup and irq unmask*/
tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_INT);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_GPIO_INT_SELECT, af_pin_table[i].pin);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_GPIO_INT_MODE, PDS_AON_GPIO_INT_TRIGGER_ASYNC_FALLING_EDGE);
tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_GPIO_INT_MASK);
BL_WR_REG(PDS_BASE, PDS_GPIO_INT, tmpVal);
} else if ((af_pin_table[i].pin > GPIO_PIN_8) && (af_pin_table[i].pin < GPIO_PIN_13)) {
hbn_gpio_mask &= ~(1 << (af_pin_table[i].pin - 9));
}
continue;
} else if ((af_pin_table[i].func == GPIO_FUN_USB) || (af_pin_table[i].func == GPIO_FUN_DAC) || (af_pin_table[i].func == GPIO_FUN_ADC)) {
/*if analog func , for usb、adc、dac*/
gpio_cfg.gpioFun = GPIO_FUN_ANALOG;
gpio_cfg.gpioMode = GPIO_MODE_ANALOG;
gpio_cfg.pullType = GPIO_PULL_NONE;
} else if ((af_pin_table[i].func & 0xF0) == 0xF0) {
/*if uart func*/
gpio_cfg.gpioFun = GPIO_FUN_UART;
uint8_t uart_func = af_pin_table[i].func & 0x07;
uint8_t uart_sig = gpio_cfg.gpioPin % 8;
/*link to one uart sig*/
GLB_UART_Fun_Sel((GLB_UART_SIG_Type)uart_sig, (GLB_UART_SIG_FUN_Type)uart_func);
GLB_UART_Fun_Sel((GLB_UART_SIG_Type)uart_func, (GLB_UART_SIG_FUN_Type)uart_sig);
} else if (af_pin_table[i].func == GPIO_FUN_PWM) {
/*if pwm func*/
gpio_cfg.pullType = GPIO_PULL_DOWN;
} else if (af_pin_table[i].func == GPIO_FUN_QDEC) {
/* if qdec a/b */
gpio_cfg.pullType = GPIO_PULL_NONE;
gpio_cfg.gpioMode = GPIO_MODE_INPUT;
gpio_cfg.gpioFun = GPIO_FUN_QDEC;
} else if (af_pin_table[i].func == GPIO_FUN_QDEC_LED) {
/* if qdec led */
gpio_cfg.pullType = GPIO_PULL_NONE;
gpio_cfg.gpioMode = GPIO_MODE_OUTPUT;
gpio_cfg.gpioFun = GPIO_FUN_QDEC;
} else if (af_pin_table[i].func == GPIO_FUN_CLK_OUT) {
if (af_pin_table[i].pin % 2) {
/*odd gpio output clock*/
GLB_Set_Chip_Out_1_CLK_Sel(GLB_CHIP_CLK_OUT_I2S_REF_CLK);
} else {
/*even gpio output clock*/
GLB_Set_Chip_Out_0_CLK_Sel(GLB_CHIP_CLK_OUT_I2S_REF_CLK);
}
} else if ((af_pin_table[i].func == GPIO_FUN_GPIO_INPUT_UP) || (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_FALLING_EDGE) || (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_LOW_LEVEL)) {
/*if common gpio func,include input、output and exti*/
gpio_cfg.gpioFun = GPIO_FUN_GPIO;
gpio_cfg.gpioMode = GPIO_MODE_INPUT;
gpio_cfg.pullType = GPIO_PULL_UP;
if (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_FALLING_EDGE) {
GLB_Set_GPIO_IntMod(af_pin_table[i].pin, GLB_GPIO_INT_CONTROL_ASYNC, GLB_GPIO_INT_TRIG_NEG_PULSE);
} else if (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_LOW_LEVEL) {
GLB_Set_GPIO_IntMod(af_pin_table[i].pin, GLB_GPIO_INT_CONTROL_ASYNC, GLB_GPIO_INT_TRIG_NEG_LEVEL);
}
} else if ((af_pin_table[i].func == GPIO_FUN_GPIO_INPUT_DOWN) || (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_RISING_EDGE) || (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_HIGH_LEVEL)) {
gpio_cfg.gpioFun = GPIO_FUN_GPIO;
gpio_cfg.gpioMode = GPIO_MODE_INPUT;
gpio_cfg.pullType = GPIO_PULL_DOWN;
if (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_RISING_EDGE) {
GLB_Set_GPIO_IntMod(af_pin_table[i].pin, GLB_GPIO_INT_CONTROL_ASYNC, GLB_GPIO_INT_TRIG_POS_PULSE);
} else if (af_pin_table[i].func == GPIO_FUN_GPIO_EXTI_HIGH_LEVEL) {
GLB_Set_GPIO_IntMod(af_pin_table[i].pin, GLB_GPIO_INT_CONTROL_ASYNC, GLB_GPIO_INT_TRIG_POS_LEVEL);
}
} else if (af_pin_table[i].func == GPIO_FUN_GPIO_INPUT_NONE) {
gpio_cfg.gpioFun = GPIO_FUN_GPIO;
gpio_cfg.gpioMode = GPIO_MODE_INPUT;
gpio_cfg.pullType = GPIO_PULL_NONE;
} else if (af_pin_table[i].func == GPIO_FUN_GPIO_OUTPUT_UP) {
gpio_cfg.gpioFun = GPIO_FUN_GPIO;
gpio_cfg.gpioMode = GPIO_MODE_OUTPUT;
gpio_cfg.pullType = GPIO_PULL_UP;
} else if (af_pin_table[i].func == GPIO_FUN_GPIO_OUTPUT_DOWN) {
gpio_cfg.gpioFun = GPIO_FUN_GPIO;
gpio_cfg.gpioMode = GPIO_MODE_OUTPUT;
gpio_cfg.pullType = GPIO_PULL_DOWN;
} else if (af_pin_table[i].func == GPIO_FUN_GPIO_OUTPUT_NONE) {
gpio_cfg.gpioFun = GPIO_FUN_GPIO;
gpio_cfg.gpioMode = GPIO_MODE_OUTPUT;
gpio_cfg.pullType = GPIO_PULL_NONE;
}
GLB_GPIO_Init(&gpio_cfg);
}
/*disable unused reg_aon_pad_ie_smt bits and hbn_pin_wakeup_mask bits*/
tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, HBN_PIN_WAKEUP_MASK, hbn_gpio_mask);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, HBN_REG_AON_PAD_IE_SMT, hbn_aon_ie);
tmpVal = BL_CLR_REG_BIT(tmpVal, HBN_REG_EN_HW_PU_PD);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, HBN_PIN_WAKEUP_MODE, HBN_GPIO_INT_TRIGGER_ASYNC_FALLING_EDGE);
BL_WR_REG(HBN_BASE, HBN_IRQ_MODE, tmpVal);
}
static void board_clock_init(void)
{
system_clock_init();
peripheral_clock_init();
}
void bl_show_info(void)
{
MSG("\r\n");
MSG(" ____ __ __ _ _ _ \r\n");
MSG(" | _ \\ / _|/ _| | | | | | | \r\n");
MSG(" | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__ \r\n");
MSG(" | _ < / _ \\| | | | _| _/ _` | |/ _ \\| |/ _` | '_ \\ \r\n");
MSG(" | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |\r\n");
MSG(" |____/ \\___/ \\__,_|_| |_| \\__,_|_|\\___/|_|\\__,_|_.__/ \r\n");
MSG("\r\n");
MSG("Build:%s,%s\r\n", __TIME__, __DATE__);
MSG("Copyright (c) 2021 Bouffalolab team\r\n");
#if 0
MSG("root clock:%dM\r\n", system_clock_get(SYSTEM_CLOCK_ROOT_CLOCK) / 1000000); /*root clock before f_div*/
MSG("fclk clock:%dM\r\n", system_clock_get(SYSTEM_CLOCK_FCLK) / 1000000); /*after f_div,this is system core clock*/
MSG("bclk clock:%dM\r\n", system_clock_get(SYSTEM_CLOCK_BCLK) / 1000000);
MSG("uart clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_UART) / 1000000);
MSG("spi clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_SPI) / 1000000);
MSG("i2c clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_I2C) / 1000000);
MSG("adc clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_ADC) / 1000000);
MSG("dac clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_DAC) / 1000000);
MSG("i2s clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_I2S) / 1000000);
MSG("pwm clock:%dhz\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_PWM));
MSG("cam clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_CAM) / 1000000);
MSG("timer0 clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / 1000000);
MSG("timer1 clock:%dM\r\n", peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / 1000000);
#endif
}
void board_init(void)
{
board_clock_init();
board_pin_mux_init();
}

View File

@@ -0,0 +1,491 @@
/**
* @file bsp_es8388.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "hal_i2c.h"
#include "bsp_es8388.h"
/** @addtogroup BL702_STD_PERIPH_DRIVER
* @{
*/
/** @addtogroup ES8388
* @{
*/
/** @defgroup ES8388_Private_Macros
* @{
*/
#define ES8388_I2C_SLAVE_ADDR 0x10
/*@} end of group ES8388_Private_Macros */
/** @defgroup ES8388_Private_Types
* @{
*/
/*@} end of group ES8388_Private_Types */
/** @defgroup ES8388_Private_Variables
* @{
*/
/*@} end of group ES8388_Private_Variables */
/** @defgroup ES8388_Global_Variables
* @{
*/
/*@} end of group ES8388_Global_Variables */
/** @defgroup ES8388_Private_Fun_Declaration
* @{
*/
/*@} end of group ES8388_Private_Fun_Declaration */
/** @defgroup ES8388_Private_Functions_User_Define
* @{
*/
/*@} end of group ES8388_Private_Functions_User_Define */
/** @defgroup ES8388_Private_Functions
* @{
*/
struct device *es8388_i2c = NULL;
/****************************************************************************/ /**
* @brief ES8388 write register
*
* @param addr: Register address
* @param data: data
*
* @return None
*
*******************************************************************************/
BL_Err_Type ES8388_Write_Reg(uint8_t addr, uint8_t data)
{
i2c_msg_t msg1;
msg1.slaveaddr = ES8388_I2C_SLAVE_ADDR,
msg1.len = 1,
msg1.buf = &data;
msg1.flags = SUB_ADDR_1BYTE | I2C_WR;
msg1.subaddr = addr;
bflb_platform_delay_ms(10);
return i2c_transfer(es8388_i2c, &msg1, 1);
}
/****************************************************************************/ /**
* @brief ES8388_Read_Reg
*
* @param addr: Register address
* @param rdata: data
*
* @return None
*
*******************************************************************************/
BL_Err_Type ES8388_Read_Reg(uint8_t addr, uint8_t *rdata)
{
i2c_msg_t msg1;
msg1.len = 1,
msg1.buf = rdata;
msg1.subaddr = addr;
msg1.slaveaddr = ES8388_I2C_SLAVE_ADDR,
msg1.flags = SUB_ADDR_1BYTE | I2C_RD;
return i2c_transfer(es8388_i2c, &msg1, 1);
}
/****************************************************************************/ /**
* @brief ES8388 codec mode
*
* @param cfg: None
*
* @return None
*
*******************************************************************************/
void ES8388_Codec_Mode(ES8388_Cfg_Type *cfg)
{
uint8_t tempVal = 0;
ES8388_Write_Reg(0x01, 0x58); //power down whole chip analog
ES8388_Write_Reg(0x01, 0x50); //power up whole chip analog
ES8388_Write_Reg(0x02, 0xf3); //power down ADC/DAC and reset ADC/DAC state machine
ES8388_Write_Reg(0x02, 0xf0); //power on ADC/DAC
ES8388_Write_Reg(0x2B, 0x80); //set internal ADC and DAC use sanme LRCK clock
ES8388_Write_Reg(0x00, 0x36); //ADC clock is same as DAC . DACMCLK is the chip master clock source
if (cfg->role == ES8388_MASTER) {
ES8388_Write_Reg(0x08, 0x8D);
} else {
ES8388_Write_Reg(0x08, 0x00);
}
ES8388_Write_Reg(0x04, 0x00); //power up dac
ES8388_Write_Reg(0x05, 0x00); //stop lowpower mode
ES8388_Write_Reg(0x06, 0xc3); //stop lowpower mode
if (cfg->mic_input_mode == ES8388_SINGLE_ENDED_MIC) {
/*
* default set LINPUT1 and RINPUT1 as single ended mic input
* if user want to use LINPUT2 and RINPUT2 as input
* please set 0x0a register as 0x50
*/
ES8388_Write_Reg(0x0A, 0xf8);
ES8388_Write_Reg(0x0B, 0x88); //analog mono mix to left ADC
} else {
/*
* defualt select LIN1 and RIN1 as Mic diff input
* if user want to use LIN2 and RIN2 as input
* please set 0x0b register as 0x82
*/
ES8388_Write_Reg(0x0A, 0xf8); // Fixed stereo problems
ES8388_Write_Reg(0x0B, 0x82); // stereo
}
tempVal = cfg->data_width;
tempVal <<= 2;
tempVal |= cfg->i2s_frame;
ES8388_Write_Reg(0x0C, tempVal); //ADC I2S Format sel as i2s_frame , data len as data_width
tempVal = cfg->data_width;
tempVal <<= 2;
tempVal |= cfg->i2s_frame;
tempVal <<= 1;
ES8388_Write_Reg(0x17, tempVal); //DAC I2S Format sel as i2s_frame , data len as data_width
/* when work in master mode , BCLK is devided form MCLK
* default divider is 256 , see datasheet reigster 13
*/
if (cfg->role == ES8388_MASTER) {
ES8388_Write_Reg(0x0d, 0x06); //ADCLRCK = MCLK/256
ES8388_Write_Reg(0x18, 0x06); //DACLRCK = MCLK/256
}
/*set ADC/DAC default volume as 0 db */
ES8388_Write_Reg(0x10, 0x00); //LADC volume as 0db
ES8388_Write_Reg(0x11, 0x00); //RADC volume as 0db
ES8388_Write_Reg(0x1A, 0x00); //LDAC volume as 0db
ES8388_Write_Reg(0x1B, 0x00); //RDAC volume as 0db
tempVal = cfg->mic_pga;
tempVal <<= 4;
tempVal |= cfg->mic_pga;
ES8388_Write_Reg(0x09, tempVal); //set ADC PGA as mic pga
/*ADC ALC default Setting */
ES8388_Write_Reg(0x12, 0xE2);
ES8388_Write_Reg(0x13, 0xC0);
ES8388_Write_Reg(0x14, 0x12);
ES8388_Write_Reg(0x15, 0x06);
ES8388_Write_Reg(0x16, 0xC3);
/*Mixer setting for LDAC to LOUT and RDAC TO ROUT
* default close mixer
*/
ES8388_Write_Reg(0x27, 0xB8);
ES8388_Write_Reg(0x2A, 0xB8);
ES8388_Write_Reg(0x02, 0x00); //startup FSM and DLL
bflb_platform_delay_ms(500);
/* set LOUT1 ROUT1 LOUT2 ROUT2 volume */
ES8388_Write_Reg(0x2e, 0x1E);
ES8388_Write_Reg(0x2f, 0x1E);
ES8388_Write_Reg(0x30, 0x1E);
ES8388_Write_Reg(0x31, 0x1E);
//ES8388_Write_Reg(0x04,0x3C);//enable LOUT & ROUT
ES8388_Write_Reg(0x04, 0x24);
ES8388_Write_Reg(0x26, 0x01);
ES8388_Write_Reg(0x03, 0x09); //power up ADC Enable LIN &RIN.
}
/****************************************************************************/ /**
* @brief ES8388 recording mode
*
* @param cfg: None
*
* @return None
*
*******************************************************************************/
void ES8388_Recording_Mode(ES8388_Cfg_Type *cfg)
{
uint8_t tempVal = 0;
MSG("RECORDING\r\n");
ES8388_Write_Reg(0x01, 0x58); //power down whole chip analog
ES8388_Write_Reg(0x01, 0x50); //power up whole chip analog
ES8388_Write_Reg(0x02, 0xf3); //power down ADC/DAC and reset ADC/DAC state machine
ES8388_Write_Reg(0x02, 0xf0); //power on ADC/DAC
ES8388_Write_Reg(0x2B, 0x80); //set internal ADC and DAC use the same LRCK clock
ES8388_Write_Reg(0x00, 0x16); //ADC clock is same as DAC. use ADC MCLK as internal MCLK
if (cfg->role == ES8388_MASTER) {
ES8388_Write_Reg(0x08, 0x80);
} else {
ES8388_Write_Reg(0x08, 0x00);
}
ES8388_Write_Reg(0x04, 0xc0);
ES8388_Write_Reg(0x05, 0x00);
ES8388_Write_Reg(0x06, 0xc3);
if (cfg->mic_input_mode == ES8388_SINGLE_ENDED_MIC) {
/*
* default set LINPUT1 and RINPUT1 as single ended mic input
* if user want to use LINPUT2 and RINPUT2 as input
* please set 0x0a register as 0x50
*/
//ES8388_Write_Reg(0x0A,0x00);//select lin1 and rin1 as micphone input
ES8388_Write_Reg(0x0A, 0xf8);
ES8388_Write_Reg(0x0B, 0x88); //analog mono mix to left ADC
//ES8388_Write_Reg(0x0B,0x90); //analog mono mix to right ADC
} else {
/*
* defualt select LIN1 and RIN1 as Mic diff input
* if user want to use LIN2 and RIN2 as input
* please set 0x0b register as 0x82
*/
//ES8388_Write_Reg(0x0A,0xf0);//set micphone input as difference mode
//ES8388_Write_Reg(0x0B,0x02);//set LIN1 and RIN1 as micphone different input
ES8388_Write_Reg(0x0A, 0xf8); // Fixed stereo problems
ES8388_Write_Reg(0x0B, 0x82); // stereo
}
tempVal = cfg->data_width;
tempVal <<= 2;
tempVal |= cfg->i2s_frame;
ES8388_Write_Reg(0x0C, tempVal); //ADC I2S Format sel as i2s_frame , data len as data_width
ES8388_Write_Reg(0x0d, 0x02); //ADC LRCK = MCLK/256
ES8388_Write_Reg(0x10, 0x00); //ADC VOLUME = 0 DB
ES8388_Write_Reg(0x11, 0x00); //set ADC VOLUME as 0 DB
tempVal = cfg->mic_pga;
tempVal <<= 4;
tempVal |= cfg->mic_pga;
ES8388_Write_Reg(0x09, tempVal); //MIC PGA SEL
ES8388_Write_Reg(0x12, 0xe2); //MIC ALC SETTING
ES8388_Write_Reg(0x13, 0xc0);
ES8388_Write_Reg(0x14, 0x12);
ES8388_Write_Reg(0x15, 0x06);
ES8388_Write_Reg(0x16, 0xc3);
ES8388_Write_Reg(0x02, 0x55); //startup FSM and DLL
ES8388_Write_Reg(0x03, 0x09); //power up adc , enable LIN and RIN
}
/****************************************************************************/ /**
* @brief ES8388 Playback mode
*
* @param cfg: None
*
* @return None
*
*******************************************************************************/
void ES8388_Playback_Mode(ES8388_Cfg_Type *cfg)
{
uint8_t tempVal = 0;
ES8388_Write_Reg(0x00, 0x80); //Reset control port register to default
ES8388_Write_Reg(0x00, 0x06); //Close reset
bflb_platform_delay_ms(10);
ES8388_Write_Reg(0x02, 0xF3); //Stop STM, DLL and digital block
if (cfg->role == ES8388_MASTER) {
ES8388_Write_Reg(0x08, 0x80);
} else {
ES8388_Write_Reg(0x08, 0x00);
}
ES8388_Write_Reg(0x2B, 0x80); //Set ADC and DAC have the same LRCK
ES8388_Write_Reg(0x00, 0x05); //Start up reference
ES8388_Write_Reg(0x01, 0x40); //Start up reference
bflb_platform_delay_ms(30);
ES8388_Write_Reg(0x03, 0x00); //Power on ADC and LIN/RIN input
ES8388_Write_Reg(0x04, 0x3F); //Power on DAC and LOUT/ROUT input
/* Set ADC */
ES8388_Write_Reg(0x09, 0x77); //MicBoost PGA = +21dB
ES8388_Write_Reg(0x0A, 0xF0); //Differential input
ES8388_Write_Reg(0x0B, 0x02); //Select LIN1 and RIN1 as differential input pairs
tempVal = cfg->data_width;
tempVal <<= 2;
tempVal |= cfg->i2s_frame;
ES8388_Write_Reg(0x0C, tempVal); //ADC I2S Format sel as i2s_frame , data len as data_width
ES8388_Write_Reg(0x0D, 0x04); //MCLK / LRCK = 512
ES8388_Write_Reg(0x10, 0x00); //LADC volume = 0dB
ES8388_Write_Reg(0x11, 0x00); //RADC volume = 0dB
ES8388_Write_Reg(0x12, 0xE2); //ALC enable, PGA Max.Gain = 23.5dB, Min.Gain = 0dB
ES8388_Write_Reg(0x13, 0xC0); //ALC target = -4.5dB, ALC hold time = 0 ms
ES8388_Write_Reg(0x14, 0x12); //Decay time = 820us, attack time = 416us
ES8388_Write_Reg(0x15, 0x06); //ALC mode
ES8388_Write_Reg(0x16, 0xC3); //Nose gate =-40.5dB, NGG = 0x01(mute ADC)
tempVal = cfg->data_width;
tempVal <<= 2;
tempVal |= cfg->i2s_frame;
tempVal <<= 1;
ES8388_Write_Reg(0x18, 0x04); //MCLK / LRCK = 512
ES8388_Write_Reg(0x1A, 0x00); //LDAC volume = 0dB
ES8388_Write_Reg(0x1B, 0x00); //RDAC volume = 0dB
ES8388_Write_Reg(0x26, 0x00); //Setup mixer
ES8388_Write_Reg(0x27, 0xB8); //Setup mixer
ES8388_Write_Reg(0x28, 0x38); //Setup mixer
ES8388_Write_Reg(0x29, 0x38); //Setup mixer
ES8388_Write_Reg(0x2A, 0xB8); //Setup mixer
ES8388_Write_Reg(0x2E, 0x1E); //Set Lout/Rout volume:0dB
ES8388_Write_Reg(0x2F, 0x1E); //Set Lout/Rout volume:0dB
ES8388_Write_Reg(0x30, 0x1E); //Set Lout/Rout volume:0dB
ES8388_Write_Reg(0x31, 0x1E); //Set Lout/Rout volume:0dB
ES8388_Write_Reg(0x02, 0x00); //Power up DEM and STM
}
/****************************************************************************/ /**
* @brief ES8388_I2C_Init
*
* @param None
*
* @return None
*
*******************************************************************************/
int ES8388_Set_Voice_Volume(int volume)
{
int res;
if (volume < 0) {
volume = 0;
} else if (volume > 100) {
volume = 100;
}
volume /= 3;
res = ES8388_Write_Reg(0x2e, volume);
res |= ES8388_Write_Reg(0x2f, volume);
res |= ES8388_Write_Reg(0x30, volume);
res |= ES8388_Write_Reg(0x31, volume);
return res;
}
/****************************************************************************/ /**
* @brief ES8388_I2C_Init
*
* @param None
*
* @return None
*
*******************************************************************************/
void ES8388_I2C_Init(void)
{
i2c_register(I2C0_INDEX, "i2c");
es8388_i2c = device_find("i2c");
if (es8388_i2c) {
device_open(es8388_i2c, 0);
}
}
/****************************************************************************/ /**
* @brief ES8388_Reg_Dump
*
* @param None
*
* @return None
*
*******************************************************************************/
void ES8388_Reg_Dump(void)
{
int i;
uint8_t tmp;
for (i = 0; i < 0X3F; i++) {
if (ES8388_Read_Reg(i, &tmp) != SUCCESS) {
bflb_platform_printf("iic read err\r\n");
}
bflb_platform_printf("Reg[%02d]=0x%02x \n", i, tmp);
}
}
/*@} end of group ES8388_Private_Functions */
/** @defgroup ES8388_Public_Functions
* @{
*/
/****************************************************************************/ /**
* @brief ES8388 Init function
*
* @param cfg: None
*
* @return None
*
*******************************************************************************/
void ES8388_Init(ES8388_Cfg_Type *cfg)
{
ES8388_I2C_Init();
switch (cfg->work_mode) {
case ES8388_CODEC_MDOE:
ES8388_Codec_Mode(cfg);
break;
case ES8388_RECORDING_MODE:
ES8388_Recording_Mode(cfg);
break;
case ES8388_PLAY_BACK_MODE:
ES8388_Playback_Mode(cfg);
break;
default:
break;
}
}
/*@} end of group ES8388_Public_Functions */
/*@} end of group ES8388 */
/*@} end of group BL702_STD_PERIPH_DRIVER */

View File

@@ -0,0 +1,193 @@
/**
* @file bsp_es8388.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __ES8388_H__
#define __ES8388_H__
#include "bflb_platform.h"
/** @addtogroup BL702_STD_PERIPH_DRIVER
* @{
*/
/** @addtogroup ES8388
* @{
*/
/** @defgroup ES8388_Public_Types
* @{
*/
/**
* @brief ES8388 Role Matser Or Slave
*/
typedef enum {
ES8388_MASTER, /*!< Master Mode */
ES8388_SLAVE, /*!< Slave Mode */
} ES8388_Role_Type;
/**
* @brief ES8388 Work Mode
*/
typedef enum {
ES8388_CODEC_MDOE, /*!< ES8388 work at codec mode */
ES8388_RECORDING_MODE, /*!< ES8388 work at recording mode */
ES8388_PLAY_BACK_MODE, /*!< ES8388 work at paly back mode */
ES8388_BY_PASS_MODE, /*!< ES8388 work at by pass mode */
} ES8388_Work_Mode;
/**
* @brief ES8388 Microphone input type
*/
typedef enum {
ES8388_SINGLE_ENDED_MIC, /*!< Mic Single Input Mode */
ES8388_DIFF_ENDED_MIC, /*!< Mic Different Input Mode */
} ES8388_MIC_Input_Type;
/**
* @brief ES8388 Microphone pga sel type
*/
typedef enum {
ES8388_MIC_PGA_0DB, /*!< Mic PGA as 0db */
ES8388_MIC_PGA_3DB, /*!< Mic PGA as 3db */
ES8388_MIC_PGA_6DB, /*!< Mic PGA as 6db */
ES8388_MIC_PGA_9DB, /*!< Mic PGA as 9db */
ES8388_MIC_PGA_12DB, /*!< Mic PGA as 12db */
ES8388_MIC_PGA_15DB, /*!< Mic PGA as 15db */
ES8388_MIC_PGA_18DB, /*!< Mic PGA as 18db */
ES8388_MIC_PGA_21DB, /*!< Mic PGA as 21db */
ES8388_MIC_PGA_24DB, /*!< Mic PGA as 24db */
} ES8388_MIC_Input_PGA_Type;
/**
* @brief ES8388 I2S Frame Type
*/
typedef enum {
ES8388_STD_I2S_FRAME, /*!< Standard I2S Frame */
ES8388_LEFT_JUSTIFY_FRAME, /*!< Left Justify Frame */
ES8388_RIGHT_JUSTIFY_FRAME, /*!< Right Justify Frame */
ES8388_DSP_FRAME, /*!< DSP Frame */
} ES8388_I2S_Frame_Type;
/**
* @brief ES8388 I2S Data Len Type
*/
typedef enum {
ES8388_DATA_LEN_24, /*!< I2S Auido Data Len 24 */
ES8388_DATA_LEN_20, /*!< I2S Auido Data Len 20 */
ES8388_DATA_LEN_18, /*!< I2S Auido Data Len 18 */
ES8388_DATA_LEN_16, /*!< I2S Auido Data Len 16 */
ES8388_DATA_LEN_32, /*!< I2S Auido Data Len 32 */
} ES8388_I2S_Data_Width;
/**
* @brief ES8388_Cfg_Type
*/
typedef struct
{
ES8388_Work_Mode work_mode; /*!< ES8388 work mode */
ES8388_Role_Type role; /*!< ES8388 role */
ES8388_MIC_Input_Type mic_input_mode; /*!< ES8388 mic input mode */
ES8388_MIC_Input_PGA_Type mic_pga; /*!< ES8388 mic PGA */
ES8388_I2S_Frame_Type i2s_frame; /*!< ES8388 I2S frame */
ES8388_I2S_Data_Width data_width; /*!< ES8388 I2S dataWitdh */
} ES8388_Cfg_Type;
/*@} end of group ES8388_Public_Types */
/** @defgroup ES8388_Public_Constants
* @{
*/
/** @defgroup ES8388_ROLE_TYPE
* @{
*/
#define IS_ES8388_ROLE_TYPE(type) (((type) == ES8388_MASTER) || \
((type) == ES8388_SLAVE))
/** @defgroup ES8388_WORK_MODE
* @{
*/
#define IS_ES8388_WORK_MODE(type) (((type) == ES8388_CODEC_MDOE) || \
((type) == ES8388_RECORDING_MODE) || \
((type) == ES8388_PLAY_BACK_MODE) || \
((type) == ES8388_BY_PASS_MODE))
/** @defgroup ES8388_MIC_INPUT_TYPE
* @{
*/
#define IS_ES8388_MIC_INPUT_TYPE(type) (((type) == ES8388_SINGLE_ENDED_MIC) || \
((type) == ES8388_DIFF_ENDED_MIC))
/** @defgroup ES8388_MIC_INPUT_PGA_TYPE
* @{
*/
#define IS_ES8388_MIC_INPUT_PGA_TYPE(type) (((type) == ES8388_MIC_PGA_0DB) || \
((type) == ES8388_MIC_PGA_3DB) || \
((type) == ES8388_MIC_PGA_6DB) || \
((type) == ES8388_MIC_PGA_9DB) || \
((type) == ES8388_MIC_PGA_12DB) || \
((type) == ES8388_MIC_PGA_15DB) || \
((type) == ES8388_MIC_PGA_18DB) || \
((type) == ES8388_MIC_PGA_21DB) || \
((type) == ES8388_MIC_PGA_24DB))
/** @defgroup ES8388_I2S_FRAME_TYPE
* @{
*/
#define IS_ES8388_I2S_FRAME_TYPE(type) (((type) == ES8388_STD_I2S_FRAME) || \
((type) == ES8388_LEFT_JUSTIFY_FRAME) || \
((type) == ES8388_RIGHT_JUSTIFY_FRAME) || \
((type) == ES8388_DSP_FRAME))
/** @defgroup ES8388_I2S_DATA_WIDTH
* @{
*/
#define IS_ES8388_I2S_DATA_WIDTH(type) (((type) == ES8388_DATA_LEN_24) || \
((type) == ES8388_DATA_LEN_20) || \
((type) == ES8388_DATA_LEN_18) || \
((type) == ES8388_DATA_LEN_16) || \
((type) == ES8388_DATA_LEN_32))
/*@} end of group ES8388_Public_Constants */
/** @defgroup ES8388_Public_Macros
* @{
*/
/*@} end of group ES8388_Public_Macros */
/** @defgroup ES8388_Public_Functions
* @{
*/
void ES8388_Init(ES8388_Cfg_Type *cfg);
void ES8388_Reg_Dump(void);
int ES8388_Set_Voice_Volume(int volume);
/*@} end of group ES8388_Public_Functions */
/*@} end of group ES8388 */
/*@} end of group BL702_STD_PERIPH_DRIVER */
#endif /* __ES8388_H__ */

View File

@@ -0,0 +1 @@
#include "phy_8720.c"

View File

@@ -0,0 +1,42 @@
/**
* @file ethernet_phy.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __ETHERNET_PHY_H__
#define __ETHERNET_PHY_H__
#include "hal_emac.h"
typedef enum emac_phy_status {
EMAC_PHY_STAT_EEROR,
EMAC_PHY_STAT_LINK_DOWN,
EMAC_PHY_STAT_LINK_INIT,
EMAC_PHY_STAT_LINK_UP,
EMAC_PHY_STAT_100MBITS_FULLDUPLEX,
EMAC_PHY_STAT_100MBITS_HALFDUPLEX,
EMAC_PHY_STAT_10MBITS_FULLDUPLEX,
EMAC_PHY_STAT_10MBITS_HALFDUPLEX,
} emac_phy_status_t;
emac_phy_status_t ethernet_phy_status_get();
int emac_phy_init(emac_phy_cfg_t *cfg);
#endif

View File

@@ -0,0 +1,556 @@
/**
* @file ethernetif.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
/* Includes ------------------------------------------------------------------*/
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "lwip/netif.h"
#if LWIP_DHCP
#include "lwip/dhcp.h"
#endif
#include "netif/etharp.h"
#include "ethernetif.h"
#include <string.h>
#include "hal_emac.h"
#include <FreeRTOS.h>
#include "semphr.h"
#include "bflb_platform.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Network interface name */
#define IFNAME0 'b'
#define IFNAME1 'l'
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
#define BL702_EMAC 0
#define EMAC_OUTPUT BL702_EMAC
#if LWIP_DHCP
#define MAX_DHCP_TRIES 4
uint32_t DHCPfineTimer = 0;
uint8_t DHCP_state = DHCP_OFF;
#else
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
#define IP_ADDR0 (uint8_t)192
#define IP_ADDR1 (uint8_t)168
#define IP_ADDR2 (uint8_t)1
#define IP_ADDR3 (uint8_t)221
/*NETMASK*/
#define NETMASK_ADDR0 (uint8_t)255
#define NETMASK_ADDR1 (uint8_t)255
#define NETMASK_ADDR2 (uint8_t)255
#define NETMASK_ADDR3 (uint8_t)0
/*Gateway Address*/
#define GW_ADDR0 (uint8_t)192
#define GW_ADDR1 (uint8_t)168
#define GW_ADDR2 (uint8_t)1
#define GW_ADDR3 (uint8_t)1
#endif
/* Private function prototypes -----------------------------------------------*/
void pbuf_free_custom(struct pbuf *p);
void ethernetif_input(void *argument);
SemaphoreHandle_t emac_rx_sem = NULL;
static StackType_t emac_rx_stack[256];
static StaticTask_t emac_rx_handle;
#if LWIP_DHCP
static StackType_t emac_dhcp_stack[256];
static StaticTask_t emac_dhcp_handle;
#endif
static uint8_t emac_rx_buffer[ETH_RX_BUFFER_SIZE] __attribute__((aligned(16))) = { 0 };
LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(struct pbuf_custom), "Zero-copy RX PBUF pool");
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
LL Driver Interface ( LwIP stack --> ETH)
*******************************************************************************/
/**
* @brief In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
extern void emac_init_txrx_buffer(void);
extern int emac_phy_init(emac_phy_cfg_t *cfg);
void dhcp_thread(void const *argument);
void low_level_init(struct netif *netif)
{
int ret = 0;
emac_device_t emac_cfg = {
.mac_addr[0] = 0x18,
.mac_addr[1] = 0xB9,
.mac_addr[2] = 0x05,
.mac_addr[3] = 0x12,
.mac_addr[4] = 0x34,
.mac_addr[5] = 0x56,
};
/* set phy cfg */
emac_phy_cfg_t phy_cfg = {
.auto_negotiation = 1, /*!< Speed and mode auto negotiation */
.full_duplex = 0, /*!< Duplex mode */
.speed = 0, /*!< Speed mode */
.phy_address = 1, /*!< PHY address */
.phy_id = 0x7c0f0, /*!< PHY OUI, masked */
.phy_state = PHY_STATE_DOWN,
};
/* set MAC hardware address length */
netif->hwaddr_len = ETH_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = emac_cfg.mac_addr[0];
netif->hwaddr[1] = emac_cfg.mac_addr[1];
netif->hwaddr[2] = emac_cfg.mac_addr[2];
netif->hwaddr[3] = emac_cfg.mac_addr[3];
netif->hwaddr[4] = emac_cfg.mac_addr[4];
netif->hwaddr[5] = emac_cfg.mac_addr[5];
/* maximum transfer unit */
netif->mtu = 1500;
/* emac init,configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
MSG("emac_init\r\n");
emac_init(&emac_cfg);
ret = emac_phy_init(&phy_cfg);
if (PHY_STATE_UP == phy_cfg.phy_state) {
MSG("PHY[%x] @%d ready on %dMbps, %s duplex\n\r", phy_cfg.phy_id, phy_cfg.phy_address,
phy_cfg.speed,
phy_cfg.full_duplex ? "full" : "half");
} else {
MSG("PHY Init fail\n\r");
BL_CASE_FAIL;
while (1)
;
}
emac_init_txrx_buffer();
emac_start();
// emac_start_tx();
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
/* Initialize the RX POOL */
LWIP_MEMPOOL_INIT(RX_POOL);
/* create a binary semaphore used for informing ethernetif of frame reception */
//vSemaphoreCreateBinary(emac_rx_sem);
emac_rx_sem = xSemaphoreCreateBinary();
/* create the task that handles the ETH_MAC */
MSG("[OS] Starting emac rx task...\r\n");
xTaskCreateStatic(ethernetif_input, (char *)"emac_rx_task", sizeof(emac_rx_stack) / 4, netif, osPriorityRealtime, emac_rx_stack, &emac_rx_handle);
#if LWIP_DHCP
MSG("[OS] Starting emac dhcp task...\r\n");
xTaskCreateStatic(dhcp_thread, (char *)"emac_dhcp_task", sizeof(emac_dhcp_stack) / 4, netif, osPriorityRealtime, emac_dhcp_stack, &emac_dhcp_handle);
#endif
if (ret == 0) {
MSG("[OS] %s Netif is up\r\n", netif->name);
netif_set_up(netif);
netif_set_link_up(netif);
}
}
void emac_tx_error_callback_app()
{
MSG("EMAC tx error callback\r\n");
}
void emac_rx_error_callback_app()
{
MSG("EMAC rx error callback\r\n");
// MSG("EMAC tx bd num 0x%x\r\n", BL_RD_WORD(0x4000D020));
// MSG("EMAC rx bd description0 0x%x\r\n", BL_RD_WORD(0x4000D400 + ((5 + 5) * 8)));
// MSG("EMAC rx bd description1 0x%x\r\n", BL_RD_WORD(0x4000D400 + ((5 + 5) * 8) + 0x4));
}
/**
* @brief This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become available since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static unsigned char emac_send_buf[1514];
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
err_t errval = ERR_OK;
struct pbuf *q;
#if (EMAC_OUTPUT == BL702_EMAC)
uint32_t byteslefttocopy = 0;
// uint32_t payloadoffset = 0;
// uint32_t bufferoffset = 0;
uint32_t framelength = 0;
uint32_t flags = (FULL_PACKET);
for (q = p; q != NULL; q = q->next) {
// MSG("p->tot_len:%d,q->len:%d, q->next:%d,f:%d\r\n", q->tot_len, q->len, q->next, framelength);
byteslefttocopy = q->len;
// payloadoffset = 0;
// check is copy data is larger than emac tx buf
while ((byteslefttocopy + framelength) > ETH_TX_BUFFER_SIZE) {
// copy data to tx buf
MSG("tx buf is too larger!\r\n");
flags = NOFULL_PACKET;
// ARCH_MemCpy_Fast(&emac_send_buf[framelength + bufferoffset], q->payload + payloadoffset, (ETH_TX_BUFFER_SIZE - bufferoffset));
}
ARCH_MemCpy_Fast(&emac_send_buf[framelength], q->payload, byteslefttocopy);
// bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
}
if (0 != emac_bd_tx_enqueue(flags, framelength, emac_send_buf)) {
MSG("emac_bd_tx_enqueue error!\r\n");
return ERR_IF;
}
#else
for (q = p; q != NULL; q = q->next) {
MSG("p->tot_len:%d,q->len:%d, q->next:%d\r\n", q->tot_len, q->len, q->next);
if (q->len == q->tot_len) {
if (0 != emac_bd_tx_enqueue(FULL_PACKET, q->len, q->payload)) {
MSG("emac_bd_tx_enqueue error!\r\n");
return ERR_IF;
}
} else if (q->len < q->tot_len) {
if (0 != emac_bd_tx_enqueue(NOFULL_PACKET, q->len, q->payload)) {
MSG("emac_bd_tx_enqueue error!\r\n");
return ERR_IF;
}
} else {
MSG("low_level_output error! Wrong packet!\r\n");
}
}
#endif
return errval;
}
/**
* @brief Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *low_level_input(struct netif *netif)
{
uint32_t rx_len = 0;
struct pbuf *p = NULL, *q;
emac_bd_rx_dequeue(-1, &rx_len, emac_rx_buffer);
if (rx_len <= 0) {
//MSG("Recv Null Data\r\n");
return NULL;
}
//MSG("Recv full Data\r\n");
p = pbuf_alloc(PBUF_RAW, rx_len, PBUF_POOL);
if (p != NULL) {
for (q = p; q != NULL; q = q->next) {
memcpy(q->payload, emac_rx_buffer + rx_len - q->tot_len, q->len);
}
}
return p;
}
void emac_rx_done_callback_app(void)
{
BaseType_t xHigherPriorityTaskWoken;
/* Is it time for vATask() to run? */
xHigherPriorityTaskWoken = pdFALSE;
//MSG("emac_rx_done_callback_app\r\n");
//low_level_input(NULL);
xSemaphoreGiveFromISR(emac_rx_sem, &xHigherPriorityTaskWoken);
/* If xHigherPriorityTaskWoken was set to true you
we should yield. The actual macro used here is
port specific. */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
/**
* @brief This function is the ethernetif_input task, it is processed when a packet
* is ready to be read from the interface. It uses the function low_level_input()
* that should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
void ethernetif_input(void *argument)
{
struct pbuf *p = NULL;
struct netif *netif = (struct netif *)argument;
for (;;) {
if (xSemaphoreTake(emac_rx_sem, portMAX_DELAY) == pdTRUE) {
do {
//MSG("ethernetif_input\r\n");
p = low_level_input(netif);
if (p != NULL) {
if (netif->input(p, netif) != ERR_OK) {
pbuf_free(p);
}
}
} while (p != NULL);
}
}
}
/**
* @brief Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}
/**
* @brief Custom Rx pbuf free callback
* @param pbuf: pbuf to be freed
* @retval None
*/
void pbuf_free_custom(struct pbuf *p)
{
struct pbuf_custom *custom_pbuf = (struct pbuf_custom *)p;
LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
}
static void ethernet_set_static_ip(struct netif *netif)
{
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gw;
IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(netif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gw));
}
/**
* @brief Notify the User about the network interface config status
* @param netif: the network interface
* @retval None
*/
void ethernet_link_status_updated(struct netif *netif)
{
if (netif_is_link_up(netif)) {
#if LWIP_DHCP
/* Update DHCP state machine */
DHCP_state = DHCP_START;
MSG("DHCP Start\n");
#else
/* IP address default setting */
ethernet_set_static_ip(netif);
uint8_t iptxt[20];
sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
MSG("Static IP address: %s\n", iptxt);
#endif
} else {
#if LWIP_DHCP
/* Update DHCP state machine */
DHCP_state = DHCP_LINK_DOWN;
#else
MSG("The network cable is not connected \n");
#endif /* LWIP_DHCP */
}
}
/**
* @brief
* @retval None
*/
void ethernet_link_check_state(struct netif *netif)
{
emac_phy_status_t phy_state;
uint32_t linkchanged = 0;
// uint32_t speed = 0, duplex = 0;
phy_state = ethernet_phy_status_get();
if (netif_is_link_up(netif) && (phy_state <= EMAC_PHY_STAT_LINK_DOWN)) {
MSG("Link Down\n");
emac_stop();
netif_set_down(netif);
netif_set_link_down(netif);
} else if (!netif_is_link_up(netif) && (phy_state <= EMAC_PHY_STAT_LINK_DOWN)) {
MSG("Reinit\n");
emac_phy_init(NULL);
} else if (!netif_is_link_up(netif) && (phy_state > EMAC_PHY_STAT_LINK_UP)) {
// switch (phy_state) {
// case EMAC_PHY_STAT_100MBITS_FULLDUPLEX:
// duplex = 1;
// speed = 100;
// linkchanged = 1;
// break;
// case EMAC_PHY_STAT_100MBITS_HALFDUPLEX:
// duplex = 0;
// speed = 100;
// linkchanged = 1;
// break;
// case EMAC_PHY_STAT_10MBITS_FULLDUPLEX:
// duplex = 1;
// speed = 10;
// linkchanged = 1;
// break;
// case EMAC_PHY_STAT_10MBITS_HALFDUPLEX:
// duplex = 0;
// speed = 10;
// linkchanged = 1;
// break;
// default:
// break;
// }
if (linkchanged) {
/* Get MAC Config MAC */
//HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
//MACConf.DuplexMode = duplex;
//MACConf.Speed = speed;
//HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
//HAL_ETH_Start(&EthHandle);
netif_set_up(netif);
netif_set_link_up(netif);
}
}
}
#if LWIP_DHCP
/**
* @brief DHCP Process
* @param argument: network interface
* @retval None
*/
void dhcp_thread(void const *argument)
{
struct netif *netif = (struct netif *)argument;
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gw;
struct dhcp *dhcp;
uint8_t iptxt[20];
for (;;) {
switch (DHCP_state) {
case DHCP_START: {
ip_addr_set_zero_ip4(&netif->ip_addr);
ip_addr_set_zero_ip4(&netif->netmask);
ip_addr_set_zero_ip4(&netif->gw);
DHCP_state = DHCP_WAIT_ADDRESS;
MSG(" State: Looking for DHCP server ...\n");
dhcp_start(netif);
} break;
case DHCP_WAIT_ADDRESS: {
if (dhcp_supplied_address(netif)) {
DHCP_state = DHCP_ADDRESS_ASSIGNED;
sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
MSG("IP address assigned by a DHCP server: %s\n", iptxt);
} else {
dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
/* DHCP timeout */
if (dhcp->tries > MAX_DHCP_TRIES) {
DHCP_state = DHCP_TIMEOUT;
/* Static address used */
ethernet_set_static_ip(netif);
sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
MSG("DHCP Timeout !! \n");
MSG("Static IP address: %s\n", iptxt);
}
}
} break;
case DHCP_LINK_DOWN: {
DHCP_state = DHCP_OFF;
MSG("The network cable is not connected \n");
} break;
default:
break;
}
vTaskDelay(100);
}
}
#endif /* LWIP_DHCP */

View File

@@ -0,0 +1,42 @@
/**
* @file ethernetif.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__
#include "lwip/err.h"
#include "lwip/netif.h"
#include "ethernet_phy.h"
#define DHCP_OFF (uint8_t)0
#define DHCP_START (uint8_t)1
#define DHCP_WAIT_ADDRESS (uint8_t)2
#define DHCP_ADDRESS_ASSIGNED (uint8_t)3
#define DHCP_TIMEOUT (uint8_t)4
#define DHCP_LINK_DOWN (uint8_t)5
/* Exported types ------------------------------------------------------------*/
err_t ethernetif_init(struct netif *netif);
void ethernet_link_check_state(struct netif *netif);
void ethernet_link_status_updated(struct netif *netif);
#endif

View File

@@ -0,0 +1,387 @@
#include <string.h>
#include "hal_emac.h"
#include "ethernet_phy.h"
/* LAN8720 PHY Address*/
#define EMAC_PHY_ADDRESS 0x00U
#define PHY_LINK_TO ((uint32_t)0x00000FFFU)
#define PHY_AUTONEGO_COMPLETED_TO ((uint32_t)0x00000FFFU)
/* Section 3: Common PHY Registers */
#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */
#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */
#define PHY_BSR_100BASETXFULL (1 << 14)
#define PHY_BSR_100BASETXHALF (1 << 13)
#define PHY_BSR_10BASETXFULL (1 << 12)
#define PHY_BSR_10BASETXHALF (1 << 11)
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
#define PHY_PHYID1 ((uint16_t)0x02U) /*!< PHY ID 1 */
#define PHY_PHYID2 ((uint16_t)0x03U) /*!< PHY ID 2 */
#define PHY_ADVERTISE ((uint16_t)0x04U) /*!< Auto-negotiation advertisement */
#define PHY_ADVERTISE_100BASETXFULL (1 << 8)
#define PHY_ADVERTISE_100BASETXHALF (1 << 7)
#define PHY_ADVERTISE_10BASETXFULL (1 << 6)
#define PHY_ADVERTISE_10BASETXHALF (1 << 5)
#define PHY_ADVERTISE_8023 (1 << 0)
#define PHY_LPA ((uint16_t)0x05U) /*!< Auto-negotiation link partner base page ability */
#define PHY_EXPANSION ((uint16_t)0x06U) /*!< Auto-negotiation expansion */
/* Section 4: Extended PHY Registers */
#define PHY_CTRL_STATUS ((uint16_t)17U) /*!< PHY MODE CONTROL/STATUS REGISTER Offset */
#define PHY_CTRL_STATUS_EDPWRDOWN (1 << 13) /*!< EDPWRDOWN */
#define PHY_CTRL_STATUS_ENERGYON (1 << 1) /*!< ENERGYON */
#define PHY_SPECIAL_MODES ((uint16_t)18U) /*!< PHY SPECIAL MODES REGISTER Offset */
#define PHY_SPECIAL_MODES_MODE (7 << 5) /*!< Transceiver mode of operation */
#define PHY_SPECIAL_MODES_MODE_PWRDOWN (6 << 5) /*!< All capable. Auto-negotiation enabled */
#define PHY_SPECIAL_MODES_MODE_ALL (7 << 5) /*!< All capable. Auto-negotiation enabled */
#define PHY_SPECIAL_MODES_PHYAD (0x1F << 0) /*!< PHY Address */
#define PHY_SR ((uint16_t)0x1FU) /*!< PHY special control/ status register Offset */
#define PHY_SR_SPEED_OFFSET (2)
#define PHY_SR_SPEED_MASK (0x7 << PHY_SR_SPEED_OFFSET)
#define PHY_SR_SPEED_10BASETXHALF (0x1 << PHY_SR_SPEED_OFFSET)
#define PHY_SR_SPEED_10BASETXFULL (0x5 << PHY_SR_SPEED_OFFSET)
#define PHY_SR_SPEED_100BASETXHALF (0x2 << PHY_SR_SPEED_OFFSET)
#define PHY_SR_SPEED_100BASETXFULL (0x6 << PHY_SR_SPEED_OFFSET)
#define PHY_SR_SPEED_MODE_COMPARE(status, mode) (!!(mode == (status & PHY_SR_SPEED_MASK)))
#define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< PHY Duplex mask */
#define PHY_ISFR ((uint16_t)0x1DU) /*!< PHY Interrupt Source Flag register Offset */
#define PHY_ISFR_INT4 ((uint16_t)0x0010U) /*!< PHY Link down inturrupt */
static emac_phy_cfg_t *phy_8720_cfg = NULL;
int phy_8720_reset(void)
{
int timeout = 1000;
uint16_t regval = PHY_RESET;
/* pull the PHY from power down mode if it is in */
if (0 != emac_phy_reg_read(PHY_SPECIAL_MODES, &regval)) {
return -1;
}
if (PHY_SPECIAL_MODES_MODE_PWRDOWN == (regval & PHY_SPECIAL_MODES_MODE)) {
if (emac_phy_reg_write(PHY_SPECIAL_MODES, regval | PHY_SPECIAL_MODES_MODE_ALL) != 0) {
return -1;
}
}
/* disable energy detect powerdown mode for cable detect, this increase the power by 220mW */
if (0 != emac_phy_reg_read(PHY_CTRL_STATUS, &regval)) {
return -1;
}
if (emac_phy_reg_write(PHY_CTRL_STATUS, regval & (~PHY_CTRL_STATUS_EDPWRDOWN)) != 0) {
return -1;
}
/* do sw reset */
if (emac_phy_reg_write(PHY_BCR, PHY_RESET) != 0) {
return -1;
}
for (; timeout; timeout--) {
if (0 != emac_phy_reg_read(PHY_BCR, &regval)) {
return -1;
}
if (!(regval & PHY_RESET)) {
return 0;
}
arch_delay_ms(1);
}
return -1;
}
int phy_8720_auto_negotiate(emac_phy_cfg_t *cfg)
{
uint16_t regval = 0;
uint16_t phyid1 = 0, phyid2 = 0;
uint16_t advertise = 0;
uint16_t lpa = 0;
uint32_t timeout = 100; //10s,in 100ms
if (0 != emac_phy_reg_read(PHY_PHYID1, &phyid1)) {
return -1;
}
if (0 != emac_phy_reg_read(PHY_PHYID2, &phyid2)) {
return -1;
}
if (cfg->phy_id != (((phyid1 << 16) | phyid2) & 0x000FFFF0)) {
/* ID error */
return -1;
} else {
cfg->phy_id = (phyid1 << 16) | phyid2;
}
if (0 != emac_phy_reg_read(PHY_BCR, &regval)) {
return -1;
}
regval &= ~PHY_AUTONEGOTIATION;
regval &= ~(PHY_LOOPBACK | PHY_POWERDOWN);
regval |= PHY_ISOLATE;
if (emac_phy_reg_write(PHY_BCR, regval) != 0) {
return -1;
}
/* set advertisement mode */
advertise = PHY_ADVERTISE_100BASETXFULL | PHY_ADVERTISE_100BASETXHALF |
PHY_ADVERTISE_10BASETXFULL | PHY_ADVERTISE_10BASETXHALF |
PHY_ADVERTISE_8023;
if (emac_phy_reg_write(PHY_ADVERTISE, advertise) != 0) {
return -1;
}
arch_delay_ms(16);
if (0 != emac_phy_reg_read(PHY_BCR, &regval)) {
return -1;
}
arch_delay_ms(16);
regval |= (PHY_FULLDUPLEX_100M | PHY_AUTONEGOTIATION);
if (emac_phy_reg_write(PHY_BCR, regval) != 0) {
return -1;
}
arch_delay_ms(16);
regval |= PHY_RESTART_AUTONEGOTIATION;
regval &= ~PHY_ISOLATE;
if (emac_phy_reg_write(PHY_BCR, regval) != 0) {
return -1;
}
arch_delay_ms(100);
while (1) {
if (0 != emac_phy_reg_read(PHY_BSR, &regval)) {
return -1;
}
if (regval & PHY_AUTONEGO_COMPLETE) {
/* complete */
break;
}
if (!(--timeout)) {
return -1;
}
arch_delay_ms(100);
}
arch_delay_ms(100);
if (0 != emac_phy_reg_read(PHY_LPA, &lpa)) {
return -1;
}
if (((advertise & lpa) & PHY_ADVERTISE_100BASETXFULL) != 0) {
/* 100BaseTX and Full Duplex */
cfg->full_duplex = 1;
cfg->speed = 100;
cfg->phy_state = PHY_STATE_READY;
} else if (((advertise & lpa) & PHY_ADVERTISE_10BASETXFULL) != 0) {
/* 10BaseT and Full Duplex */
cfg->full_duplex = 1;
cfg->speed = 10;
cfg->phy_state = PHY_STATE_READY;
} else if (((advertise & lpa) & PHY_ADVERTISE_100BASETXHALF) != 0) {
/* 100BaseTX and half Duplex */
cfg->full_duplex = 0;
cfg->speed = 100;
cfg->phy_state = PHY_STATE_READY;
} else if (((advertise & lpa) & PHY_ADVERTISE_10BASETXHALF) != 0) {
/* 10BaseT and half Duplex */
cfg->full_duplex = 0;
cfg->speed = 10;
cfg->phy_state = PHY_STATE_READY;
}
return 0;
}
int phy_8720_link_up(emac_phy_cfg_t *cfg)
{
uint16_t phy_bsr = 0;
uint16_t phy_sr = 0;
arch_delay_ms(16);
if (0 != emac_phy_reg_read(PHY_BSR, &phy_bsr)) {
return -1;
}
arch_delay_ms(16);
if (!(PHY_LINKED_STATUS & phy_bsr)) {
return ERROR;
}
arch_delay_ms(16);
if (0 != emac_phy_reg_read(PHY_SR, &phy_sr)) {
return -1;
}
if ((phy_bsr & PHY_BSR_100BASETXFULL) && PHY_SR_SPEED_MODE_COMPARE(phy_sr, PHY_SR_SPEED_100BASETXFULL)) {
/* 100BaseTX and Full Duplex */
cfg->full_duplex = 1;
cfg->speed = 100;
cfg->phy_state = PHY_STATE_UP;
} else if ((phy_bsr & PHY_BSR_10BASETXFULL) && PHY_SR_SPEED_MODE_COMPARE(phy_sr, PHY_SR_SPEED_10BASETXFULL)) {
/* 10BaseT and Full Duplex */
cfg->full_duplex = 1;
cfg->speed = 10;
cfg->phy_state = PHY_STATE_UP;
} else if ((phy_bsr & PHY_BSR_100BASETXHALF) && PHY_SR_SPEED_MODE_COMPARE(phy_sr, PHY_SR_SPEED_100BASETXHALF)) {
/* 100BaseTX and half Duplex */
cfg->full_duplex = 0;
cfg->speed = 100;
cfg->phy_state = PHY_STATE_UP;
} else if ((phy_bsr & PHY_BSR_10BASETXHALF) && PHY_SR_SPEED_MODE_COMPARE(phy_sr, PHY_SR_SPEED_10BASETXHALF)) {
/* 10BaseT and half Duplex */
cfg->full_duplex = 0;
cfg->speed = 10;
cfg->phy_state = PHY_STATE_UP;
} else {
/* 10BaseT and half Duplex */
cfg->full_duplex = -1;
cfg->speed = -1;
cfg->phy_state = PHY_STATE_DOWN;
return -1;
}
return 0;
}
/******************************************************************************
* @brief Use energy detector for cable plug in/out detect.
*
* @param cfg: EMAC PHY configuration pointer
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
int phy_8720_poll_cable_status(emac_phy_cfg_t *cfg)
{
uint16_t phy_regval = 0;
CHECK_PARAM(NULL != phy_8720_cfg);
if (0 != emac_phy_reg_read(PHY_CTRL_STATUS, &phy_regval)) {
return -1;
}
phy_8720_cfg->phy_state = (PHY_CTRL_STATUS_ENERGYON & phy_regval) ?
PHY_STATE_UP :
PHY_STATE_DOWN;
return !!(PHY_CTRL_STATUS_ENERGYON & phy_regval);
}
/****************************************************************************/ /**
* @brief Initialize EMAC PHY module
*
* @param cfg: EMAC PHY configuration pointer
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
int emac_phy_init(emac_phy_cfg_t *cfg)
{
uint16_t phyReg;
CHECK_PARAM(NULL != cfg);
phy_8720_cfg = cfg;
emac_phy_set_address(cfg->phy_address);
if (0 != phy_8720_reset()) {
return -1;
}
if (cfg->auto_negotiation) {
/*
uint32_t cnt=0;
do{
if(emac_phy_reg_read(PHY_BSR, &phyReg) != SUCCESS){
return ERROR;
}
cnt++;
if(cnt>PHY_LINK_TO){
return ERROR;
}
}while((phyReg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS);
*/
if (0 != phy_8720_auto_negotiate(cfg)) {
return -1;
}
} else {
if (emac_phy_reg_read(PHY_BCR, &phyReg) != 0) {
return -1;
}
phyReg &= (~PHY_FULLDUPLEX_100M);
if (cfg->speed == 10) {
if (cfg->full_duplex == 1) {
phyReg |= PHY_FULLDUPLEX_10M;
} else {
phyReg |= PHY_HALFDUPLEX_10M;
}
} else {
if (cfg->full_duplex == 1) {
phyReg |= PHY_FULLDUPLEX_100M;
} else {
phyReg |= PHY_HALFDUPLEX_100M;
}
}
if ((emac_phy_reg_write(PHY_BCR, phyReg)) != 0) {
return -1;
}
}
emac_phy_config_full_duplex(cfg->full_duplex);
return phy_8720_link_up(cfg);
}
emac_phy_status_t ethernet_phy_status_get()
{
CHECK_PARAM(NULL != phy_8720_cfg);
if ((100 == phy_8720_cfg->speed) &&
(phy_8720_cfg->full_duplex) &&
(PHY_STATE_UP == phy_8720_cfg->phy_state)) {
return EMAC_PHY_STAT_100MBITS_FULLDUPLEX;
} else if (PHY_STATE_UP == phy_8720_cfg->phy_state) {
return EMAC_PHY_STAT_LINK_UP;
} else {
return EMAC_PHY_STAT_LINK_DOWN;
}
}

View File

@@ -0,0 +1,22 @@
const char *FR_Table[] = {
"FR_OK成功", /* (0) Succeeded */
"FR_DISK_ERR底层硬件错误", /* (1) A hard error occurred in the low level disk I/O layer */
"FR_INT_ERR断言失败", /* (2) Assertion failed */
"FR_NOT_READY物理驱动没有工作", /* (3) The physical drive cannot work */
"FR_NO_FILE文件不存在", /* (4) Could not find the file */
"FR_NO_PATH路径不存在", /* (5) Could not find the path */
"FR_INVALID_NAME无效文件名", /* (6) The path name format is invalid */
"FR_DENIED由于禁止访问或者目录已满访问被拒绝", /* (7) Access denied due to prohibited access or directory full */
"FR_EXIST文件已经存在", /* (8) Access denied due to prohibited access */
"FR_INVALID_OBJECT文件或者目录对象无效", /* (9) The file/directory object is invalid */
"FR_WRITE_PROTECTED物理驱动被写保护", /* (10) The physical drive is write protected */
"FR_INVALID_DRIVE逻辑驱动号无效", /* (11) The logical drive number is invalid */
"FR_NOT_ENABLED卷中无工作区", /* (12) The volume has no work area */
"FR_NO_FILESYSTEM没有有效的FAT卷", /* (13) There is no valid FAT volume */
"FR_MKFS_ABORTED由于参数错误f_mkfs()被终止", /* (14) The f_mkfs() aborted due to any parameter error */
"FR_TIMEOUT在规定的时间内无法获得访问卷的许可", /* (15) Could not get a grant to access the volume within defined period */
"FR_LOCKED由于文件共享策略操作被拒绝", /* (16) The operation is rejected according to the file sharing policy */
"FR_NOT_ENOUGH_CORE无法分配长文件名工作区", /* (17) LFN working buffer could not be allocated */
"FR_TOO_MANY_OPEN_FILES当前打开的文件数大于_FS_SHARE", /* (18) Number of open files > _FS_SHARE */
"FR_INVALID_PARAMETER参数无效" /* (19) Given parameter is invalid */
};

View File

@@ -0,0 +1,135 @@
/**
* @file fatfs_sdio_sd.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2019 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "bsp_sdio_sdcard.h"
static sd_card_t gSDCardInfo;
extern const char *FR_Table[];
int MMC_disk_status()
{
return 0;
}
int MMC_disk_initialize()
{
static uint8_t inited = 0;
if (inited == 0) {
if (SDH_Init(SDH_DATA_BUS_WIDTH_4BITS, &gSDCardInfo) == SD_OK) {
inited = 1;
return 0;
} else {
return -1;
}
}
return 0;
}
int MMC_disk_read(BYTE *buff, LBA_t sector, UINT count)
{
if (SD_OK == SDH_ReadMultiBlocks(buff, sector, gSDCardInfo.blockSize, count)) {
return 0;
} else {
return -1;
}
}
int MMC_disk_write(const BYTE *buff, LBA_t sector, UINT count)
{
if (SD_OK == SDH_WriteMultiBlocks((uint8_t *)buff, sector, gSDCardInfo.blockSize, count)) {
return 0;
} else {
return -1;
}
}
int MMC_disk_ioctl(BYTE cmd, void *buff)
{
switch (cmd) {
// Get R/W sector size (WORD)
case GET_SECTOR_SIZE:
*(WORD *)buff = gSDCardInfo.blockSize;
break;
// Get erase block size in unit of sector (DWORD)
case GET_BLOCK_SIZE:
*(DWORD *)buff = 1;
break;
case GET_SECTOR_COUNT:
*(DWORD *)buff = gSDCardInfo.blockCount;
break;
case CTRL_SYNC:
break;
default:
break;
}
return 0;
}
DWORD get_fattime(void)
{
return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */
| ((DWORD)1 << 21) /* Month 1 */
| ((DWORD)1 << 16) /* Mday 1 */
| ((DWORD)0 << 11) /* Hour 0 */
| ((DWORD)0 << 5) /* Min 0 */
| ((DWORD)0 >> 1); /* Sec 0 */
}
DSTATUS Translate_Result_Code(int result)
{
// MSG("%s\r\n",FR_Table[result]);
return result;
}
void fatfs_sdio_driver_register(void)
{
FATFS_DiskioDriverTypeDef pNewDiskioDriver;
memset(&pNewDiskioDriver, 0, sizeof(FATFS_DiskioDriverTypeDef));
pNewDiskioDriver.MMC_disk_status = MMC_disk_status;
pNewDiskioDriver.MMC_disk_initialize = MMC_disk_initialize;
pNewDiskioDriver.MMC_disk_write = MMC_disk_write;
pNewDiskioDriver.MMC_disk_read = MMC_disk_read;
pNewDiskioDriver.MMC_disk_ioctl = MMC_disk_ioctl;
pNewDiskioDriver.Translate_Result_Code = Translate_Result_Code;
disk_driver_callback_init(&pNewDiskioDriver);
}

View File

@@ -0,0 +1,97 @@
/**
* @file fatfs_spi_sd.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "diskio.h"
#include "bsp_spi_sd.h"
#include "string.h"
extern const char *FR_Table[];
int sd_disk_status(void)
{
return 0;
}
int sd_disk_initialize(void)
{
return SD_Init(&SD_CardInfo);
}
int sd_disk_read(BYTE *buff, LBA_t sector, UINT count)
{
return SD_ReadBlock(sector, buff, count);
}
int sd_disk_write(const BYTE *buff, LBA_t sector, UINT count)
{
return SD_WriteBlock(sector, (BYTE *)buff, count);
}
int sd_disk_ioctl(BYTE cmd, void *buff)
{
int result = 0;
switch (cmd) {
case CTRL_SYNC:
result = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD *)buff = SD_CardInfo.CardBlockSize;
result = RES_OK;
break;
case GET_BLOCK_SIZE:
*(DWORD *)buff = SD_CardInfo.CardBlockSize;
result = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD *)buff = SD_CardInfo.CardCapacity / SD_CardInfo.CardBlockSize;
result = RES_OK;
break;
default:
result = RES_PARERR;
break;
}
return result;
}
DSTATUS Translate_Result_Code(int result)
{
// MSG("%s\r\n",FR_Table[result]);
return result;
}
void fatfs_sd_driver_register(void)
{
FATFS_DiskioDriverTypeDef sdDiskioDriver;
memset(&sdDiskioDriver, 0, sizeof(FATFS_DiskioDriverTypeDef));
sdDiskioDriver.MMC_disk_status = sd_disk_status;
sdDiskioDriver.MMC_disk_initialize = sd_disk_initialize;
sdDiskioDriver.MMC_disk_write = sd_disk_write;
sdDiskioDriver.MMC_disk_read = sd_disk_read;
sdDiskioDriver.MMC_disk_ioctl = sd_disk_ioctl;
sdDiskioDriver.Translate_Result_Code = Translate_Result_Code;
disk_driver_callback_init(&sdDiskioDriver);
}

View File

@@ -0,0 +1,104 @@
/**
* @file fatfs_spi_sd.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "diskio.h"
#include "string.h"
#include "hal_flash.h"
#define FLASH_START_ADDR 0x00040000 /*addr start from 256k */
#define FLASH_BLOCK_SIZE 4096
#define FLASH_BLOCK_COUNT 64
extern const char *FR_Table[];
int usb_disk_status(void)
{
return 0;
}
int usb_disk_initialize(void)
{
return RES_OK;
}
int usb_disk_read(BYTE *buff, LBA_t sector, UINT count)
{
flash_read(FLASH_START_ADDR + sector * FLASH_BLOCK_SIZE, (uint8_t *)buff, count * FLASH_BLOCK_SIZE);
return 0;
}
int usb_disk_write(const BYTE *buff, LBA_t sector, UINT count)
{
flash_erase(FLASH_START_ADDR + sector * FLASH_BLOCK_SIZE, 4096);
flash_write(FLASH_START_ADDR + sector * FLASH_BLOCK_SIZE, (uint8_t *)buff, count * FLASH_BLOCK_SIZE);
return 0;
}
int usb_disk_ioctl(BYTE cmd, void *buff)
{
int result = 0;
switch (cmd) {
case CTRL_SYNC:
result = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD *)buff = FLASH_BLOCK_SIZE;
result = RES_OK;
break;
case GET_BLOCK_SIZE:
*(DWORD *)buff = 1;
result = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD *)buff = FLASH_BLOCK_COUNT;
result = RES_OK;
break;
default:
result = RES_PARERR;
break;
}
return result;
}
DSTATUS Translate_Result_Code(int result)
{
//MSG("%s\r\n", FR_Table[result]);
return result;
}
void fatfs_usb_driver_register(void)
{
FATFS_DiskioDriverTypeDef USBDiskioDriver;
memset(&USBDiskioDriver, 0, sizeof(FATFS_DiskioDriverTypeDef));
USBDiskioDriver.USB_disk_status = usb_disk_status;
USBDiskioDriver.USB_disk_initialize = usb_disk_initialize;
USBDiskioDriver.USB_disk_write = usb_disk_write;
USBDiskioDriver.USB_disk_read = usb_disk_read;
USBDiskioDriver.USB_disk_ioctl = usb_disk_ioctl;
USBDiskioDriver.Translate_Result_Code = Translate_Result_Code;
disk_driver_callback_init(&USBDiskioDriver);
}

View File

@@ -0,0 +1,750 @@
/**
* @file bsp_il9341.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "bsp_il9341.h"
#include "hal_spi.h"
#include "hal_dma.h"
#include "font_ascii_16x8.h"
/** @addtogroup BL702_Peripheral_Case
* @{
*/
/** @addtogroup TFT_LCD
* @{
*/
/** @defgroup TFT_LCD_Private_Macros
* @{
*/
/*@} end of group TFT_LCD_Private_Macros */
/** @defgroup TFT_LCD_Private_Types
* @{
*/
/*@} end of group TFT_LCD_Private_Types */
/** @defgroup TFT_LCD_Private_Variables
* @{
*/
/*@} end of group TFT_LCD_Private_Variables */
/** @defgroup TFT_LCD_Global_Variables
* @{
*/
/*@} end of group TFT_LCD_Global_Variables */
/** @defgroup TFT_LCD_Private_Fun_Declaration
* @{
*/
/*@} end of group TFT_LCD_Private_Fun_Declaration */
/** @defgroup TFT_LCD_Private_Functions
* @{
*/
static struct device *spi0;
static struct device *dma_ch3;
static struct device *dma_ch4;
void dma_ch3_callback(struct device *dev, void *args, uint32_t size, uint32_t event)
{
}
/*@} end of group TFT_LCD_Private_Functions */
/** @defgroup TFT_LCD_Public_Functions
* @{
*/
void spi0_init(void)
{
gpio_set_mode(LCD_CS_PIN, GPIO_OUTPUT_MODE);
gpio_set_mode(LCD_DC_PIN, GPIO_OUTPUT_MODE);
gpio_write(LCD_CS_PIN, 1); //CS1
gpio_write(LCD_DC_PIN, 1); //DC
spi0 = device_find("spi0");
if (spi0) {
device_close(spi0);
} else {
spi_register(SPI0_INDEX, "spi0");
spi0 = device_find("spi0");
}
if (spi0) {
device_open(spi0, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
}
dma_ch3 = device_find("dma0_ch3");
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "dma0_ch3");
dma_ch3 = device_find("dma0_ch3");
}
if (dma_ch3) {
DMA_DEV(dma_ch3)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_SPI0_TX;
DMA_DEV(dma_ch3)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch3)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch3, 0);
device_set_callback(dma_ch3, NULL);
device_control(dma_ch3, DEVICE_CTRL_SET_INT, NULL);
}
dma_ch4 = device_find("dma0_ch4");
if (dma_ch4) {
device_close(dma_ch4);
} else {
dma_register(DMA0_CH4_INDEX, "dma0_ch4");
dma_ch4 = device_find("dma0_ch4");
}
if (dma_ch4) {
DMA_DEV(dma_ch4)->direction = DMA_PERIPH_TO_MEMORY;
DMA_DEV(dma_ch4)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch4)->src_req = DMA_REQUEST_SPI0_RX;
DMA_DEV(dma_ch4)->dst_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch4)->src_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch4)->dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch4)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch4)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch4)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch4)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch4, 0);
device_set_callback(dma_ch4, NULL);
device_control(dma_ch4, DEVICE_CTRL_CLR_INT, NULL);
}
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
}
/****************************************************************************/ /**
* @brief LCD write command
*
* @param command: Command to write
*
* @return None
*
*******************************************************************************/
void LCD_WR_Cmd(uint8_t command)
{
CS1_LOW;
DC_LOW;
spi_transmit(spi0, &command, 1, SPI_TRANSFER_TYPE_8BIT);
CS1_HIGH;
}
/****************************************************************************/ /**
* @brief LCD write 8-bit data
*
* @param data: 8-bit data to write
*
* @return None
*
*******************************************************************************/
void LCD_WR_Byte(uint8_t data)
{
CS1_LOW;
DC_HIGH;
spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_8BIT);
CS1_HIGH;
}
/****************************************************************************/ /**
* @brief LCD write 16-bit data
*
* @param data: 16-bit data to write
*
* @return None
*
*******************************************************************************/
void LCD_WR_HalfWord(uint16_t data)
{
CS1_LOW;
DC_HIGH;
spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_16BIT);
CS1_HIGH;
}
/****************************************************************************/ /**
* @brief LCD write 32-bit data
*
* @param data: 32-bit data to write
*
* @return None
*
*******************************************************************************/
void LCD_WR_Word(uint32_t data)
{
CS1_LOW;
DC_HIGH;
spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_32BIT);
CS1_HIGH;
}
void LCD_WR_SPI_DMA(uint16_t *img, uint32_t len)
{
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_32BIT;
DMA_DEV(dma_ch3)->src_burst_size = 0;
DMA_DEV(dma_ch3)->dst_burst_size = 1;
device_control(spi0, DEVICE_CTRL_TX_DMA_RESUME, NULL);
CS1_LOW;
DC_HIGH;
dma_reload(dma_ch3, (uint32_t)img, (uint32_t)DMA_ADDR_SPI_TDR, len);
dma_channel_start(dma_ch3);
while (dma_channel_check_busy(dma_ch3))
;
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
CS1_HIGH;
}
/****************************************************************************/ /**
* @brief LCD set dir
*
* @param dir: dir
*
* @return None
*
*******************************************************************************/
void LCD_Set_Dir(uint8_t dir)
{
LCD_WR_Cmd(0x36);
switch (dir) {
case 0:
LCD_WR_Byte(0x08);
break;
case 1:
LCD_WR_Byte(0xA8);
break;
case 2:
LCD_WR_Byte(0xC8);
break;
case 3:
LCD_WR_Byte(0x68);
break;
default:
break;
}
}
/****************************************************************************/ /**
* @brief LCD set address
*
* @param x1: Coordinate x start
* @param y1: Coordinate y start
* @param x2: Coordinate x end
* @param y2: Coordinate y end
*
* @return None
*
*******************************************************************************/
void LCD_Set_Addr(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
{
LCD_WR_Cmd(0x2a);
LCD_WR_Word(x2 << 24 | (x2 << 8 & 0xff0000) | (x1 << 8 & 0xff00) | (x1 >> 8 & 0xff));
LCD_WR_Cmd(0x2b);
LCD_WR_Word(y2 << 24 | (y2 << 8 & 0xff0000) | (y1 << 8 & 0xff00) | (y1 >> 8 & 0xff));
LCD_WR_Cmd(0x2C);
}
/****************************************************************************/ /**
* @brief SPI LCD init
*
* @param None
*
* @return None
*
*******************************************************************************/
void LCD_Init(void)
{
spi0_init();
LCD_WR_Cmd(0x11); /* Exit sleep */
bflb_platform_delay_ms(60);
LCD_WR_Cmd(0xcf);
LCD_WR_HalfWord(0xd900);
LCD_WR_Byte(0X30);
LCD_WR_Cmd(0xed);
LCD_WR_Word(0x81120364);
LCD_WR_Cmd(0xe8);
LCD_WR_HalfWord(0x1085);
LCD_WR_Byte(0x78);
LCD_WR_Cmd(0xcb);
LCD_WR_Word(0x34002c39);
LCD_WR_Byte(0x02);
LCD_WR_Cmd(0xf7);
LCD_WR_Byte(0x20);
LCD_WR_Cmd(0xea);
LCD_WR_HalfWord(0x0000);
LCD_WR_Cmd(0xc0); /* Power control */
LCD_WR_Byte(0x23); /* VRH[5:0] */
LCD_WR_Cmd(0xc1); /* Power control */
LCD_WR_Byte(0x12); /* SAP[2:0];BT[3:0] */
LCD_WR_Cmd(0xc2);
LCD_WR_Byte(0x11);
LCD_WR_Cmd(0xC5); /* VCM control */
LCD_WR_HalfWord(0x3040);
LCD_WR_Cmd(0xc7); /* VCM control2 */
LCD_WR_Byte(0xa9);
LCD_WR_Cmd(0x3a);
LCD_WR_Byte(0x55);
LCD_WR_Cmd(0x36); /* Memory Access Control */
LCD_WR_Byte(0x08);
LCD_WR_Cmd(0xb1); /* Frame Rate Control */
LCD_WR_HalfWord(0x1800);
LCD_WR_Cmd(0xb6); /* Display Function Control */
LCD_WR_HalfWord(0xa20a);
LCD_WR_Cmd(0x0c); /* display pixel format */
LCD_WR_Byte(0xd5); /* RGB 16bits,MCU 16bits */
LCD_WR_Cmd(0xf2); /* 3Gamma Function Disable */
LCD_WR_Byte(0x00);
LCD_WR_Cmd(0xf7);
LCD_WR_Byte(0x20);
LCD_WR_Cmd(0x26); /* Gamma curve selected */
LCD_WR_Byte(0x01);
LCD_WR_Cmd(0xe0); /* Set Gamma */
LCD_WR_Word(0x0b23241f);
LCD_WR_Word(0xd850080f);
LCD_WR_Word(0x000a083b);
LCD_WR_HalfWord(0x0000);
LCD_WR_Byte(0x00);
LCD_WR_Cmd(0Xe1); /* Set Gamma */
LCD_WR_Word(0x041c1b00);
LCD_WR_Word(0x272f0710);
LCD_WR_Word(0x0f150744);
LCD_WR_HalfWord(0x3f3f);
LCD_WR_Byte(0x1f);
LCD_WR_Cmd(0x29); /* Display on */
}
/****************************************************************************/ /**
* @brief LCD clear display
*
* @param color: Color to fill
*
* @return None
*
*******************************************************************************/
void LCD_Clear(uint16_t color)
{
uint16_t i, j;
LCD_Set_Addr(0, 0, LCD_W - 1, LCD_H - 1);
for (i = 0; i < LCD_W; i++) {
for (j = 0; j < LCD_H; j++) {
LCD_WR_HalfWord(color);
}
}
}
/****************************************************************************/ /**
* @brief LCD draw a point
*
* @param x: Coordinate x
* @param y: Coordinate y
* @param color: Color of the point
*
* @return None
*
*******************************************************************************/
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color)
{
LCD_Set_Addr(x, y, x, y);
LCD_WR_HalfWord(color);
}
/****************************************************************************/ /**
* @brief LCD draw line
*
* @param x1: Coordinate x start
* @param y1: Coordinate y start
* @param x2: Coordinate x end
* @param y2: Coordinate y end
* @param color: Color of the line
*
* @return None
*
*******************************************************************************/
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
int xVariation, yVariation, temp;
int absX, absY, i;
xVariation = x2 - x1;
yVariation = y2 - y1;
absX = ABS32(xVariation);
absY = ABS32(yVariation);
if (absX > absY) {
for (i = 0; i < absX + 1; i++) {
temp = yVariation * 100 / absX * i / 100;
if (xVariation > 0) {
LCD_DrawPoint(x1 + i, y1 + temp, color);
} else {
LCD_DrawPoint(x1 - i, y1 + temp, color);
}
}
} else {
for (i = 0; i < absY + 1; i++) {
temp = xVariation * 100 / absY * i / 100;
if (yVariation > 0) {
LCD_DrawPoint(x1 + temp, y1 + i, color);
} else {
LCD_DrawPoint(x1 + temp, y1 - i, color);
}
}
}
}
/****************************************************************************/ /**
* @brief LCD draw rectangle
*
* @param x1: Coordinate x start
* @param y1: Coordinate y start
* @param x2: Coordinate x end
* @param y2: Coordinate y end
* @param color: Color of the rectangle
*
* @return None
*
*******************************************************************************/
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
LCD_DrawLine(x1, y1, x2, y1, color);
LCD_DrawLine(x2, y1, x2, y2, color);
LCD_DrawLine(x2, y2, x1, y2, color);
LCD_DrawLine(x1, y2, x1, y1, color);
}
/****************************************************************************/ /**
* @brief LCD draw circle
*
* @param x: Center coordinate x
* @param y: Center coordinate y
* @param r: Radius
* @param color: Color of the circle
*
* @return None
*
*******************************************************************************/
void LCD_DrawCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color)
{
int a = 0, b;
int di;
b = r;
di = 3 - (r << 1);
while (a <= b) {
LCD_DrawPoint(x - b, y - a, color);
LCD_DrawPoint(x + b, y - a, color);
LCD_DrawPoint(x - a, y + b, color);
LCD_DrawPoint(x - b, y - a, color);
LCD_DrawPoint(x - a, y - b, color);
LCD_DrawPoint(x + b, y + a, color);
LCD_DrawPoint(x + a, y - b, color);
LCD_DrawPoint(x + a, y + b, color);
LCD_DrawPoint(x - b, y + a, color);
a++;
if (di < 0) {
di += 4 * a + 6;
} else {
di += 10 + 4 * (a - b);
b--;
}
LCD_DrawPoint(x + a, y + b, color);
}
}
/****************************************************************************/ /**
* @brief LCD fill the area with color
*
* @param x1: Coordinate x start
* @param y1: Coordinate y start
* @param x2: Coordinate x end
* @param y2: Coordinate y end
* @param color: Color to fill
*
* @return None
*
*******************************************************************************/
void LCD_DrawArea(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
uint16_t i, j;
LCD_Set_Addr(x1, y1, x2, y2);
for (i = y1; i <= y2; i++) {
for (j = x1; j <= x2; j++) {
LCD_WR_HalfWord(color);
}
}
}
/****************************************************************************/ /**
* @brief LCD draw picture
*
* @param x1: Coordinate x start
* @param y1: Coordinate y start
* @param x2: Coordinate x end
* @param y2: Coordinate y end
* @param picture: Color array of the picture
*
* @return None
*
*******************************************************************************/
void LCD_DrawPicture(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
uint32_t i;
LCD_Set_Addr(x1, y1, x2, y2);
for (i = 0; i < ABS16((x2 - x1 + 1) * (y2 - y1 + 1)); i++) {
LCD_WR_HalfWord(picture[i]);
}
}
void LCD_DrawPicture_cam(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
uint32_t i;
LCD_Set_Addr(x1, y1, x2, y2);
for (i = 0; i < ABS16((x2 - x1 + 1) * (y2 - y1 + 1)); i++) {
// LCD_WR_Byte(picture[i]);
// LCD_WR_Word(picture[i]);
LCD_WR_HalfWord(picture[i]);
}
}
/****************************************************************************/ /**
* @brief LCD use uart to receive picture data and send to display
*
* @param x1: Coordinate x start
* @param y1: Coordinate y start
* @param x2: Coordinate x end
* @param y2: Coordinate y end
* @param uartId: Color array of the picture
*
* @return None
*
*******************************************************************************/
// void LCD_UartDrawPicture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,UART_ID_Type uartId)
// {
// uint32_t rxLen = 0,i;
// uint32_t recvCnt = 0;
// uint8_t uartRxBuf[UART_RX_FIFO_SIZE] = {0};
// LCD_Set_Addr(x1,y1,x2,y2);
// UART_Enable(uartId,UART_RX);
// while(rxLen < 2*(x2-x1+1)*(y2-y1+1)){
// while((recvCnt=UART_GetRxFifoCount(uartId)) == 0){}
// rxLen += UART_ReceiveData(uartId,uartRxBuf,recvCnt);
// for(i=0;i<recvCnt;i++){
// LCD_WR_Byte(uartRxBuf[i]);
// }
// }
// UART_Disable(uartId,UART_RX);
// }
/****************************************************************************/ /**
* @brief LCD draw a 32*32 chinese character in lattice mode
*
* @param x: Coordinate x
* @param y: Coordinate y
* @param character: Array of the character
* @param bColor: Color of the background
* @param cColor: Color of the character
*
* @return None
*
*******************************************************************************/
void LCD_DrawChinese(uint16_t x, uint16_t y, uint8_t *character, uint16_t bk_color, uint16_t color)
{
uint8_t i, j;
LCD_Set_Addr(x, y, x + 31, y + 31);
for (j = 0; j < 128; j++) {
for (i = 0; i < 8; i++) {
if ((*character & (1 << i)) != 0) {
LCD_WR_HalfWord(color);
} else {
LCD_WR_HalfWord(bk_color);
}
}
character++;
}
}
//高效优化的混合字符串显示函数
// color为字体颜色bk_color为背景颜色,num为最大显示数量(汉字算两个)
void LCD_DrawFont(uint16_t x, uint16_t y, uint16_t color, uint16_t bk_color, uint8_t *str, uint8_t num)
{
uint8_t i, j, k, x0 = x;
uint8_t temp, m;
for (i = 0; i < num && *str; i++, str++) {
if (*str < 128) {
if (x > LCD_W - 7) {
x = x0;
y += 16;
}
if (x > LCD_W - 7 || y >= LCD_H - 16)
break; //空间不足
LCD_Set_Addr(x, y, x + 7, y + 15); //设置显示区
m = *str;
if (m > ' ')
m = m - ' ';
else
m = 0;
for (j = 0; j < 16; j++) //16字节点阵数据
{
temp = ascii_16x8[m * 16 + j];
for (k = 0; k < 8; k++) {
if (temp & (0x80 >> k))
LCD_WR_HalfWord(color);
else
LCD_WR_HalfWord(bk_color);
}
}
x += 8;
}
/*
//中文字符
else {
if (x > LCD_W - 15) {
x = x0;
y += 16;
} //自动换行
if (x > LCD_W - 15 || y >= LCD_H - 16)
break; //空间不足
Lcd_SetRegion(x, y, x + 15, y + 15); //设置显示区
for (j = 0; j < GBK_1616_WORD_NUM; j++) //检索法
{
if (GBK_1616[j].name[0] == str[0] && (GBK_1616[j].name[1] == str[1]))
break;
}
if (j < GBK_1616_WORD_NUM) //检索成功
for (k = 0; k < 32; k++) //32个字节点阵数据
{
temp = GBK_1616[j].dat[k];
for (l = 0; l < 8; l++) {
if (temp & (0x80 >> l))
LCD_WriteData_16Bit(color);
else
LCD_WriteData_16Bit(bk_color);
}
}
else //检索成功失败,直接显示背景色
for (j = 0; j < 16; j++)
for (k = 0; k < 16; k++)
LCD_WriteData_16Bit(bk_color);
//汉字码两字节需要额外加1
str++;
x += 16;
}
*/
}
}
void LCD_DrawFont_64x32(uint16_t x, uint16_t y, uint16_t color, uint16_t bk_color, uint8_t *str, uint8_t num)
{
uint16_t i, j, k, x0 = x;
uint8_t temp, m;
for (i = 0; i < num && *str; i++, str++) {
if (x > LCD_W - 31) {
x = x0;
y += 64;
}
if (x > LCD_W - 31 || y >= LCD_H - 64)
break; //空间不足
LCD_Set_Addr(x, y, x + 31, y + 63); //设置显示区
m = *str;
if (m > '0')
m = m - '0';
else
m = 0;
for (j = 0; j < 256; j++) //128字节点阵数据
{
temp = ascii_64x32[m * 256 + j];
for (k = 0; k < 8; k++) {
if (temp & (0x80 >> k))
LCD_WR_HalfWord(color);
else
LCD_WR_HalfWord(bk_color);
}
}
x += 32;
}
}
/*@} end of group TFT_LCD_Public_Functions */
/*@} end of group TFT_LCD */
/*@} end of group BL702_Peripheral_Case */

View File

@@ -0,0 +1,111 @@
/**
* @file bsp_il9341.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __TFT_LCD_H__
#define __TFT_LCD_H__
#include "hal_gpio.h"
/** @addtogroup BL702_Peripheral_Driver
* @{
*/
/** @addtogroup TFT_LCD
* @{
*/
/** @defgroup TFT_LCD_Public_Types
* @{
*/
/*@} end of group TFT_LCD_Public_Types */
/** @defgroup TFT_LCD_Public_Constants
* @{
*/
/*@} end of group TFT_LCD_Public_Constants */
/** @defgroup TFT_LCD_Public_Macros
* @{
*/
#define LCD_CS_PIN GPIO_PIN_10
#define LCD_DC_PIN GPIO_PIN_22
#define CS1_HIGH gpio_write(LCD_CS_PIN, 1)
#define CS1_LOW gpio_write(LCD_CS_PIN, 0)
#define DC_HIGH gpio_write(LCD_DC_PIN, 1)
#define DC_LOW gpio_write(LCD_DC_PIN, 0)
#define LCD_W 240 /* LCD width */
#define LCD_H 320 /* LCD height */
/* Turn 24-bit RGB color to 16-bit */
#define RGB(r, g, b) (((r >> 3) << 3 | (g >> 5) | (g >> 2) << 13 | (b >> 3) << 8) & 0xffff)
/* Calculate 32-bit or 16-bit absolute value */
#define ABS32(value) ((value ^ (value >> 31)) - (value >> 31))
#define ABS16(value) ((value ^ (value >> 15)) - (value >> 15))
/*@} end of group TFT_LCD_Public_Macros */
/** @defgroup TFT_LCD_Public_Functions
* @{
*/
/**
* @brief Tft_lcd Functions
*/
#ifdef __cplusplus
extern "C"{
#endif
void LCD_WR_Cmd(uint8_t command);
void LCD_WR_Byte(uint8_t data);
void LCD_WR_HalfWord(uint16_t data);
void LCD_WR_Word(uint32_t data);
void LCD_Set_Dir(uint8_t dir);
void LCD_Set_Addr(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void LCD_Init(void);
void LCD_Clear(uint16_t color);
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color);
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void LCD_DrawCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color);
void LCD_DrawArea(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void LCD_DrawPicture(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
void LCD_DrawPicture_cam(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
void LCD_WR_SPI_DMA(uint16_t *img, uint32_t len);
// void LCD_UartDrawPicture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,UART_ID_Type uartId);
void LCD_DrawChinese(uint16_t x, uint16_t y, uint8_t *character, uint16_t bColor, uint16_t cColor);
void LCD_DrawFont(uint16_t x, uint16_t y, uint16_t color, uint16_t bk_color, uint8_t *str, uint8_t num);
void LCD_DrawFont_64x32(uint16_t x, uint16_t y, uint16_t color, uint16_t bk_color, uint8_t *str, uint8_t num);
#ifdef __cplusplus
}
#endif
/*@} end of group TFT_LCD_Public_Functions */
/*@} end of group TFT_LCD */
/*@} end of group BL702_Peripheral_Driver */
#endif /* __TFT_LCD_H__ */

View File

@@ -0,0 +1,301 @@
/**
* @file font_ascii_16x8.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __FONT_ASCII_16X8_H__
#define __FONT_ASCII_16X8_H__
// clang-format off
const unsigned char ascii_16x8[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //" "
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x10,0x10,0x00,0x00, //"!"
0x00,0x00,0x6C,0x6C,0x24,0x24,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, //"""
0x00,0x24,0x24,0x24,0x24,0xFE,0x48,0x48,0x48,0x48,0xFC,0x90,0x90,0x90,0x90,0x00, //"#"
0x00,0x10,0x3C,0x54,0x92,0x90,0x50,0x38,0x14,0x12,0x12,0x92,0x54,0x78,0x10,0x00, //"$"
0x00,0x00,0x22,0x5C,0x94,0xA8,0x48,0x10,0x10,0x24,0x2A,0x52,0x54,0x88,0x00,0x00, //"%"
0x00,0x00,0x30,0x48,0x48,0x50,0x20,0x6E,0x54,0x94,0x8C,0x88,0x8A,0x74,0x00,0x00, //"&"
0x00,0x00,0x30,0x30,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"'"
0x00,0x04,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x00, //"("
0x00,0x80,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x00, //")"
0x00,0x00,0x00,0x00,0x10,0x54,0x38,0x10,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00, //"*"
0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, //"+"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x00, //","
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"-"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00, //"."
0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00, //"/"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"0"
0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, //"1"
0x00,0x00,0x38,0x44,0x82,0x82,0x04,0x08,0x10,0x20,0x40,0x82,0x84,0xFC,0x00,0x00, //"2"
0x00,0x00,0x38,0x44,0x82,0x02,0x04,0x38,0x04,0x02,0x02,0x82,0x44,0x38,0x00,0x00, //"3"
0x00,0x00,0x04,0x0C,0x14,0x14,0x24,0x24,0x44,0x44,0xFE,0x04,0x04,0x0E,0x00,0x00, //"4"
0x00,0x00,0xFC,0x80,0x80,0x80,0xB8,0xC4,0x82,0x02,0x02,0x82,0x84,0x78,0x00,0x00, //"5"
0x00,0x00,0x3C,0x42,0x82,0x80,0xB8,0xC4,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"6"
0x00,0x00,0x7E,0x42,0x82,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x10,0x10,0x00,0x00, //"7"
0x00,0x00,0x38,0x44,0x82,0x82,0x44,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"8"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x46,0x3A,0x02,0x82,0x44,0x38,0x00,0x00, //"9"
0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00, //":"
0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x00,0x00, //";"
0x00,0x00,0x00,0x00,0x06,0x18,0x60,0x80,0x60,0x18,0x06,0x00,0x00,0x00,0x00,0x00, //"<"
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, //"="
0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x02,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00, //">"
0x00,0x38,0x44,0x82,0x82,0x02,0x04,0x08,0x10,0x10,0x10,0x00,0x10,0x10,0x00,0x00, //"?"
0x00,0x00,0x38,0x44,0x82,0x9A,0xAA,0xAA,0xAA,0xAA,0xAA,0x96,0x80,0x42,0x3C,0x00, //"@"
0x00,0x00,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x7C,0x44,0x44,0xEE,0x00,0x00, //"A"
0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x42,0x42,0x42,0x42,0x42,0xFC,0x00,0x00, //"B"
0x00,0x00,0x3C,0x44,0x82,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x44,0x38,0x00,0x00, //"C"
0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xF8,0x00,0x00, //"D"
0x00,0x00,0xFC,0x44,0x42,0x40,0x44,0x7C,0x44,0x40,0x40,0x42,0x44,0xFC,0x00,0x00, //"E"
0x00,0x00,0xFC,0x44,0x42,0x40,0x44,0x7C,0x44,0x40,0x40,0x40,0x40,0xF0,0x00,0x00, //"F"
0x00,0x00,0x34,0x4C,0x82,0x80,0x80,0x80,0x8E,0x84,0x84,0x84,0x4C,0x34,0x00,0x00, //"G"
0x00,0x00,0xEE,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00, //"H"
0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, //"I"
0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x88,0x70,0x00,0x00, //"J"
0x00,0x00,0xEE,0x44,0x48,0x48,0x50,0x60,0x50,0x48,0x48,0x44,0x44,0xEE,0x00,0x00, //"K"
0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x44,0xFC,0x00,0x00, //"L"
0x00,0x00,0xC6,0x44,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x44,0x44,0x44,0xEE,0x00,0x00, //"M"
0x00,0x00,0xCE,0x44,0x64,0x64,0x64,0x54,0x54,0x4C,0x4C,0x4C,0x44,0xE4,0x00,0x00, //"N"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"O"
0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x44,0x78,0x40,0x40,0x40,0x40,0xE0,0x00,0x00, //"P"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xBA,0x44,0x3C,0x02,0x00, //"Q"
0x00,0x00,0xF0,0x48,0x44,0x44,0x44,0x48,0x70,0x48,0x44,0x44,0x44,0xE6,0x00,0x00, //"R"
0x00,0x00,0x3C,0x44,0x82,0x80,0x40,0x30,0x0C,0x02,0x02,0x82,0x44,0x78,0x00,0x00, //"S"
0x00,0x00,0x7C,0x54,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, //"T"
0x00,0x00,0xEE,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, //"U"
0x00,0x00,0xEE,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x28,0x10,0x10,0x10,0x00,0x00, //"V"
0x00,0x00,0xEE,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x28,0x28,0x28,0x00,0x00, //"W"
0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x44,0xEE,0x00,0x00, //"X"
0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, //"Y"
0x00,0x00,0x7E,0x44,0x84,0x08,0x08,0x10,0x20,0x20,0x40,0x82,0x84,0xFC,0x00,0x00, //"Z"
0x00,0x1C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1C,0x00, //"["
0x00,0x00,0xEE,0x44,0x54,0x54,0xFE,0x54,0x54,0x54,0x28,0x28,0x28,0x28,0x00,0x00, //"\"
0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, //"]"
0x00,0x30,0x48,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"^"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, //"_"
0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"`"
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x84,0x04,0x7C,0x84,0x84,0x8C,0x76,0x00,0x00, //"a"
0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x42,0x64,0x58,0x00,0x00, //"b"
0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x80,0x80,0x80,0x80,0x44,0x38,0x00,0x00, //"c"
0x00,0x00,0x0C,0x04,0x04,0x04,0x34,0x4C,0x84,0x84,0x84,0x84,0x4C,0x36,0x00,0x00, //"d"
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x84,0x84,0xFC,0x80,0x80,0x84,0x78,0x00,0x00, //"e"
0x00,0x00,0x18,0x24,0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, //"f"
0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0x44,0x44,0x78,0x80,0x7C,0x82,0x82,0x7C,0x00, //"g"
0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00, //"h"
0x00,0x00,0x10,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, //"i"
0x00,0x00,0x10,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00, //"j"
0x00,0x00,0xC0,0x40,0x40,0x40,0x5C,0x48,0x50,0x60,0x50,0x48,0x44,0xEE,0x00,0x00, //"k"
0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x11,0x10,0x10,0x10,0x10,0x10,0x39,0x00,0x00, //"l"
0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xD2,0x92,0x92,0x92,0x92,0x92,0xD6,0x00,0x00, //"m"
0x00,0x00,0x00,0x00,0x00,0x00,0x58,0xE4,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00, //"n"
0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"o"
0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x64,0x42,0x42,0x42,0x64,0x58,0x40,0xE0,0x00, //"p"
0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x4C,0x84,0x84,0x84,0x4C,0x34,0x04,0x0E,0x00, //"q"
0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x30,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, //"r"
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x84,0x60,0x18,0x84,0x44,0x78,0x00,0x00, //"s"
0x00,0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00, //"t"
0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, //"u"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, //"v"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x44,0x54,0x54,0x28,0x28,0x28,0x00,0x00, //"w"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x28,0x10,0x10,0x28,0x44,0xEE,0x00,0x00, //"x"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0xA0,0xC0,0x00, //"y"
0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x88,0x10,0x20,0x42,0x84,0xFC,0x00,0x00, //"z"
0x00,0x0C,0x10,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x10,0x0C,0x00, //"{"
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, //"|"
0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0x20,0x20,0xC0,0x00, //"}"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x8C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"~"
0x00,
};
const unsigned char ascii_64x32[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,
0x00,0x1F,0xFE,0x00,0x00,0x7F,0xFF,0x80,0x00,0xFF,0x1F,0xC0,0x00,0xFC,0x0F,0xE0,
0x01,0xF8,0x07,0xE0,0x03,0xF8,0x03,0xF0,0x03,0xF0,0x03,0xF0,0x07,0xF0,0x01,0xF8,
0x07,0xE0,0x01,0xF8,0x07,0xE0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xE0,0x00,0xFC,0x07,0xE0,0x01,0xF8,0x07,0xE0,0x01,0xF8,0x03,0xF0,0x03,0xF0,
0x03,0xF8,0x03,0xF0,0x01,0xF8,0x07,0xE0,0x00,0xFC,0x0F,0xC0,0x00,0xFF,0x1F,0xC0,
0x00,0x3F,0xFF,0x80,0x00,0x1F,0xFE,0x00,0x00,0x07,0xF8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"0",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,
0x00,0x00,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x07,0xF0,0x00,0x01,0xFF,0xF0,0x00,
0x01,0xFF,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xF8,0x00,
0x00,0x0F,0xFC,0x00,0x01,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"1",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFC,0x00,
0x00,0x3F,0xFF,0x80,0x00,0xFF,0xFF,0xE0,0x01,0xFC,0x1F,0xF0,0x03,0xF0,0x07,0xF0,
0x07,0xE0,0x03,0xF8,0x07,0xE0,0x01,0xF8,0x0F,0xC0,0x01,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xE0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x07,0xE0,0x01,0xFC,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,
0x00,0x00,0x03,0xF8,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xE0,
0x00,0x00,0x1F,0xC0,0x00,0x00,0x3F,0x80,0x00,0x00,0x7F,0x00,0x00,0x00,0xFE,0x00,
0x00,0x01,0xFC,0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xC0,0x00,
0x00,0x1F,0x80,0x00,0x00,0x3F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0xFC,0x00,0x3C,
0x01,0xF8,0x00,0x3C,0x03,0xF0,0x00,0x3C,0x03,0xE0,0x00,0x3C,0x07,0xE0,0x00,0x7C,
0x0F,0xC0,0x00,0xF8,0x1F,0x80,0x01,0xF8,0x1F,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xF8,
0x1F,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"2",2*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,
0x00,0x7F,0xFE,0x00,0x00,0xFF,0xFF,0x80,0x01,0xF8,0x7F,0xC0,0x03,0xE0,0x1F,0xC0,
0x03,0xC0,0x0F,0xE0,0x07,0xC0,0x07,0xE0,0x07,0xC0,0x07,0xF0,0x07,0xE0,0x03,0xF0,
0x07,0xE0,0x03,0xF0,0x07,0xE0,0x03,0xF0,0x07,0xE0,0x03,0xF0,0x03,0xC0,0x03,0xF0,
0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xC0,
0x00,0x00,0x1F,0xC0,0x00,0x00,0xFF,0x00,0x00,0x0F,0xFE,0x00,0x00,0x0F,0xFE,0x00,
0x00,0x0F,0xFF,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x07,0xF0,
0x00,0x00,0x03,0xF0,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xFC,
0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x03,0xE0,0x00,0xFC,0x07,0xF0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x01,0xFC,0x0F,0xF0,0x01,0xF8,
0x0F,0xE0,0x03,0xF8,0x07,0xE0,0x03,0xF0,0x07,0xF0,0x07,0xE0,0x03,0xFC,0x1F,0xC0,
0x01,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0x00,0x00,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"3",3*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,
0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x3F,0x80,0x00,0x00,0x3F,0x80,
0x00,0x00,0x7F,0x80,0x00,0x00,0xFF,0x80,0x00,0x00,0xFF,0x80,0x00,0x01,0xFF,0x80,
0x00,0x03,0xFF,0x80,0x00,0x03,0xFF,0x80,0x00,0x07,0xDF,0x80,0x00,0x0F,0x9F,0x80,
0x00,0x0F,0x9F,0x80,0x00,0x1F,0x1F,0x80,0x00,0x3E,0x1F,0x80,0x00,0x3E,0x1F,0x80,
0x00,0x7C,0x1F,0x80,0x00,0xF8,0x1F,0x80,0x00,0xF8,0x1F,0x80,0x01,0xF0,0x1F,0x80,
0x03,0xE0,0x1F,0x80,0x03,0xE0,0x1F,0x80,0x07,0xC0,0x1F,0x80,0x0F,0x80,0x1F,0x80,
0x0F,0x80,0x1F,0x80,0x1F,0x00,0x1F,0x80,0x3E,0x00,0x1F,0x80,0x3F,0xFF,0xFF,0xFF,
0x3F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,
0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,
0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,
0x00,0x00,0x3F,0xC0,0x00,0x07,0xFF,0xFE,0x00,0x07,0xFF,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"4",4*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF8,
0x01,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xF0,
0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,
0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xC0,0x00,0x00,
0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC7,0xFE,0x00,0x03,0xDF,0xFF,0x80,
0x03,0xFF,0xFF,0xC0,0x03,0xFE,0x1F,0xE0,0x03,0xF8,0x07,0xF0,0x03,0xF0,0x03,0xF0,
0x03,0xE0,0x03,0xF8,0x03,0xE0,0x01,0xF8,0x03,0x80,0x01,0xF8,0x00,0x00,0x01,0xFC,
0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,
0x00,0x00,0x00,0xFC,0x03,0xE0,0x00,0xFC,0x07,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x01,0xF8,0x0F,0xF0,0x01,0xF8,0x0F,0xE0,0x01,0xF8,
0x0F,0xE0,0x03,0xF0,0x07,0xE0,0x07,0xF0,0x03,0xF0,0x0F,0xE0,0x01,0xFC,0x1F,0xC0,
0x00,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"5",5*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x00,
0x00,0x0F,0xFF,0xC0,0x00,0x1F,0xFF,0xF0,0x00,0x3F,0x87,0xF0,0x00,0x7E,0x03,0xF8,
0x00,0xFC,0x03,0xF8,0x01,0xF8,0x03,0xF8,0x03,0xF0,0x03,0xF8,0x03,0xE0,0x01,0xF0,
0x07,0xE0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x0F,0xC0,0x00,0x00,
0x0F,0xC0,0x00,0x00,0x0F,0xC0,0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x83,0xFE,0x00,
0x1F,0x9F,0xFF,0xC0,0x1F,0xBF,0xFF,0xE0,0x1F,0xFF,0x0F,0xF0,0x1F,0xFC,0x03,0xF8,
0x1F,0xF8,0x01,0xF8,0x1F,0xF0,0x01,0xFC,0x1F,0xE0,0x00,0xFC,0x1F,0xC0,0x00,0xFC,
0x1F,0xC0,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x0F,0xC0,0x00,0x7E,0x0F,0xC0,0x00,0x7E,
0x0F,0xC0,0x00,0x7E,0x0F,0xC0,0x00,0xFE,0x07,0xE0,0x00,0xFC,0x07,0xF0,0x00,0xFC,
0x03,0xF0,0x01,0xF8,0x03,0xF8,0x01,0xF8,0x01,0xFC,0x03,0xF0,0x00,0xFF,0x0F,0xE0,
0x00,0x7F,0xFF,0xC0,0x00,0x3F,0xFF,0x80,0x00,0x07,0xFC,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"6",6*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFC,
0x07,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xF8,
0x07,0xF0,0x00,0xF0,0x07,0xC0,0x01,0xF0,0x07,0x80,0x01,0xE0,0x0F,0x80,0x03,0xE0,
0x0F,0x00,0x03,0xC0,0x0F,0x00,0x07,0xC0,0x0F,0x00,0x0F,0x80,0x00,0x00,0x0F,0x80,
0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3E,0x00,
0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,
0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x07,0xE0,0x00,
0x00,0x07,0xE0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x0F,0xE0,0x00,
0x00,0x0F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,
0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,
0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"7",7*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFC,0x00,
0x00,0x7F,0xFF,0x80,0x00,0xFF,0xFF,0xC0,0x01,0xFE,0x1F,0xE0,0x03,0xF8,0x07,0xF0,
0x07,0xF0,0x03,0xF8,0x07,0xE0,0x01,0xF8,0x0F,0xE0,0x01,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xE0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x07,0xF0,0x01,0xF8,0x07,0xFC,0x01,0xF8,0x03,0xFE,0x03,0xF0,
0x03,0xFF,0x87,0xE0,0x01,0xFF,0xEF,0xC0,0x00,0xFF,0xFF,0x80,0x00,0x3F,0xFE,0x00,
0x00,0x7F,0xFF,0x00,0x00,0xFF,0xFF,0x80,0x01,0xF8,0xFF,0xC0,0x03,0xF0,0x7F,0xE0,
0x07,0xE0,0x1F,0xF0,0x0F,0xE0,0x0F,0xF8,0x0F,0xC0,0x07,0xF8,0x0F,0xC0,0x03,0xF8,
0x1F,0xC0,0x01,0xFC,0x1F,0x80,0x01,0xFC,0x1F,0x80,0x00,0xFC,0x1F,0x80,0x00,0xFC,
0x1F,0x80,0x00,0xFC,0x1F,0x80,0x00,0xFC,0x1F,0xC0,0x00,0xFC,0x0F,0xC0,0x01,0xF8,
0x0F,0xE0,0x01,0xF8,0x07,0xE0,0x03,0xF0,0x07,0xF8,0x07,0xF0,0x03,0xFC,0x1F,0xE0,
0x00,0xFF,0xFF,0xC0,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"8",8*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,
0x00,0x7F,0xFF,0x00,0x00,0xFF,0xFF,0x80,0x01,0xFE,0x1F,0xC0,0x03,0xF8,0x07,0xE0,
0x07,0xF0,0x03,0xF0,0x07,0xE0,0x01,0xF0,0x0F,0xC0,0x01,0xF8,0x0F,0xC0,0x00,0xF8,
0x0F,0xC0,0x00,0xFC,0x1F,0x80,0x00,0xFC,0x1F,0x80,0x00,0x7C,0x1F,0x80,0x00,0x7C,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0xC0,0x00,0xFE,0x1F,0xC0,0x00,0xFE,0x0F,0xC0,0x01,0xFE,
0x0F,0xE0,0x03,0xFE,0x0F,0xF0,0x07,0xFE,0x07,0xF8,0x0F,0xFE,0x03,0xFC,0x3F,0xFE,
0x01,0xFF,0xFF,0x7E,0x00,0xFF,0xFC,0xFE,0x00,0x1F,0xF0,0xFC,0x00,0x00,0x00,0xFC,
0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,
0x00,0x00,0x01,0xF8,0x00,0x00,0x03,0xF0,0x03,0xE0,0x03,0xF0,0x07,0xF0,0x07,0xE0,
0x07,0xF0,0x0F,0xE0,0x07,0xF0,0x0F,0xC0,0x07,0xF0,0x3F,0x80,0x07,0xF8,0xFF,0x00,
0x03,0xFF,0xFE,0x00,0x01,0xFF,0xF8,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"9",9*/
};
// clang-format on
#endif // __FONT_ASCII_16X8_H__

View File

@@ -0,0 +1,865 @@
/**
* @file bsp_gc0308.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "bsp_image_sensor.h"
#include "bl702_glb.h"
#include "hal_gpio.h"
#include "hal_timer.h"
#include "hal_i2c.h"
#include "hal_cam.h"
#include "hal_mjpeg.h"
#include "hal_clock.h"
#define IMAGE_SENSOR_BF2013 0
#define IMAGE_SENSOR_GC0308 1
#define IMAGE_SENSOR_USE IMAGE_SENSOR_GC0308
#define CAM_USING_INT_MODE 0
#define CAM_USING_POLL_MODE 1
#define CAM_MODE CAM_USING_INT_MODE
/* sensor out format */
#define RGB565 0
#define UYVY 1
#define YUYV 2
#define FORMAT_SEL RGB565
#if (IMAGE_SENSOR_USE == IMAGE_SENSOR_BF2013)
#define I2C_CAMERA_ADDR 0x6E
#define BF2013_ID_MSB 0xFC
#define BF2013_ID_LSB 0xFD
#elif (IMAGE_SENSOR_USE == IMAGE_SENSOR_GC0308)
#define I2C_CAMERA_ADDR 0x21
#define GC0308_ID 0x00
#endif
struct device *image_sensor_i2c = NULL;
static const uint8_t sensorRegList[][2] = {
#if (IMAGE_SENSOR_USE == IMAGE_SENSOR_BF2013)
{ 0x12, 0x80 },
{ 0x67, 0x00 },
{ 0x68, 0x00 },
//{0xb9, 0x80},//use Test pattern
//{0x69,0x20},
#if (FORMAT_SEL == UYVY)
{ 0x3a, 0x02 },
#elif (FORMAT_SEL == YUYV)
{ 0x3a, 0x00 },
#endif
{ 0x09, 0x01 },
{ 0x15, 0x02 },
{ 0x12, 0x00 },
{ 0x1e, 0x00 },
{ 0x13, 0x00 },
{ 0x01, 0x14 },
{ 0x02, 0x21 },
{ 0x8c, 0x02 },
{ 0x8d, 0x64 },
{ 0x87, 0x18 },
{ 0x13, 0x07 },
//{0x11,0x80},//pclk=mclk
{ 0x11, 0x30 }, //pclk=mclk/8
{ 0x2b, 0x20 },
{ 0x92, 0x40 },
{ 0x9d, 0x99 },
{ 0x06, 0xe0 },
{ 0x29, 0x54 },
{ 0xeb, 0x30 },
{ 0xbb, 0x20 },
{ 0xf5, 0x21 },
{ 0xe1, 0x3c },
{ 0x16, 0x01 },
{ 0xe0, 0x0b },
{ 0x2f, 0xf6 },
{ 0x33, 0x20 },
{ 0x34, 0x08 },
{ 0x35, 0x50 },
{ 0x65, 0x4a },
{ 0x66, 0x50 },
{ 0x36, 0x05 },
{ 0x37, 0xf6 },
{ 0x38, 0x46 },
{ 0x9b, 0xf6 },
{ 0x9c, 0x46 },
{ 0xbc, 0x01 },
{ 0xbd, 0xf6 },
{ 0xbe, 0x46 },
{ 0x82, 0x14 },
{ 0x83, 0x23 },
{ 0x9a, 0x23 },
{ 0x70, 0x6f },
{ 0x72, 0x3f },
{ 0x73, 0x3f },
{ 0x74, 0x27 },
{ 0x77, 0x90 },
{ 0x79, 0x48 },
{ 0x7a, 0x1e },
{ 0x7b, 0x30 },
{ 0x84, 0x1a },
{ 0x85, 0x20 },
{ 0x89, 0x02 },
{ 0x8a, 0x64 },
{ 0x86, 0x30 },
{ 0x96, 0xa6 },
{ 0x97, 0x0c },
{ 0x98, 0x18 },
{ 0x80, 0x55 },
{ 0x24, 0x70 },
{ 0x25, 0x80 },
{ 0x94, 0x0a },
{ 0x1f, 0x20 },
{ 0x22, 0x20 },
{ 0x26, 0x20 },
{ 0x56, 0x40 },
{ 0x61, 0xd3 },
{ 0x79, 0x48 },
{ 0x3b, 0x60 },
{ 0x3c, 0x20 },
{ 0x39, 0x80 },
{ 0x3f, 0xb0 },
{ 0x39, 0x80 },
{ 0x40, 0x58 },
{ 0x41, 0x54 },
{ 0x42, 0x4e },
{ 0x43, 0x44 },
{ 0x44, 0x3e },
{ 0x45, 0x39 },
{ 0x46, 0x35 },
{ 0x47, 0x31 },
{ 0x48, 0x2e },
{ 0x49, 0x2b },
{ 0x4b, 0x29 },
{ 0x4c, 0x27 },
{ 0x4e, 0x23 },
{ 0x4f, 0x20 },
{ 0x50, 0x1e },
{ 0x51, 0x05 },
{ 0x52, 0x10 },
{ 0x53, 0x0b },
{ 0x54, 0x15 },
{ 0x57, 0x87 },
{ 0x58, 0x72 },
{ 0x59, 0x5f },
{ 0x5a, 0x7e },
{ 0x5b, 0x1f },
{ 0x5c, 0x0e },
{ 0x5d, 0x95 },
{ 0x60, 0x28 },
{ 0xb0, 0xe0 },
{ 0xb1, 0xc0 },
{ 0xb2, 0xb0 },
{ 0xb3, 0x88 },
{ 0x6a, 0x01 },
{ 0x23, 0x66 },
{ 0xa0, 0x03 },
{ 0xa1, 0x31 },
{ 0xa2, 0x0b },
{ 0xa3, 0x26 },
{ 0xa4, 0x05 },
{ 0xa5, 0x25 },
{ 0xa6, 0x06 },
{ 0xa7, 0x80 },
{ 0xa8, 0x80 },
{ 0xa9, 0x20 },
{ 0xaa, 0x20 },
{ 0xab, 0x20 },
{ 0xac, 0x3c },
{ 0xad, 0xf0 },
{ 0xc8, 0x18 },
{ 0xc9, 0x20 },
{ 0xca, 0x17 },
{ 0xcb, 0x1f },
{ 0xaf, 0x00 },
{ 0xc5, 0x18 },
{ 0xc6, 0x00 },
{ 0xc7, 0x20 },
{ 0xae, 0x80 },
{ 0xcc, 0x40 },
{ 0xcd, 0x58 },
{ 0xee, 0x4c },
{ 0x8e, 0x07 },
{ 0x8f, 0x79 },
#elif (IMAGE_SENSOR_USE == IMAGE_SENSOR_GC0308)
{ 0xfe, 0x80 },
{ 0xfe, 0x00 }, //set page0
{ 0xd2, 0x00 }, //close/en AEC; d2[7] set 1b'0 en AEC
{ 0x22, 0x55 }, //close AWB
{ 0x5a, 0x56 },
{ 0x5b, 0x40 },
{ 0x5c, 0x4a },
{ 0x22, 0x57 }, //Open AWB
#if 0
//config for 39 FPS
{0x01, 0x6a}, //HB 106
//{0x02 , 0x70},//VB 112
{0x02, 0x0c}, //change VB from 112 to 12
{0x0f, 0x00},
{0xe2, 0x00}, //anti-flicker step [11:8]
{0xe3, 0x96}, //anti-flicker step [7:0]
{0xe4, 0x01}, //exp level 1 50.00fps or 20ms
{0xe5, 0x2c},
{0xe6, 0x03}, //exp level 2 16.67fps
{0xe7, 0x84},
{0xe8, 0x04}, //exp level 3 12.5fps
{0xe9, 0xb0},
{0xea, 0x09}, //exp level 4 6.00fps
{0xeb, 0xc4},
#elif 0
//config for 33.33 FPS
{ 0x01, 0x6a }, //HB 106
{ 0x02, 0x52 }, //VB 82
{ 0x0f, 0x00 },
{ 0xe2, 0x00 }, //anti-flicker step [11:8]
{ 0xe3, 0x96 }, //anti-flicker step [7:0]
{ 0xe4, 0x01 }, //exp level 1 33.33fps or 30ms
{ 0xe5, 0x2c },
{ 0xe6, 0x03 }, //exp level 2 16.67fps
{ 0xe7, 0x84 },
{ 0xe8, 0x04 }, //exp level 3 12.5fps
{ 0xe9, 0xb0 },
{ 0xea, 0x09 }, //exp level 4 6.00fps
{ 0xeb, 0xc4 },
#else
//config for 25 FPS
{ 0x01, 0x6a }, //HB 106
//{0x02 , 0x70},//VB 112
{ 0x02, 0xe8 }, //change VB from 112 to 232
{ 0x0f, 0x00 },
{ 0xe2, 0x00 }, //anti-flicker step [11:8]
{ 0xe3, 0x96 }, //anti-flicker step [7:0]
{ 0xe4, 0x02 }, //exp level 1 25.00fps or 40ms
{ 0xe5, 0x58 },
{ 0xe6, 0x03 }, //exp level 2 16.67fps
{ 0xe7, 0x84 },
{ 0xe8, 0x04 }, //exp level 3 12.5fps
{ 0xe9, 0xb0 },
{ 0xea, 0x09 }, //exp level 4 6.00fps
{ 0xeb, 0xc4 },
#endif
{ 0xec, 0x20 }, //select max exposure level 1 - highest fps
{ 0xed, 0x04 }, //set AEC select exp min
{ 0x05, 0x00 },
{ 0x06, 0x00 },
{ 0x07, 0x00 },
{ 0x08, 0x00 },
{ 0x09, 0x01 },
{ 0x0a, 0xe8 },
//{0x0a , 0x70},//change win_height from 488 to 368
{ 0x0b, 0x02 },
{ 0x0c, 0x88 }, //win_width 648
{ 0x0d, 0x02 },
{ 0x0e, 0x02 },
{ 0x10, 0x22 },
{ 0x11, 0xfd },
{ 0x12, 0x2a },
{ 0x13, 0x00 },
//{0x14 , 0x10},
{ 0x14, 0x13 }, //enable mirror & flip
//-------------H_V_Switch(4)---------------//
/*
1://normal
{0x14 , 0x10},
2://IMAGE_H_MIRROR
{0x14 , 0x11},
3://IMAGE_V_MIRROR
{0x14 , 0x12},
4://IMAGE_HV_MIRROR
{0x14 , 0x13},*/
{ 0x15, 0x0a },
{ 0x16, 0x05 },
{ 0x17, 0x01 },
{ 0x18, 0x44 },
{ 0x19, 0x44 },
{ 0x1a, 0x1e },
{ 0x1b, 0x00 },
{ 0x1c, 0xc1 },
{ 0x1d, 0x08 },
{ 0x1e, 0x60 },
{ 0x1f, 0x17 },
{ 0x20, 0xff },
{ 0x21, 0xf8 },
{ 0x22, 0x57 },
#if FORMAT_SEL == RGB565
{ 0x24, 0xa6 }, //a6 RGB565
#elif FORMAT_SEL == UYVY
{ 0x24, 0xa0 }, //a0 Cb Y Cr Y
#elif FORMAT_SEL == YUYV
{ 0x24, 0xa2 }, //a2 Y Cb Y Cr
#endif
{ 0x25, 0x0f },
//output sync_mode
//{0x26 , 0x02},//0x03 20101016 zhj
{ 0x26, 0x03 }, //sync mode, high high
{ 0x2f, 0x01 },
{ 0x30, 0xf7 },
{ 0x31, 0x50 },
{ 0x32, 0x00 },
{ 0x39, 0x04 },
{ 0x3a, 0x18 },
{ 0x3b, 0x20 },
{ 0x3c, 0x00 },
{ 0x3d, 0x00 },
{ 0x3e, 0x00 },
{ 0x3f, 0x00 },
{ 0x50, 0x10 },
{ 0x53, 0x82 },
{ 0x54, 0x80 },
{ 0x55, 0x80 },
{ 0x56, 0x82 },
{ 0x8b, 0x40 },
{ 0x8c, 0x40 },
{ 0x8d, 0x40 },
{ 0x8e, 0x2e },
{ 0x8f, 0x2e },
{ 0x90, 0x2e },
{ 0x91, 0x3c },
{ 0x92, 0x50 },
{ 0x5d, 0x12 },
{ 0x5e, 0x1a },
{ 0x5f, 0x24 },
{ 0x60, 0x07 },
{ 0x61, 0x15 },
{ 0x62, 0x08 },
{ 0x64, 0x03 },
{ 0x66, 0xe8 },
{ 0x67, 0x86 },
{ 0x68, 0xa2 },
{ 0x69, 0x18 },
{ 0x6a, 0x0f },
{ 0x6b, 0x00 },
{ 0x6c, 0x5f },
{ 0x6d, 0x8f },
{ 0x6e, 0x55 },
{ 0x6f, 0x38 },
{ 0x70, 0x15 },
{ 0x71, 0x33 },
{ 0x72, 0xdc },
{ 0x73, 0x80 },
{ 0x74, 0x02 },
{ 0x75, 0x3f },
{ 0x76, 0x02 },
{ 0x77, 0x36 },
{ 0x78, 0x88 },
{ 0x79, 0x81 },
{ 0x7a, 0x81 },
{ 0x7b, 0x22 },
{ 0x7c, 0xff },
{ 0x93, 0x48 },
{ 0x94, 0x00 },
{ 0x95, 0x05 },
{ 0x96, 0xe8 },
{ 0x97, 0x40 },
{ 0x98, 0xf0 },
{ 0xb1, 0x38 },
{ 0xb2, 0x38 },
{ 0xbd, 0x38 },
{ 0xbe, 0x36 },
#if 1
{ 0xd0, 0xc9 },
{ 0xd1, 0x10 },
{ 0xd3, 0x80 },
{ 0xd5, 0xf2 },
{ 0xd6, 0x16 },
#else
//default AEC setting
{ 0xd0, 0xca },
{ 0xd1, 0xa1 },
{ 0xd3, 0xa0 },
{ 0xd5, 0xf2 },
{ 0xd6, 0x18 },
#endif
{ 0xdb, 0x92 },
{ 0xdc, 0xa5 },
{ 0xdf, 0x23 },
{ 0xd9, 0x00 },
{ 0xda, 0x00 },
{ 0xe0, 0x09 },
{ 0xed, 0x04 },
#if 0
//default max dgain
{0xee, 0xa0},
{0xef, 0x40},
#else
//increased max dgain
{ 0xee, 0xf0 },
{ 0xef, 0x60 },
#endif
{ 0x80, 0x03 },
{ 0x80, 0x03 },
{ 0x9F, 0x10 },
{ 0xA0, 0x20 },
{ 0xA1, 0x38 },
{ 0xA2, 0x4E },
{ 0xA3, 0x63 },
{ 0xA4, 0x76 },
{ 0xA5, 0x87 },
{ 0xA6, 0xA2 },
{ 0xA7, 0xB8 },
{ 0xA8, 0xCA },
{ 0xA9, 0xD8 },
{ 0xAA, 0xE3 },
{ 0xAB, 0xEB },
{ 0xAC, 0xF0 },
{ 0xAD, 0xF8 },
{ 0xAE, 0xFD },
{ 0xAF, 0xFF },
/*
GC0308_GAMMA_Select,
1://smallest gamma curve
{0x9F , 0x0B},
{0xA0 , 0x16},
{0xA1 , 0x29},
{0xA2 , 0x3C},
{0xA3 , 0x4F},
{0xA4 , 0x5F},
{0xA5 , 0x6F},
{0xA6 , 0x8A},
{0xA7 , 0x9F},
{0xA8 , 0xB4},
{0xA9 , 0xC6},
{0xAA , 0xD3},
{0xAB , 0xDD},
{0xAC , 0xE5},
{0xAD , 0xF1},
{0xAE , 0xFA},
{0xAF , 0xFF},
2:
{0x9F , 0x0E},
{0xA0 , 0x1C},
{0xA1 , 0x34},
{0xA2 , 0x48},
{0xA3 , 0x5A},
{0xA4 , 0x6B},
{0xA5 , 0x7B},
{0xA6 , 0x95},
{0xA7 , 0xAB},
{0xA8 , 0xBF},
{0xA9 , 0xCE},
{0xAA , 0xD9},
{0xAB , 0xE4},
{0xAC , 0xEC},
{0xAD , 0xF7},
{0xAE , 0xFD},
{0xAF , 0xFF},
3:
{0x9F , 0x10},
{0xA0 , 0x20},
{0xA1 , 0x38},
{0xA2 , 0x4E},
{0xA3 , 0x63},
{0xA4 , 0x76},
{0xA5 , 0x87},
{0xA6 , 0xA2},
{0xA7 , 0xB8},
{0xA8 , 0xCA},
{0xA9 , 0xD8},
{0xAA , 0xE3},
{0xAB , 0xEB},
{0xAC , 0xF0},
{0xAD , 0xF8},
{0xAE , 0xFD},
{0xAF , 0xFF},
4:
{0x9F , 0x14},
{0xA0 , 0x28},
{0xA1 , 0x44},
{0xA2 , 0x5D},
{0xA3 , 0x72},
{0xA4 , 0x86},
{0xA5 , 0x95},
{0xA6 , 0xB1},
{0xA7 , 0xC6},
{0xA8 , 0xD5},
{0xA9 , 0xE1},
{0xAA , 0xEA},
{0xAB , 0xF1},
{0xAC , 0xF5},
{0xAD , 0xFB},
{0xAE , 0xFE},
{0xAF , 0xFF},
5://largest gamma curve
{0x9F , 0x15},
{0xA0 , 0x2A},
{0xA1 , 0x4A},
{0xA2 , 0x67},
{0xA3 , 0x79},
{0xA4 , 0x8C},
{0xA5 , 0x9A},
{0xA6 , 0xB3},
{0xA7 , 0xC5},
{0xA8 , 0xD5},
{0xA9 , 0xDF},
{0xAA , 0xE8},
{0xAB , 0xEE},
{0xAC , 0xF3},
{0xAD , 0xFA},
{0xAE , 0xFD},
{0xAF , 0xFF},
*/
//-----------GAMMA Select End--------------//
{ 0xc0, 0x00 },
{ 0xc1, 0x10 },
{ 0xc2, 0x1C },
{ 0xc3, 0x30 },
{ 0xc4, 0x43 },
{ 0xc5, 0x54 },
{ 0xc6, 0x65 },
{ 0xc7, 0x75 },
{ 0xc8, 0x93 },
{ 0xc9, 0xB0 },
{ 0xca, 0xCB },
{ 0xcb, 0xE6 },
{ 0xcc, 0xFF },
{ 0xf0, 0x02 },
{ 0xf1, 0x01 },
{ 0xf2, 0x01 },
{ 0xf3, 0x30 },
{ 0xf9, 0x9f },
{ 0xfa, 0x78 },
//{0xfa , 0x58},//Change measure window Y1 from 480 to 352
//-------------------------------------------------
{ 0xfe, 0x01 }, // set page1
{ 0x00, 0xf5 },
{ 0x02, 0x1a },
{ 0x0a, 0xa0 },
{ 0x0b, 0x60 },
{ 0x0c, 0x08 },
{ 0x0e, 0x4c },
{ 0x0f, 0x39 },
{ 0x11, 0x3f },
{ 0x12, 0x72 },
{ 0x13, 0x13 },
{ 0x14, 0x42 },
{ 0x15, 0x43 },
{ 0x16, 0xc2 },
{ 0x17, 0xa8 },
{ 0x18, 0x18 },
{ 0x19, 0x40 },
{ 0x1a, 0xd0 },
{ 0x1b, 0xf5 },
{ 0x70, 0x40 },
{ 0x71, 0x58 },
{ 0x72, 0x30 },
{ 0x73, 0x48 },
{ 0x74, 0x20 },
{ 0x75, 0x60 },
{ 0x77, 0x20 },
{ 0x78, 0x32 },
{ 0x30, 0x03 },
{ 0x31, 0x40 },
{ 0x32, 0xe0 },
{ 0x33, 0xe0 },
{ 0x34, 0xe0 },
{ 0x35, 0xb0 },
{ 0x36, 0xc0 },
{ 0x37, 0xc0 },
{ 0x38, 0x04 },
{ 0x39, 0x09 },
{ 0x3a, 0x12 },
{ 0x3b, 0x1C },
{ 0x3c, 0x28 },
{ 0x3d, 0x31 },
{ 0x3e, 0x44 },
{ 0x3f, 0x57 },
{ 0x40, 0x6C },
{ 0x41, 0x81 },
{ 0x42, 0x94 },
{ 0x43, 0xA7 },
{ 0x44, 0xB8 },
{ 0x45, 0xD6 },
{ 0x46, 0xEE },
{ 0x47, 0x0d },
{ 0xfe, 0x00 }, //set page0
//-----------Update the registers 2010/07/06-------------//
//Registers of Page0
{ 0xfe, 0x00 }, //set page0
{ 0x10, 0x26 },
{ 0x11, 0x0d }, //fd,modified by mormo 2010/07/06
{ 0x1a, 0x2a }, //1e,modified by mormo 2010/07/06
{ 0x1c, 0x49 }, //c1,modified by mormo 2010/07/06
{ 0x1d, 0x9a }, //08,modified by mormo 2010/07/06
{ 0x1e, 0x61 }, //60,modified by mormo 2010/07/06
{ 0x3a, 0x20 },
{ 0x50, 0x14 }, //10,modified by mormo 2010/07/06
{ 0x53, 0x80 },
{ 0x56, 0x80 },
{ 0x8b, 0x20 }, //LSC
{ 0x8c, 0x20 },
{ 0x8d, 0x20 },
{ 0x8e, 0x14 },
{ 0x8f, 0x10 },
{ 0x90, 0x14 },
{ 0x94, 0x02 },
{ 0x95, 0x07 },
{ 0x96, 0xe0 },
{ 0xb1, 0x40 }, //YCPT
{ 0xb2, 0x40 },
{ 0xb3, 0x40 },
{ 0xb6, 0xe0 },
//{0xd0 , 0xcb},//AECT c9,modifed by mormo 2010/07/06
//{0xd3 , 0x48},//80,modified by mormor 2010/07/06
{ 0xf2, 0x02 },
//{0xf7 , 0x12},
//{0xf8 , 0x0a},
//Registers
{ 0xfe, 0x01 }, // set page1
{ 0x02, 0x20 },
{ 0x04, 0x10 },
{ 0x05, 0x08 },
{ 0x06, 0x20 },
{ 0x08, 0x0a },
{ 0x0e, 0x44 },
{ 0x0f, 0x32 },
{ 0x10, 0x41 },
{ 0x11, 0x37 },
{ 0x12, 0x22 },
{ 0x13, 0x19 },
{ 0x14, 0x44 },
{ 0x15, 0x44 },
{ 0x19, 0x50 },
{ 0x1a, 0xd8 },
{ 0x32, 0x10 },
{ 0x35, 0x00 },
{ 0x36, 0x80 },
{ 0x37, 0x00 },
//-----------Update the registers end---------//
{ 0xfe, 0x00 }, //set page0
{ 0xd2, 0x90 },
#endif
};
static uint8_t image_sensor_read_id(void);
static uint8_t image_sensor_regs_config(void);
void cam_clk_out(void)
{
GLB_Set_I2S_CLK(ENABLE, GLB_I2S_OUT_REF_CLK_NONE);
PDS_Set_Audio_PLL_Freq(AUDIO_PLL_24576000_HZ);
GLB_Set_Chip_Out_1_CLK_Sel(GLB_CHIP_CLK_OUT_I2S_REF_CLK);
}
uint8_t image_sensor_init(BL_Fun_Type mjpeg_en, cam_device_t *cam_cfg, mjpeg_device_t *mjpeg_cfg)
{
i2c_register(I2C0_INDEX, "i2c");
image_sensor_i2c = device_find("i2c");
if (image_sensor_i2c) {
device_open(image_sensor_i2c, 0);
}
if (image_sensor_read_id()) {
MSG("err1\r\n");
return 1;
}
if (image_sensor_regs_config()) {
MSG("err2\r\n");
return 1;
}
mjpeg_stop();
cam_register(CAM0_INDEX, "camera0");
struct device *cam0 = device_find("camera0");
if(!cam0)
{
MSG("cam do not find\r\n");
return 1;
}
if (mjpeg_en) {
mjpeg_init(mjpeg_cfg);
}
CAM_DEV(cam0)->hsp = CAM_HSPOLARITY_HIGH;
CAM_DEV(cam0)->vsp = CAM_VSPOLARITY_HIGH;
CAM_DEV(cam0)->software_mode = cam_cfg->software_mode;
CAM_DEV(cam0)->frame_mode = cam_cfg->frame_mode;
CAM_DEV(cam0)->yuv_format = cam_cfg->yuv_format;
CAM_DEV(cam0)->cam_write_ram_addr = cam_cfg->cam_write_ram_addr;
CAM_DEV(cam0)->cam_write_ram_size = cam_cfg->cam_write_ram_size;
CAM_DEV(cam0)->cam_frame_size = cam_cfg->cam_frame_size;
CAM_DEV(cam0)->cam_write_ram_addr1 = cam_cfg->cam_write_ram_addr1;
CAM_DEV(cam0)->cam_write_ram_size1 = cam_cfg->cam_write_ram_size1;
CAM_DEV(cam0)->cam_frame_size1 = cam_cfg->cam_frame_size1;
#if (CAM_MODE == CAM_USING_INT_MODE)
device_open(cam0, DEVICE_OFLAG_INT_RX);
#elif (CAM_MODE == CAM_USING_POLL_MODE)
device_open(cam0, DEVICE_OFLAG_STREAM_RX);
#endif
return SUCCESS;
}
/****************************************************************************/ /**
* @brief image_sensor_write_byte
*
* @param addr: Register address
* @param data: data
*
* @return None
*
*******************************************************************************/
uint8_t image_sensor_write_byte(uint8_t cmd, uint8_t data)
{
i2c_msg_t msg1;
msg1.slaveaddr = I2C_CAMERA_ADDR,
msg1.len = 1,
msg1.buf = &data;
msg1.flags = SUB_ADDR_1BYTE | I2C_WR;
msg1.subaddr = cmd;
return i2c_transfer(image_sensor_i2c, &msg1, 1);
}
/****************************************************************************/ /**
* @brief image_sensor_read_byte
*
* @param addr: Register address
* @param rdata: data
*
* @return None
*
*******************************************************************************/
uint8_t image_sensor_read_byte(uint8_t cmd)
{
i2c_msg_t msg1;
uint8_t temp;
msg1.len = 1,
msg1.buf = &temp;
msg1.subaddr = cmd;
msg1.slaveaddr = I2C_CAMERA_ADDR,
msg1.flags = SUB_ADDR_1BYTE | I2C_RD;
i2c_transfer(image_sensor_i2c, &msg1, 1);
return temp;
}
/****************************************************************************/ /**
* @brief CAMERA Read ID
*
* @param None
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
static uint8_t image_sensor_read_id(void)
{
uint8_t buf[2] = { 0 };
#if (IMAGE_SENSOR_USE == IMAGE_SENSOR_BF2013)
buf[0] = image_sensor_read_byte(BF2013_ID_MSB);
bflb_platform_delay_ms(10);
buf[1] = image_sensor_read_byte(BF2013_ID_LSB);
if (buf[0] == 0x37 && buf[1] == 0x03) {
return SUCCESS;
} else {
return ERROR;
}
#elif (IMAGE_SENSOR_USE == IMAGE_SENSOR_GC0308)
buf[0] = image_sensor_read_byte(GC0308_ID);
// MSG("image_sensor id:0x%2x\r\n",buf[0]);
if (buf[0] == 0x9b) {
return SUCCESS;
} else {
return ERROR;
}
#endif
}
static uint8_t image_sensor_regs_config(void)
{
int i;
for (i = 0; i < sizeof(sensorRegList) / sizeof(sensorRegList[0]); i++) {
if (image_sensor_write_byte(sensorRegList[i][0], sensorRegList[i][1]) != SUCCESS) {
return ERROR;
}
bflb_platform_delay_ms(1);
}
return SUCCESS;
}
/****************************************************************************/ /**
* @brief Dump image sensor register while is set
*
* @param None
*
* @return None
*
*******************************************************************************/
void image_sensor_dump_regs(void)
{
uint32_t i;
for (i = 0; i < sizeof(sensorRegList) / sizeof(sensorRegList[0]); i++) {
MSG("reg[%02x]: %02x\n", sensorRegList[i][0], image_sensor_read_byte(sensorRegList[i][0]));
}
}
/* cam cdc case use gpio & timer*/
void tr_gpio_init(void)
{
gpio_set_mode(GPIO_PIN_22, GPIO_OUTPUT_PP_MODE);
gpio_write(GPIO_PIN_22, 0);
}
struct device *timer_ch0_comp2 = NULL;
void timer_ch0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
static uint32_t i = 0;
if (i & 1) {
gpio_write(GPIO_PIN_22, 1);
} else {
gpio_write(GPIO_PIN_22, 0);
}
}
void tr_timer_init(void)
{
timer_register(TIMER0_INDEX, "timer_ch0_comp2");
timer_ch0_comp2 = device_find("timer_ch0_comp2");
if (timer_ch0_comp2) {
TIMER_DEV(timer_ch0_comp2)->timeout1 = 1000;
TIMER_DEV(timer_ch0_comp2)->trigger = TIMER_PRELOAD_TRIGGER_COMP0;
device_open(timer_ch0_comp2, 0);
device_set_callback(timer_ch0_comp2, timer_ch0_irq_callback);
}
}
void trigger_init(void)
{
tr_gpio_init();
tr_timer_init();
}

View File

@@ -0,0 +1,36 @@
/**
* @file bsp_gc0308.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _IMAGE_SENSOR_H_
#define _IMAGE_SENSOR_H_
#include "bflb_platform.h"
#include "bl702_cam.h"
#include "bl702_mjpeg.h"
#include "hal_cam.h"
#include "hal_mjpeg.h"
uint8_t image_sensor_init(BL_Fun_Type mjpeg_en, cam_device_t *cam_cfg, mjpeg_device_t *mjpeg_cfg);
void cam_clk_out(void);
void trigger_init(void);
#endif

View File

@@ -0,0 +1,219 @@
/**
* @file lv_port_disp_templ.c
*
*/
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1
/*********************
* INCLUDES
*********************/
#include "lvgl.h"
#include "lv_port_disp.h"
#include "hal_spi.h"
#include "hal_dma.h"
#include "../mcu_lcd/mcu_lcd.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void disp_init(void);
static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
#if LV_USE_GPU
static void gpu_blend(lv_disp_drv_t *disp_drv, lv_color_t *dest, const lv_color_t *src, uint32_t length, lv_opa_t opa);
static void gpu_fill(lv_disp_drv_t *disp_drv, lv_color_t *dest_buf, lv_coord_t dest_width,
const lv_area_t *fill_area, lv_color_t color);
#endif
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
static lv_disp_drv_t *p_disp_drv_cb;
void lv_port_disp_init(void)
{
/*-------------------------
* Initialize your display
* -----------------------*/
disp_init();
/*-----------------------------
* Create a buffer for drawing
*----------------------------*/
/* LVGL requires a buffer where it internally draws the widgets.
* Later this buffer will passed your display drivers `flush_cb` to copy its content to your display.
* The buffer has to be greater than 1 display row
*
* There are three buffering configurations:
* 1. Create ONE buffer with some rows:
* LVGL will draw the display's content here and writes it to your display
*
* 2. Create TWO buffer with some rows:
* LVGL will draw the display's content to a buffer and writes it your display.
* You should use DMA to write the buffer's content to the display.
* It will enable LVGL to draw the next part of the screen to the other buffer while
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
*
* 3. Create TWO screen-sized buffer:
* Similar to 2) but the buffer have to be screen sized. When LVGL is ready it will give the
* whole frame to display. This way you only need to change the frame buffer's address instead of
* copying the pixels.
* */
/* Example for 1) */
// static lv_disp_buf_t draw_buf_dsc_1;
// static lv_color_t draw_buf_1[LV_HOR_RES_MAX * 30]; /*A buffer for 10 rows*/
// lv_disp_buf_init(&draw_buf_dsc_1, draw_buf_1, NULL, LV_HOR_RES_MAX * 30); /*Initialize the display buffer*/
// /* Example for 2) */
static lv_disp_buf_t draw_buf_dsc_2;
static lv_color_t draw_buf_2_1[LCD_W * 20]; /*A buffer for 10 rows*/
static lv_color_t draw_buf_2_2[LCD_W * 20]; /*An other buffer for 10 rows*/
lv_disp_buf_init(&draw_buf_dsc_2, draw_buf_2_1, draw_buf_2_2, LCD_W * 20); /*Initialize the display buffer*/
// /* Example for 3) *
// static lv_disp_buf_t draw_buf_dsc_3;
// static lv_color_t draw_buf_3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*A screen sized buffer*/
// static lv_color_t draw_buf_3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*An other screen sized buffer*/
// lv_disp_buf_init(&draw_buf_dsc_3, draw_buf_3_1, draw_buf_3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = LCD_W;
disp_drv.ver_res = LCD_H;
/* hardware rotation */
disp_drv.sw_rotate = 0;
/* rotation */
disp_drv.rotated = LV_DISP_ROT_NONE;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
/*Set a display buffer*/
disp_drv.buffer = &draw_buf_dsc_2;
#if LV_USE_GPU
/*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
/*Blend two color array using opacity*/
disp_drv.gpu_blend_cb = gpu_blend;
/*Fill a memory array with a color*/
disp_drv.gpu_fill_cb = gpu_fill;
#endif
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
void flush_callback(struct device *dev, void *args, uint32_t size, uint32_t event)
{
while (lcd_draw_is_busy())
;
lv_disp_flush_ready(p_disp_drv_cb);
}
/* Initialize your display and the required peripherals. */
void disp_init(void)
{
/*You code here*/
lcd_init();
lcd_clear(0x0000);
lcd_auto_swap_set(0);
device_set_callback(SPI_DEV(lcd_dev_ifs)->tx_dma, flush_callback);
device_control(SPI_DEV(lcd_dev_ifs)->tx_dma, DEVICE_CTRL_SET_INT, NULL);
}
/* Flush the content of the internal buffer the specific area on the display
* You can use DMA or any hardware acceleration to do this operation in the background but
* 'lv_disp_flush_ready()' has to be called when finished. */
static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
static uint8_t rotated_dir = 0;
if (rotated_dir != disp_drv->rotated) {
rotated_dir = disp_drv->rotated;
lcd_set_dir(rotated_dir, 0);
}
lcd_draw_picture_nonblocking(area->x1, area->y1, area->x2, area->y2, (lcd_color_t *)color_p);
p_disp_drv_cb = disp_drv;
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
// lv_disp_flush_ready(disp_drv);
}
/*OPTIONAL: GPU INTERFACE*/
#if LV_USE_GPU
/* If your MCU has hardware accelerator (GPU) then you can use it to blend to memories using opacity
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
static void gpu_blend(lv_disp_drv_t *disp_drv, lv_color_t *dest, const lv_color_t *src, uint32_t length, lv_opa_t opa)
{
/*It's an example code which should be done by your GPU*/
uint32_t i;
for (i = 0; i < length; i++) {
dest[i] = lv_color_mix(dest[i], src[i], opa);
}
}
/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
static void gpu_fill(lv_disp_drv_t *disp_drv, lv_color_t *dest_buf, lv_coord_t dest_width,
const lv_area_t *fill_area, lv_color_t color)
{
/*It's an example code which should be done by your GPU*/
int32_t x, y;
dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
for (y = fill_area->y1; y <= fill_area->y2; y++) {
for (x = fill_area->x1; x <= fill_area->x2; x++) {
dest_buf[x] = color;
}
dest_buf += dest_width; /*Go to the next line*/
}
}
#endif /*LV_USE_GPU*/
#else /* Enable this file at the top */
/* This dummy typedef exists purely to silence -Wpedantic. */
typedef int keep_pedantic_happy;
#endif

View File

@@ -0,0 +1,46 @@
/**
* @file lv_port_disp_templ.h
*
*/
/*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
#if 1
#ifndef LV_PORT_DISP_TEMPL_H
#define LV_PORT_DISP_TEMPL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lvgl.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
extern lv_disp_drv_t disp_drv;
void lv_port_disp_init(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_PORT_DISP_TEMPL_H*/
#endif /*Disable/Enable content*/

View File

@@ -0,0 +1,715 @@
/**
* @file lv_port_fs_templ.c
*
*/
/*Copy this file as "lv_port_fs.c" and set this value to "1" to enable content*/
#if 1
/*********************
* INCLUDES
*********************/
#include "lv_port_fs.h"
#include "stdio.h"
#include "string.h"
#include "bflb_platform.h"
#if LV_USING_FATFS
#include "ff.h"
#endif
#if LV_USING_ROMFS
#include "bl_romfs.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/* Create a type to store the required data about your file.
* If you are using a File System library
* it already should have a File type.
* For example FatFS has `file_t `. In this case use `typedef file_t file_t`*/
typedef uint32_t file_t; /* 没有实际作用, 使用时是通过指针强转的 */
/*Similarly to `file_t` create a type for directory reading too */
typedef uint32_t dir_t; /* 没有实际作用, 使用时是通过指针强转的 */
#if (LV_USING_FATFS)
FATFS FS_OBJ_SD;
/**********************
* STATIC PROTOTYPES
**********************/
static void fs_init(void);
static lv_fs_res_t fs_open(lv_fs_drv_t *drv, void *file_p, const char *path, lv_fs_mode_t mode);
static lv_fs_res_t fs_close(lv_fs_drv_t *drv, void *file_p);
static lv_fs_res_t fs_read(lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br);
static lv_fs_res_t fs_write(lv_fs_drv_t *drv, void *file_p, const void *buf, uint32_t btw, uint32_t *bw);
static lv_fs_res_t fs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos);
static lv_fs_res_t fs_size(lv_fs_drv_t *drv, void *file_p, uint32_t *size_p);
static lv_fs_res_t fs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p);
static lv_fs_res_t fs_remove(lv_fs_drv_t *drv, const char *path);
static lv_fs_res_t fs_trunc(lv_fs_drv_t *drv, void *file_p);
static lv_fs_res_t fs_rename(lv_fs_drv_t *drv, const char *oldname, const char *newname);
static lv_fs_res_t fs_free(lv_fs_drv_t *drv, uint32_t *total_p, uint32_t *free_p);
static lv_fs_res_t fs_dir_open(lv_fs_drv_t *drv, void *rddir_p, const char *path);
static lv_fs_res_t fs_dir_read(lv_fs_drv_t *drv, void *rddir_p, char *fn);
static lv_fs_res_t fs_dir_close(lv_fs_drv_t *drv, void *rddir_p);
extern void fatfs_sd_driver_register(void);
#endif
#if (LV_USING_ROMFS)
static lv_fs_res_t lvport_romfs_open(lv_fs_drv_t *drv, void *file_p, const char *path, lv_fs_mode_t mode);
static lv_fs_res_t lvport_romfs_close(lv_fs_drv_t *drv, void *file_p);
static lv_fs_res_t lvport_romfs_size(lv_fs_drv_t *drv, void *file_p, uint32_t *size_p);
static lv_fs_res_t lvport_romfs_read(lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br);
static lv_fs_res_t lvport_romfs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos);
static lv_fs_res_t lvport_romfs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p);
static lv_fs_res_t lvport_romfs_dir_close(struct _lv_fs_drv_t *drv, void *rddir_p);
static lv_fs_res_t lvport_romfs_dir_open(struct _lv_fs_drv_t *drv, void *rddir_p, const char *path);
static lv_fs_res_t lvport_romfs_dir_read(struct _lv_fs_drv_t *drv, void *rddir_p, char *fn);
#endif
/**********************
* STATIC VARIABLES
**********************/
typedef uint8_t lv_fs_res_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_port_fs_init(void)
{
/* fatfs init */
#if (LV_USING_FATFS)
/*----------------------------------------------------
* Initialize your storage device and File System
* -------------------------------------------------*/
fs_init();
/*---------------------------------------------------
* Register the file system interface in LVGL
*--------------------------------------------------*/
/* Add a simple drive to open images */
lv_fs_drv_t fs_drv_s;
lv_fs_drv_init(&fs_drv_s);
/*Set up fields...*/
fs_drv_s.file_size = sizeof(FIL);
fs_drv_s.letter = 'S';
fs_drv_s.open_cb = fs_open;
fs_drv_s.close_cb = fs_close;
fs_drv_s.read_cb = fs_read;
fs_drv_s.write_cb = fs_write;
fs_drv_s.seek_cb = fs_seek;
fs_drv_s.tell_cb = fs_tell;
fs_drv_s.free_space_cb = fs_free;
fs_drv_s.size_cb = fs_size;
fs_drv_s.remove_cb = fs_remove;
fs_drv_s.rename_cb = fs_rename;
fs_drv_s.trunc_cb = fs_trunc;
fs_drv_s.rddir_size = sizeof(DIR);
fs_drv_s.dir_close_cb = fs_dir_close;
fs_drv_s.dir_open_cb = fs_dir_open;
fs_drv_s.dir_read_cb = fs_dir_read;
lv_fs_drv_register(&fs_drv_s);
#endif
/* romfs init */
#if (LV_USING_ROMFS)
romfs_mount();
/* Add a simple drive to open images */
lv_fs_drv_t fs_drv_r;
lv_fs_drv_init(&fs_drv_r);
/*Set up fields...*/
fs_drv_r.file_size = sizeof(romfs_file_t);
fs_drv_r.letter = 'R';
fs_drv_r.open_cb = lvport_romfs_open;
fs_drv_r.close_cb = lvport_romfs_close;
fs_drv_r.read_cb = lvport_romfs_read;
fs_drv_r.write_cb = NULL;
fs_drv_r.seek_cb = lvport_romfs_seek;
fs_drv_r.tell_cb = lvport_romfs_tell;
fs_drv_r.free_space_cb = NULL;
fs_drv_r.size_cb = lvport_romfs_size;
fs_drv_r.remove_cb = NULL;
fs_drv_r.rename_cb = NULL;
fs_drv_r.trunc_cb = NULL;
fs_drv_r.rddir_size = sizeof(romfs_dir_t);
fs_drv_r.dir_close_cb = lvport_romfs_dir_close;
fs_drv_r.dir_open_cb = lvport_romfs_dir_open;
fs_drv_r.dir_read_cb = lvport_romfs_dir_read;
lv_fs_drv_register(&fs_drv_r);
#endif
}
#if (LV_USING_FATFS)
/**********************
* STATIC FUNCTIONS
**********************/
lv_fs_res_t res_fatfs_to_lv(FRESULT res)
{
if (res == FR_OK) {
return LV_FS_RES_OK;
}
switch (res) {
case (FR_DISK_ERR):
res = LV_FS_RES_HW_ERR;
break;
case (FR_NO_FILE):
res = LV_FS_RES_NOT_EX;
break;
case (FR_NO_PATH):
res = LV_FS_RES_NOT_EX;
break;
case (FR_NOT_ENOUGH_CORE):
res = LV_FS_RES_OUT_OF_MEM;
break;
case (FR_LOCKED):
res = LV_FS_RES_LOCKED;
case (FR_TOO_MANY_OPEN_FILES):
res = LV_FS_RES_LOCKED;
break;
case (FR_NO_FILESYSTEM):
res = LV_FS_RES_FS_ERR;
break;
case (FR_WRITE_PROTECTED):
res = LV_FS_RES_DENIED;
break;
case (FR_TIMEOUT):
res = LV_FS_RES_TOUT;
break;
default:
res = LV_FS_RES_UNKNOWN;
}
return res;
}
/* Initialize your Storage device and File system. */
static void fs_init(void)
{
/*E.g. for FatFS initialize the SD card and FatFS itself*/
/*You code here*/
fatfs_sd_driver_register();
f_mount(&FS_OBJ_SD, "sd:", 1);
}
/**
* Open a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_open(lv_fs_drv_t *drv, void *file_p, const char *path, lv_fs_mode_t mode)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
BYTE fatfs_mode;
char *path_buf = NULL;
switch (drv->letter) {
case 'S':
path_buf = (char *)malloc(sizeof(char) * (strlen(path) + 5));
sprintf(path_buf, "SD:/%s", path);
break;
default:
return LV_FS_RES_NOT_EX;
break;
}
switch (mode) {
case (LV_FS_MODE_RD):
fatfs_mode = FA_READ;
break;
case (LV_FS_MODE_WR):
fatfs_mode = FA_WRITE;
break;
case (LV_FS_MODE_WR | LV_FS_MODE_RD):
fatfs_mode = FA_WRITE | FA_READ;
break;
default:
fatfs_mode = LV_FS_MODE_RD;
break;
}
res = f_open((FIL *)file_p, path_buf, fatfs_mode);
res = res_fatfs_to_lv(res);
lv_mem_free(path_buf);
return res;
}
/**
* Close an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_close(lv_fs_drv_t *drv, void *file_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = f_close((FIL *)file_p);
res = res_fatfs_to_lv(res);
return res;
}
/**
* Read data from an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_read(lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = f_read((FIL *)file_p, buf, btr, (UINT *)br);
res = res_fatfs_to_lv(res);
return res;
}
/**
* Write into a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param buf pointer to a buffer with the bytes to write
* @param btr Bytes To Write
* @param br the number of real written bytes (Bytes Written). NULL if unused.
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_write(lv_fs_drv_t *drv, void *file_p, const void *buf, uint32_t btw, uint32_t *bw)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = f_write((FIL *)file_p, buf, btw, (UINT *)bw);
res = res_fatfs_to_lv(res);
return res;
}
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open )
* @param pos the new position of read write pointer
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = f_lseek((FIL *)file_p, pos);
res = res_fatfs_to_lv(res);
return res;
}
/**
* Give the size of a file bytes
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param size pointer to a variable to store the size
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_size(lv_fs_drv_t *drv, void *file_p, uint32_t *size_p)
{
//lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
*size_p = f_size((FIL *)file_p);
return LV_FS_RES_OK;
}
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p)
{
//lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
*pos_p = f_tell((FIL *)file_p);
return LV_FS_RES_OK;
}
/**
* Delete a file
* @param drv pointer to a driver where this function belongs
* @param path path of the file to delete
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_remove(lv_fs_drv_t *drv, const char *path)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
char *path_buf = NULL;
switch (drv->letter) {
case 'S':
path_buf = (char *)malloc(sizeof(char) * (strlen(path) + 5));
sprintf(path_buf, "SD:/%s", path);
break;
default:
return LV_FS_RES_NOT_EX;
break;
}
res = f_unlink(path_buf);
res = res_fatfs_to_lv(res);
lv_mem_free(path_buf);
return res;
}
/**
* Truncate the file size to the current position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to an 'ufs_file_t' variable. (opened with lv_fs_open )
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_trunc(lv_fs_drv_t *drv, void *file_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = f_truncate((FIL *)file_p);
res = res_fatfs_to_lv(res);
return res;
}
/**
* Rename a file
* @param drv pointer to a driver where this function belongs
* @param oldname path to the file
* @param newname path with the new name
* @return LV_FS_RES_OK or any error from 'fs_res_t'
*/
static lv_fs_res_t fs_rename(lv_fs_drv_t *drv, const char *oldname, const char *newname)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
char *path_old_buf = NULL;
char *path_new_buf = NULL;
switch (drv->letter) {
case 'S':
path_old_buf = (char *)malloc(sizeof(char) * (strlen(oldname) + 5));
path_new_buf = (char *)malloc(sizeof(char) * (strlen(newname) + 5));
sprintf(path_old_buf, "SD:/%s", oldname);
sprintf(path_new_buf, "SD:/%s", newname);
break;
default:
return LV_FS_RES_NOT_EX;
break;
}
res = f_rename(path_old_buf, path_new_buf);
res = res_fatfs_to_lv(res);
lv_mem_free(path_old_buf);
lv_mem_free(path_new_buf);
return res;
}
/**
* Get the free and total size of a driver in kB
* @param drv pointer to a driver where this function belongs
* @param letter the driver letter
* @param total_p pointer to store the total size [kB]
* @param free_p pointer to store the free size [kB]
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_free(lv_fs_drv_t *drv, uint32_t *total_p, uint32_t *free_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
char *path = NULL;
FATFS *fs_obj;
/* Add your code here*/
switch (drv->letter) {
case 'S':
path = "SD:";
fs_obj = &FS_OBJ_SD;
break;
default:
return LV_FS_RES_NOT_EX;
break;
}
res = f_getfree(path, free_p, &fs_obj);
*free_p = (fs_obj->csize) * (*free_p) / 1024;
*total_p = (fs_obj->csize) * (fs_obj->n_fatent - 2) / 1024;
res = res_fatfs_to_lv(res);
return res;
}
/**
* Initialize a 'lv_fs_dir_t' variable for directory reading
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to a 'lv_fs_dir_t' variable
* @param path path to a directory
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_open(lv_fs_drv_t *drv, void *rddir_p, const char *path)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
char *path_buf = NULL;
switch (drv->letter) {
case 'S':
path_buf = (char *)malloc(sizeof(char) * (strlen(path) + 5));
sprintf(path_buf, "SD:/%s", path);
break;
default:
return LV_FS_RES_NOT_EX;
break;
}
res = f_opendir(rddir_p, path_buf);
res = res_fatfs_to_lv(res);
lv_mem_free(path_buf);
return res;
}
/**
* Read the next filename form a directory.
* The name of the directories will begin with '/'
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read(lv_fs_drv_t *drv, void *rddir_p, char *fn)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
FILINFO entry;
/* Add your code here*/
res = f_readdir(rddir_p, &entry);
res = res_fatfs_to_lv(res);
if (res == LV_FS_RES_OK) {
sprintf(fn, "%s%s", (entry.fattrib & AM_DIR) ? "/" : "", entry.fname);
}
return res;
}
/**
* Close the directory reading
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_close(lv_fs_drv_t *drv, void *rddir_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
f_closedir((DIR *)rddir_p);
res = res_fatfs_to_lv(res);
return res;
}
#endif
#if (LV_USING_ROMFS)
static lv_fs_res_t lvport_romfs_open(lv_fs_drv_t *drv, void *file_p, const char *path, lv_fs_mode_t mode)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
char *path_buf = NULL;
switch (drv->letter) {
case 'R':
path_buf = (char *)malloc(sizeof(char) * (strlen(path) + 8));
sprintf(path_buf, "/romfs/%s", path);
break;
default:
return LV_FS_RES_NOT_EX;
break;
}
res = romfs_open((romfs_file_t *)file_p, path_buf, mode);
lv_mem_free(path_buf);
return res;
}
static lv_fs_res_t lvport_romfs_close(lv_fs_drv_t *drv, void *file_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = romfs_close((romfs_file_t *)file_p);
return res;
}
static lv_fs_res_t lvport_romfs_read(lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
uint32_t num = romfs_read((romfs_file_t *)file_p, buf, btr);
if (num > 0) {
*br = num;
res = 0;
}else{
res = num;
}
return res;
}
static lv_fs_res_t lvport_romfs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/* Add your code here*/
res = romfs_lseek((romfs_file_t *)file_p, pos, ROMFS_SEEK_SET);
if (res > 0) {
res = 0;
}
return res;
}
static lv_fs_res_t lvport_romfs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p)
{
if(file_p == NULL){
return -1;
}
*pos_p = ((romfs_file_t *)file_p)->offset;
return 0;
}
static lv_fs_res_t lvport_romfs_dir_close(struct _lv_fs_drv_t *drv, void *rddir_p)
{
return romfs_closedir((romfs_dir_t *)rddir_p);
}
static lv_fs_res_t lvport_romfs_dir_open(struct _lv_fs_drv_t *drv, void *rddir_p,const char *path)
{
char *path_buf = NULL;
if(rddir_p == NULL){
return LV_FS_RES_UNKNOWN;
}
path_buf = (char *)malloc(sizeof(char) * (strlen(path) + 8));
sprintf(path_buf, "/romfs/%s", path);
return romfs_opendir((romfs_dir_t *)rddir_p,(const char *)path_buf);
}
static lv_fs_res_t lvport_romfs_dir_read(struct _lv_fs_drv_t *drv, void *rddir_p, char *fn)
{
if(rddir_p == NULL){
return LV_FS_RES_UNKNOWN;
}
romfs_dirent_t *romfs_dirent = romfs_readdir((romfs_dir_t *)rddir_p);
if(romfs_dirent == NULL){
return LV_FS_RES_UNKNOWN;
}
if(fn != NULL){
memcpy((void*)fn,(const void*)romfs_dirent,sizeof(romfs_dirent_t));
}
return LV_FS_RES_OK;
}
static lv_fs_res_t lvport_romfs_size(lv_fs_drv_t *drv, void *file_p, uint32_t *size_p)
{
/* Add your code here*/
int res = romfs_size((romfs_file_t *)file_p);
if(res<0){
return LV_FS_RES_UNKNOWN;
}
*size_p = res;
return LV_FS_RES_OK;
}
#endif
#else /* Enable this file at the top */
/* This dummy typedef exists purely to silence -Wpedantic. */
typedef int keep_pedantic_happy;
#endif

View File

@@ -0,0 +1,52 @@
/**
* @file lv_port_fs_templ.h
*
*/
/*Copy this file as "lv_port_fs.h" and set this value to "1" to enable content*/
#if 1
#ifndef LV_PORT_FS_TEMPL_H
#define LV_PORT_FS_TEMPL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lvgl.h"
/*********************
* DEFINES
*********************/
#ifndef LV_USING_FATFS
#define LV_USING_FATFS 0
#endif
#ifndef LV_USING_ROMFS
#define LV_USING_ROMFS 0
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_port_fs_init(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_PORT_FS_TEMPL_H*/
#endif /*Disable/Enable content*/

View File

@@ -0,0 +1,520 @@
/**
* @file lv_port_indev_templ.c
*
*/
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
#if 1
/*********************
* INCLUDES
*********************/
#include "lv_port_indev.h"
#include "bflb_platform.h"
#include "hal_gpio.h"
#include "hal_dma.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void touchpad_init(void);
static bool touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
//static bool touchpad_is_pressed(void);
static lv_coord_t touchpad_get_xy(lv_coord_t *x, lv_coord_t *y);
// static void mouse_init(void);
// static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
// static bool mouse_is_pressed(void);
// static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
static void keypad_init(void);
static bool keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
static uint32_t keypad_get_key(void);
// static void encoder_init(void);
// static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
// static void encoder_handler(void);
// static void button_init(void);
// static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
// static int8_t button_get_pressed_id(void);
// static bool button_is_pressed(uint8_t id);
/**********************
* STATIC VARIABLES
**********************/
lv_indev_t *indev_touchpad;
//lv_indev_t * indev_mouse;
lv_indev_t *indev_keypad;
//lv_indev_t * indev_encoder;
//lv_indev_t * indev_button;
// static int32_t encoder_diff;
// static lv_indev_state_t encoder_state;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_port_indev_init(void)
{
/* Here you will find example implementation of input devices supported by LittelvGL:
* - Touchpad
* - Mouse (with cursor support)
* - Keypad (supports GUI usage only with key)
* - Encoder (supports GUI usage only with: left, right, push)
* - Button (external buttons to press points on the screen)
*
* The `..._read()` function are only examples.
* You should shape them according to your hardware
*/
lv_indev_drv_t indev_drv;
/*------------------
* Touchpad
* -----------------*/
/*Initialize your touchpad if you have*/
touchpad_init();
/*Register a touchpad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touchpad_read;
indev_touchpad = lv_indev_drv_register(&indev_drv);
// lv_obj_t *touchpad_cursor = lv_img_create(lv_disp_get_scr_act(NULL), NULL);
// lv_img_set_src(touchpad_cursor, LV_SYMBOL_USB);
// lv_indev_set_cursor(indev_touchpad, touchpad_cursor);
/*------------------
* Mouse
* -----------------*/
/*Initialize your touchpad if you have*/
// mouse_init();
/*Register a mouse input device*/
// lv_indev_drv_init(&indev_drv);
// indev_drv.type = LV_INDEV_TYPE_POINTER;
// indev_drv.read_cb = mouse_read;
// indev_mouse = lv_indev_drv_register(&indev_drv);
/*Set cursor. For simplicity set a HOME symbol now.*/
// lv_obj_t * mouse_cursor = lv_img_create(lv_disp_get_scr_act(NULL), NULL);
// lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
// lv_indev_set_cursor(indev_mouse, mouse_cursor);
/*------------------
* Keypad
* -----------------*/
/*Initialize your keypad or keyboard if you have*/
keypad_init();
/*Register a keypad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = keypad_read;
indev_keypad = lv_indev_drv_register(&indev_drv);
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
* add objects to the group with `lv_group_add_obj(group, obj)`
* and assign this input device to group to navigate in it:
* `lv_indev_set_group(indev_keypad, group);` */
/*------------------
* Encoder
* -----------------*/
/*Initialize your encoder if you have*/
// encoder_init();
/*Register a encoder input device*/
// lv_indev_drv_init(&indev_drv);
// indev_drv.type = LV_INDEV_TYPE_ENCODER;
// indev_drv.read_cb = encoder_read;
// indev_encoder = lv_indev_drv_register(&indev_drv);
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
* add objects to the group with `lv_group_add_obj(group, obj)`
* and assign this input device to group to navigate in it:
* `lv_indev_set_group(indev_encoder, group);` */
/*------------------
* Button
* -----------------*/
/*Initialize your button if you have*/
// button_init();
/*Register a button input device*/
// lv_indev_drv_init(&indev_drv);
// indev_drv.type = LV_INDEV_TYPE_BUTTON;
// indev_drv.read_cb = button_read;
// indev_button = lv_indev_drv_register(&indev_drv);
/*Assign buttons to points on the screen*/
// static const lv_point_t btn_points[2] = {
// {10, 10}, /*Button 0 -> x:10; y:10*/
// {40, 100}, /*Button 1 -> x:40; y:100*/
// };
// lv_indev_set_button_points(indev_button, btn_points);
}
/**********************
* STATIC FUNCTIONS
**********************/
/*------------------
* Touchpad
* -----------------*/
#include "touch.h"
#include "hal_spi.h"
/*Initialize your touchpad*/
static void touchpad_init(void)
{
/*Your code comes here*/
if (device_find("lcd_dev_ifs") == NULL) {
xpt2046_init();
} else {
gpio_set_mode(TOUCH_PIN_CS, GPIO_OUTPUT_MODE);
gpio_write(TOUCH_PIN_CS, 1);
touch_spi = device_find("lcd_dev_ifs");
}
}
/* Will be called by the library to read the touchpad */
static bool touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
lv_coord_t xt, yt;
/*Save the pressed coordinates and the state*/
if (touchpad_get_xy(&xt, &yt)) {
last_x = xt;
last_y = yt;
data->state = LV_INDEV_STATE_PR;
} else {
data->state = LV_INDEV_STATE_REL;
}
/*Set the last pressed coordinates*/
data->point.x = last_x;
data->point.y = last_y;
/*Return `false` because we are not buffering and no more data to read*/
return false;
}
/*Return true is the touchpad is pressed*/
// static bool touchpad_is_pressed(void)
// {
// /*Your code comes here*/
// return false;
// }
/*Get the x and y coordinates if the touchpad is pressed*/
static lv_coord_t touchpad_get_xy(lv_coord_t *x, lv_coord_t *y)
{
/*Your code comes here*/
lv_disp_t *p_disp_drv_cb;
uint8_t res;
p_disp_drv_cb = lv_disp_get_default();
while (p_disp_drv_cb->driver.buffer->flushing)
;
uint32_t spi_clock = SPI_DEV(touch_spi)->clk;
device_control(touch_spi, DEVICE_CTRL_SPI_CONFIG_CLOCK, (void *)360000);
res = touch_read(x, y);
device_control(touch_spi, DEVICE_CTRL_SPI_CONFIG_CLOCK, (void *)spi_clock);
return res;
}
/*------------------
* Mouse
* -----------------*/
/* Initialize your mouse */
// static void mouse_init(void)
// {
// /*Your code comes here*/
// }
/* Will be called by the library to read the mouse */
// static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
// {
// /*Get the current x and y coordinates*/
// mouse_get_xy(&data->point.x, &data->point.y);
// /*Get whether the mouse button is pressed or released*/
// if(mouse_is_pressed()) {
// data->state = LV_INDEV_STATE_PR;
// } else {
// data->state = LV_INDEV_STATE_REL;
// }
// /*Return `false` because we are not buffering and no more data to read*/
// return false;
// }
/*Return true is the mouse button is pressed*/
// static bool mouse_is_pressed(void)
// {
// /*Your code comes here*/
// return false;
// }
/*Get the x and y coordinates if the mouse is pressed*/
// static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
// {
// /*Your code comes here*/
// (*x) = 0;
// (*y) = 0;
// }
/*------------------
* Keypad
* -----------------*/
#include "hal_adc.h"
#include "hal_gpio.h"
uint8_t PinList[] = { GPIO_PIN_18 };
adc_channel_t posChList[] = { ADC_CHANNEL8 };
adc_channel_t negChList[] = { ADC_CHANNEL_GND };
adc_channel_val_t result_val;
struct device *adc_key;
uint16_t key_value[] = { 283, 89, 198, 0, 406 };
/* Initialize your keypad */
static void keypad_init(void)
{
/*Your code comes here*/
adc_channel_cfg_t adc_channel_cfg;
adc_channel_cfg.pos_channel = posChList;
adc_channel_cfg.neg_channel = negChList;
adc_channel_cfg.num = 1;
adc_register(ADC0_INDEX, "adc_key");
adc_key = device_find("adc_key");
if (adc_key) {
ADC_DEV(adc_key)->continuous_conv_mode = ENABLE;
device_open(adc_key, DEVICE_OFLAG_STREAM_RX);
device_control(adc_key, DEVICE_CTRL_ADC_CHANNEL_CONFIG, &adc_channel_cfg);
adc_channel_start(adc_key);
}
}
/* Will be called by the library to read the keypad */
static bool keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
static uint32_t last_key = 0;
/*Get the current x and y coordinates*/
//mouse_get_xy(&data->point.x, &data->point.y);
/*Get whether the a key is pressed and save the pressed key*/
uint32_t act_key = keypad_get_key();
if (act_key != 0) {
data->state = LV_INDEV_STATE_PR;
/*Translate the keys to LVGL control characters according to your key definitions*/
switch (act_key) {
case 1:
act_key = LV_KEY_LEFT;
break;
case 2:
act_key = LV_KEY_RIGHT;
break;
case 3:
act_key = LV_KEY_UP;
break;
case 4:
act_key = LV_KEY_DOWN;
break;
case 5:
act_key = LV_KEY_ENTER;
break;
default:
break;
}
last_key = act_key;
} else {
data->state = LV_INDEV_STATE_REL;
}
data->key = last_key;
/*Return `false` because we are not buffering and no more data to read*/
return false;
}
/*Get the currently being pressed key. 0 if no key is pressed*/
static uint32_t keypad_get_key(void)
{
static uint8_t old_key_v = 0;
static uint8_t old_key_num = 0;
static uint8_t last_key;
uint8_t key;
uint16_t key_voltage;
/*Your code comes here*/
device_read(adc_key, 0, (void *)&result_val, sizeof(result_val) / sizeof(adc_channel_val_t));
key_voltage = result_val.volt * 1000;
for (key = 0; key < sizeof(key_value) / sizeof(key_value[0]); key++) {
if (DIFF(key_voltage, key_value[key]) < KEY_ADC_DIFF_MAX) {
break;
}
}
key += 1;
if (key > sizeof(key_value)) {
key = 0;
}
if (key == last_key) {
old_key_v = key;
old_key_num = 0;
} else if (key == old_key_v) {
old_key_num++;
if (old_key_num >= KEY_NOISE_NUM_MAX) {
last_key = key;
old_key_num = 0;
}
} else {
old_key_num = 0;
old_key_v = key;
}
return last_key;
}
/*------------------
* Encoder
* -----------------*/
/* Initialize your keypad */
// static void encoder_init(void)
// {
// /*Your code comes here*/
// }
/* Will be called by the library to read the encoder */
// static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
// {
// data->enc_diff = encoder_diff;
// data->state = encoder_state;
// /*Return `false` because we are not buffering and no more data to read*/
// return false;
// }
/*Call this function in an interrupt to process encoder events (turn, press)*/
// static void encoder_handler(void)
// {
// /*Your code comes here*/
// encoder_diff += 0;
// encoder_state = LV_INDEV_STATE_REL;
// }
/*------------------
* Button
* -----------------*/
/* Initialize your buttons */
// static void button_init(void)
// {
// /*Your code comes here*/
// }
/* Will be called by the library to read the button */
// static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
// {
// static uint8_t last_btn = 0;
// /*Get the pressed button's ID*/
// int8_t btn_act = button_get_pressed_id();
// if(btn_act >= 0) {
// data->state = LV_INDEV_STATE_PR;
// last_btn = btn_act;
// } else {
// data->state = LV_INDEV_STATE_REL;
// }
// /*Save the last pressed button's ID*/
// data->btn_id = last_btn;
// /*Return `false` because we are not buffering and no more data to read*/
// return false;
// }
/*Get ID (0, 1, 2 ..) of the pressed button*/
// static int8_t button_get_pressed_id(void)
// {
// uint8_t i;
// /*Check to buttons see which is being pressed (assume there are 2 buttons)*/
// for(i = 0; i < 2; i++) {
// /*Return the pressed button's ID*/
// if(button_is_pressed(i)) {
// return i;
// }
// }
// /*No button pressed*/
// return -1;
// }
/*Test if `id` button is pressed or not*/
// static bool button_is_pressed(uint8_t id)
// {
// /*Your code comes here*/
// return false;
// }
#else /* Enable this file at the top */
/* This dummy typedef exists purely to silence -Wpedantic. */
typedef int keep_pedantic_happy;
#endif

View File

@@ -0,0 +1,58 @@
/**
* @file lv_port_indev_templ.h
*
*/
/*Copy this file as "lv_port_indev.h" and set this value to "1" to enable content*/
#if 1
#ifndef LV_PORT_INDEV_TEMPL_H
#define LV_PORT_INDEV_TEMPL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lvgl.h"
/*********************
* DEFINES
*********************/
#define KEY_ADC_DIFF_MAX 15
#define DIFF(x, y) (((x) > (y)) ? ((x) - (y)) : ((y) - (x)))
#define KEY_NOISE_NUM_MAX 2
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
extern lv_indev_t *indev_touchpad;
//extern lv_indev_t * indev_mouse;
extern lv_indev_t *indev_keypad;
//extern lv_indev_t * indev_encoder;
//extern lv_indev_t * indev_button;
void lv_port_indev_init(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_PORT_INDEV_TEMPL_H*/
#endif /*Disable/Enable content*/

View File

@@ -0,0 +1,612 @@
/**
* @file font.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "font.h"
// clang-format off
#if FONT_ASCII_16X8
const unsigned char font_ascii_16x8[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //" "
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x10,0x10,0x00,0x00, //"!"
0x00,0x00,0x6C,0x6C,0x24,0x24,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, //"""
0x00,0x24,0x24,0x24,0x24,0xFE,0x48,0x48,0x48,0x48,0xFC,0x90,0x90,0x90,0x90,0x00, //"#"
0x00,0x10,0x3C,0x54,0x92,0x90,0x50,0x38,0x14,0x12,0x12,0x92,0x54,0x78,0x10,0x00, //"$"
0x00,0x00,0x22,0x5C,0x94,0xA8,0x48,0x10,0x10,0x24,0x2A,0x52,0x54,0x88,0x00,0x00, //"%"
0x00,0x00,0x30,0x48,0x48,0x50,0x20,0x6E,0x54,0x94,0x8C,0x88,0x8A,0x74,0x00,0x00, //"&"
0x00,0x00,0x30,0x30,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"'"
0x00,0x04,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x00, //"("
0x00,0x80,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x00, //")"
0x00,0x00,0x00,0x00,0x10,0x54,0x38,0x10,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00, //"*"
0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, //"+"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x00, //","
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"-"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00, //"."
0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00, //"/"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"0"
0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, //"1"
0x00,0x00,0x38,0x44,0x82,0x82,0x04,0x08,0x10,0x20,0x40,0x82,0x84,0xFC,0x00,0x00, //"2"
0x00,0x00,0x38,0x44,0x82,0x02,0x04,0x38,0x04,0x02,0x02,0x82,0x44,0x38,0x00,0x00, //"3"
0x00,0x00,0x04,0x0C,0x14,0x14,0x24,0x24,0x44,0x44,0xFE,0x04,0x04,0x0E,0x00,0x00, //"4"
0x00,0x00,0xFC,0x80,0x80,0x80,0xB8,0xC4,0x82,0x02,0x02,0x82,0x84,0x78,0x00,0x00, //"5"
0x00,0x00,0x3C,0x42,0x82,0x80,0xB8,0xC4,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"6"
0x00,0x00,0x7E,0x42,0x82,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x10,0x10,0x00,0x00, //"7"
0x00,0x00,0x38,0x44,0x82,0x82,0x44,0x38,0x44,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"8"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x46,0x3A,0x02,0x82,0x44,0x38,0x00,0x00, //"9"
0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00, //":"
0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,0x00,0x00, //";"
0x00,0x00,0x00,0x00,0x06,0x18,0x60,0x80,0x60,0x18,0x06,0x00,0x00,0x00,0x00,0x00, //"<"
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, //"="
0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x02,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00, //">"
0x00,0x38,0x44,0x82,0x82,0x02,0x04,0x08,0x10,0x10,0x10,0x00,0x10,0x10,0x00,0x00, //"?"
0x00,0x00,0x38,0x44,0x82,0x9A,0xAA,0xAA,0xAA,0xAA,0xAA,0x96,0x80,0x42,0x3C,0x00, //"@"
0x00,0x00,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x7C,0x44,0x44,0xEE,0x00,0x00, //"A"
0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x42,0x42,0x42,0x42,0x42,0xFC,0x00,0x00, //"B"
0x00,0x00,0x3C,0x44,0x82,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x44,0x38,0x00,0x00, //"C"
0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xF8,0x00,0x00, //"D"
0x00,0x00,0xFC,0x44,0x42,0x40,0x44,0x7C,0x44,0x40,0x40,0x42,0x44,0xFC,0x00,0x00, //"E"
0x00,0x00,0xFC,0x44,0x42,0x40,0x44,0x7C,0x44,0x40,0x40,0x40,0x40,0xF0,0x00,0x00, //"F"
0x00,0x00,0x34,0x4C,0x82,0x80,0x80,0x80,0x8E,0x84,0x84,0x84,0x4C,0x34,0x00,0x00, //"G"
0x00,0x00,0xEE,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00, //"H"
0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, //"I"
0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0x88,0x70,0x00,0x00, //"J"
0x00,0x00,0xEE,0x44,0x48,0x48,0x50,0x60,0x50,0x48,0x48,0x44,0x44,0xEE,0x00,0x00, //"K"
0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x44,0xFC,0x00,0x00, //"L"
0x00,0x00,0xC6,0x44,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x44,0x44,0x44,0xEE,0x00,0x00, //"M"
0x00,0x00,0xCE,0x44,0x64,0x64,0x64,0x54,0x54,0x4C,0x4C,0x4C,0x44,0xE4,0x00,0x00, //"N"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"O"
0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x44,0x78,0x40,0x40,0x40,0x40,0xE0,0x00,0x00, //"P"
0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xBA,0x44,0x3C,0x02,0x00, //"Q"
0x00,0x00,0xF0,0x48,0x44,0x44,0x44,0x48,0x70,0x48,0x44,0x44,0x44,0xE6,0x00,0x00, //"R"
0x00,0x00,0x3C,0x44,0x82,0x80,0x40,0x30,0x0C,0x02,0x02,0x82,0x44,0x78,0x00,0x00, //"S"
0x00,0x00,0x7C,0x54,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, //"T"
0x00,0x00,0xEE,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, //"U"
0x00,0x00,0xEE,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x28,0x10,0x10,0x10,0x00,0x00, //"V"
0x00,0x00,0xEE,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x28,0x28,0x28,0x00,0x00, //"W"
0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x44,0xEE,0x00,0x00, //"X"
0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, //"Y"
0x00,0x00,0x7E,0x44,0x84,0x08,0x08,0x10,0x20,0x20,0x40,0x82,0x84,0xFC,0x00,0x00, //"Z"
0x00,0x1C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1C,0x00, //"["
0x00,0x00,0xEE,0x44,0x54,0x54,0xFE,0x54,0x54,0x54,0x28,0x28,0x28,0x28,0x00,0x00, //"\"
0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, //"]"
0x00,0x30,0x48,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"^"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, //"_"
0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"`"
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x84,0x04,0x7C,0x84,0x84,0x8C,0x76,0x00,0x00, //"a"
0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x42,0x64,0x58,0x00,0x00, //"b"
0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x80,0x80,0x80,0x80,0x44,0x38,0x00,0x00, //"c"
0x00,0x00,0x0C,0x04,0x04,0x04,0x34,0x4C,0x84,0x84,0x84,0x84,0x4C,0x36,0x00,0x00, //"d"
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x84,0x84,0xFC,0x80,0x80,0x84,0x78,0x00,0x00, //"e"
0x00,0x00,0x18,0x24,0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, //"f"
0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0x44,0x44,0x78,0x80,0x7C,0x82,0x82,0x7C,0x00, //"g"
0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00, //"h"
0x00,0x00,0x10,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, //"i"
0x00,0x00,0x10,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00, //"j"
0x00,0x00,0xC0,0x40,0x40,0x40,0x5C,0x48,0x50,0x60,0x50,0x48,0x44,0xEE,0x00,0x00, //"k"
0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x11,0x10,0x10,0x10,0x10,0x10,0x39,0x00,0x00, //"l"
0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xD2,0x92,0x92,0x92,0x92,0x92,0xD6,0x00,0x00, //"m"
0x00,0x00,0x00,0x00,0x00,0x00,0x58,0xE4,0x44,0x44,0x44,0x44,0x44,0xEE,0x00,0x00, //"n"
0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00, //"o"
0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x64,0x42,0x42,0x42,0x64,0x58,0x40,0xE0,0x00, //"p"
0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x4C,0x84,0x84,0x84,0x4C,0x34,0x04,0x0E,0x00, //"q"
0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x30,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, //"r"
0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x88,0x84,0x60,0x18,0x84,0x44,0x78,0x00,0x00, //"s"
0x00,0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00, //"t"
0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, //"u"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, //"v"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x44,0x54,0x54,0x28,0x28,0x28,0x00,0x00, //"w"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x28,0x10,0x10,0x28,0x44,0xEE,0x00,0x00, //"x"
0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0xA0,0xC0,0x00, //"y"
0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x88,0x10,0x20,0x42,0x84,0xFC,0x00,0x00, //"z"
0x00,0x0C,0x10,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x10,0x0C,0x00, //"{"
0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, //"|"
0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0x20,0x20,0xC0,0x00, //"}"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x8C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //"~"
0x00,
};
#endif
#if FONT_ASCII_64X32
const unsigned char ascii_64x32[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,
0x00,0x1F,0xFE,0x00,0x00,0x7F,0xFF,0x80,0x00,0xFF,0x1F,0xC0,0x00,0xFC,0x0F,0xE0,
0x01,0xF8,0x07,0xE0,0x03,0xF8,0x03,0xF0,0x03,0xF0,0x03,0xF0,0x07,0xF0,0x01,0xF8,
0x07,0xE0,0x01,0xF8,0x07,0xE0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xE0,0x00,0xFC,0x07,0xE0,0x01,0xF8,0x07,0xE0,0x01,0xF8,0x03,0xF0,0x03,0xF0,
0x03,0xF8,0x03,0xF0,0x01,0xF8,0x07,0xE0,0x00,0xFC,0x0F,0xC0,0x00,0xFF,0x1F,0xC0,
0x00,0x3F,0xFF,0x80,0x00,0x1F,0xFE,0x00,0x00,0x07,0xF8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"0",0*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,
0x00,0x00,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x07,0xF0,0x00,0x01,0xFF,0xF0,0x00,
0x01,0xFF,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xF8,0x00,
0x00,0x0F,0xFC,0x00,0x01,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"1",1*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFC,0x00,
0x00,0x3F,0xFF,0x80,0x00,0xFF,0xFF,0xE0,0x01,0xFC,0x1F,0xF0,0x03,0xF0,0x07,0xF0,
0x07,0xE0,0x03,0xF8,0x07,0xE0,0x01,0xF8,0x0F,0xC0,0x01,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xE0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x07,0xE0,0x01,0xFC,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,
0x00,0x00,0x03,0xF8,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xE0,
0x00,0x00,0x1F,0xC0,0x00,0x00,0x3F,0x80,0x00,0x00,0x7F,0x00,0x00,0x00,0xFE,0x00,
0x00,0x01,0xFC,0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xC0,0x00,
0x00,0x1F,0x80,0x00,0x00,0x3F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0xFC,0x00,0x3C,
0x01,0xF8,0x00,0x3C,0x03,0xF0,0x00,0x3C,0x03,0xE0,0x00,0x3C,0x07,0xE0,0x00,0x7C,
0x0F,0xC0,0x00,0xF8,0x1F,0x80,0x01,0xF8,0x1F,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xF8,
0x1F,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"2",2*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,
0x00,0x7F,0xFE,0x00,0x00,0xFF,0xFF,0x80,0x01,0xF8,0x7F,0xC0,0x03,0xE0,0x1F,0xC0,
0x03,0xC0,0x0F,0xE0,0x07,0xC0,0x07,0xE0,0x07,0xC0,0x07,0xF0,0x07,0xE0,0x03,0xF0,
0x07,0xE0,0x03,0xF0,0x07,0xE0,0x03,0xF0,0x07,0xE0,0x03,0xF0,0x03,0xC0,0x03,0xF0,
0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xC0,
0x00,0x00,0x1F,0xC0,0x00,0x00,0xFF,0x00,0x00,0x0F,0xFE,0x00,0x00,0x0F,0xFE,0x00,
0x00,0x0F,0xFF,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x07,0xF0,
0x00,0x00,0x03,0xF0,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0xFC,
0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x03,0xE0,0x00,0xFC,0x07,0xF0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x01,0xFC,0x0F,0xF0,0x01,0xF8,
0x0F,0xE0,0x03,0xF8,0x07,0xE0,0x03,0xF0,0x07,0xF0,0x07,0xE0,0x03,0xFC,0x1F,0xC0,
0x01,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0x00,0x00,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"3",3*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,
0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x3F,0x80,0x00,0x00,0x3F,0x80,
0x00,0x00,0x7F,0x80,0x00,0x00,0xFF,0x80,0x00,0x00,0xFF,0x80,0x00,0x01,0xFF,0x80,
0x00,0x03,0xFF,0x80,0x00,0x03,0xFF,0x80,0x00,0x07,0xDF,0x80,0x00,0x0F,0x9F,0x80,
0x00,0x0F,0x9F,0x80,0x00,0x1F,0x1F,0x80,0x00,0x3E,0x1F,0x80,0x00,0x3E,0x1F,0x80,
0x00,0x7C,0x1F,0x80,0x00,0xF8,0x1F,0x80,0x00,0xF8,0x1F,0x80,0x01,0xF0,0x1F,0x80,
0x03,0xE0,0x1F,0x80,0x03,0xE0,0x1F,0x80,0x07,0xC0,0x1F,0x80,0x0F,0x80,0x1F,0x80,
0x0F,0x80,0x1F,0x80,0x1F,0x00,0x1F,0x80,0x3E,0x00,0x1F,0x80,0x3F,0xFF,0xFF,0xFF,
0x3F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,
0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,
0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x1F,0x80,
0x00,0x00,0x3F,0xC0,0x00,0x07,0xFF,0xFE,0x00,0x07,0xFF,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"4",4*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF8,
0x01,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xF0,
0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,
0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xC0,0x00,0x00,
0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC7,0xFE,0x00,0x03,0xDF,0xFF,0x80,
0x03,0xFF,0xFF,0xC0,0x03,0xFE,0x1F,0xE0,0x03,0xF8,0x07,0xF0,0x03,0xF0,0x03,0xF0,
0x03,0xE0,0x03,0xF8,0x03,0xE0,0x01,0xF8,0x03,0x80,0x01,0xF8,0x00,0x00,0x01,0xFC,
0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,
0x00,0x00,0x00,0xFC,0x03,0xE0,0x00,0xFC,0x07,0xF0,0x00,0xFC,0x0F,0xF0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x0F,0xF0,0x01,0xF8,0x0F,0xF0,0x01,0xF8,0x0F,0xE0,0x01,0xF8,
0x0F,0xE0,0x03,0xF0,0x07,0xE0,0x07,0xF0,0x03,0xF0,0x0F,0xE0,0x01,0xFC,0x1F,0xC0,
0x00,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"5",5*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x00,
0x00,0x0F,0xFF,0xC0,0x00,0x1F,0xFF,0xF0,0x00,0x3F,0x87,0xF0,0x00,0x7E,0x03,0xF8,
0x00,0xFC,0x03,0xF8,0x01,0xF8,0x03,0xF8,0x03,0xF0,0x03,0xF8,0x03,0xE0,0x01,0xF0,
0x07,0xE0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x0F,0xC0,0x00,0x00,
0x0F,0xC0,0x00,0x00,0x0F,0xC0,0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x83,0xFE,0x00,
0x1F,0x9F,0xFF,0xC0,0x1F,0xBF,0xFF,0xE0,0x1F,0xFF,0x0F,0xF0,0x1F,0xFC,0x03,0xF8,
0x1F,0xF8,0x01,0xF8,0x1F,0xF0,0x01,0xFC,0x1F,0xE0,0x00,0xFC,0x1F,0xC0,0x00,0xFC,
0x1F,0xC0,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x0F,0xC0,0x00,0x7E,0x0F,0xC0,0x00,0x7E,
0x0F,0xC0,0x00,0x7E,0x0F,0xC0,0x00,0xFE,0x07,0xE0,0x00,0xFC,0x07,0xF0,0x00,0xFC,
0x03,0xF0,0x01,0xF8,0x03,0xF8,0x01,0xF8,0x01,0xFC,0x03,0xF0,0x00,0xFF,0x0F,0xE0,
0x00,0x7F,0xFF,0xC0,0x00,0x3F,0xFF,0x80,0x00,0x07,0xFC,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"6",6*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFC,
0x07,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xF8,
0x07,0xF0,0x00,0xF0,0x07,0xC0,0x01,0xF0,0x07,0x80,0x01,0xE0,0x0F,0x80,0x03,0xE0,
0x0F,0x00,0x03,0xC0,0x0F,0x00,0x07,0xC0,0x0F,0x00,0x0F,0x80,0x00,0x00,0x0F,0x80,
0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3E,0x00,
0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,
0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xF0,0x00,
0x00,0x03,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x07,0xE0,0x00,
0x00,0x07,0xE0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x0F,0xE0,0x00,
0x00,0x0F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,
0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,
0x00,0x1F,0xE0,0x00,0x00,0x1F,0xE0,0x00,0x00,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"7",7*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFC,0x00,
0x00,0x7F,0xFF,0x80,0x00,0xFF,0xFF,0xC0,0x01,0xFE,0x1F,0xE0,0x03,0xF8,0x07,0xF0,
0x07,0xF0,0x03,0xF8,0x07,0xE0,0x01,0xF8,0x0F,0xE0,0x01,0xFC,0x0F,0xC0,0x00,0xFC,
0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xC0,0x00,0xFC,0x0F,0xE0,0x00,0xFC,
0x0F,0xF0,0x00,0xFC,0x07,0xF0,0x01,0xF8,0x07,0xFC,0x01,0xF8,0x03,0xFE,0x03,0xF0,
0x03,0xFF,0x87,0xE0,0x01,0xFF,0xEF,0xC0,0x00,0xFF,0xFF,0x80,0x00,0x3F,0xFE,0x00,
0x00,0x7F,0xFF,0x00,0x00,0xFF,0xFF,0x80,0x01,0xF8,0xFF,0xC0,0x03,0xF0,0x7F,0xE0,
0x07,0xE0,0x1F,0xF0,0x0F,0xE0,0x0F,0xF8,0x0F,0xC0,0x07,0xF8,0x0F,0xC0,0x03,0xF8,
0x1F,0xC0,0x01,0xFC,0x1F,0x80,0x01,0xFC,0x1F,0x80,0x00,0xFC,0x1F,0x80,0x00,0xFC,
0x1F,0x80,0x00,0xFC,0x1F,0x80,0x00,0xFC,0x1F,0xC0,0x00,0xFC,0x0F,0xC0,0x01,0xF8,
0x0F,0xE0,0x01,0xF8,0x07,0xE0,0x03,0xF0,0x07,0xF8,0x07,0xF0,0x03,0xFC,0x1F,0xE0,
0x00,0xFF,0xFF,0xC0,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"8",8*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,
0x00,0x7F,0xFF,0x00,0x00,0xFF,0xFF,0x80,0x01,0xFE,0x1F,0xC0,0x03,0xF8,0x07,0xE0,
0x07,0xF0,0x03,0xF0,0x07,0xE0,0x01,0xF0,0x0F,0xC0,0x01,0xF8,0x0F,0xC0,0x00,0xF8,
0x0F,0xC0,0x00,0xFC,0x1F,0x80,0x00,0xFC,0x1F,0x80,0x00,0x7C,0x1F,0x80,0x00,0x7C,
0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,0x1F,0x80,0x00,0x7E,
0x1F,0x80,0x00,0x7E,0x1F,0xC0,0x00,0xFE,0x1F,0xC0,0x00,0xFE,0x0F,0xC0,0x01,0xFE,
0x0F,0xE0,0x03,0xFE,0x0F,0xF0,0x07,0xFE,0x07,0xF8,0x0F,0xFE,0x03,0xFC,0x3F,0xFE,
0x01,0xFF,0xFF,0x7E,0x00,0xFF,0xFC,0xFE,0x00,0x1F,0xF0,0xFC,0x00,0x00,0x00,0xFC,
0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF8,
0x00,0x00,0x01,0xF8,0x00,0x00,0x03,0xF0,0x03,0xE0,0x03,0xF0,0x07,0xF0,0x07,0xE0,
0x07,0xF0,0x0F,0xE0,0x07,0xF0,0x0F,0xC0,0x07,0xF0,0x3F,0x80,0x07,0xF8,0xFF,0x00,
0x03,0xFF,0xFE,0x00,0x01,0xFF,0xF8,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"9",9*/
};
#endif
const unsigned char asc2_1206[95][12] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*" ",0*/
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"!",1*/
{ 0x00, 0x00, 0x30, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, 0x00, 0x00, 0x00 }, /*""",2*/
{ 0x09, 0x00, 0x0B, 0xC0, 0x3D, 0x00, 0x0B, 0xC0, 0x3D, 0x00, 0x09, 0x00 }, /*"#",3*/
{ 0x18, 0xC0, 0x24, 0x40, 0x7F, 0xE0, 0x22, 0x40, 0x31, 0x80, 0x00, 0x00 }, /*"$",4*/
{ 0x18, 0x00, 0x24, 0xC0, 0x1B, 0x00, 0x0D, 0x80, 0x32, 0x40, 0x01, 0x80 }, /*"%",5*/
{ 0x03, 0x80, 0x1C, 0x40, 0x27, 0x40, 0x1C, 0x80, 0x07, 0x40, 0x00, 0x40 }, /*"&",6*/
{ 0x10, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"'",7*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x20, 0x40, 0x40, 0x20 }, /*"(",8*/
{ 0x00, 0x00, 0x40, 0x20, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 }, /*")",9*/
{ 0x09, 0x00, 0x06, 0x00, 0x1F, 0x80, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00 }, /*"*",10*/
{ 0x04, 0x00, 0x04, 0x00, 0x3F, 0x80, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00 }, /*"+",11*/
{ 0x00, 0x10, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*",",12*/
{ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00 }, /*"-",13*/
{ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*".",14*/
{ 0x00, 0x20, 0x01, 0xC0, 0x06, 0x00, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00 }, /*"/",15*/
{ 0x1F, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00 }, /*"0",16*/
{ 0x00, 0x00, 0x10, 0x40, 0x3F, 0xC0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00 }, /*"1",17*/
{ 0x18, 0xC0, 0x21, 0x40, 0x22, 0x40, 0x24, 0x40, 0x18, 0x40, 0x00, 0x00 }, /*"2",18*/
{ 0x10, 0x80, 0x20, 0x40, 0x24, 0x40, 0x24, 0x40, 0x1B, 0x80, 0x00, 0x00 }, /*"3",19*/
{ 0x02, 0x00, 0x0D, 0x00, 0x11, 0x00, 0x3F, 0xC0, 0x01, 0x40, 0x00, 0x00 }, /*"4",20*/
{ 0x3C, 0x80, 0x24, 0x40, 0x24, 0x40, 0x24, 0x40, 0x23, 0x80, 0x00, 0x00 }, /*"5",21*/
{ 0x1F, 0x80, 0x24, 0x40, 0x24, 0x40, 0x34, 0x40, 0x03, 0x80, 0x00, 0x00 }, /*"6",22*/
{ 0x30, 0x00, 0x20, 0x00, 0x27, 0xC0, 0x38, 0x00, 0x20, 0x00, 0x00, 0x00 }, /*"7",23*/
{ 0x1B, 0x80, 0x24, 0x40, 0x24, 0x40, 0x24, 0x40, 0x1B, 0x80, 0x00, 0x00 }, /*"8",24*/
{ 0x1C, 0x00, 0x22, 0xC0, 0x22, 0x40, 0x22, 0x40, 0x1F, 0x80, 0x00, 0x00 }, /*"9",25*/
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*":",26*/
{ 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*";",27*/
{ 0x00, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x20, 0x80, 0x40, 0x40 }, /*"<",28*/
{ 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00 }, /*"=",29*/
{ 0x00, 0x00, 0x40, 0x40, 0x20, 0x80, 0x11, 0x00, 0x0A, 0x00, 0x04, 0x00 }, /*">",30*/
{ 0x18, 0x00, 0x20, 0x00, 0x23, 0x40, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00 }, /*"?",31*/
{ 0x1F, 0x80, 0x20, 0x40, 0x27, 0x40, 0x29, 0x40, 0x1F, 0x40, 0x00, 0x00 }, /*"@",32*/
{ 0x00, 0x40, 0x07, 0xC0, 0x39, 0x00, 0x0F, 0x00, 0x01, 0xC0, 0x00, 0x40 }, /*"A",33*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x24, 0x40, 0x1B, 0x80, 0x00, 0x00 }, /*"B",34*/
{ 0x1F, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x30, 0x80, 0x00, 0x00 }, /*"C",35*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00 }, /*"D",36*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x2E, 0x40, 0x30, 0xC0, 0x00, 0x00 }, /*"E",37*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x2E, 0x00, 0x30, 0x00, 0x00, 0x00 }, /*"F",38*/
{ 0x0F, 0x00, 0x10, 0x80, 0x20, 0x40, 0x22, 0x40, 0x33, 0x80, 0x02, 0x00 }, /*"G",39*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x04, 0x00, 0x04, 0x00, 0x3F, 0xC0, 0x20, 0x40 }, /*"H",40*/
{ 0x20, 0x40, 0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x00, 0x00 }, /*"I",41*/
{ 0x00, 0x60, 0x20, 0x20, 0x20, 0x20, 0x3F, 0xC0, 0x20, 0x00, 0x20, 0x00 }, /*"J",42*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x0B, 0x00, 0x30, 0xC0, 0x20, 0x40 }, /*"K",43*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0 }, /*"L",44*/
{ 0x3F, 0xC0, 0x3C, 0x00, 0x03, 0xC0, 0x3C, 0x00, 0x3F, 0xC0, 0x00, 0x00 }, /*"M",45*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x0C, 0x40, 0x23, 0x00, 0x3F, 0xC0, 0x20, 0x00 }, /*"N",46*/
{ 0x1F, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00 }, /*"O",47*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00 }, /*"P",48*/
{ 0x1F, 0x80, 0x21, 0x40, 0x21, 0x40, 0x20, 0xE0, 0x1F, 0xA0, 0x00, 0x00 }, /*"Q",49*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x26, 0x00, 0x19, 0xC0, 0x00, 0x40 }, /*"R",50*/
{ 0x18, 0xC0, 0x24, 0x40, 0x24, 0x40, 0x22, 0x40, 0x31, 0x80, 0x00, 0x00 }, /*"S",51*/
{ 0x30, 0x00, 0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x30, 0x00, 0x00, 0x00 }, /*"T",52*/
{ 0x20, 0x00, 0x3F, 0x80, 0x00, 0x40, 0x00, 0x40, 0x3F, 0x80, 0x20, 0x00 }, /*"U",53*/
{ 0x20, 0x00, 0x3E, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x38, 0x00, 0x20, 0x00 }, /*"V",54*/
{ 0x38, 0x00, 0x07, 0xC0, 0x3C, 0x00, 0x07, 0xC0, 0x38, 0x00, 0x00, 0x00 }, /*"W",55*/
{ 0x20, 0x40, 0x39, 0xC0, 0x06, 0x00, 0x39, 0xC0, 0x20, 0x40, 0x00, 0x00 }, /*"X",56*/
{ 0x20, 0x00, 0x38, 0x40, 0x07, 0xC0, 0x38, 0x40, 0x20, 0x00, 0x00, 0x00 }, /*"Y",57*/
{ 0x30, 0x40, 0x21, 0xC0, 0x26, 0x40, 0x38, 0x40, 0x20, 0xC0, 0x00, 0x00 }, /*"Z",58*/
{ 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x00, 0x00 }, /*"[",59*/
{ 0x00, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x03, 0x80, 0x00, 0x40, 0x00, 0x00 }, /*"\",60*/
{ 0x00, 0x00, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00 }, /*"]",61*/
{ 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"^",62*/
{ 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10 }, /*"_",63*/
{ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"`",64*/
{ 0x00, 0x00, 0x02, 0x80, 0x05, 0x40, 0x05, 0x40, 0x03, 0xC0, 0x00, 0x40 }, /*"a",65*/
{ 0x20, 0x00, 0x3F, 0xC0, 0x04, 0x40, 0x04, 0x40, 0x03, 0x80, 0x00, 0x00 }, /*"b",66*/
{ 0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x04, 0x40, 0x06, 0x40, 0x00, 0x00 }, /*"c",67*/
{ 0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x24, 0x40, 0x3F, 0xC0, 0x00, 0x40 }, /*"d",68*/
{ 0x00, 0x00, 0x03, 0x80, 0x05, 0x40, 0x05, 0x40, 0x03, 0x40, 0x00, 0x00 }, /*"e",69*/
{ 0x00, 0x00, 0x04, 0x40, 0x1F, 0xC0, 0x24, 0x40, 0x24, 0x40, 0x20, 0x00 }, /*"f",70*/
{ 0x00, 0x00, 0x02, 0xE0, 0x05, 0x50, 0x05, 0x50, 0x06, 0x50, 0x04, 0x20 }, /*"g",71*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x04, 0x40, 0x04, 0x00, 0x03, 0xC0, 0x00, 0x40 }, /*"h",72*/
{ 0x00, 0x00, 0x04, 0x40, 0x27, 0xC0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00 }, /*"i",73*/
{ 0x00, 0x10, 0x00, 0x10, 0x04, 0x10, 0x27, 0xE0, 0x00, 0x00, 0x00, 0x00 }, /*"j",74*/
{ 0x20, 0x40, 0x3F, 0xC0, 0x01, 0x40, 0x07, 0x00, 0x04, 0xC0, 0x04, 0x40 }, /*"k",75*/
{ 0x20, 0x40, 0x20, 0x40, 0x3F, 0xC0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00 }, /*"l",76*/
{ 0x07, 0xC0, 0x04, 0x00, 0x07, 0xC0, 0x04, 0x00, 0x03, 0xC0, 0x00, 0x00 }, /*"m",77*/
{ 0x04, 0x40, 0x07, 0xC0, 0x04, 0x40, 0x04, 0x00, 0x03, 0xC0, 0x00, 0x40 }, /*"n",78*/
{ 0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x04, 0x40, 0x03, 0x80, 0x00, 0x00 }, /*"o",79*/
{ 0x04, 0x10, 0x07, 0xF0, 0x04, 0x50, 0x04, 0x40, 0x03, 0x80, 0x00, 0x00 }, /*"p",80*/
{ 0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x04, 0x50, 0x07, 0xF0, 0x00, 0x10 }, /*"q",81*/
{ 0x04, 0x40, 0x07, 0xC0, 0x02, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00 }, /*"r",82*/
{ 0x00, 0x00, 0x06, 0x40, 0x05, 0x40, 0x05, 0x40, 0x04, 0xC0, 0x00, 0x00 }, /*"s",83*/
{ 0x00, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x04, 0x40, 0x00, 0x40, 0x00, 0x00 }, /*"t",84*/
{ 0x04, 0x00, 0x07, 0x80, 0x00, 0x40, 0x04, 0x40, 0x07, 0xC0, 0x00, 0x40 }, /*"u",85*/
{ 0x04, 0x00, 0x07, 0x00, 0x04, 0xC0, 0x01, 0x80, 0x06, 0x00, 0x04, 0x00 }, /*"v",86*/
{ 0x06, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x01, 0xC0, 0x06, 0x00, 0x00, 0x00 }, /*"w",87*/
{ 0x04, 0x40, 0x06, 0xC0, 0x01, 0x00, 0x06, 0xC0, 0x04, 0x40, 0x00, 0x00 }, /*"x",88*/
{ 0x04, 0x10, 0x07, 0x10, 0x04, 0xE0, 0x01, 0x80, 0x06, 0x00, 0x04, 0x00 }, /*"y",89*/
{ 0x00, 0x00, 0x04, 0x40, 0x05, 0xC0, 0x06, 0x40, 0x04, 0x40, 0x00, 0x00 }, /*"z",90*/
{ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x7B, 0xE0, 0x40, 0x20, 0x00, 0x00 }, /*"{",91*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00 }, /*"|",92*/
{ 0x00, 0x00, 0x40, 0x20, 0x7B, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"}",93*/
{ 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00 }, /*"~",94*/
};
const unsigned char asc2_1608[95][16] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*" ",0*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xCC, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"!",1*/
{ 0x00, 0x00, 0x08, 0x00, 0x30, 0x00, 0x60, 0x00, 0x08, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00 }, /*""",2*/
{ 0x02, 0x20, 0x03, 0xFC, 0x1E, 0x20, 0x02, 0x20, 0x03, 0xFC, 0x1E, 0x20, 0x02, 0x20, 0x00, 0x00 }, /*"#",3*/
{ 0x00, 0x00, 0x0E, 0x18, 0x11, 0x04, 0x3F, 0xFF, 0x10, 0x84, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00 }, /*"$",4*/
{ 0x0F, 0x00, 0x10, 0x84, 0x0F, 0x38, 0x00, 0xC0, 0x07, 0x78, 0x18, 0x84, 0x00, 0x78, 0x00, 0x00 }, /*"%",5*/
{ 0x00, 0x78, 0x0F, 0x84, 0x10, 0xC4, 0x11, 0x24, 0x0E, 0x98, 0x00, 0xE4, 0x00, 0x84, 0x00, 0x08 }, /*"&",6*/
{ 0x08, 0x00, 0x68, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"'",7*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x18, 0x18, 0x20, 0x04, 0x40, 0x02, 0x00, 0x00 }, /*"(",8*/
{ 0x00, 0x00, 0x40, 0x02, 0x20, 0x04, 0x18, 0x18, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*")",9*/
{ 0x02, 0x40, 0x02, 0x40, 0x01, 0x80, 0x0F, 0xF0, 0x01, 0x80, 0x02, 0x40, 0x02, 0x40, 0x00, 0x00 }, /*"*",10*/
{ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x0F, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }, /*"+",11*/
{ 0x00, 0x01, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*",",12*/
{ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80 }, /*"-",13*/
{ 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*".",14*/
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x01, 0x80, 0x06, 0x00, 0x18, 0x00, 0x20, 0x00 }, /*"/",15*/
{ 0x00, 0x00, 0x07, 0xF0, 0x08, 0x08, 0x10, 0x04, 0x10, 0x04, 0x08, 0x08, 0x07, 0xF0, 0x00, 0x00 }, /*"0",16*/
{ 0x00, 0x00, 0x08, 0x04, 0x08, 0x04, 0x1F, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }, /*"1",17*/
{ 0x00, 0x00, 0x0E, 0x0C, 0x10, 0x14, 0x10, 0x24, 0x10, 0x44, 0x11, 0x84, 0x0E, 0x0C, 0x00, 0x00 }, /*"2",18*/
{ 0x00, 0x00, 0x0C, 0x18, 0x10, 0x04, 0x11, 0x04, 0x11, 0x04, 0x12, 0x88, 0x0C, 0x70, 0x00, 0x00 }, /*"3",19*/
{ 0x00, 0x00, 0x00, 0xE0, 0x03, 0x20, 0x04, 0x24, 0x08, 0x24, 0x1F, 0xFC, 0x00, 0x24, 0x00, 0x00 }, /*"4",20*/
{ 0x00, 0x00, 0x1F, 0x98, 0x10, 0x84, 0x11, 0x04, 0x11, 0x04, 0x10, 0x88, 0x10, 0x70, 0x00, 0x00 }, /*"5",21*/
{ 0x00, 0x00, 0x07, 0xF0, 0x08, 0x88, 0x11, 0x04, 0x11, 0x04, 0x18, 0x88, 0x00, 0x70, 0x00, 0x00 }, /*"6",22*/
{ 0x00, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x10, 0xFC, 0x13, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x00, 0x00 }, /*"7",23*/
{ 0x00, 0x00, 0x0E, 0x38, 0x11, 0x44, 0x10, 0x84, 0x10, 0x84, 0x11, 0x44, 0x0E, 0x38, 0x00, 0x00 }, /*"8",24*/
{ 0x00, 0x00, 0x07, 0x00, 0x08, 0x8C, 0x10, 0x44, 0x10, 0x44, 0x08, 0x88, 0x07, 0xF0, 0x00, 0x00 }, /*"9",25*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*":",26*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*";",27*/
{ 0x00, 0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x00, 0x00 }, /*"<",28*/
{ 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x00, 0x00 }, /*"=",29*/
{ 0x00, 0x00, 0x10, 0x04, 0x08, 0x08, 0x04, 0x10, 0x02, 0x20, 0x01, 0x40, 0x00, 0x80, 0x00, 0x00 }, /*">",30*/
{ 0x00, 0x00, 0x0E, 0x00, 0x12, 0x00, 0x10, 0x0C, 0x10, 0x6C, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00 }, /*"?",31*/
{ 0x03, 0xE0, 0x0C, 0x18, 0x13, 0xE4, 0x14, 0x24, 0x17, 0xC4, 0x08, 0x28, 0x07, 0xD0, 0x00, 0x00 }, /*"@",32*/
{ 0x00, 0x04, 0x00, 0x3C, 0x03, 0xC4, 0x1C, 0x40, 0x07, 0x40, 0x00, 0xE4, 0x00, 0x1C, 0x00, 0x04 }, /*"A",33*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x04, 0x11, 0x04, 0x0E, 0x88, 0x00, 0x70, 0x00, 0x00 }, /*"B",34*/
{ 0x03, 0xE0, 0x0C, 0x18, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x10, 0x08, 0x1C, 0x10, 0x00, 0x00 }, /*"C",35*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x08, 0x08, 0x07, 0xF0, 0x00, 0x00 }, /*"D",36*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x04, 0x17, 0xC4, 0x10, 0x04, 0x08, 0x18, 0x00, 0x00 }, /*"E",37*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x00, 0x17, 0xC0, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00 }, /*"F",38*/
{ 0x03, 0xE0, 0x0C, 0x18, 0x10, 0x04, 0x10, 0x04, 0x10, 0x44, 0x1C, 0x78, 0x00, 0x40, 0x00, 0x00 }, /*"G",39*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x84, 0x00, 0x80, 0x00, 0x80, 0x10, 0x84, 0x1F, 0xFC, 0x10, 0x04 }, /*"H",40*/
{ 0x00, 0x00, 0x10, 0x04, 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00 }, /*"I",41*/
{ 0x00, 0x03, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x1F, 0xFE, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00 }, /*"J",42*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x03, 0x80, 0x14, 0x64, 0x18, 0x1C, 0x10, 0x04, 0x00, 0x00 }, /*"K",43*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00 }, /*"L",44*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x1F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x1F, 0xFC, 0x10, 0x04, 0x00, 0x00 }, /*"M",45*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x0C, 0x04, 0x03, 0x00, 0x00, 0xE0, 0x10, 0x18, 0x1F, 0xFC, 0x10, 0x00 }, /*"N",46*/
{ 0x07, 0xF0, 0x08, 0x08, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x08, 0x08, 0x07, 0xF0, 0x00, 0x00 }, /*"O",47*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x84, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00 }, /*"P",48*/
{ 0x07, 0xF0, 0x08, 0x18, 0x10, 0x24, 0x10, 0x24, 0x10, 0x1C, 0x08, 0x0A, 0x07, 0xF2, 0x00, 0x00 }, /*"Q",49*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x00, 0x11, 0xC0, 0x11, 0x30, 0x0E, 0x0C, 0x00, 0x04 }, /*"R",50*/
{ 0x00, 0x00, 0x0E, 0x1C, 0x11, 0x04, 0x10, 0x84, 0x10, 0x84, 0x10, 0x44, 0x1C, 0x38, 0x00, 0x00 }, /*"S",51*/
{ 0x18, 0x00, 0x10, 0x00, 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00 }, /*"T",52*/
{ 0x10, 0x00, 0x1F, 0xF8, 0x10, 0x04, 0x00, 0x04, 0x00, 0x04, 0x10, 0x04, 0x1F, 0xF8, 0x10, 0x00 }, /*"U",53*/
{ 0x10, 0x00, 0x1E, 0x00, 0x11, 0xE0, 0x00, 0x1C, 0x00, 0x70, 0x13, 0x80, 0x1C, 0x00, 0x10, 0x00 }, /*"V",54*/
{ 0x1F, 0xC0, 0x10, 0x3C, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x10, 0x3C, 0x1F, 0xC0, 0x00, 0x00 }, /*"W",55*/
{ 0x10, 0x04, 0x18, 0x0C, 0x16, 0x34, 0x01, 0xC0, 0x01, 0xC0, 0x16, 0x34, 0x18, 0x0C, 0x10, 0x04 }, /*"X",56*/
{ 0x10, 0x00, 0x1C, 0x00, 0x13, 0x04, 0x00, 0xFC, 0x13, 0x04, 0x1C, 0x00, 0x10, 0x00, 0x00, 0x00 }, /*"Y",57*/
{ 0x08, 0x04, 0x10, 0x1C, 0x10, 0x64, 0x10, 0x84, 0x13, 0x04, 0x1C, 0x04, 0x10, 0x18, 0x00, 0x00 }, /*"Z",58*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x00, 0x00 }, /*"[",59*/
{ 0x00, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x03, 0x80, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x03, 0x00, 0x00 }, /*"\",60*/
{ 0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"]",61*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00 }, /*"^",62*/
{ 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 }, /*"_",63*/
{ 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"`",64*/
{ 0x00, 0x00, 0x00, 0x98, 0x01, 0x24, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x00, 0xFC, 0x00, 0x04 }, /*"a",65*/
{ 0x10, 0x00, 0x1F, 0xFC, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x00, 0x88, 0x00, 0x70, 0x00, 0x00 }, /*"b",66*/
{ 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x00, 0x88, 0x00, 0x00 }, /*"c",67*/
{ 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x11, 0x08, 0x1F, 0xFC, 0x00, 0x04 }, /*"d",68*/
{ 0x00, 0x00, 0x00, 0xF8, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x00, 0xC8, 0x00, 0x00 }, /*"e",69*/
{ 0x00, 0x00, 0x01, 0x04, 0x01, 0x04, 0x0F, 0xFC, 0x11, 0x04, 0x11, 0x04, 0x11, 0x00, 0x18, 0x00 }, /*"f",70*/
{ 0x00, 0x00, 0x00, 0xD6, 0x01, 0x29, 0x01, 0x29, 0x01, 0x29, 0x01, 0xC9, 0x01, 0x06, 0x00, 0x00 }, /*"g",71*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x00, 0x84, 0x01, 0x00, 0x01, 0x00, 0x01, 0x04, 0x00, 0xFC, 0x00, 0x04 }, /*"h",72*/
{ 0x00, 0x00, 0x01, 0x04, 0x19, 0x04, 0x19, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }, /*"i",73*/
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x01, 0x19, 0x01, 0x19, 0xFE, 0x00, 0x00, 0x00, 0x00 }, /*"j",74*/
{ 0x10, 0x04, 0x1F, 0xFC, 0x00, 0x24, 0x00, 0x40, 0x01, 0xB4, 0x01, 0x0C, 0x01, 0x04, 0x00, 0x00 }, /*"k",75*/
{ 0x00, 0x00, 0x10, 0x04, 0x10, 0x04, 0x1F, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }, /*"l",76*/
{ 0x01, 0x04, 0x01, 0xFC, 0x01, 0x04, 0x01, 0x00, 0x01, 0xFC, 0x01, 0x04, 0x01, 0x00, 0x00, 0xFC }, /*"m",77*/
{ 0x01, 0x04, 0x01, 0xFC, 0x00, 0x84, 0x01, 0x00, 0x01, 0x00, 0x01, 0x04, 0x00, 0xFC, 0x00, 0x04 }, /*"n",78*/
{ 0x00, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x00, 0xF8, 0x00, 0x00 }, /*"o",79*/
{ 0x01, 0x01, 0x01, 0xFF, 0x00, 0x85, 0x01, 0x04, 0x01, 0x04, 0x00, 0x88, 0x00, 0x70, 0x00, 0x00 }, /*"p",80*/
{ 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x01, 0x05, 0x01, 0xFF, 0x00, 0x01 }, /*"q",81*/
{ 0x01, 0x04, 0x01, 0x04, 0x01, 0xFC, 0x00, 0x84, 0x01, 0x04, 0x01, 0x00, 0x01, 0x80, 0x00, 0x00 }, /*"r",82*/
{ 0x00, 0x00, 0x00, 0xCC, 0x01, 0x24, 0x01, 0x24, 0x01, 0x24, 0x01, 0x24, 0x01, 0x98, 0x00, 0x00 }, /*"s",83*/
{ 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0xF8, 0x01, 0x04, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00 }, /*"t",84*/
{ 0x01, 0x00, 0x01, 0xF8, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x01, 0x08, 0x01, 0xFC, 0x00, 0x04 }, /*"u",85*/
{ 0x01, 0x00, 0x01, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, 0x10, 0x01, 0x60, 0x01, 0x80, 0x01, 0x00 }, /*"v",86*/
{ 0x01, 0xF0, 0x01, 0x0C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x30, 0x01, 0x0C, 0x01, 0xF0, 0x01, 0x00 }, /*"w",87*/
{ 0x00, 0x00, 0x01, 0x04, 0x01, 0x8C, 0x00, 0x74, 0x01, 0x70, 0x01, 0x8C, 0x01, 0x04, 0x00, 0x00 }, /*"x",88*/
{ 0x01, 0x01, 0x01, 0x81, 0x01, 0x71, 0x00, 0x0E, 0x00, 0x18, 0x01, 0x60, 0x01, 0x80, 0x01, 0x00 }, /*"y",89*/
{ 0x00, 0x00, 0x01, 0x84, 0x01, 0x0C, 0x01, 0x34, 0x01, 0x44, 0x01, 0x84, 0x01, 0x0C, 0x00, 0x00 }, /*"z",90*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3E, 0xFC, 0x40, 0x02, 0x40, 0x02 }, /*"{",91*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"|",92*/
{ 0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0x3E, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"}",93*/
{ 0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00 }, /*"~",94*/
};
const unsigned char asc2_2412[95][36] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*" ",0*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x38, 0x0F, 0xFE, 0x38, 0x0F, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"!",1*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x31, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*""",2*/
{ 0x00, 0x00, 0x00, 0x00, 0x61, 0x80, 0x00, 0x67, 0xF8, 0x07, 0xF9, 0x80, 0x00, 0x61, 0x80, 0x00, 0x61, 0x80, 0x00, 0x61, 0x80, 0x00, 0x61, 0x80, 0x00, 0x67, 0xF8, 0x07, 0xF9, 0x80, 0x00, 0x61, 0x80, 0x00, 0x00, 0x00 }, /*"#",3*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0xE0, 0x03, 0xE0, 0xF0, 0x06, 0x30, 0x08, 0x04, 0x18, 0x08, 0x1F, 0xFF, 0xFE, 0x04, 0x0E, 0x08, 0x07, 0x87, 0xF0, 0x03, 0x81, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"$",4*/
{ 0x01, 0xF0, 0x00, 0x06, 0x0C, 0x00, 0x04, 0x04, 0x08, 0x06, 0x0C, 0x70, 0x01, 0xF9, 0xC0, 0x00, 0x0E, 0x00, 0x00, 0x3B, 0xE0, 0x00, 0xEC, 0x18, 0x07, 0x08, 0x08, 0x04, 0x0C, 0x18, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00 }, /*"%",5*/
{ 0x00, 0x01, 0xE0, 0x00, 0x07, 0xF0, 0x03, 0xF8, 0x18, 0x04, 0x1C, 0x08, 0x04, 0x17, 0x08, 0x07, 0xE1, 0xD0, 0x03, 0xC0, 0xE0, 0x00, 0x23, 0xB0, 0x00, 0x3C, 0x08, 0x00, 0x20, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 }, /*"&",6*/
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x31, 0x00, 0x00, 0x32, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"'",7*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x01, 0xFF, 0xC0, 0x07, 0x80, 0xF0, 0x0C, 0x00, 0x18, 0x10, 0x00, 0x04, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00 }, /*"(",8*/
{ 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x10, 0x00, 0x04, 0x0C, 0x00, 0x18, 0x07, 0x80, 0xF0, 0x01, 0xFF, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*")",9*/
{ 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x18, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x18, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x00, 0x00, 0x42, 0x00 }, /*"*",10*/
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00 }, /*"+",11*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x31, 0x00, 0x00, 0x32, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*",",12*/
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 }, /*"-",13*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*".",14*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x70, 0x00, 0x01, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xC0, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"/",15*/
{ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0x80, 0x70, 0x06, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x06, 0x00, 0x18, 0x03, 0x80, 0x70, 0x01, 0xFF, 0xE0, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00 }, /*"0",16*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x03, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"1",17*/
{ 0x00, 0x00, 0x00, 0x01, 0xC0, 0x38, 0x02, 0xC0, 0x58, 0x04, 0x00, 0x98, 0x04, 0x01, 0x18, 0x04, 0x02, 0x18, 0x04, 0x04, 0x18, 0x06, 0x1C, 0x18, 0x03, 0xF8, 0x18, 0x01, 0xE0, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"2",18*/
{ 0x00, 0x00, 0x00, 0x01, 0xC0, 0xE0, 0x03, 0xC0, 0xF0, 0x04, 0x00, 0x08, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x06, 0x18, 0x08, 0x03, 0xF4, 0x18, 0x01, 0xE7, 0xF0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"3",19*/
{ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x11, 0x00, 0x00, 0x61, 0x00, 0x00, 0x81, 0x08, 0x03, 0x01, 0x08, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0xF8, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00 }, /*"4",20*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0xFC, 0xD0, 0x06, 0x08, 0x08, 0x06, 0x10, 0x08, 0x06, 0x10, 0x08, 0x06, 0x10, 0x08, 0x06, 0x18, 0x38, 0x06, 0x0F, 0xF0, 0x06, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"5",21*/
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0x84, 0x30, 0x02, 0x08, 0x18, 0x04, 0x10, 0x08, 0x04, 0x10, 0x08, 0x04, 0x10, 0x08, 0x07, 0x18, 0x10, 0x03, 0x0F, 0xF0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00 }, /*"6",22*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0xF8, 0x06, 0x07, 0xF8, 0x06, 0x18, 0x00, 0x06, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"7",23*/
{ 0x00, 0x00, 0x00, 0x01, 0xE1, 0xE0, 0x03, 0xF7, 0xF0, 0x06, 0x34, 0x10, 0x04, 0x18, 0x08, 0x04, 0x18, 0x08, 0x04, 0x0C, 0x08, 0x04, 0x0C, 0x08, 0x06, 0x16, 0x18, 0x03, 0xF3, 0xF0, 0x01, 0xC1, 0xE0, 0x00, 0x00, 0x00 }, /*"8",24*/
{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x03, 0xFC, 0x30, 0x03, 0x06, 0x38, 0x04, 0x02, 0x08, 0x04, 0x02, 0x08, 0x04, 0x02, 0x08, 0x04, 0x04, 0x10, 0x03, 0x08, 0xF0, 0x01, 0xFF, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00 }, /*"9",25*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*":",26*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1A, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*";",27*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, 0x00, 0x22, 0x00, 0x00, 0x41, 0x00, 0x00, 0x80, 0x80, 0x01, 0x00, 0x40, 0x02, 0x00, 0x20, 0x04, 0x00, 0x10, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00 }, /*"<",28*/
{ 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00 }, /*"=",29*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x04, 0x00, 0x10, 0x02, 0x00, 0x20, 0x01, 0x00, 0x40, 0x00, 0x80, 0x80, 0x00, 0x41, 0x00, 0x00, 0x22, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 }, /*">",30*/
{ 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x04, 0xC0, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x38, 0x08, 0x0F, 0x38, 0x08, 0x08, 0x38, 0x08, 0x10, 0x00, 0x0C, 0x30, 0x00, 0x07, 0xE0, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00 }, /*"?",31*/
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0xFF, 0xE0, 0x03, 0x80, 0x70, 0x02, 0x0F, 0x10, 0x06, 0x70, 0x88, 0x04, 0xC0, 0x88, 0x04, 0x83, 0x08, 0x04, 0x7F, 0x88, 0x02, 0xC0, 0x90, 0x03, 0x01, 0x20, 0x00, 0xFE, 0x40 }, /*"@",32*/
{ 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x01, 0xF8, 0x00, 0x3E, 0x08, 0x01, 0xC2, 0x00, 0x07, 0x02, 0x00, 0x07, 0xE2, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x1F, 0xC8, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08 }, /*"A",33*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x06, 0x18, 0x08, 0x03, 0xF4, 0x18, 0x01, 0xE7, 0xF0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00 }, /*"B",34*/
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0x80, 0x70, 0x02, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x10, 0x06, 0x00, 0x20, 0x07, 0x80, 0xC0, 0x00, 0x00, 0x00 }, /*"C",35*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x18, 0x02, 0x00, 0x10, 0x03, 0x80, 0x70, 0x01, 0xFF, 0xE0, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00 }, /*"D",36*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x04, 0x08, 0x08, 0x04, 0x3E, 0x08, 0x04, 0x00, 0x08, 0x06, 0x00, 0x18, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00 }, /*"E",37*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x08, 0x08, 0x04, 0x08, 0x00, 0x04, 0x08, 0x00, 0x04, 0x08, 0x00, 0x04, 0x3E, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00 }, /*"F",38*/
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0x80, 0x70, 0x06, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x02, 0x08, 0x04, 0x02, 0x08, 0x02, 0x03, 0xF0, 0x07, 0x83, 0xF0, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00 }, /*"G",39*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x04, 0x08, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x08 }, /*"H",40*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"I",41*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x03, 0x07, 0xFF, 0xFE, 0x07, 0xFF, 0xFC, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00 }, /*"J",42*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x0C, 0x08, 0x00, 0x18, 0x00, 0x00, 0x3E, 0x00, 0x04, 0xC7, 0x80, 0x05, 0x03, 0xC8, 0x06, 0x00, 0xF8, 0x04, 0x00, 0x38, 0x04, 0x00, 0x18, 0x00, 0x00, 0x08 }, /*"K",43*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00 }, /*"L",44*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0x80, 0x08, 0x07, 0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xC0, 0x00, 0x78, 0x00, 0x07, 0x80, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x08 }, /*"M",45*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0x00, 0x08, 0x03, 0xC0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0xC0, 0x04, 0x00, 0xF0, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x00 }, /*"N",46*/
{ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0x80, 0x70, 0x06, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x06, 0x00, 0x18, 0x03, 0x00, 0x30, 0x01, 0xFF, 0xE0, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00 }, /*"O",47*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x04, 0x08, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x06, 0x0C, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00 }, /*"P",48*/
{ 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0x80, 0x70, 0x06, 0x00, 0x88, 0x04, 0x00, 0x88, 0x04, 0x00, 0xC8, 0x06, 0x00, 0x3C, 0x03, 0x00, 0x3E, 0x01, 0xFF, 0xE6, 0x00, 0x7F, 0x84, 0x00, 0x00, 0x00 }, /*"Q",49*/
{ 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x08, 0x08, 0x04, 0x08, 0x00, 0x04, 0x0C, 0x00, 0x04, 0x0F, 0x00, 0x04, 0x0B, 0xC0, 0x06, 0x10, 0xF0, 0x03, 0xF0, 0x38, 0x01, 0xE0, 0x08, 0x00, 0x00, 0x08 }, /*"R",50*/
{ 0x00, 0x00, 0x00, 0x01, 0xE0, 0xF8, 0x03, 0xF0, 0x30, 0x06, 0x30, 0x10, 0x04, 0x18, 0x08, 0x04, 0x18, 0x08, 0x04, 0x0C, 0x08, 0x04, 0x0C, 0x08, 0x02, 0x06, 0x18, 0x02, 0x07, 0xF0, 0x07, 0x81, 0xE0, 0x00, 0x00, 0x00 }, /*"S",51*/
{ 0x01, 0x80, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF8, 0x04, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x80, 0x00 }, /*"T",52*/
{ 0x04, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x07, 0xFF, 0xF0, 0x04, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x04, 0x00, 0x10, 0x07, 0xFF, 0xE0, 0x04, 0x00, 0x00 }, /*"U",53*/
{ 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x07, 0xFE, 0x00, 0x04, 0x1F, 0xE0, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x38, 0x00, 0x01, 0xE0, 0x04, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00 }, /*"V",54*/
{ 0x04, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x07, 0xFF, 0xC0, 0x04, 0x1F, 0xF8, 0x00, 0x07, 0xC0, 0x07, 0xF8, 0x00, 0x07, 0xFF, 0x80, 0x04, 0x3F, 0xF8, 0x00, 0x07, 0xC0, 0x04, 0xF8, 0x00, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00 }, /*"W",55*/
{ 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x18, 0x07, 0xC0, 0x78, 0x05, 0xF1, 0xC8, 0x00, 0x3E, 0x00, 0x00, 0x1F, 0x80, 0x04, 0x63, 0xE8, 0x07, 0x80, 0xF8, 0x06, 0x00, 0x18, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00 }, /*"X",56*/
{ 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x80, 0x00, 0x07, 0xE0, 0x08, 0x04, 0x7C, 0x08, 0x00, 0x1F, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x18, 0x08, 0x04, 0xE0, 0x08, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00 }, /*"Y",57*/
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x06, 0x00, 0x38, 0x04, 0x00, 0xF8, 0x04, 0x03, 0xE8, 0x04, 0x0F, 0x08, 0x04, 0x7C, 0x08, 0x05, 0xF0, 0x08, 0x07, 0xC0, 0x08, 0x07, 0x00, 0x18, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00 }, /*"Z",58*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00 }, /*"[",59*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }, /*"\",60*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"]",61*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"^",62*/
{ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01 }, /*"_",63*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"`",64*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x19, 0xF8, 0x00, 0x1B, 0x18, 0x00, 0x22, 0x08, 0x00, 0x26, 0x08, 0x00, 0x24, 0x08, 0x00, 0x24, 0x10, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18 }, /*"a",65*/
{ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x00, 0x18, 0x18, 0x00, 0x10, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x30, 0x18, 0x00, 0x1F, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00 }, /*"b",66*/
{ 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x18, 0x30, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x3C, 0x08, 0x00, 0x1C, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"c",67*/
{ 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x38, 0x18, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x04, 0x10, 0x10, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 }, /*"d",68*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x12, 0x30, 0x00, 0x22, 0x18, 0x00, 0x22, 0x08, 0x00, 0x22, 0x08, 0x00, 0x32, 0x08, 0x00, 0x1E, 0x10, 0x00, 0x0E, 0x20, 0x00, 0x00, 0x00 }, /*"e",69*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF8, 0x06, 0x20, 0x08, 0x04, 0x20, 0x08, 0x04, 0x20, 0x08, 0x07, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"f",70*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x6E, 0x00, 0x1F, 0xF3, 0x00, 0x31, 0xB1, 0x00, 0x20, 0xB1, 0x00, 0x20, 0xB1, 0x00, 0x31, 0x91, 0x00, 0x1F, 0x13, 0x00, 0x2E, 0x1E, 0x00, 0x20, 0x0E, 0x00, 0x30, 0x00 }, /*"g",71*/
{ 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0xF8, 0x00, 0x10, 0x08, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x08, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 }, /*"h",72*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x06, 0x3F, 0xF8, 0x06, 0x3F, 0xF8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"i",73*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x20, 0x01, 0x00, 0x20, 0x01, 0x00, 0x20, 0x03, 0x06, 0x3F, 0xFE, 0x06, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"j",74*/
{ 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0xF8, 0x00, 0x01, 0x88, 0x00, 0x03, 0x00, 0x00, 0x2F, 0xC0, 0x00, 0x38, 0xF8, 0x00, 0x20, 0x38, 0x00, 0x20, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 }, /*"k",75*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x07, 0xFF, 0xF8, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"l",76*/
{ 0x00, 0x20, 0x08, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x10, 0x08, 0x00, 0x20, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x10, 0x08, 0x00, 0x20, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x08 }, /*"m",77*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x10, 0x08, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x08, 0x00, 0x3F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 }, /*"n",78*/
{ 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x18, 0x30, 0x00, 0x30, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x30, 0x08, 0x00, 0x18, 0x30, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00 }, /*"o",79*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x3F, 0xFF, 0x00, 0x3F, 0xFF, 0x00, 0x10, 0x11, 0x00, 0x20, 0x09, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x30, 0x38, 0x00, 0x1F, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00 }, /*"p",80*/
{ 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x38, 0x18, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x09, 0x00, 0x10, 0x11, 0x00, 0x1F, 0xFF, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }, /*"q",81*/
{ 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x08, 0x08, 0x00, 0x10, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00 }, /*"r",82*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x78, 0x00, 0x1E, 0x18, 0x00, 0x33, 0x08, 0x00, 0x23, 0x08, 0x00, 0x21, 0x08, 0x00, 0x21, 0x88, 0x00, 0x21, 0x98, 0x00, 0x30, 0xF0, 0x00, 0x38, 0x60, 0x00, 0x00, 0x00 }, /*"s",83*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xF0, 0x03, 0xFF, 0xF8, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"t",84*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x20, 0x10, 0x00, 0x3F, 0xF8, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 }, /*"u",85*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x23, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x70, 0x00, 0x23, 0x80, 0x00, 0x3C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00 }, /*"v",86*/
{ 0x00, 0x20, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x23, 0xF8, 0x00, 0x00, 0xE0, 0x00, 0x27, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x21, 0xF8, 0x00, 0x01, 0xE0, 0x00, 0x3E, 0x00, 0x00, 0x20, 0x00 }, /*"w",87*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x38, 0x38, 0x00, 0x3E, 0x68, 0x00, 0x27, 0x80, 0x00, 0x03, 0xC8, 0x00, 0x2C, 0xF8, 0x00, 0x38, 0x38, 0x00, 0x20, 0x18, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00 }, /*"x",88*/
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x03, 0x00, 0x3C, 0x01, 0x00, 0x3F, 0x83, 0x00, 0x23, 0xEC, 0x00, 0x00, 0x70, 0x00, 0x23, 0x80, 0x00, 0x3C, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00 }, /*"y",89*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x08, 0x00, 0x20, 0x38, 0x00, 0x20, 0xF8, 0x00, 0x23, 0xE8, 0x00, 0x2F, 0x88, 0x00, 0x3E, 0x08, 0x00, 0x38, 0x08, 0x00, 0x20, 0x18, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00 }, /*"z",90*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, 0x1F, 0xF7, 0xFC, 0x30, 0x00, 0x06, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"{",91*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"|",92*/
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x30, 0x00, 0x06, 0x1F, 0xF7, 0xFC, 0x00, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*"}",93*/
{ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x00, 0x00 }, /*"~",94*/
};
const unsigned char Hzk[][32] = {
{ 0x20, 0x20, 0xFF, 0x20, 0x24, 0xF4, 0x54, 0x54, 0x54, 0xFF, 0x54, 0x55, 0x56, 0xF4, 0x04, 0x00 },
{ 0x00, 0x00, 0xFF, 0x00, 0x08, 0x0B, 0x19, 0x69, 0x09, 0x0B, 0x49, 0x89, 0x7D, 0x0B, 0x08, 0x00 }, /*"博",0*/
{ 0x10, 0x60, 0x02, 0x8C, 0x00, 0x44, 0x64, 0x54, 0x4D, 0x46, 0x44, 0x54, 0x64, 0xC4, 0x04, 0x00 },
{ 0x04, 0x04, 0x7E, 0x01, 0x80, 0x40, 0x3E, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7E, 0x80, 0xE0, 0x00 }, /*"流",1*/
{ 0x10, 0x94, 0x53, 0x32, 0x1E, 0x32, 0x52, 0x10, 0x00, 0x7E, 0x42, 0x42, 0x42, 0x7E, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0xFF, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xFF, 0x00, 0x00, 0x00, 0x00 }, /*"智",2*/
{ 0x08, 0xCC, 0x4A, 0x49, 0x48, 0x4A, 0xCC, 0x18, 0x00, 0x7F, 0x88, 0x88, 0x84, 0x82, 0xE0, 0x00 },
{ 0x00, 0xFF, 0x12, 0x12, 0x52, 0x92, 0x7F, 0x00, 0x00, 0x7E, 0x88, 0x88, 0x84, 0x82, 0xE0, 0x00 }, /*"能",3*/
};
// clang-format on

View File

@@ -0,0 +1,45 @@
/**
* @file font.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __FONT_FONT_ASCII_16X8_H__
#define __FONT_FONT_ASCII_16X8_H__
#define FONT_ASCII_16X8 1
#define FONT_ASCII_32X16 0
#define FONT_ASCII_64X32 0
#if FONT_ASCII_16X8
extern const unsigned char font_ascii_16x8[];
#endif
#if FONT_ASCII_64X32
extern const unsigned char ascii_64x32[];
#endif
extern const unsigned char asc2_1206[95][12];
extern const unsigned char asc2_1608[95][16];
extern const unsigned char asc2_2412[95][36];
extern const unsigned char Hzk[][32];
extern const unsigned char c_chFont1608[95][16];
#endif

View File

@@ -0,0 +1,399 @@
/**
* @file ili9341.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "ili9341.h"
#include "mcu_lcd.h"
#include "hal_spi.h"
#include "hal_dma.h"
#include "hal_gpio.h"
static struct device *spi0;
static struct device *dma_ch3;
const ili9341_init_cmd_t ili9341_init_cmds[] = {
{ 0x11, "\x00", 0x80 }, /* Exit sleep */
{ 0xCF, "\x00\xd9\x30", 3 },
{ 0xED, "\x64\x03\x12\x81", 4 },
{ 0xE8, "\x85\x01\x78", 3 },
{ 0xCB, "\x39\x2C\x00\x34\x02", 5 },
{ 0xF7, "\x20", 1 },
{ 0xEA, "\x00\x00", 2 },
{ 0xC0, "\x23", 1 }, /*Power control*/
{ 0xC1, "\x12", 1 }, /*Power control */
{ 0xC2, "\x11", 1 },
{ 0xC5, "\x40\x30", 2 }, /*VCOM control 1*/
{ 0xC7, "\xa9", 1 }, /*VCOM control 2*/
{ 0x36, "\x08", 1 }, /*Memory Access Control*/
{ 0x3A, "\x55", 1 }, /*Pixel Format Set*/
{ 0xB1, "\x00\x18", 2 }, /* Frame Rate Control */
{ 0xB6, "\x0a\xa2", 2 }, /* Display Function Control */
{ 0x0C, "\xd5", 1 }, /* display pixel format,RGB 16bits,MCU 16bits */
{ 0xF2, "\x00", 1 }, /* 3Gamma Function Disable */
{ 0xF7, "\x20", 1 },
{ 0x26, "\x01", 1 }, /* Gamma curve selected */
{ 0xE0, "\x1F\x1A\x18\x0A\x0F\x06\x45\x87\x32\x0A\x07\x02\x07\x05\x00", 15 }, /* Set Gamma */
{ 0XE1, "\x00\x25\x27\x05\x10\x09\x3A\x78\x4D\x05\x18\x0D\x38\x3A\x1F", 15 }, /* Set Gamma */
{ 0xB7, "\x07", 1 },
{ 0x29, "\x00", 0x80 }, /* Display on */
};
/**
* @brief ili9341_spi_init
*
* @return int 0:succes 1:error
*/
static int ili9341_spi_init(void)
{
gpio_set_mode(ILI9341_CS_PIN, GPIO_OUTPUT_MODE);
gpio_set_mode(ILI9341_DC_PIN, GPIO_OUTPUT_MODE);
ILI9341_CS_HIGH;
ILI9341_DC_HIGH;
spi0 = device_find("lcd_dev_ifs");
if (spi0) {
device_close(spi0);
} else {
spi_register(SPI0_INDEX, "lcd_dev_ifs");
spi0 = device_find("lcd_dev_ifs");
}
if (spi0) {
SPI_DEV(spi0)->mode = SPI_MASTER_MODE;
SPI_DEV(spi0)->clk = (36 * 1000 * 1000);
SPI_DEV(spi0)->direction = SPI_MSB_BYTE0_DIRECTION_FIRST;
SPI_DEV(spi0)->clk_polaraity = SPI_POLARITY_LOW;
SPI_DEV(spi0)->datasize = SPI_DATASIZE_8BIT;
SPI_DEV(spi0)->clk_phase = SPI_PHASE_1EDGE;
SPI_DEV(spi0)->fifo_threshold = 4;
device_open(spi0, DEVICE_OFLAG_STREAM_TX);
} else {
return 1;
}
dma_ch3 = device_find("lcd_dev_ifs_dma");
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "lcd_dev_ifs_dma");
dma_ch3 = device_find("lcd_dev_ifs_dma");
}
if (dma_ch3) {
DMA_DEV(dma_ch3)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_SPI0_TX;
DMA_DEV(dma_ch3)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch3)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch3, 0);
device_set_callback(dma_ch3, NULL);
device_control(spi0, DEVICE_CTRL_ATTACH_TX_DMA, dma_ch3);
device_control(dma_ch3, DEVICE_CTRL_SET_INT, NULL);
} else {
return 1;
}
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
return 0;
}
/**
* @brief ili9341_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int ili9341_write_cmd(uint8_t cmd)
{
ILI9341_DC_LOW;
ILI9341_CS_LOW;
int res = spi_transmit(spi0, &cmd, 1, SPI_TRANSFER_TYPE_8BIT);
ILI9341_CS_HIGH;
return res;
}
/**
* @brief ili9341_write_data_1byte
*
* @param data
* @return int 0:succes 1:error
*/
static int ili9341_write_data_1byte(uint8_t data)
{
ILI9341_DC_HIGH;
ILI9341_CS_LOW;
int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_8BIT);
ILI9341_CS_HIGH;
return res;
}
/**
* @brief ili9341_write_data_2byte
*
* @param data
* @return int 0:succes 1:error
*/
// static int ili9341_write_data_2byte(uint16_t data)
// {
// data = ((data >> 8) & 0xFF) | data << 8;
// ILI9341_DC_HIGH;
// ILI9341_CS_LOW;
// int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_16BIT);
// ILI9341_CS_HIGH;
// return res;
// }
/**
* @brief ili9341_write_data_4byte
*
* @param data
* @return int 0:succes 1:error
*/
static int ili9341_write_data_4byte(uint32_t data)
{
data = ((data >> 24) & 0xFF) | ((data >> 8) & 0xFF00) | ((data << 8) & 0xFF0000) | ((data << 24));
ILI9341_DC_HIGH;
ILI9341_CS_LOW;
int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_32BIT);
ILI9341_CS_HIGH;
return res;
}
/**
* @brief ili9341_draw_is_busy, After the call ili9341_draw_picture_dma must check this,
* if ili9341_draw_is_busy() == 1, Don't allow other draw !!
* can run in the DMA interrupt callback function.
*
* @return int 0:draw end; 1:Being draw
*/
int ili9341_draw_is_busy(void)
{
if (dma_channel_check_busy(SPI_DEV(spi0)->tx_dma)) {
return 1;
} else {
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
ILI9341_CS_HIGH;
return 0;
}
}
/**
* @brief ili9341_init
*
* @return int
*/
int ili9341_init()
{
int res = ili9341_spi_init();
if (res) {
return res;
}
for (uint16_t i = 0; i < (sizeof(ili9341_init_cmds) / sizeof(ili9341_init_cmd_t)); i++) {
/* send register address */
res |= ili9341_write_cmd(ili9341_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (ili9341_init_cmds[i].databytes & 0x7F); j++) {
res |= ili9341_write_data_1byte(ili9341_init_cmds[i].data[j]);
}
if (res) {
return res;
}
/* delay */
if (ili9341_init_cmds[i].databytes & 0x80) {
bflb_platform_delay_ms(100);
}
}
ili9341_set_draw_window(0, 0, ILI9341_H, ILI9341_W);
return res;
}
/**
* @brief
*
* @param dir
* @param mir_flag
*/
int ili9341_set_dir(uint8_t dir, uint8_t mir_flag)
{
ili9341_write_cmd(0x36);
switch (dir) {
case 0:
if (!mir_flag)
ili9341_write_data_1byte(0x08);
else
ili9341_write_data_1byte(0x48);
break;
case 1:
if (!mir_flag)
ili9341_write_data_1byte(0xA8);
else
ili9341_write_data_1byte(0x28);
break;
case 2:
if (!mir_flag)
ili9341_write_data_1byte(0xC8);
else
ili9341_write_data_1byte(0x88);
break;
case 3:
if (!mir_flag)
ili9341_write_data_1byte(0x68);
else
ili9341_write_data_1byte(0xE8);
break;
default:
return -1;
break;
}
return dir;
}
/**
* @brief ili9341_set_draw_window
*
* @param x1
* @param y1
* @param x2
* @param y2
*/
void ili9341_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
{
#if ILI9341_OFFSET_X
x1 += ILI9341_OFFSET_X;
x2 += ILI9341_OFFSET_X;
#endif
#if ILI9341_OFFSET_Y
y1 += ILI9341_OFFSET_Y;
y2 += ILI9341_OFFSET_Y;
#endif
ili9341_write_cmd(0x2a);
ili9341_write_data_4byte(x1 << 16 | (x2 & 0xFFFF));
ili9341_write_cmd(0x2b);
ili9341_write_data_4byte(y1 << 16 | (y2 & 0xFFFF));
ili9341_write_cmd(0x2c);
}
/**
* @brief ili9341_draw_point
*
* @param x
* @param y
* @param color
*/
void ili9341_draw_point(uint16_t x, uint16_t y, uint16_t color)
{
if (lcd_auto_swap_flag) {
color = ((color >> 8) & 0xFF) | color << 8;
}
ili9341_set_draw_window(x, y, x, y);
ILI9341_DC_HIGH;
ILI9341_CS_LOW;
spi_transmit(spi0, &color, 1, SPI_TRANSFER_TYPE_16BIT);
ILI9341_CS_HIGH;
}
/**
* @brief ili9341_draw_area
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param color
*/
void ili9341_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
if (lcd_auto_swap_flag) {
color = ((color >> 8) & 0xFF) | color << 8;
}
ili9341_set_draw_window(x1, y1, x2, y2);
ILI9341_DC_HIGH;
ILI9341_CS_LOW;
for (uint16_t i = y1; i <= y2; i++) {
for (uint16_t j = x1; j <= x2; j++)
spi_transmit(spi0, &color, 1, SPI_TRANSFER_TYPE_16BIT);
}
ILI9341_CS_HIGH;
}
/**
* @brief ili9341_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (ili9341_draw_is_busy()==0)
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void ili9341_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
uint8_t ret = 0;
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
/* 数据高低位切换 */
if (lcd_auto_swap_flag) {
lcd_swap_color_data16(picture, picture, picture_size);
}
// DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_32BIT;
// DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_1BYTE;
// DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_4BYTE;
ili9341_set_draw_window(x1, y1, x2, y2);
ILI9341_DC_HIGH;
ILI9341_CS_LOW;
device_control(spi0, DEVICE_CTRL_TX_DMA_RESUME, NULL);
ret = device_write(spi0, 0, picture, picture_size * 2);
if (ret != 0) {
MSG("device write fail!\r\n");
}
}
/**
* @brief ili9341_draw_picture,BlockingUsing DMA acceleration,Waiting for the draw end
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void ili9341_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
ili9341_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (ili9341_draw_is_busy()) {
};
}

View File

@@ -0,0 +1,58 @@
/**
* @file ili9341.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _ILI9341_H_
#define _ILI9341_H_
#include "bflb_platform.h"
#define ILI9341_CS_PIN GPIO_PIN_10
#define ILI9341_DC_PIN GPIO_PIN_22
#define ILI9341_CS_HIGH gpio_write(ILI9341_CS_PIN, 1)
#define ILI9341_CS_LOW gpio_write(ILI9341_CS_PIN, 0)
#define ILI9341_DC_HIGH gpio_write(ILI9341_DC_PIN, 1)
#define ILI9341_DC_LOW gpio_write(ILI9341_DC_PIN, 0)
#define ILI9341_W 240 /* ILI9341 LCD width */
#define ILI9341_H 320 /* ILI9341 LCD height */
#define ILI9341_OFFSET_X 0
#define ILI9341_OFFSET_Y 0
typedef struct {
uint8_t cmd;
const char *data;
uint8_t databytes; /* Num of data in data; bit 7 = delay after set */
} ili9341_init_cmd_t;
int ili9341_init();
int ili9341_set_dir(uint8_t dir, uint8_t mir_flag);
void ili9341_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void ili9341_draw_point(uint16_t x, uint16_t y, uint16_t color);
void ili9341_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void ili9341_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
void ili9341_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
int ili9341_draw_is_busy(void);
#endif

View File

@@ -0,0 +1,407 @@
/**
* @file mcu_lcd.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "mcu_lcd.h"
#include "font.h"
#include "bflb_platform.h"
#include "drv_device.h"
struct device *lcd_dev_ifs = NULL;
uint8_t lcd_dir = 0;
uint8_t lcd_auto_swap_flag = 1;
uint16_t lcd_max_x = LCD_W, lcd_max_y = LCD_H;
/**
* @brief 设置是否需要自动交换 像素数据大小端, 默认需要的屏幕会开启
*
* @param flag 0:off 1:on
* @return int
*/
int lcd_auto_swap_set(uint8_t flag)
{
lcd_auto_swap_flag = flag ? 1 : 0;
return lcd_auto_swap_flag;
}
/**
* @brief 批量交换 像素数据大小端,在 lcd_auto_swap_flag == 1 时,绘制时自动调用
*
* @param dst destination
* @param src source
* @param color_num color num
* @return int
*/
int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
{
for (size_t i = 0; i < color_num; i++) {
dst[i] = (src[i] << 8) | (src[i] >> 8);
}
return 0;
}
/**
* @brief LCD init
*
* @return int
*/
int lcd_init(void)
{
int res;
#if defined(MCU_LCD_ILI9341)
res = ili9341_init();
#elif defined(MCU_LCD_ST7735S)
res = st7735s_init();
#elif defined(MCU_LCD_ST7789V)
res = st7789v_init();
#endif
lcd_dev_ifs = device_find("lcd_dev_ifs");
return res;
}
/**
* @brief Set display direction and mir
*
* @param dir 0~3 : 0~270 Angle
* @param mir_flag 0:normal 1:Horizontal Mirroring(if support)
* @return int
*/
int lcd_set_dir(uint8_t dir, uint8_t mir_flag)
{
dir %= 4;
lcd_dir = dir;
if (dir == 0 || dir == 2) {
lcd_max_x = LCD_W;
lcd_max_y = LCD_H;
} else {
lcd_max_x = LCD_H;
lcd_max_y = LCD_W;
}
#if defined(MCU_LCD_ILI9341)
ili9341_set_dir(dir, mir_flag);
return 0;
#elif defined(MCU_LCD_ST7735S)
st7735s_set_dir(dir);
return 0;
#elif defined(MCU_LCD_ST7789V)
st7789v_set_dir(dir);
return 0;
#endif
}
/**
* @brief Draws a point at the specified position
*
* @param x X coordinate
* @param y Y coordinate
* @param color
* @return int
*/
int lcd_draw_point(uint16_t x, uint16_t y, lcd_color_t color)
{
#if defined(MCU_LCD_ILI9341)
ili9341_draw_point(x, y, color);
return 0;
#elif defined(MCU_LCD_ST7735S)
st7735s_draw_point(x, y, color);
return 0;
#elif defined(MCU_LCD_ST7789V)
st7789v_draw_point(x, y, color);
return 0;
#endif
}
/**
* @brief Draw a monochrome rectangle (May be less efficient)
*
* @param x1 start coordinate
* @param y1 start coordinate
* @param x2 end coordinate
* @param y2 end coordinate
* @param color
* @return int
*/
int lcd_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t color)
{
#if defined(MCU_LCD_ILI9341)
ili9341_draw_area(x1, y1, x2, y2, color);
return 0;
#elif defined(MCU_LCD_ST7735S)
st7735s_draw_area(x1, y1, x2, y2, color);
return 0;
#elif defined(MCU_LCD_ST7789V)
st7789v_draw_area(x1, y1, x2, y2, color);
return 0;
#endif
}
/**
* @brief Draw a picture in the designated area(blocking),Will wait for the drawing to finish
*
* @param x1 start coordinate
* @param y1 start coordinate
* @param x2 end coordinate
* @param y2 end coordinate
* @param picture
* @return int
*/
int lcd_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t *picture)
{
#if defined(MCU_LCD_ILI9341)
ili9341_draw_picture_blocking(x1, y1, x2, y2, picture);
return 0;
#elif defined(MCU_LCD_ST7735S)
st7735s_draw_picture_blocking(x1, y1, x2, y2, picture);
return 0;
#elif defined(MCU_LCD_ST7789V)
st7789v_draw_picture_blocking(x1, y1, x2, y2, picture);
return 0;
#endif
}
/**
* @brief Draw a picture in the designated area(nonblocking,if it supports),
* Must be calle lcd_draw_is_busy! and (lcd_draw_is_busyd()==1) before performing other drawing and changing picture data!
*
* @param x1 start coordinate
* @param y1 start coordinate
* @param x2 end coordinate
* @param y2 end coordinate
* @param picture
* @return int
*/
int lcd_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t *picture)
{
#if defined(MCU_LCD_ILI9341)
ili9341_draw_picture_nonblocking(x1, y1, x2, y2, picture);
return 0;
#elif defined(MCU_LCD_ST7735S)
st7735s_draw_picture_nonblocking(x1, y1, x2, y2, picture);
return 0;
#elif defined(MCU_LCD_ST7789V)
st7789v_draw_picture_nonblocking(x1, y1, x2, y2, picture);
return 0;
#endif
}
/**
* @brief Check if it is drawing, must call it After call lcd_draw_picture_nonblocking
*
* @return int 1:lcd Drawing,Prohibit other operations! 0:Drawing is over
*/
int lcd_draw_is_busy(void)
{
#if defined(MCU_LCD_ILI9341)
return ili9341_draw_is_busy();
#elif defined(MCU_LCD_ST7735S)
return st7735s_draw_is_busy();
#elif defined(MCU_LCD_ST7789V)
return st7789v_draw_is_busy();
#endif
}
/**
* @brief clear lcd
*
* @param color
* @return int
*/
int lcd_clear(uint16_t color)
{
if (lcd_dir == 0 || lcd_dir == 2) {
lcd_draw_area(0, 0, LCD_W, LCD_H, color);
} else {
lcd_draw_area(0, 0, LCD_H, LCD_W, color);
}
return 0;
}
/**
* @brief
*
* @param x1 start coordinate
* @param y1 start coordinate
* @param x2 end coordinate
* @param y2 end coordinate
* @param color
* @return int
*/
int lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t color)
{
int xVariation, yVariation, temp;
int absX, absY, i;
xVariation = x2 - x1;
yVariation = y2 - y1;
absX = ABS(xVariation);
absY = ABS(yVariation);
if (absX > absY) {
for (i = 0; i < absX + 1; i++) {
temp = yVariation * 100 / absX * i / 100;
if (xVariation > 0) {
lcd_draw_point(x1 + i, y1 + temp, color);
} else {
lcd_draw_point(x1 - i, y1 + temp, color);
}
}
} else {
for (i = 0; i < absY + 1; i++) {
temp = xVariation * 100 / absY * i / 100;
if (yVariation > 0) {
lcd_draw_point(x1 + temp, y1 + i, color);
} else {
lcd_draw_point(x1 + temp, y1 - i, color);
}
}
}
return 0;
}
/**
* @brief
*
* @param x1 start coordinate
* @param y1 start coordinate
* @param x2 end coordinate
* @param y2 end coordinate
* @param color
* @return int
*/
int lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t color)
{
lcd_draw_line(x1, y1, x2, y1, color);
lcd_draw_line(x2, y1, x2, y2, color);
lcd_draw_line(x2, y2, x1, y2, color);
lcd_draw_line(x1, y2, x1, y1, color);
return 0;
}
/**
* @brief draw a circle
*
* @param x coordinate
* @param y coordinate
* @param r
* @param color
* @return int
*/
int lcd_draw_circle(uint16_t x, uint16_t y, uint16_t r, lcd_color_t color)
{
int a = 0, b;
int di;
b = r;
di = 3 - (r << 1);
while (a <= b) {
lcd_draw_point(x - b, y - a, color);
lcd_draw_point(x + b, y - a, color);
lcd_draw_point(x - a, y + b, color);
lcd_draw_point(x - b, y - a, color);
lcd_draw_point(x - a, y - b, color);
lcd_draw_point(x + b, y + a, color);
lcd_draw_point(x + a, y - b, color);
lcd_draw_point(x + a, y + b, color);
lcd_draw_point(x - b, y + a, color);
a++;
if (di < 0) {
di += 4 * a + 6;
} else {
di += 10 + 4 * (a - b);
b--;
}
lcd_draw_point(x + a, y + b, color);
}
return 0;
}
#if FONT_ASCII_16X8
/**
* @brief Draw font(16*8) ,Use double buffer to speed up drawing
*
* @param x start coordinate
* @param y start coordinate
* @param color font color
* @param bk_color Background color
* @param str The string to be displayed
* @param num number of characters displayed
* @return int
*/
int lcd_draw_str_ascii16(uint16_t x, uint16_t y, lcd_color_t color, lcd_color_t bk_color, uint8_t *str, uint8_t num)
{
lcd_color_t draw_buff[2][16 * 8];
uint16_t buff_color_num;
uint8_t buff_using_num = 0;
uint8_t ch, temp;
uint16_t x0 = x;
for (uint16_t i = 0; i < num && str[i]; i++) {
if (str[i] < 128) {
if (x > LCD_W - 8) {
x = x0;
y += 16;
}
if (x > LCD_W - 8 || y > LCD_H - 16)
break;
ch = str[i];
if (ch >= ' ') {
ch = ch - ' ';
} else if (ch == '\n') {
x = x0;
y += 16;
continue;
} else {
continue;
}
buff_color_num = 0;
for (uint8_t j = 0; j < 16; j++) {
temp = font_ascii_16x8[ch * 16 + j];
for (uint8_t k = 0; k < 8; k++) {
if (temp & (0x80 >> k))
draw_buff[buff_using_num][buff_color_num++] = color;
else
draw_buff[buff_using_num][buff_color_num++] = bk_color;
}
}
while (lcd_draw_is_busy()) {
};
lcd_draw_picture_nonblocking(x, y, x + 7, y + 15, draw_buff[buff_using_num]);
buff_using_num = !buff_using_num;
x += 8;
} else {
continue;
}
}
while (lcd_draw_is_busy()) {
};
return 0;
}
#endif

View File

@@ -0,0 +1,80 @@
/**
* @file mcu_lcd.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _MCU_LCD_H_
#define _MCU_LCD_H_
#include "font.h"
#define MCU_LCD_ILI9341
// #define MCU_LCD_ST7735S /* 未验证 */
// #define MCU_LCD_ST7789V
extern struct device *lcd_dev_ifs;
#if defined MCU_LCD_ILI9341
#include "ili9341.h"
#define LCD_W ILI9341_W
#define LCD_H ILI9341_H
typedef uint16_t lcd_color_t;
#elif defined MCU_LCD_ST7735S
#include "st7735s.h"
#define LCD_W ST7735S_W
#define LCD_H ST7735S_H
typedef uint16_t lcd_color_t;
#elif defined MCU_LCD_ST7789V
#include "st7789v.h"
#define LCD_W ST7789V_W
#define LCD_H ST7789V_H
typedef uint16_t lcd_color_t;
#endif
#define ABS(x) ((x) > 0 ? (x) : -(x))
extern struct device *lcd_dev_ifs;
extern uint8_t lcd_auto_swap_flag;
int lcd_auto_swap_set(uint8_t flag);
int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t num);
int lcd_init(void);
int lcd_set_dir(uint8_t dir, uint8_t mir_flag);
int lcd_get_dir();
int lcd_draw_point(uint16_t x, uint16_t y, lcd_color_t color);
int lcd_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t color);
int lcd_clear(uint16_t color);
int lcd_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t *picture);
int lcd_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t *picture);
int lcd_draw_is_busy(void);
int lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t color);
int lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, lcd_color_t color);
int lcd_draw_circle(uint16_t x, uint16_t y, uint16_t r, lcd_color_t color);
#if FONT_ASCII_16X8
int lcd_draw_str_ascii16(uint16_t x, uint16_t y, lcd_color_t color, lcd_color_t bk_color, uint8_t *str, uint8_t num);
#endif
#endif

View File

@@ -0,0 +1,389 @@
#include "ssd1306.h"
#include "hal_i2c.h"
#include "hal_spi.h"
#include "hal_gpio.h"
#include "font.h"
#include "bflb_platform.h"
#define SSD1306_USING_I2C 0
#define SSD1306_USING_SPI 1
#define INTERFACE_SELECT SSD1306_USING_SPI
static uint8_t OLED_GRAM[128][8];
struct device *ssd_1306;
static void ssd1306_write_byte(uint8_t data, uint8_t cmd)
{
#if INTERFACE_SELECT == SSD1306_USING_I2C
i2c_msg_t msg;
if (cmd) {
msg.subaddr = 0x40;
} else {
msg.subaddr = 0x00;
}
msg.buf = &data;
msg.flags = SUB_ADDR_1BYTE | I2C_WR;
msg.len = 1;
msg.slaveaddr = 0x3c;
i2c_transfer(ssd_1306, &msg, 1);
#else
if (cmd) {
CS1_LOW;
DC_HIGH;
} else {
CS1_LOW;
DC_LOW;
}
spi_transmit(ssd_1306, &data, 1, SPI_TRANSFER_TYPE_8BIT);
CS1_HIGH;
DC_HIGH;
#endif
}
void ssd1306_init(void)
{
#if INTERFACE_SELECT == SSD1306_USING_I2C
i2c_register(I2C0_INDEX, "lcd_dev_ifs");
ssd_1306 = device_find("lcd_dev_ifs");
if (ssd_1306) {
device_open(ssd_1306, 0);
}
ssd1306_write_byte(0xAE, SSD1306_CMD); //--turn off oled panel
ssd1306_write_byte(0x00, SSD1306_CMD); //---set low column address
ssd1306_write_byte(0x10, SSD1306_CMD); //---set high column address
ssd1306_write_byte(0x40, SSD1306_CMD); //--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
ssd1306_write_byte(0x81, SSD1306_CMD); //--set contrast control register
ssd1306_write_byte(0xCF, SSD1306_CMD); // Set SEG Output Current Brightness
ssd1306_write_byte(0xA1, SSD1306_CMD); //--Set SEG/Column Mapping
ssd1306_write_byte(0xC0, SSD1306_CMD); //Set COM/Row Scan Direction
ssd1306_write_byte(0xA6, SSD1306_CMD); //--set normal display
ssd1306_write_byte(0xA8, SSD1306_CMD); //--set multiplex ratio(1 to 64)
ssd1306_write_byte(0x3f, SSD1306_CMD); //--1/64 duty
ssd1306_write_byte(0xD3, SSD1306_CMD); //-set display offset Shift Mapping RAM Counter (0x00~0x3F)
ssd1306_write_byte(0x00, SSD1306_CMD); //-not offset
ssd1306_write_byte(0xd5, SSD1306_CMD); //--set display clock divide ratio/oscillator frequency
ssd1306_write_byte(0x80, SSD1306_CMD); //--set divide ratio, Set Clock as 100 Frames/Sec
ssd1306_write_byte(0xD9, SSD1306_CMD); //--set pre-charge period
ssd1306_write_byte(0xF1, SSD1306_CMD); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
ssd1306_write_byte(0xDA, SSD1306_CMD); //--set com pins hardware configuration
ssd1306_write_byte(0x12, SSD1306_CMD);
ssd1306_write_byte(0xDB, SSD1306_CMD); //--set vcomh
ssd1306_write_byte(0x40, SSD1306_CMD); //Set VCOM Deselect Level
ssd1306_write_byte(0x20, SSD1306_CMD); //-Set Page Addressing Mode (0x00/0x01/0x02)
ssd1306_write_byte(0x02, SSD1306_CMD); //
ssd1306_write_byte(0x8D, SSD1306_CMD); //--set Charge Pump enable/disable
ssd1306_write_byte(0x14, SSD1306_CMD); //--set(0x10) disable
ssd1306_write_byte(0xA4, SSD1306_CMD); // Disable Entire Display On (0xa4/0xa5)
ssd1306_write_byte(0xA6, SSD1306_CMD); // Disable Inverse Display On (0xa6/a7)
ssd1306_write_byte(0xAF, SSD1306_CMD); //--turn on oled panel
ssd1306_display_on();
ssd1306_clear_screen(0xff);
#else
gpio_set_mode(OLED_CS_PIN, GPIO_OUTPUT_MODE);
gpio_set_mode(OLED_DC_PIN, GPIO_OUTPUT_MODE);
gpio_set_mode(OLED_RES_PIN, GPIO_OUTPUT_MODE);
gpio_write(OLED_CS_PIN, 1); //CS1
gpio_write(OLED_DC_PIN, 1); //DC
spi_register(SPI0_INDEX, "lcd_dev_ifs");
ssd_1306 = device_find("lcd_dev_ifs");
if (ssd_1306) {
device_open(ssd_1306, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
}
CS1_HIGH;
DC_HIGH;
RES_LOW;
bflb_platform_delay_ms(100);
RES_HIGH;
ssd1306_write_byte(0xAE, SSD1306_CMD);
ssd1306_write_byte(0xD5, SSD1306_CMD);
ssd1306_write_byte(0x50, SSD1306_CMD);
ssd1306_write_byte(0xA8, SSD1306_CMD);
ssd1306_write_byte(0x3F, SSD1306_CMD);
ssd1306_write_byte(0xD3, SSD1306_CMD);
ssd1306_write_byte(0x00, SSD1306_CMD);
ssd1306_write_byte(0x40, SSD1306_CMD);
ssd1306_write_byte(0x8D, SSD1306_CMD);
ssd1306_write_byte(0x14, SSD1306_CMD);
ssd1306_write_byte(0x20, SSD1306_CMD);
ssd1306_write_byte(0x02, SSD1306_CMD);
ssd1306_write_byte(0xA1, SSD1306_CMD);
ssd1306_write_byte(0xC0, SSD1306_CMD);
ssd1306_write_byte(0xDA, SSD1306_CMD);
ssd1306_write_byte(0x12, SSD1306_CMD);
ssd1306_write_byte(0x81, SSD1306_CMD);
ssd1306_write_byte(0xEF, SSD1306_CMD);
ssd1306_write_byte(0xD9, SSD1306_CMD);
ssd1306_write_byte(0xF1, SSD1306_CMD);
ssd1306_write_byte(0xDB, SSD1306_CMD);
ssd1306_write_byte(0x30, SSD1306_CMD);
ssd1306_write_byte(0xA4, SSD1306_CMD);
ssd1306_write_byte(0xA6, SSD1306_CMD);
ssd1306_write_byte(0xAF, SSD1306_CMD);
ssd1306_clear_screen(0);
#endif
}
void ssd1306_display_on(void)
{
ssd1306_write_byte(0x8D, SSD1306_CMD);
ssd1306_write_byte(0x14, SSD1306_CMD);
ssd1306_write_byte(0xAF, SSD1306_CMD);
}
/**
* @brief OLED turns off
*
* @param None
*
* @retval None
**/
void ssd1306_display_off(void)
{
ssd1306_write_byte(0x8D, SSD1306_CMD);
ssd1306_write_byte(0x10, SSD1306_CMD);
ssd1306_write_byte(0xAE, SSD1306_CMD);
}
void ssd1306_refresh_gram(void)
{
uint8_t i, j;
for (i = 0; i < 8; i++) {
ssd1306_write_byte(0xB0 + i, SSD1306_CMD);
ssd1306_write_byte(0x00, SSD1306_CMD);
ssd1306_write_byte(0x10, SSD1306_CMD);
for (j = 0; j < 128; j++) {
ssd1306_write_byte(OLED_GRAM[j][i], SSD1306_DAT);
}
}
}
void ssd1306_clear_screen(uint8_t fill)
{
memset(OLED_GRAM, fill, sizeof(OLED_GRAM));
ssd1306_refresh_gram();
}
/**
* @brief Draws a piont on the screen
*
* @param x: Specifies the X position
* @param y: Specifies the Y position
* @param mode: 0: the point turns off 1: the piont turns on
*
* @retval None
**/
void ssd1306_draw_point(uint8_t x, uint8_t y, uint8_t mode)
{
uint8_t i, j, temp;
if (x > 127 || y > 63)
return;
i = 7 - y / 8;
j = y % 8;
temp = 0x01 << (7 - j);
if (mode == 0)
OLED_GRAM[x][i] &= ~temp;
else
OLED_GRAM[x][i] |= temp;
}
/**
* @brief Displays one character at the specified position
*
* @param x: Specifies the X position
* @param y: Specifies the Y position
* @param size:
* @param mode
* @retval
**/
void ssd1306_display_char(uint8_t x, uint8_t y, uint8_t chr, uint8_t size, uint8_t mode)
{
uint8_t temp, t, t1;
uint8_t y0 = y;
uint8_t csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
chr = chr - ' ';
for (t = 0; t < csize; t++) {
switch (size) {
case 12:
temp = asc2_1206[chr][t];
break;
case 16:
temp = asc2_1608[chr][t];
break;
case 24:
temp = asc2_2412[chr][t];
break;
default:
return;
}
for (t1 = 0; t1 < 8; t1++) {
if (temp & 0x80)
ssd1306_draw_point(x, y, mode);
else
ssd1306_draw_point(x, y, !mode);
temp <<= 1;
y++;
if ((y - y0) == size) {
y = y0;
x++;
break;
}
}
}
}
/**
* @brief Displays a string on the screen
*
* @param x: Specifies the X position
* @param y: Specifies the Y position
* @param string: Pointer to a string to display on the screen
*
* @retval None
**/
void ssd1306_display_string(uint8_t x, uint8_t y, const char *string, uint8_t size, uint8_t mode)
{
while (*string != '\0') {
if (x > (SSD1306_WIDTH - size / 2)) {
x = 0;
y += size;
if (y > (SSD1306_HEIGHT - size)) {
y = x = 0;
ssd1306_clear_screen(0x00);
}
}
ssd1306_display_char(x, y, *string, size, mode);
x += size / 2;
string++;
}
}
void ssd1306_display_chinese(uint8_t x, uint8_t y, uint8_t no, uint8_t mode)
{
uint8_t temp1;
uint8_t temp2;
uint8_t t1, t2;
uint8_t x0 = x, y0 = y;
for (t1 = 0; t1 < 16; t1++) {
temp1 = Hzk[2 * no][t1];
for (t2 = 0; t2 < 8; t2++) {
if (temp1 & 0x01)
ssd1306_draw_point(x, y, mode);
else
ssd1306_draw_point(x, y, !mode);
temp1 >>= 1;
y++;
}
y = y0;
x++;
}
x = x0;
y = y0 + 8;
y0 = y;
for (t1 = 0; t1 < 16; t1++) {
temp2 = Hzk[2 * no + 1][t1];
for (t2 = 0; t2 < 8; t2++) {
if (temp2 & 0x01)
ssd1306_draw_point(x, y, mode);
else
ssd1306_draw_point(x, y, !mode);
temp2 >>= 1;
y++;
}
y = y0;
x++;
}
}
void ssd1306_draw_bmp(uint8_t x, uint8_t y, const unsigned char *image, uint8_t index, uint8_t mode)
{
uint8_t temp, t1;
uint16_t i;
uint8_t y0 = y;
for (i = 0; i < 1024; i++) {
temp = image[1024 * index + i];
for (t1 = 0; t1 < 8; t1++) {
if (temp & 0x80)
ssd1306_draw_point(x, y, mode);
else
ssd1306_draw_point(x, y, !mode);
temp <<= 1;
y++;
if ((y - y0) == 64) {
y = y0;
x++;
break;
}
}
}
}
void ssd1306_draw_alpha(uint8_t x, uint8_t y, const unsigned char *image, uint8_t index, uint8_t mode)
{
uint8_t temp, t1;
uint16_t i;
uint8_t y0 = y;
for (i = 0; i < 1024; i++) {
temp = image[1024 * index + i];
for (t1 = 0; t1 < 8; t1++) {
if (temp & 0x80)
ssd1306_draw_point(x, y, mode);
temp <<= 1;
y++;
if ((y - y0) == 64) {
y = y0;
x++;
break;
}
}
}
}
/**
* @brief Fills a rectangle
*
* @param x1: Specifies the X position 1 (X top left position)
* @param y1: Specifies the Y position 1 (Y top left position)
* @param x2: Specifies the X position 2 (X bottom right position)
* @param y3: Specifies the Y position 2 (Y bottom right position)
*
* @retval
**/
void ssd1306_fill_screen(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t chDot)
{
uint8_t x, y;
for (x = x1; x <= x2; x++) {
for (y = y1; y <= y2; y++) {
ssd1306_draw_point(x, y, chDot);
}
}
ssd1306_refresh_gram();
}

View File

@@ -0,0 +1,34 @@
#ifndef _SSD1306_H_
#define _SSD1306_H_
#include "stdint.h"
#define SSD1306_CMD 0
#define SSD1306_DAT 1
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
#define OLED_CS_PIN GPIO_PIN_10
#define OLED_DC_PIN GPIO_PIN_22
#define OLED_RES_PIN GPIO_PIN_11
#define CS1_HIGH gpio_write(OLED_CS_PIN, 1)
#define CS1_LOW gpio_write(OLED_CS_PIN, 0)
#define DC_HIGH gpio_write(OLED_DC_PIN, 1)
#define DC_LOW gpio_write(OLED_DC_PIN, 0)
#define RES_HIGH gpio_write(OLED_RES_PIN, 1)
#define RES_LOW gpio_write(OLED_RES_PIN, 0)
void ssd1306_init(void);
void ssd1306_display_on(void);
void ssd1306_display_off(void);
void ssd1306_refresh_gram(void);
void ssd1306_clear_screen(uint8_t fill);
void ssd1306_draw_point(uint8_t x, uint8_t y, uint8_t mode);
void ssd1306_display_char(uint8_t x, uint8_t y, uint8_t chr, uint8_t size, uint8_t mode);
void ssd1306_display_string(uint8_t x, uint8_t y, const char *string, uint8_t size, uint8_t mode);
void ssd1306_display_chinese(uint8_t x, uint8_t y, uint8_t no, uint8_t mode);
void ssd1306_draw_bmp(uint8_t x, uint8_t y, const unsigned char *image, uint8_t index, uint8_t mode);
void ssd1306_draw_alpha(uint8_t x, uint8_t y, const unsigned char *image, uint8_t index, uint8_t mode);
#endif

View File

@@ -0,0 +1,368 @@
/**
* @file st7735s.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#include "st7735s.h"
#include "mcu_lcd.h"
#include "hal_spi.h"
#include "hal_dma.h"
#include "hal_gpio.h"
static struct device *spi0;
static struct device *dma_ch3;
const st7735s_init_cmd_t st7735s_init_cmds[] = {
{ 0x01, NULL, 0x80 }, /* Software reset */
{ 0x11, NULL, 0x80 }, /* Exit sleep */
{ 0xB1, "\x01\x2C\x2D", 3 }, /* Frame rate ctrl - normal mode, Rate = fosc/(1x2+40) * (LINE+2C+2D) */
{ 0xB2, "\x01\x2C\x2D", 3 }, /* Frame rate control - idle mode, Rate = fosc/(1x2+40) * (LINE+2C+2D) */
{ 0xB3, "\x01\x2C\x2D\x01\x2C\x2D", 6 }, /* Frame rate ctrl - partial mode, Dot inversion mode. Line inversion mode */
{ 0xB4, "\x07", 1 }, /* Display inversion ctrl, No inversion */
{ 0xC0, "\xa2\x02\x84", 3 }, /* Power control, -4.6V AUTO mode */
{ 0xC1, "\xc5", 1 }, /* Power control, VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
{ 0xC2, "\x0a\x00", 2 }, /* Power control, Opamp current small, Boost frequency */
{ 0xC3, "\x8a\x2a", 2 }, /* Power control, BCLK/2, Opamp current small & Medium low */
{ 0xC4, "\x8a\xee", 2 }, /* Power control */
{ 0xC5, "\x0e", 1 }, /* Power control */
{ 0x20, "\x00", 1 }, /* set non-inverted mode, 16-bit color */
//{ 0x21, "\x00", 1 }, /* set inverted mode */
{ 0x3A, "\x05", 1 }, /* set color mode */
{ 0x36, "\xC0", 1 }, /* set MX, MY, RGB mode */
{ 0xE0, "\x02\x1c\x07\x12\x37\x32\x29\x2d\x29\x25\x2B\x39\x00\x01\x03\x10", 16 }, /* set Gamma Sequence */
{ 0xE1, "\x03\x1d\x07\x06\x2E\x2C\x29\x2D\x2E\x2E\x37\x3F\x00\x00\x02\x10", 16 }, /* set Gamma Sequence */
{ 0x13, NULL, 0x80 }, /* Normal display on */
{ 0x20, NULL, 0x80 }, /* Display on */
};
/**
* @brief st7735s_spi_init
*
* @return int 0:succes 1:error
*/
static int st7735s_spi_init(void)
{
gpio_set_mode(ST7735S_CS_PIN, GPIO_OUTPUT_MODE);
gpio_set_mode(ST7735S_DC_PIN, GPIO_OUTPUT_MODE);
ST7735S_CS_HIGH;
ST7735S_DC_HIGH;
spi0 = device_find("lcd_dev_ifs");
if (spi0) {
device_close(spi0);
} else {
spi_register(SPI0_INDEX, "lcd_dev_ifs");
spi0 = device_find("lcd_dev_ifs");
}
if (spi0) {
SPI_DEV(spi0)->mode = SPI_MASTER_MODE;
SPI_DEV(spi0)->clk = (36 * 1000 * 1000);
SPI_DEV(spi0)->direction = SPI_MSB_BYTE0_DIRECTION_FIRST;
SPI_DEV(spi0)->clk_polaraity = SPI_POLARITY_LOW;
SPI_DEV(spi0)->datasize = SPI_DATASIZE_8BIT;
SPI_DEV(spi0)->clk_phase = SPI_PHASE_1EDGE;
SPI_DEV(spi0)->fifo_threshold = 0;
device_open(spi0, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
} else {
return 1;
}
dma_ch3 = device_find("lcd_dev_ifs_dma");
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "lcd_dev_ifs_dma");
dma_ch3 = device_find("lcd_dev_ifs_dma");
}
if (dma_ch3) {
DMA_DEV(dma_ch3)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_SPI0_TX;
DMA_DEV(dma_ch3)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch3)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch3, 0);
device_set_callback(dma_ch3, NULL);
device_control(spi0, DEVICE_CTRL_ATTACH_TX_DMA, dma_ch3);
device_control(dma_ch3, DEVICE_CTRL_CLR_INT, NULL);
} else {
return 1;
}
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
return 0;
}
/**
* @brief st7735s_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int st7735s_write_cmd(uint8_t cmd)
{
ST7735S_DC_LOW;
ST7735S_CS_LOW;
int res = spi_transmit(spi0, &cmd, 1, SPI_TRANSFER_TYPE_8BIT);
ST7735S_CS_HIGH;
return res;
}
/**
* @brief st7735s_write_data_1byte
*
* @param data
* @return int 0:succes 1:error
*/
static int st7735s_write_data_1byte(uint8_t data)
{
ST7735S_DC_HIGH;
ST7735S_CS_LOW;
int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_8BIT);
ST7735S_CS_HIGH;
return res;
}
/**
* @brief st7735s_write_data_2byte
*
* @param data
* @return int 0:succes 1:error
*/
// static int st7735s_write_data_2byte(uint16_t data)
// {
// data = ((data >> 8) & 0xFF) | data << 8;
// ST7735S_DC_HIGH;
// ST7735S_CS_LOW;
// int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_16BIT);
// ST7735S_CS_HIGH;
// return res;
// }
/**
* @brief st7735s_write_data_4byte
*
* @param data
* @return int 0:succes 1:error
*/
static int st7735s_write_data_4byte(uint32_t data)
{
data = ((data >> 24) & 0xFF) | ((data >> 8) & 0xFF00) | ((data << 8) & 0xFF0000) | ((data << 24));
ST7735S_DC_HIGH;
ST7735S_CS_LOW;
int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_32BIT);
ST7735S_CS_HIGH;
return res;
}
/**
* @brief st7735s_draw_is_busy, After the call st7735s_draw_picture_dma must check this,
* if st7735s_draw_is_busy() == 1, Don't allow other draw !!
* can run in the DMA interrupt callback function.
*
* @return int 0:draw end; 1:Being draw
*/
int st7735s_draw_is_busy(void)
{
if (dma_channel_check_busy(SPI_DEV(spi0)->tx_dma)) {
return 1;
} else {
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
ST7735S_CS_HIGH;
return 0;
}
}
/**
* @brief st7735s_init
*
* @return int
*/
int st7735s_init()
{
int res = st7735s_spi_init();
if (res) {
return res;
}
for (uint16_t i = 0; i < (sizeof(st7735s_init_cmds) / sizeof(st7735s_init_cmd_t)); i++) {
/* send register address */
res |= st7735s_write_cmd(st7735s_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (st7735s_init_cmds[i].databytes & 0x7F); j++) {
res |= st7735s_write_data_1byte(st7735s_init_cmds[i].data[j]);
}
if (res) {
return res;
}
/* delay */
if (st7735s_init_cmds[i].databytes & 0x80) {
bflb_platform_delay_ms(100);
}
}
st7735s_set_draw_window(0, 0, ST7735S_W, ST7735S_H);
return res;
}
/**
* @brief st7735s_set_dir
*
* @param dir
*/
void st7735s_set_dir(uint8_t dir)
{
st7735s_write_cmd(0x36);
switch (dir) {
case 0:
st7735s_write_data_1byte(0x08);
break;
case 1:
st7735s_write_data_1byte(0xA8);
break;
case 2:
st7735s_write_data_1byte(0xC8);
break;
case 3:
st7735s_write_data_1byte(0x68);
break;
default:
break;
}
}
void st7735s_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
{
#if ST7735S_OFFSET_X
x1 += ST7735S_OFFSET_X;
x2 += ST7735S_OFFSET_X;
#endif
#if ST7735S_OFFSET_Y
y1 += ST7735S_OFFSET_Y;
y2 += ST7735S_OFFSET_Y;
#endif
st7735s_write_cmd(0x2a);
st7735s_write_data_4byte(x1 << 16 | (x2 & 0xFFFF));
st7735s_write_cmd(0x2b);
st7735s_write_data_4byte(y1 << 16 | (y2 & 0xFFFF));
st7735s_write_cmd(0x2c);
}
/**
* @brief st7735s_draw_point
*
* @param x
* @param y
* @param color
*/
void st7735s_draw_point(uint16_t x, uint16_t y, uint16_t color)
{
if (lcd_auto_swap_flag) {
color = ((color >> 8) & 0xFF) | color << 8;
}
st7735s_set_draw_window(x, y, x, y);
ST7735S_DC_HIGH;
ST7735S_CS_LOW;
spi_transmit(spi0, &color, 1, SPI_TRANSFER_TYPE_16BIT);
ST7735S_CS_HIGH;
}
/**
* @brief st7735s_draw_area
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param color
*/
void st7735s_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
if (lcd_auto_swap_flag) {
color = ((color >> 8) & 0xFF) | color << 8;
}
st7735s_set_draw_window(x1, y1, x2, y2);
ST7735S_DC_HIGH;
ST7735S_CS_LOW;
for (uint16_t i = y1; i <= y2; i++) {
for (uint16_t j = x1; j <= x2; j++)
spi_transmit(spi0, &color, 1, SPI_TRANSFER_TYPE_16BIT);
}
ST7735S_CS_HIGH;
}
/**
* @brief st7735s_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (st7735s_draw_is_busy()==0)
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void st7735s_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
/* 数据高低位切换 */
if (lcd_auto_swap_flag) {
lcd_swap_color_data16(picture, picture, picture_size);
}
st7735s_set_draw_window(x1, y1, x2, y2);
ST7735S_DC_HIGH;
ST7735S_CS_LOW;
device_control(spi0, DEVICE_CTRL_TX_DMA_RESUME, NULL);
device_write(spi0, 0, picture, picture_size * 2);
}
/**
* @brief st7735s_draw_picture,BlockingUsing DMA acceleration,Waiting for the draw end
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void st7735s_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
st7735s_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (st7735s_draw_is_busy()) {
BL_DRV_DUMMY;
};
}

View File

@@ -0,0 +1,58 @@
/**
* @file st7735s.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _ST7735S_H_
#define _ST7735S_H_
#include "bflb_platform.h"
#define ST7735S_CS_PIN GPIO_PIN_10
#define ST7735S_DC_PIN GPIO_PIN_22
#define ST7735S_CS_HIGH gpio_write(ST7735S_CS_PIN, 1)
#define ST7735S_CS_LOW gpio_write(ST7735S_CS_PIN, 0)
#define ST7735S_DC_HIGH gpio_write(ST7735S_DC_PIN, 1)
#define ST7735S_DC_LOW gpio_write(ST7735S_DC_PIN, 0)
#define ST7735S_W 128 /* ST7735S LCD width */
#define ST7735S_H 160 /* ST7735S LCD height */
#define ST7735S_OFFSET_X 0
#define ST7735S_OFFSET_Y 0
typedef struct {
uint8_t cmd;
const char *data;
uint8_t databytes; /* Num of data in data; bit 7 = delay after set */
} st7735s_init_cmd_t;
int st7735s_init();
void st7735s_set_dir(uint8_t dir);
void st7735s_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void st7735s_draw_point(uint16_t x, uint16_t y, uint16_t color);
void st7735s_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void st7735s_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
void st7735s_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
int st7735s_draw_is_busy(void);
#endif

View File

@@ -0,0 +1,370 @@
/**
* @file st7789v.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#include "st7789v.h"
#include "mcu_lcd.h"
#include "hal_spi.h"
#include "hal_dma.h"
#include "hal_gpio.h"
static struct device *spi0;
static struct device *dma_ch3;
const st7789v_init_cmd_t st7789v_init_cmds[] = {
{ 0x01, NULL, 0x80 }, /* Software reset */
{ 0x11, NULL, 0x80 }, /* Exit sleep */
{ 0xB2, "\x05\x05\x00\x33\x33", 5 },
{ 0xB7, "\x74", 1 },
{ 0xBB, "\x2a", 1 },
{ 0xC0, "\x2c", 1 },
{ 0xC2, "\x01", 1 },
{ 0xC3, "\x13", 1 },
{ 0xC4, "\x20", 1 },
{ 0xC6, "\x0F", 1 },
{ 0xD0, "\xA4\xA1", 2 },
{ 0xD6, "\xA1", 1 },
// { 0x20, "\x00", 1 }, /* set non-inverted mode, 16-bit color */
{ 0x21, "\x00", 1 }, /* set inverted mode */
{ 0x3A, "\x05", 1 }, /* set color mode */
{ 0x36, "\xC0", 1 }, /* set MX, MY, RGB mode */
{ 0xE0, "\x70\x0b\x10\x0b\x0a\x26\x35\x44\x4c\x38\x17\x17\x2f\x2f", 14 }, /* set Gamma Sequence */
{ 0xE1, "\x70\x03\x08\x09\x08\x04\x2e\x22\x47\x39\x18\x19\x2d\x30", 14 }, /* set Gamma Sequence */
{ 0xD6, "\xA1", 1 },
{ 0x29, NULL, 0x80 }, /* Display on */
};
/**
* @brief st7789v_spi_init
*
* @return int 0:succes 1:error
*/
static int st7789v_spi_init(void)
{
gpio_set_mode(ST7789V_CS_PIN, GPIO_OUTPUT_MODE);
gpio_set_mode(ST7789V_DC_PIN, GPIO_OUTPUT_MODE);
ST7789V_CS_HIGH;
ST7789V_DC_HIGH;
spi0 = device_find("lcd_dev_ifs");
if (spi0) {
device_close(spi0);
} else {
spi_register(SPI0_INDEX, "lcd_dev_ifs");
spi0 = device_find("lcd_dev_ifs");
}
if (spi0) {
SPI_DEV(spi0)->mode = SPI_MASTER_MODE;
SPI_DEV(spi0)->clk = (36 * 1000 * 1000);
SPI_DEV(spi0)->direction = SPI_MSB_BYTE0_DIRECTION_FIRST;
SPI_DEV(spi0)->clk_polaraity = SPI_POLARITY_LOW;
SPI_DEV(spi0)->datasize = SPI_DATASIZE_8BIT;
SPI_DEV(spi0)->clk_phase = SPI_PHASE_1EDGE;
SPI_DEV(spi0)->fifo_threshold = 0;
device_open(spi0, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
} else {
return 1;
}
dma_ch3 = device_find("lcd_dev_ifs_dma");
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "lcd_dev_ifs_dma");
dma_ch3 = device_find("lcd_dev_ifs_dma");
}
if (dma_ch3) {
DMA_DEV(dma_ch3)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_SPI0_TX;
DMA_DEV(dma_ch3)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch3)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch3, 0);
device_set_callback(dma_ch3, NULL);
device_control(spi0, DEVICE_CTRL_ATTACH_TX_DMA, dma_ch3);
// device_control(dma_ch3, DEVICE_CTRL_CLR_INT, NULL);
} else {
return 1;
}
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
return 0;
}
/**
* @brief st7789v_write_cmd
*
* @param cmd
* @return int 0:succes 1:error
*/
static int st7789v_write_cmd(uint8_t cmd)
{
ST7789V_DC_LOW;
ST7789V_CS_LOW;
int res = spi_transmit(spi0, &cmd, 1, SPI_TRANSFER_TYPE_8BIT);
ST7789V_CS_HIGH;
return res;
}
/**
* @brief st7789v_write_data_1byte
*
* @param data
* @return int 0:succes 1:error
*/
static int st7789v_write_data_1byte(uint8_t data)
{
ST7789V_DC_HIGH;
ST7789V_CS_LOW;
int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_8BIT);
ST7789V_CS_HIGH;
return res;
}
/**
* @brief st7789v_write_data_2byte
*
* @param data
* @return int 0:succes 1:error
*/
// static int st7789v_write_data_2byte(uint16_t data)
// {
// data = ((data >> 8) & 0xFF) | data << 8;
// ST7789V_DC_HIGH;
// ST7789V_CS_LOW;
// int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_16BIT);
// ST7789V_CS_HIGH;
// return res;
// }
/**
* @brief st7789v_write_data_4byte
*
* @param data
* @return int 0:succes 1:error
*/
static int st7789v_write_data_4byte(uint32_t data)
{
data = ((data >> 24) & 0xFF) | ((data >> 8) & 0xFF00) | ((data << 8) & 0xFF0000) | ((data << 24));
ST7789V_DC_HIGH;
ST7789V_CS_LOW;
int res = spi_transmit(spi0, &data, 1, SPI_TRANSFER_TYPE_32BIT);
ST7789V_CS_HIGH;
return res;
}
/**
* @brief st7789v_draw_is_busy, After the call st7789v_draw_picture_dma must check this,
* if st7789v_draw_is_busy() == 1, Don't allow other draw !!
* can run in the DMA interrupt callback function.
*
* @return int 0:draw end; 1:Being draw
*/
int st7789v_draw_is_busy(void)
{
if (dma_channel_check_busy(SPI_DEV(spi0)->tx_dma)) {
return 1;
} else {
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
ST7789V_CS_HIGH;
return 0;
}
}
/**
* @brief st7789v_init
*
* @return int
*/
int st7789v_init()
{
int res = st7789v_spi_init();
if (res) {
return res;
}
for (uint16_t i = 0; i < (sizeof(st7789v_init_cmds) / sizeof(st7789v_init_cmd_t)); i++) {
/* send register address */
res |= st7789v_write_cmd(st7789v_init_cmds[i].cmd);
/* send register data */
for (uint8_t j = 0; j < (st7789v_init_cmds[i].databytes & 0x7F); j++) {
res |= st7789v_write_data_1byte(st7789v_init_cmds[i].data[j]);
}
if (res) {
return res;
}
/* delay */
if (st7789v_init_cmds[i].databytes & 0x80) {
bflb_platform_delay_ms(100);
}
}
st7789v_set_draw_window(0, 0, ST7789V_W, ST7789V_H);
return res;
}
/**
* @brief st7789v_set_dir
*
* @param dir
*/
void st7789v_set_dir(uint8_t dir)
{
st7789v_write_cmd(0x36);
switch (dir) {
case 0:
st7789v_write_data_1byte(0x00);
break;
case 1:
st7789v_write_data_1byte(0xA0);
break;
case 2:
st7789v_write_data_1byte(0xC0);
break;
case 3:
st7789v_write_data_1byte(0x60);
break;
default:
break;
}
}
void st7789v_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
{
#if ST7789V_OFFSET_X
x1 += ST7789V_OFFSET_X;
x2 += ST7789V_OFFSET_X;
#endif
#if ST7789V_OFFSET_Y
y1 += ST7789V_OFFSET_Y;
y2 += ST7789V_OFFSET_Y;
#endif
st7789v_write_cmd(0x2a);
st7789v_write_data_4byte(x1 << 16 | (x2 & 0xFFFF));
st7789v_write_cmd(0x2b);
st7789v_write_data_4byte(y1 << 16 | (y2 & 0xFFFF));
st7789v_write_cmd(0x2c);
}
/**
* @brief st7789v_draw_point
*
* @param x
* @param y
* @param color
*/
void st7789v_draw_point(uint16_t x, uint16_t y, uint16_t color)
{
if (lcd_auto_swap_flag) {
color = ((color >> 8) & 0xFF) | color << 8;
}
st7789v_set_draw_window(x, y, x, y);
ST7789V_DC_HIGH;
ST7789V_CS_LOW;
spi_transmit(spi0, &color, 1, SPI_TRANSFER_TYPE_16BIT);
ST7789V_CS_HIGH;
}
/**
* @brief st7789v_draw_area
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param color
*/
void st7789v_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
if (lcd_auto_swap_flag) {
color = ((color >> 8) & 0xFF) | color << 8;
}
st7789v_set_draw_window(x1, y1, x2, y2);
ST7789V_DC_HIGH;
ST7789V_CS_LOW;
for (uint16_t i = y1; i <= y2; i++) {
for (uint16_t j = x1; j <= x2; j++)
spi_transmit(spi0, &color, 1, SPI_TRANSFER_TYPE_16BIT);
}
ST7789V_CS_HIGH;
}
/**
* @brief st7789v_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
* After the call, No other operations are allowed until (st7789v_draw_is_busy()==0)
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void st7789v_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
/* 数据高低位切换 */
if (lcd_auto_swap_flag) {
lcd_swap_color_data16(picture, picture, picture_size);
}
st7789v_set_draw_window(x1, y1, x2, y2);
ST7789V_DC_HIGH;
ST7789V_CS_LOW;
device_control(spi0, DEVICE_CTRL_TX_DMA_RESUME, NULL);
device_write(spi0, 0, picture, picture_size * 2);
}
/**
* @brief st7789v_draw_picture,BlockingUsing DMA acceleration,Waiting for the draw end
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param picture
*/
void st7789v_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture)
{
st7789v_draw_picture_nonblocking(x1, y1, x2, y2, picture);
while (st7789v_draw_is_busy()) {
BL_DRV_DUMMY;
};
}

View File

@@ -0,0 +1,58 @@
/**
* @file st7789v.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _ST7789V_H_
#define _ST7789V_H_
#include "bflb_platform.h"
#define ST7789V_CS_PIN GPIO_PIN_10
#define ST7789V_DC_PIN GPIO_PIN_22
#define ST7789V_CS_HIGH gpio_write(ST7789V_CS_PIN, 1)
#define ST7789V_CS_LOW gpio_write(ST7789V_CS_PIN, 0)
#define ST7789V_DC_HIGH gpio_write(ST7789V_DC_PIN, 1)
#define ST7789V_DC_LOW gpio_write(ST7789V_DC_PIN, 0)
#define ST7789V_W 135 /* ST7789V LCD width */
#define ST7789V_H 240 /* ST7789V LCD height */
#define ST7789V_OFFSET_X 53
#define ST7789V_OFFSET_Y 40
typedef struct {
uint8_t cmd;
const char *data;
uint8_t databytes; /* Num of data in data; bit 7 = delay after set */
} st7789v_init_cmd_t;
int st7789v_init();
void st7789v_set_dir(uint8_t dir);
void st7789v_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
void st7789v_draw_point(uint16_t x, uint16_t y, uint16_t color);
void st7789v_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void st7789v_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
void st7789v_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *picture);
int st7789v_draw_is_busy(void);
#endif

View File

@@ -0,0 +1,323 @@
/**
* @file bflb_platform.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_uart.h"
#include "hal_flash.h"
#include "hal_mtimer.h"
#include "drv_mmheap.h"
#include "hal_common.h"
#include "ring_buffer.h"
#include "bflb_platform.h"
extern uint32_t __HeapBase;
extern uint32_t __HeapLimit;
static uint8_t uart_dbg_disable = 0;
struct heap_info mmheap_root;
static struct heap_region system_mmheap[] = {
{ NULL, 0 },
{ NULL, 0 }, /* Terminates the array. */
};
__WEAK__ void board_init(void)
{
}
__WEAK__ void bl_show_info(void)
{
}
__WEAK__ enum uart_index_type board_get_debug_uart_index(void)
{
return 0;
}
void bl_show_flashinfo(void)
{
SPI_Flash_Cfg_Type flashCfg;
uint8_t *pFlashCfg = NULL;
uint32_t flashCfgLen = 0;
uint32_t flashJedecId = 0;
flashJedecId = flash_get_jedecid();
flash_get_cfg(&pFlashCfg, &flashCfgLen);
arch_memcpy((void *)&flashCfg, pFlashCfg, flashCfgLen);
MSG("show flash cfg:\r\n");
MSG("jedec id 0x%06X\r\n", flashJedecId);
MSG("mid 0x%02X\r\n", flashCfg.mid);
MSG("iomode 0x%02X\r\n", flashCfg.ioMode);
MSG("clk delay 0x%02X\r\n", flashCfg.clkDelay);
MSG("clk invert 0x%02X\r\n", flashCfg.clkInvert);
MSG("read reg cmd0 0x%02X\r\n", flashCfg.readRegCmd[0]);
MSG("read reg cmd1 0x%02X\r\n", flashCfg.readRegCmd[1]);
MSG("write reg cmd0 0x%02X\r\n", flashCfg.writeRegCmd[0]);
MSG("write reg cmd1 0x%02X\r\n", flashCfg.writeRegCmd[1]);
MSG("qe write len 0x%02X\r\n", flashCfg.qeWriteRegLen);
MSG("cread support 0x%02X\r\n", flashCfg.cReadSupport);
MSG("cread code 0x%02X\r\n", flashCfg.cReadMode);
MSG("burst wrap cmd 0x%02X\r\n", flashCfg.burstWrapCmd);
MSG("-------------------\r\n");
}
void bflb_platform_init(uint32_t baudrate)
{
static uint8_t initialized = 0;
BL_Err_Type ret = ERROR;
cpu_global_irq_disable();
ret = flash_init();
board_init();
if (!uart_dbg_disable) {
uart_register(board_get_debug_uart_index(), "debug_log");
struct device *uart = device_find("debug_log");
if (uart) {
device_open(uart, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_INT_RX);
device_set_callback(uart, NULL);
device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT));
}
bl_show_info();
}
if (!initialized) {
system_mmheap[0].addr = (uint8_t *)&__HeapBase;
system_mmheap[0].mem_size = ((size_t)&__HeapLimit - (size_t)&__HeapBase);
if (system_mmheap[0].mem_size > 0) {
mmheap_init(&mmheap_root, system_mmheap);
}
MSG("dynamic memory init success,heap size = %d Kbyte \r\n", system_mmheap[0].mem_size / 1024);
initialized = 1;
if (ret != SUCCESS) {
MSG("flash init fail!!!\r\n");
}
bl_show_flashinfo();
}
cpu_global_irq_enable();
}
#if ((defined BOOTROM) || (defined BFLB_EFLASH_LOADER))
static uint8_t eflash_loader_logbuf[1024] __attribute__((section(".system_ram_noinit")));
static uint32_t log_len = 0;
uint32_t bflb_platform_get_log(uint8_t *data, uint32_t maxlen)
{
uint32_t len = log_len;
if (len > maxlen) {
len = maxlen;
}
memcpy(data, eflash_loader_logbuf, len);
return len;
}
#endif
void bflb_platform_printf(char *fmt, ...)
{
struct device *uart;
char print_buf[128];
va_list ap;
if (!uart_dbg_disable) {
va_start(ap, fmt);
vsnprintf(print_buf, sizeof(print_buf) - 1, fmt, ap);
va_end(ap);
#if ((defined BOOTROM) || (defined BFLB_EFLASH_LOADER))
uint32_t len = strlen(print_buf);
if (log_len + len < sizeof(eflash_loader_logbuf)) {
memcpy(eflash_loader_logbuf + log_len, print_buf, len);
log_len += len;
}
#endif
uart = device_find("debug_log");
device_write(uart, 0, (uint8_t *)print_buf, strlen(print_buf));
}
}
void bflb_platform_print_set(uint8_t disable)
{
uart_dbg_disable = disable;
}
uint8_t bflb_platform_print_get(void)
{
return uart_dbg_disable;
}
void bflb_platform_deinit(void)
{
if (!uart_dbg_disable) {
struct device *uart = device_find("debug_log");
if (uart) {
device_close(uart);
device_unregister("debug_log");
}
}
}
void bflb_platform_dump(uint8_t *data, uint32_t len)
{
uint32_t i = 0;
if (!uart_dbg_disable) {
for (i = 0; i < len; i++) {
if (i % 16 == 0) {
bflb_platform_printf("\r\n");
}
bflb_platform_printf("%02x ", data[i]);
}
bflb_platform_printf("\r\n");
}
}
void bflb_platform_reg_dump(uint32_t addr)
{
bflb_platform_printf("%08x[31:0]=%08x\r\n", addr, *(volatile uint32_t *)(addr));
}
void bflb_platform_init_time()
{
}
void bflb_platform_deinit_time()
{
}
void bflb_platform_set_alarm_time(uint64_t time, void (*interruptFun)(void))
{
mtimer_set_alarm_time(time, interruptFun);
}
void bflb_platform_clear_time()
{
}
void bflb_platform_start_time()
{
}
void bflb_platform_stop_time()
{
}
uint64_t bflb_platform_get_time_ms()
{
return mtimer_get_time_ms();
}
uint64_t bflb_platform_get_time_us()
{
return mtimer_get_time_us();
}
void bflb_platform_delay_ms(uint32_t ms)
{
mtimer_delay_ms(ms);
}
void bflb_platform_delay_us(uint32_t us)
{
mtimer_delay_us(us);
}
void bflb_print_device_list(void)
{
struct device *dev;
dlist_t *node;
uint8_t device_index = 0;
MSG("Device List Print\r\n");
dlist_for_each(node, device_get_list_header())
{
dev = dlist_entry(node, struct device, list);
MSG("Index %d\r\nDevice Name = %s \r\n", device_index, dev->name);
switch (dev->type) {
case DEVICE_CLASS_GPIO:
MSG("Device Type = %s \r\n", "GPIO");
break;
case DEVICE_CLASS_UART:
MSG("Device Type = %s \r\n", "UART");
break;
case DEVICE_CLASS_SPI:
MSG("Device Type = %s \r\n", "SPI");
break;
case DEVICE_CLASS_I2C:
MSG("Device Type = %s \r\n", "I2C");
break;
case DEVICE_CLASS_ADC:
MSG("Device Type = %s \r\n", "ADC");
break;
case DEVICE_CLASS_DMA:
MSG("Device Type = %s \r\n", "DMA");
break;
case DEVICE_CLASS_TIMER:
MSG("Device Type = %s \r\n", "TIMER");
break;
case DEVICE_CLASS_PWM:
MSG("Device Type = %s \r\n", "PWM");
break;
case DEVICE_CLASS_SDIO:
MSG("Device Type = %s \r\n", "SDIO");
break;
case DEVICE_CLASS_USB:
MSG("Device Type = %s \r\n", "USB");
break;
case DEVICE_CLASS_I2S:
MSG("Device Type = %s \r\n", "I2S");
break;
case DEVICE_CLASS_CAMERA:
MSG("Device Type = %s \r\n", "CAMERA");
break;
case DEVICE_CLASS_NONE:
break;
default:
break;
}
MSG("Device Handle = 0x%x \r\n", dev);
MSG("---------------------\r\n", dev);
device_index++;
}
}

View File

@@ -0,0 +1,110 @@
/**
* @file bflb_platform.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _BFLB_PLATFORM_H
#define _BFLB_PLATFORM_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#define MSG(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#define MSG_DBG(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#define MSG_ERR(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#define BL_CASE_FAIL \
{ \
MSG("case fail\r\n"); \
}
#define BL_CASE_SUCCESS \
{ \
MSG("case success\r\n"); \
}
/* compatible with old version */
#ifndef DBG_TAG
#define DBG_TAG "DEBUG"
#endif
/*
* The color for terminal (foreground)
* BLACK 30
* RED 31
* GREEN 32
* YELLOW 33
* BLUE 34
* PURPLE 35
* CYAN 36
* WHITE 37
*/
#define _DBG_COLOR(n) bflb_platform_printf("\033[" #n "m")
#define _DBG_LOG_HDR(lvl_name, color_n) \
bflb_platform_printf("\033[" #color_n "m[" lvl_name "/" DBG_TAG "] ")
#define _DBG_LOG_X_END \
bflb_platform_printf("\033[0m\n")
#define dbg_log_line(lvl, color_n, fmt, ...) \
do { \
_DBG_LOG_HDR(lvl, color_n); \
bflb_platform_printf(fmt, ##__VA_ARGS__); \
_DBG_LOG_X_END; \
} while (0)
#define LOG_D(fmt, ...) dbg_log_line("D", 0, fmt, ##__VA_ARGS__)
#define LOG_I(fmt, ...) dbg_log_line("I", 35, fmt, ##__VA_ARGS__)
#define LOG_W(fmt, ...) dbg_log_line("W", 33, fmt, ##__VA_ARGS__)
#define LOG_E(fmt, ...) dbg_log_line("E", 31, fmt, ##__VA_ARGS__)
#define LOG_RAW(...) bflb_platform_printf(__VA_ARGS__)
void bflb_platform_init(uint32_t baudrate);
void bflb_platform_printf(char *fmt, ...);
void bflb_platform_print_set(uint8_t disable);
uint8_t bflb_platform_print_get(void);
void bflb_platform_dump(uint8_t *data, uint32_t len);
void bflb_platform_reg_dump(uint32_t addr);
uint32_t bflb_platform_get_log(uint8_t *data, uint32_t maxlen);
void bflb_platform_deinit(void);
void bflb_platform_init_time(void);
void bflb_platform_clear_time(void);
uint64_t bflb_platform_get_time_ms(void);
uint64_t bflb_platform_get_time_us(void);
void bflb_platform_start_time(void);
void bflb_platform_stop_time(void);
void bflb_platform_set_alarm_time(uint64_t time, void (*interruptFun)(void));
void bflb_platform_deinit_time(void);
void bflb_platform_delay_ms(uint32_t ms);
void bflb_platform_delay_us(uint32_t us);
void bflb_print_device_list(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,22 @@
#include <stdlib.h>
#include <stdint.h>
void *operator new(size_t size)
{
return malloc(size);
}
void *operator new[](size_t size)
{
return malloc(size);
}
void operator delete(void *ptr)
{
free(ptr);
}
void operator delete[](void *ptr)
{
free(ptr);
}

View File

@@ -0,0 +1,295 @@
#include <reent.h>
#include <errno.h>
#include <unistd.h>
#include "drv_mmheap.h"
#include "drv_device.h"
extern struct heap_info mmheap_root;
#ifdef CONF_VFS_ENABLE
#include <vfs.h>
#endif
/* Reentrant versions of system calls. */
/* global errno in RT-Thread */
static volatile int _sys_errno = 0;
#ifndef _REENT_ONLY
int *__errno()
{
// #if (configUSE_POSIX_ERRNO == 1)
// {
// extern int FreeRTOS_errno;
// return &FreeRTOS_errno;
// }
// #endif
return (int *)&_sys_errno;
}
#endif
int _getpid_r(struct _reent *ptr)
{
return 0;
}
int _execve_r(struct _reent *ptr, const char *name, char *const *argv, char *const *env)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
int _fcntl_r(struct _reent *ptr, int fd, int cmd, int arg)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
int _fork_r(struct _reent *ptr)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
int _isatty_r(struct _reent *ptr, int fd)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
int _kill_r(struct _reent *ptr, int pid, int sig)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
int _link_r(struct _reent *ptr, const char *old, const char *new)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
_off_t _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
_off_t rc;
rc = aos_lseek(fd, pos, whence);
return rc;
#endif
}
int _mkdir_r(struct _reent *ptr, const char *name, int mode)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
int rc;
rc = aos_mkdir(name);
return rc;
#endif
}
int _open_r(struct _reent *ptr, const char *file, int flags, int mode)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
int rc;
rc = aos_open(file, flags);
return rc;
#endif
}
int _close_r(struct _reent *ptr, int fd)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
return aos_close(fd);
#endif
}
_ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
_ssize_t rc;
rc = aos_read(fd, buf, nbytes);
return rc;
#endif
}
int _rename_r(struct _reent *ptr, const char *old, const char *new)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
int rc;
rc = aos_rename(old, new);
return rc;
#endif
}
int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
int rc;
rc = aos_stat(file, pstat);
return rc;
#endif
}
int _unlink_r(struct _reent *ptr, const char *file)
{
#ifndef CONF_VFS_ENABLE
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
#else
return aos_unlink(file);
#endif
}
int _wait_r(struct _reent *ptr, int *status)
{
/* return "not supported" */
ptr->_errno = -ENOSYS;
return -1;
}
_ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
{
#ifndef CONF_VFS_ENABLE
struct device *uart = device_find("debug_log");
if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd)) {
device_write(uart, 0, (uint8_t *)buf, nbytes);
}
return 0;
#else
_ssize_t rc;
rc = aos_write(fd, buf, nbytes);
return rc;
#endif
}
void *_malloc_r(struct _reent *ptr, size_t size)
{
void *result;
result = (void *)mmheap_alloc(&mmheap_root, size);
if (result == NULL) {
ptr->_errno = -ENOMEM;
}
return result;
}
void *_realloc_r(struct _reent *ptr, void *old, size_t newlen)
{
void *result;
result = (void *)mmheap_realloc(&mmheap_root, old, newlen);
if (result == NULL) {
ptr->_errno = -ENOMEM;
}
return result;
}
void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
{
void *result;
result = (void *)mmheap_calloc(&mmheap_root, size, len);
if (result == NULL) {
ptr->_errno = -ENOMEM;
}
return result;
}
void _free_r(struct _reent *ptr, void *addr)
{
mmheap_free(&mmheap_root, addr);
}
void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
{
void *ret;
ptr->_errno = ENOMEM;
ret = (void *)-1;
return ret;
}
/* for exit() and abort() */
void __attribute__((noreturn))
_exit(int status)
{
while (1) {
}
}
void _system(const char *s)
{
}
void __libc_init_array(void)
{
/* we not use __libc init_aray to initialize C++ objects */
}
mode_t umask(mode_t mask)
{
return 022;
}
int flock(int fd, int operation)
{
return 0;
}
/*
These functions are implemented and replaced by the 'common/time.c' file
int _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp);
_CLOCK_T_ _times_r(struct _reent *ptr, struct tms *ptms);
*/

View File

@@ -0,0 +1,144 @@
/**
* @file bsp_sf_psram.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bsp_sf_psram.h"
#include "bflb_platform.h"
#include "bl702_psram.h"
#include "bl702_l1c.h"
#include "bl702_sec_eng.h"
#include "bl702_glb.h"
/* bsp sf psram private variables */
SPI_Psram_Cfg_Type apMemory1604 = {
.readIdCmd = 0x9F,
.readIdDmyClk = 0,
.burstToggleCmd = 0xC0,
.resetEnableCmd = 0x66,
.resetCmd = 0x99,
.enterQuadModeCmd = 0x35,
.exitQuadModeCmd = 0xF5,
.readRegCmd = 0xB5,
.readRegDmyClk = 1,
.writeRegCmd = 0xB1,
.readCmd = 0x03,
.readDmyClk = 0,
.fReadCmd = 0x0B,
.fReadDmyClk = 1,
.fReadQuadCmd = 0xEB,
.fReadQuadDmyClk = 3,
.writeCmd = 0x02,
.quadWriteCmd = 0x38,
.pageSize = 512,
.ctrlMode = PSRAM_SPI_CTRL_MODE,
.driveStrength = PSRAM_DRIVE_STRENGTH_50_OHMS,
.burstLength = PSRAM_BURST_LENGTH_512_BYTES,
};
SF_Ctrl_Cmds_Cfg cmdsCfg = {
.cmdsEn = ENABLE,
.burstToggleEn = ENABLE,
.wrapModeEn = DISABLE,
.wrapLen = SF_CTRL_WRAP_LEN_512,
};
SF_Ctrl_Psram_Cfg sfCtrlPsramCfg = {
.owner = SF_CTRL_OWNER_SAHB,
.padSel = SF_CTRL_PAD_SEL_DUAL_CS_SF2,
.bankSel = SF_CTRL_SEL_PSRAM,
.psramRxClkInvertSrc = ENABLE,
.psramRxClkInvertSel = DISABLE,
.psramDelaySrc = ENABLE,
.psramClkDelay = 1,
};
/* bsp sf psram gpio init */
/**
* @brief
*
* @return None
*
*/
void ATTR_TCM_SECTION bsp_sf_psram_gpio_init(void)
{
GLB_GPIO_Cfg_Type cfg;
uint8_t gpiopins[7];
uint8_t i = 0;
cfg.gpioMode = GPIO_MODE_AF;
cfg.pullType = GPIO_PULL_UP;
cfg.drive = 3;
cfg.smtCtrl = 1;
cfg.gpioFun = GPIO_FUN_FLASH_PSRAM;
gpiopins[0] = BFLB_EXTPSRAM_CLK_GPIO;
gpiopins[1] = BFLB_EXTPSRAM_CS_GPIO;
gpiopins[2] = BFLB_EXTPSRAM_DATA0_GPIO;
gpiopins[3] = BFLB_EXTPSRAM_DATA1_GPIO;
gpiopins[4] = BFLB_EXTPSRAM_DATA2_GPIO;
gpiopins[5] = BFLB_EXTPSRAM_DATA3_GPIO;
gpiopins[6] = BFLB_EXTFLASH_CS_GPIO;
for (i = 0; i < sizeof(gpiopins); i++) {
cfg.gpioPin = gpiopins[i];
if (i == 0 || i == 1 || i == 6) {
/*flash clk and cs is output*/
cfg.gpioMode = GPIO_MODE_OUTPUT;
} else {
/*data are bidir*/
cfg.gpioMode = GPIO_MODE_AF;
}
GLB_GPIO_Init(&cfg);
}
}
/* bsp sf psram init */
/**
* @brief
*
* @param sw_reset
*
* @return None
*
*/
void ATTR_TCM_SECTION bsp_sf_psram_init(uint8_t sw_reset)
{
uint8_t psramId[8] = { 0 };
bsp_sf_psram_gpio_init();
Psram_Init(&apMemory1604, &cmdsCfg, &sfCtrlPsramCfg);
if (sw_reset) {
Psram_SoftwareReset(&apMemory1604, apMemory1604.ctrlMode);
}
Psram_ReadId(&apMemory1604, psramId);
Psram_Cache_Write_Set(&apMemory1604, SF_CTRL_QIO_MODE, ENABLE, DISABLE, DISABLE);
L1C_Cache_Enable_Set(L1C_WAY_DISABLE_NONE);
}
void ATTR_TCM_SECTION bsp_sf_psram_read_id(uint8_t *data)
{
Psram_ReadId(&apMemory1604, data);
}

View File

@@ -0,0 +1,45 @@
/**
* @file bsp_sf_psram.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __BSP_SF_PSRAM_H__
#define __BSP_SF_PSRAM_H__
#include "bl702.h"
#define BSP_PSRAM_BASE BL702_PSRAM_XIP_BASE
#define PSRAM_SIZE (2 * 1024 * 1024)
#define BFLB_EXTFLASH_CS_GPIO GLB_GPIO_PIN_25
#define BFLB_EXTPSRAM_CLK_GPIO GLB_GPIO_PIN_27
#define BFLB_EXTPSRAM_CS_GPIO GLB_GPIO_PIN_17
#define BFLB_EXTPSRAM_DATA0_GPIO GLB_GPIO_PIN_28
#define BFLB_EXTPSRAM_DATA1_GPIO GLB_GPIO_PIN_24
#define BFLB_EXTPSRAM_DATA2_GPIO GLB_GPIO_PIN_23
#define BFLB_EXTPSRAM_DATA3_GPIO GLB_GPIO_PIN_26
void bsp_sf_psram_gpio_init(void);
void bsp_sf_psram_init(uint8_t sw_reset);
void bsp_sf_psram_read_id(uint8_t *data);
#endif /* __BSP_SF_PSRAM_H__ */

View File

@@ -0,0 +1,874 @@
/**
* @file bsp_spi_sd.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "hal_spi.h"
#include "hal_gpio.h"
#include "hal_dma.h"
#include "bsp_spi_sd.h"
static struct device *spi0;
static struct device *dma_ch3;
static struct device *dma_ch4;
SD_CardInfoTypedef SD_CardInfo = { 0 };
uint8_t SD_SPI_Init(void)
{
gpio_set_mode(SPI_PIN_CS, GPIO_OUTPUT_MODE);
gpio_write(SPI_PIN_CS, 1);
spi0 = device_find("spi0");
if (spi0) {
device_close(spi0);
} else {
spi_register(SPI0_INDEX, "spi0");
spi0 = device_find("spi0");
}
if (spi0) {
device_open(spi0, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
}
dma_ch3 = device_find("dma0_ch3");
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "dma0_ch3");
dma_ch3 = device_find("dma0_ch3");
}
if (dma_ch3) {
DMA_DEV(dma_ch3)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_SPI0_TX;
DMA_DEV(dma_ch3)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch3)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch3, 0);
device_control(dma_ch3, DEVICE_CTRL_CLR_INT, NULL);
}
dma_ch4 = device_find("dma0_ch4");
if (dma_ch4) {
device_close(dma_ch4);
} else {
dma_register(DMA0_CH4_INDEX, "dma0_ch4");
dma_ch4 = device_find("dma0_ch4");
}
if (dma_ch4) {
DMA_DEV(dma_ch4)->direction = DMA_PERIPH_TO_MEMORY;
DMA_DEV(dma_ch4)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch4)->src_req = DMA_REQUEST_SPI0_RX;
DMA_DEV(dma_ch4)->dst_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch4)->src_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch4)->dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch4)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch4)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch4)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch4)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch4, 0);
device_control(dma_ch4, DEVICE_CTRL_CLR_INT, NULL);
}
return SUCCESS;
}
BL_Err_Type SPI_ReadWriteByte(uint8_t *txBuff, uint8_t *rxBuff, uint32_t length)
{
while (dma_channel_check_busy(dma_ch3) || dma_channel_check_busy(dma_ch4))
;
if (length < 500) {
spi_transmit_receive(spi0, txBuff, rxBuff, length, SPI_DATASIZE_8BIT);
} else {
device_control(spi0, DEVICE_CTRL_TX_DMA_RESUME, NULL);
device_control(spi0, DEVICE_CTRL_RX_DMA_RESUME, NULL);
dma_reload(dma_ch4, (uint32_t)DMA_ADDR_SPI_RDR, (uint32_t)rxBuff, length);
dma_reload(dma_ch3, (uint32_t)txBuff, (uint32_t)DMA_ADDR_SPI_TDR, length);
dma_channel_start(dma_ch4);
dma_channel_start(dma_ch3);
while (dma_channel_check_busy(dma_ch3) || dma_channel_check_busy(dma_ch4))
;
device_control(spi0, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
device_control(spi0, DEVICE_CTRL_RX_DMA_SUSPEND, NULL);
}
return SUCCESS;
}
void SPI_CS_WriteBit(uint8_t bit)
{
gpio_write(SPI_PIN_CS, bit);
}
/****************************************************************************
* @brief SPI_SetSpeed
*
*
*******************************************************************************/
static void SD_SPI_SetSpeed(uint8_t mode)
{
switch (mode) {
case (0):
device_control(spi0, DEVICE_CTRL_SPI_CONFIG_CLOCK, (void *)(300 * 1000));
break;
case (1):
device_control(spi0, DEVICE_CTRL_SPI_CONFIG_CLOCK, (void *)(18 * 1000 * 1000));
break;
case (2):
device_control(spi0, DEVICE_CTRL_SPI_CONFIG_CLOCK, (void *)(40 * 1000 * 1000));
break;
default:
break;
}
}
/****************************************************************************
* @brief SPI_CS_WriteBit
*
*
*******************************************************************************/
// static void SPI_CS_WriteBit(uint8_t bit)
// {
// GLB_GPIO_Write(SPI_PIN_CS, bit);
// }
/****************************************************************************/ /**
* @brief SD_GetResponse
*
*
*******************************************************************************/
static BL_Err_Type SD_GetResponse(uint8_t Response)
{
uint8_t rx;
uint8_t t_0xFF = 0xFF;
uint16_t Count = 0xFFFE;
do {
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
Count--;
} while (rx != Response && Count);
if (Count == 0) {
return ERROR;
} else {
return SUCCESS;
}
}
/****************************************************************************
* @brief SD_SendCommand
*
*
*******************************************************************************/
static uint8_t SD_SendCommand(uint8_t cmd, uint32_t arg, uint8_t crc)
{
uint8_t rx;
uint8_t t_0xFF = 0xFF;
uint8_t rxbuff[6];
uint8_t txbuff[6];
uint8_t retry = 0;
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
SPI_CS_WriteBit(0);
SD_GetResponse(0xFF);
txbuff[0] = cmd | 0x40;
txbuff[1] = (uint8_t)(arg >> 24);
txbuff[2] = (uint8_t)(arg >> 16);
txbuff[3] = (uint8_t)(arg >> 8);
txbuff[4] = (uint8_t)(arg);
txbuff[5] = (uint8_t)(crc);
SPI_ReadWriteByte(txbuff, rxbuff, 6);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
do {
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
retry++;
} while (rx == 0xFF && retry < 20);
//MSG("CMD%d :%d num:%d\r\n",cmd,rx,retry);
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &retry, 1);
return rx;
}
/****************************************************************************
* @brief SD_SendCommand_NoDeassert
*
*
*******************************************************************************/
static uint8_t SD_SendCommand_NoDeassert(uint8_t cmd, uint32_t arg, uint8_t crc)
{
uint8_t rx;
uint8_t t_0xFF = 0xFF;
uint8_t rxbuff[6];
uint8_t txbuff[6];
uint8_t retry = 0;
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
SPI_CS_WriteBit(0);
SD_GetResponse(0xFF);
txbuff[0] = cmd | 0x40;
txbuff[1] = (uint8_t)(arg >> 24);
txbuff[2] = (uint8_t)(arg >> 16);
txbuff[3] = (uint8_t)(arg >> 8);
txbuff[4] = (uint8_t)(arg);
txbuff[5] = (uint8_t)(crc);
SPI_ReadWriteByte(txbuff, rxbuff, 6);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
do {
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
retry++;
} while (rx == 0xFF && retry < 20);
//MSG("CMD%d :%d num:%d\r\n",cmd,rx,retry);
return rx;
}
/****************************************************************************
* @brief SD_Idle_Sta
*
*
*******************************************************************************/
static BL_Err_Type SD_Idle_Sta(void)
{
uint16_t i;
uint8_t rx = 0;
uint8_t t_0xFF = 0xFF;
uint8_t retry = 0;
SPI_CS_WriteBit(1);
for (i = 0; i < 10; i++) {
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
}
do {
rx = SD_SendCommand(CMD0, 0, 0x95);
retry++;
} while (rx != MSD_IN_IDLE_STATE && retry < 100);
if (retry >= 100) {
//MSG("SD IDLE err:%d\r\n",rx);
return ERROR;
} else {
//MSG("SD IDLE success\r\n");
return SUCCESS;
}
}
/****************************************************************************/ /**
* @brief SD_ReceiveData
*
*
*
*******************************************************************************/
uint8_t SD_ReceiveData(uint8_t *data, uint16_t len, uint8_t release)
{
uint8_t rx;
uint8_t t_0xFF = 0xFF;
uint16_t i;
SPI_CS_WriteBit(0);
/* get token */
if (SD_GetResponse(0xFE)) {
SPI_CS_WriteBit(1);
MSG("sd receive err: no token\r\n");
return ERROR;
} else {
//MSG("sd get token\r\n");
}
for (i = 0; i < len; i++) {
SPI_ReadWriteByte(&t_0xFF, data + i, 1);
}
/* two dummy CRC */
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* */
if (release) {
SPI_CS_WriteBit(1);
}
return SUCCESS;
}
/****************************************************************************/ /**
* @brief SD_SendBlock
*
*
*
*******************************************************************************/
uint8_t SD_SendBlock(uint8_t *buf, uint8_t cmd)
{
uint8_t rx;
uint8_t rxbuff[512];
uint8_t t_0xFF = 0xFF;
uint16_t i;
/* Waiti for free */
if (SD_GetResponse(0xFF)) {
SPI_CS_WriteBit(1);
return ERROR;
}
/* send token */
SPI_ReadWriteByte(&cmd, &rx, 1);
if (cmd != 0xFD) {
/* send block data */
SPI_ReadWriteByte(buf, rxbuff, 512);
/* two dummy CRC */
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* 8 clock */
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
if ((rx & 0x1F) != 0x05) {
//MSG("sd send err:%d\r\n",rx,1);
SPI_CS_WriteBit(1);
return rx;
}
i = 0;
do {
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
i++;
} while (rx != 0xFF && i <= 0xFFFE);
}
return 0;
}
/****************************************************************************/ /**
* @brief SD_Get_CardInfo
*
*
*******************************************************************************/
uint8_t SD_Get_CardInfo(SD_CardInfoTypedef *pCardInfo)
{
uint8_t rx, t_0xFF;
uint32_t tmp = 0;
/* get cid */
rx = SD_SendCommand(CMD10, 0, 0xFF);
if (rx) {
return 1;
}
SD_ReceiveData(pCardInfo->SD_cid.CID, 16, RELEASE);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* get csd */
rx = SD_SendCommand(CMD9, 0, 0xFF);
if (rx) {
return 1;
}
SD_ReceiveData(pCardInfo->SD_csd.CSD, 16, RELEASE);
/* Byte 0 */
tmp = pCardInfo->SD_csd.CSD[0];
pCardInfo->SD_csd.CSDStruct = (uint8_t)((tmp & 0xC0) >> 6);
pCardInfo->SD_csd.SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2);
pCardInfo->SD_csd.Reserved1 = tmp & 0x03;
/* Byte 1 */
tmp = pCardInfo->SD_csd.CSD[1];
pCardInfo->SD_csd.TAAC = (uint8_t)tmp;
/* Byte 2 */
tmp = pCardInfo->SD_csd.CSD[2];
pCardInfo->SD_csd.NSAC = (uint8_t)tmp;
/* Byte 3 */
tmp = pCardInfo->SD_csd.CSD[3];
pCardInfo->SD_csd.MaxBusClkFrec = (uint8_t)tmp;
/* Byte 4 */
tmp = pCardInfo->SD_csd.CSD[4];
pCardInfo->SD_csd.CardComdClasses = (uint16_t)(tmp << 4);
/* Byte 5 */
tmp = pCardInfo->SD_csd.CSD[5];
pCardInfo->SD_csd.CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4);
pCardInfo->SD_csd.RdBlockLen = (uint8_t)(tmp & 0x0F);
/* Byte 6 */
tmp = pCardInfo->SD_csd.CSD[6];
pCardInfo->SD_csd.PartBlockRead = (uint8_t)((tmp & 0x80) >> 7);
pCardInfo->SD_csd.WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6);
pCardInfo->SD_csd.RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5);
pCardInfo->SD_csd.DSRImpl = (uint8_t)((tmp & 0x10) >> 4);
pCardInfo->SD_csd.Reserved2 = 0; /*!< Reserved */
if ((pCardInfo->CardType == SD_TYPE_V1) || (pCardInfo->CardType == SD_TYPE_V2)) {
pCardInfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;
/* Byte 7 */
tmp = pCardInfo->SD_csd.CSD[7];
pCardInfo->SD_csd.DeviceSize |= (tmp) << 2;
/* Byte 8 */
tmp = pCardInfo->SD_csd.CSD[8];
pCardInfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;
pCardInfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;
pCardInfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);
/* Byte 9 */
tmp = pCardInfo->SD_csd.CSD[9];
pCardInfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
pCardInfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
pCardInfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;
/* Byte 10 */
tmp = pCardInfo->SD_csd.CSD[10];
pCardInfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;
pCardInfo->CardCapacity = (pCardInfo->SD_csd.DeviceSize + 1);
pCardInfo->CardCapacity *= (1 << (pCardInfo->SD_csd.DeviceSizeMul + 2));
pCardInfo->CardBlockSize = 1 << (pCardInfo->SD_csd.RdBlockLen);
pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
} else if (pCardInfo->CardType == SD_TYPE_V2HC) {
/* Byte 7 */
tmp = pCardInfo->SD_csd.CSD[7];
pCardInfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16;
/* Byte 8 */
tmp = pCardInfo->SD_csd.CSD[8];
pCardInfo->SD_csd.DeviceSize |= (tmp << 8);
/* Byte 9 */
tmp = pCardInfo->SD_csd.CSD[9];
pCardInfo->SD_csd.DeviceSize |= (tmp);
/* Byte 10 */
tmp = pCardInfo->SD_csd.CSD[10];
pCardInfo->CardCapacity = (uint64_t)((((uint64_t)pCardInfo->SD_csd.DeviceSize + 1)) * 512 * 1024);
pCardInfo->CardBlockSize = 512;
} else {
/* Not supported card type */
}
pCardInfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;
pCardInfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1;
/* Byte 11 */
tmp = pCardInfo->SD_csd.CSD[11];
pCardInfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7;
pCardInfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);
/* Byte 12 */
tmp = pCardInfo->SD_csd.CSD[12];
pCardInfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;
pCardInfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5;
pCardInfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2;
pCardInfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2;
/* Byte 13 */
tmp = pCardInfo->SD_csd.CSD[13];
pCardInfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6;
pCardInfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;
pCardInfo->SD_csd.Reserved3 = 0;
pCardInfo->SD_csd.ContentProtectAppli = (tmp & 0x01);
/* Byte 14 */
tmp = pCardInfo->SD_csd.CSD[14];
pCardInfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;
pCardInfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6;
pCardInfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5;
pCardInfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4;
pCardInfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2;
pCardInfo->SD_csd.ECC = (tmp & 0x03);
/* Byte 15 */
tmp = pCardInfo->SD_csd.CSD[15];
pCardInfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1;
pCardInfo->SD_csd.Reserved4 = 1;
/* Byte 0 */
tmp = pCardInfo->SD_cid.CID[0];
pCardInfo->SD_cid.ManufacturerID = tmp;
/* Byte 1 */
tmp = pCardInfo->SD_cid.CID[1];
pCardInfo->SD_cid.OEM_AppliID = tmp << 8;
/* Byte 2 */
tmp = pCardInfo->SD_cid.CID[2];
pCardInfo->SD_cid.OEM_AppliID |= tmp;
/* Byte 3 */
tmp = pCardInfo->SD_cid.CID[3];
pCardInfo->SD_cid.ProdName1 = tmp << 24;
/* Byte 4 */
tmp = pCardInfo->SD_cid.CID[4];
pCardInfo->SD_cid.ProdName1 |= tmp << 16;
/* Byte 5 */
tmp = pCardInfo->SD_cid.CID[5];
pCardInfo->SD_cid.ProdName1 |= tmp << 8;
/* Byte 6 */
tmp = pCardInfo->SD_cid.CID[6];
pCardInfo->SD_cid.ProdName1 |= tmp;
/* Byte 7 */
tmp = pCardInfo->SD_cid.CID[7];
pCardInfo->SD_cid.ProdName2 = tmp;
/* Byte 8 */
tmp = pCardInfo->SD_cid.CID[8];
pCardInfo->SD_cid.ProdRev = tmp;
/* Byte 9 */
tmp = pCardInfo->SD_cid.CID[9];
pCardInfo->SD_cid.ProdSN = tmp << 24;
/* Byte 10 */
tmp = pCardInfo->SD_cid.CID[10];
pCardInfo->SD_cid.ProdSN |= tmp << 16;
/* Byte 11 */
tmp = pCardInfo->SD_cid.CID[11];
pCardInfo->SD_cid.ProdSN |= tmp << 8;
/* Byte 12 */
tmp = pCardInfo->SD_cid.CID[12];
pCardInfo->SD_cid.ProdSN |= tmp;
/* Byte 13 */
tmp = pCardInfo->SD_cid.CID[13];
pCardInfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4;
pCardInfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;
/* Byte 14 */
tmp = pCardInfo->SD_cid.CID[14];
pCardInfo->SD_cid.ManufactDate |= tmp;
/* Byte 15 */
tmp = pCardInfo->SD_cid.CID[16];
pCardInfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1;
pCardInfo->SD_cid.Reserved2 = 1;
return 0;
}
/****************************************************************************/ /**
* @brief SD_ReadSingleBlock
*
*
*******************************************************************************/
uint8_t SD_ReadBlock(uint32_t sector, uint8_t *buffer, uint32_t num)
{
uint8_t rx;
uint8_t t_0xFF;
SPI_CS_WriteBit(0);
/* sector to byte */
if (SD_CardInfo.CardType != SD_TYPE_V2HC) {
sector = sector << 9;
}
if (num == 1) {
rx = SD_SendCommand(CMD17, sector, 0);
if (rx) {
MSG("SD CMD17 err:%02X\r\n", rx);
return rx;
}
rx = SD_ReceiveData(buffer, 512, RELEASE);
if (rx != 0) {
MSG("SD sing read err:%02X\r\n", rx);
return rx;
}
} else {
rx = SD_SendCommand(CMD18, sector, 0);
if (rx) {
MSG("SD CMD18 err:%02X\r\n", rx);
return rx;
}
while (num--) {
rx = SD_ReceiveData(buffer, 512, NO_RELEASE);
if (rx != 0) {
MSG("SD read err:%02X\r\n", rx);
return rx;
}
buffer += 512;
}
rx = SD_SendCommand(CMD12, 0, 0);
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
}
return SUCCESS;
}
/****************************************************************************/ /**
* @brief SD_WriteSingleBlock
*
*
*******************************************************************************/
uint8_t SD_WriteBlock(uint32_t sector, uint8_t *data, uint32_t num)
{
uint8_t rx;
uint8_t t_0xFF;
/* sector to byte */
if (SD_CardInfo.CardType != SD_TYPE_V2HC) {
sector = sector << 9;
}
if (SD_GetResponse(0xFF)) {
return 1;
}
if (num == 1) {
rx = SD_SendCommand(CMD24, sector, 1);
if (rx) {
MSG("SD CMD24 err:%d\r\n", rx);
return rx;
}
SPI_CS_WriteBit(0);
rx = SD_SendBlock(data, 0xFE);
if (rx) {
MSG("write err\r\n");
SPI_CS_WriteBit(0);
return rx;
}
} else if (num > 1) {
if (SD_CardInfo.CardType != SD_TYPE_MMC) {
rx = SD_SendCommand(CMD55, 0, 1);
if (rx == 0) {
rx = SD_SendCommand(ACMD23, num, 1);
}
if (rx != 0) {
MSG("SD ACMD23 err:%d\r\n", rx);
return rx;
}
}
rx = SD_SendCommand(CMD25, sector, 1);
if (rx != 0) {
MSG("SD ACMD25 err:%d\r\n", rx);
return rx;
}
SPI_CS_WriteBit(0);
do {
rx = SD_SendBlock(data, 0xFC);
data += 512;
} while (--num && rx == 0);
rx = SD_SendBlock(data, 0xFD);
}
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
return 0;
}
/****************************************************************************/ /**
* @brief SD init
*
*
*
*
*******************************************************************************/
uint8_t SD_Init(SD_CardInfoTypedef *pCardInfo)
{
uint8_t rx;
uint8_t t_0xFF = 0xFF;
//uint8_t txbuff[6];
uint8_t rxbuff[6];
uint16_t retry = 0, i;
SD_SPI_Init();
SPI_CS_WriteBit(1);
/* low speed */
SD_SPI_SetSpeed(0);
if (SD_Idle_Sta()) {
MSG("SD IDLE err:%d\r\n", rx);
return ERROR;
} else {
MSG("SD IDLE success\r\n");
}
/* send CMD8 */
rx = SD_SendCommand_NoDeassert(CMD8, 0x1aa, 0x87);
/* sd card v1.0 */
if (rx == 0x05) {
pCardInfo->CardType = SD_TYPE_V1;
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* send CMD55+CMD41 sd init */
do {
rx = SD_SendCommand(CMD55, 0, 0);
if (rx != 0x01) {
MSG("sdv1 CMD55 err:%d\r\n", rx);
return rx;
}
rx = SD_SendCommand(ACMD41, 0, 0);
retry++;
} while (rx != 0x00 && retry < 100);
/* mmc card init */
if (retry >= 100) {
retry = 0;
do {
rx = SD_SendCommand(CMD1, 0, 0);
retry++;
} while (rx != 0x00 && retry < 100);
if (retry >= 100) {
MSG("sdv2 CMD1 timeout err:%d\r\n", rx);
return ERROR;
} else {
pCardInfo->CardType = SD_TYPE_MMC;
}
}
/* high speed */
SD_SPI_SetSpeed(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* set sector size */
rx = SD_SendCommand(CMD16, 512, 0xff);
if (rx != 0x00) {
MSG("sdv1 CMD16 err:%d\r\n", rx);
return rx;
}
}
/* sd card v2.0 */
else if (rx == 0x01) {
SPI_ReadWriteByte(&t_0xFF, rxbuff + 0, 1);
SPI_ReadWriteByte(&t_0xFF, rxbuff + 1, 1);
SPI_ReadWriteByte(&t_0xFF, rxbuff + 2, 1);
SPI_ReadWriteByte(&t_0xFF, rxbuff + 3, 1);
SPI_CS_WriteBit(1);
/* next 8 clocks */
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* 2.7V - 3.6V */
if (rxbuff[2] == 0x01 && rxbuff[3] == 0xAA) {
retry = 0;
do {
rx = SD_SendCommand(CMD55, 0, 0);
if (rx != 0x01) {
MSG("sdv2 CMD55 err:%d\r\n", rx);
return rx;
}
rx = SD_SendCommand(ACMD41, 0x40000000, 0);
retry++;
if (retry > 200) {
MSG("sdv2 CMD41 timeout err:%d\r\n", rx);
return rx;
}
} while (rx != 0);
/* send CMD58 */
rx = SD_SendCommand_NoDeassert(CMD58, 0, 0);
if (rx != 0X00) {
MSG("sdv2 CMD58 err:%d\r\n", rx);
return rx;
}
/* get OCR */
SPI_ReadWriteByte(&t_0xFF, rxbuff + 0, 1);
SPI_ReadWriteByte(&t_0xFF, rxbuff + 1, 1);
SPI_ReadWriteByte(&t_0xFF, rxbuff + 2, 1);
SPI_ReadWriteByte(&t_0xFF, rxbuff + 3, 1);
SPI_CS_WriteBit(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
/* bit32 CCS: 1-SDHC 0-SD2.0 */
if (rxbuff[0] & 0x40) {
pCardInfo->CardType = SD_TYPE_V2HC;
MSG("sdv2hc success\r\n");
} else {
pCardInfo->CardType = SD_TYPE_V2;
MSG("sdv2.0 success\r\n");
}
/* set sector size */
rx = SD_SendCommand(CMD16, 512, 0xff);
if (rx != 0x00) {
MSG("sdv1 CMD16 err:%d\r\n", rx);
}
/* high speed */
SD_SPI_SetSpeed(1);
SPI_ReadWriteByte(&t_0xFF, &rx, 1);
}
} else {
return 1;
}
MSG("sd init success\r\n");
SD_Get_CardInfo(pCardInfo);
MSG(" sd csd:");
for (i = 0; i < 4; i++) {
MSG("%X ", pCardInfo->SD_csd.CSD[i]);
}
MSG("end\r\n sd cid:");
for (i = 0; i < 4; i++) {
MSG("%X ", pCardInfo->SD_cid.CID[i]);
}
MSG("end\r\n");
MSG("SDHC CardBlockSize:%d Byte\r\n", (pCardInfo->CardBlockSize));
MSG("SDHC CardCapacity:%lld MByte\r\n", (SD_CardInfo.CardCapacity / 1024 / 1024));
return 0;
}

View File

@@ -0,0 +1,148 @@
/**
* @file bsp_spi_sd.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __SPI_SD_H__
#define __SPI_SD_H__
#define SPI_PIN_CS GPIO_PIN_10
//SD传输数据结束后是否释放总线宏定义
#define NO_RELEASE 0
#define RELEASE 1
// SD卡类型定义
#define SD_TYPE_MMC 0
#define SD_TYPE_V1 1
#define SD_TYPE_V2 2
#define SD_TYPE_V2HC 4
#define CMD0 0 // Resets the SD memory card.
#define CMD1 1 // Sends host capacity support information and activates the card's initialization process.
#define CMD8 8 // Sends SD Memory Card interface condition, which includes host supply voltage information and asks the card whether card supports voltage.
#define CMD9 9 // Addressed card sends its card specific data (CSD) on the CMD line.
#define CMD10 10 // Addressed card sends its card identification (CID) on the CMD line.
#define CMD12 12 // Forces the card to stop transmission.
#define CMD16 16 // Sets the block length (in bytes for SDSC) for all following block commands (read, write, lock).
// Default block length is fixed to 512 Bytes. Not effective for SDHS and SDXC
#define CMD17 17 // Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of fixed 512 bytes in case of SDHC and SDXC
#define CMD18 18 // Continuously transfers data blocks from card to host until interrupted by STOP_TRANSMISSION command
#define ACMD23 23 // Specify block count for CMD18 and CMD25
#define CMD24 24 // Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of fixed 512 bytes in case of SDHC and SDXC.
#define CMD25 25 // Continuously writes blocks of data until a STOP_TRANSMISSION follows.
#define ACMD41 41 //
#define CMD55 55 // Indicates to the card that the next command is an application specific command rather than a standard command.
#define CMD58 58 // get OCR
#define CMD59 59 // enable/disable crc
//数据写入回应字意义
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
//SD卡回应标记字
#define MSD_RESPONSE_NO_ERROR 0x00 // Card state is ready
#define MSD_IN_IDLE_STATE 0x01 // Card is in identification state
#define MSD_ERASE_RESET 0x02 // Card is in standby state
#define MSD_ILLEGAL_COMMAND 0x04 // Card is in transfer state
#define MSD_COM_CRC_ERROR 0x08 // Card is sending an operation
#define MSD_ERASE_SEQUENCE_ERROR 0x10 // Card is receiving operation information
#define MSD_ADDRESS_ERROR 0x20 // Card is in programming state
#define MSD_PARAMETER_ERROR 0x40 // Card is disconnected
#define MSD_RESPONSE_FAILURE 0xFF // Card is in error state
typedef struct
{
uint8_t CSD[16]; /*!< SD card specific data table */
uint8_t CSDStruct; /*!< CSD structure */
uint8_t SysSpecVersion; /*!< System specification version */
uint8_t Reserved1; /*!< Reserved */
uint8_t TAAC; /*!< Data read access time 1 */
uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */
uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
uint16_t CardComdClasses; /*!< Card command classes */
uint8_t RdBlockLen; /*!< Max. read data block length */
uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
uint8_t WrBlockMisalign; /*!< Write block misalignment */
uint8_t RdBlockMisalign; /*!< Read block misalignment */
uint8_t DSRImpl; /*!< DSR implemented */
uint8_t Reserved2; /*!< Reserved */
uint32_t DeviceSize; /*!< Device Size */
uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
uint8_t DeviceSizeMul; /*!< Device size multiplier */
uint8_t EraseGrSize; /*!< Erase group size */
uint8_t EraseGrMul; /*!< Erase group size multiplier */
uint8_t WrProtectGrSize; /*!< Write protect group size */
uint8_t WrProtectGrEnable; /*!< Write protect group enable */
uint8_t ManDeflECC; /*!< Manufacturer default ECC */
uint8_t WrSpeedFact; /*!< Write speed factor */
uint8_t MaxWrBlockLen; /*!< Max. write data block length */
uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
uint8_t Reserved3; /*!< Reserved */
uint8_t ContentProtectAppli; /*!< Content protection application */
uint8_t FileFormatGrouop; /*!< File format group */
uint8_t CopyFlag; /*!< Copy flag (OTP) */
uint8_t PermWrProtect; /*!< Permanent write protection */
uint8_t TempWrProtect; /*!< Temporary write protection */
uint8_t FileFormat; /*!< File format */
uint8_t ECC; /*!< ECC code */
uint8_t CSD_CRC; /*!< CSD CRC */
uint8_t Reserved4; /*!< Always 1 */
} SD_CSDTypedef;
typedef struct
{
uint8_t CID[16]; /*!< SD card identification number table */
uint8_t ManufacturerID; /*!< Manufacturer ID */
uint16_t OEM_AppliID; /*!< OEM/Application ID */
uint32_t ProdName1; /*!< Product Name part1 */
uint8_t ProdName2; /*!< Product Name part2 */
uint8_t ProdRev; /*!< Product Revision */
uint32_t ProdSN; /*!< Product Serial Number */
uint8_t Reserved1; /*!< Reserved1 */
uint16_t ManufactDate; /*!< Manufacturing Date */
uint8_t CID_CRC; /*!< CID CRC */
uint8_t Reserved2; /*!< Always 1 */
} SD_CIDTypedef;
typedef struct SD_CardInfoTypedef {
SD_CSDTypedef SD_csd; /*!< SD card specific data register */
SD_CIDTypedef SD_cid; /*!< SD card identification number register */
uint64_t CardCapacity; /*!< Card capacity */
uint32_t CardBlockSize; /*!< Card block size */
uint16_t RCA; /*!< SD relative card address */
uint8_t CardType; /*!< SD card type */
} SD_CardInfoTypedef;
extern SD_CardInfoTypedef SD_CardInfo;
uint8_t SD_Init(SD_CardInfoTypedef *pCardInfo);
uint8_t SD_Get_CardInfo(SD_CardInfoTypedef *pCardInfo);
uint8_t SD_ReadBlock(uint32_t sector, uint8_t *buffer, uint32_t num);
uint8_t SD_WriteBlock(uint32_t sector, uint8_t *buffer, uint32_t num);
#endif

View File

@@ -0,0 +1,37 @@
/**
* @file touch.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "touch.h"
void touch_init(void)
{
#if defined(TOUCH_CONTROLLER_XPT2046)
xpt2046_init();
#endif
}
uint8_t touch_read(int16_t *x, int16_t *y)
{
#if defined(TOUCH_CONTROLLER_XPT2046)
return xpt2046_read(x, y);
#endif
}

View File

@@ -0,0 +1,40 @@
/**
* @file touch.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _TOUCH_H_
#define _TOUCH_H_
#define TOUCH_CONTROLLER_XPT2046
#ifdef TOUCH_CONTROLLER_XPT2046
#include "xpt2046.h"
#endif
#ifdef __cplusplus
extern "C"{
#endif
void touch_init(void);
uint8_t touch_read(int16_t *x, int16_t *y);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,243 @@
/**
* @file xip2046.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_spi.h"
#include "hal_gpio.h"
#include "bl702_spi.h"
#include "xpt2046.h"
// #include "lvgl.h"
#define CMD_Y_READ 0b10010000 // NOTE: XPT2046 data sheet says this is actually Y
#define CMD_X_READ 0b11010000 // NOTE: XPT2046 data sheet says this is actually X
#define CMD_Z1_READ 0b10110000
#define CMD_Z2_READ 0b11000000
struct device *touch_spi;
uint16_t avg_buf_x[XPT2046_AVG_NUM];
uint16_t avg_buf_y[XPT2046_AVG_NUM];
static void xpt2046_spi_read_reg(uint8_t reg, uint8_t *data, uint8_t byte_count)
{
gpio_write(TOUCH_PIN_CS, 0);
spi_transmit(touch_spi, &reg, 1, 0);
spi_receive(touch_spi, data, byte_count, 0);
gpio_write(TOUCH_PIN_CS, 1);
}
// static void xpt2046_spi_write_reg(uint8_t reg, uint8_t* data, uint8_t byte_count)
// {
// gpio_write(TOUCH_PIN_CS,0);
// spi_transmit(touch_spi, &reg, 1, 0);
// spi_transmit(touch_spi, data, byte_count,0);
// gpio_write(TOUCH_PIN_CS,1);
// }
static uint16_t xpt2046_cmd(uint8_t cmd)
{
uint8_t data[2];
xpt2046_spi_read_reg(cmd, data, 2);
uint16_t val = ((data[0] << 8) | data[1]) >> 3;
return val;
}
/******************************************************************************
* @brief xpt2046 touchpad init
*
* @param None
*
* @return None
*
*******************************************************************************/
void xpt2046_init(void)
{
gpio_set_mode(TOUCH_PIN_CS, GPIO_OUTPUT_MODE);
gpio_write(TOUCH_PIN_CS, 1);
touch_spi = device_find("spi0");
if (touch_spi) {
device_close(touch_spi);
} else {
spi_register(SPI0_INDEX, "spi0");
touch_spi = device_find("spi0");
}
if (touch_spi) {
device_open(touch_spi, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
}
}
/******************************************************************************
* @brief xpt2046_touch_detect_t
*
* @param
*
* @return
*
*******************************************************************************/
static uint8_t xpt2048_is_touch_detected()
{
// check pressure if we are pressure or IRQ and pressure
uint16_t z1 = xpt2046_cmd(CMD_Z1_READ);
uint16_t z2 = xpt2046_cmd(CMD_Z2_READ);
// this is not what the confusing datasheet says but it seems to
// be enough to detect real touches on the panel
uint16_t z = z1 + 4096 - z2;
if (z > XPT2046_TOUCH_THRESHOLD) {
return 1;
} else {
return 0;
}
}
/******************************************************************************
* @brief xpt2046_ads_get
*
* @param
*
* @return
*
*******************************************************************************/
static uint8_t xpt2046_ads_get(int16_t *x, int16_t *y)
{
for (uint8_t i = 0; i < XPT2046_AVG_NUM; i++) {
if (xpt2048_is_touch_detected() == 0) {
return 0;
}
avg_buf_x[i] = xpt2046_cmd(CMD_X_READ);
avg_buf_y[i] = xpt2046_cmd(CMD_Y_READ);
}
int16_t x_min = avg_buf_x[0], x_max = avg_buf_x[0];
int16_t y_min = avg_buf_y[0], y_max = avg_buf_y[0];
int32_t x_sum = avg_buf_x[0], y_sum = avg_buf_y[0];
for (uint8_t i = 1; i < XPT2046_AVG_NUM; i++) {
if (x_min < avg_buf_x[i]) {
x_min = avg_buf_x[i];
}
if (x_max > avg_buf_x[i]) {
x_max = avg_buf_x[i];
}
if (y_min < avg_buf_y[i]) {
y_min = avg_buf_y[i];
}
if (y_max > avg_buf_y[i]) {
y_max = avg_buf_y[i];
}
x_sum += avg_buf_x[i];
y_sum += avg_buf_y[i];
}
if (x_max - x_min > 40 || y_max - y_min > 50) {
return 0;
}
*x = (x_sum - x_min - x_max) / (XPT2046_AVG_NUM - 2);
*y = (y_sum - y_min - y_max) / (XPT2046_AVG_NUM - 2);
return 2;
}
/******************************************************************************
* @brief xpt2046_corr
*
* @param
*
* @return
*
*******************************************************************************/
static uint8_t xpt2046_adc2xy(int16_t *x, int16_t *y)
{
if ((*x) > XPT2046_X_MIN) {
(*x) -= XPT2046_X_MIN;
} else {
(*x) = 0;
}
if ((*y) > XPT2046_Y_MIN) {
(*y) -= XPT2046_Y_MIN;
} else {
(*y) = 0;
}
(*x) = (uint32_t)((uint32_t)(*x) * 240) /
(XPT2046_X_MAX - XPT2046_X_MIN);
(*y) = (uint32_t)((uint32_t)(*y) * 320) /
(XPT2046_Y_MAX - XPT2046_Y_MIN);
return 1;
}
/******************************************************************************
* @brief xpt2046_read
*
* @param
*
* @return
*
*******************************************************************************/
uint8_t xpt2046_read(int16_t *x, int16_t *y)
{
static int16_t xt = 0, yt = 0;
static uint8_t avg_last = 0;
int16_t x1, y1;
if (xpt2046_ads_get(&x1, &y1) == 0) {
goto end;
}
if (xpt2046_adc2xy(&x1, &y1) == 0) {
goto end;
}
if (avg_last == 0) {
avg_last = 1;
return 0;
} else {
avg_last = 2;
xt = x1;
*x = x1;
yt = y1;
*y = y1;
return 1;
}
end:
if (avg_last == 2) {
avg_last = 1;
*x = xt;
*y = yt;
return 1;
} else {
avg_last = 0;
return 0;
}
}

View File

@@ -0,0 +1,54 @@
/**
* @file xip2046.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _XPT2046_H_
#define _XPT2046_H_
#include "bflb_platform.h"
#define TOUCH_PIN_CS GPIO_PIN_11
//#define TOUCH_PIN_PEN GPIO_PIN_11
#define XPT2046_TOUCH_THRESHOLD 500 // Threshold for touch detection
#define XPT2046_AVG_NUM 5
#define TOUCH_ROT_NONE 0
#define TOUCH_ROT_90 1
#define TOUCH_ROT_180 2
#define TOUCH_ROT_270 3
#define XPT2046_X_MIN 310
#define XPT2046_Y_MIN 175
#define XPT2046_X_MAX 3850
#define XPT2046_Y_MAX 3700
extern struct device *touch_spi;
#ifdef __cplusplus
extern "C"{
#endif
void xpt2046_init(void);
uint8_t xpt2046_read(int16_t *x, int16_t *y);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,192 @@
/**
* @file uart_interface.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "hal_gpio.h"
#include "uart_interface.h"
#include "hal_usb.h"
#include "hal_dma.h"
#define USB_OUT_RINGBUFFER_SIZE (8 * 1024)
#define UART_RX_RINGBUFFER_SIZE (8 * 1024)
#define UART_TX_DMA_SIZE (4095)
uint8_t usb_rx_mem[USB_OUT_RINGBUFFER_SIZE] __attribute__((section(".system_ram")));
uint8_t uart_rx_mem[UART_RX_RINGBUFFER_SIZE] __attribute__((section(".system_ram")));
uint8_t src_buffer[UART_TX_DMA_SIZE] __attribute__((section(".tcm_code")));
struct device *uart1;
struct device *dma_ch2;
Ring_Buffer_Type usb_rx_rb;
Ring_Buffer_Type uart1_rx_rb;
void uart_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (state == UART_EVENT_RX_FIFO) {
if (size && size < Ring_Buffer_Get_Empty_Length(&uart1_rx_rb)) {
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
} else {
MSG("RF OV\r\n");
}
} else if (state == UART_EVENT_RTO) {
if (size && size < Ring_Buffer_Get_Empty_Length(&uart1_rx_rb)) {
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
} else {
MSG("RTO OV\r\n");
}
} else if (state == UART_RX_FER_IT) {
MSG("RX ERR\r\n");
}
}
void uart1_init(void)
{
uart_register(UART1_INDEX, "uart1");
uart1 = device_find("uart1");
if (uart1) {
// device_open(uart1, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
// device_set_callback(uart1, uart_irq_callback);
// device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
}
dma_register(DMA0_CH2_INDEX, "ch2");
dma_ch2 = device_find("ch2");
if (dma_ch2) {
DMA_DEV(dma_ch2)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch2)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch2)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch2)->dst_req = DMA_REQUEST_UART1_TX;
DMA_DEV(dma_ch2)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch2)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch2)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch2)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch2, 0);
}
}
void uart1_config(uint32_t baudrate, uart_databits_t databits, uart_parity_t parity, uart_stopbits_t stopbits)
{
device_close(uart1);
UART_DEV(uart1)->baudrate = baudrate;
UART_DEV(uart1)->stopbits = stopbits;
UART_DEV(uart1)->parity = parity;
UART_DEV(uart1)->databits = (databits - 5);
device_open(uart1, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
device_set_callback(uart1, uart_irq_callback);
device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
Ring_Buffer_Reset(&usb_rx_rb);
Ring_Buffer_Reset(&uart1_rx_rb);
}
static uint8_t uart1_dtr;
static uint8_t uart1_rts;
void uart1_set_dtr_rts(uint8_t dtr, uint8_t rts)
{
uart1_dtr = dtr;
uart1_rts = rts;
}
void uart1_dtr_init(void)
{
gpio_set_mode(uart1_dtr, GPIO_OUTPUT_MODE);
}
void uart1_rts_init(void)
{
gpio_set_mode(uart1_rts, GPIO_OUTPUT_MODE);
}
void uart1_dtr_deinit(void)
{
gpio_set_mode(uart1_dtr, GPIO_INPUT_MODE);
}
void uart1_rts_deinit(void)
{
gpio_set_mode(uart1_rts, GPIO_INPUT_MODE);
}
void dtr_pin_set(uint8_t status)
{
gpio_write(uart1_dtr, status);
}
void rts_pin_set(uint8_t status)
{
gpio_write(uart1_rts, status);
}
void ringbuffer_lock()
{
cpu_global_irq_disable();
}
void ringbuffer_unlock()
{
cpu_global_irq_enable();
}
void uart_ringbuffer_init(void)
{
/* init mem for ring_buffer */
memset(usb_rx_mem, 0, USB_OUT_RINGBUFFER_SIZE);
memset(uart_rx_mem, 0, UART_RX_RINGBUFFER_SIZE);
/* init ring_buffer */
Ring_Buffer_Init(&usb_rx_rb, usb_rx_mem, USB_OUT_RINGBUFFER_SIZE, ringbuffer_lock, ringbuffer_unlock);
Ring_Buffer_Init(&uart1_rx_rb, uart_rx_mem, UART_RX_RINGBUFFER_SIZE, ringbuffer_lock, ringbuffer_unlock);
}
static dma_control_data_t uart_dma_ctrl_cfg = {
.bits.fix_cnt = 0,
.bits.dst_min_mode = 0,
.bits.dst_add_mode = 0,
.bits.SI = 1,
.bits.DI = 0,
.bits.SWidth = DMA_TRANSFER_WIDTH_8BIT,
.bits.DWidth = DMA_TRANSFER_WIDTH_8BIT,
.bits.SBSize = 0,
.bits.DBSize = 0,
.bits.I = 0,
.bits.TransferSize = 4095
};
static dma_lli_ctrl_t uart_lli_list = {
.src_addr = (uint32_t)src_buffer,
.dst_addr = DMA_ADDR_UART1_TDR,
.nextlli = 0
};
void uart_send_from_ringbuffer(void)
{
if (Ring_Buffer_Get_Length(&usb_rx_rb)) {
if (!dma_channel_check_busy(dma_ch2)) {
uint32_t avalibleCnt = Ring_Buffer_Read(&usb_rx_rb, src_buffer, UART_TX_DMA_SIZE);
if (avalibleCnt) {
dma_channel_stop(dma_ch2);
uart_dma_ctrl_cfg.bits.TransferSize = avalibleCnt;
memcpy(&uart_lli_list.cfg, &uart_dma_ctrl_cfg, sizeof(dma_control_data_t));
dma_channel_update(dma_ch2, (void *)((uint32_t)&uart_lli_list));
dma_channel_start(dma_ch2);
}
}
}
}

View File

@@ -0,0 +1,44 @@
/**
* @file uart_interface.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __UART_IF_H__
#define __UART_IF_H__
#include "hal_uart.h"
#include "ring_buffer.h"
extern Ring_Buffer_Type usb_rx_rb;
extern Ring_Buffer_Type uart1_rx_rb;
void uart1_init(void);
void uart1_config(uint32_t baudrate, uart_databits_t databits, uart_parity_t parity, uart_stopbits_t stopbits);
void uart1_set_dtr_rts(uint8_t dtr, uint8_t rts);
void uart1_dtr_init(void);
void uart1_rts_init(void);
void uart1_dtr_deinit(void);
void uart1_rts_deinit(void);
void dtr_pin_set(uint8_t status);
void rts_pin_set(uint8_t status);
void uart_ringbuffer_init(void);
void uart_send_from_ringbuffer(void);
#endif

View File

@@ -0,0 +1,78 @@
/**
* @file usb_dc.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_usb.h"
#include "stdbool.h"
#include "usbd_core.h"
struct device *usb;
static void usb_dc_event_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
usbd_event_notify_handler(state, args);
}
struct device *usb_dc_init(void)
{
usb_dc_register(USB_INDEX, "usb");
usb = device_find("usb");
device_set_callback(usb, usb_dc_event_callback);
device_open(usb, 0);
return usb;
}
int usbd_set_address(const uint8_t addr)
{
return usb_dc_set_dev_address(addr);
}
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
{
return usb_dc_ep_open(usb, (const struct usb_dc_ep_cfg *)ep_cfg);
}
int usbd_ep_close(const uint8_t ep)
{
return usb_dc_ep_close(ep);
}
int usbd_ep_set_stall(const uint8_t ep)
{
return usb_dc_ep_set_stall(ep);
}
int usbd_ep_clear_stall(const uint8_t ep)
{
return usb_dc_ep_clear_stall(ep);
}
int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
{
return usb_dc_ep_is_stalled(usb, ep, stalled);
}
int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
{
return usb_dc_ep_write(usb, ep, data, data_len, ret_bytes);
}
int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
{
return usb_dc_ep_read(usb, ep, data, max_data_len, read_bytes);
}

View File

@@ -0,0 +1,588 @@
/**
* @file wm8978.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
#include "hal_i2c.h"
#include "bsp_wm8978.h"
struct device *wm8978_i2c = NULL;
#define GET_REG_VAL(reg, val, off, bits) \
{ \
reg &= ~(((1 << bits) - 1) << off); \
reg |= ((val & ((1 << bits) - 1)) << off); \
}
//WM8978寄存器值缓存区(总共58个寄存器,0~57),占用116字节内存
//因为WM8978的IIC操作不支持读操作,所以在本地保存所有寄存器值
//写WM8978寄存器时,同步更新到本地寄存器值,读寄存器时,直接返回本地保存的寄存器值.
//注意:WM8978的寄存器值是9位的,所以要用u16来存储.
volatile static uint16_t WM8978_RegCash[] = {
0X0000, 0X0000, 0X0000, 0X0000, 0X0050, 0X0000, 0X0140, 0X0000,
0X0000, 0X0000, 0X0000, 0X00FF, 0X00FF, 0X0000, 0X0100, 0X00FF,
0X00FF, 0X0000, 0X012C, 0X002C, 0X002C, 0X002C, 0X002C, 0X0000,
0X0032, 0X0000, 0X0000, 0X0000, 0X0000, 0X0000, 0X0000, 0X0000,
0X0038, 0X000B, 0X0032, 0X0000, 0X0008, 0X000C, 0X0093, 0X00E9,
0X0000, 0X0000, 0X0000, 0X0000, 0X0003, 0X0010, 0X0010, 0X0100,
0X0100, 0X0002, 0X0001, 0X0001, 0X0039, 0X0039, 0X0039, 0X0039,
0X0001, 0X0001
};
void wm8978_i2c_init(void)
{
i2c_register(I2C0_INDEX, "i2c");
wm8978_i2c = device_find("i2c");
if (wm8978_i2c) {
device_open(wm8978_i2c, 0);
}
}
uint16_t WM8978_ReadReg(uint8_t RegAddr)
{
return WM8978_RegCash[RegAddr];
}
/**
* @brief 写寄存器寄存器是9bit的,最高一位是地址的最低一位
*
* @param RegAddr
* @param Value
* @return uint8_t
*/
uint8_t WM8978_WriteReg(uint8_t RegAddr, uint16_t Value)
{
i2c_msg_t msg1;
int flag = 0;
uint8_t val = Value & 0XFF;
msg1.slaveaddr = WM8978_ADDR,
msg1.len = 1,
msg1.buf = &val;
msg1.flags = SUB_ADDR_1BYTE | I2C_WR;
msg1.subaddr = (RegAddr << 1) | ((Value >> 8) & 0X01);
bflb_platform_delay_ms(10);
flag = i2c_transfer(wm8978_i2c, &msg1, 1);
if (flag) {
MSG("[E]TYPE[%d] | REG[%d] | %04x\r\n", flag, RegAddr, Value);
return 1;
}
WM8978_RegCash[RegAddr] = Value; //保存寄存器值到本地
return 0;
}
/**
* @brief WM8978_SetVolume,(0-63)
*
* @param Volume
*/
void WM8978_SetVolume(uint8_t Volume)
{
uint16_t regV;
Volume = 0x3F;
regV = Volume;
//耳机左右声道音量设置
WM8978_WriteReg(52, regV);
WM8978_WriteReg(53, regV | (1 << 8)); //同步更新(SPKVU=1)
//喇叭左右声道音量设置
WM8978_WriteReg(54, regV);
WM8978_WriteReg(55, regV | (1 << 8));
}
uint8_t WM8978_ReadVolume(void)
{
return (uint8_t)(WM8978_ReadReg(52) & 0x3F);
}
void WM8978_MIC_Gain(uint8_t Gain)
{
Gain &= 0x3F;
WM8978_WriteReg(45, Gain);
WM8978_WriteReg(46, Gain | (1 << 8));
}
/**
*设置I2S工作模式
*fmt:0,LSB(右对齐);1,MSB(左对齐);2,飞利浦标准I2S;3,PCM/DSP;
*len:0,16位;1,20位;2,24位;3,32位;
*/
void WM8978_I2S_Cfg(uint8_t fmt, uint8_t len)
{
//限定范围
fmt &= 0x03;
len &= 0x03;
//R4,WM8978工作模式设置
WM8978_WriteReg(4, (fmt << 3) | (len << 5));
}
/**
*WM8978 DAC/ADC配置
*adcen:adc使能(1)/关闭(0)
*dacen:dac使能(1)/关闭(0)
*/
void WM8978_ADDA_Cfg(uint8_t dacen, uint8_t adcen)
{
uint16_t regval;
regval = WM8978_ReadReg(3);
if (dacen) {
//R3最低2个位设置为1,开启DACR&DACL
regval |= 3 << 0;
} else {
//R3最低2个位清零,关闭DACR&DACL.
regval &= ~(3 << 0);
}
WM8978_WriteReg(3, regval);
regval = WM8978_ReadReg(2);
if (adcen) {
//R2最低2个位设置为1,开启ADCR&ADCL
regval |= 3 << 0;
} else {
//R2最低2个位清零,关闭ADCR&ADCL.
regval &= ~(3 << 0);
}
WM8978_WriteReg(2, regval);
}
/**
*WM8978 L2/R2(也就是Line In)增益设置(L2/R2-->ADC输入部分的增益)
*gain:0~7,0表示通道禁止,1~7,对应-12dB~6dB,3dB/Step
*/
void WM8978_LINEIN_Gain(uint8_t gain)
{
uint16_t regval;
gain &= 0X07;
regval = WM8978_ReadReg(47);
//清除原来的设置
regval &= ~(7 << 4);
WM8978_WriteReg(47, regval | gain << 4);
regval = WM8978_ReadReg(48);
//清除原来的设置
regval &= ~(7 << 4);
WM8978_WriteReg(48, regval | gain << 4);
}
/**
*WM8978 AUXR,AUXL(PWM音频部分)增益设置(AUXR/L-->ADC输入部分的增益)
*gain:0~7,0表示通道禁止,1~7,对应-12dB~6dB,3dB/Step
*/
void WM8978_AUX_Gain(uint8_t gain)
{
uint16_t regval;
gain &= 0X07;
regval = WM8978_ReadReg(47);
//清除原来的设置
regval &= ~(7 << 0);
WM8978_WriteReg(47, regval | gain << 0);
regval = WM8978_ReadReg(48);
//清除原来的设置
regval &= ~(7 << 0);
WM8978_WriteReg(48, regval | gain << 0);
}
/*
*WM8978 输入通道配置
*micen:MIC开启(1)/关闭(0)
*lineinen:Line In开启(1)/关闭(0)
*auxen:aux开启(1)/关闭(0)
*/
void WM8978_Input_Cfg(uint8_t micen, uint8_t lineinen, uint8_t auxen)
{
uint16_t regval;
regval = WM8978_ReadReg(2);
if (micen) {
//开启INPPGAENR,INPPGAENL(MIC的PGA放大)
regval |= 3 << 2;
} else {
//关闭INPPGAENR,INPPGAENL.
regval &= ~(3 << 2);
}
WM8978_WriteReg(2, regval);
regval = WM8978_ReadReg(44);
if (micen) {
//开启LIN2INPPGA,LIP2INPGA,RIN2INPPGA,RIP2INPGA.
regval |= 3 << 4 | 3 << 0;
} else {
//关闭LIN2INPPGA,LIP2INPGA,RIN2INPPGA,RIP2INPGA.
regval &= ~(3 << 4 | 3 << 0);
}
WM8978_WriteReg(44, regval);
if (lineinen) {
//LINE IN 0dB增益
WM8978_LINEIN_Gain(5);
} else {
//关闭LINE IN
WM8978_LINEIN_Gain(0);
}
if (auxen) {
//AUX 6dB增益
WM8978_AUX_Gain(7);
} else {
//关闭AUX输入
WM8978_AUX_Gain(0);
}
}
/**
*WM8978 输出配置
*dacen:DAC输出(放音)开启(1)/关闭(0)
*bpsen:Bypass输出(录音,包括MIC,LINE IN,AUX等)开启(1)/关闭(0)
*/
void WM8978_Output_Cfg(uint8_t dacen, uint8_t bpsen)
{
uint16_t regval = 0;
if (dacen) {
//DAC输出使能
regval |= 1 << 0;
}
if (bpsen) {
//BYPASS使能
regval |= 1 << 1;
//0dB增益
regval |= 5 << 2;
}
WM8978_WriteReg(50, regval);
WM8978_WriteReg(51, regval);
}
/**
*设置耳机左右声道音量
*voll:左声道音量(0~63)
*volr:右声道音量(0~63)
*/
void WM8978_HPvol_Set(uint8_t voll, uint8_t volr)
{
//限定范围
voll &= 0X3F;
volr &= 0X3F;
//音量为0时,直接mute
if (voll == 0) {
voll |= 1 << 6;
}
//音量为0时,直接mute
if (volr == 0) {
volr |= 1 << 6;
}
//R52,耳机左声道音量设置
WM8978_WriteReg(52, voll);
//R53,耳机右声道音量设置,同步更新(HPVU=1)
WM8978_WriteReg(53, volr | (1 << 8));
}
/**
*设置喇叭音量
*voll:左声道音量(0~63)
*/
void WM8978_SPKvol_Set(uint8_t volx)
{
//限定范围
volx &= 0x3F;
//音量为0时,直接mute
if (volx == 0)
volx |= 1 << 6;
//R54,喇叭左声道音量设置
WM8978_WriteReg(54, volx);
//R55,喇叭右声道音量设置,同步更新(SPKVU=1)
WM8978_WriteReg(55, volx | (1 << 8));
}
uint8_t WM8978_Init(void)
{
uint8_t ucFun_res = 0;
wm8978_i2c_init();
ucFun_res |= WM8978_WriteReg(0, 0x0000); //向0寄存器写入任意值就可以软件复位
//先把声音关到最小,防止噪音
WM8978_HPvol_Set(0, 0);
WM8978_SPKvol_Set(0);
ucFun_res |= WM8978_WriteReg(1, 0x001B); //R1,MICEN设置为1(MIC使能),BIASEN设置为1(模拟器工作),VMIDSEL[1:0]设置为:11(5K)
ucFun_res |= WM8978_WriteReg(2, 0x01B0); //R2,ROUT1,LOUT1输出使能(耳机可以工作),BOOSTENR,BOOSTENL使能
ucFun_res |= WM8978_WriteReg(3, 0x006C); //R3,LOUT2,ROUT2输出使能(喇叭工作),RMIX,LMIX使能
ucFun_res |= WM8978_WriteReg(6, 0x0000); //R6,MCLK由外部提供
ucFun_res |= WM8978_WriteReg(43, 1 << 4); //R43,INVROUT2反向,驱动喇叭
ucFun_res |= WM8978_WriteReg(47, 1 << 8); //R47设置,PGABOOSTL,左通道MIC获得20倍增益
ucFun_res |= WM8978_WriteReg(48, 1 << 8); //R48设置,PGABOOSTR,右通道MIC获得20倍增益
ucFun_res |= WM8978_WriteReg(49, 1 << 1); //R49,TSDEN,开启过热保护
ucFun_res |= WM8978_WriteReg(10, 1 << 3); //R10,SOFTMUTE关闭,128x采样,最佳SNR
ucFun_res |= WM8978_WriteReg(14, 1 << 3); //R14,ADC 128x采样率
return ucFun_res;
}
/**
* @brief 仅播放模式
*
*/
void WM8978_PlayMode(void)
{
WM8978_ADDA_Cfg(1, 0); //开启DAC
WM8978_Input_Cfg(0, 0, 0); //关闭输入通道
WM8978_Output_Cfg(1, 0); //开启DAC输出
WM8978_HPvol_Set(20, 20);
WM8978_SPKvol_Set(0x3F);
WM8978_MIC_Gain(0);
WM8978_I2S_Cfg(1, 0); //设置I2S接口模式,左对齐16位
}
/**
* @brief 仅录音模式
*
*/
void WM8978_RecoMode(void)
{
WM8978_ADDA_Cfg(0, 1); //开启ADC
WM8978_Input_Cfg(1, 0, 0); //开启输入通道(MIC)
WM8978_Output_Cfg(0, 1); //开启BYPASS输出
WM8978_HPvol_Set(0, 0);
WM8978_SPKvol_Set(0);
WM8978_MIC_Gain(50); //MIC增益设置
WM8978_I2S_Cfg(1, 0); //设置I2S接口模式,左对齐16位
}
//设置3D环绕声
//depth:0~15(3D强度,0最弱,15最强)
void WM8978_3D_Set(uint8_t depth)
{
depth &= 0XF; //限定范围
WM8978_Write_Reg(41, depth); //R41,3D环绕设置
}
//设置EQ/3D作用方向
//dir:0,在ADC起作用
// 1,在DAC起作用(默认)
void WM8978_EQ_3D_Dir(uint8_t dir)
{
uint16_t regval;
regval = WM8978_Read_Reg(0X12);
if (dir)
regval |= 1 << 8;
else
regval &= ~(1 << 8);
WM8978_Write_Reg(18, regval); //R18,EQ1的第9位控制EQ/3D方向
}
//设置EQ1
//cfreq:截止频率,0~3,分别对应:80/105/135/175Hz
//gain:增益,0~24,对应-12~+12dB
void WM8978_EQ1_Set(uint8_t cfreq, uint8_t gain)
{
uint16_t regval;
cfreq &= 0X3; //限定范围
if (gain > 24)
gain = 24;
gain = 24 - gain;
regval = WM8978_Read_Reg(18);
regval &= 0X100;
regval |= cfreq << 5; //设置截止频率
regval |= gain; //设置增益
WM8978_Write_Reg(18, regval); //R18,EQ1设置
}
//设置EQ2
//cfreq:中心频率,0~3,分别对应:230/300/385/500Hz
//gain:增益,0~24,对应-12~+12dB
void WM8978_EQ2_Set(uint8_t cfreq, uint8_t gain)
{
uint16_t regval = 0;
cfreq &= 0X3; //限定范围
if (gain > 24)
gain = 24;
gain = 24 - gain;
regval |= cfreq << 5; //设置截止频率
regval |= gain; //设置增益
WM8978_Write_Reg(19, regval); //R19,EQ2设置
}
//设置EQ3
//cfreq:中心频率,0~3,分别对应:650/850/1100/1400Hz
//gain:增益,0~24,对应-12~+12dB
void WM8978_EQ3_Set(uint8_t cfreq, uint8_t gain)
{
uint16_t regval = 0;
cfreq &= 0X3; //限定范围
if (gain > 24)
gain = 24;
gain = 24 - gain;
regval |= cfreq << 5; //设置截止频率
regval |= gain; //设置增益
WM8978_Write_Reg(20, regval); //R20,EQ3设置
}
//设置EQ4
//cfreq:中心频率,0~3,分别对应:1800/2400/3200/4100Hz
//gain:增益,0~24,对应-12~+12dB
void WM8978_EQ4_Set(uint8_t cfreq, uint8_t gain)
{
uint16_t regval = 0;
cfreq &= 0X3; //限定范围
if (gain > 24)
gain = 24;
gain = 24 - gain;
regval |= cfreq << 5; //设置截止频率
regval |= gain; //设置增益
WM8978_Write_Reg(21, regval); //R21,EQ4设置
}
//设置EQ5
//cfreq:中心频率,0~3,分别对应:5300/6900/9000/11700Hz
//gain:增益,0~24,对应-12~+12dB
void WM8978_EQ5_Set(uint8_t cfreq, uint8_t gain)
{
uint16_t regval = 0;
cfreq &= 0X3; //限定范围
if (gain > 24)
gain = 24;
gain = 24 - gain;
regval |= cfreq << 5; //设置截止频率
regval |= gain; //设置增益
WM8978_Write_Reg(22, regval); //R22,EQ5设置
}
/**
* @brief config wm8978 master or slaver mode
*
* @param master 0: slaver mode
* 1: master mode
*
* @return 0: false
* 1: true
*/
bool wm8978_ms_set(bool master)
{
uint16_t regval = 0;
if (master > 2) {
return false;
}
regval = WM8978_ReadReg(6);
GET_REG_VAL(regval, master, 0, 1);
if (!WM8978_WriteReg(6, regval)) {
return true;
} else {
return false;
}
return true;
}
/**
* @brief
*
* @param div
*
* @return 0: false
* 1: true
*/
bool wm8978_bclkdiv_set(uint8_t div)
{
uint16_t regval = 0;
if (div > 7) {
return false;
}
regval = WM8978_ReadReg(6);
GET_REG_VAL(regval, div, 2, 3);
if (!WM8978_WriteReg(6, regval)) {
return true;
} else {
return false;
}
}
/**
* @brief
*
* @param div
*
* @return 0: false
* 1: true
*/
bool wm8978_mclkdiv_set(uint8_t div)
{
uint16_t regval = 0;
if (div > 7) {
return false;
}
regval = WM8978_ReadReg(6);
GET_REG_VAL(regval, div, 5, 3);
if (!WM8978_WriteReg(6, regval)) {
return true;
} else {
return false;
}
}
/**
* @brief select clk source for all internal operation
*
* @param clksel 0: mclk
* 1: pll out
*
* @return 0: false
* 1: true
*/
bool wm8978_clkset(uint8_t clksel)
{
uint16_t regval = 0;
if (clksel > 2) {
return false;
}
regval = WM8978_ReadReg(6);
GET_REG_VAL(regval, clksel, 8, 1);
if (!WM8978_WriteReg(6, regval)) {
return true;
} else {
return false;
}
}
bool wm8978_master_cfg(void)
{
bool flag = true;
/* master mode */
flag &= wm8978_ms_set(1);
/* bclk=mclk/2 */
flag &= wm8978_bclkdiv_set(3);
/* mclk/12 */
flag &= wm8978_mclkdiv_set(3);
/* clk source is mclk */
flag &= wm8978_clkset(0);
return flag;
}

View File

@@ -0,0 +1,79 @@
/**
* @file wm8978.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __WM8978_H
#define __WM8978_H
#include "stdint.h"
#define WM8978_ADDR 0X1A
#define EQ1_80Hz 0X00
#define EQ1_105Hz 0X01
#define EQ1_135Hz 0X02
#define EQ1_175Hz 0X03
#define EQ2_230Hz 0X00
#define EQ2_300Hz 0X01
#define EQ2_385Hz 0X02
#define EQ2_500Hz 0X03
#define EQ3_650Hz 0X00
#define EQ3_850Hz 0X01
#define EQ3_1100Hz 0X02
#define EQ3_14000Hz 0X03
#define EQ4_1800Hz 0X00
#define EQ4_2400Hz 0X01
#define EQ4_3200Hz 0X02
#define EQ4_4100Hz 0X03
#define EQ5_5300Hz 0X00
#define EQ5_6900Hz 0X01
#define EQ5_9000Hz 0X02
#define EQ5_11700Hz 0X03
uint8_t WM8978_Init(void);
void WM8978_ADDA_Cfg(uint8_t dacen, uint8_t adcen);
void WM8978_Input_Cfg(uint8_t micen, uint8_t lineinen, uint8_t auxen);
void WM8978_Output_Cfg(uint8_t dacen, uint8_t bpsen);
void WM8978_MIC_Gain(uint8_t gain);
void WM8978_LINEIN_Gain(uint8_t gain);
void WM8978_AUX_Gain(uint8_t gain);
uint8_t WM8978_Write_Reg(uint8_t reg, uint16_t val);
uint16_t WM8978_Read_Reg(uint8_t reg);
void WM8978_HPvol_Set(uint8_t voll, uint8_t volr);
void WM8978_SPKvol_Set(uint8_t volx);
void WM8978_I2S_Cfg(uint8_t fmt, uint8_t len);
void WM8978_PlayMode(void);
void WM8978_RecoMode(void);
void WM8978_3D_Set(uint8_t depth);
void WM8978_EQ_3D_Dir(uint8_t dir);
void WM8978_EQ1_Set(uint8_t cfreq, uint8_t gain);
void WM8978_EQ2_Set(uint8_t cfreq, uint8_t gain);
void WM8978_EQ3_Set(uint8_t cfreq, uint8_t gain);
void WM8978_EQ4_Set(uint8_t cfreq, uint8_t gain);
void WM8978_EQ5_Set(uint8_t cfreq, uint8_t gain);
bool wm8978_master_cfg(void);
#endif

View File

@@ -0,0 +1,62 @@
################# Add global include #################
list(APPEND ADD_INCLUDE
"${CMAKE_CURRENT_SOURCE_DIR}/ring_buffer"
"${CMAKE_CURRENT_SOURCE_DIR}/soft_crc"
"${CMAKE_CURRENT_SOURCE_DIR}/memheap"
"${CMAKE_CURRENT_SOURCE_DIR}/misc"
"${CMAKE_CURRENT_SOURCE_DIR}/list"
"${CMAKE_CURRENT_SOURCE_DIR}/device"
"${CMAKE_CURRENT_SOURCE_DIR}/partition"
"${CMAKE_CURRENT_SOURCE_DIR}/bl_math"
"${CMAKE_CURRENT_SOURCE_DIR}/pid"
"${CMAKE_CURRENT_SOURCE_DIR}/timestamp"
)
#######################################################
################# Add private include #################
# list(APPEND ADD_PRIVATE_INCLUDE
# )
#######################################################
############## Add current dir source files ###########
file(GLOB_RECURSE sources
"${CMAKE_CURRENT_SOURCE_DIR}/ring_buffer/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/soft_crc/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/memheap/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/misc/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/device/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/partition/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/bl_math/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/pid/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/timestamp/*.c"
)
#aux_source_directory(. sources)
list(APPEND ADD_SRCS ${sources})
#######################################################
########### Add required/dependent components #########
#list(APPEND ADD_REQUIREMENTS xxx)
#######################################################
############ Add static libs ##########################
#list(APPEND ADD_STATIC_LIB "libxxx.a")
#######################################################
############ Add dynamic libs #########################
# list(APPEND ADD_DYNAMIC_LIB "libxxx.so"
# )
#######################################################
############ Add global compile option ################
#add components denpend on this component
string(TOUPPER ${CHIP} CHIPNAME)
list(APPEND ADD_DEFINITIONS -D${CHIPNAME})
#######################################################
############ Add private compile option ################
#add compile option for this component that won't affect other modules
# list(APPEND ADD_PRIVATE_DEFINITIONS -Dxxx)
#######################################################
generate_library()

View File

@@ -0,0 +1,50 @@
/**
* @file arm_dsp_wrapper.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "arm_dsp_wrapper.h"
void arm_fill_f32(float32_t value, float32_t *pDst, uint32_t blockSize)
{
uint32_t blkCnt = blockSize >> 2u;
float32_t in1 = value;
float32_t in2 = value;
float32_t in3 = value;
float32_t in4 = value;
while (blkCnt > 0u) {
*pDst++ = in1;
*pDst++ = in2;
*pDst++ = in3;
*pDst++ = in4;
blkCnt--;
}
blkCnt = blockSize % 0x4u;
while (blkCnt > 0u) {
*pDst++ = value;
blkCnt--;
}
}

View File

@@ -0,0 +1,44 @@
/**
* @file arm_dsp_wrapper.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __MY_MATH_F_H__
#define __MY_MATH_F_H__
#include "misc.h"
#include "math.h"
typedef float float32_t;
__INLINE__ float32_t arm_sqrt_f32(float32_t x)
{
return sqrtf(x);
}
__INLINE__ float32_t arm_cos_f32(float32_t x)
{
return cosf(x);
}
void arm_fill_f32(float32_t value, float32_t *pDst, uint32_t blockSize);
#endif

View File

@@ -0,0 +1,294 @@
/**
* @file drv_device.c
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "drv_device.h"
#define DEVICE_CHECK_PARAM
#define dev_open (dev->open)
#define dev_close (dev->close)
#define dev_read (dev->read)
#define dev_write (dev->write)
#define dev_control (dev->control)
dlist_t device_head = DLIST_OBJECT_INIT(device_head);
/**
* This function get device list header
*
* @param None
*
* @return device header
*/
dlist_t *device_get_list_header(void)
{
return &device_head;
}
/**
* This function registers a device driver with specified name.
*
* @param dev the pointer of device driver structure
* @param name the device driver's name
* @param flags the capabilities flag of device
*
* @return the error code, DEVICE_EOK on initialization successfully.
*/
int device_register(struct device *dev, const char *name)
{
dlist_t *node;
dlist_for_each(node, &device_head)
{
struct device *dev_obj;
dev_obj = dlist_entry(node, struct device, list);
if (dev_obj == dev) {
return -DEVICE_EEXIST;
}
}
strcpy(dev->name, name);
dlist_insert_after(&device_head, &(dev->list));
dev->status = DEVICE_REGISTERED;
return DEVICE_EOK;
}
/**
* This function unregisters a device driver with specified name.
*
* @param dev the pointer of device driver structure
* @param name the device driver's name
* @param flags the capabilities flag of device
*
* @return the error code, DEVICE_EOK on initialization successfully.
*/
int device_unregister(const char *name)
{
struct device *dev = device_find(name);
if (!dev) {
return -DEVICE_ENODEV;
}
dev->status = DEVICE_UNREGISTER;
/* remove from old list */
dlist_remove(&(dev->list));
return DEVICE_EOK;
}
/**
* This function finds a device driver by specified name.
*
* @param name the device driver's name
*
* @return the registered device driver on successful, or NULL on failure.
*/
struct device *device_find(const char *name)
{
struct device *dev;
dlist_t *node;
dlist_for_each(node, &device_head)
{
dev = dlist_entry(node, struct device, list);
if (strncmp(dev->name, name, DEVICE_NAME_MAX) == 0) {
return dev;
}
}
return NULL;
}
/**
* This function will open a device
*
* @param dev the pointer of device driver structure
* @param oflag the flags for device open
*
* @return the result
*/
int device_open(struct device *dev, uint16_t oflag)
{
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
if ((dev->status == DEVICE_REGISTERED) || (dev->status == DEVICE_CLOSED)) {
if (dev_open != NULL) {
retval = dev_open(dev, oflag);
dev->status = DEVICE_OPENED;
dev->oflag |= oflag;
} else {
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
#else
return dev_open(dev, oflag);
#endif
}
/**
* This function will close a device
*
* @param dev the pointer of device driver structure
*
* @return the result
*/
int device_close(struct device *dev)
{
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
if (dev->status == DEVICE_OPENED) {
if (dev_close != NULL) {
retval = dev_close(dev);
dev->status = DEVICE_CLOSED;
dev->oflag = 0;
} else {
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
#else
return dev_close(dev);
#endif
}
/**
* This function will perform a variety of control functions on devices.
*
* @param dev the pointer of device driver structure
* @param cmd the command sent to device
* @param arg the argument of command
*
* @return the result
*/
int device_control(struct device *dev, int cmd, void *args)
{
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
if (dev->status > DEVICE_UNREGISTER) {
if (dev_control != NULL) {
retval = dev_control(dev, cmd, args);
} else {
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
#else
return dev_control(dev, cmd, args);
#endif
}
/**
* This function will write some data to a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of written
* @param buffer the data buffer to be written to device
* @param size the size of buffer
*
* @return the actually written size on successful, otherwise negative returned.
*/
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size)
{
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
if (dev->status == DEVICE_OPENED) {
if (dev_write != NULL) {
retval = dev_write(dev, pos, buffer, size);
} else {
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
#else
return dev_write(dev, pos, buffer, size);
#endif
}
/**
* This function will read some data from a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of reading
* @param buffer the data buffer to save read data
* @param size the size of buffer
*
* @return the actually read size on successful, otherwise negative returned.
*/
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
{
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
if (dev->status == DEVICE_OPENED) {
if (dev_read != NULL) {
retval = dev_read(dev, pos, buffer, size);
} else {
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
#else
return dev_read(dev, pos, buffer, size);
#endif
}
/**
* This function will read some data from a device.
*
* @param dev the pointer of device driver structure
* @param pos the position of reading
* @param buffer the data buffer to save read data
* @param size the size of buffer
*
* @return the actually read size on successful, otherwise negative returned.
*/
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event))
{
int retval = DEVICE_EOK;
if (dev->status > DEVICE_UNREGISTER) {
if (callback != NULL) {
dev->callback = callback;
} else {
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
}

View File

@@ -0,0 +1,135 @@
/**
* @file drv_device.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __DRV_DEVICE_H__
#define __DRV_DEVICE_H__
#include "drv_list.h"
#include "stdio.h"
#define DEVICE_NAME_MAX 20 /* max device name*/
#define DEVICE_OFLAG_DEFAULT 0x000 /* open with default */
#define DEVICE_OFLAG_STREAM_TX 0x001 /* open with poll tx */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* open with poll rx */
#define DEVICE_OFLAG_INT_TX 0x004 /* open with interrupt tx */
#define DEVICE_OFLAG_INT_RX 0x008 /* open with interrupt rx */
#define DEVICE_OFLAG_DMA_TX 0x010 /* open with dma tx */
#define DEVICE_OFLAG_DMA_RX 0x020 /* open with dma rx */
#define DEVICE_CTRL_SET_INT 0x01 /* set interrupt */
#define DEVICE_CTRL_CLR_INT 0x02 /* clear interrupt */
#define DEVICE_CTRL_GET_INT 0x03 /* get interrupt status*/
#define DEVICE_CTRL_RESUME 0x04 /* resume device */
#define DEVICE_CTRL_SUSPEND 0x05 /* suspend device */
#define DEVICE_CTRL_CONFIG 0x06 /* config device */
#define DEVICE_CTRL_GET_CONFIG 0x07 /* get device configuration */
#define DEVICE_CTRL_ATTACH_TX_DMA 0x08 /* deivce link tx dma */
#define DEVICE_CTRL_ATTACH_RX_DMA 0x09 /* deivce link rx dma */
#define DEVICE_CTRL_TX_DMA_SUSPEND 0x0a /* deivce suspend tx dma */
#define DEVICE_CTRL_RX_DMA_SUSPEND 0x0b /* deivce suspend rx dma */
#define DEVICE_CTRL_TX_DMA_RESUME 0x0c /* deivce resume tx dma */
#define DEVICE_CTRL_RX_DMA_RESUME 0x0d /* deivce resume rx dma */
#define DEVICE_CTRL_RESVD1 0x0E
#define DEVICE_CTRL_RESVD2 0x0F
/*
* POSIX Error codes
*/
#define DEVICE_EOK 0
#define DEVICE_EFAULT 14 /* Bad address */
#define DEVICE_EEXIST 17 /* device exists */
#define DEVICE_ENODEV 19 /* No such device */
#define DEVICE_EINVAL 22 /* Invalid argument */
#define DEVICE_ENOSPACE 23 /* No more Device for Allocate */
#define __ASSERT_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define __ASSERT_LOC(test) \
__ASSERT_PRINT("ASSERTION FAIL [%s] @ %s:%d\n", \
#test, \
__FILE__, __LINE__)
#define DEVICE_ASSERT(test, fmt, ...) \
do { \
if (!(test)) { \
__ASSERT_LOC(test); \
__ASSERT_PRINT(fmt, ##__VA_ARGS__); \
} \
} while (0)
enum device_class_type {
DEVICE_CLASS_NONE = 0,
DEVICE_CLASS_GPIO,
DEVICE_CLASS_UART,
DEVICE_CLASS_SPI,
DEVICE_CLASS_I2C,
DEVICE_CLASS_ADC,
DEVICE_CLASS_DAC,
DEVICE_CLASS_DMA,
DEVICE_CLASS_TIMER,
DEVICE_CLASS_PWM,
DEVICE_CLASS_QDEC,
DEVICE_CLASS_SDIO,
DEVICE_CLASS_USB,
DEVICE_CLASS_RMII,
DEVICE_CLASS_I2S,
DEVICE_CLASS_CAMERA,
DEVICE_CLASS_SEC_HASH,
DEVICE_CLASS_KEYSCAN,
};
enum device_status_type {
DEVICE_UNREGISTER = 0,
DEVICE_REGISTERED,
DEVICE_OPENED,
DEVICE_CLOSED
};
struct device {
char name[DEVICE_NAME_MAX]; /*name of device */
dlist_t list; /*list node of device */
enum device_status_type status; /*status of device */
enum device_class_type type; /*type of device */
uint16_t oflag; /*oflag of device */
int (*open)(struct device *dev, uint16_t oflag);
int (*close)(struct device *dev);
int (*control)(struct device *dev, int cmd, void *args);
int (*write)(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
int (*read)(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event);
void *handle;
};
int device_register(struct device *dev, const char *name);
int device_unregister(const char *name);
struct device *device_find(const char *name);
int device_open(struct device *dev, uint16_t oflag);
int device_close(struct device *dev);
int device_control(struct device *dev, int cmd, void *args);
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
dlist_t *device_get_list_header(void);
#endif

View File

@@ -0,0 +1,472 @@
/**
* @file drv_list.h
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __DRV_LIST_H__
#define __DRV_LIST_H__
#include "string.h"
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* container_of - return the member address of ptr, if the type of ptr is the
* struct type.
*/
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
/**
* Double List structure
*/
struct dlist_node {
struct dlist_node *next; /**< point to next node. */
struct dlist_node *prev; /**< point to prev node. */
};
typedef struct dlist_node dlist_t; /**< Type for lists. */
/**
* @brief initialize a list
*
* @param l list to be initialized
*/
static inline void dlist_init(dlist_t *l)
{
l->next = l->prev = l;
}
/**
* @brief insert a node after a list
*
* @param l list to insert it
* @param n new node to be inserted
*/
static inline void dlist_insert_after(dlist_t *l, dlist_t *n)
{
l->next->prev = n;
n->next = l->next;
l->next = n;
n->prev = l;
}
/**
* @brief insert a node before a list
*
* @param n new node to be inserted
* @param l list to insert it
*/
static inline void dlist_insert_before(dlist_t *l, dlist_t *n)
{
l->prev->next = n;
n->prev = l->prev;
l->prev = n;
n->next = l;
}
/**
* @brief remove node from list.
* @param n the node to remove from the list.
*/
static inline void dlist_remove(dlist_t *n)
{
n->next->prev = n->prev;
n->prev->next = n->next;
n->next = n->prev = n;
}
/**
* @brief move node from list.
* @param n the node to remove from the list.
*/
static inline void dlist_move_head(dlist_t *l, dlist_t *n)
{
dlist_remove(n);
dlist_insert_after(l, n);
}
/**
* @brief move node from list.
* @param n the node to remove from the list.
*/
static inline void dlist_move_tail(dlist_t *l, dlist_t *n)
{
dlist_remove(n);
dlist_insert_before(l, n);
}
/**
* @brief tests whether a list is empty
* @param l the list to test.
*/
static inline int dlist_isempty(const dlist_t *l)
{
return l->next == l;
}
/**
* @brief get the list length
* @param l the list to get.
*/
static inline unsigned int dlist_len(const dlist_t *l)
{
unsigned int len = 0;
const dlist_t *p = l;
while (p->next != l) {
p = p->next;
len++;
}
return len;
}
/**
* @brief initialize a dlist object
*/
#define DLIST_OBJECT_INIT(object) \
{ \
&(object), &(object) \
}
/**
* @brief initialize a dlist object
*/
#define DLIST_DEFINE(list) \
dlist_t list = { &(list), &(list) }
/**
* @brief get the struct for this entry
* @param node the entry point
* @param type the type of structure
* @param member the name of list in structure
*/
#define dlist_entry(node, type, member) \
container_of(node, type, member)
/**
* dlist_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define dlist_first_entry(ptr, type, member) \
dlist_entry((ptr)->next, type, member)
/**
* dlist_first_entry_or_null - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define dlist_first_entry_or_null(ptr, type, member) \
(dlist_isempty(ptr) ? NULL : dlist_first_entry(ptr, type, member))
/**
* dlist_for_each - iterate over a list
* @pos: the dlist_t * to use as a loop cursor.
* @head: the head for your list.
*/
#define dlist_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* dlist_for_each_prev - iterate over a list
* @pos: the dlist_t * to use as a loop cursor.
* @head: the head for your list.
*/
#define dlist_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* dlist_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the dlist_t * to use as a loop cursor.
* @n: another dlist_t * to use as temporary storage
* @head: the head for your list.
*/
#define dlist_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#define dlist_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; pos != (head); \
pos = n, n = pos->prev)
/**
* dlist_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define dlist_for_each_entry(pos, head, member) \
for (pos = dlist_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = dlist_entry(pos->member.next, typeof(*pos), member))
/**
* dlist_for_each_entry_reverse - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define dlist_for_each_entry_reverse(pos, head, member) \
for (pos = dlist_entry((head)->prev, typeof(*pos), member); \
&pos->member != (head); \
pos = dlist_entry(pos->member.prev, typeof(*pos), member))
/**
* dlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define dlist_for_each_entry_safe(pos, n, head, member) \
for (pos = dlist_entry((head)->next, typeof(*pos), member), \
n = dlist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = dlist_entry(n->member.next, typeof(*n), member))
/**
* dlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define dlist_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = dlist_entry((head)->prev, typeof(*pos), field), \
n = dlist_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = dlist_entry(pos->member.prev, typeof(*pos), member))
/**
* Single List structure
*/
struct slist_node {
struct slist_node *next; /**< point to next node. */
};
typedef struct slist_node slist_t; /**< Type for single list. */
/**
* @brief initialize a single list
*
* @param l the single list to be initialized
*/
static inline void slist_init(slist_t *l)
{
l->next = NULL;
}
static inline void slist_add_head(slist_t *l, slist_t *n)
{
n->next = l->next;
l->next = n;
}
static inline void slist_add_tail(slist_t *l, slist_t *n)
{
while (l->next) {
l = l->next;
}
/* append the node to the tail */
l->next = n;
n->next = NULL;
}
static inline void slist_insert(slist_t *l, slist_t *next, slist_t *n)
{
if (!next) {
slist_add_tail(next, l);
return;
}
while (l->next) {
if (l->next == next) {
l->next = n;
n->next = next;
}
l = l->next;
}
}
static inline slist_t *slist_remove(slist_t *l, slist_t *n)
{
/* remove slist head */
while (l->next && l->next != n) {
l = l->next;
}
/* remove node */
if (l->next != (slist_t *)0) {
l->next = l->next->next;
}
return l;
}
static inline unsigned int slist_len(const slist_t *l)
{
unsigned int len = 0;
const slist_t *list = l->next;
while (list != NULL) {
list = list->next;
len++;
}
return len;
}
static inline unsigned int slist_contains(slist_t *l, slist_t *n)
{
while (l->next) {
if (l->next == n) {
return 0;
}
l = l->next;
}
return 1;
}
static inline slist_t *slist_head(slist_t *l)
{
return l->next;
}
static inline slist_t *slist_tail(slist_t *l)
{
while (l->next) {
l = l->next;
}
return l;
}
static inline slist_t *slist_next(slist_t *n)
{
return n->next;
}
static inline int slist_isempty(slist_t *l)
{
return l->next == NULL;
}
/**
* @brief initialize a slist object
*/
#define SLIST_OBJECT_INIT(object) \
{ \
NULL \
}
/**
* @brief initialize a slist object
*/
#define SLIST_DEFINE(slist) \
slist_t slist = { NULL }
/**
* @brief get the struct for this single list node
* @param node the entry point
* @param type the type of structure
* @param member the name of list in structure
*/
#define slist_entry(node, type, member) \
container_of(node, type, member)
/**
* slist_first_entry - get the first element from a slist
* @ptr: the slist head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the slist_struct within the struct.
*
* Note, that slist is expected to be not empty.
*/
#define slist_first_entry(ptr, type, member) \
slist_entry((ptr)->next, type, member)
/**
* slist_tail_entry - get the tail element from a slist
* @ptr: the slist head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the slist_struct within the struct.
*
* Note, that slist is expected to be not empty.
*/
#define slist_tail_entry(ptr, type, member) \
slist_entry(slist_tail(ptr), type, member)
/**
* slist_first_entry_or_null - get the first element from a slist
* @ptr: the slist head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the slist_struct within the struct.
*
* Note, that slist is expected to be not empty.
*/
#define slist_first_entry_or_null(ptr, type, member) \
(slist_isempty(ptr) ? NULL : slist_first_entry(ptr, type, member))
/**
* slist_for_each - iterate over a single list
* @pos: the slist_t * to use as a loop cursor.
* @head: the head for your single list.
*/
#define slist_for_each(pos, head) \
for (pos = (head)->next; pos != NULL; pos = pos->next)
#define slist_for_each_safe(pos, next, head) \
for (pos = (head)->next, next = pos->next; pos; \
pos = next, next = pos->next)
/**
* slist_for_each_entry - iterate over single list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your single list.
* @member: the name of the list_struct within the struct.
*/
#define slist_for_each_entry(pos, head, member) \
for (pos = slist_entry((head)->next, typeof(*pos), member); \
&pos->member != (NULL); \
pos = slist_entry(pos->member.next, typeof(*pos), member))
#define slist_for_each_entry_safe(pos, n, head, member) \
for (pos = slist_entry((head)->next, typeof(*pos), member), \
n = slist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (NULL); \
pos = n, n = slist_entry(pos->member.next, typeof(*pos), member))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,421 @@
/**
* @file drv_mmheap.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "drv_mmheap.h"
#define MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT 8
#define MEM_MANAGE_BITS_PER_BYTE 8
#define MEM_MANAGE_MEM_STRUCT_SIZE mmheap_align_up(sizeof(struct heap_node), MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT)
#define MEM_MANAGE_MINUM_MEM_SIZE (MEM_MANAGE_MEM_STRUCT_SIZE << 1)
#define MEM_MANAGE_ALLOCA_LABAL ((size_t)((size_t)1 << (sizeof(size_t) * MEM_MANAGE_BITS_PER_BYTE - 1)))
static inline size_t mmheap_align_down(size_t data, size_t align_byte)
{
return data & ~(align_byte - 1);
}
static inline size_t mmheap_align_up(size_t data, size_t align_byte)
{
return (data + align_byte - 1) & ~(align_byte - 1);
}
static inline struct heap_node *mmheap_addr_sub(const void *addr)
{
return (struct heap_node *)((const uint8_t *)addr - MEM_MANAGE_MEM_STRUCT_SIZE);
}
static inline void *mmheap_addr_add(const struct heap_node *mem_node)
{
return (void *)((const uint8_t *)mem_node + MEM_MANAGE_MEM_STRUCT_SIZE);
}
/**
* @brief mmheap_insert_node_to_freelist
*
* @param pRoot
* @param pNode
*/
static inline void mmheap_insert_node_to_freelist(struct heap_info *pRoot, struct heap_node *pNode)
{
struct heap_node *pPriv_Node;
struct heap_node *pNext_Node;
/*Find the node with an address similar to pNode*/
for (pPriv_Node = pRoot->pStart; pPriv_Node->next_node < pNode; pPriv_Node = pPriv_Node->next_node) {
}
pNext_Node = pPriv_Node->next_node;
/*Try to merge the pNode with the previous block*/
if ((uint8_t *)mmheap_addr_add(pPriv_Node) + pPriv_Node->mem_size == (uint8_t *)pNode) {
if (pPriv_Node != pRoot->pStart) { /*can merge if not start block*/
pPriv_Node->mem_size += MEM_MANAGE_MEM_STRUCT_SIZE + pNode->mem_size;
pNode = pPriv_Node;
} else {
/*The latter is not merged if it is a Start block to avoid wasting memory*/
pRoot->pStart->next_node = pNode;
}
} else {
/*Insert directly into the free single-chain table when merging is not possible*/
pPriv_Node->next_node = pNode;
}
/*Try to merge the pNode with the next block*/
if ((uint8_t *)mmheap_addr_add(pNode) + pNode->mem_size == (uint8_t *)pNext_Node) {
if (pNext_Node != pRoot->pEnd) {
pNode->mem_size += MEM_MANAGE_MEM_STRUCT_SIZE + pNext_Node->mem_size;
pNode->next_node = pNext_Node->next_node;
} else {
pNode->next_node = pRoot->pEnd;
}
} else {
/*Insert directly into the free single-chain table when merging is not possible*/
pNode->next_node = pNext_Node;
}
}
/**
* @brief mmheap_get_state
*
* @param pRoot
* @param pState
*/
void mmheap_get_state(struct heap_info *pRoot, struct heap_state *pState)
{
MMHEAP_ASSERT(pRoot->pStart != NULL);
MMHEAP_ASSERT(pRoot->pEnd != NULL);
pState->max_node_size = pRoot->pStart->next_node->mem_size;
pState->min_node_size = pRoot->pStart->next_node->mem_size;
pState->remain_size = 0;
pState->free_node_num = 0;
MMHEAP_LOCK();
for (struct heap_node *pNode = pRoot->pStart->next_node; pNode->next_node != NULL; pNode = pNode->next_node) {
pState->remain_size += pNode->mem_size;
pState->free_node_num++;
if (pNode->mem_size > pState->max_node_size)
pState->max_node_size = pNode->mem_size;
if (pNode->mem_size < pState->min_node_size)
pState->min_node_size = pNode->mem_size;
}
MMHEAP_UNLOCK();
}
/**
* @brief mmheap_align_alloc
*
* @param pRoot
* @param align_size
* @param want_size
* @return void*
*/
void *mmheap_align_alloc(struct heap_info *pRoot, size_t align_size, size_t want_size)
{
void *pReturn = NULL;
struct heap_node *pPriv_Node, *pNow_Node;
MMHEAP_ASSERT(pRoot->pStart != NULL);
MMHEAP_ASSERT(pRoot->pEnd != NULL);
if (want_size == 0) {
return NULL;
}
if ((want_size & MEM_MANAGE_ALLOCA_LABAL) != 0) {
MMHEAP_MALLOC_FAIL();
return NULL;
}
if (align_size & (align_size - 1)) {
MMHEAP_MALLOC_FAIL();
return NULL;
}
MMHEAP_LOCK();
if (want_size < MEM_MANAGE_MINUM_MEM_SIZE)
want_size = MEM_MANAGE_MINUM_MEM_SIZE;
if (align_size < MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT)
align_size = MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT;
want_size = mmheap_align_up(want_size, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT);
pPriv_Node = pRoot->pStart;
pNow_Node = pRoot->pStart->next_node;
while (pNow_Node->next_node != NULL) {
if (pNow_Node->mem_size >= want_size + MEM_MANAGE_MEM_STRUCT_SIZE) {
size_t use_align_size;
size_t new_size;
pReturn = (void *)mmheap_align_up((size_t)mmheap_addr_add(pNow_Node), align_size); /*Calculate the aligned address*/
use_align_size = (uint8_t *)pReturn - (uint8_t *)mmheap_addr_add(pNow_Node); /*Calculate the memory consumed by the alignment*/
if (use_align_size != 0) { /*if Memory misalignment*/
if (use_align_size < MEM_MANAGE_MINUM_MEM_SIZE + MEM_MANAGE_MEM_STRUCT_SIZE) { /*The unaligned value is too small*/
pReturn = (void *)mmheap_align_up(
(size_t)mmheap_addr_add(pNow_Node) + MEM_MANAGE_MINUM_MEM_SIZE + MEM_MANAGE_MEM_STRUCT_SIZE, align_size);
use_align_size = (uint8_t *)pReturn - (uint8_t *)mmheap_addr_add(pNow_Node);
}
if (use_align_size <= pNow_Node->mem_size) {
new_size = pNow_Node->mem_size - use_align_size; /*Calculate the remaining memory size by removing the memory consumed by alignment*/
if (new_size >= want_size) { /*Meet the conditions for distribution*/
struct heap_node *pNew_Node = mmheap_addr_sub(pReturn);
pNow_Node->mem_size -= new_size + MEM_MANAGE_MEM_STRUCT_SIZE; /*Split Node*/
pNew_Node->mem_size = new_size; /*The new node is also not in the free chain and does not need to be discharged from the free chain*/
pNew_Node->next_node = NULL;
pNow_Node = pNew_Node;
break;
}
}
} else { /*Memory is directly aligned*/
pPriv_Node->next_node = pNow_Node->next_node;
pNow_Node->next_node = NULL;
break;
}
}
pPriv_Node = pNow_Node;
pNow_Node = pNow_Node->next_node;
}
if (pNow_Node == pRoot->pEnd) {
MMHEAP_UNLOCK();
MMHEAP_MALLOC_FAIL();
return NULL;
}
if (pNow_Node->mem_size >= MEM_MANAGE_MINUM_MEM_SIZE + MEM_MANAGE_MEM_STRUCT_SIZE + want_size) { /*Node memory is still available*/
struct heap_node *pNew_Node = (struct heap_node *)((uint8_t *)mmheap_addr_add(pNow_Node) + want_size); /*Calculate the address of the node that will be moved into the free chain table*/
pNew_Node->mem_size = pNow_Node->mem_size - want_size - MEM_MANAGE_MEM_STRUCT_SIZE;
pNew_Node->next_node = NULL;
pNow_Node->mem_size = want_size;
mmheap_insert_node_to_freelist(pRoot, pNew_Node);
}
pNow_Node->mem_size |= MEM_MANAGE_ALLOCA_LABAL;
MMHEAP_UNLOCK();
return pReturn;
}
/**
* @brief mmheap_alloc
*
* @param pRoot
* @param want_size
* @return void*
*/
void *mmheap_alloc(struct heap_info *pRoot, size_t want_size)
{
return mmheap_align_alloc(pRoot, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT, want_size);
}
/**
* @brief mmheap_realloc
*
* @param pRoot
* @param src_addr
* @param want_size
* @return void*
*/
void *mmheap_realloc(struct heap_info *pRoot, void *src_addr, size_t want_size)
{
void *pReturn = NULL;
struct heap_node *pNext_Node, *pPriv_Node;
struct heap_node *pSrc_Node;
MMHEAP_ASSERT(pRoot->pStart != NULL);
MMHEAP_ASSERT(pRoot->pEnd != NULL);
if (src_addr == NULL) {
return mmheap_align_alloc(pRoot, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT, want_size);
}
if (want_size == 0) {
mmheap_free(pRoot, src_addr);
return NULL;
}
MMHEAP_LOCK();
if ((want_size & MEM_MANAGE_ALLOCA_LABAL) != 0) {
MMHEAP_UNLOCK();
MMHEAP_MALLOC_FAIL();
return NULL;
}
pSrc_Node = mmheap_addr_sub(src_addr);
if ((pSrc_Node->mem_size & MEM_MANAGE_ALLOCA_LABAL) == 0) {
MMHEAP_UNLOCK();
MMHEAP_ASSERT((pSrc_Node->mem_size & MEM_MANAGE_ALLOCA_LABAL) != 0);
MMHEAP_MALLOC_FAIL();
return NULL;
}
pSrc_Node->mem_size &= ~MEM_MANAGE_ALLOCA_LABAL;
if (pSrc_Node->mem_size >= want_size) {
pSrc_Node->mem_size |= MEM_MANAGE_ALLOCA_LABAL;
pReturn = src_addr;
MMHEAP_UNLOCK();
return pReturn;
}
/*Start looking in the free list for blocks similar to this block*/
for (pPriv_Node = pRoot->pStart; pPriv_Node->next_node < pSrc_Node; pPriv_Node = pPriv_Node->next_node) {
}
pNext_Node = pPriv_Node->next_node;
if (pNext_Node != pRoot->pEnd &&
((uint8_t *)src_addr + pSrc_Node->mem_size == (uint8_t *)pNext_Node) &&
(pSrc_Node->mem_size + pNext_Node->mem_size + MEM_MANAGE_MEM_STRUCT_SIZE >= want_size)) {
/*Meet next node non-end, memory contiguous, enough memory left*/
pReturn = src_addr;
pPriv_Node->next_node = pNext_Node->next_node;
pSrc_Node->mem_size += MEM_MANAGE_MEM_STRUCT_SIZE + pNext_Node->mem_size;
want_size = mmheap_align_up(want_size, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT);
if (pSrc_Node->mem_size >= MEM_MANAGE_MINUM_MEM_SIZE + MEM_MANAGE_MEM_STRUCT_SIZE + want_size) { /*Removing the remaining space allocated is enough to open new blocks*/
struct heap_node *pNew_Node = (struct heap_node *)((uint8_t *)mmheap_addr_add(pSrc_Node) + want_size);
pNew_Node->next_node = NULL;
pNew_Node->mem_size = pSrc_Node->mem_size - want_size - MEM_MANAGE_MEM_STRUCT_SIZE;
pSrc_Node->mem_size = want_size;
mmheap_insert_node_to_freelist(pRoot, pNew_Node);
}
pSrc_Node->mem_size |= MEM_MANAGE_ALLOCA_LABAL;
MMHEAP_UNLOCK();
} else {
MMHEAP_UNLOCK();
pReturn = mmheap_align_alloc(pRoot, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT, want_size);
if (pReturn == NULL) {
pSrc_Node->mem_size |= MEM_MANAGE_ALLOCA_LABAL;
MMHEAP_MALLOC_FAIL();
return NULL;
}
MMHEAP_LOCK();
memcpy(pReturn, src_addr, pSrc_Node->mem_size);
pSrc_Node->mem_size |= MEM_MANAGE_ALLOCA_LABAL;
MMHEAP_UNLOCK();
mmheap_free(pRoot, src_addr);
}
return pReturn;
}
/**
* @brief
*
* @param pRoot
* @param num
* @param size
* @return void*
*/
void *mmheap_calloc(struct heap_info *pRoot, size_t num, size_t size)
{
void *pReturn = NULL;
pReturn = (void *)mmheap_alloc(pRoot, size * num);
if (pReturn) {
memset(pReturn, 0, num * size);
}
return pReturn;
}
/**
* @brief mmheap_free
*
* @param pRoot
* @param addr
*/
void mmheap_free(struct heap_info *pRoot, void *addr)
{
struct heap_node *pFree_Node;
MMHEAP_ASSERT(pRoot->pStart != NULL);
MMHEAP_ASSERT(pRoot->pEnd != NULL);
MMHEAP_LOCK();
if (addr == NULL) {
MMHEAP_UNLOCK();
return;
}
pFree_Node = mmheap_addr_sub(addr);
if ((pFree_Node->mem_size & MEM_MANAGE_ALLOCA_LABAL) == 0) {
MMHEAP_UNLOCK();
MMHEAP_ASSERT((pFree_Node->mem_size & MEM_MANAGE_ALLOCA_LABAL) != 0);
return;
}
if (pFree_Node->next_node != NULL) {
MMHEAP_UNLOCK();
MMHEAP_ASSERT(pFree_Node->next_node == NULL);
return;
}
pFree_Node->mem_size &= ~MEM_MANAGE_ALLOCA_LABAL;
mmheap_insert_node_to_freelist(pRoot, pFree_Node);
MMHEAP_UNLOCK();
}
/**
* @brief mmheap_init
*
* @param pRoot
* @param pRegion
*/
void mmheap_init(struct heap_info *pRoot, const struct heap_region *pRegion)
{
struct heap_node *align_addr;
size_t align_size;
struct heap_node *pPriv_node = NULL;
pRoot->total_size = 0;
pRoot->pEnd = NULL;
pRoot->pStart = NULL;
for (; pRegion->addr != NULL; pRegion++) {
align_addr = (struct heap_node *)mmheap_align_up((size_t)pRegion->addr, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT); /*Calculate the aligned address*/
if ((uint8_t *)align_addr > pRegion->mem_size + (uint8_t *)pRegion->addr) /*Alignment consumes more memory than the memory area*/
continue;
align_size = pRegion->mem_size - ((uint8_t *)align_addr - (uint8_t *)pRegion->addr); /*Calculate the size of memory left after alignment*/
if (align_size < MEM_MANAGE_MINUM_MEM_SIZE + MEM_MANAGE_MEM_STRUCT_SIZE) /*if Aligning the remaining memory is too small*/
continue;
align_size -= MEM_MANAGE_MEM_STRUCT_SIZE; /*Find the size of the memory block after removing the table header*/
align_addr->mem_size = align_size;
align_addr->next_node = NULL;
if (pRoot->pStart == NULL) {
pRoot->pStart = align_addr; /*set current addr for start*/
if (align_size >= MEM_MANAGE_MINUM_MEM_SIZE + MEM_MANAGE_MEM_STRUCT_SIZE) { /*If the remaining blocks are large enough*/
align_size -= MEM_MANAGE_MEM_STRUCT_SIZE; /*Remove the next block of table headers remaining memory size*/
align_addr = (struct heap_node *)((uint8_t *)pRoot->pStart + MEM_MANAGE_MEM_STRUCT_SIZE); //the next block addr
align_addr->mem_size = align_size;
align_addr->next_node = NULL;
pRoot->pStart->mem_size = 0;
pRoot->pStart->next_node = align_addr;
pRoot->total_size = align_addr->mem_size;
} else { /*The memory is too small, and the address of the current memory block is recorded as start*/
pRoot->total_size = 0;
pRoot->pStart->mem_size = 0;
}
} else {
pPriv_node->next_node = align_addr;
pRoot->total_size += align_size;
}
pPriv_node = align_addr;
}
//At this point, pPriv_node is the last block, then place the end of the table at the end of the block, find the address to place the end block, end block is only convenient for traversal, so as small as possible, assigned to MEM_MANAGE_MEM_STRUCT_SIZE
align_addr = (struct heap_node *)mmheap_align_down(
(size_t)mmheap_addr_add(pPriv_node) + pPriv_node->mem_size - MEM_MANAGE_MEM_STRUCT_SIZE, MEM_MANAGE_ALIGNMENT_BYTE_DEFAULT);
align_size = (uint8_t *)align_addr - (uint8_t *)mmheap_addr_add(pPriv_node); /*Find the remaining size of the previous block after the end block is allocated*/
if (align_size >= MEM_MANAGE_MINUM_MEM_SIZE) {
pRoot->total_size -= pPriv_node->mem_size - align_size; /*Removing memory consumed by allocating end blocks*/
pRoot->pEnd = align_addr; /*Update the address at the end of the list*/
pPriv_node->next_node = align_addr;
pPriv_node->mem_size = align_size;
align_addr->next_node = NULL;
align_addr->mem_size = 0; /*The end block is not involved in memory allocation, so a direct 0 is sufficient*/
} else { /*The last block is too small, directly as the end block*/
pRoot->pEnd = pPriv_node;
pRoot->total_size -= pPriv_node->mem_size;
}
MMHEAP_ASSERT(pRoot->pStart != NULL);
MMHEAP_ASSERT(pRoot->pEnd != NULL);
}

View File

@@ -0,0 +1,159 @@
/**
* @file drv_mmheap.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __DRV_MMHEAP_H
#define __DRV_MMHEAP_H
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#ifndef MMHEAP_LOCK
#define MMHEAP_LOCK()
#endif
#ifndef MMHEAP_UNLOCK
#define MMHEAP_UNLOCK()
#endif
#ifndef MMHEAP_ASSERT
#define MMHEAP_ASSERT(A) \
if (!(A)) \
printf("mmheap malloc error:drv_mmheap,%d\r\n", __LINE__)
#endif
#ifndef MMHEAP_MALLOC_FAIL
#define MMHEAP_MALLOC_FAIL() printf("mmheap malloc fail:drv_mmheap,%d\r\n", __LINE__)
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct heap_region {
void *addr;
size_t mem_size;
};
struct heap_node {
struct heap_node *next_node;
size_t mem_size;
};
struct heap_info {
struct heap_node *pStart;
struct heap_node *pEnd;
size_t total_size;
};
struct heap_state {
size_t remain_size;
size_t free_node_num;
size_t max_node_size;
size_t min_node_size;
};
void mmheap_init(struct heap_info *pRoot, const struct heap_region *pRigon);
/**
* @brief Alloc start address aligned memory from the heap.
* Alloc aligned address and specified size memory from the heap.
*
* @attention
*
* @param[in] pRoot heap info.
* @param[in] align_size address align mask of the memory.
* @param[in] want_size size of the memory.
*
* @return the pointer to the allocated memory.
*/
void *mmheap_align_alloc(struct heap_info *pRoot, size_t align_size, size_t want_size);
/**
* @brief Alloc memory.
* Allocate size bytes and returns a pointer to the allocated memory.
*
* @attention size should no bigger than MMHEAP_BLK_SIZE_MAX.
*
* @param[in] pRoot heap info.
* @param[in] want_size size of the memory.
*
* @return the pointer to the allocated memory.
*/
void *mmheap_alloc(struct heap_info *pRoot, size_t want_size);
/**
* @brief Realloc memory from the heap.
* Change the size of the memory block pointed to by ptr to size bytes.
*
* @attention
* <ul>
* <li> if ptr is NULL, then the call is equivalent to mmheap_alloc(size), for all values of size.
* <li> if ptr is if size is equal to zero, and ptr is not NULL, then the call is equivalent to mmheap_free(ptr).
* </ul>
*
* @param[in] pRoot heap info.
* @param[in] src_addr old pointer to the memory space.
* @param[in] want_size new size of the memory space.
*
* @return the new pointer to the allocated memory.
*/
void *mmheap_realloc(struct heap_info *pRoot, void *src_addr, size_t want_size);
/**
* @brief Cealloc memory from the heap.
* Change the size of the memory block pointed to by ptr to size bytes.
*
* @attention
* <ul>
* <li> if ptr is NULL, then the call is equivalent to mmheap_alloc(size), for all values of size.
* <li> if ptr is if size is equal to zero, and ptr is not NULL, then the call is equivalent to mmheap_free(ptr).
* </ul>
*
* @param[in] pRoot heap info.
* @param[in] num size number.
* @param[in] size new size of the memory space.
*
* @return the new pointer to the allocated memory.
*/
void *mmheap_calloc(struct heap_info *pRoot, size_t num, size_t size);
/**
* @brief Free the memory.
* Free the memory space pointed to by ptr, which must have been returned by a previous call to mmheap_alloc(), mmheap_aligned_alloc(), or mmheap_realloc().
*
* @attention
*
* @param[in] pRoot heap info.
* @param[in] addr pointer to the memory.
*
* @return None.
*/
void mmheap_free(struct heap_info *pRoot, void *addr);
/**
* @brief get mmheap state
*
* @param pRoot heap info.
* @param pState heap state
*/
void mmheap_get_state(struct heap_info *pRoot, struct heap_state *pState);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,65 @@
#ifndef __COMMON_H
#define __COMMON_H
/**
* @brief Memory access macro
*/
#define BL_RD_WORD(addr) (*((volatile uint32_t *)(uintptr_t)(addr)))
#define BL_WR_WORD(addr, val) ((*(volatile uint32_t *)(uintptr_t)(addr)) = (val))
#define BL_RD_SHORT(addr) (*((volatile uint16_t *)(uintptr_t)(addr)))
#define BL_WR_SHORT(addr, val) ((*(volatile uint16_t *)(uintptr_t)(addr)) = (val))
#define BL_RD_BYTE(addr) (*((volatile uint8_t *)(uintptr_t)(addr)))
#define BL_WR_BYTE(addr, val) ((*(volatile uint8_t *)(uintptr_t)(addr)) = (val))
#define BL_RDWD_FRM_BYTEP(p) ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0]))
#define BL_WRWD_TO_BYTEP(p, val) \
{ \
p[0] = val & 0xff; \
p[1] = (val >> 8) & 0xff; \
p[2] = (val >> 16) & 0xff; \
p[3] = (val >> 24) & 0xff; \
}
/**
* @brief Register access macro
*/
#define BL_RD_REG16(addr, regname) BL_RD_SHORT(addr + regname##_OFFSET)
#define BL_WR_REG16(addr, regname, val) BL_WR_SHORT(addr + regname##_OFFSET, val)
#define BL_RD_REG(addr, regname) BL_RD_WORD(addr + regname##_OFFSET)
#define BL_WR_REG(addr, regname, val) BL_WR_WORD(addr + regname##_OFFSET, val)
#define BL_SET_REG_BIT(val, bitname) ((val) | (1U << bitname##_POS))
#define BL_CLR_REG_BIT(val, bitname) ((val)&bitname##_UMSK)
#define BL_GET_REG_BITS_VAL(val, bitname) (((val)&bitname##_MSK) >> bitname##_POS)
#define BL_SET_REG_BITS_VAL(val, bitname, bitval) (((val)&bitname##_UMSK) | ((uint32_t)(bitval) << bitname##_POS))
#define BL_IS_REG_BIT_SET(val, bitname) (((val) & (1U << (bitname##_POS))) != 0)
#define BL_DRV_DUMMY \
{ \
__ASM volatile("nop"); \
__ASM volatile("nop"); \
__ASM volatile("nop"); \
__ASM volatile("nop"); \
}
/* Std driver attribute macro*/
#ifndef BFLB_USE_CUSTOM_LD_SECTIONS
//#define ATTR_UNI_SYMBOL
#define ATTR_STRINGIFY(x) #x
#define ATTR_TOSTRING(x) ATTR_STRINGIFY(x)
#define ATTR_UNI_SYMBOL __FILE__ ATTR_TOSTRING(__LINE__)
#define ATTR_CLOCK_SECTION __attribute__((section(".sclock_rlt_code." ATTR_UNI_SYMBOL)))
#define ATTR_CLOCK_CONST_SECTION __attribute__((section(".sclock_rlt_const." ATTR_UNI_SYMBOL)))
#define ATTR_TCM_SECTION __attribute__((section(".tcm_code." ATTR_UNI_SYMBOL)))
#define ATTR_TCM_CONST_SECTION __attribute__((section(".tcm_const." ATTR_UNI_SYMBOL)))
#define ATTR_DTCM_SECTION __attribute__((section(".tcm_data")))
#define ATTR_HSRAM_SECTION __attribute__((section(".hsram_code")))
#define ATTR_DMA_RAM_SECTION __attribute__((section(".system_ram")))
#define ATTR_NOCACHE_RAM_SECTION __attribute__((section(".nocache_ram")))
#define ATTR_NOCACHE_NOINIT_RAM_SECTION __attribute__((section(".nocache_noinit_ram")))
#define ATTR_HBN_RAM_SECTION __attribute__((section(".hbn_ram_code")))
#define ATTR_HBN_RAM_CONST_SECTION __attribute__((section(".hbn_ram_data")))
#define ATTR_EALIGN(x) __attribute__((aligned(x)))
#define ATTR_FALLTHROUGH() __attribute__((fallthrough))
#define ATTR_USED __attribute__((__used__))
#else
#include "bl_ld_sections.h"
#endif /* BFLB_USE_CUSTOM_LD_SECTIONS */
#endif

View File

@@ -0,0 +1,112 @@
#ifndef __GCC_H
#define __GCC_H
#ifndef __ORDER_BIG_ENDIAN__
#define __ORDER_BIG_ENDIAN__ (1)
#endif
#ifndef __ORDER_LITTLE_ENDIAN__
#define __ORDER_LITTLE_ENDIAN__ (2)
#endif
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
/* CPP header guards */
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#define __MACRO_BEGIN do {
#define __MACRO_END \
} \
while (0)
#if defined(__GNUC__)
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __INLINE__
#define __INLINE__ inline
#endif
#ifndef __ALWAYS_INLINE
#define __ALWAYS_INLINE inline __attribute__((always_inline))
#endif
#ifndef __ALWAYS_STATIC_INLINE
#define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __UNUSED__
#define __UNUSED__ __attribute__((__unused__))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __WEAK__
#define __WEAK__ __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed, aligned(1)))
#endif
#ifndef __PACKED__
#define __PACKED__ __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
#endif
#ifndef __IRQ
#define __IRQ __attribute__((interrupt))
#endif
#ifndef __IRQ_ALIGN64
#define __IRQ_ALIGN64 __attribute__((interrupt, aligned(64)))
#endif
#ifndef ALIGN4
#define ALIGN4 __attribute((aligned(4)))
#endif
#ifndef PACK_START
#define PACK_START
#endif
#ifndef PACK_END
#define PACK_END __attribute__((packed))
#endif
#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
#ifndef __ALIGNED__
#define __ALIGNED__(x) __attribute__((aligned(x)))
#endif
#ifndef SECTION
#define SECTION(x) __attribute__((section(x)))
#endif
#ifndef __CONST__
#define __CONST__ __attribute__((__const__))
#endif
#ifndef __NAKED__
#define __NAKED__ __attribute__((naked))
#endif
#ifndef __deprecated
#define __deprecated __attribute__((deprecated))
#endif
#endif
#endif

View File

@@ -0,0 +1,253 @@
/**
* @file misc.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "misc.h"
#ifndef BFLB_USE_ROM_DRIVER
/****************************************************************************/ /**
* @brief Char memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of char
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memcpy(void *dst, const void *src, uint32_t n)
{
const uint8_t *p = src;
uint8_t *q = dst;
while (n--) {
*q++ = *p++;
}
return dst;
}
/****************************************************************************/ /**
* @brief Word memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of words
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ uint32_t *ATTR_TCM_SECTION arch_memcpy4(uint32_t *dst, const uint32_t *src, uint32_t n)
{
const uint32_t *p = src;
uint32_t *q = dst;
while (n--) {
*q++ = *p++;
}
return dst;
}
/****************************************************************************/ /**
* @brief Fast memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of bytes
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memcpy_fast(void *pdst, const void *psrc, uint32_t n)
{
uint32_t left, done, i = 0;
uint8_t *dst = (uint8_t *)pdst;
uint8_t *src = (uint8_t *)psrc;
if (((uint32_t)(uintptr_t)dst & 0x3) == 0 && ((uint32_t)(uintptr_t)src & 0x3) == 0) {
arch_memcpy4((uint32_t *)dst, (const uint32_t *)src, n >> 2);
left = n % 4;
done = n - left;
while (i < left) {
dst[done + i] = src[done + i];
i++;
}
} else {
arch_memcpy(dst, src, n);
}
return dst;
}
/****************************************************************************/ /**
* @brief char memset
*
* @param dst: Destination
* @param val: Value to set
* @param n: Count of char
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memset(void *s, uint8_t c, uint32_t n)
{
uint8_t *p = (uint8_t *)s;
while (n > 0) {
*p++ = (uint8_t)c;
--n;
}
return s;
}
/****************************************************************************/ /**
* @brief Word memset
*
* @param dst: Destination
* @param val: Value to set
* @param n: Count of words
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ uint32_t *ATTR_TCM_SECTION arch_memset4(uint32_t *dst, const uint32_t val, uint32_t n)
{
uint32_t *q = dst;
while (n--) {
*q++ = val;
}
return dst;
}
/****************************************************************************/ /**
* @brief string compare
*
* @param s1: string 1
* @param s2: string 2
* @param n: Count of chars
*
* @return compare result
*
*******************************************************************************/
__WEAK__ int ATTR_TCM_SECTION arch_memcmp(const void *s1, const void *s2, uint32_t n)
{
const unsigned char *c1 = s1, *c2 = s2;
int d = 0;
while (n--) {
d = (int)*c1++ - (int)*c2++;
if (d) {
break;
}
}
return d;
}
#endif
void memcopy_to_fifo(void *fifo_addr, uint8_t *data, uint32_t length)
{
uint8_t *p = (uint8_t *)fifo_addr;
uint8_t *q = data;
while (length--) {
*p = *q++;
}
}
void fifocopy_to_mem(void *fifo_addr, uint8_t *data, uint32_t length)
{
uint8_t *p = (uint8_t *)fifo_addr;
uint8_t *q = data;
while (length--) {
*q++ = *p;
}
}
/****************************************************************************/ /**
* @brief get u64 first number 1 from right to left
*
* @param val: target value
* @param bit: first 1 in bit
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
int arch_ffsll(uint64_t *val, uint32_t *bit)
{
if (!*val) {
return ERROR;
}
*bit = __builtin_ffsll(*val) - 1;
*val &= ~((1ULL) << (*bit));
return 0;
}
int arch_ctzll(uint64_t *val, uint32_t *bit)
{
if (!*val)
return -1;
*bit = __builtin_ctzll(*val);
*val &= ~((1ULL) << (*bit));
return 0;
}
int arch_clzll(uint64_t *val, uint32_t *bit)
{
if (!*val)
return -1;
*bit = __builtin_clzll(*val);
*val &= ~((1ULL) << (*bit));
return 0;
}
#ifdef DEBUG
/*******************************************************************************
* @brief Reports the name of the source file and the source line number
* where the CHECK_PARAM error has occurred.
* @param file: Pointer to the source file name
* @param line: assert_param error line source number
* @return None
*******************************************************************************/
void check_failed(uint8_t *file, uint32_t line)
{
/* Infinite loop */
while (1)
;
}
#endif /* DEBUG */
/*@} end of group DRIVER_Public_Functions */
/*@} end of group DRIVER_COMMON */
/*@} end of group BL602_Periph_Driver */

View File

@@ -0,0 +1,131 @@
/**
* @file misc.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _MISC_H
#define _MISC_H
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include "compiler/gcc.h"
#include "compiler/common.h"
#ifdef BIT
#undef BIT
#define BIT(n) (1UL << (n))
#else
#define BIT(n) (1UL << (n))
#endif
/**
* @brief Null Type definition
*/
#ifndef NULL
#define NULL 0
#endif
/**
* @brief Error type definition
*/
typedef enum {
SUCCESS = 0,
ERROR = 1,
TIMEOUT = 2,
INVALID = 3, /* invalid arguments */
NORESC = 4 /* no resource or resource temperary unavailable */
} BL_Err_Type;
/**
* @brief Functional type definition
*/
typedef enum {
DISABLE = 0,
ENABLE = 1,
} BL_Fun_Type;
/**
* @brief Status type definition
*/
typedef enum {
RESET = 0,
SET = 1,
} BL_Sts_Type;
/**
* @brief Mask type definition
*/
typedef enum {
UNMASK = 0,
MASK = 1
} BL_Mask_Type;
/**
* @brief Logical status Type definition
*/
typedef enum {
LOGIC_LO = 0,
LOGIC_HI = !LOGIC_LO
} LogicalStatus;
/**
* @brief Active status Type definition
*/
typedef enum {
DEACTIVE = 0,
ACTIVE = !DEACTIVE
} ActiveStatus;
/**
* @brief Interrupt callback function type
*/
typedef void(intCallback_Type)(void);
typedef void (*pFunc)(void);
#define ARCH_MemCpy arch_memcpy
#define ARCH_MemSet arch_memset
#define ARCH_MemCmp arch_memcmp
#define ARCH_MemCpy4 arch_memcpy4
#define ARCH_MemCpy_Fast arch_memcpy_fast
#define ARCH_MemSet4 arch_memset4
#ifdef DEBUG
void check_failed(uint8_t *file, uint32_t line);
#define CHECK_PARAM(expr) ((expr) ? (void)0 : check_failed((uint8_t *)__FILE__, __LINE__))
#else
#define CHECK_PARAM(expr) ((void)0)
#endif /* DEBUG */
void *arch_memcpy(void *dst, const void *src, uint32_t n);
void *arch_memset(void *s, uint8_t c, uint32_t n);
int arch_memcmp(const void *s1, const void *s2, uint32_t n);
uint32_t *arch_memcpy4(uint32_t *dst, const uint32_t *src, uint32_t n);
void *arch_memcpy_fast(void *pdst, const void *psrc, uint32_t n);
uint32_t *arch_memset4(uint32_t *dst, const uint32_t val, uint32_t n);
void memcopy_to_fifo(void *fifo_addr, uint8_t *data, uint32_t length);
void fifocopy_to_mem(void *fifo_addr, uint8_t *data, uint32_t length);
int arch_ctzll(uint64_t *val, uint32_t *bit);
int arch_clzll(uint64_t *val, uint32_t *bit);
int arch_ffsll(uint64_t *val, uint32_t *bit);
#endif

View File

@@ -0,0 +1,544 @@
/**
******************************************************************************
* @file partition.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2019 Bouffalo Lab</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
#include "partition.h"
#include "softcrc.h"
#include "bflb_platform.h"
/** @addtogroup BFLB_Common_Driver
* @{
*/
/** @addtogroup PARTITION
* @{
*/
/** @defgroup PARTITION_Private_Macros
* @{
*/
/*@} end of group PARTITION_Private_Macros */
/** @defgroup PARTITION_Private_Types
* @{
*/
/*@} end of group PARTITION_Private_Types */
/** @defgroup PARTITION_Private_Variables
* @{
*/
p_pt_table_flash_erase gp_pt_table_flash_erase = NULL;
p_pt_table_flash_write gp_pt_table_flash_write = NULL;
p_pt_table_flash_read gp_pt_table_flash_read = NULL;
pt_table_iap_param_type p_iap_param;
/*@} end of group PARTITION_Private_Variables */
/** @defgroup PARTITION_Global_Variables
* @{
*/
extern int main(void);
/*@} end of group PARTITION_Global_Variables */
/** @defgroup PARTITION_Private_Fun_Declaration
* @{
*/
/*@} end of group PARTITION_Private_Fun_Declaration */
/** @defgroup PARTITION_Private_Functions
* @{
*/
/****************************************************************************/ /**
* @brief Judge partition table valid
*
* @param ptStuff: Partition table stuff pointer
*
* @return 0 for invalid and 1 for valid
*
*******************************************************************************/
static uint8_t pt_table_valid(pt_table_stuff_config *pt_stuff)
{
pt_table_config *pt_table = &pt_stuff->pt_table;
pt_table_entry_config *pt_entries = pt_stuff->pt_entries;
uint32_t *p_crc32;
uint32_t entriesLen = sizeof(pt_table_entry_config) * pt_table->entryCnt;
if (pt_table->magicCode == BFLB_PT_MAGIC_CODE) {
if (pt_table->entryCnt > PT_ENTRY_MAX) {
MSG("PT Entry Count Error\r\n");
return 0;
}
if (pt_table->crc32 !=
BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4)) {
MSG("PT CRC Error\r\n");
return 0;
}
/* ToDo it is a trap here, when entryCnt > 8, crc32 will overflow, comment by zhangcheng */
p_crc32 = (uint32_t *)((uintptr_t)pt_entries + entriesLen);
if (*p_crc32 != BFLB_Soft_CRC32((uint8_t *)pt_entries, entriesLen)) {
MSG("PT Entry CRC Error\r\n");
return 0;
}
return 1;
}
return 0;
}
/*@} end of group PARTITION_Private_Functions */
/** @defgroup PARTITION_Public_Functions
* @{
*/
/****************************************************************************/ /**
* @brief Register partition flash read write erase fucntion
*
* @param erase: Flash erase function
* @param write: Flash write function
* @param read: Flash read function
*
* @return None
*
*******************************************************************************/
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read)
{
gp_pt_table_flash_erase = erase;
gp_pt_table_flash_write = write;
gp_pt_table_flash_read = read;
}
/****************************************************************************/ /**
* @brief Get active partition table whole stuff
*
* @param ptStuff[2]: Partition table stuff pointer
*
* @return Active partition table ID
*
*******************************************************************************/
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2])
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_id_type activePtID;
if (ptStuff == NULL) {
return PT_TABLE_ID_INVALID;
}
activePtID = PT_TABLE_ID_INVALID;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&ptStuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&ptStuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&ptStuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&ptStuff[1]);
if (pt_valid[0] == 1 && pt_valid[1] == 1) {
if (ptStuff[0].pt_table.age >= ptStuff[1].pt_table.age) {
activePtID = PT_TABLE_ID_0;
} else {
activePtID = PT_TABLE_ID_1;
}
} else if (pt_valid[0] == 1) {
activePtID = PT_TABLE_ID_0;
} else if (pt_valid[1] == 1) {
activePtID = PT_TABLE_ID_1;
}
return activePtID;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry ID
*
* @param ptStuff: Partition table stuff pointer
* @param type: Type of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
pt_table_entry_type type,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (pt_stuff->pt_entries[i].type == type) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry name
*
* @param ptStuff: Partition table stuff pointer
* @param name: Name of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
uint8_t *name,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
uint32_t len = strlen((char *)name);
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (strlen((char *)pt_stuff->pt_entries[i].name) == len &&
memcmp((char *)pt_stuff->pt_entries[i].name, (char *)name, len) == 0) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Update partition entry
*
* @param targetTableID: Target partition table to update
* @param ptStuff: Partition table stuff pointer
* @param ptEntry: Partition entry pointer to update
*
* @return Partition update result
*
*******************************************************************************/
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
BL_Err_Type ret;
uint32_t write_addr;
uint32_t entries_len;
pt_table_config *pt_table;
pt_table_entry_config *pt_entries;
uint32_t *crc32;
if (pt_entry == NULL || pt_stuff == NULL) {
return PT_ERROR_PARAMETER;
}
pt_table = &pt_stuff->pt_table;
pt_entries = pt_stuff->pt_entries;
if (target_table_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (target_table_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
for (i = 0; i < pt_table->entryCnt; i++) {
if (pt_entries[i].type == pt_entry->type) {
ARCH_MemCpy_Fast(&pt_entries[i], pt_entry, sizeof(pt_table_entry_config));
break;
}
}
if (i == pt_table->entryCnt) {
/* Not found this entry ,add new one */
if (pt_table->entryCnt < PT_ENTRY_MAX) {
ARCH_MemCpy_Fast(&pt_entries[pt_table->entryCnt], pt_entry, sizeof(pt_table_entry_config));
pt_table->entryCnt++;
} else {
return PT_ERROR_ENTRY_UPDATE_FAIL;
}
}
/* Prepare write back to flash */
/* Update age */
pt_table->age++;
pt_table->crc32 = BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4);
/* Update entries CRC */
entries_len = pt_table->entryCnt * sizeof(pt_table_entry_config);
crc32 = (uint32_t *)((uintptr_t)pt_entries + entries_len);
*crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_entries[0], entries_len);
/* Write back to flash */
/* Erase flash first */
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) + entries_len + 4 - 1);
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config) + entries_len + 4);
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_WRITE;
}
/* Write flash */
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)pt_stuff, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
/****************************************************************************/ /**
* @brief Create partition entry
*
* @param ptID: Partition table ID
*
* @return Partition create result
*
*******************************************************************************/
pt_table_error_type pt_table_create(pt_table_id_type pt_id)
{
uint32_t write_addr;
BL_Err_Type ret;
pt_table_config pt_table;
if (pt_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (pt_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
/* Prepare write back to flash */
pt_table.magicCode = BFLB_PT_MAGIC_CODE;
pt_table.version = 0;
pt_table.entryCnt = 0;
pt_table.age = 0;
pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_table, sizeof(pt_table_config) - 4);
/* Write back to flash */
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) - 1);
ret = gp_pt_table_flash_erase(write_addr,sizeof(pt_table_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)&pt_table, sizeof(pt_table_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_dump(void)
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_stuff_config pt_stuff[2];
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if (pt_valid[0]) {
MSG("PT TABLE0 valid\r\n");
} else {
MSG("PT TABLE0 invalid\r\n");
}
if (pt_valid[1]) {
MSG("PT TABLE1 valid\r\n");
} else {
MSG("PT TABLE1 invalid\r\n");
}
for (int i = 0; i < 2; i++) {
if (pt_valid[i] == 1) {
MSG("ptStuff[%d].pt_table.magicCode 0x%08x\r\n", i, pt_stuff[i].pt_table.magicCode);
MSG("ptStuff[%d].pt_table.version 0x%08x\r\n", i, pt_stuff[i].pt_table.version);
MSG("ptStuff[%d].pt_table.entryCnt 0x%08x\r\n", i, pt_stuff[i].pt_table.entryCnt);
MSG("ptStuff[%d].pt_table.age 0x%08x\r\n", i, pt_stuff[i].pt_table.age);
MSG("ptStuff[%d].pt_table.crc32 0x%08x\r\n", i, pt_stuff[i].pt_table.crc32);
for (int j = 0; j < pt_stuff[i].pt_table.entryCnt; j++) {
MSG("ptStuff[%d].pt_entries[%d].type 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].type);
MSG("ptStuff[%d].pt_entries[%d].device 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].device);
MSG("ptStuff[%d].pt_entries[%d].active_index 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].active_index);
MSG("ptStuff[%d].pt_entries[%d].Address[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[0]);
MSG("ptStuff[%d].pt_entries[%d].Address[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[1]);
MSG("ptStuff[%d].pt_entries[%d].maxLen[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[0]);
MSG("ptStuff[%d].pt_entries[%d].maxLen[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[1]);
MSG("ptStuff[%d].pt_entries[%d].len 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].len);
MSG("ptStuff[%d].pt_entries[%d].age 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].age);
}
}
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para)
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_stuff_config pt_stuff[2];
uint8_t active_index;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if ((pt_valid[0] == 1) && (pt_valid[1] == 1)) {
if (pt_stuff[0].pt_table.age >= pt_stuff[1].pt_table.age) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
}
} else if (pt_valid[1] == 1) {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
} else if (pt_valid[0] == 1) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
return PT_ERROR_TABLE_NOT_VALID;
}
MSG("inactive_table_index %d, inactive index %d , IAP start addr %08x \r\n", para->inactive_table_index, para->inactive_index, para->iap_start_addr);
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para)
{
pt_table_stuff_config pt_stuff, pt_stuff_write;
int32_t ret;
uint32_t *p_crc32;
uint32_t entries_len;
if (para->inactive_table_index == 1) {
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
} else if (para->inactive_table_index == 0) {
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
}
ARCH_MemCpy_Fast((void *)&pt_stuff_write, (void *)&pt_stuff, sizeof(pt_table_stuff_config));
pt_stuff_write.pt_table.age += 1;
pt_stuff_write.pt_entries[0].active_index = !(pt_stuff_write.pt_entries[0].active_index & 0x01);
pt_stuff_write.pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_stuff_write, sizeof(pt_table_config) - 4);
entries_len = sizeof(pt_table_entry_config) * pt_stuff_write.pt_table.entryCnt;
//pt_stuff_write.crc32 = BFLB_Soft_CRC32((uint8_t*)pt_stuff_write.pt_entries,entries_len);
p_crc32 = (uint32_t *)((uintptr_t)pt_stuff_write.pt_entries + entries_len);
*p_crc32 = BFLB_Soft_CRC32((uint8_t *)pt_stuff_write.pt_entries, entries_len);
if (para->inactive_table_index == 1) {
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, BFLB_PT_TABLE1_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
} else if (para->inactive_table_index == 0) {
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, BFLB_PT_TABLE0_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
}
MSG("Update pt_table suss\r\n");
return PT_ERROR_SUCCESS;
}
/*@} end of group PARTITION_Public_Functions */
/*@} end of group PARTITION */
/*@} end of group BFLB_Common_Driver */

View File

@@ -0,0 +1,209 @@
/**
******************************************************************************
* @file partition.h
* @version V1.0
* @date
* @brief This file is the standard driver header file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
#ifndef __PARTITION_H__
#define __PARTITION_H__
#include "misc.h"
/** @addtogroup BFLB_Common_Driver
* @{
*/
/** @addtogroup PARTITION
* @{
*/
/** @defgroup PARTITION_Public_Types
* @{
*/
/**
* @brief Partition table error type definition
*/
typedef enum {
PT_ERROR_SUCCESS, /*!< Partition table error type:success */
PT_ERROR_TABLE_NOT_VALID, /*!< Partition table error type:table not found */
PT_ERROR_ENTRY_NOT_FOUND, /*!< Partition table error type:entry not found */
PT_ERROR_ENTRY_UPDATE_FAIL, /*!< Partition table error type:entry update fail */
PT_ERROR_CRC32, /*!< Partition table error type:crc32 error */
PT_ERROR_PARAMETER, /*!< Partition table error type:input parameter error */
PT_ERROR_FALSH_READ, /*!< Partition table error type:flash read error */
PT_ERROR_FALSH_WRITE, /*!< Partition table error type:flash write error */
PT_ERROR_FALSH_ERASE, /*!< Partition table error type:flash erase error */
} pt_table_error_type;
/**
* @brief Partition id type definition
*/
typedef enum {
PT_TABLE_ID_0, /*!< Partition table ID 0 */
PT_TABLE_ID_1, /*!< Partition table ID 1 */
PT_TABLE_ID_INVALID, /*!< Partition table ID invalid */
} pt_table_id_type;
/**
* @brief Partition id type definition
*/
typedef enum {
PT_ENTRY_FW_CPU0, /*!< Partition entry type:CPU0 firmware */
PT_ENTRY_FW_CPU1, /*!< Partition entry type:CPU1 firmware */
PT_ENTRY_MAX = 16, /*!< Partition entry type:Max */
} pt_table_entry_type;
/**
* @brief Partition table config definition
*/
typedef struct
{
uint32_t magicCode; /*!< Partition table magic code */
uint16_t version; /*!< Partition table verdion */
uint16_t entryCnt; /*!< Partition table entry count */
uint32_t age; /*!< Partition table age */
uint32_t crc32; /*!< Partition table CRC32 value */
} pt_table_config;
/**
* @brief Partition table entry config definition
*/
typedef struct
{
uint8_t type; /*!< Partition entry type */
uint8_t device; /*!< Partition entry device */
uint8_t active_index; /*!< Partition entry active index */
uint8_t name[9]; /*!< Partition entry name */
uint32_t start_address[2]; /*!< Partition entry start address */
uint32_t max_len[2]; /*!< Partition entry max length */
uint32_t len; /*!< Partition entry length */
uint32_t age; /*!< Partition entry age */
} pt_table_entry_config;
/**
* @brief Partition table stuff config definition
*/
typedef struct
{
pt_table_config pt_table; /*!< Partition table */
pt_table_entry_config pt_entries[PT_ENTRY_MAX]; /*!< Partition entries */
uint32_t crc32; /*!< Partition entries crc32 */
} pt_table_stuff_config;
/**
* @brief Partition table iap param definition
*/
typedef struct
{
uint32_t iap_start_addr;
uint32_t iap_write_addr;
uint32_t iap_img_len;
uint8_t inactive_index;
uint8_t inactive_table_index;
} pt_table_iap_param_type;
/*@} end of group PARTITION_Public_Types */
/** @defgroup PARTITION_Public_Constants
* @{
*/
/** @defgroup pt_table_error_type
* @{
*/
#define IS_PTTABLE_ERROR_TYPE(type) (((type) == PT_ERROR_SUCCESS) || \
((type) == PT_ERROR_TABLE_NOT_VALID) || \
((type) == PT_ERROR_ENTRY_NOT_FOUND) || \
((type) == PT_ERROR_ENTRY_UPDATE_FAIL) || \
((type) == PT_ERROR_CRC32) || \
((type) == PT_ERROR_PARAMETER) || \
((type) == PT_ERROR_FALSH_READ) || \
((type) == PT_ERROR_FALSH_WRITE) || \
((type) == PT_ERROR_FALSH_ERASE))
/** @defgroup pt_table_id_type
* @{
*/
#define IS_PTTABLE_ID_TYPE(type) (((type) == PT_TABLE_ID_0) || \
((type) == PT_TABLE_ID_1) || \
((type) == PT_TABLE_ID_INVALID))
/** @defgroup pt_table_entry_type
* @{
*/
#define IS_PTTABLE_ENTRY_TYPE(type) (((type) == PT_ENTRY_FW_CPU0) || \
((type) == PT_ENTRY_FW_CPU1) || \
((type) == PT_ENTRY_MAX))
/*@} end of group PARTITION_Public_Constants */
/** @defgroup PARTITION_Public_Macros
* @{
*/
#define BFLB_PT_TABLE0_ADDRESS 0xE000
#define BFLB_PT_TABLE1_ADDRESS 0xF000
#define BFLB_PT_MAGIC_CODE 0x54504642
typedef BL_Err_Type (*p_pt_table_flash_erase)(uint32_t startaddr, uint32_t endaddr);
typedef BL_Err_Type (*p_pt_table_flash_write)(uint32_t addr, uint8_t *data, uint32_t len);
typedef BL_Err_Type (*p_pt_table_flash_read)(uint32_t addr, uint8_t *data, uint32_t len);
/*@} end of group PARTITION_Public_Macros */
/** @defgroup PARTITION_Public_Functions
* @{
*/
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read);
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2]);
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
pt_table_entry_type type,
pt_table_entry_config *pt_entry);
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
uint8_t *name,
pt_table_entry_config *pt_entry);
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry);
pt_table_error_type pt_table_create(pt_table_id_type pt_id);
pt_table_error_type pt_table_dump(void);
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para);
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para);
/*@} end of group PARTITION_Public_Functions */
/*@} end of group PARTITION */
/*@} end of group BFLB_Common_Driver */
extern pt_table_iap_param_type p_iap_param;
#endif /* __PARTITION_H__ */

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