添加一些关于midi播放的项目
This commit is contained in:
@@ -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>
|
||||
@@ -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
|
||||
@@ -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 "${INPUTS}"" 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
|
||||
@@ -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
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>.
|
||||
@@ -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)
|
||||
@@ -0,0 +1,28 @@
|
||||
# Intro
|
||||
|
||||
This is a wavetable synthesis based music-box.
|
||||
|
||||

|
||||
|
||||
# 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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 356 KiB |
@@ -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;
|
||||
}
|
||||
@@ -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" */
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user