添加一些关于midi播放的项目

This commit is contained in:
terryLP
2025-03-24 14:30:56 +08:00
parent e31eb22077
commit 498b4ef13b
699 changed files with 186162 additions and 1 deletions
+294
View File
@@ -0,0 +1,294 @@
<?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.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545" 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.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545" name="Default" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545.180510379" name="/" resourcePath="">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.1854309630" name="ARM Cross GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.317855049" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1286321645" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.suffix.1313009165" name="Suffix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.suffix"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1651144129" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.169014546" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1880647345" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.804656651" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.280446594" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.1498171630" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.1990781892" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.8805082" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.useglobalpath.278583970" name="Use global path" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.useglobalpath"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.path.546982043" name="Path" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.path"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1826145987" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.1281777222" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.1534885687" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.567377215" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m3" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture.66992855" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.111334941" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.thumbinterwork.1336737141" name="Thumb interwork (-mthumb-interwork)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.thumbinterwork"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.endianness.1822386400" name="Endianness" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.endianness"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.1703674908" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.64687859" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.unalignedaccess.847119189" name="Unaligned access" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.unalignedaccess"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.family.1233989112" name="AArch64 family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.family"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crc.141796021" name="Feature crc" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crc"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crypto.632126161" name="Feature crypto" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.crypto"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.fp.27094266" name="Feature fp" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.fp"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.simd.1362729990" name="Feature simd" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.feature.simd"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.cmodel.291306185" name="Code model" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.cmodel"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.strictalign.1752237916" name="Strict align (-mstrict-align)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.aarch64.target.strictalign"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.target.other.1844063049" name="Other target flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.target.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.380732401" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.64225249" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.796065441" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.1709136203" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.208096495" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nocommon.1890422468" name="No common unitialized (-fno-common)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nocommon"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.noinlinefunctions.1732520119" name="Do not inline functions (-fno-inline-functions)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.noinlinefunctions"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.freestanding.1614934619" name="Assume freestanding environment (-ffreestanding)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.freestanding"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nobuiltin.885217862" name="Disable builtin (-fno-builtin)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nobuiltin"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant.456535266" name="Single precision constants (-fsingle-precision-constant)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.PIC.948522056" name="Position independent code (-fPIC)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.PIC"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto.920464168" name="Link-time optimizer (-flto)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nomoveloopinvariants.1086755533" name="Disable loop invariant move (-fno-move-loop-invariants)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.nomoveloopinvariants"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.other.484184218" name="Other optimization flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1047148244" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" value="GNU MCU Eclipse ARM Embedded GCC" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.975432137" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" value="962691777" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.syntaxonly.719611275" name="Check syntax only (-fsyntax-only)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.syntaxonly"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedantic.655392956" name="Pedantic (-pedantic)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedantic"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedanticerrors.838673661" name="Pedantic warnings as errors (-pedantic-errors)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedanticerrors"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.nowarn.184702772" name="Inhibit all warnings (-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.nowarn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused.1247599068" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized.69481655" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1011826063" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.1466263314" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.missingdeclaration.1016086456" name="Warn on undeclared global function (-Wmissing-declaration)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.missingdeclaration"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion.318529486" name="Warn on implicit conversions (-Wconversion)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith.1166168125" name="Warn if pointer arithmetic (-Wpointer-arith)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.padded.818710921" name="Warn if padding is included (-Wpadded)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.padded"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.shadow.241925492" name="Warn if shadowed variable (-Wshadow)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.shadow"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop.1056298086" name="Warn if suspicious logical ops (-Wlogical-op)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.agreggatereturn.2052857936" name="Warn if struct is returned (-Wagreggate-return)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.agreggatereturn"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.floatequal.421237335" name="Warn if floats are compared as equal (-Wfloat-equal)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.floatequal"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.toerrors.684128510" name="Generate errors instead of warnings (-Werror)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.toerrors"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.other.963498251" name="Other warning flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1189187438" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.838921950" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.prof.177371169" name="Generate prof information (-p)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.prof"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.gprof.1651192586" name="Generate gprof information (-pg)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.gprof"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other.426915838" name="Other debugging flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.other"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab.539132781" name="showDevicesTab" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.showDevicesTab"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1999827117" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder id="ilg.gnuarmeclipse.managedbuild.cross.builder.1003773746" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.281298827" name="GNU ARM Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.89692611" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.2110196406" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1267441967" name="GNU ARM Cross C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.1480581090" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.832639079" name="GNU ARM Cross C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.967431238" name="GNU ARM Cross C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.258259234" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.551251464" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.430384890" name="GNU ARM Cross C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.1125524436" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.1871187027" name="GNU ARM Cross Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.697667924" name="GNU ARM Cross Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.624590343" name="GNU ARM Cross Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.1502717734" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.575750567" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.538968576" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.2045055899" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.241488988" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.947128970" name="GNU ARM Cross Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.49474267" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.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="music-box-nv32.null.1091771498" name="music-box-nv32"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545;ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545.180510379;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1267441967;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.1480581090">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/music-box-nv32"/>
</configuration>
</storageModule>
</cproject>
+41
View File
@@ -0,0 +1,41 @@
# Object files
*.o
*.ko
*.obj
*.elf
*.bin
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
.vscode/ipch
*.lst
*.map
*.d
.DS_Store
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>music-box-nv32</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.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.966743545" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-465831206387559947" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//Ring-Buffer/ringbuffer.h=UTF-8
+17
View File
@@ -0,0 +1,17 @@
language: c
dist: trusty
sudo: required
before_install:
- sudo apt-get -qq update
- sudo apt-get install -y gcc-arm-none-eabi
compiler:
- arm-none-eabi-gcc
script:
- make
notifications:
email: true
+23
View File
@@ -0,0 +1,23 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"args": ["F:\\Users\\yuan\\Desktop\\midi-to-hex-example\\scoreList.raw"]
},
{
"type": "cortex-debug",
"request": "launch",
"servertype": "jlink",
"cwd": "${workspaceRoot}",
"executable": "./music-box-nv32.elf",
"name": "Debug (J-Link)",
"device": "NV32F100",
"interface": "swd"
}
]
}
+22
View File
@@ -0,0 +1,22 @@
{
"files.encoding": "gbk",
"files.associations": {
"common.h": "c",
"gpio.h": "c",
"synthcore.h": "c",
"nv32.h": "c",
"xhash": "c",
"xtree": "c",
"xutility": "c",
"algorithm": "c",
"list": "c",
"keyscan.h": "c",
"stdint.h": "c",
"flash.h": "c",
"rtc.h": "c"
},
"C_Cpp.default.cStandard": "c99",
"C_Cpp.default.defines": ["NV32"],
"cortex-debug.JLinkGDBServerPath":"D:/SEGGER/JLink/JLinkGDBServerCL.exe"
}
@@ -0,0 +1,22 @@
# 查找最后一个等于或者大于key的元素
def findLastEqualSmaller(arr, key):
left = 0
right = len(arr) - 1
length = len(arr)
# 这里必须是 <=
while left <= right:
mid = (left + right) // 2
if arr[mid] >= key:
right = mid - 1
else:
left = mid + 1
if left>=length:
left=length-1
return left
arr=[6,3,4,1,9]
idx = findLastEqualSmaller(arr,11)
print('Idx:',idx)
print('Value:',arr[idx])
@@ -0,0 +1,251 @@
#include <stdint.h>
#include "common.h"
#include "rtc.h"
#include "uart.h"
#include "sysinit.h"
#include "flash.h"
#include "eeprom.h"
#include "ringbuffer.h"
#include "DownloadScoreData.h"
#include "Player.h"
#include <string.h>
#define EVENT_FRAME_FLAG 0x776E //ASCII:"wn"
enum _CMD
{
CMD_FLASH_WRITE_START = 0x01,
CMD_FLASH_WRITE_BLOCK,
CMD_FLASH_WRITE_END,
CMD_FLASH_SIZE,
CMD_SCHEDULER_PREV,
CMD_SCHEDULER_NEXT,
};
#define CMD_OFFEST 0x04
typedef struct _CMD_FLASH_WRITE_BLOCK_HEADER
{
uint16_t blockIndex;
uint16_t dataLen;
} __attribute__((packed)) CMD_FLASH_WRITE_BLOCK_HEADER;
typedef enum _EVENT_FRAME_PARSER_STATUS
{
FRAME_PARSER_STATUS_IDLE = 0,
FRAME_PARSER_STATUS_SOF_LO,
FRAME_PARSER_STATUS_SOF_HI,
FRAME_PARSER_STATUS_RECV_CMD_LEN,
} EVENT_FRAME_PARSER_STATUS;
EVENT_FRAME_PARSER_STATUS frameParseStatus = FRAME_PARSER_STATUS_IDLE;
/* application address */
#define BOOT_ADDR 24 * 1024 //24k
/* flash block size */
#define BLOCK_SIZE 512
ring_buffer_t ring_buffer;
uint8_t cmdBuf[1024];
uint8_t cmdRetBuf[1024];
uint8_t blockBuf[BLOCK_SIZE];
extern uint32_t __SCORE_DATA_FLASH_SIZE__;
extern Player mPlayer;
void UART_HandleInt(UART_Type *pUART)
{
volatile uint8_t read_temp = 0;
/* 检查接收是否过载 */
if (UART_CheckFlag(pUART, UART_FlagOR))
{
read_temp = UART_ReadDataReg(pUART);
}
/* 检测接收器是否满 */
else if (UART_IsRxBuffFull(pUART))
{
/* 接收数据的缓冲区 */
read_temp = UART_ReadDataReg(pUART);
ring_buffer_queue(&ring_buffer, read_temp);
}
}
/**
* Initialize UART1 in 8N1 mode
*/
void uart_init()
{
UART_ConfigType sConfig;
sConfig.u32SysClkHz = BUS_CLK_HZ; //选择时钟源为总线时钟
sConfig.u32Baudrate = 115200; //设置波特率
UART_Init(UART0, &sConfig); //初始化串口 1
UART_SetCallback(UART_HandleInt);
UART_EnableInterrupt(UART0, UART_RxBuffFullInt);
UART_EnableInterrupt(UART0, UART_RxOverrunInt);
SIM_RemapUART0Pin();
NVIC_EnableIRQ(UART0_IRQn);
}
void DownloadInit()
{
uart_init();
ring_buffer_init(&ring_buffer);
Flash_Init();
}
uint8_t *GetCmdDataPtr(uint8_t *buffer)
{
return buffer + CMD_OFFEST;
}
int Protocol_Process(unsigned char *Buf)
{
int retByteNum = 0;
uint8_t *rbf;
uint32_t fSize = (uint32_t)(&__SCORE_DATA_FLASH_SIZE__);
CMD_FLASH_WRITE_BLOCK_HEADER *cmdFlashWriteBlockHeader;
switch (Buf[0])
{
case CMD_FLASH_WRITE_START:
StopPlayScheduler(&mPlayer);
rbf = GetCmdDataPtr(cmdRetBuf);
rbf[0] = Buf[0];
retByteNum = 1;
break;
case CMD_FLASH_WRITE_END:
StartPlayScheduler(&mPlayer);
rbf = GetCmdDataPtr(cmdRetBuf);
rbf[0] = Buf[0];
retByteNum = 1;
break;
case CMD_FLASH_WRITE_BLOCK:
cmdFlashWriteBlockHeader = (CMD_FLASH_WRITE_BLOCK_HEADER *)&Buf[1];
uint32_t addr = cmdFlashWriteBlockHeader->blockIndex * BLOCK_SIZE + BOOT_ADDR;
Flash_EraseSector(addr);
memcpy(blockBuf, &Buf[5], cmdFlashWriteBlockHeader->dataLen);
Flash_Program(addr, blockBuf, cmdFlashWriteBlockHeader->dataLen);
rbf = GetCmdDataPtr(cmdRetBuf);
rbf[0] = Buf[0];
rbf[1] = Buf[1];
rbf[2] = Buf[2];
rbf[3] = Buf[3];
rbf[4] = Buf[4];
retByteNum = 5;
break;
case CMD_FLASH_SIZE:
rbf = GetCmdDataPtr(cmdRetBuf);
rbf[0] = Buf[0];
rbf[1] = fSize & 0xFF;
rbf[2] = (fSize >> 8) & 0xFF;
rbf[3] = (fSize >> 16) & 0xFF;
rbf[4] = (fSize >> 24) & 0xFF;
retByteNum = 5;
break;
default:
break;
}
return retByteNum;
}
void ParseEventFrameStream(ring_buffer_t *buffer)
{
uint8_t streamByte;
static int cmdLen = 0;
switch (frameParseStatus)
{
case FRAME_PARSER_STATUS_IDLE:
{
if (!ring_buffer_is_empty(buffer))
{
ring_buffer_dequeue(buffer, &streamByte);
if (streamByte == ((uint8_t)(0xFF & EVENT_FRAME_FLAG)))
{
frameParseStatus = FRAME_PARSER_STATUS_SOF_LO;
}
}
}
break;
case FRAME_PARSER_STATUS_SOF_LO:
{
if (!ring_buffer_is_empty(buffer))
{
ring_buffer_dequeue(buffer, &streamByte);
if (streamByte == ((uint8_t)(0xFF & (EVENT_FRAME_FLAG >> 8))))
{
frameParseStatus = FRAME_PARSER_STATUS_SOF_HI;
}
}
}
break;
case FRAME_PARSER_STATUS_SOF_HI:
{
if (ring_buffer_num_items(buffer) >= 2)
{
ring_buffer_dequeue(buffer, &streamByte);
cmdLen = streamByte;
ring_buffer_dequeue(buffer, &streamByte);
cmdLen += streamByte << 8;
frameParseStatus = FRAME_PARSER_STATUS_RECV_CMD_LEN;
}
}
break;
case FRAME_PARSER_STATUS_RECV_CMD_LEN:
{
int bufferRemain = ring_buffer_num_items(buffer);
static int receiveCounter = 0;
if (receiveCounter < cmdLen)
{
if (bufferRemain > 0)
{
if (bufferRemain + receiveCounter > cmdLen)
bufferRemain = cmdLen - receiveCounter;
ring_buffer_dequeue_arr(buffer, cmdBuf + receiveCounter, bufferRemain);
receiveCounter += bufferRemain;
}
}
else
{
receiveCounter = 0;
int retByteNum = Protocol_Process(cmdBuf);
if (retByteNum > 0)
{
cmdRetBuf[0] = (uint8_t)(0xFF & EVENT_FRAME_FLAG);
cmdRetBuf[1] = (uint8_t)(0xFF & (EVENT_FRAME_FLAG >> 8));
cmdRetBuf[2] = retByteNum & 0xFF;
cmdRetBuf[3] = retByteNum >> 8;
retByteNum += 4;
UART_SendWait(UART0, cmdRetBuf, retByteNum);
}
frameParseStatus = FRAME_PARSER_STATUS_IDLE;
cmdLen = 0;
}
}
break;
default:
break;
}
}
void DownloadProcess(void)
{
ParseEventFrameStream(&ring_buffer);
}
@@ -0,0 +1,28 @@
/*
* DownloadScoreData.h
*
* Created on: 2019Äê9ÔÂ23ÈÕ
* Author: yuan
*/
#ifndef DOWNLOADSCOREDATA_H_
#define DOWNLOADSCOREDATA_H_
#include <stdint.h>
#include "ringbuffer.h"
/**
* Initialize UART1 in 8N1 mode
*/
void uart_init(void);
void DownloadInit(void);
uint8_t *GetCmdDataPtr(uint8_t *buffer);
int Protocol_Process(unsigned char *Buf);
void ParseEventFrameStream(ring_buffer_t* buffer);
void DownloadProcess(void);
#endif /* DOWNLOADSCOREDATA_H_ */
+64
View File
@@ -0,0 +1,64 @@
#include "KeyScan.h"
#include <stdint.h>
#include <stddef.h>
uint8_t keyStatusList[KEY_NUM];
uint8_t keyValueList[KEY_NUM];
void (*keyCallBackList[KEY_NUM])(uint32_t);
void KeyRawInput(uint32_t keyIndex, uint32_t keyValue)
{
if (keyIndex < KEY_NUM)
keyValueList[keyIndex] = keyValue;
}
void KeyDefaultCallBack(uint32_t param)
{
param = param;
}
void KeySetCallBack(uint32_t keyIndex, void (*cb)(uint32_t))
{
if (keyIndex < KEY_NUM)
keyCallBackList[keyIndex] = cb;
}
void KeyProcess(uint32_t currentMills)
{
static uint32_t lastMills = 0;
if ((currentMills - lastMills) >= SCAN_INTERVAL_MS)
{
lastMills = currentMills;
for (size_t keyIndex = 0; keyIndex < KEY_NUM; keyIndex++)
{
switch (keyStatusList[keyIndex])
{
case KEY_STATUS_IDLE:
if (keyValueList[keyIndex] == KEY_ACTIVE)
keyStatusList[keyIndex] = KEY_STATUS_PRESSED;
break;
case KEY_STATUS_PRESSED:
if (keyValueList[keyIndex] != KEY_ACTIVE)
keyStatusList[keyIndex] = KEY_STATUS_RELEASED;
break;
case KEY_STATUS_RELEASED:
keyCallBackList[keyIndex](keyStatusList[keyIndex]);
keyStatusList[keyIndex] = KEY_STATUS_IDLE;
break;
default:
break;
}
}
}
}
void KeyScanInit(void)
{
for (size_t keyIndex = 0; keyIndex < KEY_NUM; keyIndex++)
{
keyCallBackList[keyIndex] = KeyDefaultCallBack;
keyStatusList[keyIndex] = KEY_STATUS_IDLE;
keyValueList[keyIndex] = !KEY_ACTIVE;
}
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef __KEY_SCAN_H__
#define __KEY_SCAN_H__
#include <stdint.h>
#define KEY_ACTIVE 0
#define SCAN_INTERVAL_MS 20
enum KEY_INDEX
{
USER_KEY_1 = 0,
USER_KEY_2,
KEY_NUM
};
enum KEY_STATUS
{
KEY_STATUS_IDLE = 0,
KEY_STATUS_PRESSED,
KEY_STATUS_RELEASED,
};
void KeyRawInput(uint32_t keyIndex, uint32_t keyValue);
void KeyDefaultCallBack(uint32_t param);
void KeySetCallBack(uint32_t keyIndex, void (*cb)(uint32_t));
void KeyProcess(uint32_t currentMills);
void KeyScanInit(void);
#endif
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
+147
View File
@@ -0,0 +1,147 @@
# toolchain
TOOLCHAIN = arm-none-eabi-
CC = $(TOOLCHAIN)gcc
CP = $(TOOLCHAIN)objcopy
AS = $(TOOLCHAIN)gcc -x assembler-with-cpp
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
# define mcu, specify the target processor
MCU = cortex-m0plus
# all the files will be generated with this name (main.elf, main.bin, main.hex, etc)
PROJECT_NAME=music-box-nv32
# specify define
DDEFS =
# define root dir
ROOT_DIR = .
# define include dir
INCLUDE_DIRS =
# define nv32 lib dir
NV32_LIB_DIR = $(ROOT_DIR)/nv32lib
# define user dir
USER_DIR = $(ROOT_DIR)
# link file
LINK_SCRIPT = $(ROOT_DIR)/nv32f100.ld
# user specific
SRC =
ASM_SRC =
SRC += $(USER_DIR)/main.c
SRC += $(USER_DIR)/gcc-stdio-retarget.c
SRC += $(USER_DIR)/KeyScan.c
SRC += $(USER_DIR)/DownloadScoreData.c
SRC += $(ROOT_DIR)/WaveTableSynthesizer/SynthCore.c
SRC += $(ROOT_DIR)/WaveTableSynthesizer/EnvelopTable.c
SRC += $(ROOT_DIR)/WaveTableSynthesizer/AlgorithmTest.c
SRC += $(ROOT_DIR)/WaveTableSynthesizer/WaveTable_Celesta_C5.c
SRC += $(ROOT_DIR)/WaveTableSynthesizer/WaveTable_Celesta_C6.c
SRC += $(ROOT_DIR)/WaveTableSynthesizer/Player.c
SRC += $(ROOT_DIR)/Ring-Buffer/ringbuffer.c
ASM_SRC += $(ROOT_DIR)/WaveTableSynthesizer/PeriodTimer.s
ASM_SRC += $(ROOT_DIR)/WaveTableSynthesizer/SynthCoreAsm.s
# ASM_SRC += $(ROOT_DIR)/ScoreList.s
# user include
INCLUDE_DIRS = $(USER_DIR)
INCLUDE_DIRS += $(ROOT_DIR)/WaveTableSynthesizer
INCLUDE_DIRS += $(ROOT_DIR)/Ring-Buffer
# include sub makefiles
include makefile_std_lib.mk # NV32 Library
INC_DIR = $(patsubst %, -I%, $(INCLUDE_DIRS))
# run from Flash
DEFS = $(DDEFS) -DRUN_FROM_FLASH=1
OBJECTS = $(ASM_SRC:.s=.o) $(SRC:.c=.o) scoreList.o
DEPS = $(SRC:.c=.d) $(ASM_SRC:.s=.d)
# Define optimisation level here
OPT = -Os
MC_FLAGS = -mcpu=$(MCU)
AS_FLAGS = $(MC_FLAGS) -g -gdwarf-2 -mthumb -Wa,-amhls=$(<:.s=.lst)
CP_FLAGS = $(MC_FLAGS) $(OPT) -std=gnu99 -fdata-sections -ffunction-sections -g -gdwarf-2 -mthumb -fomit-frame-pointer -Wall -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
LD_FLAGS = $(MC_FLAGS) -g -specs=nano.specs -specs=nosys.specs -gdwarf-2 -mthumb -nostartfiles -Xlinker -T$(LINK_SCRIPT) -Wl,-Map=$(PROJECT_NAME).map,--cref,--no-warn-mismatch,--gc-sections
DEPFLAGS = -MT $@ -MMD -MP -MF $*.d
#
# makefile rules
#
all: $(OBJECTS) $(PROJECT_NAME).elf $(PROJECT_NAME).hex $(PROJECT_NAME).bin
$(TOOLCHAIN)size $(PROJECT_NAME).elf
# Don't delete dependency files
.PRECIOUS: %.d
# Don't rebuild deps if cleaning
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
%.o: %.c Makefile makefile_std_lib.mk
@echo [CC] $(notdir $<)
@$(CC) $(DEPFLAGS) -c $(CP_FLAGS) -I . $(INC_DIR) $< -o $@
%.o: %.s
@echo [AS] $(notdir $<)
@$(AS) $(DEPFLAGS) -c $(AS_FLAGS) $< -o $@
scoreList.o: scoreList.raw
@echo [RAW] scoreList.raw
@$(CP) -I binary -O elf32-littlearm scoreList.raw scoreList.o
%.elf: $(OBJECTS) $(LINK_SCRIPT)
@echo [LD] $(PROJECT_NAME).elf
@$(CC) $(OBJECTS) $(LD_FLAGS) -o $@
%.hex: %.elf
@echo [HEX] $(PROJECT_NAME).hex
@$(HEX) $< $@
%.bin: %.elf
@echo [BIN] $(PROJECT_NAME).bin
@$(BIN) $< $@
flash: $(PROJECT_NAME).bin
st-flash write $(PROJECT_NAME).bin 0x8000000
erase:
st-flash erase
clean:
@echo [RM] OBJ
@-rm -rf $(OBJECTS)
@echo [RM] BIN "(ELF,HEX,BIN)"
@-rm -rf $(PROJECT_NAME).elf
@-rm -rf $(PROJECT_NAME).hex
@-rm -rf $(PROJECT_NAME).bin
@echo [RM] LST
@-rm -rf $(SRC:.c=.lst)
@-rm -rf $(ASM_SRC:.s=.lst)
@echo [RM] MAP
@-rm -rf $(PROJECT_NAME).map
@echo [RM] DEPENDENCY
@-rm -rf $(DEPS)
+28
View File
@@ -0,0 +1,28 @@
# Intro
This is a wavetable synthesis based music-box.
![music-box-photo](./doc/music-box-photo.jpg)
# Pre-compiled binary
If you do not want to compile the firmware by yourself, you can download pre-compiled firmware:
https://github.com/eeyrw/music-box-nv32/releases/tag/1.0.0
# Build Firmware
The firmware can be compiled with [arm-none-eabi-gcc](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). Build system is based on Makefile. So run
```
make
```
in the root directory can handle all the things.
# Download Score Data
```
python download.py scoreList.raw
```
The pyserial and python3 is required. The "scoreList.raw" is the file generated by [midi-to-hex tool](https://github.com/eeyrw/midi-to-hex/tree/new-midi-to-hex).
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Anders Kalør
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,4 @@
Ring-Buffer
===========
A simple ring buffer (circular buffer) designed for embedded systems.
@@ -0,0 +1,10 @@
CC = gcc
CFLAGS = -Wall -g -O2 -std=c99
all: simple
simple: ../ringbuffer.c simple.c
$(CC) $(CFLAGS) -o simple simple.c ../ringbuffer.c
clean:
rm -f simple
@@ -0,0 +1,86 @@
#include <assert.h>
#include <stdio.h>
#include "../ringbuffer.h"
int main(void) {
int i, cnt;
char buf;
char buf_arr[50];
/* Create and initialize ring buffer */
ring_buffer_t ring_buffer;
ring_buffer_init(&ring_buffer);
/* Add elements to buffer; one at a time */
for(i = 0; i < 100; i++) {
ring_buffer_queue(&ring_buffer, i);
}
/* Verify size */
assert(ring_buffer_num_items(&ring_buffer) == 100);
/* Peek third element */
cnt = ring_buffer_peek(&ring_buffer, &buf, 3);
/* Assert byte returned */
assert(cnt == 1);
/* Assert contents */
assert(buf == 3);
/* Dequeue all elements */
for(cnt = 0; ring_buffer_dequeue(&ring_buffer, &buf) > 0; cnt++) {
/* Do something with buf... */
assert(buf == cnt);
printf("Read: %d\n", buf);
}
printf("\n===============\n");
/* Add array */
ring_buffer_queue_arr(&ring_buffer, "Hello, Ring Buffer!", 20);
/* Is buffer empty? */
assert(!ring_buffer_is_empty(&ring_buffer));
/* Dequeue all elements */
while(ring_buffer_dequeue(&ring_buffer, &buf) > 0) {
/* Print contents */
printf("Read: %c\n", buf);
}
/* Add new array */
ring_buffer_queue_arr(&ring_buffer, "Hello again, Ring Buffer!", 26);
/* Dequeue array in two parts */
printf("Read:\n");
cnt = ring_buffer_dequeue_arr(&ring_buffer, buf_arr, 13);
printf("%d\n", cnt);
assert(cnt == 13);
/* Add \0 termination before printing */
buf_arr[13] = '\0';
printf("%s\n", buf_arr);
/* Dequeue remaining */
cnt = ring_buffer_dequeue_arr(&ring_buffer, buf_arr, 13);
assert(cnt == 13);
printf("%s", buf_arr);
printf("\n===============\n");
/* Overfill buffer */
for(i = 0; i < 1000; i++) {
ring_buffer_queue(&ring_buffer, (i % 127));
}
/* Is buffer full? */
if(ring_buffer_is_full(&ring_buffer)) {
cnt = ring_buffer_num_items(&ring_buffer);
printf("Buffer is full and contains %d bytes\n", cnt);
}
/* Dequeue all elements */
while(ring_buffer_dequeue(&ring_buffer, &buf) > 0) {
/* Print contents */
printf("Read: 0x%02x\n", buf);
}
return 0;
}
@@ -0,0 +1,75 @@
#include "ringbuffer.h"
/**
* @file
* Implementation of ring buffer functions.
*/
void ring_buffer_init(ring_buffer_t *buffer) {
buffer->tail_index = 0;
buffer->head_index = 0;
}
void ring_buffer_queue(ring_buffer_t *buffer, uint8_t data) {
/* Is buffer full? */
if(ring_buffer_is_full(buffer)) {
/* Is going to overwrite the oldest byte */
/* Increase tail index */
buffer->tail_index = ((buffer->tail_index + 1) & RING_BUFFER_MASK);
}
/* Place data in buffer */
buffer->buffer[buffer->head_index] = data;
buffer->head_index = ((buffer->head_index + 1) & RING_BUFFER_MASK);
}
void ring_buffer_queue_arr(ring_buffer_t *buffer, const uint8_t *data, ring_buffer_size_t size) {
/* Add bytes; one by one */
ring_buffer_size_t i;
for(i = 0; i < size; i++) {
ring_buffer_queue(buffer, data[i]);
}
}
ring_buffer_size_t ring_buffer_dequeue(ring_buffer_t *buffer, uint8_t *data) {
if(ring_buffer_is_empty(buffer)) {
/* No items */
return 0;
}
*data = buffer->buffer[buffer->tail_index];
buffer->tail_index = ((buffer->tail_index + 1) & RING_BUFFER_MASK);
return 1;
}
ring_buffer_size_t ring_buffer_dequeue_arr(ring_buffer_t *buffer, uint8_t *data, ring_buffer_size_t len) {
if(ring_buffer_is_empty(buffer)) {
/* No items */
return 0;
}
uint8_t *data_ptr = data;
ring_buffer_size_t cnt = 0;
while((cnt < len) && ring_buffer_dequeue(buffer, data_ptr)) {
cnt++;
data_ptr++;
}
return cnt;
}
ring_buffer_size_t ring_buffer_peek(ring_buffer_t *buffer, uint8_t *data, ring_buffer_size_t index) {
if(index >= ring_buffer_num_items(buffer)) {
/* No items at index */
return 0;
}
/* Add index to pointer */
ring_buffer_size_t data_index = ((buffer->tail_index + index) & RING_BUFFER_MASK);
*data = buffer->buffer[data_index];
return 1;
}
extern inline ring_buffer_size_t ring_buffer_is_empty(ring_buffer_t *buffer);
extern inline ring_buffer_size_t ring_buffer_is_full(ring_buffer_t *buffer);
extern inline ring_buffer_size_t ring_buffer_num_items(ring_buffer_t *buffer);
@@ -0,0 +1,132 @@
#include <inttypes.h>
/**
* @file
* Prototypes and structures for the ring buffer module.
*/
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
/**
* The size of a ring buffer.
* Due to the design only <tt> RING_BUFFER_SIZE-1 </tt> items
* can be contained in the buffer.
* The buffer size must be a power of two.
*/
#define RING_BUFFER_SIZE 512
#if (RING_BUFFER_SIZE & (RING_BUFFER_SIZE - 1)) != 0
#error "RING_BUFFER_SIZE must be a power of two"
#endif
/**
* The type which is used to hold the size
* and the indicies of the buffer.
* Must be able to fit \c RING_BUFFER_SIZE .
*/
typedef uint32_t ring_buffer_size_t;
/**
* Used as a modulo operator
* as <tt> a % b = (a & (b 鈭 1)) </tt>
* where \c a is a positive index in the buffer and
* \c b is the (power of two) size of the buffer.
*/
#define RING_BUFFER_MASK (RING_BUFFER_SIZE-1)
/**
* Simplifies the use of <tt>struct ring_buffer_t</tt>.
*/
typedef struct ring_buffer_t ring_buffer_t;
/**
* Structure which holds a ring buffer.
* The buffer contains a buffer array
* as well as metadata for the ring buffer.
*/
struct ring_buffer_t {
/** Buffer memory. */
char buffer[RING_BUFFER_SIZE];
/** Index of tail. */
ring_buffer_size_t tail_index;
/** Index of head. */
ring_buffer_size_t head_index;
};
/**
* Initializes the ring buffer pointed to by <em>buffer</em>.
* This function can also be used to empty/reset the buffer.
* @param buffer The ring buffer to initialize.
*/
void ring_buffer_init(ring_buffer_t *buffer);
/**
* Adds a byte to a ring buffer.
* @param buffer The buffer in which the data should be placed.
* @param data The byte to place.
*/
void ring_buffer_queue(ring_buffer_t *buffer, uint8_t data);
/**
* Adds an array of bytes to a ring buffer.
* @param buffer The buffer in which the data should be placed.
* @param data A pointer to the array of bytes to place in the queue.
* @param size The size of the array.
*/
void ring_buffer_queue_arr(ring_buffer_t *buffer, const uint8_t *data, ring_buffer_size_t size);
/**
* Returns the oldest byte in a ring buffer.
* @param buffer The buffer from which the data should be returned.
* @param data A pointer to the location at which the data should be placed.
* @return 1 if data was returned; 0 otherwise.
*/
ring_buffer_size_t ring_buffer_dequeue(ring_buffer_t *buffer, uint8_t *data);
/**
* Returns the <em>len</em> oldest bytes in a ring buffer.
* @param buffer The buffer from which the data should be returned.
* @param data A pointer to the array at which the data should be placed.
* @param len The maximum number of bytes to return.
* @return The number of bytes returned.
*/
ring_buffer_size_t ring_buffer_dequeue_arr(ring_buffer_t *buffer, uint8_t *data, ring_buffer_size_t len);
/**
* Peeks a ring buffer, i.e. returns an element without removing it.
* @param buffer The buffer from which the data should be returned.
* @param data A pointer to the location at which the data should be placed.
* @param index The index to peek.
* @return 1 if data was returned; 0 otherwise.
*/
ring_buffer_size_t ring_buffer_peek(ring_buffer_t *buffer, uint8_t *data, ring_buffer_size_t index);
/**
* Returns whether a ring buffer is empty.
* @param buffer The buffer for which it should be returned whether it is empty.
* @return 1 if empty; 0 otherwise.
*/
inline ring_buffer_size_t ring_buffer_is_empty(ring_buffer_t *buffer) {
return (buffer->head_index == buffer->tail_index);
}
/**
* Returns whether a ring buffer is full.
* @param buffer The buffer for which it should be returned whether it is full.
* @return 1 if full; 0 otherwise.
*/
inline ring_buffer_size_t ring_buffer_is_full(ring_buffer_t *buffer) {
return ((buffer->head_index - buffer->tail_index) & RING_BUFFER_MASK) == RING_BUFFER_MASK;
}
/**
* Returns the number of items in a ring buffer.
* @param buffer The buffer for which the number of items should be returned.
* @return The number of items in the ring buffer.
*/
inline ring_buffer_size_t ring_buffer_num_items(ring_buffer_t *buffer) {
return ((buffer->head_index - buffer->tail_index) & RING_BUFFER_MASK);
}
#endif /* RINGBUFFER_H */
@@ -0,0 +1,170 @@
#ifdef RUN_TEST
#include "SynthCore.h"
#include "Player.h"
#include <stdint.h>
#include <stdio.h>
#define TEST_LOOP_NUN 10000
Synthesizer synthesizerC;
Synthesizer synthesizerASM;
void TestInit(void)
{
SynthInit(&synthesizerC);
SynthInit(&synthesizerASM);
}
int32_t abs_s32(int32_t num)
{
return num>0?num:-num;
}
void PrintParameters(Synthesizer* synth)
{
SoundUnit* soundUnits = synth->SoundUnitList;
printf("MixOut:%d\n",synth->mixOut);
printf("LastSoundUnit:%d\n",synth->lastSoundUnit);
printf("%12s","Chn Val");
for(uint8_t k=0;k<POLY_NUM;k++)
{
printf("%6d ",soundUnits[k].val);
}
printf("\n");
printf("%12s","Chn Sample");
for(uint8_t k=0;k<POLY_NUM;k++)
{
printf("%6d ",soundUnits[k].sampleVal);
}
printf("\n");
printf("%12s","Chn EnvLevel");
for(uint8_t k=0;k<POLY_NUM;k++)
{
printf("%6d ",soundUnits[k].envelopeLevel);
}
printf("\n");
printf("%12s","Chn WavePos");
for(uint8_t k=0;k<POLY_NUM;k++)
{
printf("%6lu ",soundUnits[k].wavetablePos);
}
printf("\n");
printf("%12s","Chn EnvlPos");
for(uint8_t k=0;k<POLY_NUM;k++)
{
printf("%6d ",soundUnits[k].envelopePos);
}
printf("\n");
printf("%12s","Chn NoteIncr");
for(uint8_t k=0;k<POLY_NUM;k++)
{
printf("%6x ",soundUnits[k].increment);
}
printf("\n");
}
void TestUpdateTickFunc(void)
{
uint32_t i;
Player player;
PlayerInit(&player);
printf("~~~~~~~Start testing updateTickFunc.~~~~~~~\n");
for(i=0;i<0xffff;i++)
{
if(i!=player.decoder.currentTick)
{
printf("UpdateTickFunc get wrong in %ld loop.\n",i);
break;
}
UpdateTick(&player);
}
if(i==player.decoder.currentTick)
printf("UpdateTickFunc passed the test.\n");
}
uint8_t SynthParamterCompare(Synthesizer* synthA,Synthesizer* synthB)
{
uint32_t error=0;
SoundUnit* sa=synthA->SoundUnitList;
SoundUnit* sb=synthB->SoundUnitList;
if(abs_s32(synthA->mixOut-synthB->mixOut)>POLY_NUM)
error++;
for(uint32_t k=0;k<POLY_NUM;k++)
{
if(abs_s32(sa[k].val-sb[k].val)>2)
error++;
if(sa[k].sampleVal!=sb[k].sampleVal)
error++;
if(sa[k].envelopeLevel!=sb[k].envelopeLevel)
error++;
if(sa[k].envelopePos!=sb[k].envelopePos)
error++;
if(sa[k].wavetablePos!=sb[k].wavetablePos)
error++;
if(sa[k].increment!=sb[k].increment)
error++;
}
if(error>0)
{
printf("%lu error(s) found:\n",error);
printf("Synth C:\n");
PrintParameters(&synthesizerC);
printf("Synth ASM:\n");
PrintParameters(&synthesizerASM);
}
else
{
printf("Passed.\n");
}
return error;
}
extern Player mainPlayer;
void TestSynth(void)
{
uint32_t errorTimes=0;
printf("~~~~~~~Start testing synthesizer.~~~~~~~\n");
for(uint32_t i=40;i<40+POLY_NUM;i++)
{
NoteOnC(&synthesizerC,i%56);
NoteOnAsm(&synthesizerASM,i%56);
}
printf("After NoteOn Test:\n");
printf("Synth C:\n");
PrintParameters(&synthesizerC);
printf("Synth ASM:\n");
PrintParameters(&synthesizerASM);
for(uint32_t i=0;i<TEST_LOOP_NUN;i++)
{
SynthAsm(&synthesizerASM);
SynthC(&synthesizerC);
GenDecayEnvlopeC(&synthesizerC);
GenDecayEnvlopeAsm(&synthesizerASM);
printf("=============%lu==============\n",i);
if(SynthParamterCompare(&synthesizerC,&synthesizerASM)>0)
errorTimes++;
if(errorTimes>2)
break;
}
}
void TestProcess(void)
{
TestInit();
TestUpdateTickFunc();
TestSynth();
}
#endif
@@ -0,0 +1,6 @@
#ifndef __ASM_COMMON_H__
#define __ASM_COMMON_H__
#endif
@@ -0,0 +1,19 @@
#include <stdint.h>
const uint8_t EnvelopeTable[] = {
255, 252, 250, 247, 245, 243, 240, 238, 235, 233, 231, 228, 226, 224, 222, 219,
217, 215, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 191, 189, 187,
185, 183, 182, 180, 178, 176, 174, 173, 171, 169, 168, 166, 164, 163, 161, 159,
158, 156, 155, 153, 152, 150, 149, 147, 146, 144, 143, 141, 140, 139, 137, 136,
134, 133, 132, 130, 129, 128, 127, 125, 124, 123, 122, 120, 119, 118, 117, 116,
115, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99,
98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 87, 86, 85, 84,
83, 82, 82, 81, 80, 79, 78, 78, 77, 76, 75, 75, 74, 73, 72, 72,
71, 70, 69, 69, 68, 67, 67, 66, 65, 65, 64, 64, 63, 62, 62, 61,
60, 60, 59, 59, 58, 57, 57, 56, 56, 55, 55, 54, 54, 53, 53, 52,
51, 51, 50, 50, 49, 49, 48, 48, 48, 47, 47, 46, 46, 45, 45, 44,
44, 43, 43, 43, 42, 42, 41, 40, 40, 39, 39, 38, 38, 37, 37, 36,
35, 35, 34, 34, 33, 33, 32, 31, 31, 30, 30, 29, 29, 28, 28, 27,
26, 26, 25, 25, 24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18,
17, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9,
8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1, 0, 0};
@@ -0,0 +1,8 @@
#ifndef __ENVELOP_TABLE_H__
#define __ENVELOP_TABLE_H__
#include <stdint.h>
extern uint8_t EnvelopeTable[256];
#endif
@@ -0,0 +1,12 @@
#ifndef __PERIOD_TIMER_H__
#define __PERIOD_TIMER_H__
#ifndef __ASSEMBLER__
extern void PIT_Task(void);
#else
#endif
#endif
@@ -0,0 +1,28 @@
#include "Player.h"
#include "RegDefNv32.h"
#define PeriodTimerHandler PIT_Ch0Isr_Override
.syntax unified
.section .text
.thumb_func
.global PeriodTimerHandler
.func PeriodTimerHandler
PeriodTimerHandler:
push {r4-r7,lr} // r0-r3,r12 saved by hardware when expection happening
ldr r0,=#PIT_TFLG0
ldr r1,[r0]
ldr r2,=#PIT_TFLG_TIF_BIT
orrs r1,r1,r2
str r1,[r0]
ldr r5,=#GlobalPlayerPtr
ldr r5,[r5]
ldr r6,=#pSynthesizer
adds r0,r5,r6
ldr r6,=#pScoreDecoder
adds r1,r5,r6
#include "Synth.inc"
#include "UpdateTick.inc"
pop {r4-r7,pc}
.endfunc
@@ -0,0 +1,189 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "SynthCore.h"
#include "Player.h"
Player *GlobalPlayerPtr;
void Player32kProc(Player *player)
{
SynthAsm(&(player->synthesizer));
if (player->decoder.status == STATUS_DECODING)
player->decoder.currentTick++;
if (player->synthesizer.decayGenTick < 200)
player->synthesizer.decayGenTick += 1;
}
void ScoreDecodeProcess(Player *player)
{
uint8_t temp;
if (player->decoder.status == STATUS_DECODING)
{
if ((player->decoder.currentTick >> 8) >= player->decoder.lastScoreTick)
{
do
{
temp = *(player->decoder.scorePointer);
player->decoder.scorePointer++;
if (temp == 0xFF)
player->decoder.status = STATUS_STOP;
else
NoteOnAsm(&(player->synthesizer), temp);
} while ((temp & 0x80) == 0);
UpdateNextScoreTick(&(player->decoder));
}
}
}
void PlaySchedulerNextScore(Player *player)
{
player->scheduler.switchDirect = SCHEDULER_SCORE_NEXT;
player->scheduler.status = SCHEDULER_SWITCHING;
StopDecode(player);
}
void PlaySchedulerPreviousScore(Player *player)
{
player->scheduler.switchDirect = SCHEDULER_SCORE_PREV;
player->scheduler.status = SCHEDULER_SWITCHING;
StopDecode(player);
}
uint8_t *GetScorePhyiscalAddr(uint32_t addr)
{
return (uint8_t *)((uint32_t)(&ScoreDataList) + addr);
}
void PlaySchedulerProcess(Player *player)
{
uint32_t *ScoreList = (&(player->scheduler.scoreListHeader)->firstAddr);
switch (player->scheduler.status)
{
case SCHEDULER_READY_TO_SWITCH:
if (player->decoder.status == STATUS_STOP)
{
player->scheduler.switchDirect = SCHEDULER_SCORE_NEXT;
player->scheduler.status = SCHEDULER_SWITCHING;
StopDecode(player);
}
break;
case SCHEDULER_SWITCHING:
player->scheduler.status = player->scheduler.switchDirect;
break;
case SCHEDULER_SCORE_PREV:
player->scheduler.currentScoreIndex--;
if (player->scheduler.currentScoreIndex < 0)
player->scheduler.currentScoreIndex = player->scheduler.maxScoreNum - 1;
PlayScore(player, GetScorePhyiscalAddr(ScoreList[player->scheduler.currentScoreIndex]));
player->scheduler.status = SCHEDULER_READY_TO_SWITCH;
break;
case SCHEDULER_SCORE_NEXT:
player->scheduler.currentScoreIndex++;
if (player->scheduler.currentScoreIndex >= player->scheduler.maxScoreNum)
{
player->scheduler.status = SCHEDULER_STOP;
player->scheduler.currentScoreIndex = -1;
}
else
{
PlayScore(player, GetScorePhyiscalAddr(ScoreList[player->scheduler.currentScoreIndex]));
player->scheduler.status = SCHEDULER_READY_TO_SWITCH;
}
break;
case SCHEDULER_STOP:
/* Do nothing */
break;
default:
break;
}
}
void PlayerProcess(Player *player)
{
SynthGenEnvelopeProcess(&(player->synthesizer));
ScoreDecodeProcess(player);
PlaySchedulerProcess(player);
}
void UpdateNextScoreTick(ScoreDecoder *decoder)
{
uint32_t tempU32;
uint8_t temp;
tempU32 = decoder->lastScoreTick;
do
{
temp = *(decoder->scorePointer);
decoder->scorePointer++;
tempU32 += temp;
} while (temp == 0xFF);
decoder->lastScoreTick = tempU32;
}
void StartPlayScheduler(Player *player)
{
if (ScoreDataList.identifer[0] == 'S' &&
ScoreDataList.identifer[1] == 'C' &&
ScoreDataList.identifer[2] == 'R' &&
ScoreDataList.identifer[3] == 'E')
{
player->scheduler.scoreListHeader = &ScoreDataList;
player->scheduler.currentScoreIndex = -1;
player->scheduler.maxScoreNum = (player->scheduler.scoreListHeader)->scoreCount;
player->scheduler.schedulerMode = MODE_ORDER_PLAY;
player->scheduler.status = SCHEDULER_READY_TO_SWITCH;
}
else
{
player->scheduler.status = SCHEDULER_STOP;
}
}
void SchedulerSetIntialRandomSeed(Player *player, uint8_t randomSeed)
{
player->scheduler.currentScoreIndex = (randomSeed % player->scheduler.maxScoreNum) - 1;
}
void StopPlayScheduler(Player *player)
{
StopDecode(player);
player->scheduler.status = SCHEDULER_STOP;
}
void PlayScore(Player *player, uint8_t *score)
{
player->synthesizer.hwSet(SYNTH_HW_ON);
player->decoder.currentTick = 0;
player->decoder.lastScoreTick = 0;
player->decoder.scorePointer = score;
UpdateNextScoreTick(&(player->decoder));
player->decoder.status = STATUS_DECODING;
}
void StopDecode(Player *player)
{
player->synthesizer.hwSet(SYNTH_HW_OFF);
player->decoder.status = STATUS_STOP;
player->decoder.currentTick = 0;
player->decoder.lastScoreTick = 0;
}
void PlayerInit(Player *player)
{
GlobalPlayerPtr = player;
player->decoder.status = STATUS_STOP;
player->decoder.currentTick = 0;
player->decoder.lastScoreTick = 0;
player->decoder.scorePointer = NULL;
SynthInit(&(player->synthesizer));
}
@@ -0,0 +1,102 @@
#ifndef __ScoreDecoder_H__
#define __ScoreDecoder_H__
#include "SynthCore.h"
#define pSynthesizer 0
#define pScoreDecoder (pSynthesizer+SynthesizerSize)
#define pCurrentTick 0
#define pLastScoreTick (pCurrentTick+4)
#define pStatus (pLastScoreTick+4)
#define constSTATUS_DECODING 2
#ifndef __ASSEMBLER__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
enum DECODER_STATUS
{
STATUS_STOP = 0,
STATUS_REDAY_TO_DECODE = 1,
STATUS_DECODING = constSTATUS_DECODING
};
enum SCHEDULER_MODE
{
MODE_ORDER_PLAY = 0,
};
enum SCHEDULER_STATUS
{
SCHEDULER_READY_TO_SWITCH = 0,
SCHEDULER_SWITCHING,
SCHEDULER_SCORE_PREV,
SCHEDULER_SCORE_NEXT,
SCHEDULER_STOP,
};
typedef struct _ScoreListHeader
{
char identifer[4];
uint32_t scoreCount;
uint32_t firstAddr;
}ScoreListHeader;
typedef struct _ScoreDecoder
{
uint32_t currentTick;
uint32_t lastScoreTick;
uint32_t status;
uint8_t *scorePointer;
} ScoreDecoder;
typedef struct _PlayScheduler
{
uint32_t schedulerMode;
int32_t currentScoreIndex;
uint32_t maxScoreNum;
ScoreListHeader* scoreListHeader;
uint32_t status;
uint32_t switchDirect;
} PlayScheduler;
typedef struct _Player
{
Synthesizer synthesizer;
ScoreDecoder decoder;
PlayScheduler scheduler;
} Player;
extern ScoreListHeader ScoreDataList;
extern Player *GlobalPlayerPtr;
extern void PlayerInit(Player *player);
extern void Player32kProc(Player *player);
extern void PlayerProcess(Player *player);
extern void ScoreDecodeProcess(Player *player);
extern void PlayScore(Player* player, uint8_t *score);
extern void StopDecode(Player *player);
extern void StartPlayScheduler(Player* player);
extern void StopPlayScheduler(Player *player);
extern void PlaySchedulerNextScore(Player *player);
extern void PlaySchedulerPreviousScore(Player *player);
extern void SchedulerSetIntialRandomSeed(Player *player,uint8_t randomSeed);
extern void UpdateTick(ScoreDecoder *decoder);
extern void UpdateNextScoreTick(ScoreDecoder *decoder);
#ifdef __cplusplus
} //end extern "C"
#endif
#else
.extern GlobalPlayerPtr;
#endif
#endif
@@ -0,0 +1,11 @@
#ifndef __REG_DEF_NV32_H__
#define __REG_DEF_NV32_H__
#define PWM_OUT1 0x4003A030
#define PWM_OUT2 0x4003A038
#define PIT_TFLG0 0x4003710C
#define PIT_TFLG1 0x4003711C
#define PIT_TFLG_TIF_BIT 0x01
#endif
@@ -0,0 +1,81 @@
#include "SynthCore.h"
#include "AsmCommon.h"
#include "RegDefNv32.h"
.syntax unified
.section .text
SynthAsm:
pSoundUnit .req r3
loopIndex .req r4
mixOut .req r2
movs loopIndex,#POLY_NUM
movs mixOut,#0
movs pSoundUnit,r0
loopSynth:
ldrh r7,[pSoundUnit,#pEnvelopeLevel]
cmp r7,#0
beq loopSynthEnd
ldr r5,[pSoundUnit,#pWaveTableAddress]
ldr r6,[pSoundUnit,#pWavetablePos]
lsrs r6,r6,#8 @wavetablePos /= 256
lsls r6,r6,#1 @wavetablePos *= 2
ldrsh r6,[r5,r6] @ Load signed 16bit sample to r6
#ifdef RUN_TEST
strsh r6,[pSoundUnit,#pSampleVal]
#endif
muls r7,r6,r7 @sample*envelope/256
#ifdef RUN_TEST
asrs r7,r7,#8
strsh r7,[pSoundUnit,#pVal]
#endif
adds mixOut,r7,mixOut @mixOut+=sample*envelope/256
ldr r6,[pSoundUnit,#pWavetablePos]
ldr r5,[pSoundUnit,#pIncrement]
adds r6,r5,r6
ldr r5,[pSoundUnit,#pWaveTableLen]
lsls r5,r5,#8 @pWaveTableLen*=256
cmp r5,r6
bhi wavePosUpdateEnd @bhi : HI C = 1 ands Z = 0 Higher, unsigned
ldr r5,[pSoundUnit,#pWaveTableLoopLen]
lsls r5,r5,#8 @waveTableLoopLen*=256
subs r6,r6,r5
wavePosUpdateEnd:
str r6,[pSoundUnit,#pWavetablePos]
loopSynthEnd:
adds pSoundUnit,pSoundUnit,#SoundUnitSize
subs loopIndex,loopIndex,#1 @ set n = n-1
bne loopSynth
movs pSoundUnit,r0
ldr r5,=#pMixOut
adds r5,r5,pSoundUnit
str mixOut,[r5]
@
ldrh r5,[r5,#(pMainVolume-pMixOut)]
asrs mixOut,mixOut,#8
muls mixOut,r5,mixOut
asrs mixOut,mixOut,#(MAX_VOLUME_SHIFT_BIT+8)
ldr r5,=#-128
cmp mixOut,r5
bge lowerBoundSatisfied
movs mixOut,r5
lowerBoundSatisfied:
ldr r5,=#127
cmp mixOut,r5
ble saturateEnd
movs mixOut,r5
saturateEnd:
@ mixOut: [-512,511] -> [0,1023]
ldr r5,=#128
adds mixOut,mixOut,r5
ldr r5,=#PWM_OUT1
strh mixOut,[r5]
ldr r5,=#PWM_OUT2
strh mixOut,[r5]
@@ -0,0 +1,123 @@
#include "SynthCore.h"
#include <stdint.h>
#include <stdio.h>
#include "WaveTable_Celesta_C5.h"
#include "WaveTable_Celesta_C6.h"
#include "EnvelopeTable.h"
#ifdef RUN_TEST
Synthesizer synthForC;
#endif
Synthesizer *GlobalSynthPtr;
void SynthInit(Synthesizer *synth)
{
SoundUnit *soundUnits = synth->SoundUnitList;
for (uint8_t i = 0; i < POLY_NUM; i++)
{
soundUnits[i].increment = 0;
soundUnits[i].wavetablePos = 0;
soundUnits[i].envelopeLevel = 0;
soundUnits[i].envelopePos = 0;
soundUnits[i].waveTableAddress = (uint32_t)WaveTable_Celesta_C5;
soundUnits[i].waveTableLen = WAVETABLE_CELESTA_C5_LEN;
soundUnits[i].waveTableLoopLen = WAVETABLE_CELESTA_C5_LOOP_LEN;
soundUnits[i].waveTableAttackLen = WAVETABLE_CELESTA_C5_ATTACK_LEN;
}
synth->mixOut = 0;
synth->lastSoundUnit = 0;
synth->mainVolume = 1 << (MAX_VOLUME_SHIFT_BIT - 1);
synth->decayGenTick = 0;
GlobalSynthPtr = synth;
}
void SynthRegisterHwChangeFunc(Synthesizer *synth, void (*hwSet)(SYNTH_HW_STATUS))
{
synth->hwSet = hwSet;
}
void SynthOn(Synthesizer *synth)
{
synth->hwSet(SYNTH_HW_ON);
SynthInit(synth);
}
void SynthOff(Synthesizer *synth)
{
synth->hwSet(SYNTH_HW_OFF);
SynthInit(synth);
}
void SynthGenEnvelopeProcess(Synthesizer *synth)
{
if (synth->decayGenTick >= DECAY_TIME_FACTOR)
{
GenDecayEnvlopeAsm(synth);
synth->decayGenTick = 0;
}
}
#ifdef RUN_TEST
void NoteOnC(Synthesizer *synth, uint8_t note)
{
uint32_t lastSoundUnit = synth->lastSoundUnit;
SoundUnit *soundUnits = synth->SoundUnitList;
//disable_interrupts();
soundUnits[lastSoundUnit].increment = WaveTable_Celesta_C5_Increment[note & 0x7F];
soundUnits[lastSoundUnit].wavetablePos = 0;
soundUnits[lastSoundUnit].waveTableAddress = (uint32_t)WaveTable_Celesta_C5;
soundUnits[lastSoundUnit].waveTableLen = WAVETABLE_CELESTA_C5_LEN;
soundUnits[lastSoundUnit].waveTableLoopLen = WAVETABLE_CELESTA_C5_LOOP_LEN;
soundUnits[lastSoundUnit].waveTableAttackLen = WAVETABLE_CELESTA_C5_ATTACK_LEN;
soundUnits[lastSoundUnit].envelopeLevel = 255;
soundUnits[lastSoundUnit].envelopePos = 0;
//enable_interrupts();
lastSoundUnit++;
if (lastSoundUnit == POLY_NUM)
lastSoundUnit = 0;
synth->lastSoundUnit = lastSoundUnit;
}
void SynthC(Synthesizer *synth)
{
synth->mixOut = 0;
int16_t *pWaveTable;
uint32_t waveTablePosInt;
SoundUnit *soundUnits = synth->SoundUnitList;
for (uint32_t i = 0; i < POLY_NUM; i++)
{
if (soundUnits[i].envelopeLevel != 0)
{
pWaveTable = (int16_t *)soundUnits[i].waveTableAddress;
waveTablePosInt = (soundUnits[i].wavetablePos) >> 8;
soundUnits[i].val = ((int32_t)soundUnits[i].envelopeLevel) * pWaveTable[waveTablePosInt] >> 8;
soundUnits[i].sampleVal = pWaveTable[waveTablePosInt];
uint32_t waveTablePos = soundUnits[i].increment +
soundUnits[i].wavetablePos;
if (waveTablePos >= soundUnits[i].waveTableLen << 8)
waveTablePos -= soundUnits[i].waveTableLoopLen << 8;
soundUnits[i].wavetablePos = waveTablePos;
synth->mixOut += soundUnits[i].val;
}
}
}
void GenDecayEnvlopeC(Synthesizer *synth)
{
SoundUnit *soundUnits = synth->SoundUnitList;
for (uint32_t i = 0; i < POLY_NUM; i++)
{
if ((soundUnits[i].wavetablePos >> 8) >= soundUnits[i].waveTableAttackLen &&
soundUnits[i].envelopePos < (sizeof(EnvelopeTable) - 1))
{
soundUnits[i].envelopeLevel = EnvelopeTable[soundUnits[i].envelopePos];
soundUnits[i].envelopePos += 1;
}
}
}
#endif
@@ -0,0 +1,107 @@
#ifndef __SYNTH_CORE_H__
#define __SYNTH_CORE_H__
#define pWavetablePos 0
#define pWaveTableAddress (pWavetablePos+4)
#define pWaveTableLen (pWaveTableAddress+4)
#define pWaveTableLoopLen (pWaveTableLen+4)
#define pWaveTableAttackLen (pWaveTableLoopLen+4)
#define pIncrement (pWaveTableAttackLen+4)
#define pEnvelopePos (pIncrement+4)
#define pEnvelopeLevel (pEnvelopePos+2)
#ifdef RUN_TEST
#define pVal (pEnvelopeLevel+2)
#define pSampleVal (pVal+2)
#define SoundUnitSize (pSampleVal+2)
#else
#define SoundUnitSize (pEnvelopeLevel+2)
#endif
#define ENVELOP_LEN 256
#define pMixOut (SoundUnitSize*POLY_NUM)
#define pLastSoundUnit (pMixOut+4)
#define pMainVolume (pLastSoundUnit+2)
#define pDecayGenTick (pMainVolume+2)
#define pFuncHwSet (pDecayGenTick+4)
#define SynthesizerSize (pFuncHwSet+4)
#define POLY_NUM 20
#define MAX_VOLUME_SHIFT_BIT 8
#define DECAY_TIME_FACTOR 120
#ifndef __ASSEMBLER__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _SoundUnit
{
uint32_t wavetablePos;
uint32_t waveTableAddress;
uint32_t waveTableLen;
uint32_t waveTableLoopLen;
uint32_t waveTableAttackLen;
uint32_t increment;
uint16_t envelopePos;
uint16_t envelopeLevel;
#ifdef RUN_TEST
int16_t val;
int16_t sampleVal;
#endif
} __attribute__((packed)) SoundUnit;
typedef enum _SYNTH_HW_STATUS
{
SYNTH_HW_OFF = 0,
SYNTH_HW_ON
}SYNTH_HW_STATUS;
typedef struct _Synthesizer
{
SoundUnit SoundUnitList[POLY_NUM];
int32_t mixOut;
uint16_t lastSoundUnit;
uint16_t mainVolume;
uint32_t decayGenTick;
void (*hwSet)(SYNTH_HW_STATUS);
} __attribute__((packed)) Synthesizer;
extern void SynthInit(Synthesizer *synth);
extern void SynthGenEnvelopeProcess(Synthesizer *synth);
extern void SynthOn(Synthesizer *synth);
extern void SynthOff(Synthesizer *synth);
void SynthRegisterHwChangeFunc(Synthesizer *synth, void (*hwSet)(SYNTH_HW_STATUS));
#ifdef RUN_TEST
extern void NoteOnC(Synthesizer *synth, uint8_t note);
extern void SynthC(Synthesizer *synth);
extern void GenDecayEnvlopeC(Synthesizer *synth);
#endif
extern void NoteOnAsm(Synthesizer *synth, uint8_t note);
extern void GenDecayEnvlopeAsm(Synthesizer *synth);
extern void SynthAsm(Synthesizer *synth);
extern Synthesizer* GlobalSynthPtr;
#ifdef __cplusplus
} //end extern "C"
#endif
#else
.extern EnvelopeTable
.extern GlobalSynthPtr
#endif
#endif
@@ -0,0 +1,151 @@
#include "SynthCore.h"
#include "WaveTable_Celesta_C5.h"
#include "WaveTable_Celesta_C6.h"
#include "AsmCommon.h"
.syntax unified
.section .text
.thumb_func
.global SynthAsm
.global GenDecayEnvlopeAsm
.global NoteOnAsm
.func GenDecayEnvlopeAsm
GenDecayEnvlopeAsm:
pSoundUnitGenEnv .req r0
loopIndexGenEnv .req r4
push {r1-r2,r4-r7,lr}
movs loopIndexGenEnv,#POLY_NUM
loopGenDecayEnvlope:
@ void GenDecayEnvlopeC(Synthesizer* synth)
@ {
@ SoundUnit* soundUnits = synth->SoundUnitList;
@ for (uint32_t i = 0; i < POLY_NUM; i++)
@ {
@ if((soundUnits[i].wavetablePos>>8) >=soundUnits[i].waveTableAttackLen &&
@ soundUnits[i].envelopePos <sizeof(EnvelopeTable)-1)
@ {
@ soundUnits[i].envelopeLevel = EnvelopeTable[soundUnits[i].envelopePos];
@ soundUnits[i].envelopePos += 1;
@ }
@ }
@ }
ldr r5,[pSoundUnitGenEnv,#pWavetablePos]
ldr r6,[pSoundUnitGenEnv,#pWaveTableAttackLen]
lsls r6,r6,#8 @WaveTableAttackLen*=WaveTableAttackLen*256
cmp r5,r6
blo conditionEnd @ blo Lower (unsigned < )
ldrh r5,[pSoundUnitGenEnv,#pEnvelopePos]
ldr r6,=#(ENVELOP_LEN-1)
cmp r5,r6
bhs conditionEnd @ bhs Higher or same (unsigned >= )
ldr r6,=EnvelopeTable
ldrb r6,[r6,r5] @ Load envelope to r6
strh r6,[pSoundUnitGenEnv,#pEnvelopeLevel]
adds r5,r5,#1
strh r5,[pSoundUnitGenEnv,#pEnvelopePos]
conditionEnd:
adds pSoundUnitGenEnv,pSoundUnitGenEnv,#SoundUnitSize
subs loopIndexGenEnv,loopIndexGenEnv,#1 @ set n = n-1
bne loopGenDecayEnvlope
pop {r1-r2,r4-r7,pc}
.endfunc
.func NoteOnAsm
NoteOnAsm:
pSynth .req r2
note .req r1
push {r1-r2,r4-r7,lr}
movs pSynth,r0
@ void NoteOnC(Synthesizer* synth,uint8_t note)
@ {
@ uint8_t lastSoundUnit = synth->lastSoundUnit;
@ SoundUnit* soundUnits = synth->SoundUnitList;
@ //disable_interrupts();
@ soundUnits[lastSoundUnit].increment = WaveTable_Celesta_C5_Increment[note&0x7F];
@ soundUnits[lastSoundUnit].wavetablePos = 0;
@ soundUnits[lastSoundUnit].waveTableAddress = (uint32_t)WaveTable_Celesta_C5;
@ soundUnits[lastSoundUnit].waveTableLen = WAVETABLE_CELESTA_C5_LEN;
@ soundUnits[lastSoundUnit].waveTableLoopLen = WAVETABLE_CELESTA_C5_LOOP_LEN;
@ soundUnits[lastSoundUnit].waveTableAttackLen = WAVETABLE_CELESTA_C5_ATTACK_LEN;
@ //enable_interrupts();
@ lastSoundUnit++;
@ if (lastSoundUnit== POLY_NUM)
@ lastSoundUnit = 0;
@ synth->lastSoundUnit=lastSoundUnit;
@ }
ldr r5,=#pLastSoundUnit
adds r5,r5,pSynth
ldrh r5,[r5]
movs r6,#SoundUnitSize
muls r5,r5,r6
adds pSynth,pSynth,r5
movs r5,#0x7F
ands note,note,r5
@cpsid i @ PRIMASK=1 Disable all interrupt except NMI ands Hardfault
movs r7,#1
MSR PRIMASK,r7
movs r6,#80
cmp note,r6
bhi c6_branch
lsls note,note,#1
ldr r5,=WaveTable_Celesta_C5_Increment
ldrh r5,[r5,note]
str r5,[pSynth,#pIncrement]
ldr r5,=WaveTable_Celesta_C5
str r5,[pSynth,#pWaveTableAddress]
ldr r5,=#WAVETABLE_CELESTA_C5_LEN
str r5,[pSynth,#pWaveTableLen]
ldr r5,=#WAVETABLE_CELESTA_C5_LOOP_LEN
str r5,[pSynth,#pWaveTableLoopLen]
ldr r5,=#WAVETABLE_CELESTA_C5_ATTACK_LEN
str r5,[pSynth,#pWaveTableAttackLen]
b c5_c6_branch_end
c6_branch:
lsls note,note,#1
ldr r5,=WaveTable_Celesta_C6_Increment
ldrh r5,[r5,note]
str r5,[pSynth,#pIncrement]
ldr r5,=WaveTable_Celesta_C6
str r5,[pSynth,#pWaveTableAddress]
ldr r5,=#WAVETABLE_CELESTA_C6_LEN
str r5,[pSynth,#pWaveTableLen]
ldr r5,=#WAVETABLE_CELESTA_C6_LOOP_LEN
str r5,[pSynth,#pWaveTableLoopLen]
ldr r5,=#WAVETABLE_CELESTA_C6_ATTACK_LEN
str r5,[pSynth,#pWaveTableAttackLen]
c5_c6_branch_end:
ldr r5,=#0
strh r5,[pSynth,#pEnvelopePos]
str r5,[pSynth,#pWavetablePos]
ldr r5,=#255
strh r5,[pSynth,#pEnvelopeLevel]
@ cpsie i @ PRIMASK=0 enable all interrupt
movs r7,#0
MSR PRIMASK,r7
movs pSynth,r0
ldr r5,=#pLastSoundUnit
adds r5,r5,pSynth
ldrh r5,[r5]
adds r5,r5,#1
cmp r5,#POLY_NUM
bne updateLastSoundUnitEnd
movs r5,#0
updateLastSoundUnitEnd:
ldr r6,=#pLastSoundUnit
adds r6,r6,pSynth
strh r5,[r6]
pop {r1-r2,r4-r7,pc}
.endfunc
@@ -0,0 +1,35 @@
#include "SynthCore.h"
#include "Player.h"
#include "AsmCommon.h"
.section .text
// if (player->decoder.status == STATUS_DECODING)
// player->decoder.currentTick++;
// if (player->synthesizer.decayGenTick < 200)
// player->synthesizer.decayGenTick += 1;
UpdateTick:
ptrSoundUnit .req r0
ptrScoreDecoder .req r1
ldr r5,=#pStatus
add r5,r5,ptrScoreDecoder
ldr r5,[r5]
cmp r5,#constSTATUS_DECODING
bne currentTickUpdateEnd
ldr r5,=#pCurrentTick
add r5,r5,ptrScoreDecoder
ldr r6,[r5]
adds r6,r6,#1
str r6,[r5]
currentTickUpdateEnd:
ldr r5,=#pDecayGenTick
add r5,r5,ptrSoundUnit
ldr r6,[r5]
ldr r4,=#DECAY_TIME_FACTOR
cmp r6,r4
bhs updateDecayGenTickEnd //bhs Branch if Same or Higher (Unsigned)
adds r6,r6,#1
str r6,[r5]
updateDecayGenTickEnd:
@@ -0,0 +1,284 @@
#include <stdint.h>
#include <WaveTable_Celesta_C5.h>
// Sample's base frequency: 523.629906 Hz
// Sample's sample rate: 32000 Hz
const int16_t WaveTable_Celesta_C5[WAVETABLE_CELESTA_C5_LEN]={
// Attack Samples:
12, -142, -127, -198, 8, 109, -157, 345, -189, -106,
555, -508, 495, 830, -452, 1372, 803, 5, 2262, -224,
-1899, -3465, -8020, -4, 12132, 13671, 9428, -971, -8338, -6442,
-5111, 5753, 20020, 11950, 1296, 271, -335, 2992, -1258, -4801,
5142, 446,-10050, -8540,-11166, 615, 9248,-12360,-20813,-15906,
-13506, -1591, -7745,-16060, 66, 2383, -771, 3063, -8204, -8016,
405, -7026, -4286, -5091,-10862, 5080, 7819, 3408, 16251, 9561,
3014, 13811, 11067, 18011, 21869, 3746, 3866, 1190, -6815, 9137,
7598, 1737, 12925, 4893, 7198, 17180, 1671, 1833, 2974, -9887,
3148, 4349, -8280, -2972,-14283,-17634, -3157,-15288,-18315,-12318,
-22975,-10004, -2219,-15243, -7346,-11649,-18505, -313, -3194, -4113,
7957, -4112, -430, 10244, -1330, 6128, 6397, -6745, 8285, 10752,
5334, 19596, 10687, 5795, 19976, 12492, 19691, 27097, 7486, 9830,
8733, -547, 16003, 10205, -1175, 8520, -4603, -2802, 12726, -237,
3620, 5677, -9882, 3838, 6263, -6100, 287,-16399,-25604, -8070,
-16325,-15758,-11106,-30641,-19901, -8537,-19154, -8239,-14949,-24755,
-4541, -8448, -8318, 5556, -8723, -2357, 10395, -1011, 11228, 9853,
-4992, 13007, 11261, 7661, 24438, 6800, 2570, 14614, -888, 11310,
17960, -710, 11895, 8750, -994, 17081, 5885, 280, 12376, -3797,
2598, 13728, -235, 10517, 6177,-10520, 6549, 1710, -3613, 10163,
-8948,-10933, 2230,-11585, -2025, -2458,-24629,-11380,-12566,-17938,
217,-14711,-19395, -5625,-19874, -9185, 858,-17572, -5671, -6524,
-18001, 2183, -5250,-11091, 4658,-10280, -4999, 9121, -5884, 6428,
9024, -4779, 16264, 13835, 5675, 21595, 6257, 6481, 22836, 6658,
14174, 17375, -3306, 13173, 14319, 3012, 19927, 6175, -1422, 15664,
2259, 7995, 16975, -3898, 4853, 4064,-11587, 5137, -2835,-13780,
-858,-18616,-18229, -2435,-19190,-12564, -9124,-25166, -5514, -3092,
-13191, 1908,-11082,-15162, 2896, -9710, -5123, 1418,-18583, -5671,
-501,-12076, 4410, -3432,-12848, 4432, -4237, 463, 15442, -625,
6675, 13311, 918, 17746, 16371, 3385, 17205, 8206, 6559, 22470,
7028, 7806, 14967, -562, 11477, 14104, -1303, 10109, 3543, -3077,
13524, 2515, -184, 7958, -9765, -4051, 2637,-11070, 336, -3645,
-17977, -4177,-10205,-13044, 493,-14509,-12695, -1521,-13072, -1591,
1610,-13316, -1775, -5132,-11604, 3545, -7647,-11578, -134,-12170,
-4685, 3905,-11238, -2887, -3259,-11762, 6124, 2020, -3193, 9773,
-2480, 446, 14056, 2565, 10276, 12506, -2309, 10755, 10922, 4117,
17918, 6310, 1891, 15164, 3653, 8408, 15292, -484, 8766, 11025,
-383, 11674, 4221, -4921, 7293, -3485, -3789, 6226, -9263, -5270,
-896,-13788, -830, -1213,-13134, -2683,-10502,-11443, 3752, -8243,
-8102, -2302,-16442, -6687, -2418,-13318, -1378, -7077,-15430, -692,
-7290, -6728, 3868,-10765, -6658, 1336, -7981, 4798, 4929, -5687,
6543, 1671, -719, 12453, 1278, 1715, 10990, 509, 9742, 14189,
2827, 12442, 8600, 1987, 15888, 8505, 5457, 14583, 2705, 6834,
13473, 850, 7502, 5855, -4290, 7202, 1371, -4798, 4789, -6683,
-6557, 2664, -8236, -1272, 1271,-11718, -2227, -2725, -7487, 4563,
-5891,-12251, -3244,-12427, -7504, -1632,-15400, -8890, -7384,-15047,
-2063, -5458,-10632, 262, -8852, -7089, 4404, -4877, 976, 4289,
-6133, 5343, 5650, -1519, 8941, 1555, -557, 11514, 3094, 6728,
13229, 1792, 10207, 13667, 6057, 17156, 12063, 5356, 16617, 8860,
8330, 15169, 1619, 4446, 8501, -1700, 6736, 4032, -6053, 3416,
-3062, -5983, 4192, -6589, -5964, 67,-11099, -4036, -1908,-11542,
-2871, -8359,-15857, -5488,-12380,-12749, -5136,-16498,-11083, -3859,
-12302, -3542, -3866,-10853, 1335, -2310, -4805, 5008, -4030, -2060,
5492, -3334, 4176, 6712, -3042, 5913, 4756, 1707, 13515, 6940,
4996, 12795, 4584, 10617, 16757, 6730, 13105, 12316, 4985, 14736,
9102, 3372, 10108, 652, 1504, 7416, -3396, 975, 2060, -7491,
1170, -1143, -7114, 1614, -5970, -7703, 870, -7647, -4985, -2190,
-13000, -6223, -5849,-12941, -4163, -9063,-13249, -4342,-10756, -8195,
-362, -9179, -4505, -1880, -8735, 1217, 263, -5547, 2435, -3726,
-4142, 5420, -1943, 563, 4433, -4097, 3988, 6091, 256, 9135,
5431, 2174, 11701, 6476, 8753, 15514, 6224, 10494, 13365, 5610,
12206, 8597, 1352, 8810, 3100, 1191, 7734, -1396, 267, 4698,
-3443, 2164, 1955, -5790, 1409, -2257, -5983, 1800, -5766, -7373,
-3063,-11472, -6652, -3598,-11637, -6115, -8385,-12818, -3347, -7220,
-8620, -1940, -9427, -6742, -1543, -8144, -1723, -1382, -8669, -1260,
-3309, -5418, 2924, -3359, -3174, 3263, -2795, 2677, 6250, -151,
7101, 6936, 3562, 12846, 9183, 7952, 14322, 7327, 10000, 13919,
5250, 8987, 8484, 2124, 9069, 5115, 590, 6553, -83, 232,
5758, -1781, 1454, 2804, -4926, 823, -920, -6101, 58, -6128,
-8530, -2447, -8844, -6073, -2393,-10416, -6030, -5990,-11547, -4118,
-6855,-10136, -3319, -8385, -7051, -1230, -8164, -4707, -2816, -9000,
-1956, -2744, -7239, -141, -3956, -4150, 3593, -1389, 1674, 6082,
184, 6782, 9019, 4490, 11534, 8645, 5462, 12516, 7606, 7627,
11706, 4005, 6791, 9024, 3039, 8582, 6737, 1769, 8133, 4110,
2609, 8124, 1330, 1778, 4241, -3418, 156, 240, -6130, -1543,
-5158, -8791, -2889, -8262, -9021, -4925,-11493, -8304, -5227,-10665,
-5682, -6857,-11005, -3947, -6623, -8215, -3426, -9359, -7333, -2650,
-7990, -3543, -2453, -7162, -746, -1408, -2683, 4602, 1204, 1580,
7059, 2659, 6918, 10583, 5338, 9754, 8970, 4904, 11003, 7890,
5900, 10982, 5714, 6655, 10322, 4625, 7933, 8626, 3398, 8461,
6284, 2270, 6654, 1627, 244, 3731, -2847, -2179, -1298, -7908,
-4507, -5187, -9290, -4174, -7652,-10055, -5081, -9187, -7399, -3113,
-8631, -6186, -5470, -9962, -4545, -5723, -8952, -4117, -7896, -8004,
-2949, -7289, -4978, -2262, -6438, -948, 730, -1745, 4243, 2539,
1614, 7676, 4287, 5256, 8727, 3679, 6861, 8504, 4316, 8978,
7855, 5068, 10119, 6833, 6263, 10401, 5513, 7000, 9195, 4379,
8143, 7655, 2638, 6201, 2780, -414, 3092, -2124, -3093, -1080,
-6939, -4912, -4019, -8455, -4490, -5771, -8601, -3470, -5897, -6604,
-3140, -8287, -7212, -4787, -9181, -6002, -6508,-10823, -6243, -7354,
-8211, -3069, -6673, -6162, -1719, -4688, -890, 1786, -1498, 3120,
3232, 1609, 7485, 5413, 4313, 8049, 4184, 5886, 8799, 4597,
7502, 7937, 4638, 9371, 8313, 6276, 10348, 7030, 7159, 10641,
6185, 7279, 7786, 2518, 4884, 3318, -1002, 1684, -2159, -4610,
-1676, -5753, -5068, -2742, -7327, -5003, -4074, -7121, -2800, -4182,
-7254, -4025, -7350, -7914, -4689, -8843, -7733, -6255, -9992, -6275,
-5767, -8520, -4372, -5731, -6170, -1122, -3223, -1907, 1587, -1380,
1953, 4366, 1663, 5224, 4305, 2034, 6561, 5044, 4861, 8275,
4688, 5824, 8436, 5647, 9043, 9719, 6849, 10537, 9250, 7512,
10534, 6536, 5306, 7047, 2783, 3566, 3439, -1537, -136, -1876,
-5203, -2003, -4149, -5326, -2543, -5952, -5262, -2960, -6228, -4315,
-4461, -7894, -4939, -6146, -8269, -5670, -8503, -8727, -5796, -8567,
-7020, -5497, -8131, -4797, -4041, -5487, -1407, -1953, -2151, 1540,
-101, 1478, 4147, 1560, 3888, 5019, 3060, 6312, 5519, 3625,
6706, 5545, 6396, 9607, 7394, 8905, 10319, 7597, 9803, 9494,
6914, 8730, 6245, 4380, 6228, 2902, 1853, 1913, -2190, -1389,
-1253, -4023, -2140, -3363, -5205, -2651, -4241, -4323, -2305, -5203,
-4830, -4078, -6790, -5083, -5634, -8471, -6938, -8434, -9098, -6470,
-8414, -7943, -5794, -7247, -4793, -3340, -4718, -1877, -1614, -2058,
1006, 21, 260, 2357, 278, 1669, 3618, 2131, 4162, 4432,
3455, 6651, 6699, 6799, 9549, 8307, 8978, 10730, 8826, 9949,
9881, 7012, 7899, 6594, 4620, 5738, 3122, 1353, 1897, -855,
-888, -502, -2961, -1882, -2007, -3689, -2031, -3233, -4662, -3620,
-5854, -6322, -5404, -7702, -7378, -7454, -9600, -8019, -8215, -9243,
-7132, -7749, -7288, -4611, -5255, -3998, -2509, -3920, -2178, -1512,
-2449, -155, -243, -353, 2168, 1550, 2166, 3970, 2696, 4238,
5876, 5378, 7881, 8454, 7920, 10172, 9495, 9094, 10514, 8703,
8508, 8966, 6747, 7218, 6671, 4123, 4447, 2730, 884, 1813,
-17, -843, -266, -2490, -2240, -1909, -3963, -3309, -4256, -6252,
-5198, -6352, -7250, -6333, -8189, -8082, -7160, -8719, -7593, -7086,
-8083, -5878, -5509, -5729, -3710, -4411, -4193, -2498, -3471, -2513,
-1596, -2828, -1006, -139, -374, 1888, 1699, 1664, 3707, 3300,
4768, 7086, 6541, 8003, 8624, 7369, 8982, 8913, 8010, 9198,
7769, 7087, 7841, 5902, 5798, 5782, 3361, 3511, 2937, 1284,
2000, 502, -796, 117, -1505, -2043, -1912, -4170, -3996, -4107,
-6126, -5587, -6233, -7414, -6314, -7432, -7785, -6398, -7441, -6749,
-5585, -6548, -5065, -4485, -5433, -3981, -4331, -4803, -3310, -4415,
-4267, -2626, -3196, -1679, -246, -676, 1355, 2163, 2292, 4857,
5267, 5714, 7307, 6285, 7023, 8460, 7416, 8223, 8054, 6543,
7587, 6857, 5969, 7253, 6046, 5365, 5607, 3686, 3993, 4299,
2649, 3241, 2441, 717, 1241, -525, -2143, -2035, -3990, -4258,
-4017, -6174, -6077, -6244, -7423, -6084, -6693, -7629, -6233, -6928,
-6627, -5340, -6502, -5732, -5024, -6274, -5120, -5069, -5946, -4549,
-4914, -4735, -2813, -3088, -1911, -117, -433, 1313, 2531, 2405,
4681, 5374, 5573, 7405, 6858, 7090, 8281, 7054, 7561, 8173,
7039, 7993, 7756, 6554, 7508, 6619, 5945, 6801, 5268, 4852,
5011, 3079, 3036, 2394, 200, 182, -1263, -3123, -2863, -4530,
-5428, -5165, -7194, -7393, -6889, -7837, -6621, -6338, -7087, -5629,
-5833, -6120, -4898, -5927, -5977, -4997, -5967, -5242, -4865, -6085,
-5037, -4756, -4791, -2585, -2213, -1670, 397, 401, 1693, 3436,
3160, 4768, 5699, 5195, 6671, 6629, 6311, 7825, 7150, 7057,
8082, 6988, 7414, 7901, 6596, 7420, 7347, 6153, 6897, 5854,
4623, 4866, 2919, 1962, 1786, -413, -878, -1584, -3686, -3634,
-4656, -6304, -5889, -6830, -7090, -5941, -6717, -6235, -5373, -6349,
-5532, -5281, -6179, -5111, -5416, -5946, -4930, -5974, -6317, -5515,
-6288, -5125, -3801, -4165, -2702, -1922, -1499, 944, 1619, 2240,
4079, 4006, 4817, 5921, 5221, 6130, 6677, 5941, 6893, 6575,
5970, 6903, 6174, 6085, 6955, 6238, 6922, 7579, 6615, 7017,
6438, 4999, 5094, 3755, 2187, 1594, -401, -1334, -1850, -3935,
-4619, -5195, -6346, -5793, -6058, -6412, -5287, -5592, -5531, -4689,
-5237, -4797, -4494, -5619, -5392, -5554, -6218, -5745, -6357, -6566,
-5471, -5578, -4881, -3738, -3631, -2193, -953, -608, 928, 1696,
2060, 3344, 3483, 3916, 4769, 4227, 4518, 5158, 4969, 5705,
5771, 5319, 6032, 6186, 6511, 7617, 7556, 7823, 8251, 7458,
7373, 6996, 5678, 4991, 3524, 1707, 985, -366, -1514, -2071,
-3634, -4422, -4603, -5291, -4967, -4747, -5020, -4496, -4618, -4919,
-4622, -5273, -5660, -5480, -6163, -6403, -6551, -7207, -6945, -6735,
-6755, -5922, -5653, -5423, -4374, -3771, -2572, -824, -49, 735,
1403, 1561, 2514, 3225, 3382, 4063, 4111, 4089, 4663, 4678,
5060, 5979, 6340, 7079, 7775, 7960, 8772, 8928, 8398, 8420,
7962, 7139, 6312, 4669, 3417, 2621, 1209, 143, -938, -2203,
-2561, -3074, -3762, -3670, -3772, -3872, -3739, -4210, -4448, -4498,
-5110, -5410, -5821, -6456, -6428, -6621, -7130, -7276, -7469, -7140,
-6346, -5955, -5340, -4621, -4180, -3220, -2103, -1175, -262, 157,
522, 1240, 1653, 2061, 2629, 2880, 3102, 3354, 3637, 4467,
5389, 5940, 6451, 6765, 7225, 8000, 8410, 8396, 8198, 7866,
7529, 6947, 5933, 4866, 3893, 3013, 2211, 1398, 562, -187,
-963, -1643, -1896, -2009, -2343, -2876, -3510, -4004, -4266, -4603,
-5057, -5645, -6411, -6885, -6913, -6994, -7132, -7364, -7502, -7086,
-6520, -6016, -5395, -4895, -4320, -3437, -2706, -1817, -952, -548,
-237, -19, 303, 1008, 1388, 1560, 1989, 2434, 3258, 4293,
4810, 5365, 5955, 6475, 7390, 8050, 8364, 8618, 8297, 8025,
7945, 7335, 6636, 5803, 4808, 4272, 3526, 2506, 1736, 627,
-275, -660, -1235, -1563, -1995, -2942, -3521, -4065, -4568, -4530,
-5064, -5911, -6330, -6929, -7031, -6996, -7672, -7836, -7662, -7389,
-6399, -5798, -5503, -4751, -4277, -3476, -2441, -2078, -1565, -1324,
-1603, -1178, -682, -220, 569, 657, 1030, 2135, 2858, 3879,
4811, 5063, 5947, 6729, 7252, 8262, 8454, 8285, 8403, 7887,
7675, 7590, 6498, 5614, 4743, 3758, 3614, 2972, 1874, 1162,
33, -467, -125, -478, -853, -1380, -2374, -2646, -3069, -3969,
-4464, -5553, -6456, -6432, -6812, -6934, -6822, -7232, -6903, -6337,
-6095, -5267, -4831, -4587, -3633, -3217, -2922, -2459, -2675, -2537,
-2199, -2180, -1406, -824, -749, -69, 465, 1303, 2787, 3504,
4150, 4965, 5274, 6231, 7218, 7415, 7750, 7509, 6917, 7092,
6823, 6358, 6069, 5071, 4511, 4349, 3662, 3384, 2981, 2177,
2083, 1684, 1146, 1065, 232, -560, -919, -1859, -2415, -3141,
-4629, -5334, -5874, -6440, -6326, -6886, -7442, -6983, -6733, -6070,
-5269, -5380, -4987, -4528, -4445, -3563, -3196, -3342, -3005, -3381,
-3522, -2858, -2688, -1998, -1309, -1287, -266, 708, 1354, 2624,
3043, 3483, 4769, 5273, 5919, 6669, 6434, 6874, 7145, 6518,
6629, 6386, 5886, 6060, 5427, 4975, 5179, 4472, 4135, 3847,
2892, 2964, 2792, 1924, 1610, 513, -589, -911, -2076, -2971,
-3578, -4936, -5356, -5565, -6336, -6223, -6439, -6679, -5821, -5672,
-5566, -5030, -5291, -4857, -4183, -4449, -4224, -4382, -4872, -4283,
-4070, -3874, -3084, -3070, -2649, -1732, -1334, -133, 1051, 1594,
2684, 3262, 3721, 5036, 5624, 6102, 6655, 6215, 6309, 6601,
6236, 6441, 6348, 5868, 6040, 5656, 5340, 5646, 5244, 5100,
4993, 3970, 3516, 2992, 1939, 1434, 476, -683, -1263, -2661,
-3768, -4086, -4817, -5045, -5314, -6202, -6031, -5727, -5605, -4827,
-4801, -4929, -4471, -4767, -4927, -4928, -5577, -5453, -5203, -5385,
-5036, -5044, -4941, -3830, -3511, -2835, -1608, -653,
// Loop Samples:
-82, 926,
1357, 2135, 3431, 3817, 4539, 4993, 5010, 5783, 6097, 5795,
6130, 6076, 6276, 6848, 6456, 6434, 6837, 6617, 6874, 6685,
5792, 5694, 5264, 4523, 4039, 2555, 1265, 443, -1124, -1957,
-2579, -3739, -4123, -4796, -5708, -5569, -5590, -5475, -4961, -5391,
-5479, -5173, -5566, -5465, -5509, -6095, -5969, -6236, -6546, -6082,
-6201, -6103, -5405, -5179, -4338, -3301, -2761, -1482, -409, 292,
1614, 2272, 2801, 3893, 4303, 4893, 5613, 5410, 5570, 5779,
5700, 6549, 7118, 7216, 7720, 7599, 7676, 8231, 7930, 7661,
7211, 6015, 5515, 4940, 3729, 2786, 1336, -123, -946, -2206,
-3101, -3437, -4195, -4490, -4739, -5387, -5245, -5227, -5634, -5503,
-5774, -5960, -5760, -6401, -6790, -6638, -6741, -6363, -6205, -6582,
-6270, -5941, -5512, -4366, -3731, -3012, -1877, -1267, -276, 796,
1269, 2168, 2760, 2873, 3667, 4074, 4201, 4742, 4667, 5029,
5986, 6356, 6976, 7374, 7167, 7628, 7915, 7781, 7984, 7509,
6964, 6786, 5851, 5022, 4233, 2712, 1757, 794, -631, -1313,
-2144, -3090, -3428, -4328, -4798, -4522, -4866, -4892, -4892, -5514,
-5392, -5475, -6064, -6076, -6540, -6860, -6430, -6735, -6783, -6394,
-6528, -5834, -4874, -4385, -3193, -2371, -1908, -736, -165, 502,
1602, 1688, 2053, 2580, 2462, 3136, 3546, 3346, 3952, 4145,
4372, 5473, 5901, 6555, 7553, 7538, 7902, 8191, 7552, 7467,
7054, 6346, 6162, 4912, 3384, 2460, 1023, 354, 100, -1028,
-1564, -2194, -3243, -3264, -3459, -3754, -3542, -4409, -5105, -4919,
-5300, -5303, -5425, -6315, -6242, -6324, -6720, -6186, -6306, -6370,
-5460, -5130, -4244, -3030, -2855, -2149, -1396, -1176, -161, 197,
247, 952, 714, 640, 1301, 1164, 1538, 2123, 2079, 3142,
4105, 4479, 5655, 6064, 6309, 7276, 7119, 7123, 7426, 6681,
6596, 6473, 5466, 5105, 4081, 2765, 2564, 1686, 928, 793,
-323, -840, -879, -1527, -1332, -1632, -2778, -2928, -3469, -3948,
-3540, -4200, -4841, -5117, -6233, -6249, -5837, -6139, -5629, -5665,
-5996, -5089, -4808, -4496, -3488, -3446, -2772, -1777, -1933, -1388,
-1096, -1450, -697, -495, -477, 484, 557, 1091, 2543, 2973,
3984, 4863, 4657, 5638, 6384, 6479, 7333, 7068, 6608, 7075,
6541, 6331, 6300, 4853, 4278, 3992, 3089, 3156, 2532, 1382,
1338, 556, 69, 397, -689, -1314, -1494, -2602, -2532, -2727,
-3927, -4081, -5033, -6057, -5724, -6274, -6529, -6161, -6886, -6453,
-5540, -5628, -4785, -4566, -4818, -3632, -3331, -3218, -2188, -2377,
-2111, -1306, -1602, -882, -187, -437, 643, 1347, 1798, 3219,
3289, 3437, 4582, 4715, 5540, 6449, 5933, 6424, 6768, 6360,
6978, 6410, 5320, 5383, 4514, 4077, 4318, 3251, 2955, 2710,
1489, 1792, 1743, 885, 874, -223, -1186, -1105, -2204, -2875,
-3217, -4806, -5346, -5645, -6297, -5595, -5747, -6410, -5682, -5544,
-5103, -4192, -4738, -4562, -3845, -3888, -2992, -2715, -3225, -2638,
-2757, -2912, -2091, -2277, -1985, -995, -817, 298, 1354, 1365,
2387, 3117, 3602, 5171, 5615, 5792, 6441, 5968, 6258, 6977,
6420, 6324, 5836, 4765, 5095, 4953, 4388, 4572, 3805, 3319,
3554, 2710, 2342, 1925, 445, 56, -431, -1463, -1602, -2582,
-3775, -3945, -4871, -5171, -4838, -5542, -5494, -5357, -5835, -5047,
-4643, -4947, -4484, -4739, -4638, -3651, -3897, -3948, -3644, -4059,
-3394, -2838, -3176, -2637, -2488, -2229, -783, -163, 457, 1575,
1705, 2646, 4021, 4446, 5417, 5689, 5127, 5554, 5545, 5526,
6062, 5304, 4883, 5295, 4956, 5288, 5444, 4624, 4748, 4579,
4047, 4289, 3523, 2578, 2302, 1187, 656, 320, -1208, -1978,
-2585, -3596, -3690, -4393, -5212, -4913, -5206, -5244, -4723, -5124,
-4949, -4683, -5177, -4661, -4265, -4508, -4253, -4836, -5282, -4657,
-4625, -4300, -3663, -3831, -3162, -2155, -1523, -165, 569, 882,
1994, 2574, 3343, 4450, 4308, 4270, 4527, 4398, 5139, 5575,
5179, 5362, 5106, 4992, 5711, 5693, 5763, 6012, 5509, 5670,
5726, 4795, 4195, 3214, 2264, 2211, 1267, -118, -1181, -2584,
-3170, -3342, -4062, -4255, -4600, -5292, -5138, -5214, -5253, -4684,
-4875, -5050, -4866, -5169, -4837, -4485, -4940, -5025, -5291, -5490,
-4852, -4582, -4238, -3163, -2620, -1760, -867, -326,};
const uint16_t WaveTable_Celesta_C5_Increment[]={
3, 4, 4, 4, 5, 5, 5, 5, 6, 6,
7, 7, 7, 8, 8, 9, 10, 10, 11, 11,
12, 13, 14, 15, 15, 16, 17, 18, 20, 21,
22, 23, 25, 26, 28, 30, 31, 33, 35, 37,
40, 42, 45, 47, 50, 53, 56, 60, 63, 67,
71, 75, 80, 85, 90, 95, 101, 107, 113, 120,
127, 134, 143, 151, 160, 170, 180, 190, 202, 214,
227, 240, 254, 269, 286, 303, 321, 340, 360, 381,
404, 428, 454, 481, 509, 539, 572, 606, 642, 680,
720, 763, 808, 857, 908, 962, 1019, 1079, 1144, 1212,
1284, 1360, 1441, 1527, 1617, 1714, 1816, 1924, 2038, 2159,
2288, 2424, 2568, 2721, 2882, 3054, 3235, 3428, 3632, 3848,
4077, 4319, 4576, 4848, 5136, 5442, 5765, 6108,};
@@ -0,0 +1,20 @@
#ifndef __WAVETABLE_CELESTA_C5__
#define __WAVETABLE_CELESTA_C5__
// Sample's base frequency: 523.629906 Hz
// Sample's sample rate: 32000 Hz
#define WAVETABLE_CELESTA_C5_LEN 2608
#define WAVETABLE_CELESTA_C5_ATTACK_LEN 1998
#define WAVETABLE_CELESTA_C5_LOOP_LEN 610
#ifndef __ASSEMBLER__
#include <stdint.h>
extern const int16_t WaveTable_Celesta_C5[WAVETABLE_CELESTA_C5_LEN];
extern const uint16_t WaveTable_Celesta_C5_Increment[];
#else
.extern WaveTable_Celesta_C5
.extern WaveTable_Celesta_C5_Increment
#endif
#endif
@@ -0,0 +1,159 @@
#include <stdint.h>
#include <WaveTable_Celesta_C6.h>
// Sample's base frequency: 1046.832025 Hz
// Sample's sample rate: 32000 Hz
const int16_t WaveTable_Celesta_C6[WAVETABLE_CELESTA_C6_LEN]={
// Attack Samples:
-126, 46, -68, 105, 10, -80, 274, 20, 228, 11,
473, 139, 568, 381, 707, 739, 1340, 1598, -872, -9072,
-9845, -6181, -452, 1399, -2002, 3272, 24345, 20587, 1495, 8390,
13074, -727,-10282, -8426,-15230, -9923, 1271,-10785,-18202, -3907,
-9044,-18986, -1366, 11172, -2065, 4477, 22083, 12858, -934, 13767,
16147, -8430, -210, 25642, 6687,-14206, 4064, 10394,-13637, -8863,
13332, -6710,-20858, 2819, 7017,-23088,-19545, 3804,-10445,-27497,
-2276, 10614, -7921, -7660, 14779, 9302, -7892, 7849, 24858, 2573,
-5891, 20419, 20469, -1111, 8924, 25426, 5732, -8190, 9350, 6885,
-17177,-12737, 4010, -8145,-22227, -4557, 490,-18971,-18781, -352,
-6672,-18313, -4794, 5930, -7894, -7792, 11093, 11323, 220, 8065,
18507, 9227, 3540, 15268, 15245, 2260, 5068, 13361, 2266, -3987,
5155, 4588, -6511, -4701, 2018, -8411,-15680, -7738, -5391,-14110,
-9207, 294, -6612,-12654, -2209, 1454, -7512, -5351, 6788, 4439,
-2401, 7843, 15983, 6112, 3851, 15440, 13451, 1676, 4888, 10797,
-121, -5472, 3390, 1115,-10786, -8034, -1660,-10756,-15741, -5493,
-3904,-11654, -6414, 2998, -3024, -7609, 2822, 5893, -1397, 1095,
11822, 8914, 2517, 8857, 12677, 2978, 359, 8812, 5621, -3907,
831, 5493, -2903, -6917, -117, -2528,-11805, -9230, -3398, -8260,
-12108, -4882, -2315, -8113, -5136, 3049, -1433, -5643, 3357, 9042,
3150, 4640, 12173, 9543, 4080, 9652, 12398, 5237, 3691, 9381,
6185, -1346, -259, 1316, -6232, -9920, -7007, -9056,-14989,-11920,
-6122, -8336,-10292, -3678, -765, -5709, -3474, 3773, 2840, 676,
7196, 10743, 5948, 5640, 10910, 8668, 4192, 7455, 9881, 5007,
4456, 8281, 4712, -1845, -37, -128, -7236,-10954, -7675, -9569,
-14589,-11405, -6840, -9929,-11589, -5365, -2638, -5478, 549, 8235,
7011, 5777, 11695, 13268, 8260, 7698, 10390, 7149, 3451, 5610,
7212, 1977, -115, 2527, -1434, -7140, -5667, -4592, -9792, -9621,
-5122, -6096, -8898, -4883, -2251, -6181, -7127, -1320, -164, -1504,
2628, 6878, 4743, 3920, 6924, 8036, 5598, 6188, 8628, 7909,
5915, 6959, 6844, 3198, 579, 46, -3276, -7620, -8134, -8096,
-10719,-11316, -8502, -8214, -9749, -7734, -4790, -5000, -3575, 1865,
4546, 3773, 6370, 9386, 8995, 8246, 10135, 10393, 8042, 7793,
9381, 7039, 2939, 2288, 1320, -3401, -5709, -5767, -7856,-10682,
-9578, -8561,-10194,-10353, -7673, -6946, -8165, -5923, -1202, -432,
479, 5396, 7850, 6245, 7626, 10846, 9529, 7720, 9967, 10411,
7367, 6586, 7625, 4661, 662, -3, -1392, -5445, -7511, -7115,
-9155,-11655,-10648, -9137,-10281,-10298, -7652, -5607, -5586, -3079,
1226, 2828, 3383, 6765, 8296, 7102, 7671, 10103, 9778, 8883,
10225, 10197, 6631, 4842, 4595, 1766, -2018, -2691, -3488, -6940,
-9028, -8454, -9381,-11072, -9529, -7398, -8173, -7890, -4312, -2362,
-2525, 160, 3744, 3975, 4543, 6652, 7508, 6434, 7344, 9293,
8873, 7459, 7684, 7019, 4239, 2148, 1962, -452, -3646, -4559,
-5393, -8586,-10155, -8845, -8942,-10038, -8460, -6044, -5489, -4633,
-1414, 681, 1349, 3803, 6182, 6011, 5906, 7447, 7895, 7092,
7279, 7936, 6798, 4582, 3797, 3089, 801, -830, -1683, -3483,
-5870, -6779, -7542, -9043, -9103, -7790, -7321, -7179, -5634, -3282,
-2321, -1130, 1378, 3266, 3903, 5013, 6439, 6662, 6418, 7199,
7906, 7183, 6443, 6138, 4784, 2795, 1825, 1111, -1107, -3213,
-4226, -5988, -8346, -8790, -8535, -9168, -8912, -6765, -5516, -5016,
-3110, -821, -121, 1180, 3788, 5135, 5225, 6842, 8443, 7725,
7164, 7810, 7284, 5507, 5077, 4860, 2656, 922, 784, -1004,
-4162, -5868, -6706, -8411, -9647, -9533, -8941, -8585, -7218, -5347,
-4368, -3858, -1687, 1031, 2348, 3615, 6177, 7302, 7199, 8240,
9219, 8184, 7266, 7380, 6251, 4058, 3482, 3144, 847, -1415,
-2077, -3623, -6660, -8229, -8466, -9495,-10073, -8765, -7636, -7258,
-6013, -3928, -2791, -1423, 1135, 3484, 4533, 5983, 7669, 8062,
7437, 7645, 7767, 7006, 6209, 5902, 5143, 3929, 2722, 1206,
-952, -2974, -4932, -6932, -8309, -8937, -9172, -8896, -8187, -7312,
-6434, -5522, -4206, -2551, -553, 1630, 3592, 5373, 6768, 7511,
7793, 7665, 7410, 6913, 6472, 6016, 5284, 4278, 3365, 2095,
384, -1515, -3612, -5839, -7574, -8884, -9822, -9656, -8710, -7927,
-7028, -5773, -4507, -3171, -1288, 1149, 3383, 5016, 6536, 7589,
7828, 7628, 7561, 7268, 6811, 6601, 6343, 5261, 3749, 2370,
821, -1321, -3759, -5596, -7145, -8544, -9380, -9570, -9270, -8629,
-7694, -6705, -5749, -4125, -2028, -4, 2258, 4634, 6296, 7275,
7737, 7998, 8092, 8194, 8094, 7522, 6741, 5924, 4414, 2355,
580, -1052, -3107, -5112, -6592, -7831, -8716, -9024, -9034, -8677,
-7597, -6593, -5923, -4636, -2698, -936, 927, 3232, 4895, 5791,
6416, 7018, 7097, 7104, 7554, 7626, 7142, 6796, 6000, 4412,
2701, 1023, -1208, -3576, -5245, -6797, -8360, -9147, -9058, -8905,
-8516, -7509, -6292, -5407, -4193, -2338, -203, 1904, 3856, 5452,
6611, 7060, 7354, 7534, 7469, 7186, 6811, 6304, 5564, 4431,
3074, 1740, 13, -1949, -3665, -5439, -7303, -8342, -8801, -9191,
-8756, -7433, -6562, -5919, -4378, -2569, -1418, 122, 2680, 4648,
5269, 6141, 7250, 7469, 7523, 8127, 7836, 6765, 6227, 5646,
3954, 2196, 779, -1198, -3524, -5194, -6574, -8287, -9386, -9394,
-9169, -8761, -7510, -6218, -5268, -3717, -1490, 478, 2199, 4377,
6152, 6853, 7398, 7991, 7817, 7290, 7481, 7346, 6083, 5100,
4604, 2978, 816, -530, -1812, -4104, -6062, -7103, -8421, -9667,
-9441, -8554, -8167, -7375, -5634, -4275, -3306, -1312, 1229, 3064,
4704, 6452, 7462, 7489, 7633, 7913, 7600, 7192, 7086, 6460,
5187, 4134, 2963, 978, -1387, -3095, -4915, -7193, -8872, -9352,
-9579, -9500, -8588, -7252, -6501, -5262, -3588, -1759,
// Loop Samples:
210, 2125,
4206, 5781, 6747, 7399, 7717, 7732, 7615, 7590, 7138, 6312,
5399, 4406, 2932, 1339, -196, -2176, -4336, -6138, -7518, -8674,
-9458, -9363, -8752, -7970, -6803, -5288, -4028, -2848, -971, 1154,
2907, 4646, 6358, 7170, 7431, 7840, 7918, 7415, 7188, 7088,
6257, 4906, 3705, 2251, 192, -1843, -3583, -5326, -7006, -8167,
-8875, -9230, -8796, -7926, -6993, -5973, -4597, -3232, -2040, -277,
1973, 3673, 4961, 6317, 7156, 7393, 7578, 7695, 7472, 7168,
6774, 5911, 4768, 3559, 1911, 65, -1741, -3797, -5842, -7372,
-8701, -9725, -9749, -8991, -8346, -7522, -6089, -4758, -3548, -1558,
766, 2646, 4347, 6144, 7329, 7628, 8174, 8751, 8459, 7859,
7737, 7165, 5514, 3956, 2706, 650, -1792, -3375, -4931, -7157,
-8563, -8780, -9319, -9884, -8838, -7411, -6981, -5951, -3715, -2143,
-861, 1573, 3987, 5070, 6071, 7679, 8203, 7760, 8042, 8414,
7477, 6454, 5972, 4716, 2978, 1745, 369, -1641, -3538, -5088,
-6799, -8449, -9335, -9357, -9119, -8680, -7502, -6050, -4936, -3642,
-1805, -104, 1645, 3724, 5608, 6700, 7495, 8402, 8860, 8353,
7754, 7594, 6907, 5408, 4475, 3483, 1213, -1003, -2476, -4635,
-7330, -8486, -8774, -9701,-10004, -8459, -7179, -7056, -6020, -3894,
-2573, -1173, 1428, 3776, 4776, 6052, 7698, 8025, 7471, 8081,
8747, 7691, 6550, 6575, 5748, 3582, 2090, 984, -1473, -4165,
-5435, -7010, -9407,-10202, -9342, -9458, -9519, -7591, -5808, -5566,
-4169, -1302, 504, 1908, 4593, 6613, 6747, 7248, 8729, 8833,
7857, 7870, 8116, 6906, 5339, 4602, 3229, 808, -1061, -2477,
-4745, -6885, -7833, -8704, -9976, -9865, -8464, -7846, -7475, -5840,
-4231, -3305, -1451, 1231, 3178, 4608, 6317, 7367, 7464, 7913,
8501, 8151, 7378, 7201, 6785, 5384, 3913, 2746, 869, -1505,
-3290, -4892, -7024, -8644, -9021, -9201, -9407, -8584, -7215, -6587,
-5889, -4158, -2248, -661, 1386, 3825, 5427, 6280, 7393, 8209,
8140, 8126, 8486, 7998, 6922, 6291, 5329, 3325, 1322, -166,
-2311, -4780, -6330, -7451, -8871, -9713, -9273, -8709, -8515, -7581,
-6027, -4963, -3802, -1535, 925, 2655, 4502, 6543, 7518, 7638,
8286, 8877, 8447, 8009, 8077, 7325, 5698, 4349, 2871, 476,
-1881, -3560, -5420, -7659, -9053, -9383, -9828,-10079, -9139, -7866,
-7211, -6025, -3796, -1974, -466, 2088, 4569, 5666, 6657, 8094,
8555, 8235, 8729, 9121, 8139, 6991, 6371, 4920, 2777, 1206,
-272, -2584, -4804, -6118, -7560, -9218, -9816, -9553, -9508, -9101,
-7680, -6236, -5358, -3735, -1298, 726, 2494, 4696, 6514, 7419,
8080, 8792, 8950, 8704, 8630, 8237, 6921, 5324, 4093, 2593,
466, -1576, -3291, -5191, -6981, -8300, -9325, -9967, -9819, -9147,
-8293, -7188, -5736, -4245, -2734, -892, 1396, 3498, 5189, 6627,
7778, 8454, 8800, 8803, 8530, 8078, 7415, 6323, 4967, 3499,
1797, -17, -1876, -4087, -6187, -7605, -8684, -9554, -9816, -9185,
-8265, -7320, -6258, -4967, -3480, -1699, 218, 2172, 3987, 5614,
6852, 7601, 7892, 8218, 8446, 8100, 7312, 6623, 5738, 4342,
2786, 1369, -397, -2610, -4462, -5920, -7692, -9136, -9398, -9330,
-8986, -8019, -6868, -5983, -4467, -2578, -1031, 705, 2916, 4426,
5514, 6983, 8075, 8159, 8333, 8578, 8121, 7243, 6541, 5425,
3709, 2328, 1041, -1249, -3791, -5410, -7024, -8895, -9747, -9539,
-9512, -9056, -7596, -6346, -5686, -4145, -1797, 111, 1820, 4183,
6067, 6843, 7445, 8272, 8309, 7860, 7956, 7892, 6882, 5740,
4855, 3401, 1468, -257, -2103, -4386, -6454, -7942, -9125, -9897,
-9668, -8949, -8218, -7304, -5857, -4482, -3074, -1103,};
const uint16_t WaveTable_Celesta_C6_Increment[]={
1, 2, 2, 2, 2, 2, 2, 2, 3, 3,
3, 3, 3, 4, 4, 4, 5, 5, 5, 5,
6, 6, 7, 7, 7, 8, 8, 9, 10, 10,
11, 11, 12, 13, 14, 15, 15, 16, 17, 18,
20, 21, 22, 23, 25, 26, 28, 30, 31, 33,
35, 37, 40, 42, 45, 47, 50, 53, 56, 60,
63, 67, 71, 75, 80, 85, 90, 95, 101, 107,
113, 120, 127, 135, 143, 151, 160, 170, 180, 190,
202, 214, 227, 240, 254, 270, 286, 303, 321, 340,
360, 381, 404, 428, 454, 481, 509, 540, 572, 606,
642, 680, 721, 763, 809, 857, 908, 962, 1019, 1080,
1144, 1212, 1284, 1361, 1442, 1527, 1618, 1714, 1816, 1924,
2039, 2160, 2289, 2425, 2569, 2722, 2884, 3055,};
@@ -0,0 +1,19 @@
#ifndef __WAVETABLE_CELESTA_C6__
#define __WAVETABLE_CELESTA_C6__
// Sample's base frequency: 1046.832025 Hz
// Sample's sample rate: 32000 Hz
#define WAVETABLE_CELESTA_C6_LEN 1358
#define WAVETABLE_CELESTA_C6_ATTACK_LEN 838
#define WAVETABLE_CELESTA_C6_LOOP_LEN 520
#ifndef __ASSEMBLER__
#include <stdint.h>
extern const int16_t WaveTable_Celesta_C6[WAVETABLE_CELESTA_C6_LEN];
extern const uint16_t WaveTable_Celesta_C6_Increment[];
#else
.extern WaveTable_Celesta_C6
.extern WaveTable_Celesta_C6_Increment
#endif
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

+118
View File
@@ -0,0 +1,118 @@
import serial
import os
import math
import argparse
import struct
from time import sleep
import serial.tools.list_ports
BLOCK_SIZE = 512 # 128 for parts with >8k flash
def autoFindPort():
portList = serial.tools.list_ports.comports()
pid = "7523"
vid = "1A86"
port = None
for p in portList:
if pid and vid in p.hwid:
port = p.device
return port
def sendCmdPacket(ser, cmd, cmdData=b''):
frameLen = 1+len(cmdData)
frameBytes = struct.pack('<HHB%ds' % len(
cmdData), 0x776e, frameLen, cmd, cmdData)
ser.write(frameBytes)
ser.flush()
def recvCmdReply(ser, cmd):
frameHeader = ser.read(4)
if len(frameHeader) != 4:
print('Invalid ACK Len!')
return b''
else:
frameId, frameLen = struct.unpack('<HH', frameHeader)
if frameId != 0x776E:
print('Invalid Frame ID!')
return b''
frameData = ser.read(frameLen)
cmdReply, cmdReplyData = struct.unpack('<B%ds' % (frameLen-1), frameData)
if cmdReply != cmd:
return b''
return cmdReplyData
def readFlashSize(ser):
sendCmdPacket(ser, 0x04)
replyData = recvCmdReply(ser, 0x04)
if replyData != b'':
return struct.unpack('<I', replyData)[0]
else:
return 0
def startFlash(ser):
sendCmdPacket(ser, 0x01)
replyData = recvCmdReply(ser, 0x01)
if replyData == b'':
return True
else:
return False
def endFlash(ser):
sendCmdPacket(ser, 0x03)
replyData = recvCmdReply(ser, 0x03)
if replyData == b'':
return True
else:
return False
def bootloader_exec(port, baud):
ser = serial.Serial(port, baud, timeout=2.0)
startFlash(ser)
flashSize = readFlashSize(ser)
print('Flash size: ', flashSize)
data = open(FILE, 'rb')
total = 0
with data as f:
flash_cmd = 0x02
chunkIndex = 0
chunk = bytearray(f.read(BLOCK_SIZE))
while chunk:
total += len(chunk)
if total > flashSize:
print('Exceed flash size!!')
break
print('Written: ', total)
cmdData = bytearray(struct.pack('<HH', chunkIndex, len(chunk)))
cmdData.extend(chunk)
sendCmdPacket(ser, flash_cmd, cmdData)
replyData = recvCmdReply(ser, flash_cmd)
recvChunkIndex, recvChunkLen = struct.unpack('<HH', replyData)
if recvChunkIndex != chunkIndex or recvChunkLen != len(chunk):
print('Wrong ACK!')
break
chunkIndex += 1
chunk = bytearray(f.read(BLOCK_SIZE))
endFlash(ser)
ser.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='music box score data downloader')
port = autoFindPort()
if port == None:
port = 'COM6'
parser.add_argument('--port', '-p', default=port)
parser.add_argument('--baud', '-b', default=115200)
parser.add_argument('file', help='firmware in binary format')
args = parser.parse_args()
FILE = args.file
print('Serial Port: ',port)
bootloader_exec(args.port, args.baud)
@@ -0,0 +1,117 @@
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#include "common.h"
#include "uart.h"
#undef errno
extern int errno;
#define OUTPUT_PRINTF 0
/******************************************************************************
*
******************************************************************************/
void stdio_setup(void)
{
#if OUTPUT_PRINTF
// Turn off buffers, so I/O occurs immediately
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
#endif
}
/******************************************************************************
*
******************************************************************************/
int _read(int file, char *data, int len)
{
int bytes_read = 0;
#if OUTPUT_PRINTF
if (file != STDIN_FILENO)
{
errno = EBADF;
return -1;
}
for (bytes_read = 0; bytes_read < len; bytes_read++)
{
*data = (char)UART_GetChar(TERM_PORT);
data++;
}
#endif
return bytes_read;
}
/******************************************************************************
*
******************************************************************************/
int _write(int file, char *data, int len)
{
int bytes_written = 0;
#if OUTPUT_PRINTF
if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
{
errno = EBADF;
return -1;
}
for (bytes_written = 0; bytes_written < len; bytes_written++)
{
UART_PutChar(TERM_PORT, *data);
data++;
}
#endif
return bytes_written;
}
/******************************************************************************
*
******************************************************************************/
int _close(int file)
{
return -1;
}
/******************************************************************************
*
******************************************************************************/
int _lseek(int file, int ptr, int dir)
{
return 0;
}
/******************************************************************************
*
******************************************************************************/
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
/******************************************************************************
*
******************************************************************************/
int _isatty(int file)
{
if ((file == STDOUT_FILENO) ||
(file == STDIN_FILENO) ||
(file == STDERR_FILENO))
{
return 1;
}
errno = EBADF;
return 0;
}
+59
View File
@@ -0,0 +1,59 @@
/******************************************************************************
*
* @brief define interrupt service routines referenced by the vector table.
*
* Note: Only "vectors.c" should include this header file.
*
*******************************************************************************
******************************************************************************/
#ifndef __ISR_H
#define __ISR_H
/* Example */
/*
#undef VECTOR_036
#define VECTOR_036 RTC_Isr
// ISR(s) are defined in your project directory.
extern void RTC_Isr(void);
*/
/*!
* @brief define interrupt service routine for different vectors.
*
*
*
*
*/
#undef VECTOR_038
#define VECTOR_038 PIT_Ch0Isr_Override /*!< Vector 38 points to PIT channel 0 interrupt service routine */
#undef VECTOR_039
#define VECTOR_039 PIT_Ch1Isr /*!< Vector 39 points to PIT channel 1 interrupt service routine */
extern void PIT_Ch1Isr(void);
extern void PIT_Ch0Isr_Override(void);
#undef VECTOR_036
#define VECTOR_036 RTC_Isr /*!< Vector 36 points to RTC interrupt service routine */
extern void RTC_Isr(void);
#undef VECTOR_015
#define VECTOR_015 SysTick_Isr /*!< Vector 15 points to SysTick interrupt service routine */
extern void SysTick_Isr(void);
#undef VECTOR_028
#define VECTOR_028 UART0_Isr
extern void UART0_Isr(void);
#endif //__ISR_H
/* End of "isr.h" */
+208
View File
@@ -0,0 +1,208 @@
#include "common.h"
#include "rtc.h"
#include "flash.h"
#include "sysinit.h"
#include "etm.h"
#include "eeprom.h"
#include "pit.h"
#include "sim.h"
#include "gpio.h"
#include "adc.h"
#include "pmc.h"
#include "Player.h"
#include "SynthCore.h"
#include "NV32.h"
#include "systick.h"
#include "KeyScan.h"
#include "DownloadScoreData.h"
#include <stdlib.h>
#include "PeriodTimer.h"
Player mPlayer;
int main(void);
void TestInit(void);
void TestSynth(void);
void ConfigPIT(void)
{
PIT_ConfigType sPITConfig0;
PIT_ConfigType *pPIT_Config0 = &sPITConfig0;
/* PIT时钟源为总线时钟 */
/* 通道0装载值为 = (1000000-1),通道1装载值为 = (40-1) */
/* 配置通道0, 仅仅使能 */
pPIT_Config0->u32LoadValue = 1249;
pPIT_Config0->bFreeze = FALSE; //定时器在调试模式下继续运行
pPIT_Config0->bModuleDis = FALSE; //使能定时器模块
pPIT_Config0->bInterruptEn = TRUE;
pPIT_Config0->bChainMode = FALSE;
pPIT_Config0->bETMerEn = TRUE; //定时器使能
PIT_Init(PIT_CHANNEL0, pPIT_Config0); //初始化PIT模块通道0
// PIT_SetCallback(PIT_CHANNEL0, PIT_Task); //设置通道1中断回调函数
}
void ConfigADC(void)
{
ADC_ConfigType sADC_Config = {0};
/*初始化ADC模块*/
sADC_Config.u8ClockDiv = ADC_ADIV_DIVIDE_8; /*!< ADC时钟源分频系数为8*/
sADC_Config.u8ClockSource = CLOCK_SOURCE_BUS_CLOCK; /*!< ADC时钟源选择总线时钟*/
sADC_Config.u8Mode = ADC_MODE_12BIT; /*!< 12位转换*/
ADC_Init(ADC, &sADC_Config); /*!< 初始化ADC模块*/
}
uint32_t GetVolt(void)
{
uint32_t voltChn = ADC_PollRead(ADC, ADC_CHANNEL_AD3);
return voltChn;
}
uint32_t GetVolume(void)
{
uint32_t volChn1 = ADC_PollRead(ADC, ADC_CHANNEL_AD2);
return volChn1 >> 4;
}
void ETM0Config(void)
{
SIM->SCGC |= SIM_SCGC_ETM0_MASK; //使能ETM2时钟
ETM0->CONTROLS[0].CnSC = ETM_CnSC_ELSA_MASK | (1 << ETM_CnSC_MSB_SHIFT); //低真脉冲
ETM_ClockSet(ETM0, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1); //ETM2时钟设置
ETM0->MOD = 0xFFFF;
ETM0->CONTROLS[0].CnV = 0xFFFF;
}
void ETM2Config(void)
{
SIM->SCGC |= SIM_SCGC_ETM2_MASK; //使能ETM2时钟
ETM2->COMBINE &= ~ETM_COMBINE_COMBINE2_MASK; //通道0和通道1独立
ETM2->SC |= ETM_SC_CPWMS_MASK; //选择先增后减的计数方式
ETM2->COMBINE |= ETM_COMBINE_COMP2_MASK; //通道0和通道1的输出互补
ETM2->CONTROLS[4].CnSC = ETM_CnSC_ELSA_MASK; //低真脉冲
ETM2->CONTROLS[5].CnSC = ETM_CnSC_ELSA_MASK;
ETM_ClockSet(ETM2, ETM_CLOCK_SYSTEMCLOCK, ETM_CLOCK_PS_DIV1); //ETM2时钟设置
ETM_SetModValue(ETM2, 255);
}
uint32_t GlobalMills = 0;
void SysTick_CallBack(void)
{
GlobalMills++;
}
void SysTickConfig(void)
{
SysTick_SetCallBack(SysTick_CallBack);
SysTick->CTRL = 0;
SysTick->LOAD = (BUS_CLK_HZ) / 1000 - 1; //配置定时中断时间为1MS
SysTick->VAL = 0;
NVIC_SetPriority(SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; //开中断开定时器
}
/********************************************************************/
void KeyNextCallBack(uint32_t param)
{
PlaySchedulerNextScore(&mPlayer);
}
void KeyPreviousCallBack(uint32_t param)
{
PlaySchedulerPreviousScore(&mPlayer);
}
void VisualIndicatorPrcoess(Player *player)
{
ETM0->CONTROLS[0].CnV = abs(player->synthesizer.mixOut) >> 8;
}
void VolumeProcess(Player *player)
{
player->synthesizer.mainVolume = GetVolume();
}
void SynthHwOnOff(SYNTH_HW_STATUS status)
{
static SYNTH_HW_STATUS lastStatus = SYNTH_HW_OFF;
DisableInterrupts;
if (status == SYNTH_HW_ON)
{
if (lastStatus != SYNTH_HW_ON)
{
lastStatus = SYNTH_HW_ON;
ConfigPIT();
ETM2Config();
}
}
else
{
if (lastStatus != SYNTH_HW_OFF)
{
lastStatus = SYNTH_HW_OFF;
PIT_DeInit();
ETM_DeInit(ETM2);
}
}
EnableInterrupts;
}
uint8_t GetRandom(void)
{
uint8_t random = 0;
for (int i = 0; i < 3; i++)
{
random |= ((ADC_PollRead(ADC, ADC_CHANNEL_AD5) & 0x07) << (i * 3));
}
return random;
}
int main(void)
{
PMC_DisableLVD(PMC);
sysinit();
GPIO_Init(GPIOA, GPIO_PTB1_MASK, GPIO_PinInput);
GPIO_Init(GPIOA, GPIO_PTA6_MASK, GPIO_PinInput);
GPIO_Init(GPIOA, GPIO_PTA7_MASK, GPIO_PinInput);
GPIO_Init(GPIOA, GPIO_PTA0_MASK, GPIO_PinInput_InternalPullup);
GPIO_Init(GPIOA, GPIO_PTA1_MASK, GPIO_PinInput_InternalPullup);
GPIO_Init(GPIOA, GPIO_PTA2_MASK, GPIO_PinInput);
SIM_RemapETM0CH0Pin();
(*((uint32_t *)0x4004900C)) = PORT_HDRVE_PTB4_MASK | PORT_HDRVE_PTB5_MASK | PORT_HDRVE_PTH1_MASK | PORT_HDRVE_PTH0_MASK;
PlayerInit(&mPlayer);
SynthRegisterHwChangeFunc(&mPlayer.synthesizer, SynthHwOnOff);
KeyScanInit();
DownloadInit();
ConfigADC();
ETM0Config();
SysTickConfig();
KeySetCallBack(USER_KEY_2, KeyNextCallBack);
KeySetCallBack(USER_KEY_1, KeyPreviousCallBack);
StartPlayScheduler(&mPlayer);
SchedulerSetIntialRandomSeed(&mPlayer, GetRandom());
srand(GetRandom());
while (1)
{
VolumeProcess(&mPlayer);
PlayerProcess(&mPlayer);
KeyProcess(GlobalMills);
KeyRawInput(USER_KEY_2, GPIO_BitRead(GPIO_PTA0));
KeyRawInput(USER_KEY_1, GPIO_BitRead(GPIO_PTA1));
VisualIndicatorPrcoess(&mPlayer);
DownloadProcess();
}
}
@@ -0,0 +1,74 @@
# STD Defines
DDEFS += -DNV32
# source director
NV32_DRIVER_LIB = $(NV32_LIB_DIR)/drivers
NV32_CPU_LIB = $(NV32_LIB_DIR)/cpu
NV32_COMMON_DIR = $(NV32_LIB_DIR)/common
NV32_PLATFORM_DIR = $(NV32_LIB_DIR)/platforms
# startup
ASM_SRC += $(NV32_CPU_LIB)/startup_NV32_gcc.s
# use libraries, please add or remove when you use or remove it.
# SRC += $(NV32_COMMON_DIR)/alloc.c
SRC += $(NV32_COMMON_DIR)/assert.c
# SRC += $(NV32_COMMON_DIR)/io.c
# SRC += $(NV32_COMMON_DIR)/memtest.c
# SRC += $(NV32_COMMON_DIR)/queue.c
# SRC += $(NV32_COMMON_DIR)/memtest.c
# SRC += $(NV32_COMMON_DIR)/stdlib.c
SRC += $(NV32_CPU_LIB)/arm_cm0.c
SRC += $(NV32_CPU_LIB)/start.c
SRC += $(NV32_CPU_LIB)/sysinit.c
SRC += $(NV32_CPU_LIB)/vectors.c
SRC += $(NV32_CPU_LIB)/systick.c
# SRC += $(NV32_DRIVER_LIB)/acmp/acmp.c
SRC += $(NV32_DRIVER_LIB)/adc/adc.c
# SRC += $(NV32_DRIVER_LIB)/crc/crc.c
SRC += $(NV32_DRIVER_LIB)/gpio/gpio.c
SRC += $(NV32_DRIVER_LIB)/ics/ics.c
# SRC += $(NV32_DRIVER_LIB)/iic/i2c.c
# SRC += $(NV32_DRIVER_LIB)/kbi/kbi.c
SRC += $(NV32_DRIVER_LIB)/nvm/flash.c
SRC += $(NV32_DRIVER_LIB)/eeprom/eeprom.c
SRC += $(NV32_DRIVER_LIB)/pit/pit.c
SRC += $(NV32_DRIVER_LIB)/PMC/pmc.c
SRC += $(NV32_DRIVER_LIB)/rtc/rtc.c
SRC += $(NV32_DRIVER_LIB)/sim/sim.c
# SRC += $(NV32_DRIVER_LIB)/spi/spi.c
SRC += $(NV32_DRIVER_LIB)/uart/uart.c
SRC += $(NV32_DRIVER_LIB)/etm/etm.c
SRC += $(NV32_DRIVER_LIB)/delay/delay.c
SRC += $(NV32_DRIVER_LIB)/wdog/wdog.c
# include directories
INCLUDE_DIRS += $(NV32_COMMON_DIR)
INCLUDE_DIRS += $(NV32_CPU_LIB)
INCLUDE_DIRS += $(NV32_CPU_LIB)/headers
INCLUDE_DIRS += $(NV32_PLATFORM_DIR)
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/acmp
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/adc
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/crc
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/gpio
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/ics
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/iic
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/kbi
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/eeprom
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/nvm
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/pit
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/PMC
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/rtc
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/sim
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/spi
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/uart
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/etm
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/delay
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/wdog
INCLUDE_DIRS += $(NV32_DRIVER_LIB)/bos
+190
View File
@@ -0,0 +1,190 @@
/*
* GCC linker script for STM32 microcontrollers (ARM Cortex-M).
*
* It exports the symbols needed for the CMSIS assembler startup script for GCC
* ARM toolchains (_sidata, _sdata, _edata, _sbss, _ebss) and sets the entry
* point to Reset_Handler.
*
* Adapt FLASH/RAM size for your particular device below.
*
* @author Bjørn Forsman
*/
MEMORY
{
vectors (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400
flash_protection (rx) : ORIGIN = 0x00000400, LENGTH = 0x00000010
flash (rx) : ORIGIN = 0x00000410, LENGTH = 24K - 0x00000410
flash_score_data (rx) : ORIGIN = 24K, LENGTH = 128K-24K
ram (rwx) : ORIGIN = 0x1FFFF800, LENGTH = 8K
}
__SCORE_DATA_FLASH_SIZE__ = LENGTH(flash_score_data);
ENTRY(Reset_Handler)
/*
* Reserve memory for heap and stack. The linker will issue an error if there
* is not enough memory.
*
* NOTE: The reserved heap and stack will be added to the bss column of the
* binutils size command.
*/
_heap_size = 1024; /* required amount of heap */
_stack_size = 2048; /* required amount of stack */
/*
* The stack starts at the end of RAM and grows downwards. Full-descending
* stack; decrement first, then store.
*/
_estack = ORIGIN(ram) + LENGTH(ram);
SECTIONS
{
/* Reset and ISR vectors */
.isr_vector :
{
__isr_vector_start__ = .;
KEEP(*(.isr_vector)) /* without 'KEEP' the garbage collector discards this section */
ASSERT(. != __isr_vector_start__, "The .isr_vector section is empty");
} >vectors
.flash_protect :
{
KEEP(*(.nv32_flash_config_field))
. = ALIGN(4);
} > flash_protection
/* Text section (code and read-only data) */
.text :
{
. = ALIGN(4);
_stext = .;
*(.text*) /* code */
*(.rodata*) /* read only data */
/*
* NOTE: .glue_7 and .glue_7t sections are not needed because Cortex-M
* only supports Thumb instructions, no ARM/Thumb interworking.
*/
/* Static constructors and destructors */
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
_etext = .;
} >flash
/*
* Stack unwinding and exception handling sections.
*
* ARM compilers emit object files with .ARM.extab and .ARM.exidx sections
* when using C++ exceptions. Also, at least GCC emits those sections when
* dividing large numbers (64-bit) in C. So we have to handle them.
*
* (ARM uses .ARM.extab and .ARM.exidx instead of the .eh_frame section
* used on x86.)
*/
.ARM.extab : /* exception unwinding information */
{
*(.ARM.extab*)
} >flash
.ARM.exidx : /* index entries for section unwinding */
{
*(.ARM.exidx*)
} >flash
/*
* Newlib and Eglibc (at least) need these for C++ support.
*
* (Copied from Sourcery CodeBench Lite: arm-none-eabi-gcc -V)
*/
.preinit_array :
{
PROVIDE_HIDDEN(__preinit_array_start = .);
KEEP(*(.preinit_array*))
PROVIDE_HIDDEN(__preinit_array_end = .);
} >flash
.init_array :
{
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array*))
PROVIDE_HIDDEN(__init_array_end = .);
} >flash
.fini_array :
{
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array*))
PROVIDE_HIDDEN(__fini_array_end = .);
} >flash
/*
* Initialized data section. This section is programmed into FLASH (LMA
* address) and copied to RAM (VMA address) in startup code.
*/
_sidata = .;
PROVIDE ( ScoreDataList = __ScoreDataList__ );
.SCORE_DATA :
{
. = ALIGN (4);
__ScoreDataList__ = .; /* symbol available within program */
scoreList.o
} > flash_score_data /* MEMORY section defined somewhere above */
.data : AT(_sidata) /* LMA address is _sidata (in FLASH) */
{
. = ALIGN(4);
_sdata = .; /* data section VMA address */
*(.data*)
. = ALIGN(4);
*(.ramfunctions) /* !!!! Placing functions in .ramfunctions section in RAM */
. = ALIGN(4);
_edata = .;
} >ram
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* Uninitialized data section (zeroed out by startup code) */
.bss :
{
. = ALIGN(4);
_sbss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >ram
/*
* Reserve memory for heap and stack. The linker will issue an error if
* there is not enough memory.
*/
._heap :
{
. = ALIGN(4);
. = . + _heap_size;
. = ALIGN(4);
} >ram
._stack :
{
. = ALIGN(4);
. = . + _stack_size;
. = ALIGN(4);
} >ram
}
/* Nice to have */
__isr_vector_size__ = SIZEOF(.isr_vector);
__text_size__ = SIZEOF(.text);
__data_size__ = SIZEOF(.data);
__bss_size__ = SIZEOF(.bss);
@@ -0,0 +1,131 @@
/******************************************************************************
*
* @brief providing generic malloc() and free() engine.
*
*******************************************************************************/
#include "common.h"
#include "stdlib.h"
#ifndef __CC_ARM
#pragma section = "HEAP"
#endif
/********************************************************************/
/*
* This struct forms the minimum block size which is allocated, and
* also forms the linked list for the memory space used with alloc()
* and free(). It is padded so that on a 32-bit machine, all malloc'ed
* pointers are 16-byte aligned.
*/
typedef struct ALLOC_HDR
{
struct
{
struct ALLOC_HDR *ptr;
unsigned int size;
} s;
unsigned int align;
unsigned int pad;
} ALLOC_HDR;
static ALLOC_HDR base;
static ALLOC_HDR *freep = NULL;
/********************************************************************/
void
free (void *ap)
{
ALLOC_HDR *bp, *p;
bp = (ALLOC_HDR *)ap - 1; /* point to block header */
for (p = freep; !((bp > p) && (bp < p->s.ptr)) ; p = p->s.ptr)
{
if ((p >= p->s.ptr) && ((bp > p) || (bp < p->s.ptr)))
{
break; /* freed block at start or end of arena */
}
}
if ((bp + bp->s.size) == p->s.ptr)
{
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
}
else
{
bp->s.ptr = p->s.ptr;
}
if ((p + p->s.size) == bp)
{
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
}
else
{
p->s.ptr = bp;
}
freep = p;
}
/********************************************************************/
void *
malloc (unsigned nbytes)
{
/* Get addresses for the HEAP start and end */
#if defined(CW)
extern char __HEAP_START[];
extern char __HEAP_END[];
#elif defined(IAR)
char* __HEAP_START = __section_begin("HEAP");
char* __HEAP_END = __section_end("HEAP");
#elif defined(KEIL)
extern uint32_t HEAP$$Base;
extern uint32_t HEAP$$Limit;
uint32_t __HEAP_START = (uint32_t)&HEAP$$Base;
uint32_t __HEAP_END = (uint32_t)&HEAP$$Limit;
#endif
ALLOC_HDR *p, *prevp;
unsigned nunits;
nunits = ((nbytes+sizeof(ALLOC_HDR)-1) / sizeof(ALLOC_HDR)) + 1;
if ((prevp = freep) == NULL)
{
p = (ALLOC_HDR *)__HEAP_START;
p->s.size = ( ((uint32)__HEAP_END - (uint32)__HEAP_START)
/ sizeof(ALLOC_HDR) );
p->s.ptr = &base;
base.s.ptr = p;
base.s.size = 0;
prevp = freep = &base;
}
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr)
{
if (p->s.size >= nunits)
{
if (p->s.size == nunits)
{
prevp->s.ptr = p->s.ptr;
}
else
{
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *)(p + 1);
}
if (p == freep)
return NULL;
}
}
/********************************************************************/
@@ -0,0 +1,28 @@
/******************************************************************************
*
* @brief provide macro for software assertions.
*
* ASSERT macro defined in assert.h calls assert_failed().
*******************************************************************************/
#include "common.h"
const char ASSERT_FAILED_STR[] = "Assertion failed in %s at line %d\n";
/********************************************************************/
void
assert_failed(char *file, int line)
{
int i;
printf(ASSERT_FAILED_STR, file, line);
while (1)
{
// platform_led_display(0xFF);
for (i = 100000; i; i--) ;
// platform_led_display(0x00);
for (i = 100000; i; i--) ;
}
}
/********************************************************************/
@@ -0,0 +1,25 @@
/******************************************************************************
*
* @brief provide macro for software assertions.
*
* assert_failed() defined in assert.c.
*******************************************************************************/
#ifndef _ASSERT_H_
#define _ASSERT_H_
/********************************************************************/
void assert_failed(char *, int);
#ifdef DEBUG_PRINT
#define ASSERT(expr) \
if (!(expr)) \
assert_failed(__FILE__, __LINE__)
#else
#define ASSERT(expr)
#endif
/********************************************************************/
#endif /* _ASSERT_H_ */
@@ -0,0 +1,90 @@
/******************************************************************************
*
* @brief provide header files to be included by all project files.
*
*******************************************************************************/
#ifndef _COMMON_H_
#define _COMMON_H_
#define swap_bytes(ptrWord) *ptrWord = (*ptrWord >>8) | (*ptrWord<<8)
typedef unsigned long dword;
typedef unsigned short word;
/********************************************************************/
/*
* Debug prints ON (#define) or OFF (#undef)
*/
#define DEBUG
#define DEBUG_PRINT
/*
* Include the generic CPU header file
*/
#include "arm_cm0.h"
/*
* Include the platform specific header file
*/
#if (defined(NV32))
#include "NV32_config.h"
#elif (defined(FRDM_NV32M3))
#include "NV32M3_config.h"
#elif (defined(FRDM_NV32M4))
#include "NV32M4_config.h"
#else
#error "No valid board defined"
#endif
/*
* Include the cpu specific header file
*/
#if (defined(CPU_NV32))
#include "NV32.h"
#elif (defined(CPU_NV32M3))
#include "NV32M3.h"
#elif (defined(CPU_NV32M4))
#include "NV32M4.h"
#else
#error "No valid CPU defined"
#endif
/*
* Include any toolchain specfic header files
*/
#if (defined(__MWERKS__))
#include "mwerks.h"
#elif (defined(__DCC__))
#include "build/wrs/diab.h"
#elif (defined(__ghs__))
#include "build/ghs/ghs.h"
#elif (defined(__GNUC__))
#if (defined(IAR))
#include "build/gnu/gnu.h"
#endif
#elif (defined(IAR))
#include "iar.h"
#elif (defined(KEIL))
#else
#warning "No toolchain specific header included"
#endif
/*
* Include common utilities
*/
#include "assert.h"
#include "io.h"
#include "startup.h"
#include "stdlib.h"
#if (defined(IAR))
#include "intrinsics.h"
#endif
/********************************************************************/
#endif /* _COMMON_H_ */
@@ -0,0 +1,822 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V4.00
* @date 22. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_H_GENERIC
#ifdef __cplusplus
extern "C" {
#endif
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex-M0+
@{
*/
/* CMSIS CM0P definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
__CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */
#define __STATIC_INLINE static inline
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI__VFP_SUPPORT____
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ ) /* Cosmic */
#if ( __CSMC__ & 0x400) // FPU present for parser
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*@} end of group Cortex-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1)
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 8 /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1)
/** \ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/** \brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register */
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register */
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register */
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register */
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
The function disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
The function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
The function sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
The function clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority. Value is aligned automatically to the implemented
priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
@@ -0,0 +1,637 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.00
* @date 28. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#endif
}
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */
@@ -0,0 +1,880 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.00
* @date 28. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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 __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
/** \brief Rotate Right with Extend (32 bit)
This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/** \brief LDRT Unprivileged (8 bit)
This function executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/** \brief LDRT Unprivileged (16 bit)
This function executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/** \brief LDRT Unprivileged (32 bit)
This function executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/** \brief STRT Unprivileged (8 bit)
This function executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/** \brief STRT Unprivileged (16 bit)
This function executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/** \brief STRT Unprivileged (32 bit)
This function executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (16 bit)
This function executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (32 bit)
This function executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint32_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief Rotate Right with Extend (32 bit)
This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief LDRT Unprivileged (8 bit)
This function executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDRT Unprivileged (16 bit)
This function executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDRT Unprivileged (32 bit)
This function executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STRT Unprivileged (8 bit)
This function executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
{
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
}
/** \brief STRT Unprivileged (16 bit)
This function executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
{
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
}
/** \brief STRT Unprivileged (32 bit)
This function executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
{
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
}
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */
@@ -0,0 +1,697 @@
/**************************************************************************//**
* @file core_cmSimd.h
* @brief CMSIS Cortex-M SIMD Header File
* @version V4.00
* @date 22. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32) ) >> 32))
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
{
int32_t result;
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/* not yet supported */
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CMSIMD_H */
@@ -0,0 +1,39 @@
/******************************************************************************
*
* @brief provide serial Input/Output routines.
*
*******************************************************************************/
#include "common.h"
#include "uart.h"
#include "stdio.h"
//********************************************************************/
char
in_char (void)
{
return UART_GetChar(TERM_PORT);
}
/********************************************************************/
void
out_char (char ch)
{
UART_PutChar(TERM_PORT, ch);
}
/********************************************************************/
int
char_present (void)
{
return UART_CharPresent(TERM_PORT);
}
#ifdef KEIL
/********************************************************************/
int fputc(int ch, FILE *f)
{
out_char((char)ch);
return 1;
}
#endif
/********************************************************************/
@@ -0,0 +1,30 @@
/******************************************************************************
*
* @brief provide serial Input/Output routines.
*
*******************************************************************************/
#ifndef _IO_H
#define _IO_H
/********************************************************************/
char
in_char(void);
void
out_char(char);
int
char_present(void);
int
printf(const char *, ... );
int
sprintf(char *, const char *, ... );
/********************************************************************/
#endif
@@ -0,0 +1,211 @@
/******************************************************************************
*
* @brief provide general-purpose memory testing functions.
*
*******************************************************************************/
#include "memtest.h"
/**********************************************************************
*
* Function: memTestDataBus()
*
* Description: Test the data bus wiring in a memory region by
* performing a walking 1's test at a fixed address
* within that region. The address (and hence the
* memory region) is selected by the caller.
*
* Notes:
*
* Returns: 0 if the test succeeds.
* A non-zero result is the first pattern that failed.
*
**********************************************************************/
datum
memTestDataBus(volatile datum * address)
{
datum pattern;
/*
* Perform a walking 1's test at the given address.
*/
for (pattern = 1; pattern != 0; pattern <<= 1)
{
/*
* Write the test pattern.
*/
*address = pattern;
/*
* Read it back (immediately is okay for this test).
*/
if (*address != pattern)
{
return (pattern);
}
}
return (0);
} /* memTestDataBus() */
/**********************************************************************
*
* Function: memTestAddressBus()
*
* Description: Test the address bus wiring in a memory region by
* performing a walking 1's test on the relevant bits
* of the address and checking for aliasing. This test
* will find single-bit address failures such as stuck
* -high, stuck-low, and shorted pins. The base address
* and size of the region are selected by the caller.
*
* Notes: For best results, the selected base address should
* have enough LSB 0's to guarantee single address bit
* changes. For example, to test a 64-Kbyte region,
* select a base address on a 64-Kbyte boundary. Also,
* select the region size as a power-of-two--if at all
* possible.
*
* Returns: NULL if the test succeeds.
* A non-zero result is the first address at which an
* aliasing problem was uncovered. By examining the
* contents of memory, it may be possible to gather
* additional information about the problem.
*
**********************************************************************/
datum *
memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)
{
unsigned long addressMask = (nBytes/sizeof(datum) - 1);
unsigned long offset;
unsigned long testOffset;
datum pattern = (datum) 0xAAAAAAAA;
datum antipattern = (datum) 0x55555555;
/*
* Write the default pattern at each of the power-of-two offsets.
*/
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
baseAddress[offset] = pattern;
}
/*
* Check for address bits stuck high.
*/
testOffset = 0;
baseAddress[testOffset] = antipattern;
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if (baseAddress[offset] != pattern)
{
return ((datum *) &baseAddress[offset]);
}
}
baseAddress[testOffset] = pattern;
/*
* Check for address bits stuck low or shorted.
*/
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
{
baseAddress[testOffset] = antipattern;
if (baseAddress[0] != pattern)
{
return ((datum *) &baseAddress[testOffset]);
}
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
{
if ((baseAddress[offset] != pattern) && (offset != testOffset))
{
return ((datum *) &baseAddress[testOffset]);
}
}
baseAddress[testOffset] = pattern;
}
return (NULL);
} /* memTestAddressBus() */
/**********************************************************************
*
* Function: memTestDevice()
*
* Description: Test the integrity of a physical memory device by
* performing an increment/decrement test over the
* entire region. In the process every storage bit
* in the device is tested as a zero and a one. The
* base address and the size of the region are
* selected by the caller.
*
* Notes:
*
* Returns: NULL if the test succeeds.
*
* A non-zero result is the first address at which an
* incorrect value was read back. By examining the
* contents of memory, it may be possible to gather
* additional information about the problem.
*
**********************************************************************/
datum *
memTestDevice(volatile datum * baseAddress, unsigned long nBytes)
{
unsigned long offset;
unsigned long nWords = nBytes / sizeof(datum);
datum pattern;
datum antipattern;
/*
* Fill memory with a known pattern.
*/
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
baseAddress[offset] = pattern;
}
/*
* Check each location and invert it for the second pass.
*/
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
if (baseAddress[offset] != pattern)
{
return ((datum *) &baseAddress[offset]);
}
antipattern = ~pattern;
baseAddress[offset] = antipattern;
}
/*
* Check each location for the inverted pattern and zero it.
*/
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
{
antipattern = ~pattern;
if (baseAddress[offset] != antipattern)
{
return ((datum *) &baseAddress[offset]);
}
}
return (NULL);
} /* memTestDevice() */
@@ -0,0 +1,32 @@
/******************************************************************************
*
* @brief provide general-purpose memory testing functions.
*
*******************************************************************************/
#ifndef _memtest_h
#define _memtest_h
/*
* Define NULL pointer value.
*/
#ifndef NULL
#define NULL (void *) 0
#endif
/*
* Set the data bus width.
*/
typedef unsigned long datum;
/*
* Function prototypes.
*/
datum memTestDataBus(volatile datum * address);
datum * memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes);
datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes);
#endif /* _memtest_h */
@@ -0,0 +1,625 @@
/******************************************************************************
*
*
* @brief provide the standard C library routine printf(), but without all the baggage.
*
*******************************************************************************/
#include "common.h"
#include <stdarg.h>
/********************************************************************/
typedef struct
{
int dest;
void (*func)(char);
char *loc;
} PRINTK_INFO;
int
printk (PRINTK_INFO *, const char *, va_list);
/********************************************************************/
#define DEST_CONSOLE (1)
#define DEST_STRING (2)
#define FLAGS_MINUS (0x01)
#define FLAGS_PLUS (0x02)
#define FLAGS_SPACE (0x04)
#define FLAGS_ZERO (0x08)
#define FLAGS_POUND (0x10)
#define IS_FLAG_MINUS(a) (a & FLAGS_MINUS)
#define IS_FLAG_PLUS(a) (a & FLAGS_PLUS)
#define IS_FLAG_SPACE(a) (a & FLAGS_SPACE)
#define IS_FLAG_ZERO(a) (a & FLAGS_ZERO)
#define IS_FLAG_POUND(a) (a & FLAGS_POUND)
#define LENMOD_h (0x01)
#define LENMOD_l (0x02)
#define LENMOD_L (0x04)
#define IS_LENMOD_h(a) (a & LENMOD_h)
#define IS_LENMOD_l(a) (a & LENMOD_l)
#define IS_LENMOD_L(a) (a & LENMOD_L)
#define FMT_d (0x0001)
#define FMT_o (0x0002)
#define FMT_x (0x0004)
#define FMT_X (0x0008)
#define FMT_u (0x0010)
#define FMT_c (0x0020)
#define FMT_s (0x0040)
#define FMT_p (0x0080)
#define FMT_n (0x0100)
#define IS_FMT_d(a) (a & FMT_d)
#define IS_FMT_o(a) (a & FMT_o)
#define IS_FMT_x(a) (a & FMT_x)
#define IS_FMT_X(a) (a & FMT_X)
#define IS_FMT_u(a) (a & FMT_u)
#define IS_FMT_c(a) (a & FMT_c)
#define IS_FMT_s(a) (a & FMT_s)
#define IS_FMT_p(a) (a & FMT_p)
#define IS_FMT_n(a) (a & FMT_n)
/********************************************************************/
static void
printk_putc (int c, int *count, PRINTK_INFO *info)
{
switch (info->dest)
{
case DEST_CONSOLE:
info->func((char)c);
break;
case DEST_STRING:
*(info->loc) = (unsigned char)c;
++(info->loc);
break;
default:
break;
}
*count += 1;
}
/********************************************************************/
static int
printk_mknumstr (char *numstr, void *nump, int neg, int radix)
{
int a,b,c;
unsigned int ua,ub,uc;
int nlen;
char *nstrp;
nlen = 0;
nstrp = numstr;
*nstrp++ = '\0';
if (neg)
{
a = *(int *)nump;
if (a == 0)
{
*nstrp = '0';
++nlen;
goto done;
}
while (a != 0)
{
b = (int)a / (int)radix;
c = (int)a - ((int)b * (int)radix);
if (c < 0)
{
c = ~c + 1 + '0';
}
else
{
c = c + '0';
}
a = b;
*nstrp++ = (char)c;
++nlen;
}
}
else
{
ua = *(unsigned int *)nump;
if (ua == 0)
{
*nstrp = '0';
++nlen;
goto done;
}
while (ua != 0)
{
ub = (unsigned int)ua / (unsigned int)radix;
uc = (unsigned int)ua - ((unsigned int)ub * (unsigned int)radix);
if (uc < 10)
{
uc = uc + '0';
}
else
{
uc = uc - 10 + 'A';
}
ua = ub;
*nstrp++ = (char)uc;
++nlen;
}
}
done:
return nlen;
}
/********************************************************************/
static void
printk_pad_zero (int curlen, int field_width, int *count, PRINTK_INFO *info)
{
int i;
for (i = curlen; i < field_width; i++)
{
printk_putc('0',count, info);
}
}
/********************************************************************/
static void
printk_pad_space (int curlen, int field_width, int *count, PRINTK_INFO *info)
{
int i;
for (i = curlen; i < field_width; i++)
{
printk_putc(' ',count, info);
}
}
/********************************************************************/
int
printk (PRINTK_INFO *info, const char *fmt, va_list ap)
{
/* va_list ap; */
char *p;
int c;
char vstr[33];
char *vstrp;
int vlen;
int done;
int count = 0;
int flags_used;
int field_width;
#if 0
int precision_used;
int precision_width;
int length_modifier;
#endif
int ival;
int schar, dschar;
int *ivalp;
char *sval;
int cval;
unsigned int uval;
/*
* Start parsing apart the format string and display appropriate
* formats and data.
*/
for (p = (char *)fmt; (c = *p) != 0; p++)
{
/*
* All formats begin with a '%' marker. Special chars like
* '\n' or '\t' are normally converted to the appropriate
* character by the __compiler__. Thus, no need for this
* routine to account for the '\' character.
*/
if (c != '%')
{
/*
* This needs to be replaced with something like
* 'out_char()' or call an OS routine.
*/
#ifndef UNIX_DEBUG
if (c != '\n')
{
printk_putc(c, &count, info);
}
else
{
printk_putc(0x0D /* CR */, &count, info);
printk_putc(0x0A /* LF */, &count, info);
}
#else
printk_putc(c, &count, info);
#endif
/*
* By using 'continue', the next iteration of the loop
* is used, skipping the code that follows.
*/
continue;
}
/*
* First check for specification modifier flags.
*/
flags_used = 0;
done = FALSE;
while (!done)
{
switch (/* c = */ *++p)
{
case '-':
flags_used |= FLAGS_MINUS;
break;
case '+':
flags_used |= FLAGS_PLUS;
break;
case ' ':
flags_used |= FLAGS_SPACE;
break;
case '0':
flags_used |= FLAGS_ZERO;
break;
case '#':
flags_used |= FLAGS_POUND;
break;
default:
/* we've gone one char too far */
--p;
done = TRUE;
break;
}
}
/*
* Next check for minimum field width.
*/
field_width = 0;
done = FALSE;
while (!done)
{
switch (c = *++p)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
field_width = (field_width * 10) + (c - '0');
break;
default:
/* we've gone one char too far */
--p;
done = TRUE;
break;
}
}
/*
* Next check for the width and precision field separator.
*/
if (/* (c = *++p) */ *++p == '.')
{
/* precision_used = TRUE; */
/*
* Must get precision field width, if present.
*/
/* precision_width = 0; */
done = FALSE;
while (!done)
{
switch (/* c = uncomment if used below */ *++p)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
#if 0
precision_width = (precision_width * 10) +
(c - '0');
#endif
break;
default:
/* we've gone one char too far */
--p;
done = TRUE;
break;
}
}
}
else
{
/* we've gone one char too far */
--p;
#if 0
precision_used = FALSE;
precision_width = 0;
#endif
}
/*
* Check for the length modifier.
*/
/* length_modifier = 0; */
switch (/* c = */ *++p)
{
case 'h':
/* length_modifier |= LENMOD_h; */
break;
case 'l':
/* length_modifier |= LENMOD_l; */
break;
case 'L':
/* length_modifier |= LENMOD_L; */
break;
default:
/* we've gone one char too far */
--p;
break;
}
/*
* Now we're ready to examine the format.
*/
switch (c = *++p)
{
case 'd':
case 'i':
ival = (int)va_arg(ap, int);
vlen = printk_mknumstr(vstr,&ival,TRUE,10);
vstrp = &vstr[vlen];
if (ival < 0)
{
schar = '-';
++vlen;
}
else
{
if (IS_FLAG_PLUS(flags_used))
{
schar = '+';
++vlen;
}
else
{
if (IS_FLAG_SPACE(flags_used))
{
schar = ' ';
++vlen;
}
else
{
schar = 0;
}
}
}
dschar = FALSE;
/*
* do the ZERO pad.
*/
if (IS_FLAG_ZERO(flags_used))
{
if (schar)
printk_putc(schar, &count, info);
dschar = TRUE;
printk_pad_zero (vlen, field_width, &count, info);
vlen = field_width;
}
else
{
if (!IS_FLAG_MINUS(flags_used))
{
printk_pad_space (vlen, field_width, &count, info);
if (schar)
printk_putc(schar, &count, info);
dschar = TRUE;
}
}
/* the string was built in reverse order, now display in */
/* correct order */
if (!dschar && schar)
{
printk_putc(schar, &count, info);
}
goto cont_xd;
case 'x':
case 'X':
uval = (unsigned int)va_arg(ap, unsigned int);
vlen = printk_mknumstr(vstr,&uval,FALSE,16);
vstrp = &vstr[vlen];
dschar = FALSE;
if (IS_FLAG_ZERO(flags_used))
{
if (IS_FLAG_POUND(flags_used))
{
printk_putc('0', &count, info);
printk_putc('x', &count, info);
/*vlen += 2;*/
dschar = TRUE;
}
printk_pad_zero (vlen, field_width, &count, info);
vlen = field_width;
}
else
{
if (!IS_FLAG_MINUS(flags_used))
{
if (IS_FLAG_POUND(flags_used))
{
vlen += 2;
}
printk_pad_space (vlen, field_width, &count, info);
if (IS_FLAG_POUND(flags_used))
{
printk_putc('0', &count, info);
printk_putc('x', &count, info);
dschar = TRUE;
}
}
}
if ((IS_FLAG_POUND(flags_used)) && !dschar)
{
printk_putc('0', &count, info);
printk_putc('x', &count, info);
vlen += 2;
}
goto cont_xd;
case 'o':
uval = (unsigned int)va_arg(ap, unsigned int);
vlen = printk_mknumstr(vstr,&uval,FALSE,8);
goto cont_u;
case 'b':
uval = (unsigned int)va_arg(ap, unsigned int);
vlen = printk_mknumstr(vstr,&uval,FALSE,2);
goto cont_u;
case 'p':
uval = (unsigned int)va_arg(ap, void *);
vlen = printk_mknumstr(vstr,&uval,FALSE,16);
goto cont_u;
case 'u':
uval = (unsigned int)va_arg(ap, unsigned int);
vlen = printk_mknumstr(vstr,&uval,FALSE,10);
cont_u:
vstrp = &vstr[vlen];
if (IS_FLAG_ZERO(flags_used))
{
printk_pad_zero (vlen, field_width, &count, info);
vlen = field_width;
}
else
{
if (!IS_FLAG_MINUS(flags_used))
{
printk_pad_space (vlen, field_width, &count, info);
}
}
cont_xd:
while (*vstrp)
printk_putc(*vstrp--, &count, info);
if (IS_FLAG_MINUS(flags_used))
{
printk_pad_space (vlen, field_width, &count, info);
}
break;
case 'c':
cval = (char)va_arg(ap, unsigned int);
printk_putc(cval,&count, info);
break;
case 's':
sval = (char *)va_arg(ap, char *);
if (sval)
{
vlen = strlen(sval);
if (!IS_FLAG_MINUS(flags_used))
{
printk_pad_space (vlen, field_width, &count, info);
}
while (*sval)
printk_putc(*sval++,&count, info);
if (IS_FLAG_MINUS(flags_used))
{
printk_pad_space (vlen, field_width, &count, info);
}
}
break;
case 'n':
ivalp = (int *)va_arg(ap, int *);
*ivalp = count;
break;
default:
printk_putc(c,&count, info);
break;
}
}
return count;
}
/********************************************************************/
int
printf (const char *fmt, ...)
{
va_list ap;
int rvalue;
PRINTK_INFO info;
info.dest = DEST_CONSOLE;
info.func = &out_char;
/*
* Initialize the pointer to the variable length argument list.
*/
va_start(ap, fmt);
rvalue = printk(&info, fmt, ap);
/*
* Cleanup the variable length argument list.
*/
va_end(ap);
return rvalue;
}
/********************************************************************/
int
sprintf (char *s, const char *fmt, ...)
{
va_list ap;
int rvalue = 0;
PRINTK_INFO info;
/*
* Initialize the pointer to the variable length argument list.
*/
if (s != 0)
{
info.dest = DEST_STRING;
info.loc = s;
va_start(ap, fmt);
rvalue = printk(&info, fmt, ap);
*info.loc = '\0';
va_end(ap);
}
return rvalue;
}
#if defined(__GNUC__)
int puts(const char * s)
{
printf(s);
return 0;
}
#endif
/********************************************************************/
@@ -0,0 +1,124 @@
/******************************************************************************
*
*
* @brief Implement a first in, first out linked list.
*
*******************************************************************************/
#include "common.h"
#include "queue.h"
/********************************************************************/
/*
* Initialize the specified queue to an empty state
*
* Parameters:
* q Pointer to queue structure
*/
void
queue_init(QUEUE *q)
{
q->head = NULL;
}
/********************************************************************/
/*
* Check for an empty queue
*
* Parameters:
* q Pointer to queue structure
*
* Return Value:
* 1 if Queue is empty
* 0 otherwise
*/
int
queue_isempty(QUEUE *q)
{
return (q->head == NULL);
}
/********************************************************************/
/*
* Add an item to the end of the queue
*
* Parameters:
* q Pointer to queue structure
* node New node to add to the queue
*/
void
queue_add(QUEUE *q, QNODE *node)
{
if (queue_isempty(q))
{
q->head = q->tail = node;
}
else
{
q->tail->next = node;
q->tail = node;
}
node->next = NULL;
}
/********************************************************************/
/*
* Remove and return first (oldest) entry from the specified queue
*
* Parameters:
* q Pointer to queue structure
*
* Return Value:
* Node at head of queue - NULL if queue is empty
*/
QNODE*
queue_remove(QUEUE *q)
{
QNODE *oldest;
if (queue_isempty(q))
return NULL;
oldest = q->head;
q->head = oldest->next;
return oldest;
}
/********************************************************************/
/*
* Peek into the queue and return pointer to first (oldest) entry.
* The queue is not modified
*
* Parameters:
* q Pointer to queue structure
*
* Return Value:
* Node at head of queue - NULL if queue is empty
*/
QNODE*
queue_peek(QUEUE *q)
{
return q->head;
}
/********************************************************************/
/*
* Move entire contents of one queue to the other
*
* Parameters:
* src Pointer to source queue
* dst Pointer to destination queue
*/
void
queue_move(QUEUE *dst, QUEUE *src)
{
if (queue_isempty(src))
return;
if (queue_isempty(dst))
dst->head = src->head;
else
dst->tail->next = src->head;
dst->tail = src->tail;
src->head = NULL;
return;
}
/********************************************************************/
@@ -0,0 +1,52 @@
/******************************************************************************
*
* @brief Implement a first in, first out linked list.
*
*******************************************************************************/
#ifndef _QUEUE_H_
#define _QUEUE_H_
/********************************************************************/
/*
* Individual queue node
*/
typedef struct NODE
{
struct NODE *next;
} QNODE;
/*
* Queue Struture - linked list of qentry items
*/
typedef struct
{
QNODE *head;
QNODE *tail;
} QUEUE;
/*
* Functions provided by queue.c
*/
void
queue_init(QUEUE *);
int
queue_isempty(QUEUE *);
void
queue_add(QUEUE *, QNODE *);
QNODE*
queue_remove(QUEUE *);
QNODE*
queue_peek(QUEUE *);
void
queue_move(QUEUE *, QUEUE *);
/********************************************************************/
#endif /* _QUEUE_H_ */
@@ -0,0 +1,77 @@
/******************************************************************************
*
* @brief Implement generic NV32 startup code.
*
*******************************************************************************/
#include "common.h"
#pragma section = ".data"
#pragma section = ".data_init"
#pragma section = ".bss"
#pragma section = "CodeRelocate"
#pragma section = "CodeRelocateRam"
/********************************************************************/
void
common_startup(void)
{
// extern char __DATA_ROM[];
// extern char __DATA_RAM[];
// extern char __DATA_END[];
/* Declare a counter we'll use in all of the copy loops */
uint32 n;
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
extern uint32 __VECTOR_TABLE[];
extern uint32 __VECTOR_RAM[];
/* Copy the vector table to RAM */
if (__VECTOR_RAM != __VECTOR_TABLE)
{
for (n = 0; n < 48 ; n++) // for small memory space, excluding flash configuration field
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
}
/* Point the VTOR to the new copy of the vector table */
write_vtor((uint32)__VECTOR_RAM);
/* Get the addresses for the .data section (initialized data section) */
uint8* data_ram = __section_begin(".data");
uint8* data_rom = __section_begin(".data_init");
uint8* data_rom_end = __section_end(".data_init");
/* Copy initialized data from ROM to RAM */
n = data_rom_end - data_rom;
while (n--)
*data_ram++ = *data_rom++;
/* Get the addresses for the .bss section (zero-initialized data) */
uint8* bss_start = __section_begin(".bss");
uint8* bss_end = __section_end(".bss");
/* Clear the zero-initialized data section */
n = bss_end - bss_start;
while(n--)
*bss_start++ = 0;
/* Get addresses for any code sections that need to be copied from ROM to RAM.
* The IAR tools have a predefined keyword that can be used to mark individual
* functions for execution from RAM. Add "__ramfunc" before the return type in
* the function prototype for any routines you need to execute from RAM instead
* of ROM. ex: __ramfunc void foo(void);
*/
uint8* code_relocate_ram = __section_begin("CodeRelocateRam");
uint8* code_relocate = __section_begin("CodeRelocate");
uint8* code_relocate_end = __section_end("CodeRelocate");
/* Copy functions from ROM to RAM */
n = code_relocate_end - code_relocate;
while (n--)
*code_relocate_ram++ = *code_relocate++;
}
/********************************************************************/
@@ -0,0 +1,15 @@
/******************************************************************************
* @brief Implement generic startup code.
*
*******************************************************************************/
#ifndef _STARTUP_H_
#define _STARTUP_H_
/********************************************************************/
void common_startup(void);
/********************************************************************/
#endif /* _STARTUP_H_ */
@@ -0,0 +1,50 @@
/*
** ###################################################################
* @brief Device specific configuration file for MKE02Z2 (implementation file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#include <stdint.h>
#include "NV32F100.h"
#define DISABLE_WDOG 1
#define DEFAULT_SYSTEM_CLOCK 20971520u /* Default System clock value */
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
#define WDOG_TOVAL *((volatile uint16_t *)(&WDOG->TOVALH))
#define WDOG_CNT *((volatile uint16_t *)(&WDOG->CNTH))
void SystemInit (void) {
#if (DISABLE_WDOG)
/* Disable the WDOG module */
WDOG_CNT = 0x20C5;
WDOG_CNT = 0x28D9;
WDOG_TOVAL = 0xFFFF;
//WDOG_WIN = 0; /* NOTE: this will cause HARDFAULT error*/
WDOG->WINH = 0xFF;
WDOG->WINL = 0xFF;
WDOG->CS2 = 0x01;
WDOG->CS1 = 0x20; /* WDOGA = 1 to allow reconfigure watchdog at any time by executing an unlock sequence */
#endif
}
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
void SystemCoreClockUpdate (void) {
}
@@ -0,0 +1,51 @@
/*
* @brief Device specific configuration file for NV32 (header file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef SYSTEM_NV32_H_
#define SYSTEM_NV32_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit (void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* #if !defined(SYSTEM_NV32_H_) */
@@ -0,0 +1,49 @@
/******************************************************************************
*
* @brief provide some type definitions which are not CMSIS style.
*
*******************************************************************************/
#ifndef __TYPEDEF_H__
#define __TYPEDEF_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifndef s8
#define s8 char
#endif
#ifndef u8
#define u8 unsigned char
#endif
#ifndef s16
#define s16 short
#endif
#ifndef u16
#define u16 unsigned short
#endif
#ifndef s32
#define s32 long
#endif
#ifndef u32
#define u32 unsigned long
#endif
#ifndef sint
#define sint int
#endif
#ifndef uint
#define uint unsigned int
#endif
#ifndef s64
#define s64 long long
#endif
#ifndef u64
#define u64 unsigned long long
#endif
#ifdef __cplusplus
}
#endif
#endif /* __TYPEDEF_H__ */
@@ -0,0 +1,328 @@
/******************************************************************************
*
* @brief provide an interactive user interface.
*
* The commands, set/show parameters, and prompt are configured at the project level.
*******************************************************************************/
#include "common.h"
#include "uif.h"
/********************************************************************/
/*
* Global messages -- constant strings
*/
const char HELPMSG[] =
"Enter 'help' for help.\n";
const char INVARG[] =
"Error: Invalid argument: %s\n";
const char INVALUE[] =
"Error: Invalid value: %s\n";
/*
* Strings used by this file only
*/
static const char INVCMD[] =
"Error: No such command: %s\n";
static const char HELPFORMAT[] =
"%8s %-25s %s %s\n";
static const char SYNTAX[] =
"Error: Invalid syntax for: %s\n";
static const char INVOPT[] =
"Error: Invalid set/show option: %s\n";
static const char OPTFMT[] =
"%12s: ";
static char cmdline1 [UIF_MAX_LINE];
static char cmdline2 [UIF_MAX_LINE];
/********************************************************************/
char *
get_line (char *line)
{
int pos;
int ch;
pos = 0;
ch = (int)in_char();
while ( (ch != 0x0D /* CR */) &&
(ch != 0x0A /* LF/NL */) &&
(pos < UIF_MAX_LINE))
{
switch (ch)
{
case 0x08: /* Backspace */
case 0x7F: /* Delete */
if (pos > 0)
{
pos -= 1;
out_char(0x08); /* backspace */
out_char(' ');
out_char(0x08); /* backspace */
}
break;
default:
if ((pos+1) < UIF_MAX_LINE)
{
if ((ch > 0x1f) && (ch < 0x80))
{
line[pos++] = (char)ch;
out_char((char)ch);
}
}
break;
}
ch = (int)in_char();
}
line[pos] = '\0';
out_char(0x0D); /* CR */
out_char(0x0A); /* LF */
return line;
}
/********************************************************************/
int
make_argv (char *cmdline, char *argv[])
{
int argc, i, in_text;
/*
* Break cmdline into strings and argv
* It is permissible for argv to be NULL, in which case
* the purpose of this routine becomes to count args
*/
argc = 0;
i = 0;
in_text = FALSE;
while (cmdline[i] != '\0') /* getline() must place 0x00 on end */
{
if (((cmdline[i] == ' ') ||
(cmdline[i] == '\t')) )
{
if (in_text)
{
/* end of command line argument */
cmdline[i] = '\0';
in_text = FALSE;
}
else
{
/* still looking for next argument */
}
}
else
{
/* got non-whitespace character */
if (in_text)
{
}
else
{
/* start of an argument */
in_text = TRUE;
if (argc < UIF_MAX_ARGS)
{
if (argv != NULL)
argv[argc] = &cmdline[i];
argc++;
}
else
/*return argc;*/
break;
}
}
i++; /* proceed to next character */
}
if (argv != NULL)
argv[argc] = NULL;
return argc;
}
/********************************************************************/
void
run_cmd (void)
{
/*
* Global array of pointers to emulate C argc,argv interface
*/
int argc;
char *argv[UIF_MAX_ARGS + 1]; /* one extra for null terminator */
get_line(cmdline1);
if (!(argc = make_argv(cmdline1,argv)))
{
/* no command entered, just a blank line */
strcpy(cmdline1,cmdline2);
argc = make_argv(cmdline1,argv);
}
cmdline2[0] = '\0';
if (argc)
{
int i;
for (i = 0; i < UIF_NUM_CMD; i++)
{
if (strcasecmp(UIF_CMDTAB[i].cmd,argv[0]) == 0)
{
if (((argc-1) >= UIF_CMDTAB[i].min_args) &&
((argc-1) <= UIF_CMDTAB[i].max_args))
{
if (UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT)
{
strcpy(cmdline2,argv[0]);
}
UIF_CMDTAB[i].func(argc,argv);
return;
}
else
{
printf(SYNTAX,argv[0]);
return;
}
}
}
printf(INVCMD,argv[0]);
printf(HELPMSG);
}
}
/********************************************************************/
uint32
get_value (char *s, int *success, int base)
{
uint32 value;
char *p;
value = strtoul(s,&p,base);
if ((value == 0) && (p == s))
{
*success = FALSE;
return 0;
}
else
{
*success = TRUE;
return value;
}
}
/********************************************************************/
void
uif_cmd_help (int argc, char **argv)
{
int index;
(void)argc;
(void)argv;
printf("\n");
for (index = 0; index < UIF_NUM_CMD; index++)
{
printf(HELPFORMAT,
UIF_CMDTAB[index].cmd,
UIF_CMDTAB[index].description,
UIF_CMDTAB[index].cmd,
UIF_CMDTAB[index].syntax);
}
printf("\n");
}
/********************************************************************/
void
uif_cmd_set (int argc, char **argv)
{
int index;
printf("\n");
if (argc == 1)
{
printf("Valid 'set' options:\n");
for (index = 0; index < UIF_NUM_SETCMD; ++index)
{
printf(OPTFMT,UIF_SETCMDTAB[index].option);
printf("%s\n",UIF_SETCMDTAB[index].syntax);
}
printf("\n");
return;
}
if (argc != 3)
{
printf("Error: Invalid argument list\n");
return;
}
for (index = 0; index < UIF_NUM_SETCMD; index++)
{
if (strcasecmp(UIF_SETCMDTAB[index].option,argv[1]) == 0)
{
if (((argc-1-1) >= UIF_SETCMDTAB[index].min_args) &&
((argc-1-1) <= UIF_SETCMDTAB[index].max_args))
{
UIF_SETCMDTAB[index].func(argc,argv);
return;
}
else
{
printf(INVARG,argv[1]);
return;
}
}
}
printf(INVOPT,argv[1]);
}
/********************************************************************/
void
uif_cmd_show (int argc, char **argv)
{
int index;
printf("\n");
if (argc == 1)
{
/*
* Show all Option settings
*/
argc = 2;
argv[2] = NULL;
for (index = 0; index < UIF_NUM_SETCMD; index++)
{
printf(OPTFMT,UIF_SETCMDTAB[index].option);
UIF_SETCMDTAB[index].func(argc,argv);
printf("\n");
}
printf("\n");
return;
}
for (index = 0; index < UIF_NUM_SETCMD; index++)
{
if (strcasecmp(UIF_SETCMDTAB[index].option,argv[1]) == 0)
{
if (((argc-1-1) >= UIF_SETCMDTAB[index].min_args) &&
((argc-1-1) <= UIF_SETCMDTAB[index].max_args))
{
printf(OPTFMT,UIF_SETCMDTAB[index].option);
UIF_SETCMDTAB[index].func(argc,argv);
printf("\n\n");
return;
}
else
{
printf(INVARG,argv[1]);
return;
}
}
}
printf(INVOPT,argv[1]);
}
/********************************************************************/
@@ -0,0 +1,123 @@
/********************************************************************************
* @brief provide an interactive user interface.
*
* The commands, set/show parameters, and prompt are configured at the project level.
*******************************************************************************/
#ifndef _UIF_H_
#define _UIF_H_
/********************************************************************/
/*
* Function prototypes
*/
char *
get_line (char *);
uint32
get_value (char *, int *, int);
void
run_cmd (void);
int
make_argv (char *, char **);
void
uif_cmd_help (int, char **);
void
uif_cmd_set (int, char **);
void
uif_cmd_show (int, char **);
/*
* Maximum command line arguments
*/
#define UIF_MAX_ARGS 10
/*
* Maximum length of the command line
*/
#define UIF_MAX_LINE 80
/*
* The command table entry data structure
*/
typedef const struct
{
char * cmd; /* command name user types, ie. GO */
int min_args; /* min num of args command accepts */
int max_args; /* max num of args command accepts */
int flags; /* command flags (e.g. repeat) */
void (*func)(int, char **); /* actual function to call */
char * description; /* brief description of command */
char * syntax; /* syntax of command */
} UIF_CMD;
/*
* Prototype and macro for size of the command table
*/
extern UIF_CMD UIF_CMDTAB[];
extern const int UIF_NUM_CMD;
#define UIF_CMDTAB_SIZE (sizeof(UIF_CMDTAB)/sizeof(UIF_CMD))
#define UIF_CMD_FLAG_REPEAT 0x1
/*
* Macros for User InterFace command table entries
*/
#ifndef UIF_CMD_HELP
#define UIF_CMD_HELP \
{"help",0,1,0,uif_cmd_help,"Help","<cmd>"},
#endif
#ifndef UIF_CMD_SET
#define UIF_CMD_SET \
{"set",0,2,0,uif_cmd_set,"Set Config","<option value>"},
#endif
#ifndef UIF_CMD_SHOW
#define UIF_CMD_SHOW \
{"show",0,1,0,uif_cmd_show,"Show Config","<option>"},
#endif
/*
* Macro to include all standard user interface commands
*/
#define UIF_CMDS_ALL \
UIF_CMD_HELP \
UIF_CMD_SET \
UIF_CMD_SHOW
/*
* The set/show table entry data structure
*/
typedef const struct
{
char * option;
int min_args;
int max_args;
void (*func)(int, char **);
char * syntax;
} UIF_SETCMD;
/*
* Prototype and macro for size of the table
*/
extern UIF_SETCMD UIF_SETCMDTAB[];
extern const int UIF_NUM_SETCMD;
#define UIF_SETCMDTAB_SIZE (sizeof(UIF_SETCMDTAB)/sizeof(UIF_SETCMD))
/*
* Strings defined in uif.c that may be useful to external functions
*/
extern const char HELPMSG[];
extern const char INVARG[];
extern const char INVALUE[];
/********************************************************************/
#endif /* _UIF_H_ */
@@ -0,0 +1,77 @@
/******************************************************************************
* @brief provide generic high-level routines for ARM Cortex M0/M0+ processors.
*
*******************************************************************************/
#include "common.h"
/***********************************************************************/
/*
* Configures the ARM system control register for STOP (deep sleep) mode
* and then executes the WFI instruction to enter the mode.
*
* Parameters:
* none
*
* Note: Might want to change this later to allow for passing in a parameter
* to optionally set the sleep on exit bit.
*/
void stop (void)
{
/* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* WFI instruction will start entry into STOP mode */
#ifndef KEIL
// If not using KEIL's uVision use the standard assembly command
asm("WFI");
#else
// If using KEIL's uVision, use the CMSIS intrinsic
__wfi();
#endif
}
/***********************************************************************/
/*
* Configures the ARM system control register for WAIT (sleep) mode
* and then executes the WFI instruction to enter the mode.
*
* Parameters:
* none
*
* Note: Might want to change this later to allow for passing in a parameter
* to optionally set the sleep on exit bit.
*/
void wait (void)
{
/* Clear the SLEEPDEEP bit to make sure we go into WAIT (sleep) mode instead
* of deep sleep.
*/
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
/* WFI instruction will start entry into WAIT mode */
#ifndef KEIL
// If not using KEIL's uVision use the standard assembly command
asm("WFI");
#else
// If using KEIL's uVision, use the CMSIS intrinsic
__wfi();
#endif
}
/***********************************************************************/
/*
* Change the value of the vector table offset register to the specified value.
*
* Parameters:
* vtor new value to write to the VTOR
*/
void write_vtor (int vtor)
{
/* Write the VTOR with the new value */
SCB->VTOR = vtor;
}
/***********************************************************************/
@@ -0,0 +1,100 @@
/******************************************************************************
*
* @brief provide generic high-level routines for ARM Cortex M0/M0+ processors.
*
*******************************************************************************/
#ifndef _CPU_ARM_CM0_H
#define _CPU_ARM_CM0_H
/*ARM Cortex M0 implementation for interrupt priority shift*/
#define ARM_INTERRUPT_LEVEL_BITS 2
/***********************************************************************/
/*!< Macro to enable all interrupts. */
#ifndef KEIL
#define EnableInterrupts __set_PRIMASK(0) //Modify
#else
#define EnableInterrupts __set_PRIMASK(0)
#endif
/*!< Macro to disable all interrupts. */
#ifndef KEIL
#define DisableInterrupts __set_PRIMASK(1)
#else
#define DisableInterrupts __set_PRIMASK(1)
#endif
#define disable_irq(irq) NVIC_DisableIRQ(irq)
#define enable_irq(irq) NVIC_EnableIRQ(irq)
#define set_irq_priority(irq, prio) NVIC_SetPriority(irq, prio)
/***********************************************************************/
/*
* Misc. Defines
*/
#ifdef FALSE
#undef FALSE
#endif
#define FALSE (0)
#ifdef TRUE
#undef TRUE
#endif
#define TRUE (1)
#ifdef NULL
#undef NULL
#endif
#define NULL (0)
#ifdef ON
#undef ON
#endif
#define ON (1)
#ifdef OFF
#undef OFF
#endif
#define OFF (0)
#undef ENABLE
#define ENABLE (1)
#undef DISABLE
#define DISABLE (0)
/***********************************************************************/
/*
* The basic data types
*/
typedef unsigned char uint8; /* 8 bits */
typedef unsigned short int uint16; /* 16 bits */
typedef unsigned long int uint32; /* 32 bits */
typedef char int8; /* 8 bits */
typedef short int int16; /* 16 bits */
typedef int int32; /* 32 bits */
typedef volatile int8 vint8; /* 8 bits */
typedef volatile int16 vint16; /* 16 bits */
typedef volatile int32 vint32; /* 32 bits */
typedef volatile uint8 vuint8; /* 8 bits */
typedef volatile uint16 vuint16; /* 16 bits */
typedef volatile uint32 vuint32; /* 32 bits */
// function prototype for main function
int main(void);
/***********************************************************************/
// function prototypes for arm_cm0.c
void stop (void);
void wait (void);
void write_vtor (int);
/***********************************************************************/
#endif /* _CPU_ARM_CM4_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
/*
* Note: This file is recreated by the project wizard whenever the MCU is
* changed and should not be edited by hand
*/
/* Include the derivative-specific header file */
#include <NV32.h>
#include "arm_cm0.h"
@@ -0,0 +1,65 @@
/******************************************************************************
* @brief provide high-level startup routines for NV32Fxx.
*
*******************************************************************************/
#include "start.h"
#include "common.h"
#include "wdog.h"
#include "sysinit.h"
void start(void);
void SystemInit( void );
/********************************************************************/
/*!
* \brief Start
* \return None
*
* This function calls all of the needed starup routines and then
* branches to the main process.
*/
void start(void)
{
/* Disable the watchdog ETMer but enable update */
WDOG_DisableWDOGEnableUpdate();
#ifndef __GNUC__
#ifndef KEIL
/* Copy any vector or data sections that need to be in RAM */
common_startup();
#endif
#endif
/* Jump to main process */
main();
/* No actions to perform after this so wait forever */
while(1);
}
/********************************************************************/
/********************************************************************/
/*!
* \brief flash SystemInit
* \return None
*
* this is a system initialization function which dediu16Cated in Keil
* others complier don't use it.
* it is similar to start function
*/
void SystemInit( void )
{
#if !defined(ENABLE_WDOG)
/* Disable the watchdog ETMer */
WDOG_Disable();
#else
/* Disable the watchdog ETMer but enable update */
WDOG_DisableWDOGEnableUpdate();
#endif
}
@@ -0,0 +1,7 @@
/******************************************************************************
* @brief provide high-level startup routines for NV32Fxx.
*
*******************************************************************************/
/* Function prototypes */
void start(void);
@@ -0,0 +1,88 @@
.syntax unified
.arch armv6-m
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/* Vectors and flash protection config in vectors.c */
@@ -0,0 +1,348 @@
;/*****************************************************************************
; * @file: startup_NV32.s
; * @purpose: CMSIS Cortex-M0plus Core Device Startup File for the
; * NV32F100
;*
; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
; *
; *****************************************************************************/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD Reserved16_IRQHandler ; Reserved interrupt 16
DCD Reserved17_IRQHandler ; Reserved interrupt 17
DCD Reserved18_IRQHandler ; Reserved interrupt 18
DCD Reserved19_IRQHandler ; Reserved interrupt 19
DCD Reserved20_IRQHandler ; Reserved interrupt 20
DCD ETMRH_IRQHandler ; ETMRH command complete/read collision interrupt
DCD LVD_LVW_IRQHandler ; Low Voltage Detect, Low Voltage Warning
DCD IRQ_IRQHandler ; External interrupt
DCD I2C0_IRQHandler ; I2C0 interrupt
DCD Reserved25_IRQHandler ; Reserved interrupt 25
DCD SPI0_IRQHandler ; SPI0 interrupt
DCD SPI1_IRQHandler ; SPI1 interrupt
DCD UART0_IRQHandler ; UART0 status/error interrupt
DCD UART1_IRQHandler ; UART1 status/error interrupt
DCD UART2_IRQHandler ; UART2 status/error interrupt
DCD ADC0_IRQHandler ; ADC0 interrupt
DCD ACMP0_IRQHandler ; ACMP0 interrupt
DCD ETM0_IRQHandler ; ETM0 Single interrupt vector for all sources
DCD ETM1_IRQHandler ; ETM1 Single interrupt vector for all sources
DCD ETM2_IRQHandler ; ETM2 Single interrupt vector for all sources
DCD RTC_IRQHandler ; RTC overflow
DCD ACMP1_IRQHandler ; ACMP1 interrupt
DCD PIT_CH0_IRQHandler ; PIT CH0 overflow
DCD PIT_CH1_IRQHandler ; PIT CH1 overflow
DCD KBI0_IRQHandler ; Keyboard interrupt 0
DCD KBI1_IRQHandler ; Keyboard interrupt 1
DCD Reserved42_IRQHandler ; Reserved interrupt 42
DCD ICS_IRQHandler ; MCG interrupt
DCD Watchdog_IRQHandler ; WDOG Interrupt
DCD Reserved45_IRQHandler ; Reserved interrupt 45
DCD Reserved46_IRQHandler ; Reserved interrupt 46
DCD Reserved47_IRQHandler ; Reserved interrupt 47
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
; <h> Flash Configuration
; <i> 16-byte flash configuration field that stores default protection settings (loaded on reset)
; <i> and security information that allows the MCU to restrict acces to the FTFL module.
; <h> Backdoor Comparison Key
; <o0> Backdoor Key 0 <0x0-0xFF:2>
; <o1> Backdoor Key 1 <0x0-0xFF:2>
; <o2> Backdoor Key 2 <0x0-0xFF:2>
; <o3> Backdoor Key 3 <0x0-0xFF:2>
; <o4> Backdoor Key 4 <0x0-0xFF:2>
; <o5> Backdoor Key 5 <0x0-0xFF:2>
; <o6> Backdoor Key 6 <0x0-0xFF:2>
; <o7> Backdoor Key 7 <0x0-0xFF:2>
BackDoorK0 EQU 0xFF
BackDoorK1 EQU 0xFF
BackDoorK2 EQU 0xFF
BackDoorK3 EQU 0xFF
BackDoorK4 EQU 0xFF
BackDoorK5 EQU 0xFF
BackDoorK6 EQU 0xFF
BackDoorK7 EQU 0xFF
; </h>
; <h> EEPROM Protection Register (EEPROT)
; <i> The DFPROT register defines which D-Flash sectors are protected against program and erase operations.
; <o.7> DPOPEN
; <0=> Enables EEPROM memory protection
; <1=> Disables EEPROM memory protection
; <o.0..2> DPS
; <0=> Flash address range: 0x00_0000 - 0x00_001F; protected size: 32 bytes
; <1=> Flash address range: 0x00_0000 - 0x00_003F; protected size: 64 bytes
; <2=> Flash address range: 0x00_0000 - 0x00_005F; protected size: 96 bytes
; <3=> Flash address range: 0x00_0000 - 0x00_007F; protected size: 128 bytes
; <4=> Flash address range: 0x00_0000 - 0x00_009F; protected size: 160 bytes
; <5=> Flash address range: 0x00_0000 - 0x00_00BF; protected size: 192 bytes
; <6=> Flash address range: 0x00_0000 - 0x00_00DF; protected size: 224 bytes
; <7=> Flash address range: 0x00_0000 - 0x00_00FF; protected size: 256 bytes
EEPROT EQU 0xFF
; </h>
; <h> FPROT
; <i> P-Flash Protection Register
; <o.7> FPOPEN
; <0=> FPHDIS and FPLDIS bits define unprotected address ranges as specified by the corresponding FPHS and FPLS bits FPROT1.1
; <1=> FPHDIS and FPLDIS bits enable protection for the address range specified by the corresponding FPHS and FPLS bits
; <o.5> FPHDIS
; <0=> Protection/Unprotection enabled
; <1=> Protection/Unprotection disabled
; <o.3..4> FPHS
; <0=> Address range: 0x00_7C00-0x00_7FFF; protected size: 1 KB
; <1=> Address range: 0x00_7800-0x00_7FFF; protected size: 2 KB
; <2=> Address range: 0x00_7000-0x00_7FFF; protected size: 4 KB
; <3=> Address range: 0x00_6000-0x00_7FFF; protected size: 8 KB
; <o.5> FPLDIS
; <0=> Protection/Unprotection enabled
; <1=> Protection/Unprotection disabled
; <o.3..4> FPLS
; <0=> Address range: 0x00_0000-0x00_07FF; protected size: 2 KB
; <1=> Address range: 0x00_0000-0x00_0FFF; protected size: 4 KB
; <2=> Address range: 0x00_0000-0x00_1FFF; protected size: 8 KB
; <3=> Address range: 0x00_0000-0x00_3FFF; protected size: 16 KB
FPROT EQU 0xFF
; </h>
; </h>
; <h> Flash security byte (FSEC)
; <i> WARNING: If SEC field is configured as "MCU security status is secure" and MEEN field is configured as "Mass erase is disabled",
; <i> MCU's security status cannot be set back to unsecure state since Mass erase via the debugger is blocked !!!
; <o.0..1> SEC
; <2=> MCU security status is unsecure
; <3=> MCU security status is secure
; <i> Flash Security
; <i> This bits define the security state of the MCU.
; <o.6..7> KEYEN
; <2=> Backdoor key access enabled
; <3=> Backdoor key access disabled
; <i> Backdoor key Security Enable
; <i> These bits enable and disable backdoor key access to the FTFL module.
FSEC EQU 0xFE
; </h>
; <h> Flash Option Register (FOPT)
FOPT EQU 0xFE
; </h>
IF :LNOT::DEF:RAM_TARGET
AREA |.ARM.__at_0x400|, CODE, READONLY
DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3
DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7
DCB 0xFF, 0xFF, 0xFF, 0xFF
DCB EEPROT, FPROT, FSEC, FOPT ;Modified by ARM. DCB FPROT, EEPROT, FOPT, FSEC
ENDIF
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT Reserved16_IRQHandler [WEAK]
EXPORT Reserved17_IRQHandler [WEAK]
EXPORT Reserved18_IRQHandler [WEAK]
EXPORT Reserved19_IRQHandler [WEAK]
EXPORT Reserved20_IRQHandler [WEAK]
EXPORT ETMRH_IRQHandler [WEAK]
EXPORT LVD_LVW_IRQHandler [WEAK]
EXPORT IRQ_IRQHandler [WEAK]
EXPORT I2C0_IRQHandler [WEAK]
EXPORT Reserved25_IRQHandler [WEAK]
EXPORT SPI0_IRQHandler [WEAK]
EXPORT SPI1_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT UART2_IRQHandler [WEAK]
EXPORT ADC0_IRQHandler [WEAK]
EXPORT ACMP0_IRQHandler [WEAK]
EXPORT ETM0_IRQHandler [WEAK]
EXPORT ETM1_IRQHandler [WEAK]
EXPORT ETM2_IRQHandler [WEAK]
EXPORT RTC_IRQHandler [WEAK]
EXPORT ACMP1_IRQHandler [WEAK]
EXPORT PIT_CH0_IRQHandler [WEAK]
EXPORT PIT_CH1_IRQHandler [WEAK]
EXPORT KBI0_IRQHandler [WEAK]
EXPORT KBI1_IRQHandler [WEAK]
EXPORT Reserved42_IRQHandler [WEAK]
EXPORT ICS_IRQHandler [WEAK]
EXPORT Watchdog_IRQHandler [WEAK]
EXPORT Reserved45_IRQHandler [WEAK]
EXPORT Reserved46_IRQHandler [WEAK]
EXPORT Reserved47_IRQHandler [WEAK]
EXPORT DefaultISR [WEAK]
Reserved16_IRQHandler
Reserved17_IRQHandler
Reserved18_IRQHandler
Reserved19_IRQHandler
Reserved20_IRQHandler
ETMRH_IRQHandler
LVD_LVW_IRQHandler
IRQ_IRQHandler
I2C0_IRQHandler
Reserved25_IRQHandler
SPI0_IRQHandler
SPI1_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
ADC0_IRQHandler
ACMP0_IRQHandler
ETM0_IRQHandler
ETM1_IRQHandler
ETM2_IRQHandler
RTC_IRQHandler
ACMP1_IRQHandler
PIT_CH0_IRQHandler
PIT_CH1_IRQHandler
KBI0_IRQHandler
KBI1_IRQHandler
Reserved42_IRQHandler
ICS_IRQHandler
Watchdog_IRQHandler
Reserved45_IRQHandler
Reserved46_IRQHandler
Reserved47_IRQHandler
DefaultISR
B .
ENDP
ALIGN
; User Initial Stack & Heap
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END
@@ -0,0 +1,257 @@
/*****************************************************************************
* @brief provide system init routine/configuration for NV32Fxx.
*
*******************************************************************************/
#include "common.h"
#include "sysinit.h"
#include "sim.h"
#include "uart.h"
#include "ics.h"
/********************************************************************/
uint16_t global_pass_count = 0;
uint16_t global_fail_count = 0;
void print_sys_log(void);
void UART_InitPrint(void);
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: sysinit
*
* @brief initalize system including SIM, ICS, UART, etc
*
* @param none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void sysinit (void)
{
SIM_ConfigType sSIMConfig = {{0},0};
ICS_ConfigType sICSConfig = {0};
/* initialize the Pass/Fail counts to 0 */
global_pass_count = 0;
global_fail_count = 0;
EFMCR &=0xFFFF0001; // set wait state 1
#if defined(TRIM_IRC)
/* if not trimmed, do trim first */
ICS_Trim(ICS_TRIM_VALUE);
#endif
/*
* Enable SWD pin, RESET pin
*/
/*
* NOTE: please make sure other register bits are also write-once and
* need add other bit mask here if needed.
*/
#if defined(SPI0_PINREMAP)
sSIMConfig.u32PinSel |= SIM_PINSEL_SPI0PS_MASK;
#endif
#if defined(OUTPUT_BUSCLK)
sSIMConfig.sBits.bEnableCLKOUT = 1; /* output bus clock if enabled */
#endif
#if defined(DISABLE_NMI)
sSIMConfig.sBits.bDisableNMI = 1;
#endif
/* make sure clocks to peripheral modules are enabled */
sSIMConfig.u32SCGC |= SIM_SCGC_SWD_MASK | SIM_SCGC_FLASH_MASK |
SIM_SCGC_UART0_MASK | SIM_SCGC_UART1_MASK |
SIM_SCGC_UART2_MASK;
sSIMConfig.sBits.bBusDiv |= BUSDIV_ENCODE;
SIM_Init(&sSIMConfig); /* initialize SIM */
#if defined(XOSC_STOP_ENABLE)
sICSConfig.oscConfig.bStopEnable = 1; /* enabled in stop mode */
#endif
#if defined(CRYST_HIGH_GAIN)
sICSConfig.oscConfig.bGain = 1; /* high gain */
#endif
#if (EXT_CLK_FREQ_KHZ >=4000)
sICSConfig.oscConfig.bRange = 1; /* high range */
#endif
sICSConfig.oscConfig.bEnable = 1; /* enable OSC */
sICSConfig.u32ClkFreq = EXT_CLK_FREQ_KHZ;
#if defined(USE_FEE)
sICSConfig.u8ClkMode = ICS_CLK_MODE_FEE;
#elif defined(USE_FBE_OSC)
sICSConfig.u8ClkMode = ICS_CLK_MODE_FBE_OSC;
#elif defined(USE_FEE_OSC)
sICSConfig.u8ClkMode = ICS_CLK_MODE_FEE_OSC;
#elif defined(USE_FBILP)
sICSConfig.u8ClkMode = ICS_CLK_MODE_FBILP;
#elif defined(USE_FBELP)
sICSConfig.u8ClkMode = ICS_CLK_MODE_FBELP;
#endif
ICS_Init(&sICSConfig); /* initialize ICS */
/* initialize UART for printing */
//UART_InitPrint();
#if defined(PRINT_SYS_LOG)
//print_sys_log();
#endif
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: print_sys_log
*
* @brief print system reset sources
*
* @param none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void print_sys_log(void)
{
uint8_t u8Rst = 0;
uint8_t u8FamID,u8SubFamID,u8RevID,u8PinID;
uint32_t u32Status;
u32Status = SIM_GetStatus(0xFF); /* get all status bits */
/* get all IDs */
u8FamID = SIM_ReadID(ID_TYPE_FAMID);
u8SubFamID = SIM_ReadID(ID_TYPE_SUBFAMID);
u8RevID = SIM_ReadID(ID_TYPE_REVID);
u8PinID = SIM_ReadID(ID_TYPE_PINID);
printf("\n\n--System Log BEGINS--\n\n");
printf("\n Familly ID = 0x%x, Sub-family ID = 0x%x, Revision ID = 0x%x, Pin ID = 0x%x \n",
u8FamID, u8SubFamID, u8RevID, u8PinID);
if((u32Status & SIM_SRSID_POR_MASK) && (u32Status & SIM_SRSID_LVD_MASK))
{
u8Rst = 1;
printf(" Power On Reset\n");
}
if(!(u32Status & SIM_SRSID_POR_MASK) && (u32Status & SIM_SRSID_LVD_MASK))
{
u8Rst = 1;
printf(" LVD Reset\n");
}
if(u32Status & SIM_SRSID_WDOG_MASK)
{
u8Rst = 1;
printf(" WDOG Reset\n");
}
if(u32Status & SIM_SRSID_PIN_MASK)
{
u8Rst = 1;
printf(" Pin Reset\n");
}
if(u32Status & SIM_SRSID_LOC_MASK)
{
u8Rst = 1;
printf(" Loss of Clock Reset\n");
}
if(u32Status & SIM_SRSID_SACKERR_MASK)
{
u8Rst = 1;
printf(" Stop Mode Acknowledge Error Reset\n");
}
if(u32Status & SIM_SRSID_MDMAP_MASK)
{
u8Rst = 1;
printf(" MDM-AP System Reset Request\n");
}
if(u32Status & SIM_SRSID_SW_MASK)
{
u8Rst = 1;
printf(" Software/SYSRESETREQ Reset\n");
}
if(u32Status & SIM_SRSID_LOCKUP_MASK)
{
u8Rst = 1;
printf(" Core lockup Reset\n");
}
if(u8Rst != 1)
{
printf("SWD Reset\n");
}
printf("\n--System Log ENDS--\n\n");
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: end_test
*
* @brief print test result (pass/fail counts) after end of test
*
* @param none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void end_test(void)
{
if(global_fail_count==0){
printf("\n global_pass_count = 0x%02x%02x",(uint8)(global_pass_count>>8),(uint8)global_pass_count);
printf("\n\n TEST PASSED");
} else{
printf("\n global_pass_count = 0x%02x%02x",(uint8)(global_pass_count>>8),(uint8)global_pass_count);
printf("\n global_fail_count = 0x%02x%02x",(uint8)(global_fail_count>>8),(uint8)global_fail_count);
printf("\n\n TEST FAILED");
}
printf("\n\n TEST FINISHED");
}
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: UART_InitPrint
*
* @brief initialize UART for print on port defined by TERM_PORT.
*
* @param none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void UART_InitPrint(void)
{
UART_ConfigType sConfig;
sConfig.u32SysClkHz = BUS_CLK_HZ;
sConfig.u32Baudrate = UART_PRINT_BITRATE;
SIM_RemapUART0Pin();
UART_Init (TERM_PORT, &sConfig);
}
@@ -0,0 +1,38 @@
/******************************************************************************
* @brief provide system init routine/configuration for KExx.
*
*******************************************************************************/
/********************************************************************/
#ifndef SYSINIT_H_
#define SYSINIT_H_
/******************************************************************************
* Includes
******************************************************************************/
/******************************************************************************
* Constants
******************************************************************************/
/******************************************************************************
* Macros
******************************************************************************/
#define SIM_SCGC_VALUE 0x00003000L
/******************************************************************************
* Global variables
******************************************************************************/
/******************************************************************************
* Global functions
******************************************************************************/
void sysinit (void);
void enable_abort_button(void);
void end_test(void);
/********************************************************************/
#endif /* SYSINIT_H_ */
@@ -0,0 +1,51 @@
/*
** ###################################################################
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef SYSTEM_MKE02Z2_H_
#define SYSTEM_MKE02Z2_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit (void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* #if !defined(SYSTEM_MKE02Z2_H_) */
@@ -0,0 +1,89 @@
/******************************************************************************
*
* @brief provide systick utility routines.
*
*******************************************************************************/
#include "common.h"
#include "systick.h"
//#include "stdint.h"
uint32_t cnt_start_value;
uint32_t cnt_end_value;
uint32_t overhead;
SysTick_CallbackType SysTick_Callback[1] = {NULL};
#if 0
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
#endif
void systick_init(void)
{
SysTick->VAL = 0x0; /* clear current ETMer value */
SysTick->LOAD = 0x00FFFFFF;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}
void SysTick_SetCallBack(SysTick_CallbackType pSysTick_CallBack)
{
SysTick_Callback[0] = pSysTick_CallBack;
}
/***
void delay_us(int n)//微秒级别的延时
{
int temp;
SysTick->LOAD= 48 *n; //????
SysTick->VAL=0x00000000; //?????
SysTick->CTRL=0x00000005;
while(SysTick->CTRL&0x00010000); //????
SysTick->CTRL=0x00000004;
}
***/
/****
void delay_ms(int n)//毫秒级别的延时
{
int temp;
SysTick->LOAD= 48000 *n; //????
SysTick->VAL=0x00000000; //?????
SysTick->CTRL=0x00000005;
while(SysTick->CTRL&0x00010000); //????
SysTick->CTRL=0x00000004;
}******////
void systick_disable(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
void cal_systick_read_overhead(void)
{
uint32_t cnt_start_value;
uint32_t cnt_end_value;
cnt_start_value = SysTick->VAL;
cnt_end_value = SysTick->VAL;
overhead = cnt_start_value - cnt_end_value;
#ifdef DEBUG_PRINT
printf("systick start value: 0x%x\n\r", (unsigned int)cnt_start_value);
printf("systick end value: 0x%x\n\r", (unsigned int) cnt_end_value);
printf("systick current value read overhead: 0x%x\n\r", (unsigned int)overhead);
#endif
}
void SysTick_Isr(void)
{
//printf("input any character to start a new conversion!\n");
if( SysTick_Callback[0] )
{
SysTick_Callback[0]();
}
}
@@ -0,0 +1,25 @@
/******************************************************************************
* @brief provide systick utility routines.
*
*******************************************************************************/
#ifndef __SYSTICK_H
#define __SYSTICK_H
typedef void (*SysTick_CallbackType)(void);
#define SYS_COUNT_ETME 10 //ms
#define SYS_COUNT MCU_CLCOK*SYS_COUNT_ETME/16
/* Global variables */
extern uint32_t cnt_start_value;
extern uint32_t cnt_end_value;
extern uint32_t overhead;
void SysTick_SetCallBack(SysTick_CallbackType pSysTick_CallBack);
/* Function declaration */
void systick_init(void);
void systick_disable(void);
void cal_systick_read_overhead(void);
//void delay_us(int n);
//void delay_ms(int n);
void SysTick_SetCallBack(SysTick_CallbackType pSysTick_CallBack);
#endif
@@ -0,0 +1,171 @@
/******************************************************************************
*
* @brief provide interrupt vector table for NV32Fxxx.
*
*******************************************************************************/
#include "vectors.h"
#include "isr.h"
#include "common.h"
/******************************************************************************
* Vector Table
******************************************************************************/
typedef void (*vector_entry)(void);
#ifdef KEIL
const vector_entry __vector_table[] __attribute__((at(0x00))) =
#elif (defined(__GNUC__))
//void (* const __vector_table[])() __attribute__ ((section(".vectortable"))) =
void (* const InterruptVector[])() __attribute__ ((section(".isr_vector"))) =
#else
#pragma location = ".intvec"
const vector_entry __vector_table[] = //@ ".intvec" =
#endif
{
VECTOR_000, /* Initial SP */
VECTOR_001, /* Initial PC */
VECTOR_002,
VECTOR_003,
VECTOR_004,
VECTOR_005,
VECTOR_006,
VECTOR_007,
VECTOR_008,
VECTOR_009,
VECTOR_010,
VECTOR_011,
VECTOR_012,
VECTOR_013,
VECTOR_014,
VECTOR_015,
VECTOR_016,
VECTOR_017,
VECTOR_018,
VECTOR_019,
VECTOR_020,
VECTOR_021,
VECTOR_022,
VECTOR_023,
VECTOR_024,
VECTOR_025,
VECTOR_026,
VECTOR_027,
VECTOR_028,
VECTOR_029,
VECTOR_030,
VECTOR_031,
VECTOR_032,
VECTOR_033,
VECTOR_034,
VECTOR_035,
VECTOR_036,
VECTOR_037,
VECTOR_038,
VECTOR_039,
VECTOR_040,
VECTOR_041,
VECTOR_042,
VECTOR_043,
VECTOR_044,
VECTOR_045,
VECTOR_046,
VECTOR_047 // END of real vector table
};
// VECTOR_TABLE end
#ifndef KEIL
#ifndef USE_BOOTLOADER
#ifdef KEIL
const uint32_t __flash_config[] __attribute__((at(0x400))) =
#elif (defined(__GNUC__))
const uint32_t __flash_config[] __attribute__ ((section(".nv32_flash_config_field"))) =
#else
#pragma location = 0x400
__root const uint32_t __flash_config[] = //@ ".intvec" =
#endif
{
CONFIG_1,
CONFIG_2,
CONFIG_3,
CONFIG_4,
};
#endif
#endif
/******************************************************************************
* default_isr(void)
*
* Default ISR definition.
*
* In: n/a
* Out: n/a
******************************************************************************/
void default_isr(void)
{
#define VECTORNUM (*(volatile uint32_t*)(0xE000ED04))
printf("\n****default_isr entered on vector %lu*****\r\n\n",VECTORNUM);
return;
}
/******************************************************************************/
/* Generic interrupt handler for a GPIO interrupt connected to an
* abort switch.
* NOTE: For true abort operation this handler should be modified
* to jump to the main process instead of executing a return.
*/
void abort_isr(void)
{
//printf("\n****Abort button interrupt****\n\n");
return;
}
/******************************************************************************/
/* Exception frame without floating-point storage
* hard fault handler in C,
* with stack frame location as input parameter
*/
void
hard_fault_handler_c(unsigned int * hardfault_args)
{
/*
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
//Exception stack frame
stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);
stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);
printf ("[Hard fault handler]\n");
printf ("R0 = %x\n", stacked_r0);
printf ("R1 = %x\n", stacked_r1);
printf ("R2 = %x\n", stacked_r2);
printf ("R3 = %x\n", stacked_r3);
printf ("R12 = %x\n", stacked_r12);
printf ("LR = %x\n", stacked_lr);
printf ("PC = %x\n", stacked_pc);
printf ("PSR = %x\n", stacked_psr);
printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
*/
//for(;;)
//;/*infinite loop*/
}
/* End of "vectors.c" */
@@ -0,0 +1,146 @@
/******************************************************************************
* @brief provide interrupt vector table for NV32Fxxx
*
*******************************************************************************/
#ifndef __VECTORS_H
#define __VECTORS_H 1
// function prototype for default_isr in vectors.c
void default_isr(void);
void abort_isr(void);
void hard_fault_handler_c(unsigned int * hardfault_args);
/* Interrupt Vector Table Function Pointers */
typedef void pointer(void);
extern void __startup(void);
extern unsigned long __BOOT_STACK_ADDRESS[];
extern unsigned long __initial_sp[];
extern void Reset_Handler( void );
#if (defined(__GNUC__))
extern unsigned long _estack;
extern void Reset_Handler(void);
#define VECTOR_000 (pointer*)&_estack // ARM core Initial Supervisor SP
#define VECTOR_001 Reset_Handler // 0x0000_0004 1 - ARM core Initial Program Counter
#elif (defined(KEIL))
#define VECTOR_000 (pointer*)__initial_sp // ARM core Initial Supervisor SP
#define VECTOR_001 Reset_Handler // 0x0000_0004 1 - ARM core Initial Program Counter
#else
// Address Vector IRQ Source module Source description
#define VECTOR_000 (pointer*)__BOOT_STACK_ADDRESS // ARM core Initial Supervisor SP
#define VECTOR_001 __startup // 0x0000_0004 1 - ARM core Initial Program Counter
#endif
#define VECTOR_002 default_isr // 0x0000_0008 2 - ARM core Non-maskable Interrupt (NMI)
#define VECTOR_003 default_isr // 0x0000_000C 3 - ARM core Hard Fault
#define VECTOR_004 default_isr // 0x0000_0010 4 -
#define VECTOR_005 default_isr // 0x0000_0014 5 - ARM core Bus Fault
#define VECTOR_006 default_isr // 0x0000_0018 6 - ARM core Usage Fault
#define VECTOR_007 default_isr // 0x0000_001C 7 -
#define VECTOR_008 default_isr // 0x0000_0020 8 -
#define VECTOR_009 default_isr // 0x0000_0024 9 -
#define VECTOR_010 default_isr // 0x0000_0028 10 -
#define VECTOR_011 default_isr // 0x0000_002C 11 - ARM core Supervisor call (SVCall)
#define VECTOR_012 default_isr // 0x0000_0030 12 - ARM core Debug Monitor
#define VECTOR_013 default_isr // 0x0000_0034 13 -
#define VECTOR_014 default_isr // 0x0000_0038 14 - ARM core Pendable request for system service (PendableSrvReq)
#define VECTOR_015 default_isr // 0x0000_003C 15 - ARM core System tick ETMer (SysTick)
#define VECTOR_016 default_isr // 0x0000_0040 16 0 Reserved DMA DMA Channel 0 transfer complete
#define VECTOR_017 default_isr // 0x0000_0044 17 1 Reserved DMA DMA Channel 1 transfer complete
#define VECTOR_018 default_isr // 0x0000_0048 18 2 Reserved DMA DMA Channel 2 transfer complete
#define VECTOR_019 default_isr // 0x0000_004C 19 3 Reserved DMA DMA Channel 3 transfer complete
#define VECTOR_020 default_isr // 0x0000_0050 20 4 Reserved MCM MCM
#define VECTOR_021 default_isr // 0x0000_0054 21 5 NVM ETMRH flash memory command complete,ECC fault
#define VECTOR_022 default_isr // 0x0000_0058 22 6 PMC LVD,LVW interrupt
#define VECTOR_023 default_isr // 0x0000_005C 23 7 LLWU LLWU/IRQ
#define VECTOR_024 default_isr // 0x0000_0060 24 8 I2C0 I2C
#define VECTOR_025 default_isr // 0x0000_0064 25 9 - --
#define VECTOR_026 default_isr // 0x0000_0068 26 10 SPI0 SPI0
#define VECTOR_027 default_isr // 0x0000_006C 27 11 SPI1 SPI1
#define VECTOR_028 default_isr // 0x0000_0070 28 12 SCI0 UART0
#define VECTOR_029 default_isr // 0x0000_0074 29 13 SCI1 UART1
#define VECTOR_030 default_isr // 0x0000_0078 30 14 SCI2 UART2
#define VECTOR_031 default_isr // 0x0000_007C 31 15 ADC0 ADC conversion complete
#define VECTOR_032 default_isr // 0x0000_0080 32 16 ACMP0 ACMP0
#define VECTOR_033 default_isr // 0x0000_0084 33 17 ETM0 FlexETMer0
#define VECTOR_034 default_isr // 0x0000_0088 34 18 ETM1 FlexETMer1
#define VECTOR_035 default_isr // 0x0000_008C 35 19 ETM2 FlexETMer2
#define VECTOR_036 default_isr // 0x0000_0090 36 20 RTC RTC overflow
#define VECTOR_037 default_isr // 0x0000_0094 37 21 ACMP1 ACMP1
#define VECTOR_038 default_isr // 0x0000_0098 38 22 PIT_CH0 PIT_CH0 overflow
#define VECTOR_039 default_isr // 0x0000_009C 39 23 PIT_CH1 PIT_CH1 overflow
#define VECTOR_040 default_isr // 0x0000_00A0 40 24 KBI0 Keyboard0 interrupt
#define VECTOR_041 default_isr // 0x0000_00A4 41 25 KBI1 Keyboard1 interrupt
#define VECTOR_042 default_isr // 0x0000_00A8 42 26 Reserved ---
#define VECTOR_043 default_isr // 0x0000_00AC 43 27 ICS ICS loss of lock
#define VECTOR_044 default_isr // 0x0000_00B0 44 28 WDOG Watchdog ETMeout
#define VECTOR_045 default_isr // 0x0000_00B4 45 29 Reserved
#define VECTOR_046 default_isr // 0x0000_00B8 46 30 Reserved
#define VECTOR_047 default_isr // 0x0000_00BC 47 31 Reserved // END of real vector table
/********************************************************************************************************************/
#define VECTOR_048 default_isr // 0x0000_00C0 48 32 Reserved
#define VECTOR_049 default_isr // 0x0000_00C4 49 33 Reserved
#define VECTOR_050 default_isr // 0x0000_00C8 50 34 Reserved
#define VECTOR_051 default_isr // 0x0000_00CC 51 35 Reserved
#define VECTOR_052 default_isr // 0x0000_00D0 52 36 Reserved
#define VECTOR_053 default_isr // 0x0000_00D4 53 37 Reserved
#define VECTOR_054 default_isr // 0x0000_00D8 54 38 Reserved
#define VECTOR_055 default_isr // 0x0000_00DC 55 39 Reserved
#define VECTOR_056 default_isr // 0x0000_00E0 56 40 Reserved
#define VECTOR_057 default_isr // 0x0000_00E4 57 41 Reserved
#define VECTOR_058 default_isr // 0x0000_00E8 58 42 Reserved
#define VECTOR_059 default_isr // 0x0000_00EC 59 43 Reserved
#define VECTOR_060 default_isr // 0x0000_00F0 60 44 Reserved
#define VECTOR_061 default_isr // 0x0000_00F4 61 45 Reserved Single interrupt vector for SCI status sources
#define VECTOR_062 default_isr // 0x0000_00F8 62 46 Reserved Single interrupt vector for SCI error sources
#define VECTOR_063 default_isr // 0x0000_00FC 63 47 Reserved Single interrupt vector for SCI status sources
#define VECTOR_064 default_isr // 0x0000_0100 64 48 Reserved Single interrupt vector for SCI error sources
#define VECTOR_065 default_isr // 0x0000_0104 65 49 Reserved Single interrupt vector for SCI status sources
#define VECTOR_066 default_isr // 0x0000_0108 66 50 Reserved Single interrupt vector for SCI error sources
#define VECTOR_067 default_isr // 0x0000_010C 67 51 Reserved Single interrupt vector for SCI status sources
#define VECTOR_068 default_isr // 0x0000_0110 68 52 Reserved Single interrupt vector for SCI error sources
#define VECTOR_069 default_isr // 0x0000_0114 69 53 Reserved Single interrupt vector for SCI status sources
#define VECTOR_070 default_isr // 0x0000_0118 70 54 Reserved Single interrupt vector for SCI error sources
#define VECTOR_071 default_isr // 0x0000_011C 71 55 Reserved Single interrupt vector for SCI status sources
#define VECTOR_072 default_isr // 0x0000_0120 72 56 Reserved Single interrupt vector for SCI error sources
#define VECTOR_073 default_isr // 0x0000_0124 73 57 Reserved
#define VECTOR_074 default_isr // 0x0000_0128 74 58 Reserved
#define VECTOR_075 default_isr // 0x0000_012C 75 59 Reserved
#define VECTOR_076 default_isr // 0x0000_0130 76 60 Reserved
#define VECTOR_077 default_isr // 0x0000_0134 77 61 Reserved
#define VECTOR_078 default_isr // 0x0000_0138 78 62 Reserved Single interrupt vector for all sources
#define VECTOR_079 default_isr // 0x0000_013C 79 63 Reserved Single interrupt vector for all sources
#define VECTOR_080 default_isr // 0x0000_0140 80 64 Reserved Single interrupt vector for all sources
#define VECTOR_081 default_isr // 0x0000_0144 81 65 Reserved
#define VECTOR_082 default_isr // 0x0000_0148 82 66 Reserved
#define VECTOR_083 default_isr // 0x0000_014C 83 67
#define VECTOR_084 default_isr // 0x0000_0150 84 68
#define VECTOR_085 default_isr // 0x0000_0154 85 69
#define VECTOR_086 default_isr // 0x0000_0158 86 70
#define VECTOR_087 default_isr // 0x0000_015C 87 71
#define VECTOR_088 default_isr // 0x0000_0160 88 72
#define VECTOR_089 default_isr // 0x0000_0164 89 73
#define VECTOR_090 default_isr // 0x0000_0168 90 74
#define VECTOR_091 default_isr // 0x0000_016C 91 75
#define VECTOR_092 default_isr // 0x0000_0170 92 76
#define VECTOR_093 default_isr // 0x0000_0174 93 77
#define VECTOR_094 default_isr // 0x0000_0178 94 78
#define VECTOR_095 default_isr // 0x0000_017C 95 79
#define VECTOR_096 default_isr // 0x0000_0180 96 80
#define VECTOR_097 default_isr // 0x0000_0184 97 81
#define VECTOR_098 default_isr // 0x0000_0188 98 82
#define VECTOR_099 default_isr // 0x0000_018C 99 83
#ifdef USE_BOOTLOADER
#else
#define CONFIG_1 0xffffffff
#define CONFIG_2 0xffffffff
#define CONFIG_3 0xffffffff
#define CONFIG_4 0xfffeffff
#endif
#endif /*__VECTORS_H*/
/* End of "vectors.h" */
@@ -0,0 +1,11 @@
lemcu.org GPL Exception version 1.0
-----------------------------------
As an additional permission, if Lemcusb library is statically linked with one or more of the following
software libraries, then, these software libraries are not subjected to the TERMS AND CONDITIONS of
GNU General Public License version 3.0.
(1) Silicon Laboratories Inc's "emlib", "emdrv", any software supplied as part of application note and/or examples.
(2) ARM Limited's "CMSIS".
They are bound by their own terms and conditions as specified by their authors.
@@ -0,0 +1,681 @@
The Lemcusb is Copyright (C) 2014 http://lemcu.org
You may use, distribute and copy the Lemcusb under the terms of
GNU General Public License version 3.0, which is displayed below.
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
@@ -0,0 +1,35 @@
/****************************************************************************
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef __C_COMPAT_H__
#define __C_COMPAT_H__
#if defined ( __ICCARM__ )
#define RAMFUNC __ramfunc
#else
#define RAMFUNC __attribute__((__long_call__)) __attribute__((section(".functioninRAM"))) __attribute__ ((noinline))
#endif
#endif
@@ -0,0 +1,381 @@
/****************************************************************************
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "usb.h"
//#include "em_device.h"
//#include "em_cmu.h"
//#include "em_int.h"
//#include "em_timer.h"
#include "gpio.h"
#include "usb_internal_ll.h"
#include "usb_stack.h"
#include "usb_helperfunctions.h"
void usb_reset_received(void)
{
uint32_t cnt;
uint32_t *ptr;
GPIOA->PSOR = (1<<1);
/* zero intitialize endpoint buffers and len/status fields */
ptr = (uint32_t *)usb_ep_buffers;
for (cnt=0; cnt < (sizeof(usb_ep_buffers)>>2); cnt++)
{
*ptr++ = 0;
}
/* preinitialize DATA PIDS for IN endpoints */
usb_ep_buffers[USB_EPBUF_OFFSET_EP0IN_BUF] = 0x4B;
usb_ep_buffers[USB_EPBUF_OFFSET_EP1IN_BUF] = 0x4B;
/* reset usb device address to 0 (will be changed during enumeration) */
usbstack_init();
GPIOA->PSOR = (1<<1);
}
/*
* Pinout information:
* PA2 = D-
* PA3 = D+
* PA1 = debug output (to scope)
*/
/*
* Pre-condition: GPIO clock enabled
*
*/
void usb_init(void)
{
usb_reset_received();
/* Pinout: PA1 = USB connect line (1k5 resistor to PC0)
PA2 = D-
PA3 = D+
*/
/* set PA0 low (disconnected) Will enable the pulldown */
GPIOA->PCOR = (1 << 2);
/* Pin PA0 is configured to Input enabled with pull-down */
//GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | GPIO_P_MODEL_MODE0_INPUTPULL;
/* Pin PC0 is configured to Input enabled */
//GPIO->P[2].MODEL = (GPIO->P[2].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | GPIO_P_MODEL_MODE0_INPUT;
/* Pin PC1 is configured to Input enabled */
// GPIO->P[2].MODEL = (GPIO->P[2].MODEL & ~_GPIO_P_MODEL_MODE1_MASK) | GPIO_P_MODEL_MODE1_INPUT;
/* set output state of PC0 PC1 (D- D+) to 1 0 */
GPIOA->PSOR = (1<<2); /* D- = 1 */
GPIOA->PCOR = (1<<3); /* D+ = 0 */
/* Pin PE13 is configured to Push-pull */
//GPIO->P[4].MODEH = (GPIO->P[4].MODEH & ~_GPIO_P_MODEH_MODE13_MASK) | GPIO_P_MODEH_MODE13_PUSHPULL;
/* setup PC1 interrupt on rising edge (D+ first SYNC bit) */
/* Configure PC1 interrupt on rising edge */
// GPIO_IntConfig(gpioPortC, 1, true, false, true);
/* Set Interrupt priority to highest */
// NVIC_SetPriority(GPIO_ODD_IRQn, 0);
/* Enable GPIO_EVEN interrupt vector in NVIC */
// NVIC_EnableIRQ(GPIO_ODD_IRQn);
}
void usb_connect(void)
{
GPIOA->PSOR = (1 << 3);
//GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | GPIO_P_MODEL_MODE0_PUSHPULL;
}
void usb_disconnect(void)
{
/* Pin PA0 is configured to Input enabled with pull-down */
// GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | GPIO_P_MODEL_MODE0_INPUTPULL;
/* set PA0 low (disconnected) Will enable the pulldown */
GPIOA->PCOR = (1 << 3);
}
bool usb_check_resetcondition(void)
{
return ( (GPIOA->PDIR & 0x00000006) == 0x00 );
}
/* check if a setup packet was received */
bool usb_setup_available(void)
{
return (usb_ep_buffers[USB_EPBUF_OFFSET_SETUP_BUF + USB_EPBUF_SUBOFFSET_STAT] & (1 << 0)) != 0x00;
}
/* IDEA: The reordering / Bitreversal can be done in place to save some RAM */
void usb_setup_get_data(setupData_t *psetupdata)
{
uint32_t i, j;
uint8_t dat;
uint8_t setupdat[8];
volatile uint8_t *SETUP_BUF;
SETUP_BUF = &usb_ep_buffers[USB_EPBUF_OFFSET_SETUP_BUF];
for (i=0; i<8; i++) /* walk through all bytes */
{
j = i+1;
j = (j & 0xfC) | (3-(j & 0x03)); /* reverse byteorder => TODO: This can be done in the .s file using the REV instruction (single cycle) */
dat = SETUP_BUF[j];
dat = bitreverse(dat); /* reverse bits*/
setupdat[i] = dat; /* store data */
}
usb_ep_buffers[USB_EPBUF_OFFSET_SETUP_BUF + USB_EPBUF_SUBOFFSET_STAT] &= ~(1 << 0); /* flag setup data as empty */
psetupdata->bmRequestType = setupdat[0];
psetupdata->bRequest = setupdat[1];
psetupdata->wValue = setupdat[2];
psetupdata->wValue |= setupdat[3] << 8;
psetupdata->wIndex = setupdat[4];
psetupdata->wIndex |= setupdat[5] << 8;
psetupdata->wLength = setupdat[6];
psetupdata->wLength |= setupdat[7] << 8;
}
bool usb_ep_in_buf_empty(uint32_t epnum)
{
if (epnum)
{
return (usb_ep_buffers[USB_EPBUF_OFFSET_EP1IN_BUF + USB_EPBUF_SUBOFFSET_STAT] & (1 << 0)) == 0x00;
}
else
{
return (usb_ep_buffers[USB_EPBUF_OFFSET_EP0IN_BUF + USB_EPBUF_SUBOFFSET_STAT] & (1 << 0)) == 0x00;
}
}
/* TODO/IDEA: check parameters like len. This can be done e.g. with ASSERTIONS, so
* that checks can be disabled later to save time & space
*/
void usb_ep_in_commit_pkt(uint32_t epnum, bool firstpkt, const uint8_t *pbuf, uint32_t len)
{
uint32_t i;
uint8_t dat;
uint16_t crc_value;
volatile uint8_t *EP0IN_BUF;
if (!len)
{
GPIOA->PSOR = (1<<8);
GPIOA->PCOR = (1<<8);
}
if (epnum)
{
EP0IN_BUF = &usb_ep_buffers[USB_EPBUF_OFFSET_EP1IN_BUF];
}
else
{
EP0IN_BUF = &usb_ep_buffers[USB_EPBUF_OFFSET_EP0IN_BUF];
}
if (firstpkt)
{
EP0IN_BUF[0] = 0x4B; /* first IN packet is always transmitted with DATA1 PID */
}
else
{
EP0IN_BUF[0] ^= 0x88; /* Following packets toggle between DATA0 and DATA1 PID */
}
crc_value = 0xffff;
for (i=0; i<len; i++)
{
dat = *pbuf++;
EP0IN_BUF[i+1] = dat;
crc_value = crc16(crc_value, dat);
}
crc_value = ~crc_value; /* this is described in the USB spec. */
/* ADD CRC */
EP0IN_BUF[1+len+0] = crc_value & 0xff; /* CRC low */
EP0IN_BUF[1+len+1] = crc_value >> 8; /* CRC high */
/* set packet length */
EP0IN_BUF[USB_EPBUF_SUBOFFSET_LEN] = len + 1 +2; /* DATAx PID + CRC16 */
/* Flag endpoint as "ready" for transmission. This needs to be done as the last step */
EP0IN_BUF[USB_EPBUF_SUBOFFSET_STAT] |= (1 << 0);
}
bool usb_ep_out_data_available(uint32_t epnum)
{
if (epnum == 0x00)
{
return (usb_ep_buffers[USB_EPBUF_OFFSET_EP0OUT_BUF + USB_EPBUF_SUBOFFSET_STAT] & (1 << 0)) != 0x00;
}
else
{
return (usb_ep_buffers[USB_EPBUF_OFFSET_EP1OUT_BUF + USB_EPBUF_SUBOFFSET_STAT] & (1 << 0)) != 0x00;
}
}
uint32_t usb_ep_out_get_data(uint32_t epnum, uint8_t *pbuf)
{
uint32_t i, j, len;
uint8_t dat, bytecount;
volatile uint8_t *EP0OUT_BUF;
if (epnum == 0)
{
EP0OUT_BUF = &usb_ep_buffers[USB_EPBUF_OFFSET_EP0OUT_BUF];
}
else
{
EP0OUT_BUF = &usb_ep_buffers[USB_EPBUF_OFFSET_EP1OUT_BUF];
}
len = EP0OUT_BUF[USB_EPBUF_SUBOFFSET_LEN];
bytecount = ((len + 7) >> 3) - 1 - 2; /* -PID -CRC16 */
for (i=0; i<bytecount; i++) /* walk through all bytes */
{
j = i+1;
j = (j & 0xfC) | (3-(j & 0x03)); /* reverse byteorder => TODO: This can be done in the .s file using the REV instruction (single cycle) */
dat = EP0OUT_BUF[j];
dat = bitreverse(dat); /* reverse bits*/
*pbuf++ = dat; /* store data */
}
//bytecount = 0;
if (bytecount > 0)
{
volatile int i;
i=0;
}
/* flag endpoint as empty. Needs to be done as last step */
EP0OUT_BUF[USB_EPBUF_SUBOFFSET_STAT] &= ~(1 << 0);
//usb_ep_buffers[USB_EPBUF_OFFSET_EP0OUT_BUF + USB_EPBUF_SUBOFFSET_STAT] &= ~(1 << 0);
return bytecount;
}
void usb_ep_stall(uint32_t epnum)
{
usb_ep_buffers[epnum + USB_EPBUF_SUBOFFSET_STAT] |= (1 << 1);
}
void usb_ep_unstall(uint32_t epnum)
{
usb_ep_buffers[epnum + USB_EPBUF_SUBOFFSET_STAT] &= ~(1 << 1);
}
bool usb_ep_is_stalled(uint32_t epnum)
{
return (usb_ep_buffers[epnum + USB_EPBUF_SUBOFFSET_STAT] & (1 << 1));
}
/* send a package via EP0IN which is longer as 7 bytes */
void usb_ep_in_commit_pkt_long(uint32_t epnum, const uint8_t *pbuf, uint8_t len, bool sendshortpkt)
{
bool first;
uint8_t curlen;
first = (epnum == 0x00); /* EP0IN packets always start with DATA1 PID, while EP1IN PID toggles between DATA0/1 */
curlen = 0;
while (len)
{
curlen = len;
if (curlen > 8)
{
curlen = 8;
}
while (!usb_ep_in_buf_empty(epnum)); /* wait until endpoint buffer is free */
usb_ep_in_commit_pkt(epnum, first, pbuf, curlen);
len -= curlen;
pbuf += curlen;
first = false;
}
if (!sendshortpkt)
{
return;
}
if ((curlen == 8) || (curlen == 0)) /* in case the last packet has 8 bytes a short packet needs to be sent to signalize the host, that this was the last packet*/
{
while (!usb_ep_in_buf_empty(epnum)); /* wait until endpoint buffer is free */
usb_ep_in_commit_pkt(epnum, false, pbuf, 0);
}
}
/* receive a package via EP0OUT. It is allowed to be longer than 8 bytes */
/* important: ensure, that pbuf has a buffer size with a multiple of 8 Bytes */
/* returns received length */
uint8_t usb_ep_out_get_data_long(uint8_t *pbuf, uint8_t maxlen)
{
uint8_t curlen, len;
curlen = 8;
len = 0;
do
{
if (usb_ep_out_data_available(0))
{
curlen = usb_ep_out_get_data(0, pbuf); /* TODO: Handle this within usb_stack.c. It is part of control transfers. setup */
pbuf += curlen;
if (len >= maxlen) /* at least a little bit of protection against buffer overruns */
{
pbuf -= curlen;
}
len += curlen;
}
} while ( (curlen == 8) && (len < maxlen) ); /* a short packet indicates the last packet */
return len;
}
/* Handle a Control transfer without data stage => transmits a ACK in status stage */
void usb_control_acknowledge(void)
{
uint8_t response[8];
while (!usb_ep_in_buf_empty(0x00))
;
usb_ep_in_commit_pkt(0, true, response, 0);
}
/* Handle a Control IN transfer */
bool usb_control_dataIn(const uint8_t *pbuf, uint8_t len)
{
usb_ep_in_commit_pkt_long(0, pbuf, len, false);//true);
/* wait for status stage - acknowledge from HOST*/
while ( !usb_ep_out_data_available(0) )
{
}
usb_ep_buffers[USB_EPBUF_OFFSET_EP0OUT_BUF + USB_EPBUF_SUBOFFSET_STAT] &= ~(1 << 0); /* ignore ACK (OUT packet) */
return true;
}
/* Handle a Control OUT transfer */
uint8_t usb_control_dataOut(uint8_t *pbuf, uint8_t maxlen)
{
maxlen = usb_ep_out_get_data_long(pbuf, maxlen);
usb_control_acknowledge();
return maxlen;
}
/* TODO: Combine the functions */
@@ -0,0 +1,137 @@
/****************************************************************************//*
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef __USB_H__
#define __USB_H__
#include <stdint.h>
#include <stdbool.h>
#include "usb_config.h"
/* public interface to virtual USB peripheral & Stack */
/* some definitions for USB descriptors */
#define DESCRIPTOR_DEVICE (0x01) /* Get device descriptor: Device */
#define DESCRIPTOR_CONFIGURATION (0x02) /* Get device descriptor: Configuration */
#define DESCRIPTOR_STRING (0x03) /* Get device descriptor: String */
#define DESCRIPTOR_INTERFACE (0x04)
#define DESCRIPTOR_ENDPOINT (0x05)
#ifdef USB_ENABLE_HID
#define DESCRIPTOR_HID (0x21) /* Get descriptor: HID */
#define DESCRIPTOR_REPORT (0x22) /* Get descriptor: Report */
#endif
#define EPTYPE_CONTROL (0x00)
#define EPTYPE_INTERRUPT (0x03)
/* Some defines for endpoint function parameters => TODO, will be used in a later stage */
#define USB_EPSETUP (0)
#define USB_EP0OUT (16)
#define USB_EP0IN (32)
#if USB_ENABLE_EP1OUT_EP1IN == 1
#define USB_EP1OUT (48)
#define USB_EP1IN (64)
#endif
/* struct, which is used for control transfers */
typedef struct
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wLength;
uint16_t wValue;
uint16_t wIndex;
} setupData_t;
/* Initialize USB and all used peripherals
It startes with the USB peripheral disconnected from PC.
Call usb_connect after initialization.
*/
void usb_init(void);
void usb_connect(void);
void usb_disconnect(void);
bool usb_check_resetcondition(void);
void usb_reset_received(void);
/* check, if a setup packet was received */
bool usb_setup_available(void);
/* read setup data. Setup data does have a fixed length of 8 Bytes */
void usb_setup_get_data(setupData_t *psetupdata);
/* check, if data can be written to ep0in buffer (== buffer is empty) */
bool usb_ep_in_buf_empty(uint32_t epnum);
/* write data to ep0in buffer */
void usb_ep_in_commit_pkt(uint32_t epnum, bool firstpkt, const uint8_t *pbuf, uint32_t len);
/* check, if received data is in OUT endpoint */
bool usb_ep_out_data_available(uint32_t epnum);
/* get data from EPxOUT. Length [bytes] is returned. */
uint32_t usb_ep_out_get_data(uint32_t epnum, uint8_t *pbuf);
/* stall endpoint */
void usb_ep_stall(uint32_t epnum);
/* remove stall condition from endpoint */
void usb_ep_unstall(uint32_t epnum);
/* returns true if endpoint is stalled */
bool usb_ep_is_stalled(uint32_t epnum);
/* receive a package via EP0OUT. It is allowed to be longer than 8 bytes */
/* important: ensure, that pbuf has a buffer size with a multiple of 8 Bytes */
/* returns received length */
uint8_t usb_ep_out_get_data_long(uint8_t *pbuf, uint8_t maxlen);
/* send a package via EP0IN which is longer as 7 bytes */
//void usb_ep_in_commit_pkt_long(uint32_t epnum, const uint8_t *pbuf, uint8_t len);
void usb_ep_in_commit_pkt_long(uint32_t epnum, const uint8_t *pbuf, uint8_t len, bool sendshortpkt);
/* Handle a Control transfer without data stage => transmits a ACK in status stage */
void usb_control_acknowledge(void);
/* Handle a Control IN transfer */
bool usb_control_dataIn(const uint8_t *pbuf, uint8_t len);
/* Handle a Control OUT transfer */
uint8_t usb_control_dataOut(uint8_t *pbuf, uint8_t maxlen);
#endif
@@ -0,0 +1,40 @@
/***************************************************************************//*
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef __USB_CONFIG_H__
#define __USB_CONFIG_H__
/* Set to 1 to enable 2 additional endpoints.
If set to 0, only control transfers will be supported, because only EP0OUT and EP0IN are present
*/
#define USB_ENABLE_EP1OUT_EP1IN (1)
#define USB_ENABLE_HID
/*
Enable this define, if the USB low level protocol handling should be done in RAM.
This is e.g. mandatory if Flash programming is used, otherwise USB will not be
responsive anymore when flash is erased or programmed, because Flash accesses will
be stalled.
*/
#define USB_PROTOCOL_HANDLING_IN_RAM
#endif
@@ -0,0 +1,162 @@
/***************************************************************************//*
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef __USB_DESCRIPTORS_H__
#define __USB_DESCRIPTORS_H__
#include <stdint.h>
#include <stdbool.h>
#include "usb.h"
/* include this file only once! */
#define WBVAL(x) (x & 0xFF),((x >> 8) & 0xFF)
/* report descriptor for HID keyboard */
const uint8_t hid_report_descriptor[] =
{
0x05, 0x01, 0x09,
0x06, 0xA1,
0x01, 0x05,
0x07, 0x19,
0xE0, 0x29, 0xE7,
0x15, 0x00,
0x25, 0x01,
0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01,
0x75, 0x08, 0x81, 0x01, 0x95, 0x03, 0x75, 0x01,
0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91, 0x02,
0x95, 0x05, 0x75, 0x01, 0x91, 0x01, 0x95, 0x06,
0x75, 0x08, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x05,
0x07, 0x19, 0x00, 0x2A, 0xFF, 0x00, 0x81, 0x00,
0xC0
};
const uint8_t device_descriptor[] =
{
0x12, /* descriptor length */
0x01, /* descriptor type */
WBVAL(0x0110), /* USB version */
0x00, /* Devices class */
0x00, /* Device sub class */
0x00, /* Device sub sub class */
0x08, /* max packet size (for EP0IN/OUT) */
WBVAL(0x10C4), /* VID (low, high) */
WBVAL(0x8944), /* PID */
WBVAL(0x0100), /* DID */
0x01, /* manufacturer string index */
0x02, /* product string index */
0x00, /* serial number string index */
0x01 /* number of configurations */
};
const uint8_t config_0_descriptor[] =
{
0x09, /* length of config descriptor */
DESCRIPTOR_CONFIGURATION, /* descriptor type */
0x12+7+9, 0x00, /* Config + Interface + Endpoints length (low, high) */
0x01, /* number of interfaces */
0x01, /* interface number */
0x00, /* configuration string index */
0xA0, /* attributes (buspowered = Bit7, Selfpowered = Bit6, RemoteWakeup = Bit 5) */
50, /* power requirement (multiply by 2 to get current in mA) */
/* interface descriptor */
0x09, /* length of interface descriptor */
DESCRIPTOR_INTERFACE, /* descriptor type */
0x00, /* Index of this interface (starts at 0) */
0x00, /* Alternate setting */
0x01, /* Number of Endpoints */
0x03, /* Interface class */
0x01, /* Interface sub class */
0x01, /* Interface sub sub class */
0x00, /* Interface descriptor string index */
/* HID descriptor - Keyboard */
0x09, /* Length of this descriptor */
DESCRIPTOR_HID, /* bDescriptorType */
WBVAL(0x0100), /* 1.00 */ /* bcdHID */
0x00, /* bCountryCode */
0x01, /* bNumDescriptors */
0x22, /* bDescriptorType */
WBVAL(sizeof(hid_report_descriptor)), /* wDescriptorLength */
/* EP1IN */
0x07, /* length of endpoint descriptor */
DESCRIPTOR_ENDPOINT, /* descriptor type */
0x81, /* Endpoint number and direction (Bit 7) */
EPTYPE_INTERRUPT, /* Endpoint type */
0x08, 0x00, /* Max packet size of this Endpoint (Low, High) */
0x18 /* Polling Interval */
};
const uint8_t string_0_descriptor[] =
{
0x04, /* length of string descriptor */
DESCRIPTOR_STRING, /* descriptor type */
0x09,
0x04
};
const uint8_t string_1_descriptor[] =
{
0x14, /* length of string descriptor */
DESCRIPTOR_STRING, /* descriptor type */
'L', 0,
'E', 0,
'M', 0,
'C', 0,
'U', 0,
'.', 0,
'O', 0,
'R', 0,
'G', 0,
};
const uint8_t string_2_descriptor[] =
{
0x1A, /* length of string descriptor */
DESCRIPTOR_STRING, /* descriptor type */
'I', 0,
't', 0,
' ', 0,
'w', 0,
'o', 0,
'r', 0,
'k', 0,
's', 0,
' ', 0,
':', 0,
'-', 0,
')', 0,
};
const uint8_t hid_descriptor[] =
{
0x09,
DESCRIPTOR_HID,
0x10, 0x01, /* USB version */
0x00, /* Localization*/
};
#endif
@@ -0,0 +1,63 @@
/****************************************************************************
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef __USB_HELPERFUNCTIONS_H__
#define __USB_HELPERFUNCTIONS_H__
#include <stdint.h>
/* from bit twiddling hacks. Did not check efficiency.
My guess is, that the standard assembly way using 8 consecutive ROR/ROL instructions is faster!
so: TODO check and optimize
*/
static inline uint8_t bitreverse(uint8_t b)
{
return ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
}
/* TODO: Make this nice and efficient! Maybe implement this directly in CM0+ assembly
using uint32_t instead of uint8_t can also speed things up
See: http%3A%2F%2Fwww.usb.org%2Fdevelopers%2Fwhitepapers%2Fcrcdes.pdf&ei=
AKrAUtuBD4WMtQakyoCwAQ&usg=AFQjCNE71tY6EAUjJKXWbjtbNvDTiOKKlg&bvm=bv.
58187178,d.Yms&cad=rja
*/
static uint16_t crc16(uint16_t crc, uint8_t c)
{
uint8_t i;
for (i=0; i<8; i++)
{
if ((crc ^ c) & 1)
{
crc = (crc >> 1) ^ 0xa001; /* 0xa001*/
}
else
{
crc >>= 1;
}
c >>= 1;
}
return crc;
}
#endif
@@ -0,0 +1,104 @@
/****************************************************************************
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "usb_stack.h"
#include "usb.h"
#include "usb_helperfunctions.h"
#include "usb_config.h"
#include "usb_hid.h"
//#include "em_device.h" /* removeme. Only needed for debugging */
#ifdef USB_ENABLE_HID
/* HID requests */
#define HID_GET_REPORT (0x01) /* mandatory */
#define HID_GET_IDLE (0x02) /* optional */
#define HID_GET_PROTOCOL (0x03) /* mandatory for BOOT devices */
#define HID_SET_REPORT (0x09) /* mandatory if USB device does not use EP1OUT */
#define HID_SET_IDLE (0x0a) /* optional */
#define HID_SET_PROTOCOL (0x0b) /* mandatory for BOOT devices */
bool usbhid_got_setup_cmd(const setupData_t *psetupdata)
{
uint8_t response[8];
bool doStall;
doStall = false;
switch(psetupdata->bRequest)
{
case HID_GET_REPORT:
doStall = !HID_GetReport(psetupdata->wValue >> 8);
break;
case HID_SET_REPORT:
doStall = !HID_SetReport(psetupdata->wValue >> 8);
if (!doStall)
{
//usb_control_acknowledge(); //TODO: REMOVE UNCOMMENT!!!
}
break;
case HID_GET_PROTOCOL:
doStall = !HID_GetProtocol(response);
if (!doStall)
{
usb_control_dataIn(response, 1);
}
break;
case HID_SET_PROTOCOL:
doStall = !HID_SetProtocol(psetupdata->wValue >> 8); /* low byte of value is interface number */
if (!doStall)
{
usb_control_acknowledge();
}
break;
case HID_GET_IDLE:
doStall = !HID_GetIdle(response);
if (!doStall)
{
usb_control_dataIn(response, 1);
}
break;
case HID_SET_IDLE:
doStall = !HID_SetIdle(psetupdata->wValue >> 8); /* low byte of value is interface number */
if (!doStall)
{
usb_control_acknowledge();
}
break;
}
if (doStall)
{
usb_ep_stall(USB_EP0OUT);
usb_ep_stall(USB_EP0IN);
}
return true;
}
#endif
@@ -0,0 +1,61 @@
/***************************************************************************//*
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef __USB_HID_H__
#define __USB_HID_H__
#include <stdint.h>
#include <stdbool.h>
#include "usb.h"
#include "usb_config.h"
#ifdef USB_ENABLE_HID
/* HID Report Types */
#define HID_RPRT_INPUT (0x01)
#define HID_RPRT_OUTPUT (0x02)
#define HID_RPRT_FEATURE (0x03)
/* HID Requests functions, need to be defined by the user! */
/* They are not implemented as callback functions to get */
/* a more efficient code.*/
/* The functions should false, if they were not handled */
/* return TRUE if function was handled */
extern bool HID_GetReport (uint8_t reportType);
extern bool HID_SetReport (uint8_t reportType);
extern bool HID_GetIdle (uint8_t *pIdleTime);
extern bool HID_SetIdle (uint8_t idleTime);
extern bool HID_GetProtocol (uint8_t *pProtocol);
extern bool HID_SetProtocol (uint8_t protocol);
bool usbhid_got_setup_cmd(const setupData_t *psetupdata);
#else
#warning "HID disabled, but hid includes compiled"
#endif
#endif
@@ -0,0 +1,484 @@
//****************************************************************************
//
// Lemcusb - Firmware USB driver for EFM32 Microcontroller
// Copyright (C) 2014 http://lemcu.org
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 3.0 as
// published by the Free Software Foundation and appearing in the file
// LICENSE.txt included in the packaging of this file.
//
// In addition, as a special exception, http://lemcu.org gives you certain
// additional rights. These rights are described in the lemcu.org GPL
// Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
// package.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY// without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
//**************************************************************************/
#if defined ( __IAR_SYSTEMS_ASM__ )
NAME usb_internal_bitbangusb
;; For a description of the purpose of the following part, look here:
;; http://supp.iar.com/Support/?note=80737&from=search+result
;; (TOPIC: IAR assembler ramfunction)
#define SHT_PROGBITS 0x1
#define SHF_WRITE 0x1
#define SHF_EXECINSTR 0x4
RSEG MYCODE:CODE:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR
THUMB
EXTERN usb_protocol_handle
PUBLIC GPIO_ODD_IRQHandler
PUBLIC usb_transmit
PUBLIC protocol_handled
#else
.syntax unified
.arch armv6-m
.SECTION .functioninRAM
.thumb
.thumb_func
.extern usb_protocol_handle
.global GPIO_ODD_IRQHandler
.global usb_transmit
.global protocol_handled
.type GPIO_ODD_IRQHandler, %function // IMPORTANT FOR GCC to get lsb of address set to 1
.type protocol_handled, %function // IMPORTANT FOR GCC to get lsb of address set to 1
#endif
#define USBEP_OFS_SETUP ( 0)
#define USBEP_OFS_EP0OUT (16)
#define USBEP_OFS_EP0IN (32)
#define USBEP_OFS_EP1OUT (48)
#define USBEP_OFS_EP1IN (64)
#define USBEP_SOFS_STAT (12)
#define USBEP_SOFS_LEN (13)
// This is the Interrupt handler, triggered by a rising edge on D+ (PC1)
// It is implemented in assembly to minimize latency
// (=> avoid branch from C code to ASM and addition of veneer code)
// This is called for each received USB data packet. received data is unstuffed.
// The data is decoded to R8, R9, R10
// Each data byte is in reversed bitorder. For data bytes, the bitorder
// needs to be reversed. For PIDs, etc. bitorder reversal is not mandatory
// The received bitcount is written to R11
// BYTE ORDER:
// R8. 24-31 Byte 0
// R8. 16-23 Byte 1
// R8. 8-15 Byte 2
// R8. 0- 7 Byte 3
// R9. 24-31 Byte 4
// R9. 16-23 Byte 5
// R9. 8-15 Byte 6
// R9. 0- 7 Byte 7
// R10.24-31 Byte 8
// R10.16-23 Byte 9
// R10. 8-15 Byte 10
// R10. 0- 7 Byte 11
//
// An interupt saves the following register on stack:
// - R0-R3, R12
// - LR, PC & xPSR
GPIO_ODD_IRQHandler:
NOP
NOP
MOV r0, r8
MOV r1, r9
MOV r2, r10
MOV r3, r11
PUSH {r0-r7}
MOV r0, LR
PUSH {r0}
MOVS r3, #3
MOVS r4, #0xff // preload with 0xff to avoid bitunstuffing after start
MOVS r5, #0x80
LSLS r5, r5, #24
MOVS r0, #0
MOV r11, r0
MOVS r1, #1
MOV r12, r1
// r1 = 1
// r3 = 3
// r5 = (1<<13)
// r7 = &GPIO_PE_DOUTSET
LDR r7, GPIO_PC_DIN // r7 = address of register GPIO_PC_DIN
// wait until a 1 is detected. Unfolded loop to be able to detect a timeout condition
usb_sync_wait_while_0:
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
LDR r0, [r7] // read port state
TST r0, r1
BEQ usb_sync_found
B protocol_handled // State was zero for more than 1 bittime => exit (timeout condition)
usb_sync_found:
// delay 1 bittime
LDR r0, [r7] // read port state
TST r0, r1
BNE usb_sync_wait_while_0
LDR r0, [r7] // read port state
TST r0, r1
BNE usb_sync_wait_while_0
LDR r0, [r7] // read port state
TST r0, r1
BNE usb_sync_wait_while_0
LDR r0, [r7] // read port state
TST r0, r1
BNE usb_sync_wait_while_0
LDR r0, [r7] // read port state
TST r0, r1
BNE usb_sync_wait_while_0
NOP
// check, if bitstate is still 1 (=> if 2 consecutive 1 bits received)
LDR r2, [r7] // read port state
TST r2, r1
BNE usb_sync_wait_while_0
BL _delay_13
// here: We are in the middle of the very first bit of this packet
// r0 = port state current
// r1 = 1
// r2 = port state old
// r3 = 3
// r4/5/6 = received data (parallel)
// r7 = address of GPIO_PC_DIN
// r11 = bitcounter
MOVS r1, #0
rcv_bits: LDR r0, [r7] // read port state
ANDS r0, r3 // check for SE0 and mask out unneeded bits
BEQ se0_detected // end of receive loop!
EORS r2, r0 // NRZ decoding (XOR bitstate with old bitstate) => inverts data, USB uses NRZI!
LSRS r2, r2, #1
ADCS r4, r4, r4 // Shift carry into receive chain
ADCS r5, r5, r5
ADCS r6, r6, r6
ADD r11, r11, r12 // increment bitcounter
MOV r2, r0 // Store old bitstate
NOP
LSLS r1, r1, #1 // Shift bitunstuffing EOR mask
LSLS r0, r4, #26 // Mask out last 6 received bits
EORS r0, r0, r1 // check if 6 consecutive 0s have been received
BNE rcv_bits
// here we get when bitunstuffing needs to be done
// 15/16 cycles over
NOP //16
LDR r2, [r7] // 1 // read port state to save it as "old" bitstate
BL _delay_11 //12
MOVS r1, #1 //13 // save bitunstuffing EOR mask
LSLS r1, r1, #26 //14
B rcv_bits //16
se0_detected:
// left align data (rough: 32 Bit steps)
MOV r0, r11
CMP r0, #64
BHI se0_detected_align_0
MOVS r6, r5
MOVS r5, r4
SUBS r4, r4, r4 // not mandatory
CMP r0, #32
BHI se0_detected_align_0
MOVS r6, r5
MOVS r5, r4
SUBS r4, r4, r4 // not mandatory
// left align data (fine alignment: 0..31 bits)
se0_detected_align_0: MOV r0, r11
MOVS r1, #31
ANDS r1, r1, r0 // r1 = bitcount & 31
CMP r1, #0
BEQ se0_alginment_done
MOVS r0, #0
MVNS r0, r0 // r0 = 0xffffffff
LSRS r0, r0, r1 // 8 => 0x00ffffff, 24 => 0x000000ff r0 = Mask of bytes to copy from lower word to upper one
RORS r6, r6, r1 //
BICS r6, r6, r0 // r6 = r6 and not r0 (reset lower bytes to 0)
RORS r5, r5, r1 //
MOVS r2, r5
ANDS r2, r2, r0
ORRS r6, r6, r2 //
BICS r5, r5, r0 // r6 = r6 and not r0 (reset lower bytes to 0)
RORS r4, r4, r1 //
MOVS r2, r4
ANDS r2, r2, r0
ORRS r5, r5, r2
BICS r4, r4, r0 // not mandatory
// Invert data (NRZ => NRZI)
se0_alginment_done: MVNS r0, r4
MOV r10, r0
MVNS r0, r5
MOV r9, r0
MVNS r0, r6
MOV r8, r0
LDR r0, LABEL_USB_PROT_HDL
BX r0 // Jump to protocol state machine code located in Flash
protocol_handled:
// This was for debugging. enable it, if you want to debug host packets only
// MOVS r5, #255
//delayloop:
// SUBS r5, r5, #1
// BNE delayloop
// acknowledge GPIO interrupt
LDR r6, GPIO_IFC
MOVS r5, #2
STR r5, [r6]
POP {r0}
MOV LR, r0
POP {r0-r7}
MOV r8, r0
MOV r9, r1
MOV r10, r2
MOV r11, r3 // r0-r3 are restored by ISR return
BX LR // return
////////////////////////////////////////
#if defined ( __IAR_SYSTEMS_ASM__ )
DATA
ALIGNROM 2
GPIO_PC_DIN: DC32 0x40006064 ; GPIO_PC_DIN
GPIO_PE_DOUTSET DC32 0x400060a0 ; GPIO_PE_DOUTSET.DOUTSET
GPIO_IFC: DC32 0x4000611c ; GPIO.IFC
LABEL_USB_PROT_HDL: DC32 usb_protocol_handle
//GPIO_PB_TOGGLE: DC32 0x4000603C ; REMOVEME
#else
.BALIGN 4
GPIO_PC_DIN: .INT 0x40006064 // GPIO_PC_DIN
GPIO_PE_DOUTSET: .INT 0x400060a0 // GPIO_PE_DOUTSET.DOUTSET
GPIO_IFC: .INT 0x4000611c // GPIO.IFC
LABEL_USB_PROT_HDL: .INT usb_protocol_handle
#endif
#if defined ( __IAR_SYSTEMS_ASM__ )
CODE
THUMB
#else
.SECTION .functioninRAM
.THUMB
#endif
// This function transmits a USB packet as response to the host
// Used for : ACK, NAK, STALL, DATA0 & DATA1 PIDs
// Parameters:
// r0/r1/r2 = Data to transmit
// r5 = Bitcount
// The Bitorder of the transmission is the right one (no bitreversal as in receive function)
// transmit order:
// r0.0-7 => r0.8-15 => r0.16-23 => r0.24-31 =>
// r1.0-7 => r1.8-15 => r1.16-23 => r1.24-31 =>
// r2.0-7 => r2.8-15 => r2.16-23 => r2.24-31
usb_transmit:
MOV r7, LR
PUSH {r7}
// Switch PC0 & PC1 to output
LDR r7, GPIO_PC_BASE
LDR r3, [r7, #4] // read pin mode low register
ADDS r3, r3, #0x33 // mode Input = 0x11, Output = 0x44
STR r3, [r7, #4] // writepin mode low register
// IO state = push pull & IDLE (D-=1 D+=0)
// 1.) Send SYNC Byte
MOVS r3, #0x03 // bitmask for toggling IO pin
MOVS r4, #7
usb_tx_syncloop: STR r3, [r7, #24] // Toggle IOs to transmit a 0
BL _delay_12
SUBS r4, r4, #1
BNE usb_tx_syncloop
//15
// transmit a "1" - last bit of SYNC sequence
BL _delay_12
// 2.) Send data given in registers r0/r1/r2 and bitcount in r5
// Here all bits get transmitted. Bitstuffing is also applied
// The minimal version of this would only need 6 cycles
MOVS r4, #5 // consecutive 1-Bit counter (used for bitstuffing). Last transmitted Bit was 1, so initialize it with 5 rather than 6
MOVS r6, #32 // Needed to check if a new 32 Bit word should be transmitted
usb_tx_bitloop: LSRS r0, r0, #1 // shift out bit to carry flag for transmitting
BCS usb_txbitloop_send1 //do nothing if bit is 1 (only a zero causes toggling
usb_txbitloop_send0: STR r3, [r7, #24] // Toggle IOs to transmit a 0
MOVS r4, #6 // Reset 1-Bit counter
B usb_txbitloop_sent1
usb_txbitloop_send1: SUBS r4, #1
BEQ usb_tx_sendstuffbit
usb_tx_bitstutt_ret: NOP // equalize execution time for 2 branch paths
usb_txbitloop_sent1: SUBS r5, r5, #1
BEQ usb_tx_send_eop // final word transmitted
SUBS r6, r6, #1
BEQ usb_txbit_nextword
NOP
NOP
NOP
NOP
B usb_tx_bitloop
// select next word for transmission
usb_txbit_nextword: MOVS r0, r1
MOVS r1, r2
MOVS r6, #32
B usb_tx_bitloop
// Send stuffbit
// 4 cycles over since last bit
usb_tx_sendstuffbit: BL _delay_11
MOVS r4, #6 // Reset 1-Bit counter
STR r3, [r7, #24] // Toggle IOs to transmit a 0
B usb_tx_bitstutt_ret
// send EOP (2*SE0)
// 7 cycles over since last bit
usb_tx_send_eop:
BL _delay_9
STR r3, [r7, #20] // write to GPIO_PC_DOUTCLR to set D+ and D- to LOW
BL _delay_10
BL _delay_10
BL _delay_10
MOVS r1, #1
STR r1, [r7, #16] // Set D- back to HIGH
// Switch PC0 & PC1 to input
LDR r7, GPIO_PC_BASE
LDR r0, [r7, #4] // read pin mode low register
SUBS r0, r0, #0x33 // set from 0x44 to 0x11 (push pull to input)
STR r0, [r7, #4] // writepin mode low register
// // delay some time for easier debugging
// MOVS r5, #255
//delayloop_x: MOVS r4, #6 // reset 1-bit counter
// SUBS r5, r5, #1
// BNE delayloop_x
POP {r0}
MOV LR, r0
BX LR
// some delay functions:
_delay_14: NOP
_delay_13: NOP
_delay_12: NOP
_delay_11: NOP
_delay_10: NOP
_delay_9: NOP
_delay_8: NOP
_delay_7: NOP
_delay_6: NOP
_delay_5: BX LR
#if defined ( __IAR_SYSTEMS_ASM__ )
DATA
ALIGNROM 2
GPIO_PC_BASE: DC32 0x40006048 ; GPIO_PC_DIN - This is redundant, has already been defined in the RX function
GPIO_PE_DOUTSET_ DC32 0x400060a0 ; GPIO_PE_DOUTSET.DOUTSET
END
#else
.BALIGN 4
GPIO_PC_BASE: .INT 0x40006048 // GPIO_PC_DIN - This is redundant, has already been defined in the RX function
GPIO_PE_DOUTSET_: .INT 0x400060a0 // GPIO_PE_DOUTSET.DOUTSET
.END
#endif
/*
TODO:
- Flag endpoint status based on Host reply
- interpret CRC5 ??
- detect RESET condition on bus (very long SE0 phase, check USB spec. for duration). This should reset the usb address
- RESET = SE0 for >= 10ms
- codesize optimization:
* use branches to identical code secitions
*/
@@ -0,0 +1,59 @@
/****************************************************************************
**
** Lemcusb - Firmware USB driver for EFM32 Microcontroller
** Copyright (C) 2014 http://lemcu.org
**
** This library is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3.0 as
** published by the Free Software Foundation and appearing in the file
** LICENSE.txt included in the packaging of this file.
**
** In addition, as a special exception, http://lemcu.org gives you certain
** additional rights. These rights are described in the lemcu.org GPL
** Exception version 1.0, included in the file GPL_EXCEPTION.txt in this
** package.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
/*
* Low level internal functions.
* These functions are internal.
*/
//#include "em_device.h"
#include <stdint.h>
//#include "em_chip.h"
//#include "em_int.h"
#include "gpio.h"
//#include "em_cmu.h"
#include "usb_config.h"
/* Endpoint buffers
Offset 0: SETUP packets
Offset 16: EP0OUT
Offset 32: EP0IN
(Offset 48: EP1OUT)
(Offset 64: EP1IN)
Offsets within one of theese buffers:
0-11: Raw data
Offset 12: _STAT Status empty/filled (0x00/0x01)
Offset 13: _LEN Length of data in buffer
14 & 15 are free for future used - would be added anyway by codegen tools for alignment
*/
volatile uint8_t usb_ep_buffers[ (3+2*USB_ENABLE_EP1OUT_EP1IN)*16 ];
/* low level protocol handling state */
/* Bit 0- 7 = state machine index*/
/* Bit 8-15 = last received USB Address (bitreversed: a0 a1 a2 a3 a4 a5 a6 0) */
/* Bit 16-23 = last received USB Endpoint (bitreversed: e0 e1 e2 e3 0 0 0 0) */
/* Bit 24-31 = not used yet */
uint32_t USB_PROT_STATE;

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