First commit

This commit is contained in:
Portisch 2017-11-30 14:58:29 +01:00
commit 8c92ca07c5
28 changed files with 7118 additions and 0 deletions

92
.cproject Normal file
View File

@ -0,0 +1,92 @@
<?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="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" moduleId="org.eclipse.cdt.core.settings" name="Keil 8051 v9.53 - Release">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.8051:4.0.9._-963069514}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF2" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.KeilErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" cppBuildConfig.builtinIncludes="studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8BB1/inc/ studio:/sdk/Device/EFM8BB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8BB1/inc/ studio:/sdk/Device/EFM8BB1/peripheral_driver/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8bb1/peripheralDrivers/inc/pca_0.h&quot;,&quot;lib/efm8bb1/peripheralDrivers/src/pca_0.c&quot;],&quot;builtin&quot;:false,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8PeripheralDriver.pca0\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8bb1/peripheralDrivers/src/uart_0.c&quot;,&quot;lib/efm8bb1/peripheralDrivers/inc/uart_0.h&quot;],&quot;builtin&quot;:false,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8PeripheralDriver.uart0\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;src/SILABS_STARTUP.A51&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.shared\&quot;/&gt;&quot;}]" projectCommon.toolchainId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="omf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" name="Keil 8051 v9.53 - Release" parent="com.silabs.ide.si8051.keil.exe.default" postannouncebuildStep="">
<folderInfo id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si8051.keil.toolchain.exe.default.166809853" name="Keil 8051" superClass="com.silabs.ide.si8051.keil.toolchain.exe.default">
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.debug.1984276196" name="Generate debug information" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.debug" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler.980587367" name="Use Extended Assembler (AX51) instead of A51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker.907895507" name="Use Extended Linker (LX51) instead of BL51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker" value="true" valueType="boolean"/>
<targetPlatform binaryParser="com.silabs.ss.tool.ide.c8051.debug.OMF;com.silabs.ss.tool.ide.c8051.debug.OMF2;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si8051.keil.targetplatform.230898451" isAbstract="false" superClass="com.silabs.ide.si8051.keil.targetplatform"/>
<builder buildPath="${workspace_loc:/RF_Bridge}/Keil 8051 v9.53 - Release" id="com.silabs.ide.si8051.keil.builder.1497200682" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Keil Builder" parallelBuildOn="false" superClass="com.silabs.ide.si8051.keil.builder"/>
<tool id="com.silabs.ide.si8051.keil.toolchain.compiler.1502244024" name="Keil 8051 Compiler" superClass="com.silabs.ide.si8051.keil.toolchain.compiler">
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.level.688135799" name="Level" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.level" value="com.silabs.ide.si8051.keil.compiler.category.optimization.level.9" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.symbols.def.620158654" name="Defined symbols (DEFINE(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.symbols.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.coloring.2040331638" name="Global register coloring" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.coloring" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.138466822" name="Emphasis" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis" value="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.speed" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.includes.paths.1540185603" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8BB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8BB1/peripheral_driver/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si8051.keil.compiler.inputType.816728815" superClass="com.silabs.ide.si8051.keil.compiler.inputType"/>
</tool>
<tool command="AX51" id="com.silabs.ide.si8051.keil.toolchain.assembler.2115123515" name="Keil 8051 Assembler" superClass="com.silabs.ide.si8051.keil.toolchain.assembler">
<option id="com.silabs.ide.si8051.keil.assembler.category.symbols.def.1370001353" name="Defined symbols (SET(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.symbols.def" valueType="stringList">
<listOptionValue builtIn="false" value="SILABS_STARTUP=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.assembler.category.includes.paths.1830020867" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8BB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8BB1/peripheral_driver/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si8051.keil.assembler.inputType.541849322" superClass="com.silabs.ide.si8051.keil.assembler.inputType"/>
</tool>
<tool command="LX51" id="com.silabs.ide.si8051.keil.toolchain.linker.1678919565" name="Keil 8051 Linker" superClass="com.silabs.ide.si8051.keil.toolchain.linker">
<inputType id="com.silabs.ide.si8051.keil.linker.inputType.732015689" superClass="com.silabs.ide.si8051.keil.linker.inputType"/>
</tool>
<tool id="com.silabs.ide.si8051.keil.toolchain.librarian.889701608" name="Keil 8051 Library Manager" superClass="com.silabs.ide.si8051.keil.toolchain.librarian"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="lib/bsp/bsp.h|lib/efm8bb1/peripheralDrivers/inc/pca_0.h|lib/efm8bb1/peripheralDrivers/src/pca_0.c|src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.boardIds="com.silabs.board.none:0.0.0" projectCommon.buildArtifactType="EXE" projectCommon.importModeId="COPY" projectCommon.partId="mcu.8051.efm8.bb1.efm8bb10f8g-a-qfn20" projectCommon.sdkId="com.silabs.sdk.8051:4.0.9._-963069514"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="RF_Bridge.com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType.929239758" name="SLS CDT Project" projectType="com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0;com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.silabs.ide.si8051.keil.KeilScannerInfoCollector"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Keil 8051 v9.53 - Release">
<resource resourceType="PROJECT" workspacePath="/RF_Bridge"/>
</configuration>
</storageModule>
</cproject>

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
Keil 8051 v9.53 - Release/lib/*
Keil 8051 v9.53 - Release/src/*

27
.project Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RF_Bridge</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>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@ -0,0 +1,174 @@
:020000040000FA
:100000000205DAE4FDFCFF120A0753DAFE120AAB1E
:1000100053E2FDC28043E2029000D0E06003120987
:10002000BF2222020760C0E0C083C082C0D05391CB
:100030007FD39000D4E094009000D3E0940050036C
:100040005391FB9000D4E024FBF09000D3E034FF08
:10005000F0D0D0D082D083D0E03222020669C2DE56
:1000600075D90575F9FF75960143F74022C2DE5335
:10007000DBFE22020026EF8DF0A4A8F0CF8CF0A4C6
:1000800028CE8DF0A42EFE22BC000BBE0029EF8DE1
:10009000F084FFADF022E4CCF875F008EF2FFFEE0E
:1000A00033FEEC33FCEE9DEC984005FCEE9DFE0F1C
:1000B000D5F0E9E4CEFD22EDF8F5F0EE8420D21C77
:1000C000FEADF075F008EF2FFFED33FD40079850BF
:1000D00006D5F0F222C398FD0FD5F0EA22C2D5EC86
:1000E00030E709B2D5E4C39DFDE49CFCEE30E71592
:1000F000B2D5E4C39FFFE49EFE120088C3E49DFDD9
:10010000E49CFC800312008830D507C3E49FFFE421
:100110009EFE22E88FF0A4CC8BF0A42CFCE98EF09C
:10012000A42CFC8AF0EDA42CFCEA8EF0A4CDA8F05F
:100130008BF0A42DCC3825F0FDE98FF0A42CCD3523
:10014000F0FCEB8EF0A4FEA9F0EB8FF0A4CFC5F08D
:100150002ECD39FEE43CFCEAA42DCE35F0FDE43C86
:10016000FC2275F008758200EF2FFFEE33FECD33D1
:10017000CDCC33CCC58233C5829BED9AEC99E58218
:1001800098400CF582EE9BFEED9AFDEC99FC0FD5A4
:10019000F0D6E4CEFBE4CDFAE4CCF9A88222B80094
:1001A000C1B90059BA002DEC8BF084CFCECDFCE55F
:1001B000F0CBF97818EF2FFFEE33FEED33FDEC3383
:1001C000FCEB33FB10D703994004EB99FB0FD8E508
:1001D000E4F9FA227818EF2FFFEE33FEED33FDEC51
:1001E00033FCC933C910D7059BE99A4007EC9BFC47
:1001F000E99AF90FD8E0E4C9FAE4CCFB2275F010D3
:10020000EF2FFFEE33FEED33FDCC33CCC833C810F7
:10021000D7079BEC9AE899400AED9BFDEC9AFCE825
:1002200099F80FD5F0DAE4CDFBE4CCFAE4C8F92272
:10023000EF4E6012EF60010EEDBB010B89828A83E5
:10024000F0A3DFFCDEFA2289F05007F709DFFCA9F2
:10025000F022BBFEFCF309DFFCA9F022120998C2D0
:1002600090C296D280E4FBFD7F10120A7030000528
:100270001209BF800312006DD2AF1209318E438F75
:1002800044E5447004E54364017003020339E51D4D
:1002900014602214700302032C146063146073242E
:1002A000046003020339E54464AA6003020339755C
:1002B0001D01020339E544F51C751D02E51C245A95
:1002C000602214602414602B2407702C9000D374D7
:1002D000C3F0A37450F0D296439104E59120E2FB61
:1002E000C29680551209BF805012006DE49000D074
:1002F000F08046751D038041E4F51CF51D803AE44D
:10030000F546E544F545E545D39400401A751D04CE
:100310008027748D2546F582E43400F583E544F0AA
:100320000546E546B54512751D02800DE544645548
:100330007007F51D7FA0120A51E51C245860232484
:1003400002600302027A9000D1E020E70302027A01
:10035000547FF547FD7FA612089DE49000D1F0027E
:10036000027AE51D600302027A9000D0E060031279
:10037000006D90008DE0FF12053E9000D7EFF0F485
:10038000604F9000D57408F0E014F09000CD740137
:10039000F09000CFF09000CDE0248DF582E43400A1
:1003A000F583E0FF9000D5E0FEEFA806088002C3C9
:1003B00013D8FC30E0059000CE80039000D6E07D9D
:1003C00000FCE4FF120A079000D7E0FF1207D1D229
:1003D000DEE4F51C02027AAFE9AEEA7C007D0A1287
:1003E00000768E218F2220930302052A8521238502
:1003F0002224C3E5229526F52AE5219525F52990A5
:1004000000D2E014700302049104600302053D90E1
:1004100000D1E0600302053DE4F52BE52B75F00A01
:10042000A4242F120911E5289DE5279C405AEF24AA
:10043000C8FFE43EFEC3E5289FE5279E504AE52B12
:1004400075F00AA42431120911E52A9DE5299C4082
:1004500037EF24C8FFE43EFEC3E52A9FE5299E50FE
:10046000279000D57408F0E49000CDF09000CFF014
:10047000F52CF52DFE7F40FD7B017A00798D12026F
:10048000309000D27401F022052BE52B6402708BB2
:10049000229000D5E014F09000CFE004F0D3E528DE
:1004A000952AE527952940081208EFE0C39F400FE1
:1004B00012092040461208EF9000CFE0B5073CD269
:1004C000909000CFE024FFFFE434FFFE7C007D0825
:1004D0001200DD748D2FF58274003EF583C083C059
:1004E00082E0FF9000D5E0FE7401A806088002C3F8
:1004F00033D8FC4FD082D083F0800DC290120920F7
:10050000400685272C85282D9000D5E070037408BF
:10051000F01208EF9000CFE0B507229000D1E52B54
:10052000F04480F0C290E4A3F022852125852226A4
:10053000C3E5229524F528E5219523F52722754862
:10054000FFEFD3940050030205D7EF9480400302DD
:1005500005D7E4FEEE75F00AA4242EF8E6B50704EC
:100560008E4880040EBE02ECE548F4606A12092A47
:100570002433F8E6FE08E6FBAA06E4F9F87F407E9D
:10058000427D0FFC12019EE47BFFFAF9F812011381
:10059000A804A905AA06AB077F207ED77D757C013C
:1005A00012019EEFF404AF885388EFF58CEF5410DE
:1005B000428812092A24351208FBE49E9000CEEFEF
:1005C000F012092A24361208FB9000D6EFF043DA25
:1005D0000153DBFE75F9FFAF4822120022787FE459
:1005E000F6D8FD75814802062402025CE493A3F864
:1005F000E493A34003F68001F208DFF48029E4933A
:10060000A3F85407240CC8C333C4540F4420C88330
:100610004004F456800146F6DFE4800B0102040832
:10062000102040809006EEE47E019360BCA3FF544E
:100630003F30E509541FFEE493A360010ECF54C080
:1006400025E060A840B8E493A3FAE493A3F8E49308
:10065000A3C8C582C8CAC583CAF0A3C8C582C8CA10
:10066000C583CADFE9DEE780BEC0E0C0F0C083C05A
:1006700082C0D075D000C000C001C002C003C00459
:10068000C005C006C007E5D85487F542F452D8E546
:10069000F730E508E5F730E603120AB153F7DFE576
:1006A0004230E708E5D930E00312005AE54230E075
:1006B00008E5DA30E00312083BE54230E108E5DB0B
:1006C00030E0031203D7E54230E208E5DC30E00316
:1006D000120AB2D007D006D005D004D003D002D081
:1006E00001D000D0D0D082D083D0F0D0E032011D34
:1006F00000011C00C100142E0112C005DC03E81E1D
:100700004628020BB8232805DC194B184100D100FC
:100710004100D2004200D300004100D0004100CE91
:10072000564100D6AB4100D5004100CF004100CD7D
:10073000004100D70014080112C005DC03E81E4682
:1007400028020BB8232805DC194B1841008B004107
:10075000008C004100890041008A004100880000AF
:10076000C0E0C083C082C0D075D000C007E59854F7
:1007700003FFF45298EF30E01B90008BE0B4440587
:10078000120987800F90008B120971E599F0900093
:100790008BE004F0EF30E12E90008CE0B4440512C1
:1007A00009878022120967C39F500C12097CE0F56B
:1007B0009990008AE004F0120967B5070990008C4F
:1007C000E4F090008AF0D007D0D0D082D083D0E07F
:1007D0003253E2FD9000D3740BF0A374B8F0D280D2
:1007E000439104E59120E2FBC2809000D3E4F0A3A2
:1007F0007464F0439104E59120E2FBD280EF75F040
:100800000AA4242FF8E6FD08E69000D3CDF0A3ED6E
:10081000F0439104E59120E2FBC280EF75F00AA459
:100820002431F8E6FF08E69000D3CFF0A3EFF043C1
:100830009104E59120E2FB43E202229000D5E070B2
:100840000C9000CDE004F09000D57408F09000D733
:10085000E01208F19000CFE0B5070302000390001A
:10086000CFE004F09000D5E014F09000CDE0248DAE
:10087000F582E43400F583E0FF9000D5E0FEEFA8B8
:1008800006088002C313D8FC30E0059000CE800338
:100890009000D6E07D00FCE4FF120A0722AE07E4D8
:1008A000FCFB1209E7ED75F00AA42411F8E6FFEC51
:1008B000C39F500774082CFC0B80EAEB04FF12095D
:1008C000EEED75F00AA42408F8E6FF1209EEE4FC48
:1008D000ECC39B5012748D2CF582E43400F583E058
:1008E000FF1209EE0C80E97F551209EE020AAEE50F
:1008F0002B75F00AA42437F8E6FF22F8E675F0FF1E
:10090000A4FFAEF07C007D64120088C374FF9FFFDB
:1009100022F8E6FE08E6FF2438FDEE34FFFCD32281
:10092000D3E528952DE527952C22E54875F00AA4F6
:100930002212098EB507057E017F002290008912E0
:100940000971E0FD7C00900089E004F012098EB589
:100950000706E4F090008BF0900088E0FEEE420481
:10096000E4F0AE04AF052290008CE0FF90008AE036
:1009700022E02400F582E43400F58322E02444F5EB
:1009800082E43400F583229000887402F022900003
:100990008BE0FF900089E022120A79120A80120A85
:1009A00087120A5C120AA3120A25120A3B120A666F
:1009B00012005E120A8E120A95120AA7020A9CAF52
:1009C000885388EF758C0BEF54104288C2DE43DBEE
:1009D0000153DAFED2DEE49000D2F09000D1F09024
:1009E00000D004F022AE077FAA1209EEAF069000F5
:1009F0008CE0B4440312098790008C12097CEFF05C
:100A000090008CE004F022AB07AF04EB14600C14F0
:100A1000600E2402700E8DFB8FFC228DE98FEA227E
:100A20008DEB8FEC22AF885388AF758C0B758D964C
:100A3000EF5440FEEF54104E428822E59154045387
:100A400091FB7595FF7594FF7593FF7592864291A2
:100A5000221209E57F551209EE020AAE75E34075D0
:100A6000E10175E20222758E447589224388502285
:100A700053984FEB4F4DF598227597DE7597AD2241
:100A800075A41175D4CE2275A54175D5772253F77B
:100A90007F75DA4A2253F77F75DB302275E6907551
:100AA000A89022E4F5A92243981022C2DE22D2990E
:030AB000222222DD
:00000001FF

View File

@ -0,0 +1,8 @@
"./lib/efm8bb1/peripheralDrivers/src/pca_0.OBJ",
"./lib/efm8bb1/peripheralDrivers/src/uart_0.OBJ",
"./src/InitDevice.OBJ",
"./src/RF_Bridge_main.OBJ",
"./src/RF_Handling.OBJ",
"./src/SILABS_STARTUP.OBJ",
"./src/uart.OBJ"
TO "RF_BRIDGE.OMF.CRBUILD" REMOVEUNUSED PRINT(.\RF_Bridge.m51) PAGEWIDTH (120) PAGELENGTH (65) CLASSES( CODE(C:0x0 - C:0x1ffe), CONST(C:0x0 - C:0x1ffe), ECODE(C:0x0 - C:0x1ffe), HCONST(C:0x0 - C:0x1ffe), XDATA(X:0x0 - X:0xff), HDATA(X:0x0 - X:0xff))

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,52 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Keil tools exit code 1 is warnings only, so don't treat as an error in make
RC := test $$? -lt 2
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include src/subdir.mk
-include lib/efm8bb1/peripheralDrivers/src/subdir.mk
-include subdir.mk
-include objects.mk
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: RF_Bridge.omf
# Tool invocations
RF_Bridge.omf: echo_path $(OBJS)
@echo 'Building target: $@'
@echo 'Invoking: Keil 8051 Linker'
LX51 "@RF_Bridge.lnp" || $(RC)
@echo 'Finished building target: $@'
# Change from all upper case to the expected case
@-mv "RF_BRIDGE.OMF.CRBUILD" "$@"
# Generate hex file: RF_Bridge.hex
@Ohx51 "RF_Bridge.omf" "HEXFILE (RF_Bridge.hex)" "H386" 2>&1 >/dev/null
# Other Targets
clean:
-$(RM) $(EXECUTABLES)$(OBJS) RF_Bridge.omf
-@echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets
# echo the path
echo_path:
@echo PATH=$$PATH
@echo ' '

View File

@ -0,0 +1,8 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS :=

View File

@ -0,0 +1,18 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
A51_UPPER_SRCS :=
OBJ_UPPER_SRCS :=
SRC_UPPER_SRCS :=
ASM_SRCS :=
C_SRCS :=
S_UPPER_SRCS :=
EXECUTABLES :=
OBJS :=
# Every subdirectory with source files must be described here
SUBDIRS := \
lib/efm8bb1/peripheralDrivers/src \
src \

58
README.md Normal file
View File

@ -0,0 +1,58 @@
# RF-Bridge-EFM8BB1
RF-Bridge-EFM8BB1
The Sonoff RF Bridge is only supporting one protocol with 24 bits.<br/>
The Idea is to write a alternative firmware for the onboard EFM8BB1 chip.
# Hardware
There are the pins C2 & C2CK on the board. With a Arduino you can build a programmer to read/erase and program the flash.
Software for the Arduino: https://github.com/conorpp/efm8-arduino-programmer
# Software
The project is written with Simplicity Studio 4. The resulting *.hex file can be programmed on the EFM8BB1.
# First results
The reading of RF signals is already working:<br/>
Sending start sniffing: 0xAA 0xA6 0x55<br/>
Receiving AKN: 0xAA 0xA0 0x55<br/>
Sending stop sniffing: 0xAA 0xA7 0x55<br/>
Receiving AKN: 0xAA 0xA0 0x55<br/>
## RF decode from Rohrmotor24.de remote (40 bit of data):
0xAA: uart sync init<br/>
0xA6: sniffing active<br/>
0x06: data len<br/>
0x01: protocol identifier<br/>
0xD0-0x55: data<br/>
0x55: uart sync end
STOP:<br/>
Binary: 10101010 10100110 00000110 00000001 11010000 11111001 00110010 00010001 01010101 01010101<br/>
Hex: AA A6 06 01 D0 F9 32 11 55 55<br/>
DOWN:<br/>
Binary: 10101010 10100110 00000110 00000001 11010000 11111001 00110010 00010001 00110011 01010101<br/>
Hex: AA A6 06 01 D0 F9 32 11 33 55<br/>
## RF decode from Seamaid_PAR_56_RGB remote (24 bit of data):
Light ON:<br/>
Binary: 10101010 10100110 00000100 00000010 00110010 11111010 10001111 01010101<br/>
Hex: AA A6 04 02 32 FA 8F 55<br/>
## Transmiting by command 0xA8
There is already a new command in the firmware to be able to send RF data.<br/>
The original command isn't supported yet!<br/>
Hex: AA A8 06 01 D0 F9 32 11 33 55<br/>
0xAA: uart sync init<br/>
0xA8: transmit RF data<br/>
0x06: data len<br/>
0x01: protocol identifier (ROHRMOTOR24)<br/>
0xD0-0x55: data<br/>
0x55: uart sync end
# Next Steps
Add full support for the original firmware<br/>
Add ESPurna support:<br/>
A new protocol have to be implemented to support more RF signals -> have to be defined!

101
RF_Bridge.hwconf Normal file
View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM8BB10F8G-A-QFN20" partId="mcu.8051.efm8.bb1.efm8bb10f8g-a-qfn20" version="4.0.1" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="CLOCK_0" propertyId="ABPeripheral.included" value="true"/>
<property object="CLOCK_0" propertyId="clock.clockselect.clocksourcedivider" value="SYSCLK / 1"/>
<property object="CLOCK_0" propertyId="clock.clockselect.sysclk" value="24.500 MHz"/>
<property object="CROSSBAR0" propertyId="xbar0.pca0.cex" value="CEX0 and CEX1"/>
<property object="CROSSBAR0" propertyId="xbar0.uart0.data" value="Enabled"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="INTERRUPT_0" propertyId="ABPeripheral.included" value="true"/>
<property object="INTERRUPT_0" propertyId="interrupt.extendedinterruptenable1.enableprogrammablecounterarraypca0interrupt" value="Enabled"/>
<property object="INTERRUPT_0" propertyId="interrupt.extendedinterruptenable1.enabletimer3interrupt" value="Enabled"/>
<property object="INTERRUPT_0" propertyId="interrupt.interruptenable.enableallinterrupts" value="Enabled"/>
<property object="INTERRUPT_0" propertyId="interrupt.interruptenable.enableuart0interrupt" value="Enabled"/>
<property object="INTERRUPT_0" propertyId="interruptenables.codegenerationoptions.generateinterruptfunctions" value="Disabled"/>
<property object="P0.0" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P0.0" propertyId="ports.settings.label" value="T_DATA"/>
<property object="P0.0" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P0.1" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.2" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.3" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.4" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P0.4" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P0.6" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.7" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P1.0" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P1.0" propertyId="ports.settings.label" value="LED"/>
<property object="P1.0" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P1.0" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P1.1" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P1.2" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P1.3" propertyId="ports.settings.label" value="R_DATA"/>
<property object="P1.4" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P1.5" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P1.6" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P1.6" propertyId="ports.settings.label" value="BUZZER"/>
<property object="P1.6" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P1.6" propertyId="ports.settings.skip" value="Skipped"/>
<property object="PBCFG_0" propertyId="pbcfg.settings.enablecrossbar" value="Enabled"/>
<property object="PCACH_0" propertyId="ABPeripheral.included" value="true"/>
<property object="PCACH_0" propertyId="pcach.pcachannel.cex0outputpolarity" value="Inverted"/>
<property object="PCACH_0" propertyId="pcach.pcachannel.matchfunction" value="Enabled"/>
<property object="PCACH_0" propertyId="pcach.pcachannelcapturecomparemode.enablechannelcomparatorfunction" value="Enabled"/>
<property object="PCACH_0" propertyId="pcach.pcachannelcapturecomparemode.enablechannelpulsewidthmodulationmoden" value="Enabled"/>
<property object="PCACH_0" propertyId="pcach.pcacontrol.channelcapturecomparemode" value="Predefined 8~11-bit pulse modulator"/>
<property object="PCACH_1" propertyId="ABPeripheral.included" value="true"/>
<property object="PCACH_1" propertyId="pcach.pcachannelcapturecomparemode.enablechannelcapturenegativefunction" value="Enabled"/>
<property object="PCACH_1" propertyId="pcach.pcachannelcapturecomparemode.enablechannelcapturepositivefunction" value="Enabled"/>
<property object="PCACH_1" propertyId="pcach.pcacontrol.channelcapturecomparemode" value="Capture on transition of CEX"/>
<property object="PCACH_2" propertyId="ABPeripheral.included" value="true"/>
<property object="PCA_0" propertyId="ABPeripheral.included" value="true"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.enablepcacountertimeroverflowinterrupt" value="Enabled"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.pcaclockfrequency" value="100.000 kHz"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.pcaclockfrequencyintegervalue" value="100000"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.pcaclockperiod" value="10.000 uS"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.pcacontertimerlowbyte" value="255"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.pcacountertimer" value="255"/>
<property object="PCA_0" propertyId="pca.pcacountertimerconfiguration.selectpcacountertimerpulse" value="Timer 0 overflow"/>
<property object="PCA_0" propertyId="pca.pcapwmconfiguration.cex0outputpolarity" value="Inverted"/>
<property object="PCA_0" propertyId="pca.pcapwmconfiguration.enablecycleoverflowinterrupt" value="Enabled"/>
<property object="TIMER01_0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER01_0" propertyId="timer01.timer0highbyte.timer0highbyte" value="11"/>
<property object="TIMER01_0" propertyId="timer01.timer0mode2:8bitcountertimerwithautoreload.targetoverflowfrequency" value="100000"/>
<property object="TIMER01_0" propertyId="timer01.timer0mode2:8bitcountertimerwithautoreload.timerreloadvalue" value="11"/>
<property object="TIMER01_0" propertyId="timer01.timer1highbyte.timer1highbyte" value="150"/>
<property object="TIMER01_0" propertyId="timer01.timer1mode2:8bitcountertimerwithautoreload.targetoverflowfrequency" value="19200"/>
<property object="TIMER01_0" propertyId="timer01.timer1mode2:8bitcountertimerwithautoreload.timerreloadvalue" value="150"/>
<property object="TIMER16_2" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_3" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_3" propertyId="timer16.control.clocksource" value="SYSCLK"/>
<property object="TIMER16_3" propertyId="timer16.highbyte.highbyte" value="255"/>
<property object="TIMER16_3" propertyId="timer16.initandreloadvalue.targetoverflowfrequency" value="200000"/>
<property object="TIMER16_3" propertyId="timer16.initandreloadvalue.timerinitvalue" value="65535"/>
<property object="TIMER16_3" propertyId="timer16.initandreloadvalue.timerreloadvalue" value="65414"/>
<property object="TIMER16_3" propertyId="timer16.lowbyte.lowbyte" value="255"/>
<property object="TIMER16_3" propertyId="timer16.reloadhighbyte.reloadhighbyte" value="255"/>
<property object="TIMER16_3" propertyId="timer16.reloadlowbyte.reloadlowbyte" value="134"/>
<property object="TIMER_SETUP_0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.clockcontrol.timer0clockselect" value="Use SYSCLK"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.clockcontrol.timer3lowbyteclockselect" value="Use SYSCLK"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer0.clocksource" value="Use SYSCLK"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer0.mode" value="Mode 2, 8-bit Counter/Timer with Auto-Reload"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer0.timerrunningstate" value="Timer is Running"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer0.timerswitch1:runcontrol" value="Start"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer01control.timer0runcontrol" value="Start"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer01control.timer1runcontrol" value="Start"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.mode" value="Mode 2, 8-bit Counter/Timer with Auto-Reload"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.timerrunningstate" value="Timer is Running"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.timerswitch1:runcontrol" value="Start"/>
<property object="UART_0" propertyId="ABPeripheral.included" value="true"/>
<property object="UART_0" propertyId="uart.serialportcontrol.enablereceive" value="Enabled"/>
<property object="WDT_0" propertyId="ABPeripheral.included" value="true"/>
<property object="WDT_0" propertyId="wdt.watchdogcontrol.wdtenable" value="Disable"/>
<property object="WDT_0" propertyId="wdt.watchdogcontrol.wdtinitialvalue" value="5"/>
<property object="WDT_0" propertyId="wdt.watchdogcontrol.wdtperiodactual" value="6.554 s"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

27
inc/Globals.h Normal file
View File

@ -0,0 +1,27 @@
/*
* Globals.h
*
* Created on: 27.11.2017
* Author:
*/
#ifndef INC_GLOBALS_H_
#define INC_GLOBALS_H_
// USER CONSTANTS
#define LED_ON 1
#define LED_OFF 0
#define BUZZER_ON 1
#define BUZZER_OFF 0
#define TDATA_ON 1
#define TDATA_OFF 0
// USER PROTOTYPES
SI_SBIT(LED, SFR_P1, 0); // LED
SI_SBIT(T_DATA, SFR_P0, 0); // T_DATA
SI_SBIT(R_DATA, SFR_P1, 3); // R_DATA
SI_SBIT(BUZZER, SFR_P1, 6); // BUZZER
#endif /* INC_GLOBALS_H_ */

35
inc/InitDevice.h Normal file
View File

@ -0,0 +1,35 @@
//=========================================================
// inc/InitDevice.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
#ifndef __INIT_DEVICE_H__
#define __INIT_DEVICE_H__
// USER CONSTANTS
// USER PROTOTYPES
// $[Mode Transition Prototypes]
extern void enter_DefaultMode_from_RESET(void);
// [Mode Transition Prototypes]$
// $[Config(Per-Module Mode)Transition Prototypes]
extern void WDT_0_enter_DefaultMode_from_RESET(void);
extern void PORTS_0_enter_DefaultMode_from_RESET(void);
extern void PORTS_1_enter_DefaultMode_from_RESET(void);
extern void PBCFG_0_enter_DefaultMode_from_RESET(void);
extern void CLOCK_0_enter_DefaultMode_from_RESET(void);
extern void TIMER01_0_enter_DefaultMode_from_RESET(void);
extern void TIMER16_3_enter_DefaultMode_from_RESET(void);
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void);
extern void PCA_0_enter_DefaultMode_from_RESET(void);
extern void PCACH_0_enter_DefaultMode_from_RESET(void);
extern void PCACH_1_enter_DefaultMode_from_RESET(void);
extern void UART_0_enter_DefaultMode_from_RESET(void);
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void);
// [Config(Per-Module Mode)Transition Prototypes]$
#endif

48
inc/RF_Handling.h Normal file
View File

@ -0,0 +1,48 @@
/*
* RF_Handling.h
*
* Created on: 28.11.2017
* Author:
*/
#ifndef INC_RF_HANDLING_H_
#define INC_RF_HANDLING_H_
extern void SendRF_SYNC(uint8_t used_protocol);
extern uint8_t PCA0_DoTransmit(uint8_t identifier);
extern void PCA0_StopTransmit(void);
extern void PCA0_DoSniffing(void);
extern void PCA0_StopSniffing(void);
#define SYSCLK 24500000
// 64 byte == 512 bits, so a RF signal with maximum of 512 bits is possible
#define RF_DATA_BUFFERSIZE 64
typedef enum
{
RF_IDLE,
RF_IN_SYNC
} rf_state_t;
#define RF_DATA_RECEIVED_MASK 0x80
extern SI_SEGMENT_VARIABLE(RF_DATA[RF_DATA_BUFFERSIZE], uint8_t, SI_SEG_XDATA);
// RF_DATA_STATUS
// Bit 7: 1 Data received, 0 nothing received
// Bit 6-0: Protocol identifier
extern SI_SEGMENT_VARIABLE(RF_DATA_STATUS, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(Timer_3_Timeout, uint16_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(sniffing_is_on, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(DUTY_CYCLE_HIGH, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(DUTY_CYLCE_LOW, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(actual_bit_of_byte, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(actual_bit, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(actual_byte, uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(protocol_index, uint8_t, SI_SEG_XDATA);
extern uint8_t testbyte;
#endif /* INC_RF_HANDLING_H_ */

60
inc/RF_Protocols.h Normal file
View File

@ -0,0 +1,60 @@
/*
* RF_Protocols.h
*
* Created on: 28.11.2017
* Author:
*/
#ifndef INC_RF_PROTOCOLS_H_
#define INC_RF_PROTOCOLS_H_
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <stdint.h>
typedef struct
{
// Protocol specific identifier
uint8_t IDENTIFIER;
// normal high signal time on sync pulse
uint16_t SYNC_HIGH;
// normal low signal time on sync pulse
uint16_t SYNC_LOW;
// time in µs for one bit. This is the sum of the high and low time of on bit
// example bit 1: high time 700µs, low time 300µs: sum is 1000µs == 1kHz
uint16_t BIT_TIME;
// duty cycle for logic bit 1
uint8_t BIT_HIGH_DUTY;
// duty cycle for logic bit 0
uint8_t BIT_LOW_DUTY;
// bit count for this protocol
uint8_t BIT_COUNT;
} PROTOCOL_DATA_t;
#define SYNC_TOLERANCE 200
/*
* Rohrmotor24
* https://github.com/bjwelker/Raspi-Rollo/tree/master/Arduino/Rollo_Code_Receiver
*/
#define ROHRMOTOR24_IDENTIFIER 0x01
#define ROHRMOTOR24 {ROHRMOTOR24_IDENTIFIER, 4800, 1500, 1000, 30, 70, 40}
/*
* UNDERWATER PAR56 LED LAMP, 502266
* http://www.seamaid-lighting.com/de/produit/lampe-par56/
*/
#define Seamaid_PAR_56_RGB_IDENTIFIER 0x02
#define Seamaid_PAR_56_RGB {Seamaid_PAR_56_RGB_IDENTIFIER, 3000, 9000, 1500, 25, 75, 24}
/*
* Protocol array
*/
static const PROTOCOL_DATA_t PROTOCOL_DATA[2] = { ROHRMOTOR24, Seamaid_PAR_56_RGB};
#define PROTOCOLCOUNT sizeof PROTOCOL_DATA / sizeof PROTOCOL_DATA[0]
#endif /* INC_RF_PROTOCOLS_H_ */

15
inc/efm8_config.h Normal file
View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2014 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef __EFM8_CONFIG_H__
#define __EFM8_CONFIG_H__
#define EFM8PDL_PCA0_USE_ISR 1
#define EFM8PDL_UART0_USE_STDIO 0
#define EFM8PDL_UART0_USE_BUFFER 0
#endif // __EFM8_CONFIG_H__

74
inc/uart.h Normal file
View File

@ -0,0 +1,74 @@
/*
* uart.h
*
* Created on: 28.11.2017
* Author:
*/
#ifndef INC_UART_H_
#define INC_UART_H_
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
//#define UART_BUFFER_LENGTH 64 + 4
#define UART_SYNC_INIT 0xAA
#define UART_SYNC_END 0x55
#define UART_BUFFER_SIZE 64 + 4
/*
** high byte error return code of uart_getc()
*/
#define UART_FRAME_ERROR 0x1000 /* Framing Error by UART */
#define UART_OVERRUN_ERROR 0x0800 /* Overrun condition by UART */
#define UART_PARITY_ERROR 0x0400 /* Parity Error by UART */
#define UART_BUFFER_OVERFLOW 0x0200 /* receive ringbuffer overflow */
#define UART_NO_DATA 0x0100 /* no receive data available */
//-----------------------------------------------------------------------------
// Global Enums
//-----------------------------------------------------------------------------
typedef enum
{
IDLE,
SYNC_INIT,
SYNC_FINISH,
RECEIVE_LEN,
RECEIVING,
TRANSMIT,
COMMAND
} uart_state_t;
typedef enum
{
NONE = 0x00,
COMMAND_AK = 0xA0,
LEARNING = 0xA1,
TIMEOUT_EXITS = 0xA2,
LEARNING_SUCCESS = 0xA3,
FORWARD_RF_KEY = 0xA4,
TRANSMIT_KEY = 0xA5,
SNIFFING_ON = 0xA6,
SNIFFING_OFF = 0xA7,
TRANSMIT_DATA = 0xA8
} uart_command_t;
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
extern SI_SEGMENT_VARIABLE(UART_RX_Buffer[UART_BUFFER_SIZE], uint8_t, SI_SEG_XDATA);
extern SI_SEGMENT_VARIABLE(UART_TX_Buffer[UART_BUFFER_SIZE], uint8_t, SI_SEG_XDATA);
extern uart_state_t uart_state;
extern void uart_buffer_reset(void);
extern uint8_t uart_getlen(void);
extern bool uart_transfer_finished(void);
extern unsigned int uart_getc(void);
extern void uart_putc(uint8_t txdata);
extern void uart_put_command(uint8_t command);
extern void uart_put_uint16_t(uint8_t command, uint16_t value);
extern void uart_put_RF_Data(uint8_t Command, uint8_t used_protocol);
#endif /* INC_UART_H_ */

View File

@ -0,0 +1,601 @@
/******************************************************************************
* Copyright (c) 2014 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef __PCA_0_H__
#define __PCA_0_H__
#include "efm8_config.h"
#include "SI_EFM8BB1_Register_Enums.h"
/**************************************************************************//**
* @addtogroup pca_0 PCA0 Driver
* @{
*
* @brief Peripheral driver for PCA0
*
* # Introduction #
*
* This module contains all the driver content for PCA0
*
* @warning The WDT0 module on this device interacts with the PCA.
*
* ### Memory Usage ###
*
* The table below shows the memory consumption of the library with various
* options. The 'default' entry shows the consumption when most or all available
* functions are called. Typical consumption is expected to be less than this
* since there are normally many uncalled functions that will consume no
* resources.
*
* @note It is possible for memory usage to exceed the listed values in rare cases
*
* | condition | CODE | XRAM | IRAM | RAM |
* |--------------------|------|------|------|-----|
* |default | 504 | 0 | 0 | 0 |
*
* # Theory of Operation #
*
* The Programable counter array provides 3 main catagories of functionality.
*
* - PWM
* - Counter/capture
* - Timer
*
* It consists of a single counter/timer and several channels which all operate
* using the single counter.
*
* ### Timer operations ###
*
* The PCA can be used to provide basic timer operations. The timer period
* is determined by the timer configuration. Each PCA channel may fire an
* interrupt at an independent point in the period. For example We may set up
* the timer to overflow (and provide an interrupt) every 100 cycles. We can
* then configure on channel to provide an interrupt at 90 cycles and another
* at 50 cycles. This would generate a 'half-way' and 'early-warning'
* interrupts.
*
* ### PWM operations ###
*
* The PCA can be configured to output PWM waveforms (or square waveforms).
* The period of the PWM is controlled by the time an thus the same for all
* channels. The duty cycle and polarity is controlled by each channel
* independently.
*
* A related mode is high frequency output mode where each PCA channel can be
* configured to toggle it's output ever N ticks of the timer. This allows
* each module to independently generate a digital frequency.
*
* ### Capture operations ###
*
* The state of the timer can be captured by a PCA channel based on several
* triggers. The captured value can then be used for various operations.
*
* For example if channel 0 captures on the rising edge of a signal and
* channel 0 captures on the falling edge of that same signal then the
* high pulse with time can be calculated by the equation.
* time = (ch1_value - ch0_value) * period_of_timer
*
* Another mode of operation is to
*
* ### Watch Dog Timer ###
*
* While the Peripheral Driver Library defines a separate module for interacting with the
* watch-dog timer the WDT is physically located in channel 4 of the PCA on this device.
* Any changes to the counter in the WDT or PCA block will effect the other block. In
* addition when the WDT is in used PCA channel 4 is unavailable.
*
* Runtime asserts have been placed in this module to help highlight cases where the
* WDT and PCA interfere with one another. However it is not possible to catch all
* issues and the user needs to be aware of this interaction.
*
* ### Hardware Configuration ###
*
* This driver provides basic facilities for configuring the PCA.
* it is recommended that Simplicity Hardware Configurator be for more
* advanced configuration as it provides more comprehensive validation
* of user selections.
*
*****************************************************************************/
//Option macro documentation
/**************************************************************************//**
* @addtogroup pca0_config Driver Configuration
* @{
*****************************************************************************/
/**************************************************************************//**
* @def EFM8PDL_PCA0_USE_ISR
* @brief Controls inclusion of PCA0 ISR and associated callbacks.
*
* When '1' the PCA0 ISR in the driver is used and callbacks are functional.
*
* Default setting is '1' and may be overridden by defining in 'efm8_config.h'.
*
*****************************************************************************/
/** @} (end addtogroup pca0_config Driver Configuration) */
//Configuration defaults
#ifndef IS_DOXYGEN
#define IS_DOXYGEN 0
#endif
#ifndef EFM8PDL_PCA0_USE_ISR
#define EFM8PDL_PCA0_USE_ISR 1
#endif
// Runtime API
/**************************************************************************//**
* @addtogroup pca0_runtime PCA0 Runtime API
* @{
*****************************************************************************/
/// PCA Channel Enumeration
typedef enum
{
PCA0_CHAN0 = 0x0, //!< PCA Channel 0
PCA0_CHAN1 = 0x1, //!< PCA Channel 1
PCA0_CHAN2 = 0x2, //!< PCA Channel 2
#if IS_DOXYGEN
PCA0_CHAN3 = -1, //!< NOT SUPPORTED ON THIS DEVICE
PCA0_CHAN4 = -1, //!< NOT SUPPORTED ON THIS DEVICE
PCA0_CHAN5 = -1, //!< NOT SUPPORTED ON THIS DEVICE
#endif
} PCA0_Channel_t;
/**************************************************************************//**
* @addtogroup pca0_if Interrupt Flag Enums
* @{
******************************************************************************/
#define PCA0_OVERFLOW_IF PCA0CN0_CF__BMASK //!< Counter overflow flag
#define PCA0_IOVERFLOW_IF PCA0PWM_COVF__BMASK //!< Intermediate overflow flag
#define PCA0_CHAN0_IF PCA0CN0_CCF0__BMASK //!< Channel 0
#define PCA0_CHAN1_IF PCA0CN0_CCF1__BMASK //!< Channel 1
#define PCA0_CHAN2_IF PCA0CN0_CCF2__BMASK //!< Channel 2
#if IS_DOXYGEN
#define PCA0_CHAN3_IF -1 //!< @warning NOT SUPPORTED ON THIS DEVICE
#define PCA0_CHAN4_IF -1 //!< @warning NOT SUPPORTED ON THIS DEVICE
#define PCA0_CHAN5_IF -1 //!< @warning NOT SUPPORTED ON THIS DEVICE
#endif
/** @} (end addtogroup pca0_if Interrupt Flag Enums) */
/***************************************************************************//**
* @brief
* Return the value of the interrupt flags
*
* @return
* The state of the flags. This value is the OR of all flags which are set.
*
* Valid enums can be fond in the Interrupt Flag Enums group.
*
******************************************************************************/
uint8_t PCA0_getIntFlags();
/***************************************************************************//**
* @brief
* Clear the specified status flag
*
* @param flag:
* Flag to clear. Multiple flags can be cleared by OR-ing the flags.
*
* Valid enums can be found in the Interrupt Flag Enums group.
******************************************************************************/
void PCA0_clearIntFlag(uint8_t flag);
/***************************************************************************//**
* @brief
* Enable or disable the PCA interrupts
*
* @param flag:
* Interrupt to be enabled/disabled
* @param enable:
* New target status (true to enable)
*
* Multiple interrupts may be enabled/disabled at a time by or-ing their flags
*
* Valid enums can be found in the Interrupt Flag Enums group.
*
******************************************************************************/
void PCA0_enableInt(uint8_t flag, bool enable);
/***************************************************************************//**
* @brief
* Read the channel capture/compare register
*
* @param channel:
* Channel to read.
*
* @return
* Current value of capture/compare register for the specified channel.
*
******************************************************************************/
uint16_t PCA0_readChannel(PCA0_Channel_t channel);
/***************************************************************************//**
* @brief
* Write the channel capture.compare register
*
* @param channel:
* Channel to read.
* @param value:
* Value to write to capture/compare register.
*
******************************************************************************/
void PCA0_writeChannel(PCA0_Channel_t channel, uint16_t value);
/***************************************************************************//**
* @brief
* Read the PCA counter.
*
* @return
* Current value of the PCA counter.
******************************************************************************/
uint16_t PCA0_readCounter();
/***************************************************************************//**
* @brief
* Write to the PCA counter.
*
* @param value:
* Value to write to PCA counter.
*
******************************************************************************/
void PCA0_writeCounter(uint16_t value);
/***************************************************************************//**
* @brief
* Start the PCA Counter.
*
******************************************************************************/
void PCA0_run();
/***************************************************************************//**
* @brief
* Stop the PCA Counter.
*
******************************************************************************/
void PCA0_halt();
/** @} (end addtogroup pca0_runtime PCA0 Runtime API) */
// Initialization API
/**************************************************************************//**
* @addtogroup pca0_init PCA0 Initialization API
* @{
*****************************************************************************/
/// @brief Clock Selection Enum.
typedef enum
{
PCA0_SYSCLK_DIV12 = PCA0MD_CPS__SYSCLK_DIV_12, //!< Select SystemClock/12
PCA0_SYSCLK_DIV4 = PCA0MD_CPS__SYSCLK_DIV_4, //!< Select SystemClock/4
PCA0_TIMER0 = PCA0MD_CPS__T0_OVERFLOW, //!< Select Timer0 Overflow
PCA0_ECI = PCA0MD_CPS__ECI, //!< Select ECI falling edge
PCA0_SYSCLK = PCA0MD_CPS__SYSCLK, //!< Select SystemClock
PCA0_EXTOSC_DIV8 = PCA0MD_CPS__EXTOSC_DIV_8, //!< Select ExternalOsc/8
PCA0_LFOSC_DIV8 = PCA0MD_CPS__LFOSC_DIV_8, //!< Select LowFrequencyOsc/8
} PCA0_Timebase_t;
/// @brief Channel mode enum.
typedef enum
{
//xx10 000* (CPM) 0x20
//0x*0 0xxx (PWM)
PCA0_CAPTURE_POS_CEX = PCA0CPM0_PWM16__8_BIT //!< Capture mode triggered by CEX rising
| PCA0CPM0_ECOM__DISABLED
| PCA0CPM0_CAPP__ENABLED
| PCA0CPM0_CAPN__DISABLED
| PCA0CPM0_MAT__DISABLED
| PCA0CPM0_TOG__DISABLED
| PCA0CPM0_PWM__DISABLED,
//xx01 000* (CPM) 0x10
//0x*0 0xxx (PWM)
PCA0_CAPTURE_NEG_CEX = PCA0CPM0_PWM16__8_BIT //!< Capture mode triggered by CEX falling
| PCA0CPM0_ECOM__DISABLED
| PCA0CPM0_CAPP__DISABLED
| PCA0CPM0_CAPN__ENABLED
| PCA0CPM0_MAT__DISABLED
| PCA0CPM0_TOG__DISABLED
| PCA0CPM0_PWM__DISABLED,
//xx11 000* (CPM) 0x30
//0x*0 0xxx (PWM)
PCA0_CAPTUE_TOGGLE_CEX = PCA0CPM0_PWM16__8_BIT //!< Capture Mode triggered by CEX rising or falling
| PCA0CPM0_ECOM__DISABLED
| PCA0CPM0_CAPP__ENABLED
| PCA0CPM0_CAPN__ENABLED
| PCA0CPM0_MAT__DISABLED
| PCA0CPM0_TOG__DISABLED
| PCA0CPM0_PWM__DISABLED,
//x100 100* (CPM) 0x48
//0x*0 0xxx (PWM)
PCA0_TIMER = PCA0CPM0_PWM16__8_BIT //!< Timer mode
| PCA0CPM0_ECOM__ENABLED
| PCA0CPM0_CAPP__DISABLED
| PCA0CPM0_CAPN__DISABLED
| PCA0CPM0_MAT__ENABLED
| PCA0CPM0_TOG__DISABLED
| PCA0CPM0_PWM__DISABLED,
//x100 110* (CPM) 0x4C
//0x*0 0xxx (PWM)
PCA0_HIGH_SPEED_OUT = PCA0CPM0_PWM16__8_BIT //!< High speed output mode
| PCA0CPM0_ECOM__ENABLED
| PCA0CPM0_CAPP__DISABLED
| PCA0CPM0_CAPN__DISABLED
| PCA0CPM0_MAT__ENABLED
| PCA0CPM0_TOG__ENABLED
| PCA0CPM0_PWM__DISABLED,
//x100 011* (CPM) 0x46
//0x*0 0xxx (PWM)
PCA0_FREQUENCY_OUT = PCA0CPM0_PWM16__8_BIT //!< High frequency output mode
| PCA0CPM0_ECOM__ENABLED
| PCA0CPM0_CAPP__DISABLED
| PCA0CPM0_CAPN__DISABLED
| PCA0CPM0_MAT__DISABLED
| PCA0CPM0_TOG__ENABLED
| PCA0CPM0_PWM__ENABLED,
//0111 101* (CPM) 0x4A
//10*0 0000 (PWM) 0x80
PCA0_PWM8 = PCA0CPM0_PWM16__8_BIT //!< 8-bit PWM (edge aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__8_BITS,
PCA0_PWM8_CENTER = PCA0CPM0_PWM16__8_BIT //!< 8-bit PWM (center aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__8_BITS
| 0x08, //center alignment
//0111 101* (CPM) 0x4A
//10*0 0001 (PWM) 0x81
PCA0_PWM9 = PCA0CPM0_PWM16__8_BIT //!< 9-bit PWM (edge aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__9_BITS,
PCA0_PWM9_CENTER = PCA0CPM0_PWM16__8_BIT //!< 9-bit PWM (center aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__9_BITS
| 0x08, //center alignment
//0111 101* (CPM) 0x4A
//10*0 0010 (PWM) 0x82
PCA0_PWM10 = PCA0CPM0_PWM16__8_BIT //!< 10-bit PWM (edge aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__10_BITS,
PCA0_PWM10_CENTER = PCA0CPM0_PWM16__8_BIT //!< 10-bit PWM (center aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__10_BITS
| 0x08, //center alignment
//0111 101* (CPM) 0x4A
//10*0 0011 (PWM) 0x83
PCA0_PWM11 = PCA0CPM0_PWM16__8_BIT //!< 11-bit PWM (edge aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__11_BITS,
PCA0_PWM11_CENTER = PCA0CPM0_PWM16__8_BIT //!< 11-bit PWM (center aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__11_BITS
| 0x08, //center alignment
//1111 101* (CPM) 0xCA
//00*0 0xxx (PWM) 0x00
PCA0_PWM16 = PCA0CPM0_PWM16__16_BIT //!< 16-bit PWM (edge aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__11_BITS,
//1111 101* (CPM) 0xCA
//00*0 0xxx (PWM) 0x00
PCA0_PWM16_CENTER = PCA0CPM0_PWM16__16_BIT //!< 16-bit PWM (center aligned)
| PCA0CPM0_ECOM__ENABLED
| 0x30 //Code for n-bit PWM
| PCA0PWM_CLSEL__11_BITS
| 0x08, //center alignment
} PCA0_ChannelMode_t;
/// @brief Output Polarity enum.
typedef enum
{
PCA0_NORMAL_POLARITY = 0x0, //!< normal channel out
PCA0_INVERT_POLARITY = 0x1, //!< normal channel out
} PCA0_ChannelOutPolatiry_t;
/// @brief Idle state of PCA Counter
typedef enum
{
PCA0_IDLE_RUN = PCA0MD_CIDL__NORMAL, //!< PCA runs when idle
PCA0_IDLE_SUSPEND = PCA0MD_CIDL__SUSPEND, //!< PCA suspended when idle
} PCA0_IdleState_t;
/***************************************************************************//**
* @brief Initialize the PCA
*
* @param timebase:
* Timebase selection.
* @param idleState:
* Idle state selection.
*
******************************************************************************/
void PCA0_init(PCA0_Timebase_t timebase, PCA0_IdleState_t idleState);
/**************************************************************************//**
* @brief
* Initialize the PCA Channel.
*
* @param channel:
* The channel to initialize.
* @param mode:
* The desired mode for this channel.
* @param pol:
* Desired output polarity for this channel.
*
* This function initialized the PCA channel including setting up
* the shared PCA0PWM register.
*
* @warning
* All channels in 8-11 bit PWM mode must be in the same
* mode. You can not use 8-bit PWM for one channel and 11-bit PWM
* for another. The N-bit PWM mode will be set to whatever was
* specified in the last call to PCA0_init Channel.
*
*****************************************************************************/
void PCA0_initChannel(PCA0_Channel_t channel,
PCA0_ChannelMode_t mode,
PCA0_ChannelOutPolatiry_t pol
);
/***************************************************************************//**
* @brief
* Restore the PCA to it's uninitialized (reset) state.
*
* This function restores the entire PCA INCLUDING ALL CHANNELS to default values.
******************************************************************************/
void PCA0_reset();
/***************************************************************************//**
* @brief
* Restore the PCA Channel to it's uninitialized (reset) state.
*
* @param channel:
* Channel to reset;
*
* This function restores only the specified channels to the reset state.
******************************************************************************/
void PCA0_resetChannel(PCA0_Channel_t channel);
/** @} (end addtogroup pca0_init PCA0 Initialization API) */
//=========================================================
// ISR API
//=========================================================
#if (EFM8PDL_PCA0_USE_ISR == 1) || IS_DOXYGEN
/**************************************************************************//**
* @def void PCA0_ISR()
* @brief PCA Interrupt handler (not a callback).
*
* This ISR is provided by the library when EFM8PDL_PCA0_USE_ISR = "1".
*
*****************************************************************************/
#endif //EFM8PDL_PCA0_USE_ISR
// Callbacks
/**************************************************************************//**
* @addtogroup pca0_callback User Callbacks
* @{
*****************************************************************************/
#if (EFM8PDL_PCA0_USE_ISR == 1) || IS_DOXYGEN
/***************************************************************************//**
* @addtogroup pca0_callbacks_isr ISR API
* @{
*
* These callbacks will be called by the library when
* EFM8PDL_PCA0_USE_ISR. If the ISR Api is disabled
* the callbacks do not need to be provided by the user.
*
*****************************************************************************/
/***************************************************************************//**
* @brief
* Callback for overflow of PCA.
*
* This function is defined by the user and called by the peripheral driver the PCA counter overflows.
*
* @warning
* This function is called from an ISR and should be as short as possible.
*
******************************************************************************/
extern void PCA0_overflowCb();
/***************************************************************************//**
* @brief
* Callback for intermediate overflow of PCA.
*
* This function is defined by the user and called by the peripheral driver the
* PCA counter half way point is reached as defined by the N-bit PWM settings.
*
* @warning
* This function is called from an ISR and should be as short as possible
*
******************************************************************************/
extern void PCA0_intermediateOverflowCb();
/***************************************************************************//**
* @brief
* Callback for channel 0 events.
*
* This function is defined by the user and called when there is a capture
* or compare event on channel 0
*
* @warning
* This function is called from an ISR and should be as short as possible.
*
******************************************************************************/
extern void PCA0_channel0EventCb();
/***************************************************************************//**
* @brief
* Callback for channel 1 events.
*
* This function is defined by the user and called when there is a capture
* or compare event on channel 1
*
* @warning
* This function is called from an ISR and should be as short as possible.
*
******************************************************************************/
extern void PCA0_channel1EventCb();
/***************************************************************************//**
* @brief
* Callback for channel 2 events.
*
* This function is defined by the user and called when there is a capture
* or compare event on channel 2
*
* @warning
* This function is called from an ISR and should be as short as possible.
*
******************************************************************************/
extern void PCA0_channel2EventCb();
/**************************************************************************//**
* @def void PCA0_channel3EventCb()
* @warning NOT SUPPORTED ON THIS DEVICE
*****************************************************************************/
/**************************************************************************//**
* @def void PCA0_channel4EventCb()
* @warning NOT SUPPORTED ON THIS DEVICE
*****************************************************************************/
/**************************************************************************//**
* @def void PCA0_channel5EventCb()
* @warning NOT SUPPORTED ON THIS DEVICE
*****************************************************************************/
#endif //EFM8PDL_PCA0_USE_ISR
/** @} (end addtogroup pca0_callbacks_isr ISR API) */
/** @} (end addtogroup pca0_callback User Callbacks) */
/** @} (end addtogroup PCA0 Driver) */
#endif //__PCA_0_H__

View File

@ -0,0 +1,632 @@
/******************************************************************************
* Copyright (c) 2014 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef __UART_0_H__
#define __UART_0_H__
#include "efm8_config.h"
#include "SI_EFM8BB1_Register_Enums.h"
/**************************************************************************//**
*@addtogroup uart_0 UART0 Driver
*@{
*
*@brief Peripheral driver for uart0
*
* # Introduction #
*
* This module contains all the driver content for UART0
*
* ### Memory Usage ###
*
* The table below shows the memory consumption of the library with various
* options. The 'default' entry shows the consumption when most or all available
* functions are called. Typical consumption is expected to be less than this
* since there are normally many uncalled functions that will consume no
* resources.
*
* @note It is possible for memory usage to exceed the listed values in rare cases
*
* | condition | CODE | XRAM | IRAM | RAM |
* |--------------------|------|------|------|-----|
* |USE | 295 | 6 | 0 | 0 |
* |STDIO | 20 | 0 | 0 | 0 |
*
* # Theory of Operation #
*
* The UART driver provides several levels of functionality. Higher level
* functionality is more user friendly but also less broadly applicable.
*
* ### Buffered Api ###
*
* The driver provides high level functions for transferring a buffer of data.
* This functionality is made available by setting EFM8PDL_UART0_USE_BUFFER
* to 1.
*
* This functionality relies on the UART0 interrupt to function and the
* library provides the ISR for that interrupt.
*
* For data transmission the user provides a data buffer and the length of that
* buffer. The driver will then transmit the entire buffer before issuing an
* end-of-transfer callback.
*
* In the following example we implement a ping-pong transmission.
*
* ~~~~~.c
*
* SI_SEGMENT_VARIABLE(bufferA[32], uint8_t, SI_SEG_XDATA);
* SI_SEGMENT_VARIABLE(bufferB[32], uint8_t, SI_SEG_XDATA);
* SI_VARIABLE_SEGMENT_POINTER(curBuffer, uint8_t, SI_SEG_XDATA);
* bool targetA;
*
* // Some other code pushes data to curBuffer and handles
* // kicking the transfer with an initial call to writeBuffer
*
* //when current transfer is complete send switch ping-pong
* // and send all data accumulated in the other buffer.
* // If no data is ready in other buffer we will write
* void UART0_transmitCompleteCb()
* {
* if(targetA)
* {
* //Don't transmit if no data is available
* if(curBuffer == bufferA)
* {
* //Some code to mark that the transfer is stalled
* return;
* }
*
* // Send all data in A and start accumulating in B
* UART0_writeBuffer(bufferA, curBuffer - bufferA);
* curBuffer = bufferB;
* targetA = false;
* }
* else
* {
* //Don't transmit if no data is available
* if(curBuffer == bufferA)
* {
* //Some code to mark that the transfer is stalled
* return;
* }
*
* //send all data in B and start accumulating in A
* UART0_writeBuffer(bufferA, curBuffer - bufferA);
* curBuffer = bufferA;
* targetA = true;
* }
* }
*
* ~~~~~
*
* For reception the user provides a buffer and it's size. The library will
* receive data into the buffer until it is full and then call the user
* back. The user may query the number of bytes remaining in the buffer at
* any time if they wish to process data before the buffer is full.
*
* This example provides ping-pong reception.
*
* ~~~~~.c
*
* SI_SEGMENT_VARIABLE(bufferA[32], uint8_t, SI_SEG_XDATA);
* SI_SEGMENT_VARIABLE(bufferB[32], uint8_t, SI_SEG_XDATA);
* SI_VARIABLE_SEGMENT_POINTER(curBuffer, uint8_t, SI_SEG_XDATA);
* SI_VARIABLE_SEGMENT_POINTER(dataReady, uint8_t, SI_SEG_XDATA);
* bool targetA;
*
* //Here the main loop handles stuff
* void main()
* {
* //other initialization
* UART0_readBuffer(bufferA, 32);
* targetA = true;
*
* while(1)
* {
* if(dataReady != NULL)
* {
* //process data
* dataReady = NULL;
* }
* }
* }
*
* // When the current buffer is full inform the main loop it's
* //ready for processing and switch to the other buffer
* void UART0_receiveCompleteCb()
* {
* if(targetA)
* {
* datReady = bufferA;
* UART0_readBuffer(bufferB, 32);
* targetA = false;
* }
* else
* {
* datReady = bufferB;
* UART0_readBuffer(bufferA, 32);
* targetA = true;
* }
* }
*
* ~~~~~
*
* ### STDIO Api ###
*
* One of the simplest use cases is using UART 0 to stdio data. The driver
* provides a standard blocking implementation accessed by setting
* EFM8PDL_UART0_USE_STDIO.
*
* When this is in use no other functions are available.
*
* When this is in use calls to printf will block until the entire string
* has been transmitted on the uart.
*
* ### Runtime & Initialization API ###
*
* The final option is to use the runtime and initialization api to implement
* a custom uart driver.
*
* The reference manual should be consulted for a full understanding of how
* the block operates in order to use the Runtime api correctly.
*
* ### Hardware Configuration ###
*
* This Driver provides a basic level of configuration through the API. However
* use of the Simplicity Hardware Configuration tool is highly recommended.
*
*****************************************************************************/
// Option macro documentation
/**************************************************************************//**
* @addtogroup uart0_config Driver Configuration
* @{
*****************************************************************************/
/***************************************************************************//**
* @def EFM8PDL_UART0_USE
* @brief Controls inclusion of UART0 Peripheral Driver.
*
*
* When '1' the UART0 driver is available.
*
* Default setting is '0' and may be overridden by defining in 'efm8_config.h'.
*
*****************************************************************************/
/**************************************************************************//**
* @def EFM8PDL_UART0_USE_STDIO
* @brief Controls the inclusion of putchar and setchar for use with printf/scanf.
*
* When '1' blocking implementations of putchar and set char are defined. This option
* is intended to be use in place of all other options. If EFM8PDL_UART0_USE_STDIO
* is '1' then EFM8PDL_UART0_USE should be 0 and the UART 0 peripheral driver should
* not be called by the user directly accept for the initial setup.
*
* The putchar implementation provides an initialization function to prime the TX transfer
* and configure the UART for receive and transmit. This function should be called immediately
* after device configuration and before any printf or scanf calls.
*
* Default setting is '0' and may be overridden by defining in 'efm8_config.h'.
*
*****************************************************************************/
/**************************************************************************//**
* @def EFM8PDL_UART0_USE_INIT
* @brief Controls inclusion of UART0 Initialization API.
*
* When '1' the UART0 Initialization API is included in the driver.
*
* Default setting is '1' and may be overridden by defining in 'efm8_config.h'.
*
*****************************************************************************/
/**************************************************************************//**
* @def EFM8PDL_UART0_USE_BUFFER
* @brief Controls inclusion of UART0 Buffer Access API.
*
* When '1' the UART0 Buffered Access API is included in the driver.
*
* Default setting is '1' and may be overridden by defining in 'efm8_config.h'.
*
*****************************************************************************/
/**************************************************************************//**
* @addtogroup uart0_config_buffered Buffered API Options
* @{
*****************************************************************************/
/**************************************************************************//**
* @def EFM8PDL_UART0_RX_BUFTYPE
* @brief Controls the type of pointer used for buffered receives.
*
* Sets the memory segment for the rx data buffer pointer when EFM8PDL_UART0_USE_BUFFER is '1'
* valid values are:
*
* - SI_SEG_XDATA (default)
* - SI_SEG_PDATA
* - SI_SEG_IDATA
* - SI_SEG_CODE
* - SI_SEG_GENERIC
*
* @warning: Use of generic pointers will adversely effect the size and performance
* of the buffering functions.
*
*****************************************************************************/
/**************************************************************************//**
* @def EFM8PDL_UART0_TX_BUFTYPE
* @brief Controls the type of pointer used for buffered transmits.
*
* Sets the memory segment for the tx data buffer pointer when EFM8PDL_UART0_USE_BUFFER is '1'
* valid values are:
*
* - SI_SEG_XDATA (default)
* - SI_SEG_PDATA
* - SI_SEG_IDATA
* - SI_SEG_CODE
* - SI_SEG_GENERIC
*
*****************************************************************************/
/** @} (end addtogroup uart0_config_buffered Buffered API Optionsn) */
/** @} (end addtogroup uart0_config Driver Configuration) */
// Option macro default values
#ifndef IS_DOXYGEN
#define IS_DOXYGEN 0
#endif
#ifndef EFM8PDL_UART0_USE_STDIO
#define EFM8PDL_UART0_USE_STDIO 0
#endif
#ifndef EFM8PDL_UART0_USE_BUFFER
#if (!EFM8PDL_UART0_USE_STDIO)
#define EFM8PDL_UART0_USE_BUFFER 1 // buffer mode by default unless user has already selected one of the others
#else
#define EFM8PDL_UART0_USE_BUFFER 0 // buffer mode by default unless user has already selected one of the others
#endif
#endif
#ifndef EFM8PDL_UART0_TX_BUFTYPE
#define EFM8PDL_UART0_TX_BUFTYPE SI_SEG_XDATA
#endif
#ifndef EFM8PDL_UART0_RX_BUFTYPE
#define EFM8PDL_UART0_RX_BUFTYPE SI_SEG_XDATA
#endif
// Runtime API
/**************************************************************************//**
* @addtogroup uart0_runtime UART0 Runtime API
* @{
*****************************************************************************/
/**************************************************************************//**
* @addtogroup uart0_if Interrupt Flag Enums
* @{
*****************************************************************************/
#define UART0_TX_IF SCON0_TI__BMASK /**< UART0 TX Interrupt */
#define UART0_RX_IF SCON0_RI__BMASK /**< UART0 RX Interrupt */
/** @} (end addtogroup uart0_if Interrupt Flag Enums) */
/***************************************************************************//**
* @brief
* Return the value of the specified interrupt flag.
*
* @param flag:
* Flag to check. If OR'd together will return >0 if either flag is set.
*
* @return
* The state of the flags. This value is the OR of all flags which are set.
*
* ~~~~~.c
* if(UART0_getIntFlags() & UART_TX_IF)
* {
* //do something
* }
*
* uint8_t value = UART0_getIntFlags();
* if(value)
* {
* //do some stuff that needs to be done for RX and TX
* if (value & UART_RX_IF)
* {
* //Do stuff that only needs to be done for RX
* }
* }
* ~~~~~
*
* Valid flags can be found in the Interrupt Flag Enums group.
*
*****************************************************************************/
uint8_t UART0_getIntFlags();
/***************************************************************************//**
* @brief
* Clear the specified interrupt flag.
*
* @param flag:
* Flag to clear. Multiple flags can be cleared by OR-ing the flags.
*
* Valid flags can be found in the Interrupt Flag Enums group.
*
******************************************************************************/
void UART0_clearIntFlag(uint8_t flag);
/***************************************************************************//**
* @brief
* Sets the TX complete interrupt flag.
*
* It is common to operate the UART in polling mode where the procedure for
* transmitting a byte is to block till TX is complete and then clear the flag
* and write to SBUF. For these cases it is necessary to manually set the TX bit
* to initialize the UART.
*
******************************************************************************/
void UART0_initTxPolling();
/***************************************************************************//**
* @brief
* Write 8 bits to the UART to be transmitted.
*
* @param value:
* Data to be transmitted.
*
* If the UART already has data pending transmission it will be overwritten.
*
******************************************************************************/
void UART0_write(uint8_t value);
/***************************************************************************//**
* @brief
* Read the last received byte from UART.
*
* @return
* The most recent byte read by the UART.
*
******************************************************************************/
uint8_t UART0_read(void);
/***************************************************************************//**
* @brief
* Write the a byte to the UART with an extra bit.
*
* @param value:
* Data to transmit.
*
* Data[9] should contain the value of the extra bit.
*
******************************************************************************/
void UART0_writeWithExtraBit(uint16_t value);
/***************************************************************************//**
* @brief
* Read a byte from the UART with an extra bit.
*
* @return
* The last byte received with data[9] set to the value of the extra bit.
*
******************************************************************************/
uint16_t UART0_readWithExtraBit(void);
/** @} (end addtogroup uart0_runtime UART0 Runtime API) */
// Initialization API
/***************************************************************************//**
* @addtogroup uart0_init UART0 Initialization API
* @{
******************************************************************************/
/// UART transfer width enums.
typedef enum
{
UART0_WIDTH_8 = SCON0_SMODE__8_BIT, //!< UART in 8-bit mode.
UART0_WIDTH_9 = SCON0_SMODE__9_BIT, //!< UART in 9-bit mode.
} UART0_Width_t;
/// UART Multiprocessor support enums.
typedef enum
{
UART0_MULTIPROC_DISABLE = SCON0_MCE__MULTI_DISABLED, //!< UART Multiprocessor communication Disabled.
UART0_MULTIPROC_ENABLE = SCON0_MCE__MULTI_ENABLED, //!< UART Multiprocessor communication Enabled.
} UART0_Multiproc_t;
/// UART RX support enums
typedef enum
{
UART0_RX_ENABLE = SCON0_REN__RECEIVE_ENABLED, //!< UART Receive Enabled.
UART0_RX_DISABLE = SCON0_REN__RECEIVE_DISABLED, //!< UART Receive Disabled.
} UART0_RxEnable_t;
/***************************************************************************//**
* @brief
* Initialize the UART
*
* @param rxen:
* Receive enable status.
* @param width:
* Data word width.
* @param mce:
* Multiprocessor mode status.
*
******************************************************************************/
void UART0_init(UART0_RxEnable_t rxen, UART0_Width_t width, UART0_Multiproc_t mce);
/***************************************************************************//**
* @brief
* Restore the UART to it's uninitialized (reset) state.
*
******************************************************************************/
void UART0_reset();
/** @} (end uart0_init UART0 Initialization API) */
// Buffer API
/**************************************************************************//**
* @addtogroup uart0_buffer UART0 Buffer Access API
* @{
*****************************************************************************/
#if (EFM8PDL_UART0_USE_BUFFER == 1) || IS_DOXYGEN
/***************************************************************************//**
* @brief
* Transmit a buffer of data via UART.
*
* @param[in] buffer:
* Pointer to buffer of data to be transmitted.
* @param length:
* Number of bytes in transfer to be transmitted.
*
* Buffer transfers support only 8-bit wide transfers.
*
******************************************************************************/
void UART0_writeBuffer(SI_VARIABLE_SEGMENT_POINTER(buffer,
uint8_t,
EFM8PDL_UART0_TX_BUFTYPE),
uint8_t length);
/***************************************************************************//**
* @brief
* Receive a buffer of data via UART.
*
* @param[out] buffer:
* Pointer to buffer of data to be transmitted.
* @param length:
* Number of bytes in transfer to be transmitted.
*
* Buffered transfers support only 8-bit words.
*
******************************************************************************/
void UART0_readBuffer(SI_VARIABLE_SEGMENT_POINTER(buffer,
uint8_t,
EFM8PDL_UART0_RX_BUFTYPE),
uint8_t length);
/***************************************************************************//**
* @brief
* Abort current buffer transmission.
*
* Data already moved into the UART will finish transmission. No more
* data will be pulled out of the TX buffer.
*
******************************************************************************/
void UART0_abortWrite();
/***************************************************************************//**
* @brief
* Abort current buffer reception.
*
* No more data will be written to the RX buffer.
*
******************************************************************************/
void UART0_abortRead();
/***************************************************************************//**
* @brief
* Return the number of bytes remaining in the TX buffer.
*
* @return
* number of btyes remaining in TX buffer. 0 if no transfer is in progress.
*
* @returns 0 if transfer is not in progress.
******************************************************************************/
uint8_t UART0_txBytesRemaining();
/***************************************************************************//**
* @brief
* Return the number of bytes remaining in the RX buffer.
*
* @return
* number of btyes remaining in RX buffer. 0 if no transfer is in progress.
*
******************************************************************************/
uint8_t UART0_rxBytesRemaining();
/** @} (end uart0_buffer UART0 Buffer Access API) */
/**************************************************************************//**
* @def void UART0_ISR()
* @brief UART0 Interrupt handler.
*
* This callback is implemented inside the driver if EFM8PDL_UART0_USE_BUFFER is set
* otherwise the user must implement the ISR.
*
*****************************************************************************/
#endif // EFM8PDL_UART0_USE_BUFFER
// Callbacks
/**************************************************************************//**
* @addtogroup uart0_callbacks User Callbacks
* @{
*****************************************************************************/
/**************************************************************************//**
*@addtogroup uart0_callbacks_buffer Buffer Access API
*@{
*
* These callbacks will be called by the library when
* EFM8PDL_UART0_USE_BUFFER. If the Buffered Access API is disabled
* the callbacks do not need to be provided by the user.
*
*****************************************************************************/
#if (EFM8PDL_UART0_USE_BUFFER == 1) || IS_DOXYGEN
/***************************************************************************//**
* @brief
* Callback for reception of byte.
*
* This function is called when all expected bytes have been received.
*
* @warning
* This function is called from an ISR and should be as short as possible.
*
******************************************************************************/
void UART0_receiveCompleteCb();
/***************************************************************************//**
* @brief
* Callback for transmission of a byte.
*
* This function is called when all bytes in the buffer have been transferred.
*
* @warning
* This function is called from an ISR and should be as short as possible.
*
******************************************************************************/
void UART0_transmitCompleteCb();
#endif //EFM8PDL_UART0_USE_BUFFER
/** @} (end uart0_callbacks_buffer Buffer Access API) */
/** @} (end uart0_callbacks User Callbacks) */
// STIDO API
/**************************************************************************//**
* @addtogroup uart0_stdio UART0 STDIO API
* @{
*
* This API is intended to be used in place of all other uart driver
* API's and will assume control of the uart.
*
* @warning
* This implementation is blocking and may hang the MCU under certain
* conditions.
*
******************************************************************************/
#if (EFM8PDL_UART0_USE_STDIO == 1) || IS_DOXYGEN
/***************************************************************************//**
* @brief
* Initializes uart for STDIO operation.
*
* This function sets up the uart for use by printf/scanif. It must be called
* once durring device initialization **before** using STDIO.
*
******************************************************************************/
void UART0_initStdio();
#endif //EFM8PDL_UART0_USE_STDIO
/** @} (end uart0_stdio UART0 STDIO API) */
/** @} (end uart_0 UART0 Driver) */
#endif //__UART_0_H__

View File

@ -0,0 +1,269 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "pca_0.h"
#include "assert.h"
uint8_t PCA0_getIntFlags()
{
uint8_t val;
val = PCA0CN0 & (PCA0_OVERFLOW_IF
| PCA0_CHAN0_IF
| PCA0_CHAN1_IF
| PCA0_CHAN2_IF);
return val | (PCA0PWM & PCA0_IOVERFLOW_IF);
}
void PCA0_clearIntFlag(uint8_t flag)
{
PCA0CN0 &= ~(flag & ~PCA0_IOVERFLOW_IF);
PCA0PWM &= ~(flag & PCA0_IOVERFLOW_IF);
}
void PCA0_enableInt(uint8_t flag, bool enable)
{
uint8_t en = (uint8_t) enable;
if(flag & PCA0_CHAN0_IF){
PCA0CPM0 &= ~PCA0CPM0_ECCF__BMASK;
PCA0CPM0 |= en << PCA0CPM0_ECCF__SHIFT;
}
if(flag & PCA0_CHAN1_IF){
PCA0CPM1 &= ~PCA0CPM1_ECCF__BMASK;
PCA0CPM1 |= en << PCA0CPM1_ECCF__SHIFT;
}
if(flag & PCA0_CHAN2_IF){
PCA0CPM2 &= ~PCA0CPM2_ECCF__BMASK;
PCA0CPM2 |= en << PCA0CPM2_ECCF__SHIFT;
}
if(flag & PCA0_OVERFLOW_IF){
PCA0MD &= ~PCA0MD_ECF__BMASK;
PCA0MD |= en << PCA0MD_ECF__SHIFT;
}
if(flag & PCA0_IOVERFLOW_IF){
PCA0PWM &= ~PCA0PWM_ECOV__BMASK;
PCA0PWM |= en << PCA0PWM_ECOV__SHIFT;
}
}
uint16_t PCA0_readChannel(PCA0_Channel_t channel)
{
switch(channel)
{
case 0:
return PCA0CP0;
case 1:
return PCA0CP1;
case 2:
return PCA0CP2;
}
return 0x0;
}
void PCA0_writeChannel(PCA0_Channel_t channel, uint16_t value)
{
uint8_t lower = value >> 8;
switch(channel)
{
case 0:
PCA0CPL0 = value;
PCA0CPH0 = lower;
break;
case 1:
PCA0CPL1 = value;
PCA0CPH1 = lower;
break;
case 2:
PCA0CPL2 = value;
PCA0CPH2 = lower;
break;
}
}
uint16_t PCA0_readCounter()
{
//PCA0L must be read first for accurate results. If PCA0
// is returned then PCA0H will be read first (compiler specific).
return PCA0L + (PCA0H << 8);
}
void PCA0_writeCounter(uint16_t value)
{
PCA0 = value;
}
void PCA0_run()
{
PCA0CN0_CR = 1;
}
void PCA0_halt()
{
PCA0CN0_CR = 0;
}
void PCA0_init(PCA0_Timebase_t timebase, PCA0_IdleState_t idleState)
{
PCA0MD &= ~(PCA0MD_CPS__FMASK | PCA0MD_CIDL__BMASK);
PCA0MD |= timebase + idleState;
}
void PCA0_initChannel(PCA0_Channel_t channel,
PCA0_ChannelMode_t mode,
PCA0_ChannelOutPolatiry_t pol
)
{
#define MODE_MASK ~(PCA0CPM0_PWM16__BMASK \
| PCA0CPM0_ECOM__BMASK \
| PCA0CPM0_CAPP__BMASK \
| PCA0CPM0_CAPN__BMASK \
| PCA0CPM0_MAT__BMASK \
| PCA0CPM0_TOG__BMASK \
| PCA0CPM0_PWM__BMASK)
#define PWM_MASK ~(PCA0PWM_ARSEL__BMASK \
| PCA0PWM_CLSEL__FMASK)
#define NBIT_VALUE_MASK 0x07
#define NBIT_MASK 0x70
#define NBIT_PCM PCA0CPM0_PWM16__8_BIT \
| PCA0CPM0_ECOM__ENABLED \
| PCA0CPM0_CAPP__DISABLED \
| PCA0CPM0_CAPN__DISABLED \
| PCA0CPM0_MAT__ENABLED \
| PCA0CPM0_TOG__DISABLED \
| PCA0CPM0_PWM__ENABLED
# define IS_16BIT 0x80
uint8_t pwmValue = (uint8_t) mode;
//Set channel polarity
PCA0POL &= ~(0x01 << channel);
PCA0POL |= (pol << channel);
//UPDATE PWM if we are a PWM mode
if( (mode & NBIT_MASK) == NBIT_MASK)
{
PCA0PWM &= PWM_MASK;
if(mode & IS_16BIT)
{
pwmValue = NBIT_PCM | IS_16BIT;
}
else
{
PCA0PWM |= (mode & NBIT_VALUE_MASK) | PCA0PWM_ARSEL__AUTORELOAD;
pwmValue = NBIT_PCM;
}
//Update center/edge selection
PCA0CENT &= ~(0x01 << channel);
PCA0CENT |= ((mode & 0x08) >> 3) << channel;
}
//Set channel mode
switch (channel)
{
case 0:
PCA0CPM0 &= MODE_MASK;
PCA0CPM0 |= pwmValue;
break;
case 1:
PCA0CPM1 &= MODE_MASK;
PCA0CPM1 |= pwmValue;
break;
case 2:
PCA0CPM2 &= MODE_MASK;
PCA0CPM2 |= pwmValue;
break;
}
}
void PCA0_reset()
{
//Reset channels
uint8_t i;
for (i=0; i<=2; i++)
{
PCA0_resetChannel(i);
}
//Reset PCA regs
PCA0MD = 0x0;
PCA0CN0 = 0x0;
PCA0 = 0x0;
PCA0PWM = 0x0;
}
void PCA0_resetChannel(PCA0_Channel_t channel)
{
//Clear polarity and center align
PCA0POL &= ~(0x01 << channel);
PCA0CENT &= ~(0x01 << channel);
switch (channel)
{
case 0:
PCA0CP0 = 0x00;
PCA0CPM0 = 0x0;
return;
case 1:
PCA0CP1 = 0x00;
PCA0CPM1 = 0x0;
return;
case 2:
PCA0CP2 = 0x00;
PCA0CPM2 = 0x0;
return;
}
}
#if EFM8PDL_PCA0_USE_ISR == 1
SI_INTERRUPT(PCA0_ISR, PCA0_IRQn)
{
//Save and clear flags
uint8_t flags = PCA0CN0 & (PCA0CN0_CF__BMASK
| PCA0CN0_CCF0__BMASK
| PCA0CN0_CCF1__BMASK
| PCA0CN0_CCF2__BMASK);
PCA0CN0 &= ~flags;
if( (PCA0PWM & PCA0PWM_COVF__BMASK)
&& (PCA0PWM & PCA0PWM_ECOV__BMASK))
{
PCA0_intermediateOverflowCb();
}
PCA0PWM &= ~PCA0PWM_COVF__BMASK;
if((flags & PCA0CN0_CF__BMASK)
&& (PCA0MD & PCA0MD_ECF__BMASK))
{
PCA0_overflowCb();
}
if((flags & PCA0CN0_CCF0__BMASK)
&& (PCA0CPM0 & PCA0CPM0_ECCF__BMASK))
{
PCA0_channel0EventCb();
}
if((flags & PCA0CN0_CCF1__BMASK)
&& (PCA0CPM1 & PCA0CPM1_ECCF__BMASK))
{
PCA0_channel1EventCb();
}
if((flags & PCA0CN0_CCF2__BMASK)
&& (PCA0CPM2 & PCA0CPM2_ECCF__BMASK))
{
PCA0_channel2EventCb();
}
}
#endif //EFM8PDL_PCA0_USE_ISR

View File

@ -0,0 +1,193 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "uart_0.h"
uint8_t UART0_getIntFlags()
{
return SCON0 & (UART0_TX_IF | UART0_RX_IF);
}
void UART0_clearIntFlag(uint8_t flag)
{
SCON0 &= ~(flag);
}
void UART0_initTxPolling()
{
SCON0_TI = 1;
}
void UART0_write(uint8_t value)
{
SBUF0 = value;
}
uint8_t UART0_read(void)
{
return SBUF0;
}
void UART0_writeWithExtraBit(uint16_t value)
{
SCON0_TB8 = value >> 8;
SBUF0 = value;
}
uint16_t UART0_readWithExtraBit(void)
{
return (SBUF0 | ((SCON0 & SCON0_RB8__BMASK) << 6) );
}
void UART0_init(UART0_RxEnable_t rxen, UART0_Width_t width, UART0_Multiproc_t mce)
{
SCON0 &= ~(SCON0_SMODE__BMASK
| SCON0_MCE__BMASK
| SCON0_REN__BMASK);
SCON0 = mce | rxen | width;
}
void UART0_reset()
{
SCON0 = SCON0_SMODE__8_BIT
| SCON0_MCE__MULTI_DISABLED
| SCON0_REN__RECEIVE_DISABLED
| SCON0_TB8__CLEARED_TO_0
| SCON0_RB8__CLEARED_TO_0
| SCON0_TI__NOT_SET
| SCON0_RI__NOT_SET;
}
//=========================================================
// Interrupt API
//=========================================================
#if EFM8PDL_UART0_USE_BUFFER == 1
/**
* Internal variable fort tracking buffer transfers. transferLenth[UART0_TX_TRANSFER] = bytes remaining in transfer.
*/
SI_SEGMENT_VARIABLE(txRemaining, static uint8_t, SI_SEG_XDATA)=0;
SI_SEGMENT_VARIABLE(rxRemaining, static uint8_t, SI_SEG_XDATA)=0;
SI_SEGMENT_VARIABLE_SEGMENT_POINTER(txBuffer, static uint8_t, EFM8PDL_UART0_TX_BUFTYPE, SI_SEG_XDATA);
SI_SEGMENT_VARIABLE_SEGMENT_POINTER(rxBuffer, static uint8_t, EFM8PDL_UART0_RX_BUFTYPE, SI_SEG_XDATA);
SI_INTERRUPT(UART0_ISR, UART0_IRQn)
{
//Buffer and clear flags immediately so we don't miss an interrupt while processing
uint8_t flags = SCON0 & (UART0_RX_IF | UART0_TX_IF);
SCON0 &= ~flags;
if (rxRemaining && (flags & SCON0_RI__SET))
{
*rxBuffer = SBUF0;
++rxBuffer;
--rxRemaining;
if (!rxRemaining)
{
UART0_receiveCompleteCb();
}
}
if ((flags & SCON0_TI__SET))
{
if (txRemaining){
SBUF0 = *txBuffer;
++txBuffer;
--txRemaining;
}
else
{
UART0_transmitCompleteCb();
}
}
}
void UART0_writeBuffer(SI_VARIABLE_SEGMENT_POINTER(buffer,
uint8_t,
EFM8PDL_UART0_TX_BUFTYPE),
uint8_t length)
{
//Init internal data
txBuffer = buffer+1;
txRemaining = length-1;
//Send initial byte
SBUF0 = *buffer;
}
void UART0_readBuffer(SI_VARIABLE_SEGMENT_POINTER(buffer,
uint8_t,
EFM8PDL_UART0_RX_BUFTYPE),
uint8_t length)
{
//Init internal data
rxBuffer = buffer;
rxRemaining = length;
}
void UART0_abortWrite()
{
txRemaining = 0;
}
void UART0_abortRead()
{
rxRemaining = 0;
}
uint8_t UART0_txBytesRemaining()
{
return txRemaining;
}
uint8_t UART0_rxBytesRemaining()
{
return rxRemaining;
}
#endif //EFM8PDL_UART0_USE_BUFFER
#if EFM8PDL_UART0_USE_STDIO == 1
#if defined __C51__
char putchar(char c){
while(!SCON0_TI);
SBUF0 = c;
SCON0_TI = 0;
return c;
}
char _getkey(){
while(!SCON0_RI);
SCON0_RI = 0;
return SBUF0;
}
#elif defined __ICC8051__
int putchar(int c){
while(!SCON0_TI);
SBUF0 = c;
SCON0_TI = 0;
return c;
}
int getchar(void){
while(!SCON0_RI);
SCON0_RI = 0;
return SBUF0;
}
#endif
void UART0_initStdio()
{
SCON0 |= SCON0_REN__RECEIVE_ENABLED | SCON0_TI__SET;
}
#endif //EFM8PDL_UART0_USE_STDIO

542
src/InitDevice.c Normal file
View File

@ -0,0 +1,542 @@
//=========================================================
// src/InitDevice.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include <SI_EFM8BB1_Register_Enums.h>
#include "InitDevice.h"
// USER PROTOTYPES
// USER FUNCTIONS
// $[Library Includes]
// [Library Includes]$
//==============================================================================
// enter_DefaultMode_from_RESET
//==============================================================================
extern void enter_DefaultMode_from_RESET(void) {
// $[Config Calls]
WDT_0_enter_DefaultMode_from_RESET();
PORTS_0_enter_DefaultMode_from_RESET();
PORTS_1_enter_DefaultMode_from_RESET();
PBCFG_0_enter_DefaultMode_from_RESET();
CLOCK_0_enter_DefaultMode_from_RESET();
TIMER01_0_enter_DefaultMode_from_RESET();
TIMER16_3_enter_DefaultMode_from_RESET();
TIMER_SETUP_0_enter_DefaultMode_from_RESET();
PCA_0_enter_DefaultMode_from_RESET();
PCACH_0_enter_DefaultMode_from_RESET();
PCACH_1_enter_DefaultMode_from_RESET();
UART_0_enter_DefaultMode_from_RESET();
INTERRUPT_0_enter_DefaultMode_from_RESET();
// [Config Calls]$
}
//================================================================================
// WDT_0_enter_DefaultMode_from_RESET
//================================================================================
extern void WDT_0_enter_DefaultMode_from_RESET(void) {
// $[WDTCN - Watchdog Timer Control]
//Disable Watchdog with key sequence
WDTCN = 0xDE; //First key
WDTCN = 0xAD; //Second key
// [WDTCN - Watchdog Timer Control]$
}
//================================================================================
// PORTS_0_enter_DefaultMode_from_RESET
//================================================================================
extern void PORTS_0_enter_DefaultMode_from_RESET(void) {
// $[P0 - Port 0 Pin Latch]
// [P0 - Port 0 Pin Latch]$
// $[P0MDOUT - Port 0 Output Mode]
/***********************************************************************
- P0.0 output is push-pull
- P0.1 output is open-drain
- P0.2 output is open-drain
- P0.3 output is open-drain
- P0.4 output is push-pull
- P0.5 output is open-drain
- P0.6 output is open-drain
- P0.7 output is open-drain
***********************************************************************/
P0MDOUT = P0MDOUT_B0__PUSH_PULL | P0MDOUT_B1__OPEN_DRAIN
| P0MDOUT_B2__OPEN_DRAIN | P0MDOUT_B3__OPEN_DRAIN
| P0MDOUT_B4__PUSH_PULL | P0MDOUT_B5__OPEN_DRAIN
| P0MDOUT_B6__OPEN_DRAIN | P0MDOUT_B7__OPEN_DRAIN;
// [P0MDOUT - Port 0 Output Mode]$
// $[P0MDIN - Port 0 Input Mode]
// [P0MDIN - Port 0 Input Mode]$
// $[P0SKIP - Port 0 Skip]
/***********************************************************************
- P0.0 pin is not skipped by the crossbar
- P0.1 pin is skipped by the crossbar
- P0.2 pin is skipped by the crossbar
- P0.3 pin is skipped by the crossbar
- P0.4 pin is not skipped by the crossbar
- P0.5 pin is not skipped by the crossbar
- P0.6 pin is skipped by the crossbar
- P0.7 pin is skipped by the crossbar
***********************************************************************/
P0SKIP = P0SKIP_B0__NOT_SKIPPED | P0SKIP_B1__SKIPPED | P0SKIP_B2__SKIPPED
| P0SKIP_B3__SKIPPED | P0SKIP_B4__NOT_SKIPPED
| P0SKIP_B5__NOT_SKIPPED | P0SKIP_B6__SKIPPED | P0SKIP_B7__SKIPPED;
// [P0SKIP - Port 0 Skip]$
// $[P0MASK - Port 0 Mask]
// [P0MASK - Port 0 Mask]$
// $[P0MAT - Port 0 Match]
// [P0MAT - Port 0 Match]$
}
//================================================================================
// PORTS_1_enter_DefaultMode_from_RESET
//================================================================================
extern void PORTS_1_enter_DefaultMode_from_RESET(void) {
// $[P1 - Port 1 Pin Latch]
// [P1 - Port 1 Pin Latch]$
// $[P1MDOUT - Port 1 Output Mode]
/***********************************************************************
- P1.0 output is push-pull
- P1.1 output is open-drain
- P1.2 output is open-drain
- P1.3 output is open-drain
- P1.4 output is open-drain
- P1.5 output is open-drain
- P1.6 output is push-pull
***********************************************************************/
P1MDOUT = P1MDOUT_B0__PUSH_PULL | P1MDOUT_B1__OPEN_DRAIN
| P1MDOUT_B2__OPEN_DRAIN | P1MDOUT_B3__OPEN_DRAIN
| P1MDOUT_B4__OPEN_DRAIN | P1MDOUT_B5__OPEN_DRAIN
| P1MDOUT_B6__PUSH_PULL;
// [P1MDOUT - Port 1 Output Mode]$
// $[P1MDIN - Port 1 Input Mode]
// [P1MDIN - Port 1 Input Mode]$
// $[P1SKIP - Port 1 Skip]
/***********************************************************************
- P1.0 pin is skipped by the crossbar
- P1.1 pin is skipped by the crossbar
- P1.2 pin is skipped by the crossbar
- P1.3 pin is not skipped by the crossbar
- P1.4 pin is skipped by the crossbar
- P1.5 pin is skipped by the crossbar
- P1.6 pin is skipped by the crossbar
***********************************************************************/
P1SKIP = P1SKIP_B0__SKIPPED | P1SKIP_B1__SKIPPED | P1SKIP_B2__SKIPPED
| P1SKIP_B3__NOT_SKIPPED | P1SKIP_B4__SKIPPED | P1SKIP_B5__SKIPPED
| P1SKIP_B6__SKIPPED;
// [P1SKIP - Port 1 Skip]$
// $[P1MASK - Port 1 Mask]
// [P1MASK - Port 1 Mask]$
// $[P1MAT - Port 1 Match]
// [P1MAT - Port 1 Match]$
}
//================================================================================
// PBCFG_0_enter_DefaultMode_from_RESET
//================================================================================
extern void PBCFG_0_enter_DefaultMode_from_RESET(void) {
// $[XBR2 - Port I/O Crossbar 2]
/***********************************************************************
- Weak Pullups enabled
- Crossbar enabled
***********************************************************************/
XBR2 = XBR2_WEAKPUD__PULL_UPS_ENABLED | XBR2_XBARE__ENABLED;
// [XBR2 - Port I/O Crossbar 2]$
// $[PRTDRV - Port Drive Strength]
// [PRTDRV - Port Drive Strength]$
// $[XBR0 - Port I/O Crossbar 0]
/***********************************************************************
- UART TX, RX routed to Port pins P0.4 and P0.5
- SPI I/O unavailable at Port pins
- SMBus 0 I/O unavailable at Port pins
- CP0 unavailable at Port pin
- Asynchronous CP0 unavailable at Port pin
- CP1 unavailable at Port pin
- Asynchronous CP1 unavailable at Port pin
- SYSCLK unavailable at Port pin
***********************************************************************/
XBR0 = XBR0_URT0E__ENABLED | XBR0_SPI0E__DISABLED | XBR0_SMB0E__DISABLED
| XBR0_CP0E__DISABLED | XBR0_CP0AE__DISABLED | XBR0_CP1E__DISABLED
| XBR0_CP1AE__DISABLED | XBR0_SYSCKE__DISABLED;
// [XBR0 - Port I/O Crossbar 0]$
// $[XBR1 - Port I/O Crossbar 1]
/***********************************************************************
- CEX0, CEX1 routed to Port pins
- ECI unavailable at Port pin
- T0 unavailable at Port pin
- T1 unavailable at Port pin
- T2 unavailable at Port pin
***********************************************************************/
XBR1 = XBR1_PCA0ME__CEX0_CEX1 | XBR1_ECIE__DISABLED | XBR1_T0E__DISABLED
| XBR1_T1E__DISABLED | XBR1_T2E__DISABLED;
// [XBR1 - Port I/O Crossbar 1]$
}
//================================================================================
// CLOCK_0_enter_DefaultMode_from_RESET
//================================================================================
extern void CLOCK_0_enter_DefaultMode_from_RESET(void) {
// $[CLKSEL - Clock Select]
/***********************************************************************
- Clock derived from the Internal High-Frequency Oscillator
- SYSCLK is equal to selected clock source divided by 1
***********************************************************************/
CLKSEL = CLKSEL_CLKSL__HFOSC | CLKSEL_CLKDIV__SYSCLK_DIV_1;
// [CLKSEL - Clock Select]$
}
//================================================================================
// TIMER01_0_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER01_0_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
//Save Timer Configuration
uint8_t TCON_save;
TCON_save = TCON;
//Stop Timers
TCON &= ~TCON_TR0__BMASK & ~TCON_TR1__BMASK;
// [Timer Initialization]$
// $[TH0 - Timer 0 High Byte]
/***********************************************************************
- Timer 0 High Byte = 0x0B
***********************************************************************/
TH0 = (0x0B << TH0_TH0__SHIFT);
// [TH0 - Timer 0 High Byte]$
// $[TL0 - Timer 0 Low Byte]
// [TL0 - Timer 0 Low Byte]$
// $[TH1 - Timer 1 High Byte]
/***********************************************************************
- Timer 1 High Byte = 0x96
***********************************************************************/
TH1 = (0x96 << TH1_TH1__SHIFT);
// [TH1 - Timer 1 High Byte]$
// $[TL1 - Timer 1 Low Byte]
// [TL1 - Timer 1 Low Byte]$
// $[Timer Restoration]
//Restore Timer Configuration
TCON |= (TCON_save & TCON_TR0__BMASK) | (TCON_save & TCON_TR1__BMASK);
// [Timer Restoration]$
}
//================================================================================
// TIMER16_3_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER16_3_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR3CN0_TR3_save;
TMR3CN0_TR3_save = TMR3CN0 & TMR3CN0_TR3__BMASK;
// Stop Timer
TMR3CN0 &= ~(TMR3CN0_TR3__BMASK);
// [Timer Initialization]$
// $[TMR3CN0 - Timer 3 Control]
// [TMR3CN0 - Timer 3 Control]$
// $[TMR3H - Timer 3 High Byte]
/***********************************************************************
- Timer 3 High Byte = 0xFF
***********************************************************************/
TMR3H = (0xFF << TMR3H_TMR3H__SHIFT);
// [TMR3H - Timer 3 High Byte]$
// $[TMR3L - Timer 3 Low Byte]
/***********************************************************************
- Timer 3 Low Byte = 0xFF
***********************************************************************/
TMR3L = (0xFF << TMR3L_TMR3L__SHIFT);
// [TMR3L - Timer 3 Low Byte]$
// $[TMR3RLH - Timer 3 Reload High Byte]
/***********************************************************************
- Timer 3 Reload High Byte = 0xFF
***********************************************************************/
TMR3RLH = (0xFF << TMR3RLH_TMR3RLH__SHIFT);
// [TMR3RLH - Timer 3 Reload High Byte]$
// $[TMR3RLL - Timer 3 Reload Low Byte]
/***********************************************************************
- Timer 3 Reload Low Byte = 0x86
***********************************************************************/
TMR3RLL = (0x86 << TMR3RLL_TMR3RLL__SHIFT);
// [TMR3RLL - Timer 3 Reload Low Byte]$
// $[TMR3CN0]
// [TMR3CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR3CN0 |= TMR3CN0_TR3_save;
// [Timer Restoration]$
}
//================================================================================
// TIMER_SETUP_0_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void) {
// $[CKCON0 - Clock Control 0]
/***********************************************************************
- System clock divided by 12
- Counter/Timer 0 uses the system clock
- Timer 2 high byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 2 low byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 3 high byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 3 low byte uses the system clock
- Timer 1 uses the clock defined by the prescale field, SCA
***********************************************************************/
CKCON0 = CKCON0_SCA__SYSCLK_DIV_12 | CKCON0_T0M__SYSCLK
| CKCON0_T2MH__EXTERNAL_CLOCK | CKCON0_T2ML__EXTERNAL_CLOCK
| CKCON0_T3MH__EXTERNAL_CLOCK | CKCON0_T3ML__SYSCLK
| CKCON0_T1M__PRESCALE;
// [CKCON0 - Clock Control 0]$
// $[TMOD - Timer 0/1 Mode]
/***********************************************************************
- Mode 2, 8-bit Counter/Timer with Auto-Reload
- Mode 2, 8-bit Counter/Timer with Auto-Reload
- Timer Mode
- Timer 0 enabled when TR0 = 1 irrespective of INT0 logic level
- Timer Mode
- Timer 1 enabled when TR1 = 1 irrespective of INT1 logic level
***********************************************************************/
TMOD = TMOD_T0M__MODE2 | TMOD_T1M__MODE2 | TMOD_CT0__TIMER
| TMOD_GATE0__DISABLED | TMOD_CT1__TIMER | TMOD_GATE1__DISABLED;
// [TMOD - Timer 0/1 Mode]$
// $[TCON - Timer 0/1 Control]
/***********************************************************************
- Start Timer 0 running
- Start Timer 1 running
***********************************************************************/
TCON |= TCON_TR0__RUN | TCON_TR1__RUN;
// [TCON - Timer 0/1 Control]$
}
//================================================================================
// PCA_0_enter_DefaultMode_from_RESET
//================================================================================
extern void PCA_0_enter_DefaultMode_from_RESET(void) {
// $[PCA Off]
PCA0CN0_CR = PCA0CN0_CR__STOP;
// [PCA Off]$
// $[PCA0MD - PCA Mode]
/***********************************************************************
- PCA continues to function normally while the system controller is in
Idle Mode
- Enable a PCA Counter/Timer Overflow interrupt request when CF is set
- Timer 0 overflow
***********************************************************************/
PCA0MD = PCA0MD_CIDL__NORMAL | PCA0MD_ECF__OVF_INT_ENABLED
| PCA0MD_CPS__T0_OVERFLOW;
// [PCA0MD - PCA Mode]$
// $[PCA0CENT - PCA Center Alignment Enable]
// [PCA0CENT - PCA Center Alignment Enable]$
// $[PCA0CLR - PCA Comparator Clear Control]
// [PCA0CLR - PCA Comparator Clear Control]$
// $[PCA0L - PCA Counter/Timer Low Byte]
/***********************************************************************
- PCA Counter/Timer Low Byte = 0xFF
***********************************************************************/
PCA0L = (0xFF << PCA0L_PCA0L__SHIFT);
// [PCA0L - PCA Counter/Timer Low Byte]$
// $[PCA0H - PCA Counter/Timer High Byte]
// [PCA0H - PCA Counter/Timer High Byte]$
// $[PCA0POL - PCA Output Polarity]
/***********************************************************************
- Invert polarity
- Use default polarity
- Use default polarity
***********************************************************************/
PCA0POL = PCA0POL_CEX0POL__INVERT | PCA0POL_CEX1POL__DEFAULT
| PCA0POL_CEX2POL__DEFAULT;
// [PCA0POL - PCA Output Polarity]$
// $[PCA0PWM - PCA PWM Configuration]
/***********************************************************************
- A PCA interrupt will be generated when COVF is set
***********************************************************************/
PCA0PWM |= PCA0PWM_ECOV__COVF_MASK_ENABLED;
// [PCA0PWM - PCA PWM Configuration]$
// $[PCA On]
// [PCA On]$
}
//================================================================================
// PCACH_0_enter_DefaultMode_from_RESET
//================================================================================
extern void PCACH_0_enter_DefaultMode_from_RESET(void) {
// $[PCA0 Settings Save]
// Select Capture/Compare register)
PCA0PWM &= ~PCA0PWM_ARSEL__BMASK;
// [PCA0 Settings Save]$
// $[PCA0CPM0 - PCA Channel 0 Capture/Compare Mode]
/***********************************************************************
- Disable negative edge capture
- Disable CCF0 interrupts
- Enable match function
- 8 to 11-bit PWM selected
- Disable positive edge capture
- Enable comparator function
- Enable PWM function
- Disable toggle function
***********************************************************************/
PCA0CPM0 = PCA0CPM0_CAPN__DISABLED | PCA0CPM0_ECCF__DISABLED
| PCA0CPM0_MAT__ENABLED | PCA0CPM0_PWM16__8_BIT
| PCA0CPM0_CAPP__DISABLED | PCA0CPM0_ECOM__ENABLED
| PCA0CPM0_PWM__ENABLED | PCA0CPM0_TOG__DISABLED;
// [PCA0CPM0 - PCA Channel 0 Capture/Compare Mode]$
// $[PCA0CPL0 - PCA Channel 0 Capture Module Low Byte]
// [PCA0CPL0 - PCA Channel 0 Capture Module Low Byte]$
// $[PCA0CPH0 - PCA Channel 0 Capture Module High Byte]
// [PCA0CPH0 - PCA Channel 0 Capture Module High Byte]$
// $[Auto-reload]
// [Auto-reload]$
// $[PCA0 Settings Restore]
// [PCA0 Settings Restore]$
}
//================================================================================
// PCACH_1_enter_DefaultMode_from_RESET
//================================================================================
extern void PCACH_1_enter_DefaultMode_from_RESET(void) {
// $[PCA0 Settings Save]
// Select Capture/Compare register)
PCA0PWM &= ~PCA0PWM_ARSEL__BMASK;
// [PCA0 Settings Save]$
// $[PCA0CPM1 - PCA Channel 1 Capture/Compare Mode]
/***********************************************************************
- Enable negative edge capture
- Disable CCF1 interrupts
- Disable match function
- 8 to 11-bit PWM selected
- Enable positive edge capture
- Disable comparator function
- Disable PWM function
- Disable toggle function
***********************************************************************/
PCA0CPM1 = PCA0CPM1_CAPN__ENABLED | PCA0CPM1_ECCF__DISABLED
| PCA0CPM1_MAT__DISABLED | PCA0CPM1_PWM16__8_BIT
| PCA0CPM1_CAPP__ENABLED | PCA0CPM1_ECOM__DISABLED
| PCA0CPM1_PWM__DISABLED | PCA0CPM1_TOG__DISABLED;
// [PCA0CPM1 - PCA Channel 1 Capture/Compare Mode]$
// $[PCA0CPL1 - PCA Channel 1 Capture Module Low Byte]
// [PCA0CPL1 - PCA Channel 1 Capture Module Low Byte]$
// $[PCA0CPH1 - PCA Channel 1 Capture Module High Byte]
// [PCA0CPH1 - PCA Channel 1 Capture Module High Byte]$
// $[Auto-reload]
// [Auto-reload]$
// $[PCA0 Settings Restore]
// [PCA0 Settings Restore]$
}
//================================================================================
// UART_0_enter_DefaultMode_from_RESET
//================================================================================
extern void UART_0_enter_DefaultMode_from_RESET(void) {
// $[SCON0 - UART0 Serial Port Control]
/***********************************************************************
- UART0 reception enabled
***********************************************************************/
SCON0 |= SCON0_REN__RECEIVE_ENABLED;
// [SCON0 - UART0 Serial Port Control]$
}
//================================================================================
// INTERRUPT_0_enter_DefaultMode_from_RESET
//================================================================================
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void) {
// $[EIE1 - Extended Interrupt Enable 1]
/***********************************************************************
- Disable ADC0 Conversion Complete interrupt
- Disable ADC0 Window Comparison interrupt
- Disable CP0 interrupts
- Disable CP1 interrupts
- Disable all Port Match interrupts
- Enable interrupt requests generated by PCA0
- Disable all SMB0 interrupts
- Enable interrupt requests generated by the TF3L or TF3H flags
***********************************************************************/
EIE1 = EIE1_EADC0__DISABLED | EIE1_EWADC0__DISABLED | EIE1_ECP0__DISABLED
| EIE1_ECP1__DISABLED | EIE1_EMAT__DISABLED | EIE1_EPCA0__ENABLED
| EIE1_ESMB0__DISABLED | EIE1_ET3__ENABLED;
// [EIE1 - Extended Interrupt Enable 1]$
// $[EIP1 - Extended Interrupt Priority 1]
// [EIP1 - Extended Interrupt Priority 1]$
// $[IE - Interrupt Enable]
/***********************************************************************
- Enable each interrupt according to its individual mask setting
- Disable external interrupt 0
- Disable external interrupt 1
- Disable all SPI0 interrupts
- Disable all Timer 0 interrupt
- Disable all Timer 1 interrupt
- Disable Timer 2 interrupt
- Enable UART0 interrupt
***********************************************************************/
IE = IE_EA__ENABLED | IE_EX0__DISABLED | IE_EX1__DISABLED
| IE_ESPI0__DISABLED | IE_ET0__DISABLED | IE_ET1__DISABLED
| IE_ET2__DISABLED | IE_ES0__ENABLED;
// [IE - Interrupt Enable]$
// $[IP - Interrupt Priority]
// [IP - Interrupt Priority]$
}

211
src/RF_Bridge_main.c Normal file
View File

@ -0,0 +1,211 @@
//=========================================================
// src/RF_Bridge_2_main.c: generated by Hardware Configurator
//
// This file will be updated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!!
//=========================================================
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <SI_EFM8BB1_Register_Enums.h> // SFR declarations
#include "Globals.h"
#include "InitDevice.h"
#include "uart_0.h"
#include "pca_0.h"
#include "uart.h"
#include "RF_Handling.h"
// $[Generated Includes]
// [Generated Includes]$
uart_state_t uart_state = IDLE;
uart_command_t uart_command = NONE;
bool Sniffing = false;
//-----------------------------------------------------------------------------
// SiLabs_Startup() Routine
// ----------------------------------------------------------------------------
// This function is called immediately after reset, before the initialization
// code is run in SILABS_STARTUP.A51 (which runs before main() ). This is a
// useful place to disable the watchdog timer, which is enable by default
// and may trigger before main() in some instances.
//-----------------------------------------------------------------------------
void SiLabs_Startup (void)
{
}
//-----------------------------------------------------------------------------
// main() Routine
// ----------------------------------------------------------------------------
int main (void)
{
// Call hardware initialization routine
enter_DefaultMode_from_RESET();
// enter default state
LED = LED_OFF;
BUZZER = BUZZER_OFF;
T_DATA = 1;
// enable UART
UART0_init(UART0_RX_ENABLE, UART0_WIDTH_8, UART0_MULTIPROC_DISABLE);
// start sniffing if enabled by default
if (Sniffing)
PCA0_DoSniffing();
else
PCA0_StopSniffing();
// enable global interrupts
IE_EA = 1;
while (1)
{
/*------------------------------------------
* check if something got received by UART
------------------------------------------*/
unsigned int rxdata;
uint8_t len;
uint8_t position;
rxdata = uart_getc();
if (rxdata != UART_NO_DATA)
{
// state machine for UART
switch(uart_state)
{
// check if UART_SYNC_INIT got received
case IDLE:
if ((rxdata & 0xFF) == UART_SYNC_INIT)
uart_state = SYNC_INIT;
break;
// sync byte got received, read command
case SYNC_INIT:
uart_command = rxdata & 0xFF;
uart_state = SYNC_FINISH;
// check if some data needs to be received
switch(uart_command)
{
case LEARNING:
Timer_3_Timeout = 50000;
BUZZER = BUZZER_ON;
// start 5µs timer
TMR3CN0 |= TMR3CN0_TR3__RUN;
// wait until timer has finished
while((TMR3CN0 & TMR3CN0_TR3__BMASK) == TMR3CN0_TR3__RUN);
BUZZER = BUZZER_OFF;
break;
case SNIFFING_ON:
PCA0_DoSniffing();
break;
case SNIFFING_OFF:
PCA0_StopSniffing();
sniffing_is_on = false;
break;
case TRANSMIT_DATA:
uart_state = RECEIVE_LEN;
break;
// unknown command
default:
uart_command = NONE;
uart_state = IDLE;
break;
}
break;
// Receiving UART data len
case RECEIVE_LEN:
position = 0;
len = rxdata & 0xFF;
if (len > 0)
uart_state = RECEIVING;
else
uart_state = SYNC_FINISH;
break;
// Receiving UART data
case RECEIVING:
RF_DATA[position] = rxdata & 0xFF;
position++;
if (position == len)
uart_state = SYNC_FINISH;
break;
// wait and check for UART_SYNC_END
case SYNC_FINISH:
if ((rxdata & 0xFF) == UART_SYNC_END)
{
uart_state = IDLE;
// send acknowledge
uart_put_command(COMMAND_AK);
}
break;
}
}
/*------------------------------------------
* check command byte
------------------------------------------*/
switch(uart_command)
{
case SNIFFING_ON:
// check if a RF signal got decoded
if ((RF_DATA_STATUS & RF_DATA_RECEIVED_MASK) != 0)
{
uint8_t used_protocol = RF_DATA_STATUS & 0x7F;
uart_put_RF_Data(SNIFFING_ON, used_protocol);
// clear RF status
RF_DATA_STATUS = 0;
}
break;
// transmit data on RF
// byte 0: Protocol identifier
// byte 1..N: data to be transmitted
case TRANSMIT_DATA:
// only do the job if all data got received by UART
if (uart_state != IDLE)
break;
if (sniffing_is_on)
PCA0_StopSniffing();
protocol_index = PCA0_DoTransmit(RF_DATA[0]);
if (protocol_index != 0xFF)
{
actual_bit_of_byte = 0x08;
actual_bit_of_byte--;
actual_byte = 1;
actual_bit = 1;
if(((RF_DATA[actual_byte] >> actual_bit_of_byte) & 0x01) == 0x01)
{
// bit 1
PCA0_writeChannel(PCA0_CHAN0, DUTY_CYCLE_HIGH << 8);
}
else
{
// bit 0
PCA0_writeChannel(PCA0_CHAN0, DUTY_CYLCE_LOW << 8);
}
SendRF_SYNC(protocol_index);
PCA0CN0_CR = PCA0CN0_CR__RUN;
}
uart_command = NONE;
break;
}
}
}

364
src/RF_Handling.c Normal file
View File

@ -0,0 +1,364 @@
/*
* RF_Handling.c
*
* Created on: 27.11.2017
* Author:
*/
#include <SI_EFM8BB1_Register_Enums.h>
#include <string.h>
#include "Globals.h"
#include "RF_Handling.h"
#include "RF_Protocols.h"
#include "pca_0.h"
#include "uart.h"
SI_SEGMENT_VARIABLE(RF_DATA[RF_DATA_BUFFERSIZE], uint8_t, SI_SEG_XDATA);
SI_SEGMENT_VARIABLE(RF_DATA_STATUS, uint8_t, SI_SEG_XDATA) = 0;
SI_SEGMENT_VARIABLE(rf_state, rf_state_t, SI_SEG_XDATA) = RF_IDLE;
SI_SEGMENT_VARIABLE(Timer_3_Timeout, uint16_t, SI_SEG_XDATA) = 0x0000;
SI_SEGMENT_VARIABLE(sniffing_is_on, uint8_t, SI_SEG_XDATA) = false;
SI_SEGMENT_VARIABLE(DUTY_CYCLE_HIGH, uint8_t, SI_SEG_XDATA) = 0x56;
SI_SEGMENT_VARIABLE(DUTY_CYLCE_LOW, uint8_t, SI_SEG_XDATA) = 0xAB;
SI_SEGMENT_VARIABLE(actual_bit_of_byte, uint8_t, SI_SEG_XDATA) = 0;
SI_SEGMENT_VARIABLE(actual_bit, uint8_t, SI_SEG_XDATA) = 0;
SI_SEGMENT_VARIABLE(actual_byte, uint8_t, SI_SEG_XDATA) = 0;
SI_SEGMENT_VARIABLE(protocol_index, uint8_t, SI_SEG_XDATA) = 0;
//-----------------------------------------------------------------------------
// Callbacks
//-----------------------------------------------------------------------------
void PCA0_overflowCb()
{
}
void PCA0_intermediateOverflowCb()
{
}
void PCA0_channel0EventCb()
{
// stop transfer if all bits are transmitted
if (actual_bit_of_byte == 0)
{
actual_byte++;
actual_bit_of_byte = 8;
}
if (actual_bit == PROTOCOL_DATA[protocol_index].BIT_COUNT)
{
PCA0_StopTransmit();
return;
}
actual_bit++;
actual_bit_of_byte--;
if(((RF_DATA[actual_byte] >> actual_bit_of_byte) & 0x01) == 0x01)
{
// bit 1
PCA0_writeChannel(PCA0_CHAN0, DUTY_CYCLE_HIGH << 8);
}
else
{
// bit 0
PCA0_writeChannel(PCA0_CHAN0, DUTY_CYLCE_LOW << 8);
}
}
void PCA0_channel1EventCb()
{
static uint16_t current_capture_value;
static uint16_t previous_capture_value_pos, previous_capture_value_neg;
static uint16_t capture_period_pos, capture_period_neg;
static uint8_t used_protocol;
static uint16_t low_pulse_time;
// Store most recent capture value
current_capture_value = PCA0CP1 * 10;
// positive edge
if (R_DATA)
{
// Update previous capture value with most recent info.
previous_capture_value_pos = current_capture_value;
// Calculate capture period from last two values.
capture_period_neg = current_capture_value - previous_capture_value_neg;
switch (rf_state)
{
// check if we receive a sync
case RF_IDLE:
// check first if last decoded RF signal was cleared
if (RF_DATA_STATUS != 0)
break;
for ( used_protocol = 0; used_protocol < PROTOCOLCOUNT; used_protocol++)
{
if (
(capture_period_pos > (PROTOCOL_DATA[used_protocol].SYNC_HIGH - SYNC_TOLERANCE)) &&
(capture_period_pos < (PROTOCOL_DATA[used_protocol].SYNC_HIGH + SYNC_TOLERANCE)) &&
(capture_period_neg > (PROTOCOL_DATA[used_protocol].SYNC_LOW - SYNC_TOLERANCE)) &&
(capture_period_neg < (PROTOCOL_DATA[used_protocol].SYNC_LOW + SYNC_TOLERANCE))
)
{
actual_bit_of_byte = 8;
actual_byte = 0;
actual_bit = 0;
low_pulse_time = 0;
memset(RF_DATA, 0, sizeof(RF_DATA));
rf_state = RF_IN_SYNC;
break;
}
}
break;
// one matching sync got received
case RF_IN_SYNC:
actual_bit_of_byte--;
actual_bit++;
// if high time is longer than low time: logic 1
// if high time is shorter than low time: logic 0
// the high time of bit 0 is getting measured to be able to determine the last bit
if (
((capture_period_pos > capture_period_neg) && (actual_bit < PROTOCOL_DATA[used_protocol].BIT_COUNT)) ||
((capture_period_pos > low_pulse_time) && (actual_bit == PROTOCOL_DATA[used_protocol].BIT_COUNT))
)
{
LED = LED_ON;
RF_DATA[(actual_bit - 1) / 8] |= (1 << actual_bit_of_byte);
}
else
{
LED = LED_OFF;
// backup low bit pulse time to be able to determine the last bit
if (capture_period_pos > low_pulse_time)
low_pulse_time = capture_period_pos;
}
if (actual_bit_of_byte == 0)
actual_bit_of_byte = 8;
// check if all bits for this protocol got received
if (actual_bit == PROTOCOL_DATA[used_protocol].BIT_COUNT)
{
RF_DATA_STATUS = used_protocol;
RF_DATA_STATUS |= RF_DATA_RECEIVED_MASK;
LED = LED_OFF;
rf_state = RF_IDLE;
}
break;
}
}
// negative edge
else
{
// Update previous capture value with most recent info.
previous_capture_value_neg = current_capture_value;
// Calculate capture period from last two values.
capture_period_pos = current_capture_value - previous_capture_value_pos;
}
}
void PCA0_channel2EventCb()
{
}
//-----------------------------------------------------------------------------
// Send RF SYNC HIGH/LOW Routine
//-----------------------------------------------------------------------------
void SendRF_SYNC(uint8_t used_protocol)
{
// enable P0.0 for I/O control
XBR1 &= ~XBR1_PCA0ME__CEX0_CEX1;
// do activate the SYN115 chip
Timer_3_Timeout = 3000;
// switch to high
T_DATA = 1;
// start 5µs timer
TMR3CN0 |= TMR3CN0_TR3__RUN;
// wait until timer has finished
while((TMR3CN0 & TMR3CN0_TR3__BMASK) == TMR3CN0_TR3__RUN);
// switch to low
T_DATA = 0;
Timer_3_Timeout = 100;
// start 5µs timer
TMR3CN0 |= TMR3CN0_TR3__RUN;
// wait until timer has finished
while((TMR3CN0 & TMR3CN0_TR3__BMASK) == TMR3CN0_TR3__RUN);
// switch to high
T_DATA = 1;
// do high time
Timer_3_Timeout = PROTOCOL_DATA[used_protocol].SYNC_HIGH;
// start 5µs timer
TMR3CN0 |= TMR3CN0_TR3__RUN;
// wait until timer has finished
while((TMR3CN0 & TMR3CN0_TR3__BMASK) == TMR3CN0_TR3__RUN);
// switch to low
T_DATA = 0;
// do low time
Timer_3_Timeout = PROTOCOL_DATA[used_protocol].SYNC_LOW;
// start 5µs timer
TMR3CN0 |= TMR3CN0_TR3__RUN;
// wait until timer has finished
while((TMR3CN0 & TMR3CN0_TR3__BMASK) == TMR3CN0_TR3__RUN);
// disable P0.0 for I/O control, enter PCA mode
XBR1 |= XBR1_PCA0ME__CEX0_CEX1;
}
uint8_t PCA0_DoTransmit(uint8_t identifier)
{
uint8_t i;
uint8_t protocol_index = 0xFF;
uint8_t TCON_save;
// check first for valid identifier
if ((identifier > 0x00) && (identifier < 0x80))
{
// find protocol index by identifier
for(i = 0; i < PROTOCOLCOUNT; i++)
{
if (PROTOCOL_DATA[i].IDENTIFIER == identifier)
{
protocol_index = i;
break;
}
}
// check if protocol got found
if (protocol_index != 0xFF)
{
// calculate T0_Overflow
i = (uint8_t)(0x100 - ((uint32_t)SYSCLK / (0xFF * (1000000 / (uint32_t)PROTOCOL_DATA[protocol_index].BIT_TIME))));
//Save Timer Configuration
TCON_save = TCON;
//Stop Timer 0
TCON &= ~TCON_TR0__BMASK;
/***********************************************************************
- Timer 0 High Byte = i (T0_Overflow)
***********************************************************************/
TH0 = (i << TH0_TH0__SHIFT);
//Restore Timer Configuration
TCON |= (TCON_save & TCON_TR0__BMASK);
// calculate high and low duty cycle
DUTY_CYCLE_HIGH = (uint16_t)(0xFF - ((PROTOCOL_DATA[protocol_index].BIT_HIGH_DUTY * 0xFF) / 100));
DUTY_CYLCE_LOW = (uint16_t)(0xFF - ((PROTOCOL_DATA[protocol_index].BIT_LOW_DUTY * 0xFF) / 100));
// enable interrupt for RF transmitting
PCA0CPM0 |= PCA0CPM0_ECCF__ENABLED;
// disable interrupt for RF receiving
PCA0CPM1 &= ~PCA0CPM1_ECCF__ENABLED;
/***********************************************************************
- PCA Counter/Timer Low Byte = 0xFF
***********************************************************************/
PCA0L = (0xFF << PCA0L_PCA0L__SHIFT);
}
}
return protocol_index;
}
void PCA0_StopTransmit(void)
{
// set duty cycle to zero
PCA0_writeChannel(PCA0_CHAN0, 0x0000);
// disable interrupt for RF transmitting
PCA0CPM0 &= ~PCA0CPM0_ECCF__ENABLED;
PCA0_halt();
// enable P0.0 for I/O control
XBR1 &= ~XBR1_PCA0ME__CEX0_CEX1;
// switch to low
T_DATA = 0;
// disable P0.0 for I/O control, enter PCA mode
XBR1 |= XBR1_PCA0ME__CEX0_CEX1;
// restart sniffing it was active
if(sniffing_is_on)
PCA0_DoSniffing();
}
void PCA0_DoSniffing(void)
{
// restore timer to 100000Hz, 10µs interval
//Save Timer Configuration
uint8_t TCON_save;
TCON_save = TCON;
//Stop Timer 0
TCON &= ~TCON_TR0__BMASK;
/***********************************************************************
- Timer 0 High Byte = 0x0B
***********************************************************************/
TH0 = (0x0B << TH0_TH0__SHIFT);
//Restore Timer Configuration
TCON |= (TCON_save & TCON_TR0__BMASK);
// stop PCA
PCA0CN0_CR = PCA0CN0_CR__STOP;
// enable interrupt for RF receiving
PCA0CPM1 |= PCA0CPM1_ECCF__ENABLED;
// disable interrupt for RF transmitting
PCA0CPM0 &= ~PCA0CPM0_ECCF__ENABLED;
// start PCA
PCA0CN0_CR = PCA0CN0_CR__RUN;
rf_state = RF_IDLE;
RF_DATA_STATUS = 0;
sniffing_is_on = true;
}
void PCA0_StopSniffing(void)
{
// stop PCA
PCA0CN0_CR = PCA0CN0_CR__STOP;
// disable interrupt for RF receiving
PCA0CPM1 &= ~PCA0CPM1_ECCF__ENABLED;
}
//-----------------------------------------------------------------------------
// TIMER3_ISR
//-----------------------------------------------------------------------------
//
// TIMER3 ISR Content goes here. Remember to clear flag bits:
// TMR3CN0::TF3H (Timer # High Byte Overflow Flag)
// TMR3CN0::TF3L (Timer # Low Byte Overflow Flag)
//
//-----------------------------------------------------------------------------
SI_INTERRUPT (TIMER3_ISR, TIMER3_IRQn)
{
// Clear Timer 3 high overflow flag
TMR3CN0 &= ~TMR3CN0_TF3H__SET;
// check if pulse time is over
if(Timer_3_Timeout <= 0)
{
// stop timer
TMR3CN0 &= ~TMR3CN0_TR3__RUN;
}
Timer_3_Timeout -= 5;
}

203
src/SILABS_STARTUP.A51 Normal file
View File

@ -0,0 +1,203 @@
$NOMOD51
;------------------------------------------------------------------------------
; This file is part of the C51 Compiler package
; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
; Version 8.01
;
; *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
; STARTUP.A51: This code is executed after processor reset.
;
; To translate this file use A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use the following
; Lx51 invocation:
;
; Lx51 your object file list, STARTUP.OBJ controls
;
;------------------------------------------------------------------------------
;
; User-defined <h> Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; <o> IDATALEN: IDATA memory size <0x0-0x100>
; <i> Note: The absolute start-address of IDATA memory is always 0
; <i> The IDATA space overlaps physically the DATA and BIT areas.
IDATALEN EQU 80H
;
; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of XDATA memory
XDATASTART EQU 0
;
; <o> XDATALEN: XDATA memory size <0x0-0xFFFF>
; <i> The length of XDATA memory in bytes.
XDATALEN EQU 0
;
; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of PDATA memory
PDATASTART EQU 0H
;
; <o> PDATALEN: PDATA memory size <0x0-0xFF>
; <i> The length of PDATA memory in bytes.
PDATALEN EQU 0H
;
;</h>
;------------------------------------------------------------------------------
;
;<h> Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
;
; <h> Stack Space for reentrant functions in the SMALL model.
; <q> IBPSTACK: Enable SMALL model reentrant stack
; <i> Stack space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
; <i> Set the top of the stack to the highest location.
IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the LARGE model.
; <q> XBPSTACK: Enable LARGE model reentrant stack
; <i> Stack space for reentrant functions in the LARGE model.
XBPSTACK EQU 0 ; set to 1 if large reentrant is used.
; <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the COMPACT model.
; <q> PBPSTACK: Enable COMPACT model reentrant stack
; <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.
;
; <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;</h>
;------------------------------------------------------------------------------
;
; Memory Page for Using the Compact Model with 64 KByte xdata RAM
; <e>Compact Model Page Definition
;
; <i>Define the XDATA page used for PDATA variables.
; <i>PPAGE must conform with the PPAGE set in the linker invocation.
;
; Enable pdata memory page initalization
PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
;
; <o> PPAGE number <0x0-0xFF>
; <i> uppermost 256-byte address of the page used for PDATA variables.
PPAGE EQU 0
;
; <o> SFR address which supplies uppermost address byte <0x0-0xFF>
; <i> most 8051 variants use P2 as uppermost address byte
PPAGE_SFR DATA 0A0H
;
; </e>
;------------------------------------------------------------------------------
; Standard SFR Symbols
ACC DATA 0E0H
B DATA 0F0H
SP DATA 81H
DPL DATA 82H
DPH DATA 83H
NAME ?C_STARTUP
?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA
RSEG ?STACK
DS 1
EXTRN CODE (?C_START)
PUBLIC ?C_STARTUP
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
$IF (SILABS_STARTUP = 1)
EXTRN CODE (SiLabs_Startup)
LCALL SiLabs_Startup
$ENDIF
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF XDATALEN <> 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV R6,#(HIGH (XDATALEN)) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV PPAGE_SFR,#PPAGE
ENDIF
IF PDATALEN <> 0
MOV R0,#LOW (PDATASTART)
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV ?C_IBP,#LOW IBPSTACKTOP
ENDIF
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF
MOV SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
;<h> Code Banking
; <q> Select Bank 0 for L51_BANK.A51 Mode 4
$IF (USE_BANKING = 1)
; <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
EXTRN CODE (?B_SWITCH0)
CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
$ENDIF
;</h>
LJMP ?C_START
END

266
src/uart.c Normal file
View File

@ -0,0 +1,266 @@
/*
* uart.c
*
* Created on: 27.11.2017
* Author:
*/
#include <SI_EFM8BB1_Register_Enums.h>
#include <string.h>
#include "Globals.h"
#include "uart_0.h"
#include "uart.h"
#include "RF_Handling.h"
#include "RF_Protocols.h"
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
SI_SEGMENT_VARIABLE(UART_RX_Buffer[UART_BUFFER_SIZE], uint8_t, SI_SEG_XDATA);
SI_SEGMENT_VARIABLE(UART_TX_Buffer[UART_BUFFER_SIZE], uint8_t, SI_SEG_XDATA);
SI_SEGMENT_VARIABLE(UART_RX_Buffer_Position, static volatile uint8_t, SI_SEG_XDATA)=0;
SI_SEGMENT_VARIABLE(UART_TX_Buffer_Position, static volatile uint8_t, SI_SEG_XDATA)=0;
SI_SEGMENT_VARIABLE(UART_Buffer_Read_Position, static volatile uint8_t, SI_SEG_XDATA)=0;
SI_SEGMENT_VARIABLE(UART_Buffer_Write_Position, static volatile uint8_t, SI_SEG_XDATA)=0;
SI_SEGMENT_VARIABLE(lastRxError, static volatile uint8_t, SI_SEG_XDATA)=0;
/*
uint8_t SendCommand(uint8_t command)
{
uart_buffer[0] = UART_SYNC_INIT;
uart_buffer[1] = command;
uart_buffer[2] = UART_SYNC_END;
return 3;
}
*/
/*
void SendData(SI_VARIABLE_SEGMENT_POINTER(buffer, uint8_t, EFM8PDL_UART0_TX_BUFTYPE), uint8_t len)
{
uart_buffer[0] = UART_SYNC_INIT;
memcpy(&uart_buffer[1], buffer, len);
}
*/
//-----------------------------------------------------------------------------
// UART ISR Callbacks
//-----------------------------------------------------------------------------
void UART0_receiveCompleteCb()
{
//UART0_writeBuffer(uart_buffer, 1);
/*
static uint8_t len;
static uart_command_t uart_command;
switch(uart_state)
{
// check if byte was got received is sync byte
case SYNC_INIT:
len = 0;
if (uart_buffer[0] == UART_SYNC_INIT)
uart_state = COMMAND;
// start reading the next byte
UART0_readBuffer(uart_buffer, 1);
break;
// check which command should be handled
case COMMAND:
uart_command = uart_buffer[0];
// check which command got received
switch(uart_command)
{
case LEARNING:
uart_state = SYNC_FINISH;
break;
default:
uart_state = SYNC_INIT;
break;
}
// start reading the next byte and data if available
UART0_readBuffer(uart_buffer, 1 + len);
break;
// check if byte was got received is sync byte
case SYNC_FINISH:
if (uart_buffer[len] == UART_SYNC_END)
{
// send acknowledge
len = SendCommand(COMMAND_AK);
UART0_writeBuffer(uart_buffer, len);
uart_state = TRANSMIT;
}
break;
}
*/
}
void UART0_transmitCompleteCb()
{
}
//=========================================================
// Interrupt API
//=========================================================
SI_INTERRUPT(UART0_ISR, UART0_IRQn)
{
//Buffer and clear flags immediately so we don't miss an interrupt while processing
uint8_t flags = SCON0 & (UART0_RX_IF | UART0_TX_IF);
SCON0 &= ~flags;
// receiving byte
if ((flags & SCON0_RI__SET))
{
if ( UART_RX_Buffer_Position == UART_BUFFER_SIZE )
{
/* error: receive buffer overflow */
lastRxError = UART_BUFFER_OVERFLOW >> 8;
}
else
{
/* store received data in buffer */
UART_RX_Buffer[UART_RX_Buffer_Position] = SBUF0;
UART_RX_Buffer_Position++;
}
}
// transmit byte
if ((flags & SCON0_TI__SET))
{
if ( UART_TX_Buffer_Position == UART_BUFFER_SIZE )
{
/* error: receive buffer overflow */
lastRxError = UART_BUFFER_OVERFLOW >> 8;
}
else
{
if (UART_Buffer_Write_Position < UART_TX_Buffer_Position)
{
SBUF0 = UART_TX_Buffer[UART_Buffer_Write_Position];
UART_Buffer_Write_Position++;
}
if (UART_Buffer_Write_Position == UART_TX_Buffer_Position)
{
UART_TX_Buffer_Position = 0;
UART_Buffer_Write_Position = 0;
}
}
}
}
void uart_buffer_reset(void)
{
UART_RX_Buffer_Position = 0;
UART_Buffer_Read_Position = 0;
UART_TX_Buffer_Position = 0;
UART_Buffer_Write_Position = 0;
}
uint8_t uart_getlen(void)
{
return UART_RX_Buffer_Position - UART_Buffer_Read_Position;
}
bool uart_transfer_finished(void)
{
return UART_Buffer_Write_Position == UART_TX_Buffer_Position;
}
/*************************************************************************
Function: uart_getc()
Purpose: return byte from ringbuffer
Returns: lower byte: received byte from ringbuffer
higher byte: last receive error
**************************************************************************/
unsigned int uart_getc(void)
{
unsigned int rxdata;
if ( UART_Buffer_Read_Position == UART_RX_Buffer_Position ) {
return UART_NO_DATA; /* no data available */
}
/* get data from receive buffer */
rxdata = UART_RX_Buffer[UART_Buffer_Read_Position];
UART_Buffer_Read_Position++;
/* all got read of the received data, reset to 0 */
if (UART_Buffer_Read_Position == UART_RX_Buffer_Position)
{
UART_Buffer_Read_Position = 0;
UART_RX_Buffer_Position = 0;
}
rxdata |= (lastRxError << 8);
lastRxError = 0;
return rxdata;
}
/*************************************************************************
Function: uart_putc()
Purpose: write byte to ringbuffer for transmitting via UART
Input: byte to be transmitted
Returns: none
**************************************************************************/
void uart_putc(uint8_t txdata)
{
if (UART_TX_Buffer_Position == UART_BUFFER_SIZE)
lastRxError = UART_BUFFER_OVERFLOW >> 8;
UART_TX_Buffer[UART_TX_Buffer_Position] = txdata;
UART_TX_Buffer_Position++;
}
void uart_put_command(uint8_t command)
{
uart_putc(UART_SYNC_INIT);
uart_putc(command);
uart_putc(UART_SYNC_END);
UART0_initTxPolling();
}
void uart_put_uint16_t(uint8_t command, uint16_t value)
{
uart_putc(UART_SYNC_INIT);
uart_putc(command);
uart_putc((value >> 8) & 0xFF);
uart_putc(value & 0xFF);
uart_putc(UART_SYNC_END);
UART0_initTxPolling();
}
void uart_put_RF_Data(uint8_t Command, uint8_t used_protocol)
{
uint8_t i = 0;
uint8_t b = 0;
uart_putc(UART_SYNC_INIT);
uart_putc(Command);
while(i < PROTOCOL_DATA[used_protocol].BIT_COUNT)
{
i += 8;
b++;
}
uart_putc(b+1);
// set identifier for this protocol
uart_putc(PROTOCOL_DATA[used_protocol].IDENTIFIER);
// copy data to UART buffer
i = 0;
while(i < b)
{
uart_putc(RF_DATA[i]);
i++;
}
uart_putc(UART_SYNC_END);
UART0_initTxPolling();
}