diff --git a/Samples/Blinky/Blinky-samc21xpro.lpi b/Samples/Blinky/Blinky-samc21xpro.lpi index a13e7a0..771beef 100644 --- a/Samples/Blinky/Blinky-samc21xpro.lpi +++ b/Samples/Blinky/Blinky-samc21xpro.lpi @@ -73,12 +73,12 @@ - + - + @@ -86,20 +86,18 @@ - - + diff --git a/Samples/Blinky/Blinky-samd10xmini.lpi b/Samples/Blinky/Blinky-samd10xmini.lpi new file mode 100644 index 0000000..ca42698 --- /dev/null +++ b/Samples/Blinky/Blinky-samd10xmini.lpi @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/Blinky/Blinky-samd20xpro.lpi b/Samples/Blinky/Blinky-samd20xpro.lpi index a439a2b..c1d2826 100644 --- a/Samples/Blinky/Blinky-samd20xpro.lpi +++ b/Samples/Blinky/Blinky-samd20xpro.lpi @@ -66,12 +66,12 @@ - + - + @@ -79,20 +79,18 @@ - - + diff --git a/Samples/Blinky/Blinky-samd21xpro.lpi b/Samples/Blinky/Blinky-samd21xpro.lpi index 5ff5a23..6e08802 100644 --- a/Samples/Blinky/Blinky-samd21xpro.lpi +++ b/Samples/Blinky/Blinky-samd21xpro.lpi @@ -26,8 +26,8 @@ - - + + @@ -114,12 +114,12 @@ - + - + @@ -127,20 +127,18 @@ - - + diff --git a/Samples/MBEDAppShield/MBED.lpi b/Samples/MBEDAppShield/MBED.lpi new file mode 100644 index 0000000..c147fa9 --- /dev/null +++ b/Samples/MBEDAppShield/MBED.lpi @@ -0,0 +1,920 @@ + + + + + + + + + + + <UseAppBundle Value="False"/> + </General> + <BuildModes Count="2" Active="SAMC21"> + <Item1 Name="SAMD10" Default="True"/> + <Item2 Name="SAMC21"> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="bin/$(TargetCPU)-$(TargetOS)/samc21/$NameOnly($(ProjFile))"/> + </Target> + <SearchPaths> + <IncludeFiles Value="../../Source;$(ProjOutDir)"/> + <OtherUnitFiles Value="../../Source"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/samc21"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="arm"/> + <TargetOS Value="embedded"/> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <DebugInfoType Value="dsDwarf2"/> + <UseLineInfoUnit Value="False"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <CustomOptions Value="-Cparmv6m +-a +-al +-Xs +-Xg +-WpSAMC21XPRO +-dSAMC21XPRO"/> + </Other> + </CompilerOptions> + </Item2> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="1"> + <Mode0 Name="default"/> + </Modes> + </RunParams> + <Units Count="103"> + <Unit0> + <Filename Value="MBED.lpr"/> + <IsPartOfProject Value="True"/> + <TopLine Value="9"/> + <CursorPos X="11" Y="26"/> + <UsageCount Value="200"/> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + </Unit0> + <Unit1> + <Filename Value="../../Source/MBF.Config.inc"/> + <EditorIndex Value="4"/> + <TopLine Value="51"/> + <CursorPos X="24" Y="71"/> + <UsageCount Value="35"/> + <Loaded Value="True"/> + </Unit1> + <Unit2> + <Filename Value="../../Source/MBF.Boards.NRF51.inc"/> + <EditorIndex Value="-1"/> + <UsageCount Value="10"/> + </Unit2> + <Unit3> + <Filename Value="../../Source/mbf.boards.atsamcd21.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos X="36" Y="33"/> + <UsageCount Value="6"/> + </Unit3> + <Unit4> + <Filename Value="../../Source/MBF.NRF51.Systemcore.pas"/> + <UnitName Value="mbf.nrf51.systemcore"/> + <EditorIndex Value="-1"/> + <TopLine Value="11"/> + <CursorPos X="4" Y="29"/> + <UsageCount Value="10"/> + </Unit4> + <Unit5> + <Filename Value="../../Source/MBF.SAMD10.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="73"/> + <CursorPos X="30" Y="88"/> + <UsageCount Value="28"/> + </Unit5> + <Unit6> + <Filename Value="../../Source/MBF.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="299"/> + <CursorPos X="24" Y="238"/> + <UsageCount Value="15"/> + </Unit6> + <Unit7> + <Filename Value="../../Source/MBF.LPC8xx.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos X="3" Y="179"/> + <UsageCount Value="10"/> + </Unit7> + <Unit8> + <Filename Value="../../Source/MBF.SAMD10.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="11"/> + <CursorPos Y="28"/> + <UsageCount Value="36"/> + </Unit8> + <Unit9> + <Filename Value="../../Source/MBF.Boards.LPC8xx.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="38"/> + <UsageCount Value="10"/> + </Unit9> + <Unit10> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/sam10d.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="13"/> + <CursorPos X="29" Y="35"/> + <UsageCount Value="29"/> + </Unit10> + <Unit11> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/atmel/samd10/samd10-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="3"/> + <UsageCount Value="10"/> + </Unit11> + <Unit12> + <Filename Value="../../Source/MBF.SAMD10.Helpers.pas"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="-1"/> + <TopLine Value="15"/> + <CursorPos X="11" Y="32"/> + <UsageCount Value="199"/> + </Unit12> + <Unit13> + <Filename Value="../../Source/MBF.PIC32MX.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="216"/> + <CursorPos Y="247"/> + <UsageCount Value="10"/> + </Unit13> + <Unit14> + <Filename Value="../../Source/MBF.Devices.ULN2003.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="48"/> + <CursorPos X="41" Y="66"/> + <UsageCount Value="10"/> + </Unit14> + <Unit15> + <Filename Value="../../Source/MBF.STM32L4.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="254"/> + <CursorPos X="69" Y="266"/> + <UsageCount Value="1"/> + </Unit15> + <Unit16> + <Filename Value="../../Source/MBF.STM32F0.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="239"/> + <CursorPos X="69" Y="251"/> + <UsageCount Value="1"/> + </Unit16> + <Unit17> + <Filename Value="../../Source/MBF.Kinetis.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="107"/> + <CursorPos X="78" Y="110"/> + <UsageCount Value="5"/> + </Unit17> + <Unit18> + <Filename Value="../../Source/MBF.LPC8xx.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="59"/> + <CursorPos Y="79"/> + <UsageCount Value="1"/> + </Unit18> + <Unit19> + <Filename Value="../../Source/MBF.SAMD10.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="64"/> + <CursorPos X="18" Y="23"/> + <UsageCount Value="33"/> + </Unit19> + <Unit20> + <Filename Value="../../Source/MBF.SAMD10.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="261"/> + <CursorPos X="109" Y="38"/> + <UsageCount Value="33"/> + </Unit20> + <Unit21> + <Filename Value="../../Source/samd10/samd10-pm.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="29"/> + <CursorPos X="26" Y="46"/> + <UsageCount Value="2"/> + </Unit21> + <Unit22> + <Filename Value="../../Source/samd10/samd10-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="25" Y="3"/> + <UsageCount Value="10"/> + </Unit22> + <Unit23> + <Filename Value="../../Source/samd10/samd10-adc.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="9"/> + <UsageCount Value="7"/> + </Unit23> + <Unit24> + <Filename Value="../../Source/samd10/samd10-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="60"/> + <CursorPos Y="89"/> + <UsageCount Value="10"/> + </Unit24> + <Unit25> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/atmel/samd10/samd10-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="42"/> + <CursorPos X="31" Y="68"/> + <UsageCount Value="25"/> + </Unit25> + <Unit26> + <Filename Value="../../Source/MBF.STM32F3.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="44"/> + <CursorPos Y="63"/> + <UsageCount Value="23"/> + </Unit26> + <Unit27> + <Filename Value="../../Source/samd10/samd10-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="66"/> + <CursorPos Y="90"/> + <UsageCount Value="10"/> + </Unit27> + <Unit28> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd11c14a.pp"/> + <EditorIndex Value="-1"/> + <UsageCount Value="5"/> + </Unit28> + <Unit29> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd10d14a.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="51"/> + <CursorPos X="5" Y="69"/> + <UsageCount Value="5"/> + </Unit29> + <Unit30> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/lazarus/components/codetools/definetemplates.pas"/> + <UnitName Value="DefineTemplates"/> + <EditorIndex Value="-1"/> + <TopLine Value="7863"/> + <CursorPos X="38" Y="7871"/> + <UsageCount Value="5"/> + </Unit30> + <Unit31> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd10d13a.pp"/> + <EditorIndex Value="-1"/> + <CursorPos X="16"/> + <UsageCount Value="5"/> + </Unit31> + <Unit32> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/compiler/arm/cpuinfo.pas"/> + <UnitName Value="CPUInfo"/> + <EditorIndex Value="-1"/> + <TopLine Value="1057"/> + <CursorPos X="33" Y="1071"/> + <UsageCount Value="5"/> + </Unit32> + <Unit33> + <Filename Value="../../Source/samd10/samd10-nvmctrl.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="30" Y="4"/> + <UsageCount Value="5"/> + </Unit33> + <Unit34> + <Filename Value="../../Source/MBF.STM32F3.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="130"/> + <CursorPos X="69" Y="151"/> + <UsageCount Value="5"/> + </Unit34> + <Unit35> + <Filename Value="../../Source/MBF.Boards.ATSAMD10D.inc"/> + <EditorIndex Value="-1"/> + <CursorPos Y="26"/> + <UsageCount Value="6"/> + </Unit35> + <Unit36> + <Filename Value="../../Source/MBF.Boards.ATSAMCD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="2"/> + <CursorPos X="24" Y="26"/> + <UsageCount Value="6"/> + </Unit36> + <Unit37> + <Filename Value="../../Source/MBF.SAMCD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <CursorPos X="9" Y="18"/> + <UsageCount Value="6"/> + </Unit37> + <Unit38> + <Filename Value="../../Source/MBF.SAMCD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="223"/> + <CursorPos X="30" Y="216"/> + <UsageCount Value="6"/> + </Unit38> + <Unit39> + <Filename Value="../../Source/MBF.SAMCD.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="317"/> + <CursorPos X="51" Y="338"/> + <UsageCount Value="11"/> + </Unit39> + <Unit40> + <Filename Value="../../Source/MBF.SAMCD.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="34"/> + <UsageCount Value="6"/> + </Unit40> + <Unit41> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samc21j18a.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="745"/> + <CursorPos X="3" Y="340"/> + <UsageCount Value="6"/> + </Unit41> + <Unit42> + <Filename Value="../../Source/MBF.Boards.ATSAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="13"/> + <CursorPos X="36" Y="23"/> + <UsageCount Value="21"/> + </Unit42> + <Unit43> + <Filename Value="../../Source/MBF.SAMD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <CursorPos Y="95"/> + <UsageCount Value="19"/> + </Unit43> + <Unit44> + <Filename Value="../../Source/MBF.SAMD.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="95"/> + <CursorPos Y="102"/> + <UsageCount Value="10"/> + </Unit44> + <Unit45> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd21j18a.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="435"/> + <CursorPos X="5" Y="450"/> + <UsageCount Value="9"/> + </Unit45> + <Unit46> + <Filename Value="../../Source/atsamd/samd-pm.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="88"/> + <CursorPos Y="111"/> + <UsageCount Value="5"/> + </Unit46> + <Unit47> + <Filename Value="../../Source/MBF.SAMD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="21"/> + <CursorPos X="37" Y="73"/> + <UsageCount Value="18"/> + </Unit47> + <Unit48> + <Filename Value="../../Source/atsamd/samd-adc.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="20"/> + <UsageCount Value="7"/> + </Unit48> + <Unit49> + <Filename Value="../../Source/MBF.SAMD.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="97"/> + <CursorPos Y="124"/> + <UsageCount Value="41"/> + </Unit49> + <Unit50> + <Filename Value="../../Source/atsamd/samd-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="45"/> + <CursorPos X="3" Y="63"/> + <UsageCount Value="8"/> + </Unit50> + <Unit51> + <Filename Value="../../Source/atsamd/samd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="150"/> + <CursorPos Y="162"/> + <UsageCount Value="28"/> + </Unit51> + <Unit52> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/heapmgr.pp"/> + <EditorIndex Value="-1"/> + <UsageCount Value="5"/> + </Unit52> + <Unit53> + <Filename Value="../../Source/atsamd/samd-nvmctrl.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="21"/> + <CursorPos X="3" Y="38"/> + <UsageCount Value="6"/> + </Unit53> + <Unit54> + <Filename Value="../../Source/MBF.SAMD.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="270"/> + <CursorPos X="44" Y="274"/> + <UsageCount Value="37"/> + </Unit54> + <Unit55> + <Filename Value="../../Source/atsamd/samd-port.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="651"/> + <CursorPos X="3" Y="665"/> + <UsageCount Value="9"/> + </Unit55> + <Unit56> + <Filename Value="../../Source/MBF.SAMC.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="72"/> + <CursorPos X="57" Y="83"/> + <UsageCount Value="6"/> + </Unit56> + <Unit57> + <Filename Value="../../Source/MBF.Boards.ATSAMC.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos Y="51"/> + <UsageCount Value="6"/> + </Unit57> + <Unit58> + <Filename Value="../../Source/MBF.SAMD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="139"/> + <CursorPos X="3" Y="145"/> + <UsageCount Value="22"/> + </Unit58> + <Unit59> + <Filename Value="../../Source/MBF.SAMD.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="112"/> + <CursorPos Y="122"/> + <UsageCount Value="28"/> + </Unit59> + <Unit60> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/inc/systemh.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="97"/> + <CursorPos X="3" Y="111"/> + <UsageCount Value="10"/> + </Unit60> + <Unit61> + <Filename Value="../../Source/MBF.SAMD.SPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="47"/> + <CursorPos X="30" Y="62"/> + <UsageCount Value="14"/> + </Unit61> + <Unit62> + <Filename Value="../../Source/MBF.Displays.C12832.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="183"/> + <CursorPos Y="601"/> + <UsageCount Value="11"/> + </Unit62> + <Unit63> + <Filename Value="../../../Source/MBF.Config.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="51"/> + <CursorPos X="24" Y="72"/> + <UsageCount Value="13"/> + </Unit63> + <Unit64> + <Filename Value="../../../Source/MBF.SAMC.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="8"/> + <CursorPos X="23" Y="119"/> + <UsageCount Value="11"/> + </Unit64> + <Unit65> + <Filename Value="../../../Source/MBF.SAMC.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="266"/> + <CursorPos X="46" Y="286"/> + <UsageCount Value="11"/> + </Unit65> + <Unit66> + <Filename Value="../../../Source/MBF.Boards.ATSAMC.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="27"/> + <CursorPos Y="48"/> + <UsageCount Value="13"/> + </Unit66> + <Unit67> + <Filename Value="../../../Source/MBF.Boards.ATSAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="19"/> + <CursorPos Y="56"/> + <UsageCount Value="10"/> + </Unit67> + <Unit68> + <Filename Value="../../../Source/atsamd/samd-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="5"/> + <UsageCount Value="10"/> + </Unit68> + <Unit69> + <Filename Value="../../../Source/MBF.SAMD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="79"/> + <CursorPos X="23" Y="169"/> + <UsageCount Value="10"/> + </Unit69> + <Unit70> + <Filename Value="../../../Source/MBF.SAMD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="17"/> + <CursorPos X="4" Y="31"/> + <UsageCount Value="9"/> + </Unit70> + <Unit71> + <Filename Value="../../../Source/MBF.SAMC.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="17"/> + <CursorPos X="17" Y="28"/> + <UsageCount Value="10"/> + </Unit71> + <Unit72> + <Filename Value="../../../Source/MBF.SAMC.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="52"/> + <CursorPos X="14" Y="65"/> + <UsageCount Value="9"/> + </Unit72> + <Unit73> + <Filename Value="../../../Source/atsamd/samd-mclk.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="28" Y="15"/> + <UsageCount Value="10"/> + </Unit73> + <Unit74> + <Filename Value="../../../Source/MBF.SAMD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="4"/> + <CursorPos X="18" Y="9"/> + <UsageCount Value="10"/> + </Unit74> + <Unit75> + <Filename Value="../../../Source/atsamd/samd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="45"/> + <CursorPos X="3" Y="59"/> + <UsageCount Value="9"/> + </Unit75> + <Unit76> + <Filename Value="../../../Source/atsamd/samd-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="81"/> + <CursorPos X="22" Y="71"/> + <UsageCount Value="10"/> + </Unit76> + <Unit77> + <Filename Value="../../../Source/MBF.SAMCD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="196"/> + <CursorPos X="17" Y="205"/> + <UsageCount Value="16"/> + </Unit77> + <Unit78> + <Filename Value="../../../Source/MBF.SAMCD.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="56"/> + <CursorPos X="12" Y="52"/> + <UsageCount Value="12"/> + </Unit78> + <Unit79> + <Filename Value="../../../Source/MBF.SAMCD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="174"/> + <CursorPos X="31" Y="198"/> + <UsageCount Value="17"/> + </Unit79> + <Unit80> + <Filename Value="../../../Source/MBF.SAMCD.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="7"/> + <CursorPos X="12" Y="23"/> + <UsageCount Value="13"/> + </Unit80> + <Unit81> + <Filename Value="../../../Source/MBF.SAMCD.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="81"/> + <CursorPos X="3" Y="240"/> + <UsageCount Value="19"/> + </Unit81> + <Unit82> + <Filename Value="../../../Source/MBF.SAMCD.SPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="46"/> + <CursorPos X="79" Y="61"/> + <UsageCount Value="10"/> + </Unit82> + <Unit83> + <Filename Value="../../../Source/MBF.Displays.C12832.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="10"/> + <CursorPos Y="23"/> + <UsageCount Value="13"/> + </Unit83> + <Unit84> + <Filename Value="../../../Source/MBF.Displays.CustomDisplay.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="41"/> + <CursorPos X="3" Y="133"/> + <UsageCount Value="10"/> + </Unit84> + <Unit85> + <Filename Value="../../../Source/MBF.Displays.CustomSPIDisplay.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="35"/> + <UsageCount Value="10"/> + </Unit85> + <Unit86> + <Filename Value="../../../Source/MBF.SAMCD.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="152"/> + <CursorPos X="35" Y="76"/> + <UsageCount Value="13"/> + </Unit86> + <Unit87> + <Filename Value="../../../Source/atsamcd/samcd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="74"/> + <CursorPos X="3" Y="91"/> + <UsageCount Value="18"/> + </Unit87> + <Unit88> + <Filename Value="../../../Source/atsamcd/samcd-adc.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="22"/> + <CursorPos X="42" Y="36"/> + <UsageCount Value="10"/> + </Unit88> + <Unit89> + <Filename Value="../../../Source/MBF.SAMCD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="2"/> + <CursorPos X="9" Y="27"/> + <UsageCount Value="13"/> + </Unit89> + <Unit90> + <Filename Value="../../../../../../../fpclazbydeluxe/trunknewforarm/fpcsrc/packages/fcl-base/examples/xmldump.pp"/> + <EditorIndex Value="-1"/> + <CursorPos X="12" Y="12"/> + <UsageCount Value="13"/> + </Unit90> + <Unit91> + <Filename Value="../../../../../../../fpclazbydeluxe/trunknewforarm/fpcsrc/rtl/solaris/x86_64/start.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="71"/> + <CursorPos X="10" Y="88"/> + <UsageCount Value="13"/> + </Unit91> + <Unit92> + <Filename Value="../../../../../../../fpclazbydeluxe/trunknewforarm/fpcsrc/compiler/systems/t_embed.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="1709"/> + <CursorPos X="19" Y="1725"/> + <UsageCount Value="13"/> + </Unit92> + <Unit93> + <Filename Value="../../../Source/atsamcd/samcd-nvmctrl.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="20" Y="19"/> + <UsageCount Value="11"/> + </Unit93> + <Unit94> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/inc/generic.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="195"/> + <CursorPos X="3" Y="48"/> + <UsageCount Value="10"/> + </Unit94> + <Unit95> + <Filename Value="../../../Source/MBF.Boards.SAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="52"/> + <CursorPos X="17" Y="73"/> + <UsageCount Value="10"/> + </Unit95> + <Unit96> + <Filename Value="../../../Source/MBF.BitHelpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="10"/> + <CursorPos X="5" Y="27"/> + <UsageCount Value="10"/> + </Unit96> + <Unit97> + <Filename Value="../../Source/MBF.Boards.SAMC.inc"/> + <EditorIndex Value="5"/> + <CursorPos X="24" Y="21"/> + <UsageCount Value="12"/> + <Loaded Value="True"/> + </Unit97> + <Unit98> + <Filename Value="../../Source/MBF.Displays.CustomDisplay.pas"/> + <EditorIndex Value="-1"/> + <CursorPos Y="131"/> + <UsageCount Value="11"/> + </Unit98> + <Unit99> + <Filename Value="../../Source/MBF.BitHelpers.pas"/> + <IsVisibleTab Value="True"/> + <EditorIndex Value="3"/> + <TopLine Value="199"/> + <CursorPos X="18" Y="11"/> + <UsageCount Value="12"/> + <Loaded Value="True"/> + </Unit99> + <Unit100> + <Filename Value="../../Source/atsamcd/samcd-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="23"/> + <UsageCount Value="10"/> + </Unit100> + <Unit101> + <Filename Value="../../Source/MBF.SAMCD.I2C.pas"/> + <EditorIndex Value="1"/> + <TopLine Value="237"/> + <CursorPos X="86" Y="240"/> + <UsageCount Value="11"/> + <Loaded Value="True"/> + </Unit101> + <Unit102> + <Filename Value="../../Source/atsamcd/samcd-sercom.inc"/> + <EditorIndex Value="2"/> + <TopLine Value="77"/> + <CursorPos X="3" Y="90"/> + <UsageCount Value="11"/> + <Loaded Value="True"/> + </Unit102> + </Units> + <JumpHistory Count="26" HistoryIndex="25"> + <Position1> + <Filename Value="MBED.lpr"/> + <Caret Line="273" TopLine="259"/> + </Position1> + <Position2> + <Filename Value="MBED.lpr"/> + <Caret Line="227" Column="7" TopLine="220"/> + </Position2> + <Position3> + <Filename Value="MBED.lpr"/> + <Caret Line="31" Column="17" TopLine="14"/> + </Position3> + <Position4> + <Filename Value="MBED.lpr"/> + <Caret Line="141" Column="50" TopLine="128"/> + </Position4> + <Position5> + <Filename Value="MBED.lpr"/> + </Position5> + <Position6> + <Filename Value="MBED.lpr"/> + <Caret Line="251" Column="31" TopLine="230"/> + </Position6> + <Position7> + <Filename Value="MBED.lpr"/> + </Position7> + <Position8> + <Filename Value="MBED.lpr"/> + <Caret Line="265" Column="38" TopLine="252"/> + </Position8> + <Position9> + <Filename Value="MBED.lpr"/> + <Caret Line="279" Column="19" TopLine="269"/> + </Position9> + <Position10> + <Filename Value="MBED.lpr"/> + <Caret Line="24" TopLine="11"/> + </Position10> + <Position11> + <Filename Value="MBED.lpr"/> + <Caret Line="66" Column="7" TopLine="62"/> + </Position11> + <Position12> + <Filename Value="MBED.lpr"/> + <Caret Line="18" Column="20" TopLine="5"/> + </Position12> + <Position13> + <Filename Value="../../Source/MBF.Config.inc"/> + <Caret Line="71" Column="24" TopLine="51"/> + </Position13> + <Position14> + <Filename Value="MBED.lpr"/> + <Caret Line="278" Column="17" TopLine="272"/> + </Position14> + <Position15> + <Filename Value="MBED.lpr"/> + <Caret Line="278" Column="16" TopLine="272"/> + </Position15> + <Position16> + <Filename Value="MBED.lpr"/> + <Caret Line="278" Column="16" TopLine="272"/> + </Position16> + <Position17> + <Filename Value="MBED.lpr"/> + </Position17> + <Position18> + <Filename Value="MBED.lpr"/> + <Caret Line="237" Column="17" TopLine="222"/> + </Position18> + <Position19> + <Filename Value="MBED.lpr"/> + <Caret Line="257" Column="5" TopLine="247"/> + </Position19> + <Position20> + <Filename Value="../../Source/MBF.BitHelpers.pas"/> + <Caret Line="196" Column="9" TopLine="181"/> + </Position20> + <Position21> + <Filename Value="MBED.lpr"/> + <Caret Line="33" Column="28" TopLine="15"/> + </Position21> + <Position22> + <Filename Value="../../Source/MBF.SAMCD.I2C.pas"/> + <Caret Line="76" Column="24" TopLine="60"/> + </Position22> + <Position23> + <Filename Value="../../Source/MBF.SAMCD.I2C.pas"/> + <Caret Line="240" Column="92" TopLine="237"/> + </Position23> + <Position24> + <Filename Value="../../Source/MBF.BitHelpers.pas"/> + <Caret Line="27" Column="4" TopLine="14"/> + </Position24> + <Position25> + <Filename Value="../../Source/MBF.BitHelpers.pas"/> + <Caret Line="267" TopLine="140"/> + </Position25> + <Position26> + <Filename Value="../../Source/MBF.SAMCD.I2C.pas"/> + <Caret Line="240" Column="86" TopLine="237"/> + </Position26> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="bin/$(TargetCPU)-$(TargetOS)/samd10/$NameOnly($(ProjFile))"/> + </Target> + <SearchPaths> + <IncludeFiles Value="../../Source;$(ProjOutDir)"/> + <OtherUnitFiles Value="../../Source"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/samd10"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="arm"/> + <TargetOS Value="embedded"/> + <Optimizations> + <OptimizationLevel Value="2"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <DebugInfoType Value="dsDwarf2"/> + <UseLineInfoUnit Value="False"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <CustomOptions Value="-Cparmv6m +-a +-al +-Xs +-Xg +-WpSAMD10XMINI +-dSAMD10XMINI"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/Samples/MBEDAppShield/MBED.lpr b/Samples/MBEDAppShield/MBED.lpr new file mode 100644 index 0000000..1182ccd --- /dev/null +++ b/Samples/MBEDAppShield/MBED.lpr @@ -0,0 +1,377 @@ +program MBED; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} + +{< MBED application shield demo program. } + +{$INCLUDE MBF.Config.inc} + +{.$define DEBUG} + +uses + heapmgr, // this is needed for SAMD10, but keep it in place for the others also !!!! + MBF.BitHelpers, + MBF.Displays.C12832, + MBF.__CONTROLLERTYPE__.SystemCore, + {$ifdef DEBUG} + MBF.__CONTROLLERTYPE__.UART, + {$endif} + MBF.__CONTROLLERTYPE__.GPIO, + MBF.__CONTROLLERTYPE__.ADC, + MBF.__CONTROLLERTYPE__.I2C, + MBF.__CONTROLLERTYPE__.SPI; + +const + {$ifdef samc21j18a} + {$define __ADC__:=ADC0} + {$ifdef has_samc21_xplained_pro} + PinLED = LED0; + PinButton = SW0; + + {$ifdef DEBUG} + PortUART = 4; + PortUARTMux = TPinMux.MuxD; + PinTX = TNativePin.PB10; //PAD0 + PinRX = TNativePin.PB11; //PAD1 + PinTXMux = PortUARTMux; + PinRXMux = PortUARTMux; + {$endif} + + PortI2C = 2; + PortI2CMux = Ord(TPinMux.MuxC); + PinSDAMux = PortI2CMux; + PinSCLMux = PortI2CMux; + + PortSPI = 5; + PortSPIMux = Ord(TPinMux.MuxD); + PinMOSIMux = PortSPIMux; + PinMISOMux = PortSPIMux; + PinSCKMux = PortSPIMux; + {$endif has_samc21_xplained_pro} + {$endif samc21j18a} + + {$ifdef samd10d14a} + {$define __ADC__:=ADC} + {$ifdef has_samd10_xplained_mini} + PinLED = TNativePin.PA9; + PinButton = TNativePin.PA25; + + {$ifdef DEBUG} + PortUART = 0; + PinTX = TNativePin.PA10; //PAD0 + PinTXMux = 2; + PinRX = TNativePin.PA11; //PAD1 + PinRXMux = 2; + {$endif} + + PortI2C = 2; + PortI2CMux = Ord(TPinMux.MuxD); + PinSDAMux = PortI2CMux; + PinSCLMux = PortI2CMux; + + PortSPI = 1; + PortSPIMux = Ord(TPinMux.MuxC); + PinMOSIMux = PortSPIMux; + PinMISOMux = PortSPIMux; + PinSCKMux = PortSPIMux; + {$endif has_samd10_xplained_mini} + {$endif samd10d14} + + Fast = 100; + Slow = 500; + + PinLEDRed = TArduinoPin.D5; + PinLEDBlue = TArduinoPin.D8; + PinLEDGreen = TArduinoPin.D9; + + PinSDA = TArduinoPin.D14; + PinSCL = TArduinoPin.D15; + + PinSS = TArduinoPin.D10; + PinMOSI = TArduinoPin.D11; + PinMISO = TArduinoPin.None; + //PinMISO = TArduinoPin.D12; + PinSCK = TArduinoPin.D13; + + PinReset = TArduinoPin.D12; + PinA0 = TArduinoPin.D7; + + LM75_I2C_Address = ($90 shr 1); + LM75_TEMP_REGISTER = 0; + LM75_CONF_REGISTER = 1; + LM75_THYST_REGISTER = 2; + LM75_TOS_REGISTER = 3; + + MMA7660_I2C_Address = ($98 shr 1); + MMA7660_XOUT = 0; + MMA7660_YOUT = 1; + MMA7660_ZOUT = 2; + MMA7660_TILT = 3; + MMA7660_SRST = 4; + MMA7660_SPCNT = 5; + MMA7660_INTSU = 6; + MMA7660_MODE = 7; + MMA7660_SR = 8; + MMA7660_PDET = 9; + MMA7660_PD = 10; + + (* + * The MMA766 accelerometer has one measurement range: + * + * -1.5g - +1.5g (6-bit, signed) + * + * scale = (1.5 + 1.5) * 9.81 / (2^6 - 1) = 0.467142857 + *) + MMA7660_NSCALE = 467142857; + + POT1 = TArduinoPin.A0; + POT2 = TArduinoPin.A1; + +var + {$ifdef DEBUG} + UART1:TUART_Registers; + {$endif} + Display:TDisplay; + SPI1:TSPI_Registers; + I2C1:TI2C_Registers; + TurnedOn:boolean; + aData:word; + aRawData:longword; + aDataArray:packed array[0..1] of byte; + aResult,aFinalResult:string; + +procedure ToggleLed; +begin + TurnedOn:=NOT TurnedOn; + if (PinLEDGreen<>TNativePin.None) then + {%H-}begin + if TurnedOn then + begin + GPIO.PinValue[PinLEDGreen] := 0; + GPIO.PinValue[PinLEDBlue] := 1; + end + else + begin + GPIO.PinValue[PinLEDGreen] := 1; + GPIO.PinValue[PinLEDBlue] := 0; + end; + end + else + {%H-}begin + if TurnedOn then + GPIO.PinValue[PinLEDRed] := 1 + else + GPIO.PinValue[PinLEDRed] := 0; + end; +end; + +begin + SystemCore.Initialize; + + GPIO.Initialize; + + PutValue(aRawData,1,2,3); + + // Switch on Red LED pin for output. + GPIO.PinMode[PinLEDRed] := TPinMode.Output; + GPIO.PinValue[PinLEDRed] := 0; + + if (PinLEDBlue<>TNativePin.None) then + {%H-}begin + GPIO.PinMode[PinLEDBlue] := TPinMode.Output; + GPIO.PinValue[PinLEDBlue] := 1; + end; + if (PinLEDGreen<>TNativePin.None) then + {%H-}begin + GPIO.PinMode[PinLEDGreen] := TPinMode.Output; + GPIO.PinValue[PinLEDGreen] := 1; + end; + + {$ifdef DEBUG} + // Setup UART + // Setup pins + // PAD[0] TX + GPIO.PinMux[PinTX] := TPinMux(PinTXMux); + // PAD[1] RX + GPIO.PinMux[PinRX] := TPinMux(PinRXMux); + + // Setup UART port + + {$ifdef samc21} + UART1.Initialize(PortUART,9600,3,1); // PAD config: RXPO=3 ; TXPO=1 + {$endif} + {$ifdef samd10} + UART1.Initialize(PortUART,9600,3,1); // PAD config: RXPO=3 ; TXPO=1 + {$endif} + + UART1.WriteString('Hello debugger by SPI display test ! '+#13#10); + {$endif} + + {$ifdef samd21} + SPI1.Initialize(PortSPI,100000,3,0); // PAD3=MISO (DI) PAD0=MOSI (DO) ; PAD1=SCL ; SS_ on PAD[2] + {$endif} + {$ifdef samd10} + SPI1.Initialize(PortSPI,100000,2,3); // PAD2=MISO (DI) PAD0=MOSI (DO) ; PAD3=SCL ; SS_ on PAD[1] + {$endif} + {$ifdef samc21} + SPI1.Initialize(PortSPI,100000,0,1); // PAD0=MISO (DI) PAD2=MOSI (DO) ; PAD3=SCL ; SS_ on PAD[1] + {$endif} + + GPIO.PinMode[PinSS] := TPinMode.Output; + GPIO.PinValue[PinSS] := 1; + GPIO.PinMode[PinReset] := TPinMode.Output; + GPIO.PinValue[PinReset] := 1; + GPIO.PinMode[PinA0] := TPinMode.Output; + GPIO.PinValue[PinA0] := 1; + + GPIO.PinMux[PinMOSI] := TPinMux(PinMOSIMux); + GPIO.PinMux[PinSCK] := TPinMux(PinSCKMux); + if (PinMISO<>TNativePin.None) then {%H-}GPIO.PinMux[PinMISO] := TPinMux(PinMISOMux); + + Display.Initialize(SPI1,PinA0,PinReset,ScreenSize128x32x1); + Display.PinCS:=PinSS; + + Display.InitSequence; + + // not enough flash ... :-( + {$ifndef samd10} + Display.GetDemo1; + ToggleLed; + SystemCore.Delay(2500); + + Display.InvertScr(true); + Display.GetDemo2; + ToggleLed; + SystemCore.Delay(2500); + {$endif} + + Display.ClrScr; + Display.DrawString(5,0,'MBED 0.16 demo.'); + Display.DrawString(5,1,'Powered by FPC.'); + Display.DrawString(5,2,'Powered by Lazarus.'); + Display.DrawString(5,3,'By Michael / Alfred.'); + Display.Present; + SystemCore.Delay(3000); + + Display.InvertScr(false); + + // Setup I2C + // Setup pins + // PAD[0] SDA + //GPIO.PinMode[PinSDA] := TPinMode.Output; + //GPIO.PinValue[PinSDA] := 0; + //GPIO.PinDrive[PinSDA] := TPinDrive.PullUp; + + GPIO.PinMux[PinSDA] := TPinMux(PinSDAMux); + + // PAD[1] SCL + GPIO.PinMux[PinSCL] := TPinMux(PinSCLMux); + + // Setup I2C port + I2C1.initMasterWIRE(PortI2C); // speed = 100kHz + + // Setup ADC pin + GPIO.PinMode[POT1]:=TPinMode.Analog; + GPIO.PinMode[POT2]:=TPinMode.Analog; + + // Setup ADC itself + __ADC__.Initialize; + + //Activate MMA7660 + aDataArray[0]:=MMA7660_MODE; + aDataArray[1]:=1; + I2C1.Write(MMA7660_I2C_Address,@aDataArray,2,true); + + TurnedOn:=false; + + GPIO.PinValue[PinLEDRed] := 1; + + while true do + begin + ToggleLed; + + Display.ClrScr; + Display.DrawString(5,0,'MBED 0.16 demo.'); + + //Get temperature from LM75 + aDataArray[0]:=LM75_TEMP_REGISTER; + + I2C1.Write(LM75_I2C_Address,@aDataArray,1,false); + aData:=I2C1.Read(LM75_I2C_Address,@aDataArray,2,true); + aRawData:=10*((aDataArray[0] shl 8)+aDataArray[1]); + + //Process temperature + aFinalResult:='Temp LM75: '; + + aData:=((aRawData DIV 32) DIV 8); + System.Str(aData DIV 10,aResult); + aFinalResult:=aFinalResult+aResult+'.'; + + System.Str(aData MOD 10,aResult); + aFinalResult:=aFinalResult+aResult+'C'; + + Display.DrawString(5,2,aFinalResult); + + + //Get orientation from MMA7660 + aDataArray[0]:=MMA7660_TILT; + + I2C1.Write(MMA7660_I2C_Address,@aDataArray,1,false); + aData:=I2C1.Read(MMA7660_I2C_Address,@aDataArray,1,true); + + aData:=aDataArray[0] AND ($7 shl 2); + aData:=(aData shr 2); + + //Process orientation + aFinalResult:='Pos MMA7660: '; + + if (aData = 0) then + aFinalResult:=aFinalResult+'No data'; + if (aData = 1) then + aFinalResult:=aFinalResult+'Left'; + if (aData = 2) then + aFinalResult:=aFinalResult+'Right'; + if (aData = 5) then + aFinalResult:=aFinalResult+'Down'; + if (aData = 6) then + aFinalResult:=aFinalResult+'Up'; + Display.DrawString(5,1,aFinalResult); + + + // Get voltage reading + aRawData:=__ADC__.GetADCResult[POT1]; + + //Process voltage + aFinalResult:='Voltage POT1:'; + + aRawData:=((aRawData*3300) DIV 65535); + //aRawData now holds result in mV + + System.Str(aRawData DIV 1000,aResult); + aFinalResult:=aFinalResult+aResult+'.'; + + aRawData:=aRawData{%H-}-((aRawData DIV 1000)*1000); + + System.Str(aRawData,aResult); + aFinalResult:=aFinalResult+aResult+'V'; + + Display.DrawString(5,3,aFinalResult); + + Display.Present; + + SystemCore.Delay(Slow); + + end; +end. + diff --git a/Samples/OLED1Xplained/OLED1.lpi b/Samples/OLED1Xplained/OLED1.lpi new file mode 100644 index 0000000..495a97e --- /dev/null +++ b/Samples/OLED1Xplained/OLED1.lpi @@ -0,0 +1,1003 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="11"/> + <General> + <Flags> + <LRSInOutputDirectory Value="False"/> + </Flags> + <MainUnit Value="0"/> + <Title Value="OLED1"/> + <UseAppBundle Value="False"/> + </General> + <BuildModes Count="3" Active="SAMD20"> + <Item1 Name="SAMD21" Default="True"/> + <Item2 Name="SAMC21"> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="bin/$(TargetCPU)-$(TargetOS)/samc21/$NameOnly($(ProjFile))"/> + </Target> + <SearchPaths> + <IncludeFiles Value="../../Source;$(ProjOutDir)"/> + <OtherUnitFiles Value="../../Source"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/samc21"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="arm"/> + <TargetOS Value="embedded"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <DebugInfoType Value="dsDwarf2"/> + <UseLineInfoUnit Value="False"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <CustomOptions Value="-Cparmv6m +-a +-al +-Xs +-Xg +-WpSAMC21XPRO +-dSAMC21XPRO"/> + </Other> + </CompilerOptions> + </Item2> + <Item3 Name="SAMD20"> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="bin/$(TargetCPU)-$(TargetOS)/samd20/$NameOnly($(ProjFile))"/> + </Target> + <SearchPaths> + <IncludeFiles Value="../../Source;$(ProjOutDir)"/> + <OtherUnitFiles Value="../../Source"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/samd20"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="arm"/> + <TargetOS Value="embedded"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <DebugInfoType Value="dsDwarf2"/> + <UseLineInfoUnit Value="False"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <CustomOptions Value="-Cparmv6m +-a +-al +-Xs +-Xg +-WpSAMD20XPRO +-dSAMD20XPRO"/> + </Other> + </CompilerOptions> + </Item3> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="1"> + <Mode0 Name="default"/> + </Modes> + </RunParams> + <Units Count="120"> + <Unit0> + <Filename Value="OLED1.lpr"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <UsageCount Value="200"/> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + </Unit0> + <Unit1> + <Filename Value="../../Source/MBF.Config.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="51"/> + <CursorPos X="4" Y="75"/> + <UsageCount Value="39"/> + </Unit1> + <Unit2> + <Filename Value="../../Source/MBF.Boards.NRF51.inc"/> + <EditorIndex Value="-1"/> + <UsageCount Value="10"/> + </Unit2> + <Unit3> + <Filename Value="../../Source/mbf.boards.atsamcd21.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos X="36" Y="33"/> + <UsageCount Value="6"/> + </Unit3> + <Unit4> + <Filename Value="../../Source/MBF.NRF51.Systemcore.pas"/> + <UnitName Value="mbf.nrf51.systemcore"/> + <EditorIndex Value="-1"/> + <TopLine Value="11"/> + <CursorPos X="4" Y="29"/> + <UsageCount Value="10"/> + </Unit4> + <Unit5> + <Filename Value="../../Source/MBF.SAMD10.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="73"/> + <CursorPos X="30" Y="88"/> + <UsageCount Value="28"/> + </Unit5> + <Unit6> + <Filename Value="../../Source/MBF.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="299"/> + <CursorPos X="24" Y="238"/> + <UsageCount Value="15"/> + </Unit6> + <Unit7> + <Filename Value="../../Source/MBF.LPC8xx.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos X="3" Y="179"/> + <UsageCount Value="10"/> + </Unit7> + <Unit8> + <Filename Value="../../Source/MBF.SAMD10.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="11"/> + <CursorPos Y="28"/> + <UsageCount Value="36"/> + </Unit8> + <Unit9> + <Filename Value="../../Source/MBF.Boards.LPC8xx.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="38"/> + <UsageCount Value="10"/> + </Unit9> + <Unit10> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/sam10d.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="13"/> + <CursorPos X="29" Y="35"/> + <UsageCount Value="29"/> + </Unit10> + <Unit11> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/atmel/samd10/samd10-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="3"/> + <UsageCount Value="10"/> + </Unit11> + <Unit12> + <Filename Value="../../Source/MBF.SAMD10.Helpers.pas"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="-1"/> + <TopLine Value="15"/> + <CursorPos X="11" Y="32"/> + <UsageCount Value="200"/> + </Unit12> + <Unit13> + <Filename Value="../../Source/MBF.PIC32MX.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="216"/> + <CursorPos Y="247"/> + <UsageCount Value="10"/> + </Unit13> + <Unit14> + <Filename Value="../../Source/MBF.Devices.ULN2003.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="48"/> + <CursorPos X="41" Y="66"/> + <UsageCount Value="10"/> + </Unit14> + <Unit15> + <Filename Value="../../Source/MBF.STM32L4.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="254"/> + <CursorPos X="69" Y="266"/> + <UsageCount Value="1"/> + </Unit15> + <Unit16> + <Filename Value="../../Source/MBF.STM32F0.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="239"/> + <CursorPos X="69" Y="251"/> + <UsageCount Value="1"/> + </Unit16> + <Unit17> + <Filename Value="../../Source/MBF.Kinetis.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="134"/> + <CursorPos X="17" Y="138"/> + <UsageCount Value="13"/> + </Unit17> + <Unit18> + <Filename Value="../../Source/MBF.LPC8xx.GPIO.pas"/> + <EditorIndex Value="-1"/> + <CursorPos X="11" Y="131"/> + <UsageCount Value="13"/> + </Unit18> + <Unit19> + <Filename Value="../../Source/MBF.SAMD10.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="64"/> + <CursorPos X="18" Y="23"/> + <UsageCount Value="33"/> + </Unit19> + <Unit20> + <Filename Value="../../Source/MBF.SAMD10.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="261"/> + <CursorPos X="109" Y="38"/> + <UsageCount Value="33"/> + </Unit20> + <Unit21> + <Filename Value="../../Source/samd10/samd10-pm.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="29"/> + <CursorPos X="26" Y="46"/> + <UsageCount Value="2"/> + </Unit21> + <Unit22> + <Filename Value="../../Source/samd10/samd10-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="25" Y="3"/> + <UsageCount Value="10"/> + </Unit22> + <Unit23> + <Filename Value="../../Source/samd10/samd10-adc.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="9"/> + <UsageCount Value="7"/> + </Unit23> + <Unit24> + <Filename Value="../../Source/samd10/samd10-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="60"/> + <CursorPos Y="89"/> + <UsageCount Value="10"/> + </Unit24> + <Unit25> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/atmel/samd10/samd10-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="42"/> + <CursorPos X="31" Y="68"/> + <UsageCount Value="25"/> + </Unit25> + <Unit26> + <Filename Value="../../Source/MBF.STM32F3.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="44"/> + <CursorPos Y="63"/> + <UsageCount Value="23"/> + </Unit26> + <Unit27> + <Filename Value="../../Source/samd10/samd10-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="66"/> + <CursorPos Y="90"/> + <UsageCount Value="10"/> + </Unit27> + <Unit28> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd11c14a.pp"/> + <EditorIndex Value="-1"/> + <UsageCount Value="5"/> + </Unit28> + <Unit29> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd10d14a.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="51"/> + <CursorPos X="5" Y="69"/> + <UsageCount Value="5"/> + </Unit29> + <Unit30> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/lazarus/components/codetools/definetemplates.pas"/> + <UnitName Value="DefineTemplates"/> + <EditorIndex Value="-1"/> + <TopLine Value="7863"/> + <CursorPos X="38" Y="7871"/> + <UsageCount Value="5"/> + </Unit30> + <Unit31> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd10d13a.pp"/> + <EditorIndex Value="-1"/> + <CursorPos X="16"/> + <UsageCount Value="5"/> + </Unit31> + <Unit32> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/compiler/arm/cpuinfo.pas"/> + <UnitName Value="CPUInfo"/> + <EditorIndex Value="-1"/> + <TopLine Value="1057"/> + <CursorPos X="33" Y="1071"/> + <UsageCount Value="5"/> + </Unit32> + <Unit33> + <Filename Value="../../Source/samd10/samd10-nvmctrl.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="30" Y="4"/> + <UsageCount Value="5"/> + </Unit33> + <Unit34> + <Filename Value="../../Source/MBF.STM32F3.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="130"/> + <CursorPos X="69" Y="151"/> + <UsageCount Value="5"/> + </Unit34> + <Unit35> + <Filename Value="../../Source/MBF.Boards.ATSAMD10D.inc"/> + <EditorIndex Value="-1"/> + <CursorPos Y="26"/> + <UsageCount Value="6"/> + </Unit35> + <Unit36> + <Filename Value="../../Source/MBF.Boards.ATSAMCD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="2"/> + <CursorPos X="24" Y="26"/> + <UsageCount Value="6"/> + </Unit36> + <Unit37> + <Filename Value="../../Source/MBF.SAMCD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <CursorPos X="9" Y="18"/> + <UsageCount Value="6"/> + </Unit37> + <Unit38> + <Filename Value="../../Source/MBF.SAMCD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="223"/> + <CursorPos X="30" Y="216"/> + <UsageCount Value="6"/> + </Unit38> + <Unit39> + <Filename Value="../../Source/MBF.SAMCD.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="136"/> + <CursorPos X="47" Y="143"/> + <UsageCount Value="14"/> + </Unit39> + <Unit40> + <Filename Value="../../Source/MBF.SAMCD.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="29"/> + <CursorPos X="39" Y="137"/> + <UsageCount Value="13"/> + </Unit40> + <Unit41> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samc21j18a.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="865"/> + <CursorPos X="3" Y="878"/> + <UsageCount Value="13"/> + </Unit41> + <Unit42> + <Filename Value="../../Source/MBF.Boards.ATSAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="13"/> + <CursorPos X="36" Y="23"/> + <UsageCount Value="21"/> + </Unit42> + <Unit43> + <Filename Value="../../Source/MBF.SAMD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <CursorPos Y="95"/> + <UsageCount Value="19"/> + </Unit43> + <Unit44> + <Filename Value="../../Source/MBF.SAMD.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="95"/> + <CursorPos Y="102"/> + <UsageCount Value="10"/> + </Unit44> + <Unit45> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd21j18a.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="444"/> + <CursorPos X="5" Y="463"/> + <UsageCount Value="10"/> + </Unit45> + <Unit46> + <Filename Value="../../Source/atsamd/samd-pm.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="88"/> + <CursorPos Y="111"/> + <UsageCount Value="5"/> + </Unit46> + <Unit47> + <Filename Value="../../Source/MBF.SAMD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="21"/> + <CursorPos X="37" Y="73"/> + <UsageCount Value="18"/> + </Unit47> + <Unit48> + <Filename Value="../../Source/atsamd/samd-adc.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="20"/> + <UsageCount Value="7"/> + </Unit48> + <Unit49> + <Filename Value="../../Source/MBF.SAMD.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="97"/> + <CursorPos Y="124"/> + <UsageCount Value="41"/> + </Unit49> + <Unit50> + <Filename Value="../../Source/atsamd/samd-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="45"/> + <CursorPos X="3" Y="63"/> + <UsageCount Value="8"/> + </Unit50> + <Unit51> + <Filename Value="../../Source/atsamd/samd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="150"/> + <CursorPos Y="162"/> + <UsageCount Value="28"/> + </Unit51> + <Unit52> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/heapmgr.pp"/> + <EditorIndex Value="-1"/> + <UsageCount Value="5"/> + </Unit52> + <Unit53> + <Filename Value="../../Source/atsamd/samd-nvmctrl.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="21"/> + <CursorPos X="3" Y="38"/> + <UsageCount Value="6"/> + </Unit53> + <Unit54> + <Filename Value="../../Source/MBF.SAMD.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="270"/> + <CursorPos X="44" Y="274"/> + <UsageCount Value="37"/> + </Unit54> + <Unit55> + <Filename Value="../../Source/atsamd/samd-port.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="651"/> + <CursorPos X="3" Y="665"/> + <UsageCount Value="9"/> + </Unit55> + <Unit56> + <Filename Value="../../Source/MBF.SAMC.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="72"/> + <CursorPos X="57" Y="83"/> + <UsageCount Value="6"/> + </Unit56> + <Unit57> + <Filename Value="../../Source/MBF.Boards.ATSAMC.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos Y="51"/> + <UsageCount Value="6"/> + </Unit57> + <Unit58> + <Filename Value="../../Source/MBF.SAMD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="139"/> + <CursorPos X="3" Y="145"/> + <UsageCount Value="22"/> + </Unit58> + <Unit59> + <Filename Value="../../Source/MBF.SAMD.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="112"/> + <CursorPos Y="122"/> + <UsageCount Value="28"/> + </Unit59> + <Unit60> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/inc/systemh.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="97"/> + <CursorPos X="3" Y="111"/> + <UsageCount Value="10"/> + </Unit60> + <Unit61> + <Filename Value="../../Source/MBF.SAMD.SPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="47"/> + <CursorPos X="30" Y="62"/> + <UsageCount Value="14"/> + </Unit61> + <Unit62> + <Filename Value="../../Source/MBF.Displays.OLED1Xplained.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="641"/> + <CursorPos X="49" Y="654"/> + <UsageCount Value="13"/> + </Unit62> + <Unit63> + <Filename Value="../../../Source/MBF.Config.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="51"/> + <CursorPos X="24" Y="72"/> + <UsageCount Value="13"/> + </Unit63> + <Unit64> + <Filename Value="../../../Source/MBF.SAMC.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="8"/> + <CursorPos X="23" Y="119"/> + <UsageCount Value="11"/> + </Unit64> + <Unit65> + <Filename Value="../../../Source/MBF.SAMC.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="266"/> + <CursorPos X="46" Y="286"/> + <UsageCount Value="11"/> + </Unit65> + <Unit66> + <Filename Value="../../../Source/MBF.Boards.ATSAMC.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="27"/> + <CursorPos Y="48"/> + <UsageCount Value="13"/> + </Unit66> + <Unit67> + <Filename Value="../../../Source/MBF.Boards.ATSAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="19"/> + <CursorPos Y="56"/> + <UsageCount Value="10"/> + </Unit67> + <Unit68> + <Filename Value="../../../Source/atsamd/samd-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="5"/> + <UsageCount Value="10"/> + </Unit68> + <Unit69> + <Filename Value="../../../Source/MBF.SAMD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="79"/> + <CursorPos X="23" Y="169"/> + <UsageCount Value="10"/> + </Unit69> + <Unit70> + <Filename Value="../../../Source/MBF.SAMD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="17"/> + <CursorPos X="4" Y="31"/> + <UsageCount Value="9"/> + </Unit70> + <Unit71> + <Filename Value="../../../Source/MBF.SAMC.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="17"/> + <CursorPos X="17" Y="28"/> + <UsageCount Value="10"/> + </Unit71> + <Unit72> + <Filename Value="../../../Source/MBF.SAMC.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="52"/> + <CursorPos X="14" Y="65"/> + <UsageCount Value="9"/> + </Unit72> + <Unit73> + <Filename Value="../../../Source/atsamd/samd-mclk.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="28" Y="15"/> + <UsageCount Value="10"/> + </Unit73> + <Unit74> + <Filename Value="../../../Source/MBF.SAMD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="4"/> + <CursorPos X="18" Y="9"/> + <UsageCount Value="10"/> + </Unit74> + <Unit75> + <Filename Value="../../../Source/atsamd/samd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="45"/> + <CursorPos X="3" Y="59"/> + <UsageCount Value="9"/> + </Unit75> + <Unit76> + <Filename Value="../../../Source/atsamd/samd-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="81"/> + <CursorPos X="22" Y="71"/> + <UsageCount Value="10"/> + </Unit76> + <Unit77> + <Filename Value="../../../Source/MBF.SAMCD.SystemCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="196"/> + <CursorPos X="17" Y="205"/> + <UsageCount Value="16"/> + </Unit77> + <Unit78> + <Filename Value="../../../Source/MBF.SAMCD.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="56"/> + <CursorPos X="12" Y="52"/> + <UsageCount Value="12"/> + </Unit78> + <Unit79> + <Filename Value="../../../Source/MBF.SAMCD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="174"/> + <CursorPos X="31" Y="198"/> + <UsageCount Value="17"/> + </Unit79> + <Unit80> + <Filename Value="../../../Source/MBF.SAMCD.GPIO.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="7"/> + <CursorPos X="12" Y="23"/> + <UsageCount Value="13"/> + </Unit80> + <Unit81> + <Filename Value="../../../Source/MBF.SAMCD.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="81"/> + <CursorPos X="3" Y="240"/> + <UsageCount Value="19"/> + </Unit81> + <Unit82> + <Filename Value="../../../Source/MBF.SAMCD.SPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="46"/> + <CursorPos X="79" Y="61"/> + <UsageCount Value="10"/> + </Unit82> + <Unit83> + <Filename Value="../../../Source/MBF.Displays.C12832.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="10"/> + <CursorPos Y="23"/> + <UsageCount Value="13"/> + </Unit83> + <Unit84> + <Filename Value="../../../Source/MBF.Displays.CustomDisplay.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="41"/> + <CursorPos X="3" Y="133"/> + <UsageCount Value="10"/> + </Unit84> + <Unit85> + <Filename Value="../../../Source/MBF.Displays.CustomSPIDisplay.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="35"/> + <UsageCount Value="10"/> + </Unit85> + <Unit86> + <Filename Value="../../../Source/MBF.SAMCD.ADC.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="152"/> + <CursorPos X="35" Y="76"/> + <UsageCount Value="13"/> + </Unit86> + <Unit87> + <Filename Value="../../../Source/atsamcd/samcd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="74"/> + <CursorPos X="3" Y="91"/> + <UsageCount Value="18"/> + </Unit87> + <Unit88> + <Filename Value="../../../Source/atsamcd/samcd-adc.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="22"/> + <CursorPos X="42" Y="36"/> + <UsageCount Value="10"/> + </Unit88> + <Unit89> + <Filename Value="../../../Source/MBF.SAMCD.Helpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="2"/> + <CursorPos X="9" Y="27"/> + <UsageCount Value="13"/> + </Unit89> + <Unit90> + <Filename Value="../../../../../../../fpclazbydeluxe/trunknewforarm/fpcsrc/packages/fcl-base/examples/xmldump.pp"/> + <EditorIndex Value="-1"/> + <CursorPos X="12" Y="12"/> + <UsageCount Value="13"/> + </Unit90> + <Unit91> + <Filename Value="../../../../../../../fpclazbydeluxe/trunknewforarm/fpcsrc/rtl/solaris/x86_64/start.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="71"/> + <CursorPos X="10" Y="88"/> + <UsageCount Value="13"/> + </Unit91> + <Unit92> + <Filename Value="../../../../../../../fpclazbydeluxe/trunknewforarm/fpcsrc/compiler/systems/t_embed.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="1709"/> + <CursorPos X="19" Y="1725"/> + <UsageCount Value="13"/> + </Unit92> + <Unit93> + <Filename Value="../../../Source/atsamcd/samcd-nvmctrl.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="20" Y="19"/> + <UsageCount Value="11"/> + </Unit93> + <Unit94> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/inc/generic.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="195"/> + <CursorPos X="3" Y="48"/> + <UsageCount Value="10"/> + </Unit94> + <Unit95> + <Filename Value="../../../Source/MBF.Boards.SAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="52"/> + <CursorPos X="17" Y="73"/> + <UsageCount Value="10"/> + </Unit95> + <Unit96> + <Filename Value="../../../Source/MBF.BitHelpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="10"/> + <CursorPos X="5" Y="27"/> + <UsageCount Value="10"/> + </Unit96> + <Unit97> + <Filename Value="../../Source/MBF.Boards.SAMC.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos Y="25"/> + <UsageCount Value="16"/> + </Unit97> + <Unit98> + <Filename Value="../../Source/MBF.Displays.CustomDisplay.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="114"/> + <CursorPos X="14" Y="71"/> + <UsageCount Value="12"/> + </Unit98> + <Unit99> + <Filename Value="../../Source/MBF.BitHelpers.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="176"/> + <CursorPos X="27" Y="186"/> + <UsageCount Value="13"/> + </Unit99> + <Unit100> + <Filename Value="../../Source/atsamcd/samcd-port.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="3" Y="23"/> + <UsageCount Value="10"/> + </Unit100> + <Unit101> + <Filename Value="../../Source/MBF.SAMCD.I2C.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos X="17" Y="23"/> + <UsageCount Value="15"/> + </Unit101> + <Unit102> + <Filename Value="../../Source/atsamcd/samcd-sercom.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="77"/> + <CursorPos X="3" Y="90"/> + <UsageCount Value="12"/> + </Unit102> + <Unit103> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/compiler/msgtxt.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="954"/> + <CursorPos X="9" Y="967"/> + <UsageCount Value="10"/> + </Unit103> + <Unit104> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/compiler/msgidx.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="779"/> + <CursorPos X="34" Y="792"/> + <UsageCount Value="10"/> + </Unit104> + <Unit105> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/compiler/arm/raarmgas.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="527"/> + <CursorPos X="27" Y="549"/> + <UsageCount Value="10"/> + </Unit105> + <Unit106> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/compiler/raatt.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="36"/> + <CursorPos X="39" Y="49"/> + <UsageCount Value="10"/> + </Unit106> + <Unit107> + <Filename Value="../../Source/MBF.SAMCD.SerCom.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="198"/> + <CursorPos X="18" Y="215"/> + <UsageCount Value="13"/> + </Unit107> + <Unit108> + <Filename Value="../../Source/atsamcd/samcd-mclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="28"/> + <CursorPos X="25" Y="43"/> + <UsageCount Value="13"/> + </Unit108> + <Unit109> + <Filename Value="../../Source/MBF.Kinetis.SPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="179"/> + <CursorPos X="3" Y="198"/> + <UsageCount Value="12"/> + </Unit109> + <Unit110> + <Filename Value="../../Source/MBF.Kinetis.UART.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="225"/> + <CursorPos X="18" Y="224"/> + <UsageCount Value="12"/> + </Unit110> + <Unit111> + <Filename Value="../../Source/MBF.LPC8xx.SPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="425"/> + <CursorPos X="18" Y="409"/> + <UsageCount Value="12"/> + </Unit111> + <Unit112> + <Filename Value="../../Source/atsamcd/samcd-adc.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="43"/> + <CursorPos X="9" Y="56"/> + <UsageCount Value="12"/> + </Unit112> + <Unit113> + <Filename Value="../../Source/MBF.Boards.SAMD.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="16"/> + <CursorPos X="21" Y="36"/> + <UsageCount Value="10"/> + </Unit113> + <Unit114> + <Filename Value="../../Source/MBF.Displays.CustomDisplaySPI.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="59"/> + <CursorPos X="3" Y="61"/> + <UsageCount Value="10"/> + </Unit114> + <Unit115> + <Filename Value="../../Source/MBF.Displays.C12832.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="417"/> + <CursorPos X="22" Y="431"/> + <UsageCount Value="11"/> + </Unit115> + <Unit116> + <Filename Value="../MBEDAppShield/MBED.lpr"/> + <EditorIndex Value="-1"/> + <TopLine Value="232"/> + <CursorPos Y="254"/> + <UsageCount Value="10"/> + </Unit116> + <Unit117> + <Filename Value="../../Source/atsamcd/samcd-gclk.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="108"/> + <CursorPos X="25" Y="121"/> + <UsageCount Value="10"/> + </Unit117> + <Unit118> + <Filename Value="../../Source/atsamcd/samcd-pm.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="33"/> + <CursorPos X="17" Y="65"/> + <UsageCount Value="10"/> + </Unit118> + <Unit119> + <Filename Value="../../../../../../../fpclazbydeluxe/trunk/fpcsrc/rtl/embedded/arm/samd20j18.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="325"/> + <CursorPos X="3" Y="338"/> + <UsageCount Value="10"/> + </Unit119> + </Units> + <JumpHistory Count="6" HistoryIndex="5"> + <Position1> + <Filename Value="OLED1.lpr"/> + <Caret Line="124" Column="15" TopLine="107"/> + </Position1> + <Position2> + <Filename Value="OLED1.lpr"/> + <Caret Line="126" Column="15" TopLine="107"/> + </Position2> + <Position3> + <Filename Value="OLED1.lpr"/> + <Caret Line="130" Column="22" TopLine="111"/> + </Position3> + <Position4> + <Filename Value="OLED1.lpr"/> + <Caret Line="122" Column="14" TopLine="98"/> + </Position4> + <Position5> + <Filename Value="OLED1.lpr"/> + <Caret Line="67" Column="25" TopLine="51"/> + </Position5> + <Position6> + <Filename Value="OLED1.lpr"/> + <Caret Line="18" Column="18" TopLine="4"/> + </Position6> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="bin/$(TargetCPU)-$(TargetOS)/samd21/$NameOnly($(ProjFile))"/> + </Target> + <SearchPaths> + <IncludeFiles Value="../../Source;$(ProjOutDir)"/> + <OtherUnitFiles Value="../../Source"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)/samd21"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <TargetCPU Value="arm"/> + <TargetOS Value="embedded"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <DebugInfoType Value="dsDwarf2"/> + <UseLineInfoUnit Value="False"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <CustomOptions Value="-Cparmv6m +-a +-al +-Xs +-Xg +-WpSAMD21XPRO +-dSAMD21XPRO"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/Samples/OLED1Xplained/OLED1.lpr b/Samples/OLED1Xplained/OLED1.lpr new file mode 100644 index 0000000..b3ca46d --- /dev/null +++ b/Samples/OLED1Xplained/OLED1.lpr @@ -0,0 +1,152 @@ +program OLED1; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} + +{< MBED application shield demo program. } + +{$INCLUDE MBF.Config.inc} + +{.$define DEBUG} + +uses + heapmgr, // this is needed for SAMD10, but keep it in place for the others also !!!! + MBF.BitHelpers, + MBF.__CONTROLLERTYPE__.SystemCore, + MBF.__CONTROLLERTYPE__.GPIO, + MBF.__CONTROLLERTYPE__.SPI, + MBF.Displays.OLED1Xplained; + +const + {$if defined(has_samd20_xplained_pro) or defined(has_samd21_xplained_pro) or defined(has_samc21_xplained_pro)} + PinLED = LED0; + PinButton = SW0; + + PortSPI = 5; + PortSPIMux = Ord(TPinMux.MuxD); + PinMOSIMux = PortSPIMux; + PinMISOMux = Ord(TPinMux.None); + PinSCKMux = PortSPIMux; + + PinReset = EXT3_PIN_10; + PinMISO = TNativePin.None; + PinSS = EXT3_PIN_15; + PinMOSI = EXT3_PIN_16;//PAD[2] + PinSCK = EXT3_PIN_18;//PAD[3] + PinA0 = EXT3_PIN_5; + {$endif} + +var + Display:TDisplay; + SPI1:TSPI_Registers; + TurnedOn:boolean; + i:byte; + +procedure ToggleLed; +begin + TurnedOn:=NOT TurnedOn; + if TurnedOn then + GPIO.PinValue[PinLED] := 1 + else + GPIO.PinValue[PinLED] := 0; +end; + +begin + SystemCore.Initialize; + + GPIO.Initialize; + + // Switch on LED pin for output. + GPIO.PinMode[PinLED] := TPinMode.Output; + GPIO.PinValue[PinLED] := 0; + + SPI1.Initialize(PortSPI,100000,0,1); + + GPIO.PinMode[PinSS] := TPinMode.Output; + GPIO.PinValue[PinSS] := 1; + GPIO.PinMode[PinReset] := TPinMode.Output; + GPIO.PinValue[PinReset] := 1; + GPIO.PinMode[PinA0] := TPinMode.Output; + GPIO.PinValue[PinA0] := 1; + + GPIO.PinMux[PinMOSI] := TPinMux(PinMOSIMux); + GPIO.PinMux[PinSCK] := TPinMux(PinSCKMux); + if (PinMISO<>TNativePin.None) then {%H-}GPIO.PinMux[PinMISO] := TPinMux(PinMISOMux); + + Display.Initialize(SPI1,PinA0,PinReset,ScreenSize128x32x1); + Display.PinCS:=PinSS; + + Display.InitSequence; + + // not enough flash ... :-( + {$ifndef samd10} + Display.GetDemo1; + ToggleLed; + SystemCore.Delay(2500); + + Display.InvertScr(true); + Display.GetDemo2; + ToggleLed; + SystemCore.Delay(2500); + {$endif} + + Display.ClrScr; + Display.DrawString(5,0,'MBED 0.16 demo.'); + Display.DrawString(5,1,'Powered by FPC.'); + Display.DrawString(5,2,'Powered by Lazarus.'); + Display.DrawString(5,3,'By Michael / Alfred.'); + Display.Present; + SystemCore.Delay(3000); + + TurnedOn:=false; + + GPIO.PinValue[PinLED] := 1; + + Display.InvertScr(false); + Display.ClrScr; + Display.Present; + for i:=0 to (ScreenSize128x32x1.Width-1) do + begin + Display.Pixel[i,0]:=1; + Display.Present; + end; + for i:=0 to (ScreenSize128x32x1.Height-1) do + begin + Display.Pixel[(ScreenSize128x32x1.Width-1),i]:=1; + Display.Present; + end; + for i:=ScreenSize128x32x1.Width-1 downto 0 do + begin + Display.Pixel[i,(ScreenSize128x32x1.Height-1)]:=1; + Display.Present; + end; + for i:=ScreenSize128x32x1.Height-1 downto 0 do + begin + Display.Pixel[0,i]:=1; + Display.Present; + end; + + while true do + begin + ToggleLed; + Inc(i); + + Display.DrawString(5,(((i+1) mod 2)+1),' '); + Display.DrawString(5,((i mod 2)+1),'Hello Michael !'); + Display.Present; + + SystemCore.Delay(500); + + end; +end. + diff --git a/Samples/SSD1306Demo/SSD1306Demo.lpr b/Samples/SSD1306Demo/SSD1306Demo.lpr index 4adddee..d3ef417 100644 --- a/Samples/SSD1306Demo/SSD1306Demo.lpr +++ b/Samples/SSD1306Demo/SSD1306Demo.lpr @@ -22,7 +22,7 @@ MBF.__CONTROLLERTYPE__.GPIO, MBF.__CONTROLLERTYPE__.SPI, MBF.Displays.SSD1306, - MBF.Displays.CustomDisplay, + MBF.Displays.CustomDisplayGPIO, MBF.Fonts.Hack12x16; var diff --git a/Source/MBF.BitHelpers.pas b/Source/MBF.BitHelpers.pas index 7fd861a..0f30aa2 100644 --- a/Source/MBF.BitHelpers.pas +++ b/Source/MBF.BitHelpers.pas @@ -36,7 +36,6 @@ procedure ClearBit(var Value: longword; const Index: Byte); lsl r3, r1 bic r2, r3 str r2, [r0] - //bx lr end; {$else} begin @@ -188,12 +187,13 @@ procedure PutValue(var Value: longword; const Mask:longword; const Data:longword {$ifdef useassembler} assembler;nostackframe; asm - ldr r4,[r0] - bic r4,r1 - lsl r2,r3 - orr r4,r2 - str r4,[r0] + lsl r2, r3 + ldr r3, [r0] + bic r3, r1 + orr r3, r2 + str r3, [r0] end; + {$else} begin Value:=Value AND (NOT Mask); @@ -205,11 +205,11 @@ procedure PutValue(var Value: word; const Mask:word; const Data:word; const Posi {$ifdef useassembler} assembler;nostackframe; asm - ldrh r4,[r0] - bic r4,r1 - lsl r2,r3 - orr r4,r2 - strh r4,[r0] + lsl r2, r3 + ldrh r3, [r0] + bic r3, r1 + orr r3, r2 + strh r3, [r0] end; {$else} begin @@ -222,11 +222,11 @@ procedure PutValue(var Value: byte; const Mask:byte; const Data:byte; const Posi {$ifdef useassembler} assembler;nostackframe; asm - ldrb r4,[r0] - bic r4,r1 - lsl r2,r3 - orr r4,r2 - strb r4,[r0] + lsl r2, r3 + ldrb r3, [r0] + bic r3, r1 + orr r3, r2 + strb r3, [r0] end; {$else} begin @@ -239,10 +239,10 @@ procedure PutValue(var Value: longword; const Mask:longword; const Data:longword {$ifdef useassembler} assembler;nostackframe; asm - ldr r3,[r0] - bic r3,r1 - orr r3,r2 - str r3,[r0] + ldr r3, [r0] + bic r3, r1 + orr r3, r2 + str r3, [r0] end; {$else} begin diff --git a/Source/MBF.Boards.SAMD.inc b/Source/MBF.Boards.SAMD.inc index fd7238a..82aa453 100644 --- a/Source/MBF.Boards.SAMD.inc +++ b/Source/MBF.Boards.SAMD.inc @@ -27,17 +27,18 @@ {$if defined(SAMD10XMINI)} {$define has_arduinopins} {$define has_samd10_xplained_mini} - {$define SAMD10D14} + {$define SAMD10D14A} {$endif} {$if defined(SAMD20XPRO)} {$define has_arduinopins} + {$define has_samd20_xplained_pro} {$define SAMD20J18} {$endif} {$if defined(SAMD21XPRO)} {$define has_arduinopins} - + {$define has_samd21_xplained_pro} {$define SAMD21J18A} {$endif} diff --git a/Source/MBF.Displays.C12832.pas b/Source/MBF.Displays.C12832.pas new file mode 100644 index 0000000..e5663dd --- /dev/null +++ b/Source/MBF.Displays.C12832.pas @@ -0,0 +1,656 @@ +unit MBF.Displays.C12832; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +interface + +{$INCLUDE MBF.Config.inc} + +uses + MBF.Types, + MBF.Displays.CustomDisplay, + MBF.Displays.CustomDisplaySPI, + MBF.__CONTROLLERTYPE__.GPIO; + +const + ScreenBufferInit1: packed array [0..511] of byte = ( + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $3, $7, $F, $1F, $1F, $3F, $3F, $3F, $3F, $7, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $7F, $3F, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $1F, $3F, $70, $70, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $6, $6, $0, $0, $0, $3, $3, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $F, $7, $7, + $7, $3F, $FF, $FF, $FF, $FF, $FF, $FE, $FF, $FF, $FF, $FF, $FF, $3E, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $F, $3F, + $70, $60, $60, $60, $60, $30, $7F, $3F, $0, $0, $1F, $3F, $70, $60, $60, $60, + $60, $39, $FF, $FF, $0, $6, $1F, $39, $60, $60, $60, $60, $30, $3F, $7F, $0, + $0, $60, $FF, $FF, $60, $60, $0, $7F, $7F, $70, $60, $60, $40, $0, $7F, $7F, + $0, $0, $0, $0, $7F, $7F, $0, $0, $0, $7F, $7F, $0, $0, $60, $FF, $FF, + $60, $60, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $80, $F8, $FC, $FE, $FE, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $EF, $E7, $E7, $E3, + $F3, $F9, $FF, $FF, $FF, $F7, $7, $1F, $FF, $FF, $FF, $FF, $FF, $FF, $7F, $FF, + $7F, $7F, $7F, $7F, $7F, $7F, $3F, $3F, $1F, $F, $7, $3, $0, $0, $0, $C0, + $E0, $60, $20, $20, $60, $E0, $E0, $E0, $0, $0, $80, $C0, $E0, $60, $20, $60, + $60, $E0, $E0, $E0, $0, $0, $80, $C0, $60, $60, $20, $60, $60, $E0, $E0, $0, + $0, $0, $E0, $E0, $0, $0, $0, $E0, $E0, $0, $0, $0, $0, $0, $80, $E0, + $60, $60, $60, $60, $E0, $80, $0, $0, $0, $E0, $E0, $0, $0, $0, $E0, $E0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0); {section '.progmem';} + + ScreenBufferInit2: array [0..511] of byte = ( + $0, $0, $0, $3, $7, $1F, $9F, $FF, $FF, $FF, $FF, $FF, $FF, $FD, $F1, $E3, + $E3, $CF, $FF, $FF, $FF, $FF, $F0, $FC, $7F, $3F, $3F, $3F, $3F, $7F, $FF, $FF, + $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE, $FC, $F0, $E0, $80, $0, $0, $0, $C, + $1C, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $7F, $7F, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $7, $7, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $1C, $C, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $0, $7, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE, $FE, $FE, $FE, $FC, $F8, + $F8, $F0, $FE, $FF, $FF, $FF, $7F, $3F, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $1F, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $FF, + $FF, $0, $0, $0, $FF, $FF, $E0, $C0, $C0, $C0, $FF, $7F, $0, $0, $1E, $7F, + $E1, $C0, $C0, $C0, $C0, $61, $FF, $FF, $0, $0, $FE, $FF, $1, $0, $0, $0, + $FF, $FF, $0, $0, $21, $F9, $F8, $DC, $CC, $CF, $7, $0, $C0, $FF, $FF, $C0, + $80, $0, $FF, $FF, $C0, $C0, $80, $0, $0, $FF, $FF, $0, $0, $1F, $7F, $F9, + $C8, $C8, $C8, $C8, $79, $39, $0, $0, $71, $F9, $D8, $CC, $CE, $47, $3, $0, + + $0, $0, $0, $0, $80, $80, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $80, $C0, $E0, $F0, $F8, $F8, $FC, $FC, $FC, $FC, $F8, $F0, $C0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $C0, + $C0, $0, $0, $0, $C0, $C0, $0, $0, $0, $0, $C0, $C0, $0, $0, $0, $80, + $C0, $C0, $C0, $C0, $C0, $80, $C0, $C0, $0, $0, $0, $80, $C0, $C0, $C0, $C0, + $C0, $80, $0, $0, $80, $C0, $C0, $C0, $C0, $C0, $0, $0, $0, $C0, $C0, $0, + $0, $0, $C0, $80, $0, $0, $0, $0, $0, $C0, $C0, $0, $0, $0, $80, $C0, + $C0, $C0, $C0, $C0, $80, $80, $0, $0, $80, $C0, $C0, $C0, $C0, $80, $0, $0, + + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0); {section '.progmem';} + + font: array [0..1274] of byte = ( + $0, $0, $0, $0, $0, // Ascii 0 + $7C, $DA, $F2, $DA, $7C, //ASC(01) + $7C, $D6, $F2, $D6, $7C, //ASC(02) + $38, $7C, $3E, $7C, $38, + $18, $3C, $7E, $3C, $18, + $38, $EA, $BE, $EA, $38, + $38, $7A, $FE, $7A, $38, + $0, $18, $3C, $18, $0, + $FF, $E7, $C3, $E7, $FF, + $0, $18, $24, $18, $0, + $FF, $E7, $DB, $E7, $FF, + $C, $12, $5C, $60, $70, + $64, $94, $9E, $94, $64, + $2, $FE, $A0, $A0, $E0, + $2, $FE, $A0, $A4, $FC, + $5A, $3C, $E7, $3C, $5A, + $FE, $7C, $38, $38, $10, + $10, $38, $38, $7C, $FE, + $28, $44, $FE, $44, $28, + $FA, $FA, $0, $FA, $FA, + $60, $90, $FE, $80, $FE, + $0, $66, $91, $A9, $56, + $6, $6, $6, $6, $6, + $29, $45, $FF, $45, $29, + $10, $20, $7E, $20, $10, + $8, $4, $7E, $4, $8, + $10, $10, $54, $38, $10, + $10, $38, $54, $10, $10, + $78, $8, $8, $8, $8, + $30, $78, $30, $78, $30, + $C, $1C, $7C, $1C, $C, + $60, $70, $7C, $70, $60, + $0, $0, $0, $0, $0, + $0, $0, $FA, $0, $0, + $0, $E0, $0, $E0, $0, + $28, $FE, $28, $FE, $28, + $24, $54, $FE, $54, $48, + $C4, $C8, $10, $26, $46, + $6C, $92, $6A, $4, $A, + $0, $10, $E0, $C0, $0, + $0, $38, $44, $82, $0, + $0, $82, $44, $38, $0, + $54, $38, $FE, $38, $54, + $10, $10, $7C, $10, $10, + $0, $1, $E, $C, $0, + $10, $10, $10, $10, $10, + $0, $0, $6, $6, $0, + $4, $8, $10, $20, $40, + $7C, $8A, $92, $A2, $7C, + $0, $42, $FE, $2, $0, + $4E, $92, $92, $92, $62, + $84, $82, $92, $B2, $CC, + $18, $28, $48, $FE, $8, + $E4, $A2, $A2, $A2, $9C, + $3C, $52, $92, $92, $8C, + $82, $84, $88, $90, $E0, + $6C, $92, $92, $92, $6C, + $62, $92, $92, $94, $78, + $0, $0, $28, $0, $0, + $0, $2, $2C, $0, $0, + $0, $10, $28, $44, $82, + $28, $28, $28, $28, $28, + $0, $82, $44, $28, $10, + $40, $80, $9A, $90, $60, + $7C, $82, $BA, $9A, $72, + $3E, $48, $88, $48, $3E, + $FE, $92, $92, $92, $6C, + $7C, $82, $82, $82, $44, + $FE, $82, $82, $82, $7C, + $FE, $92, $92, $92, $82, + $FE, $90, $90, $90, $80, + $7C, $82, $82, $8A, $CE, + $FE, $10, $10, $10, $FE, + $0, $82, $FE, $82, $0, + $4, $2, $82, $FC, $80, + $FE, $10, $28, $44, $82, + $FE, $2, $2, $2, $2, + $FE, $40, $38, $40, $FE, + $FE, $20, $10, $8, $FE, + $7C, $82, $82, $82, $7C, + $FE, $90, $90, $90, $60, + $7C, $82, $8A, $84, $7A, + $FE, $90, $98, $94, $62, + $64, $92, $92, $92, $4C, + $C0, $80, $FE, $80, $C0, + $FC, $2, $2, $2, $FC, + $F8, $4, $2, $4, $F8, + $FC, $2, $1C, $2, $FC, + $C6, $28, $10, $28, $C6, + $C0, $20, $1E, $20, $C0, + $86, $9A, $92, $B2, $C2, + $0, $FE, $82, $82, $82, + $40, $20, $10, $8, $4, + $0, $82, $82, $82, $FE, + $20, $40, $80, $40, $20, + $2, $2, $2, $2, $2, + $0, $C0, $E0, $10, $0, + $4, $2A, $2A, $1E, $2, + $FE, $14, $22, $22, $1C, + $1C, $22, $22, $22, $14, + $1C, $22, $22, $14, $FE, + $1C, $2A, $2A, $2A, $18, + $0, $10, $7E, $90, $40, + $18, $25, $25, $39, $1E, + $FE, $10, $20, $20, $1E, + $0, $22, $BE, $2, $0, + $4, $2, $2, $BC, $0, + $FE, $8, $14, $22, $0, + $0, $82, $FE, $2, $0, + $3E, $20, $1E, $20, $1E, + $3E, $10, $20, $20, $1E, + $1C, $22, $22, $22, $1C, + $3F, $18, $24, $24, $18, + $18, $24, $24, $18, $3F, + $3E, $10, $20, $20, $10, + $12, $2A, $2A, $2A, $24, + $20, $20, $FC, $22, $24, + $3C, $2, $2, $4, $3E, + $38, $4, $2, $4, $38, + $3C, $2, $C, $2, $3C, + $22, $14, $8, $14, $22, + $32, $9, $9, $9, $3E, + $22, $26, $2A, $32, $22, + $0, $10, $6C, $82, $0, + $0, $0, $EE, $0, $0, + $0, $82, $6C, $10, $0, + $40, $80, $40, $20, $40, + $3C, $64, $C4, $64, $3C, + $78, $85, $85, $86, $48, + $5C, $2, $2, $4, $5E, + $1C, $2A, $2A, $AA, $9A, + $84, $AA, $AA, $9E, $82, + $84, $2A, $2A, $1E, $82, + $84, $AA, $2A, $1E, $2, + $4, $2A, $AA, $9E, $2, + $30, $78, $4A, $4E, $48, + $9C, $AA, $AA, $AA, $9A, + $9C, $2A, $2A, $2A, $9A, + $9C, $AA, $2A, $2A, $1A, + $0, $0, $A2, $3E, $82, + $0, $40, $A2, $BE, $42, + $0, $80, $A2, $3E, $2, + $F, $94, $24, $94, $F, + $F, $14, $A4, $14, $F, + $3E, $2A, $AA, $A2, $0, + $4, $2A, $2A, $3E, $2A, + $3E, $50, $90, $FE, $92, + $4C, $92, $92, $92, $4C, + $4C, $12, $12, $12, $4C, + $4C, $52, $12, $12, $C, + $5C, $82, $82, $84, $5E, + $5C, $42, $2, $4, $1E, + $0, $B9, $5, $5, $BE, + $9C, $22, $22, $22, $9C, + $BC, $2, $2, $2, $BC, + $3C, $24, $FF, $24, $24, + $12, $7E, $92, $C2, $66, + $D4, $F4, $3F, $F4, $D4, + $FF, $90, $94, $6F, $4, + $3, $11, $7E, $90, $C0, + $4, $2A, $2A, $9E, $82, + $0, $0, $22, $BE, $82, + $C, $12, $12, $52, $4C, + $1C, $2, $2, $44, $5E, + $0, $5E, $50, $50, $4E, + $BE, $B0, $98, $8C, $BE, + $64, $94, $94, $F4, $14, + $64, $94, $94, $94, $64, + $C, $12, $B2, $2, $4, + $1C, $10, $10, $10, $10, + $10, $10, $10, $10, $1C, + $F4, $8, $13, $35, $5D, + $F4, $8, $14, $2C, $5F, + $0, $0, $DE, $0, $0, + $10, $28, $54, $28, $44, + $44, $28, $54, $28, $10, + $55, $0, $AA, $0, $55, + $55, $AA, $55, $AA, $55, + $AA, $55, $AA, $55, $AA, + $0, $0, $0, $FF, $0, + $8, $8, $8, $FF, $0, + $28, $28, $28, $FF, $0, + $8, $8, $FF, $0, $FF, + $8, $8, $F, $8, $F, + $28, $28, $28, $3F, $0, + $28, $28, $EF, $0, $FF, + $0, $0, $FF, $0, $FF, + $28, $28, $2F, $20, $3F, + $28, $28, $E8, $8, $F8, + $8, $8, $F8, $8, $F8, + $28, $28, $28, $F8, $0, + $8, $8, $8, $F, $0, + $0, $0, $0, $F8, $8, + $8, $8, $8, $F8, $8, + $8, $8, $8, $F, $8, + $0, $0, $0, $FF, $8, + $8, $8, $8, $8, $8, + $8, $8, $8, $FF, $8, + $0, $0, $0, $FF, $28, + $0, $0, $FF, $0, $FF, + $0, $0, $F8, $8, $E8, + $0, $0, $3F, $20, $2F, + $28, $28, $E8, $8, $E8, + $28, $28, $2F, $20, $2F, + $0, $0, $FF, $0, $EF, + $28, $28, $28, $28, $28, + $28, $28, $EF, $0, $EF, + $28, $28, $28, $E8, $28, + $8, $8, $F8, $8, $F8, + $28, $28, $28, $2F, $28, + $8, $8, $F, $8, $F, + $0, $0, $F8, $8, $F8, + $0, $0, $0, $F8, $28, + $0, $0, $0, $3F, $28, + $0, $0, $F, $8, $F, + $8, $8, $FF, $8, $FF, + $28, $28, $28, $FF, $28, + $8, $8, $8, $F8, $0, + $0, $0, $0, $F, $8, + $FF, $FF, $FF, $FF, $FF, + $F, $F, $F, $F, $F, + $FF, $FF, $FF, $0, $0, + $0, $0, $0, $FF, $FF, + $F0, $F0, $F0, $F0, $F0, + $1C, $22, $22, $1C, $22, + $3E, $54, $54, $7C, $28, + $7E, $40, $40, $60, $60, + $40, $7E, $40, $7E, $40, + $C6, $AA, $92, $82, $C6, + $1C, $22, $22, $3C, $20, + $2, $7E, $4, $78, $4, + $60, $40, $7E, $40, $40, + $99, $A5, $E7, $A5, $99, + $38, $54, $92, $54, $38, + $32, $4E, $80, $4E, $32, + $C, $52, $B2, $B2, $C, + $C, $12, $1E, $12, $C, + $3D, $46, $5A, $62, $BC, + $7C, $92, $92, $92, $0, + $7E, $80, $80, $80, $7E, + $54, $54, $54, $54, $54, + $22, $22, $FA, $22, $22, + $2, $8A, $52, $22, $2, + $2, $22, $52, $8A, $2, + $0, $0, $FF, $80, $C0, + $7, $1, $FF, $0, $0, + $10, $10, $D6, $D6, $10, + $6C, $48, $6C, $24, $6C, + $60, $F0, $90, $F0, $60, + $0, $0, $18, $18, $0, + $0, $0, $8, $8, $0, + $C, $2, $FF, $80, $80, + $0, $F8, $80, $80, $78, + $0, $98, $B8, $E8, $48, + $0, $3C, $3C, $3C, $3C); { section '.progmem';} + + ScreenSize128x32x1: TScreenInfo = + (Width: 128; Height: 32; Depth: TDisplayBitDepth.OneBit); + ScreenSize128x64x1: TScreenInfo = + (Width: 128; Height: 64; Depth: TDisplayBitDepth.OneBit); + ScreenSize96x16x1: TScreenInfo = + (Width: 96; Height: 16; Depth: TDisplayBitDepth.OneBit); + ScreenSize64x48x1: TScreenInfo = + (Width: 64; Height: 48; Depth: TDisplayBitDepth.OneBit); + +type + TBWColor=0..1; + + TDisplay = object(TCustomSPIDisplay) + private const + LCD128x64: TPoint2px = (X: 128; Y: 64); + LCD128x32: TPoint2px = (X: 128; Y: 32); + LCD96x16: TPoint2px = (X: 96; Y: 16); + LCD64x48: TPoint2px = (X: 64; Y: 48); + pagemap :array[0..7] of byte = ( 3, 2, 1, 0, 7, 6, 5, 4); + + private var + FScreenSize: TPoint2px; + FScreenBufferSize: longword; + FScreenBuffer: Pointer; + FScreenBuffer2: packed array [0..511] of byte; + protected + function ReadPixel(const X, Y: word): TBWColor; + procedure WritePixel(const X, Y: word; const Color: TBWColor); + function GetScanline(const Index: word): Pointer; + procedure PresentBuffer; + procedure EngageCS; + procedure ReleaseCS; + public + function InitSequence:boolean; + procedure ClrScr; + procedure InvertScr(Orientation:boolean); + procedure Present; + procedure SetBrightness(aVal:byte); + procedure DrawCharacter(const X, Line: word; const aChar: byte); + procedure DrawString(const X, Line: word; const aString: string); + procedure GetDemo1; + procedure GetDemo2; + property ScreenSize: TPoint2px read FScreenSize; + property Scanline[const Index: word]: Pointer read GetScanline; + property Pixel[const X,Y: word]: TBWColor read ReadPixel write WritePixel; + end; + +implementation + +const + CMD_DISPLAY_OFF = $AE; + CMD_DISPLAY_ON = $AF; + + CMD_SET_DISP_START_LINE = $40; + CMD_SET_PAGE = $B0; + + CMD_SET_COLUMN_UPPER = $10; + CMD_SET_COLUMN_LOWER = $00; + + CMD_SET_ADC_NORMAL = $A0; + CMD_SET_ADC_REVERSE = $A1; + + CMD_SET_DISP_NORMAL = $A6; + CMD_SET_DISP_REVERSE = $A7; + + CMD_SET_ALLPTS_NORMAL = $A4; + CMD_SET_ALLPTS_ON = $A5; + CMD_SET_BIAS_9 = $A2; + CMD_SET_BIAS_7 = $A3; + + CMD_RMW = $E0; + CMD_RMW_CLEAR = $EE; + CMD_INTERNAL_RESET = $E2; + CMD_SET_COM_NORMAL = $C0; + CMD_SET_COM_REVERSE = $C8; + CMD_SET_POWER_CONTROL = $28; + CMD_SET_RESISTOR_RATIO = $20; + CMD_SET_VOLUME_FIRST = $81; + CMD_SET_VOLUME_SECOND = 0; + CMD_SET_STATIC_OFF = $AC; + CMD_SET_STATIC_ON = $AD; + CMD_SET_STATIC_REG = $0; + CMD_SET_BOOSTER_FIRST = $F8; + CMD_SET_BOOSTER_234 = 0; + CMD_SET_BOOSTER_5 = 1; + CMD_SET_BOOSTER_6 = 3; + CMD_NOP = $E3; + CMD_TEST = $F0; + + //ST7565_STARTBYTES = 1; + ST7565_STARTBYTES = 0; + +function TDisplay.InitSequence:boolean; +begin + result:=false; + Reset; + + FScreenSize.X := ScreenInfo.Width; + FScreenSize.Y := ScreenInfo.Height; + + FScreenBufferSize := (FScreenSize.X * FScreenSize.Y); + + case ScreenInfo.Depth of + TDisplayBitDepth.OneBit: FScreenBufferSize:=(FScreenBufferSize DIV 8); + TDisplayBitDepth.TwoBits: FScreenBufferSize:=(FScreenBufferSize DIV 4); + TDisplayBitDepth.FourBits: FScreenBufferSize:=(FScreenBufferSize DIV 2); + TDisplayBitDepth.SixteenBits: FScreenBufferSize:=(FScreenBufferSize * 2); + end; + + { + if (FScreenBufferSize=0) OR (FScreenBufferSize>Length(FScreenBuffer2)) then + begin + // Houston, we have a problem !! + exit; + end; + } + + //Does not work !! + //FScreenBuffer := GetMem(FScreenBufferSize); + FScreenBuffer := @FScreenBuffer2; + + EngageCS; + + WriteCommand(CMD_DISPLAY_OFF); + WriteCommand(CMD_SET_BIAS_9); + WriteCommand(CMD_SET_ADC_NORMAL); + WriteCommand(CMD_SET_COM_NORMAL); + WriteCommand(CMD_SET_RESISTOR_RATIO+2); + // turn on voltage converter (VC=1, VR=0, VF=0) + //WriteCommand(CMD_SET_POWER_CONTROL OR $4); + // turn on voltage regulator (VC=1, VR=1, VF=0) + //WriteCommand(CMD_SET_POWER_CONTROL OR $6); + // turn on voltage follower (VC=1, VR=1, VF=1) + WriteCommand(CMD_SET_POWER_CONTROL+7); + WriteCommand(CMD_SET_DISP_START_LINE+0); + WriteCommand(CMD_DISPLAY_ON); + WriteCommand(CMD_SET_ALLPTS_NORMAL); + WriteCommand(CMD_SET_DISP_NORMAL); + + ReleaseCS; + + SetBrightness($17); + + result:=true; +end; + +procedure TDisplay.SetBrightness(aVal:byte); +begin + EngageCS; + WriteCommand(CMD_SET_VOLUME_FIRST); + WriteCommand(CMD_SET_VOLUME_SECOND OR (aVal AND $3f)); + ReleaseCS; +end; + +procedure TDisplay.PresentBuffer; +var + p,col,maxcol:byte; +begin + EngageCS; + + for p:=0 to 3 do + begin + col:=0; + maxcol:=(FScreenSize.X-1); + + WriteCommand(CMD_SET_PAGE OR pagemap[p]); + WriteCommand(CMD_SET_COLUMN_LOWER OR ((col+ST7565_STARTBYTES) AND $0F)); + WriteCommand(CMD_SET_COLUMN_UPPER OR (((col+ST7565_STARTBYTES) shr 4) AND $0F)); + WriteCommand(CMD_RMW); + //WriteData(@FScreenBuffer2[(FScreenSize.X*p)],FScreenSize.X); + WriteData(FScreenBuffer+(FScreenSize.X*p+col),FScreenSize.X); + { + while (col<=maxcol) do + begin + WriteData(FScreenBuffer2[(FScreenSize.X*p)+col]); + Inc(col); + end; + } + WriteCommand(CMD_RMW_CLEAR); + end; + + ReleaseCS; +end; + +procedure TDisplay.EngageCS; +begin + if PinCS <> TNativePin.None then + GPIO.PinValue[PinCS]:=0; +end; + +procedure TDisplay.ReleaseCS; +begin + if PinCS <> TNativePin.None then + GPIO.PinValue[PinCS]:=1; +end; + +procedure TDisplay.Present; +begin + PresentBuffer; + //Present(IntRect(ZeroPoint2i, FLogicalSize)); +end; + + +function TDisplay.ReadPixel(const X, Y: word): TBWColor; +var + Location,Position: Byte; +begin + if (X > FScreenSize.X) OR (Y > FScreenSize.Y) then exit; + + Location := PByte(FScreenBuffer + (Cardinal(Y) div 8) * Cardinal(FScreenSize.X) + Cardinal(X))^; + Position := (1 shl (7-(Y mod 8))); + + if ((Location AND Position) > 0) then + Result := 1 + else + Result := 0; +end; + +procedure TDisplay.WritePixel(const X, Y: word; const Color: TBWColor); +var + Location: PByte; + Position: Byte; + index:word; +begin + index:=X + ((Y shr 3) * FScreenSize.X); + if (index>=FScreenBufferSize) then exit; + + Location := (FScreenBuffer + PtrUInt(index)); + Position := (1 shl (7-(Y mod 8))); + + if Color=1 then + Location^ := Location^ OR Position + else + Location^ := Location^ AND ($FF xor (Position)); +end; + +function TDisplay.GetScanline(const Index: word): Pointer; +begin + Result := Pointer(FScreenBuffer + (Cardinal(Index) shr 3) * Cardinal(FScreenSize.X)); +end; + +procedure TDisplay.ClrScr; +begin + FillChar(FScreenBuffer^, FScreenBufferSize, 0); +end; + +procedure TDisplay.InvertScr(Orientation:boolean); +begin + EngageCS; + if (Orientation) then WriteCommand(CMD_SET_DISP_REVERSE) else WriteCommand(CMD_SET_DISP_NORMAL); + ReleaseCS; +end; + +procedure TDisplay.DrawCharacter(const X, Line: word; const aChar: byte); +var + i:byte; + index:word; +begin + index:=Line * FScreenSize.X + X; + for i:=0 to 4 do + begin + if (index+i)>=FScreenBufferSize then break; + PByte(FScreenBuffer+index+i)^:=font[(aChar*5)+i]; + end; +end; + +procedure TDisplay.DrawString(const X, Line: word; const aString: string); +const + FONTWIDTH=6; +var + i:byte; + localX, localLine: longword; +begin + localX:=X; + localLine:=Line; + for i:=1 to Length(aString) do + begin + if ((localX+FONTWIDTH)>=FScreenSize.X) then + begin + localX:=0; + Inc(localLine); + end; + DrawCharacter(localX,localLine,Ord(aString[i])); + Inc(localX,FONTWIDTH); + end; +end; + +procedure TDisplay.GetDemo1; +begin + Move(ScreenBufferInit1,FScreenBuffer^,FScreenBufferSize); + PresentBuffer; +end; + +procedure TDisplay.GetDemo2; +begin + Move(ScreenBufferInit2,FScreenBuffer^,FScreenBufferSize); + PresentBuffer; +end; + +end. diff --git a/Source/MBF.Displays.CustomDisplay.pas b/Source/MBF.Displays.CustomDisplay.pas index f5f610c..888d291 100644 --- a/Source/MBF.Displays.CustomDisplay.pas +++ b/Source/MBF.Displays.CustomDisplay.pas @@ -19,9 +19,8 @@ interface uses MBF.Types, - MBF.__CONTROLLERTYPE__.SystemCore, MBF.__CONTROLLERTYPE__.GPIO, - MBF.__CONTROLLERTYPE__.SPI; + MBF.__CONTROLLERTYPE__.SystemCore; type TDisplayBitDepth = (OneBit=1,TwoBits=2,FourBits=4,EightBits=8,SixteenBits=16); @@ -45,49 +44,33 @@ TScreenInfo = record type TCustomDisplay = object private FScreenInfo : TScreenInfo; - FpSPI : ^TSPI_Registers; - FpGPIOPort : ^TGPIO_Registers; FPinDC : TPinIdentifier; + FPinRST : TPinIdentifier; FPinWR : TPinIdentifier; FPinRD : TPinIdentifier; FPinCS : TPinIdentifier; - FPinRST : TPinIdentifier; FForegroundColor : TColor; FBackgroundColor : TColor; procedure setPinDC(const Value : TPinIdentifier); procedure setPinRST(const Value : TPinIdentifier); + procedure setPinWR(const Value : TPinIdentifier); + procedure setPinRD(const Value : TPinIdentifier); + procedure setPinCS(const Value : TPinIdentifier); procedure setScreenInfo(const Value : TScreenInfo); public procedure Reset; procedure InitSequence; - procedure clearScreen; + procedure ClearScreen; property ForegroundColor: TColor read FForegroundColor write FForegroundColor; property BackgroundColor : TColor read FBackgroundColor write FBackgroundColor; property PinDC : TPinIdentifier read FPinDC write setPinDC; property PinRST : TPinIdentifier read FPinRST write setPinRST; + property PinWR : TPinIdentifier read FPinWR write setPinWR; + property PinRD : TPinIdentifier read FPinRD write setPinRD; + property PinCS : TPinIdentifier read FPinCS write setPinCS; property ScreenInfo : TScreenInfo read FScreenInfo write setScreenInfo; end; - TCustomSPIDisplay = object(TCustomDisplay) - procedure WriteCommand(const value : byte); - procedure WriteCommand(const Values: array of Byte); - procedure WriteData(const value : byte); - procedure WriteData(const Values: array of Byte); - //procedure Initialize(var SPI : TSpi_Registers); - procedure Initialize(var SPI : TSpi_Registers;const APinDC : TPinIdentifier;const APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); - end; - - TCustomGPIODisplay = object(TCustomDisplay) - var - procedure Initialize(var GPIOPort : TGPIO_Registers;const APinDC,APinWR,APinRD,aPinCS,APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); - procedure WriteCommand(const value : byte); - procedure WriteCommand(const Values: array of Byte); - procedure WriteData(const value : byte); - procedure WriteDataWord(const value : word); - procedure WriteData(const Values: array of Byte); - procedure WriteDataWord(const Values : array of word); - end; - implementation class operator TScreenInfo.= (a,b : TScreenInfo) : boolean; @@ -95,59 +78,6 @@ implementation Result := (a.Width = b.Width) and (a.Height = b.Height) and (a.Depth = b.Depth); end; -//procedure TCustomSPIDisplay.Initialize(var SPI : TSpi_Registers); -//begin -// FpSPI := @SPI; -// FPinDC := TNativePin.NONE; -// FPinRST := TNativePin.NONE; -// FScreenSize.X := 0; -// FScreenSize.Y := 0; -//end; - -procedure TCustomSPIDisplay.Initialize(var SPI : TSpi_Registers;const APinDC : TPinIdentifier;const APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); -begin - FpSPI := @SPI; - FPinDC := APinDC; - FPinRST := APinRST; - FPinWR := TNativePin.None; - FPinRD := TNativePin.None; - FPinCS := TNativePin.None; - FScreenInfo := AScreenInfo; - FBackgroundColor := clBlack; - FForegroundColor := clWhite; - - GPIO.PinMode[APinDC] := TPinMode.Output; - GPIO.PinMode[APinRST] := TPinMode.Output; - GPIO.PinValue[APinDC] := 1; - GPIO.PinValue[APinRST] := 1; -end; - -procedure TCustomGPIODisplay.Initialize(var GPIOPort : TGPIO_Registers;const APinDC,APinWR,APinRD,aPinCS,APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); -begin - FpGPIOPort := @GPIOPort; - FPinDC := APinDC; - FPinWR := APinWR; - FPinRD := APinRD; - FPinCS := APinCS; - FPinRST := APinRST; - FScreenInfo := AScreenInfo; - FBackgroundColor := clBlack; - FForegroundColor := clWhite; - - FpGPIOPort^.Initialize; - FpGPIOPort^.SetPortMode(TPinMode.Output); - FpGPIOPort^.SetPortOutputSpeed(TPinOutputSpeed.Slow); - FpGPIOPort^.SetPortOutputMode(TPinOutputmode.PushPull); - FpGPIOPort^.SetPortDrive(TPinDrive.None); - - //Arduino Pins D10-D13 are connected to the additional Signal needed - GPIO.PinMode[FPinDC] := TPinMode.Output; //RS D/~C - GPIO.PinMode[FPinWR] := TPinMode.Output; //WR - GPIO.PinMode[FPinRD] := TPinMode.Output; //RD - GPIO.PinMode[FPinCS] := TPinMode.Output; //~CS - GPIO.PinMode[FPinRST] := TPinMode.Output; //~Reset -end; - procedure TCustomDisplay.Reset; begin if FPinDC <> TNativePin.None then @@ -172,141 +102,33 @@ procedure TCustomDisplay.InitSequence; begin end; -procedure TCustomSPIDisplay.WriteCommand(const Value: Byte); -begin - GPIO.PinValue[FPinDC] := 0; - FpSPI^.Write(@Value, 1); -end; - -procedure TCustomSPIDisplay.WriteCommand(const Values: array of Byte); -begin - GPIO.PinValue[FPinDC] := 0; - if Length(Values) > 0 then - FpSPI^.Write(@Values[0], Length(Values)); -end; - -procedure TCustomSPIDisplay.WriteData(const Value: Byte); -begin - GPIO.PinValue[FPinDC] := 1; - FpSPI^.Write(@Value, 1); -end; - -procedure TCustomSPIDisplay.WriteData(const Values: array of Byte); -begin - GPIO.PinValue[FPinDC] := 1; - if Length(Values) > 0 then - FpSPI^.Write(@Values[0], Length(Values)); -end; - -procedure TCustomGPIODisplay.WriteCommand(const Value: Byte); -begin - GPIO.SetPinLevelHigh(FPinRD); - GPIO.SetPinLevelLow (FPinWR); - GPIO.SetPinLevelLow (FPinDC); - FpGPIOPort^.SetPortValues(Value); - GPIO.SetPinLevelLow(FPinCS); - GPIO.SetPinLevelHigh(FPinCS); - GPIO.SetPinLevelHigh(FPinDC); - GPIO.SetPinLevelHigh(FPinWR); -end; - -procedure TCustomGPIODisplay.WriteCommand(const Values: array of Byte); -var - i : integer; +procedure TCustomDisplay.setPinDC(const Value : TPinIdentifier); begin - if Length(Values) > 0 then - begin - GPIO.SetPinLevelHigh(FPinRD); - GPIO.SetPinLevelLow (FPinWR); - GPIO.SetPinLevelLow (FPinDC); - begin - for i := 0 to Length(Values)-1 do - begin - FpGPIOPort^.SetPortValues(Values[i]); - GPIO.SetPinLevelLow(FPinCS); - GPIO.SetPinLevelHigh(FPinCS); - end; - end; - GPIO.SetPinLevelHigh(FPinDC); - GPIO.SetPinLevelHigh(FPinWR); - end; + FPinDC := Value; end; -procedure TCustomGPIODisplay.WriteData(const Value: Byte); +procedure TCustomDisplay.setPinRST(const Value : TPinIdentifier); begin - GPIO.SetPinLevelHigh(FPinRD); - FpGPIOPort^.SetPortValues(Value); - GPIO.SetPinLevelLow(FPinWR); - GPIO.SetPinLevelHigh(FPinDC); - GPIO.SetPinLevelLow(FPinCS); - GPIO.SetPinLevelHigh(FPinCS); - GPIO.SetPinLevelHigh(FPinWR); + FPinRST := Value; end; -procedure TCustomGPIODisplay.WriteDataWord(const Value: Word); +procedure TCustomDisplay.setPinWR(const Value : TPinIdentifier); begin - GPIO.SetPinLevelHigh(FPinRD); - FpGPIOPort^.SetPortValues(Value); - GPIO.SetPinLevelLow(FPinWR); - GPIO.SetPinLevelHigh(FPinDC); - GPIO.SetPinLevelLow(FPinCS); - GPIO.SetPinLevelHigh(FPinCS); - GPIO.SetPinLevelHigh(FPinWR); + FPinWR := Value; end; -procedure TCustomGPIODisplay.WriteData(const Values: array of Byte); -var - i : integer; +procedure TCustomDisplay.setPinRD(const Value : TPinIdentifier); begin - if Length(Values) > 0 then - begin - GPIO.SetPinLevelHigh(FPinRD); - GPIO.SetPinLevelLow (FPinWR); - GPIO.SetPinLevelHigh(FPinDC); - begin - for i := 0 to Length(Values)-1 do - begin - FpGPIOPort^.SetPortValues(Values[i]); - GPIO.SetPinLevelLow(FPinCS); - GPIO.SetPinLevelHigh(FPinCS); - end; - end; - GPIO.SetPinLevelHigh(FPinWR); - end; + FPinRD := Value; end; -procedure TCustomGPIODisplay.WriteDataWord(const Values: array of Word); -var - i : integer; +procedure TCustomDisplay.setPinCS(const Value : TPinIdentifier); begin - if Length(Values) > 0 then - begin - GPIO.SetPinLevelHigh(FPinRD); - GPIO.SetPinLevelLow (FPinWR); - GPIO.SetPinLevelHigh(FPinDC); - begin - for i := 0 to Length(Values)-1 do - begin - FpGPIOPort^.SetPortValues(Values[i]); - GPIO.SetPinLevelLow(FPinCS); - GPIO.SetPinLevelHigh(FPinCS); - end; - end; - GPIO.SetPinLevelHigh(FPinWR); - end; -end; - -procedure TCustomDisplay.setPinDC(const Value : TPinIdentifier); -begin - FPinDC := Value; + FPinCS := Value; end; -procedure TCustomDisplay.setPinRST(const Value : TPinIdentifier); -begin - FPinRST := Value; -end; -procedure TCustomDisplay.clearScreen; +procedure TCustomDisplay.ClearScreen; begin end; diff --git a/Source/MBF.Displays.CustomDisplayGPIO.pas b/Source/MBF.Displays.CustomDisplayGPIO.pas new file mode 100644 index 0000000..65b125c --- /dev/null +++ b/Source/MBF.Displays.CustomDisplayGPIO.pas @@ -0,0 +1,164 @@ +unit MBF.Displays.CustomDisplayGPIO; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} + +{$INCLUDE MBF.Config.inc} + +interface + +uses + MBF.Types, + MBF.__CONTROLLERTYPE__.GPIO, + MBF.Displays.CustomDisplay; + +type + TCustomGPIODisplay = object(TCustomDisplay) + var + FpGPIOPort : ^TGPIO_Registers; + procedure Initialize(var GPIOPort : TGPIO_Registers;const APinDC,APinWR,APinRD,aPinCS,APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); + procedure WriteCommand(const value : byte); + procedure WriteCommand(const Values: array of Byte); + procedure WriteData(const value : byte); + procedure WriteDataWord(const value : word); + procedure WriteData(const Values: array of Byte); + procedure WriteDataWord(const Values : array of word); + end; + +implementation + +procedure TCustomGPIODisplay.Initialize(var GPIOPort : TGPIO_Registers;const APinDC,APinWR,APinRD,aPinCS,APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); +begin + FpGPIOPort := @GPIOPort; + PinDC := APinDC; + PinRST := APinRST; + PinWR := APinWR; + PinRD := APinRD; + PinCS := APinCS; + ScreenInfo := AScreenInfo; + BackgroundColor := clBlack; + ForegroundColor := clWhite; + + FpGPIOPort^.Initialize; + FpGPIOPort^.SetPortMode(TPinMode.Output); + FpGPIOPort^.SetPortOutputSpeed(TPinOutputSpeed.Slow); + FpGPIOPort^.SetPortOutputMode(TPinOutputmode.PushPull); + FpGPIOPort^.SetPortDrive(TPinDrive.None); + + //Arduino Pins D10-D13 are connected to the additional Signal needed + GPIO.PinMode[PinDC] := TPinMode.Output; //RS D/~C + GPIO.PinMode[PinWR] := TPinMode.Output; //WR + GPIO.PinMode[PinRD] := TPinMode.Output; //RD + GPIO.PinMode[PinCS] := TPinMode.Output; //~CS + GPIO.PinMode[PinRST] := TPinMode.Output; //~Reset +end; + +procedure TCustomGPIODisplay.WriteCommand(const Value: Byte); +begin + GPIO.SetPinLevelHigh(PinRD); + GPIO.SetPinLevelLow (PinWR); + GPIO.SetPinLevelLow (PinDC); + FpGPIOPort^.SetPortValues(Value); + GPIO.SetPinLevelLow(PinCS); + GPIO.SetPinLevelHigh(PinCS); + GPIO.SetPinLevelHigh(PinDC); + GPIO.SetPinLevelHigh(PinWR); +end; + +procedure TCustomGPIODisplay.WriteCommand(const Values: array of Byte); +var + i : integer; +begin + if Length(Values) > 0 then + begin + GPIO.SetPinLevelHigh(PinRD); + GPIO.SetPinLevelLow (PinWR); + GPIO.SetPinLevelLow (PinDC); + begin + for i := 0 to Length(Values)-1 do + begin + FpGPIOPort^.SetPortValues(Values[i]); + GPIO.SetPinLevelLow(PinCS); + GPIO.SetPinLevelHigh(PinCS); + end; + end; + GPIO.SetPinLevelHigh(PinDC); + GPIO.SetPinLevelHigh(PinWR); + end; +end; + +procedure TCustomGPIODisplay.WriteData(const Value: Byte); +begin + GPIO.SetPinLevelHigh(PinRD); + FpGPIOPort^.SetPortValues(Value); + GPIO.SetPinLevelLow(PinWR); + GPIO.SetPinLevelHigh(PinDC); + GPIO.SetPinLevelLow(PinCS); + GPIO.SetPinLevelHigh(PinCS); + GPIO.SetPinLevelHigh(PinWR); +end; + +procedure TCustomGPIODisplay.WriteDataWord(const Value: Word); +begin + GPIO.SetPinLevelHigh(PinRD); + FpGPIOPort^.SetPortValues(Value); + GPIO.SetPinLevelLow(PinWR); + GPIO.SetPinLevelHigh(PinDC); + GPIO.SetPinLevelLow(PinCS); + GPIO.SetPinLevelHigh(PinCS); + GPIO.SetPinLevelHigh(PinWR); +end; + +procedure TCustomGPIODisplay.WriteData(const Values: array of Byte); +var + i : integer; +begin + if Length(Values) > 0 then + begin + GPIO.SetPinLevelHigh(PinRD); + GPIO.SetPinLevelLow (PinWR); + GPIO.SetPinLevelHigh(PinDC); + begin + for i := 0 to Length(Values)-1 do + begin + FpGPIOPort^.SetPortValues(Values[i]); + GPIO.SetPinLevelLow(PinCS); + GPIO.SetPinLevelHigh(PinCS); + end; + end; + GPIO.SetPinLevelHigh(PinWR); + end; +end; + +procedure TCustomGPIODisplay.WriteDataWord(const Values: array of Word); +var + i : integer; +begin + if Length(Values) > 0 then + begin + GPIO.SetPinLevelHigh(PinRD); + GPIO.SetPinLevelLow (PinWR); + GPIO.SetPinLevelHigh(PinDC); + begin + for i := 0 to Length(Values)-1 do + begin + FpGPIOPort^.SetPortValues(Values[i]); + GPIO.SetPinLevelLow(PinCS); + GPIO.SetPinLevelHigh(PinCS); + end; + end; + GPIO.SetPinLevelHigh(PinWR); + end; +end; + +end. diff --git a/Source/MBF.Displays.CustomDisplaySPI.pas b/Source/MBF.Displays.CustomDisplaySPI.pas new file mode 100644 index 0000000..a9ff774 --- /dev/null +++ b/Source/MBF.Displays.CustomDisplaySPI.pas @@ -0,0 +1,92 @@ +unit MBF.Displays.CustomDisplaySPI; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} + +{$INCLUDE MBF.Config.inc} + +interface + +uses + MBF.Types, + MBF.__CONTROLLERTYPE__.GPIO, + MBF.__CONTROLLERTYPE__.SPI, + MBF.Displays.CustomDisplay; + +type + TCustomSPIDisplay = object(TCustomDisplay) + private + FpSPI : ^TSPI_Registers; + public + procedure WriteCommand(const value : byte); + procedure WriteCommand(const Values: array of Byte); + procedure WriteData(const value : byte); + procedure WriteData(const Values: array of Byte); + procedure WriteData(const Buffer: pointer; const Length:word); + procedure Initialize(var SPI : TSpi_Registers;const APinDC : TPinIdentifier;const APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); + end; + +implementation + +procedure TCustomSPIDisplay.Initialize(var SPI : TSpi_Registers;const APinDC : TPinIdentifier;const APinRST : TPinIdentifier;AScreenInfo : TScreenInfo); +begin + FpSPI := @SPI; + PinDC := APinDC; + PinRST := APinRST; + PinWR := TNativePin.None; + PinRD := TNativePin.None; + PinCS := TNativePin.None; + ScreenInfo := AScreenInfo; + BackgroundColor := clBlack; + ForegroundColor := clWhite; + + GPIO.PinMode[APinDC] := TPinMode.Output; + GPIO.PinMode[APinRST] := TPinMode.Output; + GPIO.PinValue[APinDC] := 1; + GPIO.PinValue[APinRST] := 1; +end; + +procedure TCustomSPIDisplay.WriteCommand(const Value: Byte); +begin + GPIO.PinValue[PinDC] := 0; + FpSPI^.Write(@Value, 1); +end; + +procedure TCustomSPIDisplay.WriteCommand(const Values: array of Byte); +begin + GPIO.PinValue[PinDC] := 0; + if Length(Values) > 0 then + FpSPI^.Write(@Values[0], Length(Values)); +end; + +procedure TCustomSPIDisplay.WriteData(const Value: Byte); +begin + GPIO.PinValue[PinDC] := 1; + FpSPI^.Write(@Value, 1); +end; + +procedure TCustomSPIDisplay.WriteData(const Values: array of Byte); +begin + GPIO.PinValue[PinDC] := 1; + if Length(Values) > 0 then + FpSPI^.Write(@Values[0], Length(Values)); +end; + +procedure TCustomSPIDisplay.WriteData(const Buffer: pointer; const Length:word); +begin + GPIO.PinValue[PinDC] := 1; + if (Assigned(Buffer) AND (Length>0)) then + FpSPI^.Write(Buffer, Length); +end; + +end. diff --git a/Source/MBF.Displays.OLED1Xplained.pas b/Source/MBF.Displays.OLED1Xplained.pas new file mode 100644 index 0000000..7e5cbeb --- /dev/null +++ b/Source/MBF.Displays.OLED1Xplained.pas @@ -0,0 +1,704 @@ +unit MBF.Displays.OLED1Xplained; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +interface + +{$INCLUDE MBF.Config.inc} + +uses + MBF.Types, + MBF.Displays.CustomDisplay, + MBF.Displays.CustomDisplaySPI, + MBF.__CONTROLLERTYPE__.GPIO; + +const + ScreenBufferInit1: packed array [0..511] of byte = ( + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $3, $7, $F, $1F, $1F, $3F, $3F, $3F, $3F, $7, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $7F, $3F, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $1F, $3F, $70, $70, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $6, $6, $0, $0, $0, $3, $3, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $F, $7, $7, + $7, $3F, $FF, $FF, $FF, $FF, $FF, $FE, $FF, $FF, $FF, $FF, $FF, $3E, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $F, $3F, + $70, $60, $60, $60, $60, $30, $7F, $3F, $0, $0, $1F, $3F, $70, $60, $60, $60, + $60, $39, $FF, $FF, $0, $6, $1F, $39, $60, $60, $60, $60, $30, $3F, $7F, $0, + $0, $60, $FF, $FF, $60, $60, $0, $7F, $7F, $70, $60, $60, $40, $0, $7F, $7F, + $0, $0, $0, $0, $7F, $7F, $0, $0, $0, $7F, $7F, $0, $0, $60, $FF, $FF, + $60, $60, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $80, $F8, $FC, $FE, $FE, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $EF, $E7, $E7, $E3, + $F3, $F9, $FF, $FF, $FF, $F7, $7, $1F, $FF, $FF, $FF, $FF, $FF, $FF, $7F, $FF, + $7F, $7F, $7F, $7F, $7F, $7F, $3F, $3F, $1F, $F, $7, $3, $0, $0, $0, $C0, + $E0, $60, $20, $20, $60, $E0, $E0, $E0, $0, $0, $80, $C0, $E0, $60, $20, $60, + $60, $E0, $E0, $E0, $0, $0, $80, $C0, $60, $60, $20, $60, $60, $E0, $E0, $0, + $0, $0, $E0, $E0, $0, $0, $0, $E0, $E0, $0, $0, $0, $0, $0, $80, $E0, + $60, $60, $60, $60, $E0, $80, $0, $0, $0, $E0, $E0, $0, $0, $0, $E0, $E0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0); {section '.progmem';} + + ScreenBufferInit2: array [0..511] of byte = ( + $0, $0, $0, $3, $7, $1F, $9F, $FF, $FF, $FF, $FF, $FF, $FF, $FD, $F1, $E3, + $E3, $CF, $FF, $FF, $FF, $FF, $F0, $FC, $7F, $3F, $3F, $3F, $3F, $7F, $FF, $FF, + $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE, $FC, $F0, $E0, $80, $0, $0, $0, $C, + $1C, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $7F, $7F, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $7, $7, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $1C, $C, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + + $0, $7, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE, $FE, $FE, $FE, $FC, $F8, + $F8, $F0, $FE, $FF, $FF, $FF, $7F, $3F, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $1F, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $FF, + $FF, $0, $0, $0, $FF, $FF, $E0, $C0, $C0, $C0, $FF, $7F, $0, $0, $1E, $7F, + $E1, $C0, $C0, $C0, $C0, $61, $FF, $FF, $0, $0, $FE, $FF, $1, $0, $0, $0, + $FF, $FF, $0, $0, $21, $F9, $F8, $DC, $CC, $CF, $7, $0, $C0, $FF, $FF, $C0, + $80, $0, $FF, $FF, $C0, $C0, $80, $0, $0, $FF, $FF, $0, $0, $1F, $7F, $F9, + $C8, $C8, $C8, $C8, $79, $39, $0, $0, $71, $F9, $D8, $CC, $CE, $47, $3, $0, + + $0, $0, $0, $0, $80, $80, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $80, $C0, $E0, $F0, $F8, $F8, $FC, $FC, $FC, $FC, $F8, $F0, $C0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $C0, + $C0, $0, $0, $0, $C0, $C0, $0, $0, $0, $0, $C0, $C0, $0, $0, $0, $80, + $C0, $C0, $C0, $C0, $C0, $80, $C0, $C0, $0, $0, $0, $80, $C0, $C0, $C0, $C0, + $C0, $80, $0, $0, $80, $C0, $C0, $C0, $C0, $C0, $0, $0, $0, $C0, $C0, $0, + $0, $0, $C0, $80, $0, $0, $0, $0, $0, $C0, $C0, $0, $0, $0, $80, $C0, + $C0, $C0, $C0, $C0, $80, $80, $0, $0, $80, $C0, $C0, $C0, $C0, $80, $0, $0, + + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, + $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0); {section '.progmem';} + + font: array [0..1274] of byte = ( + $0, $0, $0, $0, $0, // Ascii 0 + $7C, $DA, $F2, $DA, $7C, //ASC(01) + $7C, $D6, $F2, $D6, $7C, //ASC(02) + $38, $7C, $3E, $7C, $38, + $18, $3C, $7E, $3C, $18, + $38, $EA, $BE, $EA, $38, + $38, $7A, $FE, $7A, $38, + $0, $18, $3C, $18, $0, + $FF, $E7, $C3, $E7, $FF, + $0, $18, $24, $18, $0, + $FF, $E7, $DB, $E7, $FF, + $C, $12, $5C, $60, $70, + $64, $94, $9E, $94, $64, + $2, $FE, $A0, $A0, $E0, + $2, $FE, $A0, $A4, $FC, + $5A, $3C, $E7, $3C, $5A, + $FE, $7C, $38, $38, $10, + $10, $38, $38, $7C, $FE, + $28, $44, $FE, $44, $28, + $FA, $FA, $0, $FA, $FA, + $60, $90, $FE, $80, $FE, + $0, $66, $91, $A9, $56, + $6, $6, $6, $6, $6, + $29, $45, $FF, $45, $29, + $10, $20, $7E, $20, $10, + $8, $4, $7E, $4, $8, + $10, $10, $54, $38, $10, + $10, $38, $54, $10, $10, + $78, $8, $8, $8, $8, + $30, $78, $30, $78, $30, + $C, $1C, $7C, $1C, $C, + $60, $70, $7C, $70, $60, + $0, $0, $0, $0, $0, + $0, $0, $FA, $0, $0, + $0, $E0, $0, $E0, $0, + $28, $FE, $28, $FE, $28, + $24, $54, $FE, $54, $48, + $C4, $C8, $10, $26, $46, + $6C, $92, $6A, $4, $A, + $0, $10, $E0, $C0, $0, + $0, $38, $44, $82, $0, + $0, $82, $44, $38, $0, + $54, $38, $FE, $38, $54, + $10, $10, $7C, $10, $10, + $0, $1, $E, $C, $0, + $10, $10, $10, $10, $10, + $0, $0, $6, $6, $0, + $4, $8, $10, $20, $40, + $7C, $8A, $92, $A2, $7C, + $0, $42, $FE, $2, $0, + $4E, $92, $92, $92, $62, + $84, $82, $92, $B2, $CC, + $18, $28, $48, $FE, $8, + $E4, $A2, $A2, $A2, $9C, + $3C, $52, $92, $92, $8C, + $82, $84, $88, $90, $E0, + $6C, $92, $92, $92, $6C, + $62, $92, $92, $94, $78, + $0, $0, $28, $0, $0, + $0, $2, $2C, $0, $0, + $0, $10, $28, $44, $82, + $28, $28, $28, $28, $28, + $0, $82, $44, $28, $10, + $40, $80, $9A, $90, $60, + $7C, $82, $BA, $9A, $72, + $3E, $48, $88, $48, $3E, + $FE, $92, $92, $92, $6C, + $7C, $82, $82, $82, $44, + $FE, $82, $82, $82, $7C, + $FE, $92, $92, $92, $82, + $FE, $90, $90, $90, $80, + $7C, $82, $82, $8A, $CE, + $FE, $10, $10, $10, $FE, + $0, $82, $FE, $82, $0, + $4, $2, $82, $FC, $80, + $FE, $10, $28, $44, $82, + $FE, $2, $2, $2, $2, + $FE, $40, $38, $40, $FE, + $FE, $20, $10, $8, $FE, + $7C, $82, $82, $82, $7C, + $FE, $90, $90, $90, $60, + $7C, $82, $8A, $84, $7A, + $FE, $90, $98, $94, $62, + $64, $92, $92, $92, $4C, + $C0, $80, $FE, $80, $C0, + $FC, $2, $2, $2, $FC, + $F8, $4, $2, $4, $F8, + $FC, $2, $1C, $2, $FC, + $C6, $28, $10, $28, $C6, + $C0, $20, $1E, $20, $C0, + $86, $9A, $92, $B2, $C2, + $0, $FE, $82, $82, $82, + $40, $20, $10, $8, $4, + $0, $82, $82, $82, $FE, + $20, $40, $80, $40, $20, + $2, $2, $2, $2, $2, + $0, $C0, $E0, $10, $0, + $4, $2A, $2A, $1E, $2, + $FE, $14, $22, $22, $1C, + $1C, $22, $22, $22, $14, + $1C, $22, $22, $14, $FE, + $1C, $2A, $2A, $2A, $18, + $0, $10, $7E, $90, $40, + $18, $25, $25, $39, $1E, + $FE, $10, $20, $20, $1E, + $0, $22, $BE, $2, $0, + $4, $2, $2, $BC, $0, + $FE, $8, $14, $22, $0, + $0, $82, $FE, $2, $0, + $3E, $20, $1E, $20, $1E, + $3E, $10, $20, $20, $1E, + $1C, $22, $22, $22, $1C, + $3F, $18, $24, $24, $18, + $18, $24, $24, $18, $3F, + $3E, $10, $20, $20, $10, + $12, $2A, $2A, $2A, $24, + $20, $20, $FC, $22, $24, + $3C, $2, $2, $4, $3E, + $38, $4, $2, $4, $38, + $3C, $2, $C, $2, $3C, + $22, $14, $8, $14, $22, + $32, $9, $9, $9, $3E, + $22, $26, $2A, $32, $22, + $0, $10, $6C, $82, $0, + $0, $0, $EE, $0, $0, + $0, $82, $6C, $10, $0, + $40, $80, $40, $20, $40, + $3C, $64, $C4, $64, $3C, + $78, $85, $85, $86, $48, + $5C, $2, $2, $4, $5E, + $1C, $2A, $2A, $AA, $9A, + $84, $AA, $AA, $9E, $82, + $84, $2A, $2A, $1E, $82, + $84, $AA, $2A, $1E, $2, + $4, $2A, $AA, $9E, $2, + $30, $78, $4A, $4E, $48, + $9C, $AA, $AA, $AA, $9A, + $9C, $2A, $2A, $2A, $9A, + $9C, $AA, $2A, $2A, $1A, + $0, $0, $A2, $3E, $82, + $0, $40, $A2, $BE, $42, + $0, $80, $A2, $3E, $2, + $F, $94, $24, $94, $F, + $F, $14, $A4, $14, $F, + $3E, $2A, $AA, $A2, $0, + $4, $2A, $2A, $3E, $2A, + $3E, $50, $90, $FE, $92, + $4C, $92, $92, $92, $4C, + $4C, $12, $12, $12, $4C, + $4C, $52, $12, $12, $C, + $5C, $82, $82, $84, $5E, + $5C, $42, $2, $4, $1E, + $0, $B9, $5, $5, $BE, + $9C, $22, $22, $22, $9C, + $BC, $2, $2, $2, $BC, + $3C, $24, $FF, $24, $24, + $12, $7E, $92, $C2, $66, + $D4, $F4, $3F, $F4, $D4, + $FF, $90, $94, $6F, $4, + $3, $11, $7E, $90, $C0, + $4, $2A, $2A, $9E, $82, + $0, $0, $22, $BE, $82, + $C, $12, $12, $52, $4C, + $1C, $2, $2, $44, $5E, + $0, $5E, $50, $50, $4E, + $BE, $B0, $98, $8C, $BE, + $64, $94, $94, $F4, $14, + $64, $94, $94, $94, $64, + $C, $12, $B2, $2, $4, + $1C, $10, $10, $10, $10, + $10, $10, $10, $10, $1C, + $F4, $8, $13, $35, $5D, + $F4, $8, $14, $2C, $5F, + $0, $0, $DE, $0, $0, + $10, $28, $54, $28, $44, + $44, $28, $54, $28, $10, + $55, $0, $AA, $0, $55, + $55, $AA, $55, $AA, $55, + $AA, $55, $AA, $55, $AA, + $0, $0, $0, $FF, $0, + $8, $8, $8, $FF, $0, + $28, $28, $28, $FF, $0, + $8, $8, $FF, $0, $FF, + $8, $8, $F, $8, $F, + $28, $28, $28, $3F, $0, + $28, $28, $EF, $0, $FF, + $0, $0, $FF, $0, $FF, + $28, $28, $2F, $20, $3F, + $28, $28, $E8, $8, $F8, + $8, $8, $F8, $8, $F8, + $28, $28, $28, $F8, $0, + $8, $8, $8, $F, $0, + $0, $0, $0, $F8, $8, + $8, $8, $8, $F8, $8, + $8, $8, $8, $F, $8, + $0, $0, $0, $FF, $8, + $8, $8, $8, $8, $8, + $8, $8, $8, $FF, $8, + $0, $0, $0, $FF, $28, + $0, $0, $FF, $0, $FF, + $0, $0, $F8, $8, $E8, + $0, $0, $3F, $20, $2F, + $28, $28, $E8, $8, $E8, + $28, $28, $2F, $20, $2F, + $0, $0, $FF, $0, $EF, + $28, $28, $28, $28, $28, + $28, $28, $EF, $0, $EF, + $28, $28, $28, $E8, $28, + $8, $8, $F8, $8, $F8, + $28, $28, $28, $2F, $28, + $8, $8, $F, $8, $F, + $0, $0, $F8, $8, $F8, + $0, $0, $0, $F8, $28, + $0, $0, $0, $3F, $28, + $0, $0, $F, $8, $F, + $8, $8, $FF, $8, $FF, + $28, $28, $28, $FF, $28, + $8, $8, $8, $F8, $0, + $0, $0, $0, $F, $8, + $FF, $FF, $FF, $FF, $FF, + $F, $F, $F, $F, $F, + $FF, $FF, $FF, $0, $0, + $0, $0, $0, $FF, $FF, + $F0, $F0, $F0, $F0, $F0, + $1C, $22, $22, $1C, $22, + $3E, $54, $54, $7C, $28, + $7E, $40, $40, $60, $60, + $40, $7E, $40, $7E, $40, + $C6, $AA, $92, $82, $C6, + $1C, $22, $22, $3C, $20, + $2, $7E, $4, $78, $4, + $60, $40, $7E, $40, $40, + $99, $A5, $E7, $A5, $99, + $38, $54, $92, $54, $38, + $32, $4E, $80, $4E, $32, + $C, $52, $B2, $B2, $C, + $C, $12, $1E, $12, $C, + $3D, $46, $5A, $62, $BC, + $7C, $92, $92, $92, $0, + $7E, $80, $80, $80, $7E, + $54, $54, $54, $54, $54, + $22, $22, $FA, $22, $22, + $2, $8A, $52, $22, $2, + $2, $22, $52, $8A, $2, + $0, $0, $FF, $80, $C0, + $7, $1, $FF, $0, $0, + $10, $10, $D6, $D6, $10, + $6C, $48, $6C, $24, $6C, + $60, $F0, $90, $F0, $60, + $0, $0, $18, $18, $0, + $0, $0, $8, $8, $0, + $C, $2, $FF, $80, $80, + $0, $F8, $80, $80, $78, + $0, $98, $B8, $E8, $48, + $0, $3C, $3C, $3C, $3C); { section '.progmem';} + + ScreenSize128x32x1: TScreenInfo = + (Width: 128; Height: 32; Depth: TDisplayBitDepth.OneBit); + ScreenSize128x64x1: TScreenInfo = + (Width: 128; Height: 64; Depth: TDisplayBitDepth.OneBit); + ScreenSize96x16x1: TScreenInfo = + (Width: 96; Height: 16; Depth: TDisplayBitDepth.OneBit); + ScreenSize64x48x1: TScreenInfo = + (Width: 64; Height: 48; Depth: TDisplayBitDepth.OneBit); + +type + TBWColor=0..1; + + TDisplay = object(TCustomSPIDisplay) + private const + LCD128x64: TPoint2px = (X: 128; Y: 64); + LCD128x32: TPoint2px = (X: 128; Y: 32); + LCD96x16: TPoint2px = (X: 96; Y: 16); + LCD64x48: TPoint2px = (X: 64; Y: 48); + pagemap :array[0..7] of byte = ( 3, 2, 1, 0, 7, 6, 5, 4); + + private var + FInternalVCC : boolean; + FScreenSize: TPoint2px; + FScreenBufferSize: longword; + FScreenBuffer: Pointer; + FScreenBuffer2: packed array [0..511] of byte; + protected + function ReadPixel(const X, Y: word): TBWColor; + procedure WritePixel(const X, Y: word; const Color: TBWColor); + function GetScanline(const Index: word): Pointer; + procedure PresentBuffer; + procedure EngageCS; + procedure ReleaseCS; + public + function InitSequence:boolean; + procedure ClrScr; + procedure InvertScr(Orientation:boolean); + procedure Present; + procedure DrawCharacter(const X, Line: word; const aChar: byte); + procedure DrawString(const X, Line: word; const aString: string); + procedure GetDemo1; + procedure GetDemo2; + property ScreenSize: TPoint2px read FScreenSize; + property Scanline[const Index: word]: Pointer read GetScanline; + property Pixel[const X,Y: word]: TBWColor read ReadPixel write WritePixel; + end; + +implementation + +uses + MBF.__CONTROLLERTYPE__.SystemCore; + +const + CMD_CHARGE_PUMP = $8D; + + + CMD_SET_COLUMN_UPPER = $10; + CMD_SET_COLUMN_LOWER = $00; + CMD_COLUMN_ADDRESS = $21; + CMD_COM_SCAN_NORMAL = $C0; + CMD_COM_SCAN_DEC = $C8; + CMD_DISPLAY_ALL_ON_RESUME = $A4; + CMD_DISPLAY_OFF = $AE; + CMD_DISPLAY_ON = $AF; + CMD_MEMORY_MODE = $20; + CMD_NORMAL_DISPLAY = $A6; + CMD_INVERSE_DISPLAY = $A7; + CMD_PAGE_ADDRESS = $22; + CMD_SEGMENT_REMAP = $A0; + CMD_SET_COM_PINS = $DA; + CMD_SET_CONTRAST = $81; + CMD_SET_DISPLAY_CLOCK_DIV = $D5; + CMD_SET_DISPLAY_OFFSET = $D3; + CMD_SET_MULTIPLEX = $A8; + CMD_SET_PRECHARGE = $D9; + CMD_SET_START_LINE = $40; + CMD_SET_VCOM_DETECT = $DB; + + + +function TDisplay.InitSequence:boolean; +begin + result:=false; + Reset; + + FScreenSize.X := ScreenInfo.Width; + FScreenSize.Y := ScreenInfo.Height; + + FScreenBufferSize := (FScreenSize.X * FScreenSize.Y); + + case ScreenInfo.Depth of + TDisplayBitDepth.OneBit: FScreenBufferSize:=(FScreenBufferSize DIV 8); + TDisplayBitDepth.TwoBits: FScreenBufferSize:=(FScreenBufferSize DIV 4); + TDisplayBitDepth.FourBits: FScreenBufferSize:=(FScreenBufferSize DIV 2); + TDisplayBitDepth.SixteenBits: FScreenBufferSize:=(FScreenBufferSize * 2); + end; + + { + if (FScreenBufferSize=0) OR (FScreenBufferSize>Length(FScreenBuffer2)) then + begin + // Houston, we have a problem !! + exit; + end; + } + + //Does not work !! + //FScreenBuffer := GetMem(FScreenBufferSize); + FScreenBuffer := @FScreenBuffer2; + + EngageCS; + + FInternalVCC := true; + //Set Display off + WriteCommand(CMD_DISPLAY_OFF); + SystemCore.Delay(10); + + // Set Display Clock Divide Ratio / OSC Frequency + WriteCommand([CMD_SET_DISPLAY_CLOCK_DIV, $80]); + + // Set Multiplex Ratio + WriteCommand(CMD_SET_MULTIPLEX); + if ScreenInfo = ScreenSize128x32x1 then + WriteCommand($1F) + else if ScreenInfo = ScreenSize96x16x1 then + WriteCommand($0F) + else if ScreenInfo = ScreenSize64x48x1 then + WriteCommand($2F) + else + WriteCommand($3F); + + // Set Display Offset + WriteCommand([CMD_SET_DISPLAY_OFFSET, $00]); + + // Set Display Start Line + WriteCommand(CMD_SET_START_LINE); + + // Set Charge Pump + WriteCommand(CMD_CHARGE_PUMP); + if FInternalVCC then + WriteCommand($14) + else + WriteCommand($10); + + WriteCommand([CMD_MEMORY_MODE, $00]); + + // Set Segment Re-Map + WriteCommand(CMD_SEGMENT_REMAP or $01); + + // Set Com Output Scan Direction + WriteCommand(CMD_COM_SCAN_NORMAL); + + // Set COM Hardware Configuration + WriteCommand(CMD_SET_COM_PINS); + if (ScreenInfo = ScreenSize128x32x1) or (ScreenInfo = ScreenSize96x16x1) then + WriteCommand($02) + else + WriteCommand($12); + + // Set Contrast + WriteCommand(CMD_SET_CONTRAST); + if (ScreenInfo = ScreenSize128x32x1) or (ScreenInfo = ScreenSize64x48x1) then + WriteCommand($8F) + else if ScreenInfo = ScreenSize96x16x1 then + begin + if FInternalVCC then + WriteCommand($AF) + else + WriteCommand($10); + end + else + begin + if FInternalVCC then + WriteCommand($CF) + else + WriteCommand($9F); + end; + + // Set Pre-Charge Period + WriteCommand(CMD_SET_PRECHARGE); + + if FInternalVCC then + WriteCommand($F1) + else + WriteCommand($22); + + // Set VCOMH Deselect Level + WriteCommand([CMD_SET_VCOM_DETECT, $40]); + + // Set all pixels OFF + WriteCommand(CMD_DISPLAY_ALL_ON_RESUME); + + // Set display not inverted + WriteCommand(CMD_NORMAL_DISPLAY); + Systemcore.Delay(10); + + // Set display On + WriteCommand(CMD_DISPLAY_ON); + + ReleaseCS; + + result:=true; +end; + +procedure TDisplay.PresentBuffer; +var + p,col,maxcol:byte; +begin + EngageCS; + + for p:=0 to 3 do + begin + col:=0; + maxcol:=(FScreenSize.X-1); + + WriteCommand(CMD_SET_COLUMN_LOWER OR ((col) AND $0F)); + WriteCommand(CMD_SET_COLUMN_UPPER OR (((col) shr 4) AND $0F)); + //WriteCommand([CMD_COLUMN_ADDRESS,0,ScreenInfo.Width-1]); + WriteCommand([CMD_PAGE_ADDRESS,pagemap[p],pagemap[p]]); + WriteData(FScreenBuffer+(FScreenSize.X*p+col),FScreenSize.X); + { + while (col<=maxcol) do + begin + WriteData(FScreenBuffer2[(FScreenSize.X*p)+col]); + Inc(col); + end; + } + end; + + ReleaseCS; +end; + +procedure TDisplay.EngageCS; +begin + if PinCS <> TNativePin.None then + GPIO.PinValue[PinCS]:=0; +end; + +procedure TDisplay.ReleaseCS; +begin + if PinCS <> TNativePin.None then + GPIO.PinValue[PinCS]:=1; +end; + +procedure TDisplay.Present; +begin + PresentBuffer; + //Present(IntRect(ZeroPoint2i, FLogicalSize)); +end; + + +function TDisplay.ReadPixel(const X, Y: word): TBWColor; +var + Location,Position: Byte; +begin + Result := 0; + + if (X > FScreenSize.X) OR (Y > FScreenSize.Y) then exit; + + Location := PByte(FScreenBuffer + (Cardinal(Y) div 8) * Cardinal(FScreenSize.X) + Cardinal(X))^; + Position := (1 shl (7-(Y mod 8))); + //Position := (1 shl (Y mod 8)); + + if ((Location AND Position) > 0) then Result := 1; +end; + +procedure TDisplay.WritePixel(const X, Y: word; const Color: TBWColor); +var + Location: PByte; + Position: Byte; + index:word; +begin + index:=X + ((Y shr 3) * FScreenSize.X); + if (index>=FScreenBufferSize) then exit; + + Location := (FScreenBuffer + PtrUInt(index)); + Position := (1 shl (7-(Y mod 8))); + //Position := (1 shl (Y mod 8)); + + if Color=1 then + Location^ := Location^ OR Position + else + Location^ := Location^ AND ($FF xor (Position)); +end; + +function TDisplay.GetScanline(const Index: word): Pointer; +begin + Result := Pointer(FScreenBuffer + (Cardinal(Index) shr 3) * Cardinal(FScreenSize.X)); +end; + +procedure TDisplay.ClrScr; +begin + FillChar(FScreenBuffer^, FScreenBufferSize, 0); +end; + +procedure TDisplay.InvertScr(Orientation:boolean); +begin + EngageCS; + if (Orientation) then WriteCommand(CMD_INVERSE_DISPLAY) else WriteCommand(CMD_NORMAL_DISPLAY); + ReleaseCS; +end; + +procedure TDisplay.DrawCharacter(const X, Line: word; const aChar: byte); +var + i:byte; + index:word; +begin + index:=Line * FScreenSize.X + X; + for i:=0 to 4 do + begin + if (index+i)>=FScreenBufferSize then break; + PByte(FScreenBuffer+index+i)^:=font[(aChar*5)+i]; + end; +end; + +procedure TDisplay.DrawString(const X, Line: word; const aString: string); +const + FONTWIDTH=6; +var + i:byte; + localX, localLine: longword; +begin + localX:=X; + localLine:=Line; + for i:=1 to Length(aString) do + begin + if ((localX+FONTWIDTH)>=FScreenSize.X) then + begin + localX:=0; + Inc(localLine); + end; + DrawCharacter(localX,localLine,Ord(aString[i])); + Inc(localX,FONTWIDTH); + end; +end; + +procedure TDisplay.GetDemo1; +begin + Move(ScreenBufferInit1,FScreenBuffer^,FScreenBufferSize); + PresentBuffer; +end; + +procedure TDisplay.GetDemo2; +begin + Move(ScreenBufferInit2,FScreenBuffer^,FScreenBufferSize); + PresentBuffer; +end; + +end. diff --git a/Source/MBF.Displays.SSD1306.pas b/Source/MBF.Displays.SSD1306.pas index 49ea0c9..a6951d1 100644 --- a/Source/MBF.Displays.SSD1306.pas +++ b/Source/MBF.Displays.SSD1306.pas @@ -17,9 +17,8 @@ interface {$INCLUDE MBF.Config.inc} uses - MBF.__CONTROLLERTYPE__.GPIO, - MBF.__CONTROLLERTYPE__.SPI, - MBF.Displays.CustomDisplay; + MBF.Displays.CustomDisplay, + MBF.Displays.CustomDisplaySPI; const ScreenSize128x64x1: TScreenInfo = diff --git a/Source/MBF.SAMCD.ADC.pas b/Source/MBF.SAMCD.ADC.pas new file mode 100644 index 0000000..3510781 --- /dev/null +++ b/Source/MBF.SAMCD.ADC.pas @@ -0,0 +1,225 @@ +unit MBF.SAMCD.ADC; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +{< Atmel SAMD series ADC functions. } + +interface + +{$include MBF.Config.inc} + +uses + MBF.SAMCD.Helpers, + MBF.SAMCD.GPIO; + +const +{$if defined(samd10) or defined(samd21)} + ADCMux = PORT_PMUX_B_Val; +{$elseif defined(samc21)} + ADCMux = PORT_PMUX_B_Val; + ADC1Mux = PORT_PMUX_B_Val; +{$else} + {$error Unknown Chip, please check mbf.boards.samd10.inc and then define ADC Mux here} +{$endif} + +type + TADCHelper = record helper for TADC_Registers + private + procedure SyncWait; + procedure ConversionWait; + function GetRawValue(const Channel: TPinIdentifier): Cardinal; + public + procedure Initialize; + property GetADCResult[const Channel: TPinIdentifier]:Cardinal read GetRawValue; + end; + +implementation + +uses + MBF.BitHelpers, + MBF.SAMCD.SystemCore; + +type + {$ifdef samd10} + TADCPin = (AIN0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,None); + {$endif} + {$ifdef samd21} + TADCPin = (AIN0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,AIN10,AIN11,AIN12,AIN13,AIN14,AIN15,AIN16,AIN17,AIN18,AIN19,None); + {$endif} + {$ifdef samc21} + TADCPin = (AIN0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,AIN10,AIN11,None); + TADC1Pin = (AIN0,AIN1,AIN2,AIN3,AIN4,AIN5,AIN6,AIN7,AIN8,AIN9,AIN10,AIN11,None); + {$endif} + + TADCPins = set of TADCPin; + {$ifdef samc21} + TADC1Pins = set of TADC1Pin; + {$endif} + +const + {$ifdef samd10} + TADCPinsMap : array[TADCPin] of TPinIdentifier=( + TNativePin.PA2,TNativePin.PA3,TNativePin.PA4,TNativePin.PA5,TNativePin.PA6,TNativePin.PA7,TNativePin.PA14,TNativePin.PA15, + TNativePin.PA10,TNativePin.PA11,TNativePin.None); + {$endif} + + {$ifdef samd21} + TADCPinsMap : array[TADCPin] of TPinIdentifier=( + TNativePin.PA2,TNativePin.PA3,TNativePin.PB8,TNativePin.PB9,TNativePin.PA4,TNativePin.PA5,TNativePin.PA6,TNativePin.PA7, + TNativePin.PB0,TNativePin.PB1,TNativePin.PB2,TNativePin.PB3,TNativePin.PB4,TNativePin.PB5,TNativePin.PB6,TNativePin.PB7, + TNativePin.PA8,TNativePin.PA9,TNativePin.PA10,TNativePin.PA11,TNativePin.None); + {$endif} + + {$ifdef samc21} + TADCPinsMap : array[TADCPin] of TPinIdentifier=( + TNativePin.PA2,TNativePin.PA3,TNativePin.PB8,TNativePin.PB9,TNativePin.PA4,TNativePin.PA5,TNativePin.PA6,TNativePin.PA7, + TNativePin.PA8,TNativePin.PA9,TNativePin.PA10,TNativePin.PA11,TNativePin.None); + TADC1PinsMap : array[TADC1Pin] of TPinIdentifier=( + TNativePin.PB0,TNativePin.PB1,TNativePin.PB2,TNativePin.PB3,TNativePin.PB8,TNativePin.PB9,TNativePin.PB4,TNativePin.PB5, + TNativePin.PB6,TNativePin.PB7,TNativePin.PA8,TNativePin.PA9,TNativePin.None); + {$endif} + +procedure TADCHelper.SyncWait; +begin + {$ifdef samd} + while (GetBit(Self.STATUS,ADC_STATUS_SYNCBUSY_Pos)) do begin end; // Wait for synchronization + {$endif} + {$ifdef samc} + while (Self.SYNCBUSY>0) do begin end; // Wait for synchronization + {$endif} +end; + +procedure TADCHelper.ConversionWait; +begin + while (NOT GetBit(Self.INTFLAG,ADC_INTFLAG_RESRDY_Pos)) do begin end; +end; + +procedure TADCHelper.Initialize; +var + bias,linearity:word; +begin + {$ifdef samd} + SetBit(PM.APBCMASK,PM_APBCMASK_ADC_Pos); + {$endif} + + {$ifdef samc} + case {%H-}longword(@Self) of + //{$ifdef has_adc}ADC_BASE : SetBit(MCLK.APBCMASK,MCLK_APBCMASK_ADC_Pos);{$endif} + {$ifdef has_adc0}ADC0_BASE : SetBit(MCLK.APBCMASK,MCLK_APBCMASK_ADC0_Pos);{$endif} + {$ifdef has_adc0}ADC1_BASE : SetBit(MCLK.APBCMASK,MCLK_APBCMASK_ADC1_Pos);{$endif} + end; + {$endif} + + // Switch ADC off to be sure + ClearBit(Self.CTRLA,ADC_CTRLA_ENABLE_Pos); + SyncWait; + + SystemCore.SetClockSourceTarget(GCLK_CLKCTRL_GEN_GCLK0,ADC_GCLK_ID); + + // Software Reset: Resets all registers in the ADC, except DBGCTRL + SetBit(Self.CTRLA,ADC_CTRLA_SWRST_Pos); + SyncWait; + + {$ifdef samd} + Self.REFCTRL:=(ADC_REFCTRL_REFSEL_INTVCC1 OR ADC_REFCTRL_REFCOMP); + {$endif} + {$ifdef samc} + Self.REFCTRL:=(ADC_REFCTRL_REFSEL_INTVCC2 OR ADC_REFCTRL_REFCOMP); + {$endif} + + SyncWait; + + {$ifdef samd} + Self.CTRLB:=(ADC_CTRLB_RESSEL_16BIT OR ADC_CTRLB_PRESCALER_DIV512);// OR ADC_CTRLB_FREERUN; + {$endif} + {$ifdef samc} + Self.CTRLB:=(ADC_CTRLB_PRESCALER_DIV256); + Self.CTRLC:=(ADC_CTRLB_RESSEL_16BIT); + {$endif} + SyncWait; + + Self.AVGCTRL:=ADC_AVGCTRL_SAMPLENUM_256; + SyncWait; + + //Sample time in half clock cycles will be set before conversion, set to max (slow but high impedance) + Self.SAMPCTRL:=$3f; + SyncWait; + + Self.INPUTCTRL:= + (ADC_INPUTCTRL_MUXPOS_BANDGAP_Val shl ADC_INPUTCTRL_MUXPOS_Pos) OR // Default: Internal bandgap + (ADC_INPUTCTRL_MUXNEG_GND_Val shl ADC_INPUTCTRL_MUXNEG_Pos) // Default: Internal Ground + {$ifdef samd} + OR ADC_INPUTCTRL_GAIN_DIV2 + {$endif} + ; + SyncWait; + + {$ifdef samd} + bias := ReadCal(NVM_ADC_BIASCAL_POS,NVM_ADC_BIASCAL_SIZE); + linearity := ReadCal(NVM_ADC_LINEARITY_POS,NVM_ADC_LINEARITY_SIZE); + PutValue(Self.CALIB,ADC_CALIB_BIAS_CAL_Msk,bias,ADC_CALIB_BIAS_CAL_Pos); + SyncWait; + PutValue(Self.CALIB,ADC_CALIB_LINEARITY_CAL_Msk,linearity,ADC_CALIB_LINEARITY_CAL_Pos); + SyncWait; + {$endif} + + + //SetBit(Self.CTRLA,ADC_CTRLA_ENABLE_Pos); + Self.CTRLA:=ADC_CTRLA_ENABLE; + SyncWait; +end; + +function TADCHelper.GetRawValue(const Channel: TPinIdentifier): Cardinal; +var + aPin,aChannel:TADCPin; +begin + + result:=0; + + // find correct ADC channel + aChannel:=TADCPin.None; + for aPin in TADCPins do + begin + if TADCPinsMap[aPin]=Channel then + begin + aChannel:=aPin; + break; + end; + end; + + if aChannel=TADCPin.None then exit; + + SyncWait; + + //Set channel to measure + PutValue(Self.INPUTCTRL,ADC_INPUTCTRL_MUXPOS_Msk,Ord(aChannel),ADC_INPUTCTRL_MUXPOS_Pos); + SyncWait; + //Dump first result + //Trigger conversion + //Self.SWTRIG:=ADC_SWTRIG_START; + SetBit(Self.SWTRIG,ADC_SWTRIG_START_Pos); + // Clear result ready flag + Self.INTFLAG := ADC_INTFLAG_RESRDY; + SyncWait; + + //Trigger conversion + //Self.SWTRIG:=(ADC_SWTRIG_START {OR ADC_SWTRIG_FLUSH}); + SetBit(Self.SWTRIG,ADC_SWTRIG_START_Pos); + SyncWait; + ConversionWait; + // reading a result also clear the ADC.INTFLAG -> ADC_INTFLAG_RESRDY flag + //result:=(ADC.RESULT * 1000) DIV (4096 DIV 4); + result:=(Self.RESULT); +end; + +end. diff --git a/Source/MBF.SAMCD.GPIO.pas b/Source/MBF.SAMCD.GPIO.pas index a44ff1b..dd27d70 100644 --- a/Source/MBF.SAMCD.GPIO.pas +++ b/Source/MBF.SAMCD.GPIO.pas @@ -96,7 +96,15 @@ TArduinoPin = record A4 = TNativePin.PA5; A5 = TNativePin.PB2; end; {$endif} - {$if defined(SAMD20XPRO) or defined(SAMD21XPRO) } + {$if defined(SAMD20XPRO)} + type + TArduinoPin = record + const + None=-1; + D13= TNativePin.PA14; // just for blinky to work + end; + {$endif} + {$if defined(SAMD21XPRO) } // Arduino Pins via AtmelXPlained Shield Adapter type TArduinoPin = record @@ -130,6 +138,68 @@ TArduinoPin = record {$endif} {$endif} + {$ifdef has_samd20_xplained_pro} + const + LED0 = TNativePin.PA14; + SW0 = TNativePin.PA15; + + // Extension header #1 pin definitions + EXT1_PIN_3 = TNativePin.PB0; + EXT1_PIN_4 = TNativePin.PB1; + EXT1_PIN_5 = TNativePin.PB6; + EXT1_PIN_6 = TNativePin.PB7; + EXT1_PIN_7 = TNativePin.PB2; + EXT1_PIN_8 = TNativePin.PB3; + EXT1_PIN_9 = TNativePin.PB4; + EXT1_PIN_10 = TNativePin.PB5; + EXT1_PIN_11 = TNativePin.PA8; + EXT1_PIN_12 = TNativePin.PA9; + EXT1_PIN_13 = TNativePin.PB9; + EXT1_PIN_14 = TNativePin.PB8; + EXT1_PIN_15 = TNativePin.PA5; + EXT1_PIN_16 = TNativePin.PA6; + EXT1_PIN_17 = TNativePin.PA4; + EXT1_PIN_18 = TNativePin.PA7; + + // Extension header #2 pin definitions + EXT2_PIN_3 = TNativePin.PA10; + EXT2_PIN_4 = TNativePin.PA11; + EXT2_PIN_5 = TNativePin.PA20; + EXT2_PIN_6 = TNativePin.PA21; + EXT2_PIN_7 = TNativePin.PA22; + EXT2_PIN_8 = TNativePin.PA23; + EXT2_PIN_9 = TNativePin.PB14; + EXT2_PIN_10 = TNativePin.PB15; + EXT2_PIN_11 = TNativePin.PA8; + EXT2_PIN_12 = TNativePin.PA9; + EXT2_PIN_13 = TNativePin.PB13; + EXT2_PIN_14 = TNativePin.PB12; + EXT2_PIN_15 = TNativePin.PA17; + EXT2_PIN_16 = TNativePin.PA18; + EXT2_PIN_17 = TNativePin.PA16; + EXT2_PIN_18 = TNativePin.PA19; + + // Extension header #3 pin definitions + EXT3_PIN_3 = TNativePin.PA2; + EXT3_PIN_4 = TNativePin.PA3; + EXT3_PIN_5 = TNativePin.PB30; + EXT3_PIN_6 = TNativePin.PA15; + EXT3_PIN_7 = TNativePin.PA12; + EXT3_PIN_8 = TNativePin.PA13; + EXT3_PIN_9 = TNativePin.PA28; + EXT3_PIN_10 = TNativePin.PA27; + EXT3_PIN_11 = TNativePin.PA8; + EXT3_PIN_12 = TNativePin.PA9; + EXT3_PIN_13 = TNativePin.PB11; + EXT3_PIN_14 = TNativePin.PB10; + EXT3_PIN_15 = TNativePin.PB17; + EXT3_PIN_16 = TNativePin.PB22; + EXT3_PIN_17 = TNativePin.PB16; + EXT3_PIN_18 = TNativePin.PB23; + + {$endif} + + {$ifdef has_samd21_xplained_pro} const LED0 = TNativePin.PB30; @@ -278,6 +348,9 @@ TGPIO_Registers = record procedure SetPinValue(const Pin: TPinIdentifier; const Value: TPinValue); procedure TogglePinValue(const Pin: TPinIdentifier); + procedure SetPinLevelHigh(const Pin: TPinIdentifier); + procedure SetPinLevelLow(const Pin: TPinIdentifier); + property PinMux[const Pin: TPinIdentifier] : TPinMux write SetPinMux; property PinMode[const Pin : TPinIdentifier] : TPinMode read GetPinMode write SetPinMode; property PinDrive[const Pin : TPinIdentifier] : TPinDrive read GetPinDrive write SetPinDrive; @@ -378,6 +451,8 @@ procedure TGPIO_Registers.SetPinMode(const Pin: TPinIdentifier; const Value: TPi PGPIOPort^.DIRSET:=GPIOMask; // enable input buffer for the I/O pin: input value will be sampled when required SetBit(aPINCFG^,PORT_PINCFG_INEN_Pos); + // Cannot use a pullup if the output driver is enabled + ClearBit(aPINCFG^,PORT_PINCFG_PULLEN_Pos); end; end; @@ -411,6 +486,16 @@ procedure TGPIO_Registers.TogglePinValue(const Pin: TPinIdentifier); PGPIOPort^.OUTTGL:=GPIOMask; end; +procedure TGPIO_Registers.SetPinLevelHigh(const Pin: TPinIdentifier); +begin + SetPinValue(Pin,1); +end; + +procedure TGPIO_Registers.SetPinLevelLow(const Pin: TPinIdentifier); +begin + SetPinValue(Pin,0); +end; + function TGPIO_Registers.GetPinDrive(const Pin: TPinIdentifier): TPinDrive; var aPINCFG:PByte; diff --git a/Source/MBF.SAMCD.Helpers.pas b/Source/MBF.SAMCD.Helpers.pas index 14339ce..2514f22 100644 --- a/Source/MBF.SAMCD.Helpers.pas +++ b/Source/MBF.SAMCD.Helpers.pas @@ -15,6 +15,7 @@ interface {$i atsamcd/samcd-tc.inc} function ReadCal(Position,Size:byte):longword; +function DivCeiling(a,b:longint):longint; implementation @@ -23,5 +24,10 @@ function ReadCal(Position,Size:byte):longword; result:=(({%H-}plongword(NVMCTRL_OTP4+(Position DIV 32))^ shr (Position MOD 32)) AND (1 shl Size)); end; +function DivCeiling(a,b:longint):longint; +begin + result:=(((a) + (b) - 1) DIV (b)); +end; + end. diff --git a/Source/MBF.SAMCD.I2C.pas b/Source/MBF.SAMCD.I2C.pas new file mode 100644 index 0000000..5c2dd03 --- /dev/null +++ b/Source/MBF.SAMCD.I2C.pas @@ -0,0 +1,431 @@ +unit MBF.SAMCD.I2C; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +{< Atmel SAMD series GPIO functions. } + +interface + +{$include MBF.Config.inc} + +uses + MBF.SAMCD.Helpers, + MBF.SAMCD.SerCom; + +type + TI2C_Registers = record + //PAD[0] Digital I/O SDA + //PAD[1] Digital I/O SCL + //PAD[2] Digital I/O SDA_OUT (4-wire) + //PAD[3] Digital I/O SDC_OUT (4-wire) + strict private type + TSercomWireBusState=record + const + WIRE_UNKNOWN_STATE=0; + WIRE_IDLE_STATE=1; + WIRE_OWNER_STATE=2; + WIRE_BUSY_STATE=3; + end; + TSercomMasterCommandWire=record + const + WIRE_MASTER_ACT_NO_ACTION=0; + WIRE_MASTER_ACT_REPEAT_START=1; + WIRE_MASTER_ACT_READ=2; + WIRE_MASTER_ACT_STOP=3; + end; + strict private const + I2C_TRANSFER_WRITE=0; + I2C_TRANSFER_READ=1; + T_RISE=215; // In ns; depends on the board/pull-up-resistors + SPEED100KHZ=100; + strict private + FSerCom:TSerCom; + procedure SetPort(aPort:TPortIdentifier); + function GetBaud(const Value: Cardinal):cardinal; + function isMasterWIRE:boolean; + function isSlaveWIRE:boolean; + function isBusIdleWIRE:boolean; + function isBusOwnerWIRE:boolean; + function isDataReadyWIRE:boolean; + function isStopDetectedWIRE:boolean; + function isRestartDetectedWIRE:boolean; + function isAddressMatch:boolean; + function isMasterReadOperationWIRE:boolean; + function isRXNackReceivedWIRE:boolean; + function errorOnWIRE:boolean; + function busErrorOnWIRE:boolean; + function busClockHoldWIRE:boolean; + function availableWIRE:boolean; + function availableMasterWIRE:boolean; + function readDataWIRE:byte; + procedure resetWIRE; + procedure enableWIRE; + procedure disableWIRE; + procedure prepareNackBitWIRE; + procedure prepareAckBitWIRE; + procedure prepareCommandBitsWire(aCommand:byte); + function startTransmissionWIRE(const Address:byte;const aDirection:byte):boolean; + function stopTransmissionWIRE:boolean; + function sendDataMasterWIRE(data:byte):boolean; + function sendDataSlaveWIRE(data:byte):boolean; + public + procedure initMasterWIRE(const aPort:TPortIdentifier;const Speed:cardinal=SPEED100KHZ); + function Read(const Address:byte; const buffer: pointer; const length: byte; const stopBit: boolean):byte; + function Write(const Address:byte; const buffer: pointer; const length: integer; const stopBit: boolean):boolean; + function ReadByte(const Address:byte; out aByte:byte):boolean; + function WriteByte(const Address:byte; const aByte:byte):boolean; + function WriteWord(const Address:byte; const aWord:word):boolean; + function WriteLongWord(const Address:byte; const aLongWord:longword):boolean; + end; + +implementation + +uses + MBF.BitHelpers, + MBF.SAMCD.SystemCore; + +function TI2C_Registers.isMasterWIRE:boolean; +begin + result:=((FSerCom.PSerComRegisters^.I2CM.CTRLA AND SERCOM_MODE_Msk)=SERCOM_MODE_I2C_MASTER); +end; + +function TI2C_Registers.isSlaveWIRE:boolean; +begin + result:=((FSerCom.PSerComRegisters^.I2CM.CTRLA AND SERCOM_MODE_Msk)=SERCOM_MODE_I2C_SLAVE); +end; + +function TI2C_Registers.isBusIdleWIRE:boolean; +begin + result:=((FSerCom.PSerComRegisters^.I2CM.STATUS AND SERCOM_I2CM_STATUS_BUSSTATE_Msk)=(TSercomWireBusState.WIRE_IDLE_STATE shl SERCOM_I2CM_STATUS_BUSSTATE_Pos)); +end; + +function TI2C_Registers.isBusOwnerWIRE:boolean; +begin + result:=((FSerCom.PSerComRegisters^.I2CM.STATUS AND SERCOM_I2CM_STATUS_BUSSTATE_Msk)=(TSercomWireBusState.WIRE_OWNER_STATE shl SERCOM_I2CM_STATUS_BUSSTATE_Pos)); +end; + +function TI2C_Registers.isDataReadyWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CS.INTFLAG,SERCOM_I2CS_INTFLAG_DRDY_Pos); +end; + +function TI2C_Registers.isStopDetectedWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CS.INTFLAG,SERCOM_I2CS_INTFLAG_PREC_Pos); +end; + +function TI2C_Registers.isRestartDetectedWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CS.STATUS,SERCOM_I2CS_STATUS_SR_Pos); +end; + +function TI2C_Registers.isAddressMatch:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CS.INTFLAG,SERCOM_I2CS_INTFLAG_AMATCH_Pos); +end; + +function TI2C_Registers.isMasterReadOperationWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CS.STATUS,SERCOM_I2CS_STATUS_DIR_Pos); +end; + +function TI2C_Registers.isRXNackReceivedWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CM.STATUS,SERCOM_I2CM_STATUS_RXNACK_Pos); +end; + +function TI2C_Registers.errorOnWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CM.INTFLAG,SERCOM_I2CM_INTFLAG_ERROR_Pos); + // clear the error flag + SetBit(FSerCom.PSerComRegisters^.I2CM.INTFLAG,SERCOM_I2CM_INTFLAG_ERROR_Pos); +end; + +function TI2C_Registers.busErrorOnWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CM.STATUS,SERCOM_I2CM_STATUS_BUSERR_Pos); +end; + +function TI2C_Registers.busClockHoldWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CM.STATUS,SERCOM_I2CM_STATUS_CLKHOLD_Pos); +end; + + +function TI2C_Registers.availableWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CM.INTFLAG,SERCOM_I2CM_INTFLAG_SB_Pos); +end; + +function TI2C_Registers.availableMasterWIRE:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.I2CM.INTFLAG,SERCOM_I2CM_INTFLAG_MB_Pos); +end; + +function TI2C_Registers.readDataWIRE:byte; +begin + FSerCom.SyncWait; + result:=FSerCom.PSerComRegisters^.I2CM.DATA; + while (NOT availableWIRE) do begin end; +end; + +procedure TI2C_Registers.resetWIRE; +begin + FSerCom.Reset; +end; + +procedure TI2C_Registers.enableWIRE; +begin + FSerCom.Enable; + // Go (by force) from unknow busstate to idle + PutValue(FSerCom.PSerComRegisters^.I2CM.STATUS,SERCOM_I2CM_STATUS_BUSSTATE_Msk,TSercomWireBusState.WIRE_IDLE_STATE,SERCOM_I2CM_STATUS_BUSSTATE_Pos); + FSerCom.SyncWait; +end; + +procedure TI2C_Registers.disableWIRE; +begin + FSerCom.Disable; +end; + +procedure TI2C_Registers.initMasterWIRE(const aPort:TPortIdentifier; const Speed:cardinal=SPEED100KHZ); +var + baud,baudlow:cardinal; +begin + SetPort(aPort); + + //Enable Smart Mode: (N)ACK is sent when DATA.DATA is read) + //Do not use smart mode (yet) + //FSerCom.PSerComRegisters^.I2CM.CTRLB:=SERCOM_I2CM_CTRLB_SMEN; + //FSerCom.SyncWait; + + baudlow:=GetBaud(Speed); + baud:=(baudlow DIV 2); + baudlow:=baudlow-baud; + FSerCom.PSerComRegisters^.I2CM.BAUD:=(baudlow shl 8) OR baud; + FSerCom.SyncWait; + + FSerCom.PSerComRegisters^.I2CM.CTRLA:= + SERCOM_MODE_I2C_MASTER OR + //SERCOM_I2CM_CTRLA_SCLSM OR //SCL stretch only after ACK bit. + ((SERCOM_I2CM_CTRLA_SDAHOLD_Msk AND ((3) shl SERCOM_I2CM_CTRLA_SDAHOLD_Pos))); + FSerCom.SyncWait; + + enableWIRE; +end; + +procedure TI2C_Registers.prepareNackBitWIRE; +begin + SetBit(FSerCom.PSerComRegisters^.I2CM.CTRLB,SERCOM_I2CM_CTRLB_ACKACT_Pos); + FSerCom.SyncWait; +end; + +procedure TI2C_Registers.prepareAckBitWIRE; +begin + ClearBit(FSerCom.PSerComRegisters^.I2CM.CTRLB,SERCOM_I2CM_CTRLB_ACKACT_Pos); + FSerCom.SyncWait; +end; + +procedure TI2C_Registers.prepareCommandBitsWire(aCommand:byte); +begin + PutValue(FSerCom.PSerComRegisters^.I2CM.CTRLB,SERCOM_I2CM_CTRLB_CMD_Msk,aCommand,SERCOM_I2CM_CTRLB_CMD_Pos); + FSerCom.SyncWait; +end; + + +function TI2C_Registers.startTransmissionWIRE(const Address:byte;const aDirection:byte):boolean; +begin + result:=false; + + FSerCom.SyncWait; + + // clear the error flag + errorOnWIRE; + + // Wait idle or owner bus mode + while ( (NOT isBusIdleWIRE) AND (NOT isBusOwnerWIRE) ) do begin end; + + prepareAckBitWIRE; + + // Send start and address and R/W bit + FSerCom.PSerComRegisters^.I2CM.ADDR:=((Address shl 1) OR aDirection); + FSerCom.SyncWait; + + if aDirection=I2C_TRANSFER_READ then + begin + while (NOT availableWIRE) do begin end; + // If the slave NACKS the address, the MB bit will be set. + // In that case, send a stop condition and return false. + if availableMasterWIRE then + begin + stopTransmissionWIRE; + exit; + end; + end + else + begin + while (NOT availableMasterWIRE) do begin end; + //while (NOT busClockHoldWIRE) do begin end; + end; + + if ( + isRXNackReceivedWIRE + OR + errorOnWIRE + ) then + begin + stopTransmissionWIRE; + exit; + end; + + result:=true; +end; + +function TI2C_Registers.stopTransmissionWIRE:boolean; +begin + result:=false; + if (availableMasterWIRE OR availableWIRE) then + begin + prepareCommandBitsWire(TSercomMasterCommandWire.WIRE_MASTER_ACT_STOP); // Send Stop + result:=true; + end; +end; + +function TI2C_Registers.sendDataMasterWIRE(data:byte):boolean; +begin + result:=false; + + //Send data + FSerCom.PSerComRegisters^.I2CM.DATA := data; + FSerCom.SyncWait; + + //Wait transmission successful + while (NOT availableMasterWIRE) do + begin + // If a bus error occurs, the MB bit may never be set. + // Check the bus error bit and bail if it's set. + if busErrorOnWIRE then exit; + end; + + //Problems on line? nack received? + if (isRXNackReceivedWIRE) then exit; + + result:=true; +end; + +function TI2C_Registers.sendDataSlaveWIRE(data:byte):boolean; +begin + result:=false; + + //Send data + FSerCom.PSerComRegisters^.I2CS.DATA := data; + FSerCom.SyncWait; + + //Problems on line? nack received? + if ((isRXNackReceivedWIRE) OR (NOT isDataReadyWIRE)) then exit; + + result:=true; +end; + + +procedure TI2C_Registers.SetPort(aPort:TPortIdentifier); +begin + FSerCom.Initialize(aPort); + FSerCom.SetCoreClockSource(GCLK_CLKCTRL_GEN_GCLK0); // use gclk0 at 48MHz +end; + + +function TI2C_Registers.GetBaud(const Value: Cardinal):cardinal; +var + tmp_baud, correction:longword; +begin + tmp_baud := DivCeiling(SystemCore.CPUFrequency,(1000*Value)); + correction := (10 + (((SystemCore.CPUFrequency DIV 1000)*T_RISE) DIV 1000000)); + result:= tmp_baud-correction; +end; + +function TI2C_Registers.Read(const Address:byte; const buffer: pointer; const length: byte; const stopBit: boolean):byte; +var + i:byte; +begin + i:=0; + if length>0 then + begin + if startTransmissionWIRE(Address,I2C_TRANSFER_READ) then + begin + while i<length do + begin + if i=(length-1) then + begin + prepareNackBitWIRE; // Final read: Prepare Nack + prepareCommandBitsWire(TSercomMasterCommandWire.WIRE_MASTER_ACT_READ); + end + else + begin + prepareAckBitWIRE; // Normal read: Prepare Ack + prepareCommandBitsWire(TSercomMasterCommandWire.WIRE_MASTER_ACT_READ); + end; + PByte(buffer+i)^:=readDataWIRE; // Read data and send the (N)ACK + Inc(i); + end; + end; + end; + + if (stopBit) then stopTransmissionWIRE; + + result:=i; +end; + +function TI2C_Registers.ReadByte(const Address:byte; out aByte:byte):boolean; +begin + result:=(Read(Address, @aByte, 1, true)=1); +end; + +function TI2C_Registers.Write(const Address:byte; const buffer: pointer; const length: integer; const stopBit: boolean):boolean; +var + i:longword; +begin + result:=startTransmissionWIRE(Address,I2C_TRANSFER_WRITE); + + if result then + begin + for i:=0 to (length-1) do + begin + result:=sendDataMasterWIRE(PByte(buffer+i)^); + if not result then break; + end; + end; + + if ((stopBit) OR (NOT result)) then + begin + if (NOT result) then prepareNackBitWIRE; + stopTransmissionWIRE; + end; +end; + +function TI2C_Registers.WriteByte(const Address:byte; const aByte:byte):boolean; +begin + result:=Write(Address, @aByte, 1,true); +end; + +function TI2C_Registers.WriteWord(const Address:byte; const aWord:word):boolean; +begin + result:=Write(Address, @aWord, SizeOf(aWord),true); +end; + +function TI2C_Registers.WriteLongWord(const Address:byte; const aLongWord:longword):boolean; +begin + result:=Write(Address, @aLongWord, SizeOf(aLongWord),true); +end; + + +end. diff --git a/Source/MBF.SAMCD.SPI.pas b/Source/MBF.SAMCD.SPI.pas new file mode 100644 index 0000000..5ae08dc --- /dev/null +++ b/Source/MBF.SAMCD.SPI.pas @@ -0,0 +1,118 @@ +unit MBF.SAMCD.SPI; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +{< Atmel SAMD series GPIO functions. } + +interface + +{$include MBF.Config.inc} + +uses + MBF.SAMCD.Helpers, + MBF.SAMCD.SerCom; + +type + TSPI_Registers = record + strict private type + strict private const + DEFAULT_SPI_FREQUENCY=100000; + strict private + FSerCom:TSerCom; + procedure SetPort(aPort:TPortIdentifier); + function TXC_Ready:boolean; + function DRE_Ready:boolean; + function RXC_Ready:boolean; + procedure WriteSingle(aData:word); + function ReadSingle:word; + public + procedure Initialize(const aPort:TPortIdentifier;const Speed:cardinal;aDIPO,aDOPO:byte); + procedure Write(const buffer: pointer; const length: longword); + + end; + +implementation + +uses + MBF.BitHelpers, + MBF.SAMCD.SystemCore; + +procedure TSPI_Registers.SetPort(aPort:TPortIdentifier); +begin + FSerCom.Initialize(aPort); + FSerCom.SetCoreClockSource(GCLK_CLKCTRL_GEN_GCLK0); // use gclk0 +end; + +procedure TSPI_Registers.Initialize(const aPort:TPortIdentifier;const Speed:cardinal;aDIPO,aDOPO:byte); +begin + SetPort(aPort); + + FSerCom.PSerComRegisters^.SPI.CTRLA:= + (SERCOM_SPI_CTRLA_DIPO_Msk AND ((aDIPO) shl SERCOM_SPI_CTRLA_DIPO_Pos)) OR + (SERCOM_SPI_CTRLA_DOPO_Msk AND ((aDOPO) shl SERCOM_SPI_CTRLA_DOPO_Pos)) OR + SERCOM_MODE_SPI_MASTER; + FSerCom.SyncWait; + + // Set character size (8=0) + //PutValue(FSerCom.PSerComRegisters^.SPI.CTRLB,SERCOM_SPI_CTRLB_CHSIZE_Msk,0,SERCOM_SPI_CTRLB_CHSIZE_Pos); + //FSerCom.SyncWait; + + //SetBit(FSerCom.PSerComRegisters^.SPI.CTRLB,SERCOM_SPI_CTRLB_MSSEN_Pos); + //FSerCom.SyncWait; + + //SetBit(FSerCom.PSerComRegisters^.SPI.CTRLB,SERCOM_SPI_CTRLB_RXEN_Pos); //RX_EN + //FSerCom.SyncWait; + + FSerCom.PSerComRegisters^.SPI.BAUD := (SystemCore.CPUFrequency DIV (2*Speed)) - 1; + FSerCom.SyncWait; + + FSerCom.Enable; +end; + +function TSPI_Registers.TXC_Ready:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.SPI.INTFLAG,SERCOM_SPI_INTFLAG_TXC_Pos); +end; + +function TSPI_Registers.DRE_Ready:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.SPI.INTFLAG,SERCOM_SPI_INTFLAG_DRE_Pos); +end; + +function TSPI_Registers.RXC_Ready:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.SPI.INTFLAG,SERCOM_SPI_INTFLAG_RXC_Pos); +end; + +procedure TSPI_Registers.WriteSingle(aData:word); +begin + while (NOT DRE_Ready) do begin end; + FSerCom.PSerComRegisters^.SPI.DATA := aData; + while (NOT TXC_Ready) do begin end; +end; + +function TSPI_Registers.ReadSingle:word; +begin + while (NOT RXC_Ready) do begin end; + result:=FSerCom.PSerComRegisters^.SPI.DATA; +end; + +procedure TSPI_Registers.Write(const buffer: pointer; const length: longword); +var + i:longword; +begin + for i:=0 to (length-1) do WriteSingle(PByte(buffer+i)^); +end; + + +end. diff --git a/Source/MBF.SAMCD.SerCom.pas b/Source/MBF.SAMCD.SerCom.pas new file mode 100644 index 0000000..11d2ef2 --- /dev/null +++ b/Source/MBF.SAMCD.SerCom.pas @@ -0,0 +1,225 @@ +unit MBF.SAMCD.SerCom; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +{< Atmel SAMD series GPIO functions. } + +interface + +{$include MBF.Config.inc} + +uses + MBF.SAMCD.Helpers; + +type + TPortIdentifier=-1..8; + +type + TSerCom = record + strict private type + pSCR = ^TSercom_Registers; + strict private + FPort:TPortIdentifier; + FPSerComRegisters:pSCR; + //property Port:TPortIdentifier read FPort; + strict private const + // Indexed mapping to SerCom registers. + SerComMem: array[0..8] of pSCR =( + {$ifdef has_sercom0}@SerCom0{$else}nil{$endif}, + {$ifdef has_sercom1}@SerCom1{$else}nil{$endif}, + {$ifdef has_sercom2}@SerCom2{$else}nil{$endif}, + {$ifdef has_sercom3}@SerCom3{$else}nil{$endif}, + {$ifdef has_sercom4}@SerCom4{$else}nil{$endif}, + {$ifdef has_sercom5}@SerCom5{$else}nil{$endif}, + {$ifdef has_sercom6}@SerCom6{$else}nil{$endif}, + {$ifdef has_sercom7}@SerCom7{$else}nil{$endif}, + {$ifdef has_sercom8}@SerCom8{$else}nil{$endif} + ); + public + procedure Initialize(aPort:TPortIdentifier); + procedure Close; + procedure SetCoreClockSource(aClockSource:longword); + procedure Reset; + procedure Enable; + procedure Disable; + procedure SyncWait; + property PSerComRegisters:pSCR read FPSerComRegisters; + end; + +implementation + +uses + MBF.BitHelpers, + MBF.SAMCD.SystemCore; + +procedure TSerCom.Initialize(aPort:TPortIdentifier); +begin + if aPort=-1 then exit; + FPort:=aPort; + {$ifdef samd} + case FPort of + {$ifdef has_sercom0}0: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM0_Pos);{$endif} + {$ifdef has_sercom1}1: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM1_Pos);{$endif} + {$ifdef has_sercom2}2: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM2_Pos);{$endif} + {$ifdef has_sercom3}3: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM3_Pos);{$endif} + {$ifdef has_sercom4}4: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM4_Pos);{$endif} + {$ifdef has_sercom5}5: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM5_Pos);{$endif} + {$ifdef has_sercom6}6: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM6_Pos);{$endif} + {$ifdef has_sercom7}7: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM7_Pos);{$endif} + {$ifdef has_sercom8}8: SetBit(PM.APBCMASK,PM_APBCMASK_SERCOM8_Pos);{$endif} + else + begin + FPort:=-1; + exit; + end; + end; + {$endif} + {$ifdef samc} + case FPort of + {$ifdef has_sercom0}0: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM0_Pos);{$endif} + {$ifdef has_sercom1}1: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM1_Pos);{$endif} + {$ifdef has_sercom2}2: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM2_Pos);{$endif} + {$ifdef has_sercom3}3: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM3_Pos);{$endif} + {$ifdef has_sercom4}4: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM4_Pos);{$endif} + {$ifdef has_sercom5}5: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM5_Pos);{$endif} + {$ifdef has_sercom6}6: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM6_Pos);{$endif} + {$ifdef has_sercom7}7: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM7_Pos);{$endif} + {$ifdef has_sercom8}8: SetBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM8_Pos);{$endif} + else + begin + FPort:=-1; + exit; + end; + end; + {$endif} + + FPSerComRegisters:=SerComMem[FPort]; + Disable; + Reset; +end; + +procedure TSerCom.Close; +begin + if FPort=-1 then exit; + Disable; + {$ifdef samd} + case FPort of + {$ifdef has_sercom0}0: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM0_Pos);{$endif} + {$ifdef has_sercom1}1: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM1_Pos);{$endif} + {$ifdef has_sercom2}2: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM2_Pos);{$endif} + {$ifdef has_sercom3}3: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM3_Pos);{$endif} + {$ifdef has_sercom4}4: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM4_Pos);{$endif} + {$ifdef has_sercom5}5: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM5_Pos);{$endif} + {$ifdef has_sercom6}6: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM6_Pos);{$endif} + {$ifdef has_sercom7}7: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM7_Pos);{$endif} + {$ifdef has_sercom8}8: ClearBit(PM.APBCMASK,PM_APBCMASK_SERCOM8_Pos);{$endif} + end; + {$endif} + {$ifdef samc} + case FPort of + {$ifdef has_sercom0}0: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM0_Pos);{$endif} + {$ifdef has_sercom1}1: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM1_Pos);{$endif} + {$ifdef has_sercom2}2: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM2_Pos);{$endif} + {$ifdef has_sercom3}3: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM3_Pos);{$endif} + {$ifdef has_sercom4}4: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM4_Pos);{$endif} + {$ifdef has_sercom5}5: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM5_Pos);{$endif} + {$ifdef has_sercom6}6: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM6_Pos);{$endif} + {$ifdef has_sercom7}7: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM7_Pos);{$endif} + {$ifdef has_sercom8}8: ClearBit(MCLK.APBCMASK,MCLK_APBCMASK_SERCOM8_Pos);{$endif} + else + begin + FPort:=-1; + exit; + end; + end; + {$endif} + + FPort:=-1; +end; + +procedure TSerCom.SetCoreClockSource(aClockSource:longword); +var + aID:longword; +begin + if FPort=-1 then exit; + case FPort of + {$ifdef has_sercom0}0: aID:=SERCOM0_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom1}1: aID:=SERCOM1_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom2}2: aID:=SERCOM2_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom3}3: aID:=SERCOM3_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom4}4: aID:=SERCOM4_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom5}5: aID:=SERCOM5_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom6}6: aID:=SERCOM6_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom7}7: aID:=SERCOM7_GCLK_ID_CORE;{$endif} + {$ifdef has_sercom8}8: aID:=SERCOM8_GCLK_ID_CORE;{$endif} + else + begin + exit; + end; + end; + SystemCore.SetClockSourceTarget(aClockSource,aID); +end; + +procedure TSerCom.Reset; +begin + if (NOT Assigned(FPSerComRegisters)) then exit; + // Reset is on the same spot for every configuration, so just choose one : usart + SetBit(FPSerComRegisters^.USART.CTRLA,SERCOM_SWRST_Pos); + while (GetBit(FPSerComRegisters^.USART.CTRLA,SERCOM_SWRST_Pos)) do begin end; + // All syncbusy registers are at offset $1C, so just choose one ... usart ... ;-) + {$ifdef samd20} + while ((FPSerComRegisters^.USART.STATUS AND (1 shl 15))>0) do begin end; + {$else} + while ((FPSerComRegisters^.USART.SYNCBUSY AND $1)>0) do begin end; + {$endif} +end; + +procedure TSerCom.Enable; +begin + if (NOT Assigned(FPSerComRegisters)) then exit; + // Enable is on the same spot for every configuration, so just choose one : usart + SetBit(FPSerComRegisters^.USART.CTRLA,SERCOM_ENABLE_Pos); + // All syncbusy registers are at offset $1C, so just choose one ... usart ... ;-) + {$ifdef samd20} + while ((FPSerComRegisters^.USART.STATUS AND (1 shl 15))>0) do begin end; + {$else} + while ((FPSerComRegisters^.USART.SYNCBUSY AND $2)>0) do begin end; + {$endif} +end; + +procedure TSerCom.Disable; +begin + if (NOT Assigned(FPSerComRegisters)) then exit; + // Disable is on the same spot for every configuration, so just choose one : usart + ClearBit(FPSerComRegisters^.USART.CTRLA,SERCOM_ENABLE_Pos); + // All syncbusy registers are at offset $1C, so just choose one ... usart ... ;-) + {$ifdef samd20} + while ((FPSerComRegisters^.USART.STATUS AND (1 shl 15))>0) do begin end; + {$else} + while ((FPSerComRegisters^.USART.SYNCBUSY AND $2)>0) do begin end; + {$endif} +end; + +procedure TSerCom.SyncWait; +begin + if (NOT Assigned(FPSerComRegisters)) then exit; + // All syncbusy registers are at offset $1C, so just choose one ... usart ... ;-) + //while ((FPSerComRegisters^.USART.SYNCBUSY AND $7)>0) do begin end; + {$ifdef samd20} + while ((FPSerComRegisters^.USART.STATUS AND (1 shl 15))>0) do begin end; + {$else} + while ((FPSerComRegisters^.USART.SYNCBUSY AND $4)>0) do begin end; + {$endif} +end; + +end. diff --git a/Source/MBF.SAMCD.SystemCore.pas b/Source/MBF.SAMCD.SystemCore.pas index 582ae9a..3aa7910 100644 --- a/Source/MBF.SAMCD.SystemCore.pas +++ b/Source/MBF.SAMCD.SystemCore.pas @@ -39,7 +39,7 @@ interface FCPUFrequency : longWord = ResetCPUFrequency; type - TClockType = (HSI,HSE,PLLHSI,PLLHSE); + TClockType = (RC,XTAL32_PLL,RC_PLL); TSAMCDSystemCore = record helper for TSystemCore type @@ -59,7 +59,7 @@ TOSCParameters = record function getMaxCPUFrequency : Cardinal; procedure SetClockSourceTarget(aClockSource,aClockTarget:longword); function GetCPUFrequency: Cardinal; - procedure SetCPUFrequency(const Value: Cardinal; aClockType : TClockType = TClockType.PLLHSI); + procedure SetCPUFrequency(const Value: Cardinal; aClockType : TClockType = TClockType.RC); property CPUFrequency: Cardinal read GetCPUFrequency write SetCPUFrequency; end; @@ -128,14 +128,132 @@ function TSAMCDSystemCore.GetCPUFrequency: Cardinal; end; {$ifdef samc} -procedure TSAMCDSystemCore.SetCPUFrequency(const Value: Cardinal; aClockType : TClockType = TClockType.PLLHSI); +procedure TSAMCDSystemCore.SetCPUFrequency(const Value: Cardinal; aClockType : TClockType = TClockType.RC); +procedure WaitDPLLSync; begin - //TODO Implement for SAMC + while (OSCCTRL.DPLLSYNCBUSY>0) do begin end; // Wait for synchronization +end; +var + PLLFrequency:longword; + OSC48M_divider:word; + GEN0_divider:word; + WaitStates:byte; + PllFactInt:longword; + PllFactFra:longword; +begin + + if (FCPUFrequency<>Value) then + begin + + GEN0_divider:=1; + + if aClockType=TClockType.RC then + begin + OSC48M_divider:=DivCeiling(OSC48MFrequency,Value); + if OSC48M_divider=0 then OSC48M_divider:=1; + if (OSC48M_divider>16) then + begin + OSC48M_divider:=16; + GEN0_divider:=DivCeiling((OSC48MFrequency DIV OSC48M_divider),Value); + if GEN0_divider=0 then GEN0_divider:=1; + end; + FCPUFrequency:=(OSC48MFrequency DIV OSC48M_divider); + end; + + if aClockType = TClockType.XTAL32_PLL then + begin + if Value<48000000 then + begin + PLLFrequency:=48000000; + GEN0_divider:=DivCeiling(PLLFrequency,Value); + if GEN0_divider=0 then GEN0_divider:=1; + end + else + begin + PLLFrequency:=Value; + end; + PllFactInt := (PLLFrequency DIV 32768) - 1; + PllFactFra := (32*(PLLFrequency - 32768*(PllFactInt+1))) DIV 32768; + FCPUFrequency:=32768*(PllFactInt+1) + ((32768*PllFactFra) DIV 32); + end; + + // GEN0 : 8 division factor bits - DIV[7:0] + // GEN1 : 16 division factor bits - DIV[15:0] + // GEN2-11 : 5 division factor bits - DIV[4:0] + if (GEN0_divider>255) then GEN0_divider:=255; + FCPUFrequency:=(FCPUFrequency DIV GEN0_divider); + + WaitStates:=0; + if (FCPUFrequency>=22000000) then Inc(WaitStates); + if (FCPUFrequency>=44000000) then Inc(WaitStates); + if (FCPUFrequency>=67000000) then Inc(WaitStates); + if (FCPUFrequency>=89000000) then Inc(WaitStates); + if (FCPUFrequency>=111000000) then Inc(WaitStates); + if (FCPUFrequency>=120000000) then Inc(WaitStates); + + // Enable the bus clock for the clock system. + SetBit(MCLK.APBCMASK,MCLK_APBAMASK_GCLK_Pos); + + // Set waitstates + NVMCTRL.CTRLB:=(NVMCTRL_CTRLB_RWS_Msk AND ((WaitStates) shl NVMCTRL_CTRLB_RWS_Pos)); + + if aClockType = TClockType.RC then + begin + OSCCTRL.OSC48MCTRL := OSCCTRL_OSC48MCTRL_ONDEMAND OR OSCCTRL_OSC48MCTRL_ENABLE OR OSCCTRL_OSC48MCTRL_RUNSTDBY; + OSCCTRL.OSC48MDIV := (OSCCTRL_OSC48MDIV_DIV_Msk AND ((OSC48M_divider-1) shl OSCCTRL_OSC48MDIV_DIV_Pos)); + OSCCTRL.OSC48MSTUP := $07; // ~21uS startup; + + while (OSCCTRL.OSC48MSYNCBUSY>0) do begin end; // Wait until synced + while ((OSCCTRL.STATUS AND OSCCTRL_STATUS_OSC48MRDY)=0) do begin end; // Wait until ready + + // Default setting for GEN0 + GCLK.GENCTRL[0] := + GCLK_GENCTRL_SRC_OSC48M OR + GCLK_GENCTRL_GENEN OR + (($FF shl GCLK_GENCTRL_DIV_Pos) AND ((GEN0_divider) shl GCLK_GENCTRL_DIV_Pos)); + end; + + if aClockType = TClockType.XTAL32_PLL then + begin + //Enable the 32.768 khz external crystal oscillator + OSC32KCTRL.XOSC32K:=((OSC32KCTRL_XOSC32K_STARTUP_Msk AND ((5) shl OSC32KCTRL_XOSC32K_STARTUP_Pos)) OR OSC32KCTRL_XOSC32K_XTALEN OR OSC32KCTRL_XOSC32K_EN32K OR OSC32KCTRL_XOSC32K_ENABLE); + + //Wait for the crystal oscillator to start up + while (NOT GetBit(OSC32KCTRL.STATUS,OSC32KCTRL_STATUS_XOSC32KRDY_Pos)) do begin end; // Wait for synchronization + + ClearBit(OSCCTRL.DPLLCTRLA,1);//disable DPLL + + OSCCTRL.DPLLRATIO:=(PllFactFra shl 16) + PllFactInt; + WaitDPLLSync; + + OSCCTRL.DPLLCTRLB:= + OSCCTRL_DPLLCTRLB_LBYPASS OR // CLK_DPLL0 output clock is always on, and not dependent on frequency lock + (OSCCTRL_DPLLCTRLB_REFCLK_Msk AND ((0) shl OSCCTRL_DPLLCTRLB_REFCLK_Pos)) //XOSC32K clock reference + ; + + SetBit(OSCCTRL.DPLLCTRLA,1);//enable DPLL + WaitDPLLSync; + + //while (NOT GetBit(OSCCTRL.DPLLSTATUS,0)) do begin end; + //while (NOT GetBit(OSCCTRL.DPLLSTATUS,1)) do begin end; + + // Default setting for GEN0 + GCLK.GENCTRL[0] := + //GCLK_GENCTRL_SRC_XOSC32K OR + GCLK_GENCTRL_SRC_DPLL96M OR + GCLK_GENCTRL_GENEN OR + (GCLK_GENCTRL_DIV_Msk AND ((GEN0_divider) shl GCLK_GENCTRL_DIV_Pos)); + end; + + ConfigureTimer; + + end; + end; {$endif} {$ifdef samd} -procedure TSAMCDSystemCore.SetCPUFrequency(const Value: Cardinal; aClockType : TClockType = TClockType.PLLHSI); +procedure TSAMCDSystemCore.SetCPUFrequency(const Value: Cardinal; aClockType : TClockType = TClockType.RC); procedure WaitGLK; begin while GetBit(GCLK.STATUS,GCLK_STATUS_SYNCBUSY_Pos) do begin end; // Wait for synchronization @@ -151,128 +269,136 @@ procedure WaitSYSCTRL; begin FCPUFrequency:=Value; - // Clear interrupt flags - SYSCTRL.INTFLAG := SYSCTRL_INTFLAG_BOD33RDY OR SYSCTRL_INTFLAG_BOD33DET OR SYSCTRL_INTFLAG_DFLLRDY; - - // Change the timing of the NVM access - // 1 wait state for operating at 2.7-3.3V at 48MHz. - PutValue(NVMCTRL.CTRLB,NVMCTRL_CTRLB_RWS_Msk,NVMCTRL_CTRLB_RWS_HALF); - - // Enable the bus clock for the clock system. - SetBit(PM.APBAMASK,PM_APBAMASK_GCLK_Pos); - - // Initialise the DFLL to run in closed-loop mode at 48MHz - // 1. Make a software reset of the clock system. - SetBit(GCLK.CTRL,GCLK_CTRL_SWRST_Pos); - while GetBit(GCLK.CTRL,GCLK_CTRL_SWRST_Pos) do begin end; // Wait for synchronization - WaitGLK; - - // 2. Make sure the OCM8M keeps running. - // presetscaler=3 : run at 1MHz - PutValue(SysCtrl.OSC8M,SYSCTRL_OSC8M_PRESC_Msk,3,SYSCTRL_OSC8M_PRESC_Pos); - ClearBit(SYSCTRL.OSC8M,SYSCTRL_OSC8M_ONDEMAND_Pos); - - // 3. Set the division factor to 32, which reduces the 1MHz source to 15.625kHz - GCLK.GENDIV:= - (GCLK_GENDIV_ID_Msk AND ((3) shl GCLK_GENDIV_ID_Pos)) OR // Select generator 3 - (GCLK_GENDIV_DIV_Msk AND ((32) shl GCLK_GENDIV_DIV_Pos)); // Set the division factor to 64 - WaitGLK; - - // 4. Create generic clock generator 3 for the 15KHz signal of the DFLL - GCLK.GENCTRL:=( - (GCLK_GENCTRL_ID_Msk AND ((3) shl GCLK_GENCTRL_ID_Pos)) OR // Select generator 3 - GCLK_GENCTRL_SRC_OSC8M OR // Select source OSC8M - GCLK_GENCTRL_IDC OR // Set improved duty cycle 50/50 - GCLK_GENCTRL_GENEN); // Enable this generic clock generator - WaitGLK; - - // 5. Configure DFLL48 - GCLK.CLKCTRL:=( - GCLK_CLKCTRL_ID_DFLL48 OR // Target is DFLL48M - (GCLK_CLKCTRL_GEN_Msk AND ((3) shl GCLK_CLKCTRL_GEN_Pos)) OR // Select generator 3 as source. - //((0) shl GCLK_CLKCTRL_WRTLOCK_Pos) OR // The generic clock and the associated generic clock generator and division factor are locked */ - GCLK_CLKCTRL_CLKEN); // Enable the DFLL48M - WaitGLK; - - // 6. Workaround to be able to configure the DFLL. - // Errata 9905: - // The DFLL clock must be requested before being configured otherwise a write access - // to a DFLL register can freeze the device. - ClearBit(SysCtrl.DFLLCTRL,SYSCTRL_DFLLCTRL_ONDEMAND_Pos); - WaitSYSCTRL; - - // 6a Load in DFLL48 factory calibrations - coarse := ReadCal(NVM_DFLL48M_COARSE_CAL_POS,NVM_DFLL48M_COARSE_CAL_SIZE); - // In some revision chip, the coarse calibration value is not correct. - if (coarse = $3f) then coarse := $1f; - fine := ReadCal(NVM_DFLL48M_FINE_CAL_POS,NVM_DFLL48M_FINE_CAL_SIZE); - PutValue(SysCtrl.DFLLVAL,SYSCTRL_DFLLVAL_COARSE_Msk,coarse,SYSCTRL_DFLLVAL_COARSE_Pos); - WaitSYSCTRL; - PutValue(SysCtrl.DFLLVAL,SYSCTRL_DFLLVAL_FINE_Msk,fine,SYSCTRL_DFLLVAL_FINE_Pos); - WaitSYSCTRL; - - // 7. Change the multiplication factor. - SysCtrl.DFLLMUL:=( -// (3000 shl SYSCTRL_DFLLMUL_MUL_Pos) OR // 48MHz / (1MHz / 64) - (1500 shl SYSCTRL_DFLLMUL_MUL_Pos) OR // 48MHz / (1MHz / 32) -// (5 shl SYSCTRL_DFLLMUL_CSTEP_Pos) OR // Coarse step = 5 -// (10 shl SYSCTRL_DFLLMUL_FSTEP_Pos) // Fine step = 10 - (31 shl SYSCTRL_DFLLMUL_CSTEP_Pos) OR // Coarse step = half of max step - (511 shl SYSCTRL_DFLLMUL_FSTEP_Pos) // Fine step = half of max step - ); - WaitSYSCTRL; - - // 8. Start closed-loop mode - SysCtrl.DFLLCTRL:=0; - while (NOT GetBit(SysCtrl.PCLKSR,SYSCTRL_PCLKSR_DFLLRDY_Pos)) do begin end; // Wait for synchronization - SysCtrl.DFLLCTRL:= - SYSCTRL_DFLLCTRL_MODE OR // 1 = Closed loop mode. + //if aClockType = TClockType.PLL then + if true then + begin + // Clear interrupt flags + SYSCTRL.INTFLAG := SYSCTRL_INTFLAG_BOD33RDY OR SYSCTRL_INTFLAG_BOD33DET OR SYSCTRL_INTFLAG_DFLLRDY; + + // Change the timing of the NVM access + // 1 wait state for operating at 2.7-3.3V at 48MHz. + PutValue(NVMCTRL.CTRLB,NVMCTRL_CTRLB_RWS_Msk,NVMCTRL_CTRLB_RWS_HALF); + + // Enable the bus clock for the clock system. + SetBit(PM.APBAMASK,PM_APBAMASK_GCLK_Pos); + + // Initialise the DFLL to run in closed-loop mode at 48MHz + // 1. Make a software reset of the clock system. + SetBit(GCLK.CTRL,GCLK_CTRL_SWRST_Pos); + while GetBit(GCLK.CTRL,GCLK_CTRL_SWRST_Pos) do begin end; // Wait for synchronization + WaitGLK; + + // 2. Make sure the OCM8M keeps running. + // presetscaler=3 : run at 1MHz + PutValue(SysCtrl.OSC8M,SYSCTRL_OSC8M_PRESC_Msk,3,SYSCTRL_OSC8M_PRESC_Pos); + ClearBit(SYSCTRL.OSC8M,SYSCTRL_OSC8M_ONDEMAND_Pos); + + // 3. Set the division factor to 32, which reduces the 1MHz source to 15.625kHz + GCLK.GENDIV:= + (GCLK_GENDIV_ID_Msk AND ((3) shl GCLK_GENDIV_ID_Pos)) OR // Select generator 3 + (GCLK_GENDIV_DIV_Msk AND ((32) shl GCLK_GENDIV_DIV_Pos)); // Set the division factor to 64 + WaitGLK; + + // 4. Create generic clock generator 3 for the 15KHz signal of the DFLL + GCLK.GENCTRL:=( + (GCLK_GENCTRL_ID_Msk AND ((3) shl GCLK_GENCTRL_ID_Pos)) OR // Select generator 3 + GCLK_GENCTRL_SRC_OSC8M OR // Select source OSC8M + GCLK_GENCTRL_IDC OR // Set improved duty cycle 50/50 + GCLK_GENCTRL_GENEN); // Enable this generic clock generator + WaitGLK; + + // 5. Configure DFLL48 + GCLK.CLKCTRL:=( + GCLK_CLKCTRL_ID_DFLL48 OR // Target is DFLL48M + (GCLK_CLKCTRL_GEN_Msk AND ((3) shl GCLK_CLKCTRL_GEN_Pos)) OR // Select generator 3 as source. + //((0) shl GCLK_CLKCTRL_WRTLOCK_Pos) OR // The generic clock and the associated generic clock generator and division factor are locked */ + GCLK_CLKCTRL_CLKEN); // Enable the DFLL48M + WaitGLK; + + // 6. Workaround to be able to configure the DFLL. + // Errata 9905: + // The DFLL clock must be requested before being configured otherwise a write access + // to a DFLL register can freeze the device. + ClearBit(SysCtrl.DFLLCTRL,SYSCTRL_DFLLCTRL_ONDEMAND_Pos); + WaitSYSCTRL; + + // 6a Load in DFLL48 factory calibrations + coarse := ReadCal(NVM_DFLL48M_COARSE_CAL_POS,NVM_DFLL48M_COARSE_CAL_SIZE); + // In some revision chip, the coarse calibration value is not correct. + if (coarse = $3f) then coarse := $1f; + fine := ReadCal(NVM_DFLL48M_FINE_CAL_POS,NVM_DFLL48M_FINE_CAL_SIZE); + PutValue(SysCtrl.DFLLVAL,SYSCTRL_DFLLVAL_COARSE_Msk,coarse,SYSCTRL_DFLLVAL_COARSE_Pos); + WaitSYSCTRL; + PutValue(SysCtrl.DFLLVAL,SYSCTRL_DFLLVAL_FINE_Msk,fine,SYSCTRL_DFLLVAL_FINE_Pos); + WaitSYSCTRL; + + // 7. Change the multiplication factor. + SysCtrl.DFLLMUL:=( + // (3000 shl SYSCTRL_DFLLMUL_MUL_Pos) OR // 48MHz / (1MHz / 64) + (1500 shl SYSCTRL_DFLLMUL_MUL_Pos) OR // 48MHz / (1MHz / 32) + // (5 shl SYSCTRL_DFLLMUL_CSTEP_Pos) OR // Coarse step = 5 + // (10 shl SYSCTRL_DFLLMUL_FSTEP_Pos) // Fine step = 10 + (31 shl SYSCTRL_DFLLMUL_CSTEP_Pos) OR // Coarse step = half of max step + (511 shl SYSCTRL_DFLLMUL_FSTEP_Pos) // Fine step = half of max step + ); + WaitSYSCTRL; + + // 8. Start closed-loop mode + SysCtrl.DFLLCTRL:=0; + while (NOT GetBit(SysCtrl.PCLKSR,SYSCTRL_PCLKSR_DFLLRDY_Pos)) do begin end; // Wait for synchronization + SysCtrl.DFLLCTRL:= + SYSCTRL_DFLLCTRL_MODE OR // 1 = Closed loop mode. + {$ifdef samd20} + SYSCTRL_DFLLCTRL_STABLE OR // See SAMD20 errata + {$endif} + {$ifdef CRYSTAL} + SYSCTRL_DFLLCTRL_WAITLOCK OR + SYSCTRL_DFLLCTRL_QLDIS; // 1 = Disable quick lock. + {$else} + SYSCTRL_DFLLCTRL_CCDIS OR + {$ifdef has_usb} + SYSCTRL_DFLLCTRL_USBCRM OR //* USB correction */ + {$endif} + SYSCTRL_DFLLCTRL_BPLCKC; + {$endif} + WaitSYSCTRL; + + // 9. Enable the DFLL + SetBit(SysCtrl.DFLLCTRL,SYSCTRL_DFLLCTRL_ENABLE_Pos); + WaitSYSCTRL; + + // 10. Wait for the coarse locks. + while (NOT GetBit(SysCtrl.PCLKSR,SYSCTRL_PCLKSR_DFLLLCKC_Pos)) do begin end; {$ifdef CRYSTAL} - SYSCTRL_DFLLCTRL_WAITLOCK OR - SYSCTRL_DFLLCTRL_QLDIS; // 1 = Disable quick lock. - {$else} - SYSCTRL_DFLLCTRL_CCDIS OR - SYSCTRL_DFLLCTRL_USBCRM OR //* USB correction */ - SYSCTRL_DFLLCTRL_BPLCKC; + // 11. Wait for the fine locks. + while (NOT GetBit(SysCtrl.PCLKSR,SYSCTRL_PCLKSR_DFLLLCKF_Pos)) do begin end; {$endif} - WaitSYSCTRL; - - // 9. Enable the DFLL - SetBit(SysCtrl.DFLLCTRL,SYSCTRL_DFLLCTRL_ENABLE_Pos); - WaitSYSCTRL; - - // 10. Wait for the coarse locks. - // TODO This hangs on SAMD20 - while (NOT GetBit(SysCtrl.PCLKSR,SYSCTRL_PCLKSR_DFLLLCKC_Pos)) do begin end; - {$ifdef CRYSTAL} - // 11. Wait for the fine locks. - while (NOT GetBit(SysCtrl.PCLKSR,SYSCTRL_PCLKSR_DFLLLCKF_Pos)) do begin end; - {$endif} - - - // Switch the main clock speed. - // 1. Set the divisor of generic clock 0 to 0 - GCLK.GENDIV:= - (GCLK_GENDIV_ID_Msk AND ((0) shl GCLK_GENDIV_ID_Pos)) OR // Select generator 0 - //(GCLK_GENDIV_GEN_GCLK0) OR // Select generator 0 - (GCLK_GENDIV_DIV_Msk AND ((0) shl GCLK_GENDIV_DIV_Pos)); // // Set the division factor to 0 - WaitGLK; - - // 2. Switch generic clock 0 to the DFLL - GCLK.GENCTRL:= - (GCLK_GENCTRL_ID_Msk AND ((0) shl GCLK_GENCTRL_ID_Pos)) OR // Select generator 0 - GCLK_GENCTRL_SRC_DFLL48M OR // Select source DFLL - GCLK_GENCTRL_IDC OR // Set improved duty cycle 50/50 - GCLK_GENCTRL_GENEN; // Enable this generic clock generator - WaitGLK; - - //Now that all system clocks are configured, we can set CPU and APBx BUS clocks. - - //There values are normally the one present after Reset. - //PM.CPUSEL := PM_GENERALDIV_DIV1; - //PM.APBASEL := PM_GENERALDIV_DIV1; - //PM.APBBSEL := PM_GENERALDIV_DIV1; - //PM.APBCSEL := PM_GENERALDIV_DIV1; + + + // Switch the main clock speed. + // 1. Set the divisor of generic clock 0 to 0 + GCLK.GENDIV:= + (GCLK_GENDIV_ID_Msk AND ((0) shl GCLK_GENDIV_ID_Pos)) OR // Select generator 0 + //(GCLK_GENDIV_GEN_GCLK0) OR // Select generator 0 + (GCLK_GENDIV_DIV_Msk AND ((0) shl GCLK_GENDIV_DIV_Pos)); // // Set the division factor to 0 + WaitGLK; + + // 2. Switch generic clock 0 to the DFLL + GCLK.GENCTRL:= + (GCLK_GENCTRL_ID_Msk AND ((0) shl GCLK_GENCTRL_ID_Pos)) OR // Select generator 0 + GCLK_GENCTRL_SRC_DFLL48M OR // Select source DFLL + GCLK_GENCTRL_IDC OR // Set improved duty cycle 50/50 + GCLK_GENCTRL_GENEN; // Enable this generic clock generator + WaitGLK; + + //Now that all system clocks are configured, we can set CPU and APBx BUS clocks. + + //There values are normally the one present after Reset. + //PM.CPUSEL := PM_GENERALDIV_DIV1; + //PM.APBASEL := PM_GENERALDIV_DIV1; + //PM.APBBSEL := PM_GENERALDIV_DIV1; + //PM.APBCSEL := PM_GENERALDIV_DIV1; + end; ConfigureTimer; end diff --git a/Source/MBF.SAMCD.UART.pas b/Source/MBF.SAMCD.UART.pas new file mode 100644 index 0000000..df6a7d7 --- /dev/null +++ b/Source/MBF.SAMCD.UART.pas @@ -0,0 +1,197 @@ +unit MBF.SAMCD.UART; +{ + This file is part of Pascal Microcontroller Board Framework (MBF) + Copyright (c) 2015 - Michael Ring + based on Pascal eXtended Library (PXL) + Copyright (c) 2000 - 2015 Yuriy Kotsarenko + + This program is free software: you can redistribute it and/or modify it under the terms of the FPC modified GNU + Library General Public License for more + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FPC modified GNU Library General Public + License for more details. +} +{< Atmel SAMD series GPIO functions. } + +interface + +{$include MBF.Config.inc} + +uses + MBF.SAMCD.Helpers, + MBF.SAMCD.SerCom; + +type + TUART_Registers = record + strict private const + USART_SAMPLE_NUM=16; + BAUD_INT_MAX=8192; + BAUD_FP_MAX=8; + strict private + FSerCom:TSerCom; + procedure SetPort(aPort:TPortIdentifier); + function GetBaud(const Value: Cardinal):cardinal; + function GetBaud2(const Value: Cardinal):cardinal; + function GetBaudFrac(const Value: Cardinal):cardinal; + function GetBaudFrac2(const Value: Cardinal):cardinal; + function TX_Ready:boolean; + function DRE_Ready:boolean; + function RXC_Ready:boolean; + public + procedure Initialize(const aPort:TPortIdentifier;const Speed:cardinal; aRXPO,aTXPO:byte); + procedure Close; + function WriteByte(const aByte:byte):boolean; + function WriteString(const aString:string):boolean; + function ReadByte(out aByte:byte):boolean; + end; + +implementation + +uses + MBF.SAMCD.SystemCore; + +procedure TUART_Registers.SetPort(aPort:TPortIdentifier); +begin + FSerCom.Initialize(aPort); + FSerCom.SetCoreClockSource(GCLK_CLKCTRL_GEN_GCLK0); // use gclk0 at 1Mhz or 48MHz +end; + +function TUART_Registers.GetBaud(const Value: Cardinal):cardinal; +const + SHIFT=32; +var + ratio,scale,temp1:uint64; +begin + temp1 := ((uint64(USART_SAMPLE_NUM) * uint64(Value)) shl SHIFT); + ratio := temp1 DIV SystemCore.CPUFrequency; + scale := (uint64(1) shl SHIFT) - ratio; + result := ((65536 * scale) shr SHIFT); +end; + +function TUART_Registers.GetBaud2(const Value: Cardinal):cardinal; +var + temp1:uint64; +begin + temp1:=(uint64(Value) shl 20); + temp1:=(temp1 + (SystemCore.CPUFrequency shr 1)) DIV SystemCore.CPUFrequency; + result:=65536 - word(temp1); +end; + +function TUART_Registers.GetBaudFrac(const Value: Cardinal):cardinal; +var + baud_fp:byte; + temp1,temp2:uint64; + baud_int:cardinal; +begin + result:=0; + baud_fp:=0; + while (baud_fp<BAUD_FP_MAX) do + begin + temp1:=uint64(BAUD_FP_MAX) * uint64(SystemCore.CPUFrequency); + temp2:=uint64(Value) * uint64(USART_SAMPLE_NUM); + baud_int:=temp1 DIV temp2; + baud_int:=baud_int-baud_fp; + baud_int:=baud_int DIV BAUD_FP_MAX; + if (baud_int < BAUD_INT_MAX) then break; + Inc(baud_fp); + end; + if (baud_fp=BAUD_FP_MAX) then exit; + result:=((baud_int AND longword($FFF)) OR ((baud_fp AND byte($7)) shl 13)); +end; + +function TUART_Registers.GetBaudFrac2(const Value: Cardinal):cardinal; +var + baud,fp,mul_ratio:uint64; +begin + mul_ratio:=(SystemCore.CPUFrequency*1000) DIV (Value*USART_SAMPLE_NUM); + baud:= (mul_ratio DIV 1000); + fp:=((mul_ratio - (baud*1000))*8) DIV 1000; + result:=((baud AND $FFF) OR ((fp AND $7) shl 13)); +end; + +procedure TUART_Registers.Initialize(const aPort:TPortIdentifier;const Speed:cardinal; aRXPO,aTXPO:byte); +begin + SetPort(aPort); + + //Using 8N1 for setting the CTRLA/CTRLB registers + + //Setting the CTRLA register + FSerCom.PSerComRegisters^.USART.CTRLA:= + SERCOM_USART_CTRLA_DORD OR // DWORD + (SERCOM_USART_CTRLA_RXPO_Msk AND ((aRXPO) shl SERCOM_USART_CTRLA_RXPO_Pos)) OR + (SERCOM_USART_CTRLA_TXPO_Msk AND ((aTXPO) shl SERCOM_USART_CTRLA_TXPO_Pos)) OR + (SERCOM_USART_CTRLA_SAMPR_Msk AND ((0) shl SERCOM_USART_CTRLA_SAMPR_Pos)) OR + SERCOM_MODE_USART_INT_CLK; + FSerCom.SyncWait; + + FSerCom.PSerComRegisters^.USART.BAUD:=GetBaud(Speed); + FSerCom.SyncWait; + + //Setting the CTRLB register + FSerCom.PSerComRegisters^.USART.CTRLB:=0; + FSerCom.SyncWait; + + SetBit(FSerCom.PSerComRegisters^.USART.CTRLB,SERCOM_USART_CTRLB_RXEN_Pos); //RX_EN + FSerCom.SyncWait; + SetBit(FSerCom.PSerComRegisters^.USART.CTRLB,SERCOM_USART_CTRLB_TXEN_Pos); //TX_EN + FSerCom.SyncWait; + + SetBit(FSerCom.PSerComRegisters^.USART.CTRLA,SERCOM_ENABLE_Pos);//UART_EN + FSerCom.SyncWait; +end; + +procedure TUART_Registers.Close; +begin + FSerCom.Close; +end; + +function TUART_Registers.WriteByte(const aByte:byte):boolean; +begin + while (NOT DRE_Ready) do begin end; + FSerCom.PSerComRegisters^.USART.DATA:=aByte; + while (NOT TX_Ready) do begin end; + result:=true; +end; + +function TUART_Registers.WriteString(const aString:string):boolean; +var + i:byte; +begin + result:=false; + for i:=1 to Length(aString) do + begin + if (NOT WriteByte(Ord(aString[i]))) then exit; + end; + result:=true; +end; + + +function TUART_Registers.ReadByte(out aByte:byte):boolean; +begin + while (NOT RXC_Ready) do begin end; + //check errors + //if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) + // /* Set the error flag */ + aByte:=FSerCom.PSerComRegisters^.USART.DATA; + //while (NOT TX_Ready) do begin end; + result:=true; +end; + + +function TUART_Registers.TX_Ready:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.USART.INTFLAG,SERCOM_USART_INTFLAG_TXC_Pos); +end; + +function TUART_Registers.DRE_Ready:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.USART.INTFLAG,SERCOM_USART_INTFLAG_DRE_Pos); +end; + +function TUART_Registers.RXC_Ready:boolean; +begin + result:=GetBit(FSerCom.PSerComRegisters^.USART.INTFLAG,SERCOM_USART_INTFLAG_RXC_Pos); +end; + +end. diff --git a/Source/MBF.SystemCore.pas b/Source/MBF.SystemCore.pas index 9743558..b546953 100644 --- a/Source/MBF.SystemCore.pas +++ b/Source/MBF.SystemCore.pas @@ -44,6 +44,19 @@ TSystemCore = record function getCoreTimerValue: longWord; public {$IF DEFINED(CPUARM)} + procedure NVIC_SystemReset; + {$IF DEFINED(CortexM0)} + function NVIC_GetPendingIRQ(const IRQn:TIRQn_Enum):boolean; + procedure NVIC_ClearPendingIRQ(const IRQn:TIRQn_Enum); + procedure NVIC_EnableIRQ(const IRQn:TIRQn_Enum); + procedure NVIC_DisableIRQ(const IRQn:TIRQn_Enum); + {$endif} + procedure Enable_IRQ; + procedure Disable_IRQ; + {$if not defined(cortexm0)} // only CortexM3 and higher + procedure Enable_FIRQ; + procedure Disable_FIRQ; + {$endif} {$if not defined(cortexm0)} function udiv(Divisor,Dividend : longWord) : longWord; function sdiv(Divisor,Dividend : integer) : integer; @@ -239,15 +252,22 @@ procedure TSystemCore.ConfigureTimer; Value,Value2 : longWord; begin TicksPerMillisecond := GetSysTickClockFrequency div 1000; - {$if defined(CPUARM)} + + if (TicksPerMillisecond>$FFFFFF) then TicksPerMillisecond:=$FFFFFF; + if (TicksPerMillisecond<100) then TicksPerMillisecond:=100; + + {$ifdef samd10} + //SAMD10 errata + //The SYSTICK calibration value is incorrect. Errata reference: 14157 + //The correct SYSTICK calibration value is 0x40000000 + SysTick.Calib:=$40000000; + {$endif} + SysTick.CTRL := 0; - setCoreTimerValue(0); setCoreTimerComp(TicksPerMillisecond - 1); + setCoreTimerValue(0); SysTick.CTRL := %0111; - asm - cpsie if // enable faults and interrupts - end; {$elseif defined(CPUMIPS)} //Coretimer was set on Startup Code SetCoreTimerValue(0); @@ -274,6 +294,74 @@ procedure TSystemCore.ConfigureTimer; procedure TSystemCore.ConfigureInterrupts; begin end; + +procedure TSystemCore.NVIC_SystemReset; +const + SCB_AIRCR_VECTKEY_Pos = 16; + SCB_AIRCR_VECTKEY_Msk = ($FFFF shl SCB_AIRCR_VECTKEY_Pos); + SCB_AIRCR_SYSRESETREQ_Pos = 2; + SCB_AIRCR_SYSRESETREQ_Msk = (1 shl SCB_AIRCR_SYSRESETREQ_Pos); +begin + asm + dsb + end; + SCB.AIRCR:=(($5FA shl SCB_AIRCR_VECTKEY_Pos) OR (SCB_AIRCR_SYSRESETREQ_Msk)); + asm + dsb + end; + while true do begin end; +end; + +{$IF DEFINED(CortexM0)} +function TSystemCore.NVIC_GetPendingIRQ(const IRQn:TIRQn_Enum):boolean; +var + aMask:longword; +begin + aMask:=(1 shl (Ord(IRQn) AND $1F)); + result:=((NVIC.ISPR AND aMask)=aMask); +end; + +procedure TSystemCore.NVIC_ClearPendingIRQ(const IRQn:TIRQn_Enum); +begin + NVIC.ICPR:=(1 shl (Ord(IRQn) AND $1F)); +end; + +procedure TSystemCore.NVIC_EnableIRQ(const IRQn:TIRQn_Enum); +begin + NVIC.ISER:=(1 shl (Ord(IRQn) AND $1F)); +end; + +procedure TSystemCore.NVIC_DisableIRQ(const IRQn:TIRQn_Enum); +begin + NVIC.ICER:=(1 shl (Ord(IRQn) AND $1F)); +end; +{$endif} + +procedure TSystemCore.Enable_IRQ; +assembler;nostackframe; +asm + cpsie i +end; + +procedure TSystemCore.Disable_IRQ; +assembler;nostackframe; +asm + cpsid i +end; + +{$if not defined(cortexm0)} // only CortexM3 and higher +procedure TSystemCore.Enable_FIRQ; +assembler;nostackframe; +asm + cpsie f +end; +procedure TSystemCore.Disable_FIRQ; +assembler;nostackframe; +asm + cpsid f +end; +{$endif} + {$elseif defined(CPUMIPS)} procedure TSystemCore.ConfigureInterrupts; @@ -317,6 +405,7 @@ procedure TSystemCore.MicroDelay(const Microseconds: TMicroseconds); begin StartTicks := GetCoreTimerValue; TickCount := convertMicroSecondsToCoreTicks(Microseconds); + if (TickCount=0) then exit; while TicksInBetween(StartTicks, GetCoreTimerValue) < TickCount do ; end; diff --git a/Source/atsamcd/samcd-adc.inc b/Source/atsamcd/samcd-adc.inc index 1fb0e1a..f11b9bf 100644 --- a/Source/atsamcd/samcd-adc.inc +++ b/Source/atsamcd/samcd-adc.inc @@ -6,6 +6,9 @@ const {$ifdef samd10} ADC_GCLK_ID = $13; // Index of Generic Clock {$endif} + {$ifdef samd20} + ADC_GCLK_ID = $17; // Index of Generic Clock + {$endif} {$ifdef samd21} ADC_GCLK_ID = $1E; // Index of Generic Clock {$endif} @@ -33,12 +36,24 @@ const ADC_REFCTRL_REFSEL_INTVCC0_Val = $1; //(ADC_REFCTRL) 1/1.48 VDDANA */ ADC_REFCTRL_REFSEL_INTVCC1_Val = $2; //(ADC_REFCTRL) 1/2 VDDANA (only for VDDANA > 2.0V) */ ADC_REFCTRL_REFSEL_AREFA_Val = $3; //(ADC_REFCTRL) External reference */ + {$ifdef samd} ADC_REFCTRL_REFSEL_AREFB_Val = $4; //(ADC_REFCTRL) External reference */ + {$endif} + {$ifdef samc} + ADC_REFCTRL_REFSEL_DAC_Val = $4; //(ADC_REFCTRL) External reference */ + ADC_REFCTRL_REFSEL_INTVCC2_Val = $5; //(ADC_REFCTRL) External reference */ + {$endif} ADC_REFCTRL_REFSEL_INT1V = (ADC_REFCTRL_REFSEL_INT1V_Val shl ADC_REFCTRL_REFSEL_Pos); ADC_REFCTRL_REFSEL_INTVCC0 = (ADC_REFCTRL_REFSEL_INTVCC0_Val shl ADC_REFCTRL_REFSEL_Pos); ADC_REFCTRL_REFSEL_INTVCC1 = (ADC_REFCTRL_REFSEL_INTVCC1_Val shl ADC_REFCTRL_REFSEL_Pos); ADC_REFCTRL_REFSEL_AREFA = (ADC_REFCTRL_REFSEL_AREFA_Val shl ADC_REFCTRL_REFSEL_Pos); + {$ifdef samd} ADC_REFCTRL_REFSEL_AREFB = (ADC_REFCTRL_REFSEL_AREFB_Val shl ADC_REFCTRL_REFSEL_Pos); + {$endif} + {$ifdef samc} + ADC_REFCTRL_REFSEL_DAC = (ADC_REFCTRL_REFSEL_DAC_Val shl ADC_REFCTRL_REFSEL_Pos); + ADC_REFCTRL_REFSEL_INTVCC2 = (ADC_REFCTRL_REFSEL_INTVCC2_Val shl ADC_REFCTRL_REFSEL_Pos); + {$endif} ADC_REFCTRL_REFCOMP_Pos = 7; //(ADC_REFCTRL) Reference Buffer Offset Compensation Enable */ ADC_REFCTRL_REFCOMP = ($1 shl ADC_REFCTRL_REFCOMP_Pos); ADC_REFCTRL_MASK = $8F; //(ADC_REFCTRL) MASK Register */ @@ -61,6 +76,26 @@ const ADC_CTRLB_RESSEL_16BIT = (ADC_CTRLB_RESSEL_16BIT_Val shl ADC_CTRLB_RESSEL_Pos); ADC_CTRLB_RESSEL_10BIT = (ADC_CTRLB_RESSEL_10BIT_Val shl ADC_CTRLB_RESSEL_Pos); ADC_CTRLB_RESSEL_8BIT = (ADC_CTRLB_RESSEL_8BIT_Val shl ADC_CTRLB_RESSEL_Pos); + + {$ifdef samc} + ADC_CTRLC_R2R_Pos = 7; + ADC_CTRLC_R2R = ($1 shl ADC_CTRLC_R2R_Pos); + + ADC_CTRLC_WINMODE_Pos = 8; + ADC_CTRLC_WINMODE_Msk = ($7 shl ADC_CTRLC_WINMODE_Pos); + ADC_CTRLC_WINMODE_DISABLE_Val = $0; + ADC_CTRLC_WINMODE_MODE1_Val = $1; + ADC_CTRLC_WINMODE_MODE2_Val = $2; + ADC_CTRLC_WINMODE_MODE3_Val = $3; + ADC_CTRLC_WINMODE_MODE4_Val = $4; + + ADC_CTRLC_DUALSEL_Pos = 12; + ADC_CTRLC_DUALSEL_Msk = ($3 shl ADC_CTRLC_DUALSEL_Pos); + ADC_CTRLC_DUALSEL_BOTH_Val = $0; + ADC_CTRLC_DUALSEL_INTERLEAVE_Val = $1; + {$endif} + + {$ifdef samd} ADC_CTRLB_PRESCALER_Pos = 8; //(ADC_CTRLB) Prescaler Configuration */ ADC_CTRLB_PRESCALER_Msk = ($7 shl ADC_CTRLB_PRESCALER_Pos); ADC_CTRLB_PRESCALER_DIV4_Val = $0; //(ADC_CTRLB) Peripheral clock divided by 4 */ @@ -79,7 +114,29 @@ const ADC_CTRLB_PRESCALER_DIV128 = (ADC_CTRLB_PRESCALER_DIV128_Val shl ADC_CTRLB_PRESCALER_Pos); ADC_CTRLB_PRESCALER_DIV256 = (ADC_CTRLB_PRESCALER_DIV256_Val shl ADC_CTRLB_PRESCALER_Pos); ADC_CTRLB_PRESCALER_DIV512 = (ADC_CTRLB_PRESCALER_DIV512_Val shl ADC_CTRLB_PRESCALER_Pos); - ADC_CTRLB_MASK = $073F; //(ADC_CTRLB) MASK Register */ + {$endif} + + {$ifdef samc} + ADC_CTRLB_PRESCALER_Pos = 0; //(ADC_CTRLB) Prescaler Configuration */ + ADC_CTRLB_PRESCALER_Msk = ($7 shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV2_Val = $0; //(ADC_CTRLB) Peripheral clock divided by 4 */ + ADC_CTRLB_PRESCALER_DIV4_Val = $1; //(ADC_CTRLB) Peripheral clock divided by 8 */ + ADC_CTRLB_PRESCALER_DIV8_Val = $2; //(ADC_CTRLB) Peripheral clock divided by 16 */ + ADC_CTRLB_PRESCALER_DIV16_Val = $3; //(ADC_CTRLB) Peripheral clock divided by 32 */ + ADC_CTRLB_PRESCALER_DIV32_Val = $4; //(ADC_CTRLB) Peripheral clock divided by 64 */ + ADC_CTRLB_PRESCALER_DIV64_Val = $5; //(ADC_CTRLB) Peripheral clock divided by 128 */ + ADC_CTRLB_PRESCALER_DIV128_Val = $6; //(ADC_CTRLB) Peripheral clock divided by 256 */ + ADC_CTRLB_PRESCALER_DIV256_Val = $7; //(ADC_CTRLB) Peripheral clock divided by 512 */ + ADC_CTRLB_PRESCALER_DIV2 = (ADC_CTRLB_PRESCALER_DIV2_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV4 = (ADC_CTRLB_PRESCALER_DIV4_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV8 = (ADC_CTRLB_PRESCALER_DIV8_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV16 = (ADC_CTRLB_PRESCALER_DIV16_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV32 = (ADC_CTRLB_PRESCALER_DIV32_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV64 = (ADC_CTRLB_PRESCALER_DIV64_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV128 = (ADC_CTRLB_PRESCALER_DIV128_Val shl ADC_CTRLB_PRESCALER_Pos); + ADC_CTRLB_PRESCALER_DIV256 = (ADC_CTRLB_PRESCALER_DIV256_Val shl ADC_CTRLB_PRESCALER_Pos); + {$endif} + ADC_AVGCTRL_SAMPLENUM_Pos = 0; //(ADC_AVGCTRL) Number of Samples to be Collected */ ADC_AVGCTRL_SAMPLENUM_Msk = ($F shl ADC_AVGCTRL_SAMPLENUM_Pos); @@ -111,15 +168,21 @@ const ADC_INPUTCTRL_MUXPOS_Pos = 0; //(ADC_INPUTCTRL) Positive Mux Input Selection */ ADC_INPUTCTRL_MUXPOS_Msk = ($1F shl ADC_INPUTCTRL_MUXPOS_Pos); - ADC_INPUTCTRL_MUXPOS_TEMP_Val = $18; //(ADC_INPUTCTRL) Temperature Reference */ ADC_INPUTCTRL_MUXPOS_BANDGAP_Val = $19; //(ADC_INPUTCTRL) Bandgap Voltage */ + ADC_INPUTCTRL_MUXPOS_DAC_Val = $1C; //(ADC_INPUTCTRL) DAC Output */ + {$ifdef samd} + ADC_INPUTCTRL_MUXPOS_TEMP_Val = $18; //(ADC_INPUTCTRL) Temperature Reference */ ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val = $1A; //(ADC_INPUTCTRL) 1/4 Scaled Core Supply */ ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val = $1B; //(ADC_INPUTCTRL) 1/4 Scaled I/O Supply */ - ADC_INPUTCTRL_MUXPOS_DAC_Val = $1C; //(ADC_INPUTCTRL) DAC Output */ + {$endif} + ADC_INPUTCTRL_MUXNEG_Pos = 8; //(ADC_INPUTCTRL) Negative Mux Input Selection */ ADC_INPUTCTRL_MUXNEG_Msk = ($1F shl ADC_INPUTCTRL_MUXNEG_Pos); ADC_INPUTCTRL_MUXNEG_GND_Val = $18; //(ADC_INPUTCTRL) Internal Ground */ + {$ifdef samd} ADC_INPUTCTRL_MUXNEG_IOGND_Val = $19; //(ADC_INPUTCTRL) I/O Ground */ + {$endif} + ADC_INPUTCTRL_INPUTSCAN_Pos = 16; //(ADC_INPUTCTRL) Number of Input Channels Included in Scan */ ADC_INPUTCTRL_INPUTSCAN_Msk = ($F shl ADC_INPUTCTRL_INPUTSCAN_Pos); ADC_INPUTCTRL_INPUTOFFSET_Pos = 20; //(ADC_INPUTCTRL) Positive Mux Setting Offset */ diff --git a/Source/atsamcd/samcd-gclk.inc b/Source/atsamcd/samcd-gclk.inc index 9ebf9dd..1464202 100644 --- a/Source/atsamcd/samcd-gclk.inc +++ b/Source/atsamcd/samcd-gclk.inc @@ -32,7 +32,21 @@ const GCLK_CLKCTRL_ID_Pos = 0; //(GCLK_CLKCTRL) Generic Clock Selection ID */ GCLK_CLKCTRL_ID_Msk = ($3F shl GCLK_CLKCTRL_ID_Pos); + GCLK_CLKCTRL_ID_DFLL48_Val = $00; //(GCLK_CLKCTRL) DFLL48 */ + {$ifdef samd20} + GCLK_CLKCTRL_ID_WDT_Val = $01; //(GCLK_CLKCTRL) WDT */ + GCLK_CLKCTRL_ID_RTC_Val = $02; //(GCLK_CLKCTRL) RTC */ + GCLK_CLKCTRL_ID_EIC_Val = $03; //(GCLK_CLKCTRL) EIC */ + GCLK_CLKCTRL_ID_EVSYS_0_Val = $04; //(GCLK_CLKCTRL) EVSYS_0 */ + GCLK_CLKCTRL_ID_EVSYS_1_Val = $05; //(GCLK_CLKCTRL) EVSYS_1 */ + GCLK_CLKCTRL_ID_EVSYS_2_Val = $06; //(GCLK_CLKCTRL) EVSYS_2 */ + GCLK_CLKCTRL_ID_EVSYS_3_Val = $07; //(GCLK_CLKCTRL) EVSYS_3 */ + GCLK_CLKCTRL_ID_EVSYS_4_Val = $08; //(GCLK_CLKCTRL) EVSYS_4 */ + GCLK_CLKCTRL_ID_EVSYS_5_Val = $09; //(GCLK_CLKCTRL) EVSYS_5 */ + GCLK_CLKCTRL_ID_EVSYS_6_Val = $0A; //(GCLK_CLKCTRL) EVSYS_6 */ + GCLK_CLKCTRL_ID_EVSYS_7_Val = $0B; //(GCLK_CLKCTRL) EVSYS_7 */ + {$else} GCLK_CLKCTRL_ID_FDPLL_Val = $01; //(GCLK_CLKCTRL) FDPLL */ GCLK_CLKCTRL_ID_FDPLL32K_Val = $02; //(GCLK_CLKCTRL) FDPLL32K */ GCLK_CLKCTRL_ID_WDT_Val = $03; //(GCLK_CLKCTRL) WDT */ @@ -45,13 +59,20 @@ const GCLK_CLKCTRL_ID_EVSYS_3_Val = $0A; //(GCLK_CLKCTRL) EVSYS_3 */ GCLK_CLKCTRL_ID_EVSYS_4_Val = $0B; //(GCLK_CLKCTRL) EVSYS_4 */ GCLK_CLKCTRL_ID_EVSYS_5_Val = $0C; //(GCLK_CLKCTRL) EVSYS_5 */ + {$endif} + + GCLK_CLKCTRL_ID_DFLL48 = (GCLK_CLKCTRL_ID_DFLL48_Val shl GCLK_CLKCTRL_ID_Pos); + {$ifndef samd20} GCLK_CLKCTRL_ID_FDPLL = (GCLK_CLKCTRL_ID_FDPLL_Val shl GCLK_CLKCTRL_ID_Pos); GCLK_CLKCTRL_ID_FDPLL32K = (GCLK_CLKCTRL_ID_FDPLL32K_Val shl GCLK_CLKCTRL_ID_Pos); + {$endif} GCLK_CLKCTRL_ID_WDT = (GCLK_CLKCTRL_ID_WDT_Val shl GCLK_CLKCTRL_ID_Pos); GCLK_CLKCTRL_ID_RTC = (GCLK_CLKCTRL_ID_RTC_Val shl GCLK_CLKCTRL_ID_Pos); GCLK_CLKCTRL_ID_EIC = (GCLK_CLKCTRL_ID_EIC_Val shl GCLK_CLKCTRL_ID_Pos); + {$ifndef samd20} GCLK_CLKCTRL_ID_USB = (GCLK_CLKCTRL_ID_USB_Val shl GCLK_CLKCTRL_ID_Pos); + {$endif} GCLK_CLKCTRL_ID_EVSYS_0 = (GCLK_CLKCTRL_ID_EVSYS_0_Val shl GCLK_CLKCTRL_ID_Pos); GCLK_CLKCTRL_ID_EVSYS_1 = (GCLK_CLKCTRL_ID_EVSYS_1_Val shl GCLK_CLKCTRL_ID_Pos); GCLK_CLKCTRL_ID_EVSYS_2 = (GCLK_CLKCTRL_ID_EVSYS_2_Val shl GCLK_CLKCTRL_ID_Pos); @@ -94,9 +115,12 @@ const GCLK_CLKCTRL_WRTLOCK_Pos = 15; //(GCLK_CLKCTRL) Write Lock */ GCLK_CLKCTRL_WRTLOCK = (1 shl GCLK_CLKCTRL_WRTLOCK_Pos); {$endif} + {$ifdef samc} GCLK_PCHCTRL_CLKEN_Pos = 6; //(GCLK_PCHCTRL) Clock Enable */ GCLK_PCHCTRL_CLKEN = (1 shl GCLK_PCHCTRL_CLKEN_Pos); + GCLK_PCHCTRL_CHEN_Pos = GCLK_PCHCTRL_CLKEN_Pos; + GCLK_PCHCTRL_CHEN = GCLK_PCHCTRL_CLKEN; GCLK_PCHCTRL_WRTLOCK_Pos = 7; //(GCLK_PCHCTRL) Write Lock */ GCLK_PCHCTRL_WRTLOCK = (1 shl GCLK_PCHCTRL_WRTLOCK_Pos); {$endif} @@ -104,67 +128,102 @@ const GCLK_GENCTRL_OFFSET = $04; // (GCLK_GENCTRL offset) Generic Clock Generator Control */ GCLK_GENCTRL_RESETVALUE = $00000000; // (GCLK_GENCTRL reset_value) Generic Clock Generator Control */ - GCLK_GENCTRL_ID_Pos = 0; // (GCLK_GENCTRL) Generic Clock Generator Selection */ - GCLK_GENCTRL_ID_Msk = ($0F shl GCLK_GENCTRL_ID_Pos); - GCLK_GENCTRL_SRC_Pos = 8; // (GCLK_GENCTRL) Source Select */ - GCLK_GENCTRL_SRC_Msk = ($1F shl GCLK_GENCTRL_SRC_Pos); - GCLK_GENCTRL_SRC_XOSC_Val = $00; // (GCLK_GENCTRL) XOSC oscillator output */ - GCLK_GENCTRL_SRC_GCLKIN_Val = $01; // (GCLK_GENCTRL) Generator input pad */ - GCLK_GENCTRL_SRC_GCLKGEN1_Val= $02; // (GCLK_GENCTRL) Generic clock generator 1 output */ + {$ifdef samd} + GCLK_GENCTRL_ID_Pos = 0; // (GCLK_GENCTRL) Generic Clock Generator Selection */ + GCLK_GENCTRL_ID_Msk = ($0F shl GCLK_GENCTRL_ID_Pos); + GCLK_GENCTRL_SRC_Pos = 8; // (GCLK_GENCTRL) Source Select */ + GCLK_GENCTRL_SRC_Msk = ($1F shl GCLK_GENCTRL_SRC_Pos); + {$endif} + {$ifdef samc} + GCLK_GENCTRL_SRC_Pos = 0; // (GCLK_GENCTRL) Source Select */ + GCLK_GENCTRL_SRC_Msk = ($7 shl GCLK_GENCTRL_SRC_Pos); + {$endif} + + GCLK_GENCTRL_SRC_XOSC_Val = $00; // (GCLK_GENCTRL) XOSC oscillator output */ + GCLK_GENCTRL_SRC_GCLKIN_Val = $01; // (GCLK_GENCTRL) Generator input pad */ + GCLK_GENCTRL_SRC_GCLKGEN1_Val = $02; // (GCLK_GENCTRL) Generic clock generator 1 output */ GCLK_GENCTRL_SRC_OSCULP32K_Val = $03; // (GCLK_GENCTRL) OSCULP32K oscillator output */ - GCLK_GENCTRL_SRC_OSC32K_Val = $04; // (GCLK_GENCTRL) OSC32K oscillator output */ - GCLK_GENCTRL_SRC_XOSC32K_Val = $05; // (GCLK_GENCTRL) XOSC32K oscillator output */ - GCLK_GENCTRL_SRC_OSC8M_Val = $06; // (GCLK_GENCTRL) OSC8M oscillator output */ - GCLK_GENCTRL_SRC_DFLL48M_Val = $07; // (GCLK_GENCTRL) DFLL48M output */ - GCLK_GENCTRL_SRC_FDPLL_Val = $08; // (GCLK_GENCTRL) FDPLL output */ + GCLK_GENCTRL_SRC_OSC32K_Val = $04; // (GCLK_GENCTRL) OSC32K oscillator output */ + GCLK_GENCTRL_SRC_XOSC32K_Val = $05; // (GCLK_GENCTRL) XOSC32K oscillator output */ + + {$ifdef samd} + GCLK_GENCTRL_SRC_OSC8M_Val = $06; // (GCLK_GENCTRL) OSC8M oscillator output */ + GCLK_GENCTRL_SRC_DFLL48M_Val = $07; // (GCLK_GENCTRL) DFLL48M output */ + GCLK_GENCTRL_SRC_FDPLL_Val = $08; // (GCLK_GENCTRL) FDPLL output */ + {$endif} + {$ifdef samc} + GCLK_GENCTRL_SRC_OSC48M_Val = $06; // (GCLK_GENCTRL) OSC8M oscillator output */ + GCLK_GENCTRL_SRC_DPLL96M_Val = $07; // (GCLK_GENCTRL) DFLL48M output */ + {$endif} + GCLK_GENCTRL_SRC_XOSC = (GCLK_GENCTRL_SRC_XOSC_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_GCLKIN = (GCLK_GENCTRL_SRC_GCLKIN_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_GCLKGEN1 = (GCLK_GENCTRL_SRC_GCLKGEN1_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_OSCULP32K = (GCLK_GENCTRL_SRC_OSCULP32K_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_OSC32K = (GCLK_GENCTRL_SRC_OSC32K_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_XOSC32K = (GCLK_GENCTRL_SRC_XOSC32K_Val shl GCLK_GENCTRL_SRC_Pos); + + {$ifdef samd} GCLK_GENCTRL_SRC_OSC8M = (GCLK_GENCTRL_SRC_OSC8M_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_DFLL48M = (GCLK_GENCTRL_SRC_DFLL48M_Val shl GCLK_GENCTRL_SRC_Pos); GCLK_GENCTRL_SRC_FDPLL = (GCLK_GENCTRL_SRC_FDPLL_Val shl GCLK_GENCTRL_SRC_Pos); - GCLK_GENCTRL_GENEN_Pos = 16; // (GCLK_GENCTRL) Generic Clock Generator Enable */ + {$endif} + {$ifdef samc} + GCLK_GENCTRL_SRC_OSC48M = (GCLK_GENCTRL_SRC_OSC48M_Val shl GCLK_GENCTRL_SRC_Pos); + GCLK_GENCTRL_SRC_DPLL96M = (GCLK_GENCTRL_SRC_DPLL96M_Val shl GCLK_GENCTRL_SRC_Pos); + {$endif} + + {$ifdef samd} + SAM_GCLK_GENCTRL_OFFSET = 16; + {$endif} + {$ifdef samc} + SAM_GCLK_GENCTRL_OFFSET = 8; + {$endif} + + GCLK_GENCTRL_GENEN_Pos = 0+SAM_GCLK_GENCTRL_OFFSET; // (GCLK_GENCTRL) Generic Clock Generator Enable */ GCLK_GENCTRL_GENEN = (1 shl GCLK_GENCTRL_GENEN_Pos); - GCLK_GENCTRL_IDC_Pos = 17; // (GCLK_GENCTRL) Improve Duty Cycle */ + GCLK_GENCTRL_IDC_Pos = 1+SAM_GCLK_GENCTRL_OFFSET; // (GCLK_GENCTRL) Improve Duty Cycle */ GCLK_GENCTRL_IDC = (1 shl GCLK_GENCTRL_IDC_Pos); - GCLK_GENCTRL_OOV_Pos = 18; // (GCLK_GENCTRL) Output Off Value */ + GCLK_GENCTRL_OOV_Pos = 2+SAM_GCLK_GENCTRL_OFFSET; // (GCLK_GENCTRL) Output Off Value */ GCLK_GENCTRL_OOV = (1 shl GCLK_GENCTRL_OOV_Pos); - GCLK_GENCTRL_OE_Pos = 19; // (GCLK_GENCTRL) Output Enable */ + GCLK_GENCTRL_OE_Pos = 3+SAM_GCLK_GENCTRL_OFFSET; // (GCLK_GENCTRL) Output Enable */ GCLK_GENCTRL_OE = (1 shl GCLK_GENCTRL_OE_Pos); - GCLK_GENCTRL_DIVSEL_Pos = 20; // (GCLK_GENCTRL) Divide Selection */ + GCLK_GENCTRL_DIVSEL_Pos = 4+SAM_GCLK_GENCTRL_OFFSET; // (GCLK_GENCTRL) Divide Selection */ GCLK_GENCTRL_DIVSEL = (1 shl GCLK_GENCTRL_DIVSEL_Pos); - GCLK_GENCTRL_RUNSTDBY_Pos = 21; // (GCLK_GENCTRL) Run in Standby */ + GCLK_GENCTRL_RUNSTDBY_Pos = 5+SAM_GCLK_GENCTRL_OFFSET; // (GCLK_GENCTRL) Run in Standby */ GCLK_GENCTRL_RUNSTDBY = (1 shl GCLK_GENCTRL_RUNSTDBY_Pos); - GCLK_GENCTRL_MASK = $003F1F0F; // (GCLK_GENCTRL) MASK Register */ - - GCLK_GENDIV_OFFSET = $8; // (GCLK_GENDIV offset) Generic Clock Generator Division */ - GCLK_GENDIV_RESETVALUE = $00000000; // (GCLK_GENDIV reset_value) Generic Clock Generator Division */ - - GCLK_GENDIV_ID_Pos = 0; // (GCLK_GENDIV) Generic Clock Generator Selection */ - GCLK_GENDIV_ID_Msk = ($F shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK0_Val = $00; //(GCLK_GENDIV) Generic clock divisor 0 */ - GCLK_GENDIV_GEN_GCLK1_Val = $01; //(GCLK_GENDIV) Generic clock divisor 1 */ - GCLK_GENDIV_GEN_GCLK2_Val = $02; //(GCLK_GENDIV) Generic clock divisor 2 */ - GCLK_GENDIV_GEN_GCLK3_Val = $03; //(GCLK_GENDIV) Generic clock divisor 3 */ - GCLK_GENDIV_GEN_GCLK4_Val = $04; //(GCLK_GENDIV) Generic clock divisor 4 */ - GCLK_GENDIV_GEN_GCLK5_Val = $05; //(GCLK_GENDIV) Generic clock divisor 5 */ - GCLK_GENDIV_GEN_GCLK6_Val = $06; //(GCLK_GENDIV) Generic clock divisor 6 */ - GCLK_GENDIV_GEN_GCLK7_Val = $07; //(GCLK_GENDIV) Generic clock divisor 7 */ - GCLK_GENDIV_GEN_GCLK0 = (GCLK_GENDIV_GEN_GCLK0_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK1 = (GCLK_GENDIV_GEN_GCLK1_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK2 = (GCLK_GENDIV_GEN_GCLK2_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK3 = (GCLK_GENDIV_GEN_GCLK3_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK4 = (GCLK_GENDIV_GEN_GCLK4_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK5 = (GCLK_GENDIV_GEN_GCLK5_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK6 = (GCLK_GENDIV_GEN_GCLK6_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_GEN_GCLK7 = (GCLK_GENDIV_GEN_GCLK7_Val shl GCLK_GENDIV_ID_Pos); - GCLK_GENDIV_DIV_Pos = 8; // (GCLK_GENDIV) Division Factor */ - GCLK_GENDIV_DIV_Msk = ($FFFF shl GCLK_GENDIV_DIV_Pos); - GCLK_GENDIV_MASK = $00FFFF0F; // (GCLK_GENDIV) MASK Register */ + {$ifdef samc} + GCLK_GENCTRL_DIV_Pos = 8+SAM_GCLK_GENCTRL_OFFSET; // \brief (GCLK_GENCTRL) Division Factor */ + GCLK_GENCTRL_DIV_Msk = ($FFFF shl GCLK_GENCTRL_DIV_Pos); + {$endif} + + + GCLK_GENDIV_OFFSET = $8; // (GCLK_GENDIV offset) Generic Clock Generator Division */ + GCLK_GENDIV_RESETVALUE = $00000000; // (GCLK_GENDIV reset_value) Generic Clock Generator Division */ + + GCLK_GENDIV_ID_Pos = 0; // (GCLK_GENDIV) Generic Clock Generator Selection */ + GCLK_GENDIV_ID_Msk = ($F shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK0_Val = $00; //(GCLK_GENDIV) Generic clock divisor 0 */ + GCLK_GENDIV_GEN_GCLK1_Val = $01; //(GCLK_GENDIV) Generic clock divisor 1 */ + GCLK_GENDIV_GEN_GCLK2_Val = $02; //(GCLK_GENDIV) Generic clock divisor 2 */ + GCLK_GENDIV_GEN_GCLK3_Val = $03; //(GCLK_GENDIV) Generic clock divisor 3 */ + GCLK_GENDIV_GEN_GCLK4_Val = $04; //(GCLK_GENDIV) Generic clock divisor 4 */ + GCLK_GENDIV_GEN_GCLK5_Val = $05; //(GCLK_GENDIV) Generic clock divisor 5 */ + GCLK_GENDIV_GEN_GCLK6_Val = $06; //(GCLK_GENDIV) Generic clock divisor 6 */ + GCLK_GENDIV_GEN_GCLK7_Val = $07; //(GCLK_GENDIV) Generic clock divisor 7 */ + GCLK_GENDIV_GEN_GCLK0 = (GCLK_GENDIV_GEN_GCLK0_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK1 = (GCLK_GENDIV_GEN_GCLK1_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK2 = (GCLK_GENDIV_GEN_GCLK2_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK3 = (GCLK_GENDIV_GEN_GCLK3_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK4 = (GCLK_GENDIV_GEN_GCLK4_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK5 = (GCLK_GENDIV_GEN_GCLK5_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK6 = (GCLK_GENDIV_GEN_GCLK6_Val shl GCLK_GENDIV_ID_Pos); + GCLK_GENDIV_GEN_GCLK7 = (GCLK_GENDIV_GEN_GCLK7_Val shl GCLK_GENDIV_ID_Pos); + {$ifdef samd} + GCLK_GENDIV_DIV_Pos = 8; // (GCLK_GENDIV) Division Factor */ + GCLK_GENDIV_DIV_Msk = ($FFFF shl GCLK_GENDIV_DIV_Pos); + {$endif} GCLK_CTRL_OFFSET = $0; // (GCLK_CTRL offset) Control */ GCLK_CTRL_RESETVALUE = $00; // (GCLK_CTRL reset_value) Control */ diff --git a/Source/atsamcd/samcd-pm.inc b/Source/atsamcd/samcd-pm.inc index d801e07..a7651ff 100644 --- a/Source/atsamcd/samcd-pm.inc +++ b/Source/atsamcd/samcd-pm.inc @@ -11,6 +11,36 @@ const PM_APBAMASK_OFFSET = $18; // (PM_APBAMASK offset) APBA Mask */ PM_APBAMASK_RESETVALUE = $0000007F; // (PM_APBAMASK reset_value) APBA Mask */ + {$ifdef samc} + MCLK_APBAMASK_PAC0_Pos = 0; // (PM_APBAMASK) PAC0 APB Clock Enable */ + MCLK_APBAMASK_PAC0 = ($1 shl MCLK_APBAMASK_PAC0_Pos); + MCLK_APBAMASK_PM_Pos = 1; // (PM_APBAMASK) PM APB Clock Enable */ + MCLK_APBAMASK_PM = ($1 shl MCLK_APBAMASK_PM_Pos); + MCLK_APBAMASK_MCLK_Pos = 2; // brief (MCLK_APBAMASK) MCLK APB Clock Enable */ + MCLK_APBAMASK_MCLK = ($1 shl MCLK_APBAMASK_MCLK_Pos); + MCLK_APBAMASK_RSTC_Pos = 3; // brief (MCLK_APBAMASK) RSTC APB Clock Enable */ + MCLK_APBAMASK_RSTC = ($1 shl MCLK_APBAMASK_RSTC_Pos); + MCLK_APBAMASK_OSCCTRL_Pos = 4; // brief (MCLK_APBAMASK) OSCCTRL APB Clock Enable */ + MCLK_APBAMASK_OSCCTRL = ($1 shl MCLK_APBAMASK_OSCCTRL_Pos); + MCLK_APBAMASK_OSC32KCTRL_Pos = 5; // brief (MCLK_APBAMASK) OSC32KCTRL APB Clock Enable */ + MCLK_APBAMASK_OSC32KCTRL = ($1 shl MCLK_APBAMASK_OSC32KCTRL_Pos); + MCLK_APBAMASK_SUPC_Pos = 6; // brief (MCLK_APBAMASK) SUPC APB Clock Enable */ + MCLK_APBAMASK_SUPC = ($1 shl MCLK_APBAMASK_SUPC_Pos); + MCLK_APBAMASK_GCLK_Pos = 7; // brief (MCLK_APBAMASK) GCLK APB Clock Enable */ + MCLK_APBAMASK_GCLK = ($1 shl MCLK_APBAMASK_GCLK_Pos); + MCLK_APBAMASK_WDT_Pos = 8; // brief (MCLK_APBAMASK) WDT APB Clock Enable */ + MCLK_APBAMASK_WDT = ($1 shl MCLK_APBAMASK_WDT_Pos); + MCLK_APBAMASK_RTC_Pos = 9; // brief (MCLK_APBAMASK) RTC APB Clock Enable */ + MCLK_APBAMASK_RTC = ($1 shl MCLK_APBAMASK_RTC_Pos); + MCLK_APBAMASK_EIC_Pos = 10; // brief (MCLK_APBAMASK) EIC APB Clock Enable */ + MCLK_APBAMASK_EIC = ($1 shl MCLK_APBAMASK_EIC_Pos); + MCLK_APBAMASK_FREQM_Pos = 11; // brief (MCLK_APBAMASK) FREQM APB Clock Enable */ + MCLK_APBAMASK_FREQM = ($1 shl MCLK_APBAMASK_FREQM_Pos); + MCLK_APBAMASK_TSENS_Pos = 12; // brief (MCLK_APBAMASK) TSENS APB Clock Enable */ + MCLK_APBAMASK_TSENS = ($1 shl MCLK_APBAMASK_TSENS_Pos); + {$endif} + + {$ifdef samd} PM_APBAMASK_PAC0_Pos = 0; // (PM_APBAMASK) PAC0 APB Clock Enable */ PM_APBAMASK_PAC0 = (1 shl PM_APBAMASK_PAC0_Pos); PM_APBAMASK_PM_Pos = 1; // (PM_APBAMASK) PM APB Clock Enable */ @@ -25,7 +55,7 @@ const PM_APBAMASK_RTC = (1 shl PM_APBAMASK_RTC_Pos); PM_APBAMASK_EIC_Pos = 6; // (PM_APBAMASK) EIC APB Clock Enable */ PM_APBAMASK_EIC = (1 shl PM_APBAMASK_EIC_Pos); - PM_APBAMASK_MASK = $0000007F; // (PM_APBAMASK) MASK Register */ + {$endif} //******PM_APBB****** PM_APBBMASK_PORT_Pos = 3; // PORT APB Clock Enable */ @@ -60,7 +90,7 @@ const PM_APBCMASK_PTC = (1 shl PM_APBCMASK_PTC_Pos); {$endif} - {$ifdef samd21} + {$if defined(samd20) or defined(samd21)} PM_APBCMASK_PAC2_Pos = 0; // PAC2 APB Clock Enable */ PM_APBCMASK_PAC2 = (1 shl PM_APBCMASK_PAC2_Pos); PM_APBCMASK_EVSYS_Pos = 1; // EVSYS APB Clock Enable */ diff --git a/Source/atsamcd/samcd-sercom.inc b/Source/atsamcd/samcd-sercom.inc index 9b6e195..7255ae7 100644 --- a/Source/atsamcd/samcd-sercom.inc +++ b/Source/atsamcd/samcd-sercom.inc @@ -9,6 +9,15 @@ const SERCOM1_GCLK_ID_CORE = $0F; // Index of Generic Clock for Core SERCOM2_GCLK_ID_CORE = $10; // Index of Generic Clock for Core {$endif} + {$ifdef samd20} + SERCOM0_GCLK_ID_SLOW = $0C; // Index of Generic Clock for SMbus Timeout + SERCOM0_GCLK_ID_CORE = $0D; // Index of Generic Clock for Core + SERCOM1_GCLK_ID_CORE = $0E; // Index of Generic Clock for Core + SERCOM2_GCLK_ID_CORE = $0F; // Index of Generic Clock for Core + SERCOM3_GCLK_ID_CORE = $10; // Index of Generic Clock for Core + SERCOM4_GCLK_ID_CORE = $11; // Index of Generic Clock for Core + SERCOM5_GCLK_ID_CORE = $12; // Index of Generic Clock for Core + {$endif} {$ifdef samd21} SERCOM_GCLK_ID_SLOW = $13; // Index of Generic Clock for Slow SERCOM0_GCLK_ID_CORE = $14; // Index of Generic Clock for Core @@ -31,6 +40,10 @@ const SERCOM4_GCLK_ID_CORE = 23; // Index of Generic Clock for Core SERCOM5_GCLK_ID_SLOW = 24; // Index of Generic Clock for Slow SERCOM5_GCLK_ID_CORE = 25; // Index of Generic Clock for Core + SERCOM6_GCLK_ID_SLOW = 18; // Index of Generic Clock for Slow + SERCOM6_GCLK_ID_CORE = 41; // Index of Generic Clock for Core + SERCOM7_GCLK_ID_SLOW = 18; // Index of Generic Clock for Slow + SERCOM7_GCLK_ID_CORE = 42; // Index of Generic Clock for Core {$endif} SERCOM0_INT_MSB = 6; @@ -68,6 +81,11 @@ const SERCOM_I2CM_CTRLA_PINOUT = ($1 shl SERCOM_I2CM_CTRLA_PINOUT_Pos); SERCOM_I2CM_CTRLA_SDAHOLD_Pos = 20; // (SERCOM_I2CM_CTRLA) SDA Hold Time */ SERCOM_I2CM_CTRLA_SDAHOLD_Msk = ($3 shl SERCOM_I2CM_CTRLA_SDAHOLD_Pos); + SERCOM_I2CM_CTRLA_SCLSM_Pos = 27; // (SERCOM_I2CM_CTRLA) Pin Usage */ + SERCOM_I2CM_CTRLA_SCLSM = ($1 shl SERCOM_I2CM_CTRLA_SCLSM_Pos); + SERCOM_I2CM_CTRLA_LOWTOUT_Pos = 30; // (SERCOM_I2CM_CTRLA) Pin Usage */ + SERCOM_I2CM_CTRLA_LOWTOUT = ($1 shl SERCOM_I2CM_CTRLA_LOWTOUT_Pos); + SERCOM_I2CM_CTRLB_SMEN_Pos = 8; // (SERCOM_I2CM_CTRLB) Smart Mode Enable */ SERCOM_I2CM_CTRLB_SMEN = ($1 shl SERCOM_I2CM_CTRLB_SMEN_Pos); diff --git a/Source/atsamcd/samcd-sysctrl.inc b/Source/atsamcd/samcd-sysctrl.inc index ac4a97a..378baef 100644 --- a/Source/atsamcd/samcd-sysctrl.inc +++ b/Source/atsamcd/samcd-sysctrl.inc @@ -37,9 +37,105 @@ const SYSCTRL_OSC8M_ENABLE_Pos = 1; // \brief (SYSCTRL_OSC8M) Oscillator Enable */ SYSCTRL_OSC8M_ENABLE = ($01 shl SYSCTRL_OSC8M_ENABLE_Pos); + SYSCTRL_OSC8M_RUNSTDBY_Pos = 6; // \brief (SYSCTRL_OSC8M) Oscillator Run in Standby */ + SYSCTRL_OSC8M_RUNSTDBY = ($01 shl SYSCTRL_OSC8M_RUNSTDBY_Pos); + SYSCTRL_OSC8M_ONDEMAND_Pos = 7; // \brief (SYSCTRL_OSC8M) Oscillator OnDemand */ SYSCTRL_OSC8M_ONDEMAND = ($01 shl SYSCTRL_OSC8M_ONDEMAND_Pos); + {$ifdef samc} + OSCCTRL_OSC48MCTRL_ENABLE_Pos = 1; + OSCCTRL_OSC48MCTRL_ENABLE = ($01 shl OSCCTRL_OSC48MCTRL_ENABLE_Pos); + + OSCCTRL_OSC48MCTRL_RUNSTDBY_Pos = 6; + OSCCTRL_OSC48MCTRL_RUNSTDBY = ($01 shl OSCCTRL_OSC48MCTRL_RUNSTDBY_Pos); + + OSCCTRL_OSC48MCTRL_ONDEMAND_Pos = 7; + OSCCTRL_OSC48MCTRL_ONDEMAND = ($01 shl OSCCTRL_OSC48MCTRL_ONDEMAND_Pos); + + OSCCTRL_OSC48MDIV_DIV_Pos = 0; // \brief (OSCCTRL_OSC48MDIV) OSC48M Division Factor */ + OSCCTRL_OSC48MDIV_DIV_Msk = ($F shl OSCCTRL_OSC48MDIV_DIV_Pos); + + + OSCCTRL_STATUS_XOSCRDY_Pos = 0; //brief (OSCCTRL_STATUS) XOSC Ready */ + OSCCTRL_STATUS_XOSCRDY = ($1 shl OSCCTRL_STATUS_XOSCRDY_Pos); + OSCCTRL_STATUS_XOSCFAIL_Pos = 1; //brief (OSCCTRL_STATUS) XOSC Clock Failure Detector */ + OSCCTRL_STATUS_XOSCFAIL = ($1 shl OSCCTRL_STATUS_XOSCFAIL_Pos); + OSCCTRL_STATUS_XOSCCKSW_Pos = 2; //brief (OSCCTRL_STATUS) XOSC Clock Switch */ + OSCCTRL_STATUS_XOSCCKSW = ($1 shl OSCCTRL_STATUS_XOSCCKSW_Pos); + OSCCTRL_STATUS_OSC48MRDY_Pos = 4; //brief (OSCCTRL_STATUS) OSC48M Ready */ + OSCCTRL_STATUS_OSC48MRDY = ($1 shl OSCCTRL_STATUS_OSC48MRDY_Pos); + OSCCTRL_STATUS_DPLLLCKR_Pos = 8; //brief (OSCCTRL_STATUS) DPLL Lock Rise */ + OSCCTRL_STATUS_DPLLLCKR = ($1 shl OSCCTRL_STATUS_DPLLLCKR_Pos); + OSCCTRL_STATUS_DPLLLCKF_Pos = 9; //brief (OSCCTRL_STATUS) DPLL Lock Fall */ + OSCCTRL_STATUS_DPLLLCKF = ($1 shl OSCCTRL_STATUS_DPLLLCKF_Pos); + OSCCTRL_STATUS_DPLLTO_Pos = 10; //brief (OSCCTRL_STATUS) DPLL Timeout */ + OSCCTRL_STATUS_DPLLTO = ($1 shl OSCCTRL_STATUS_DPLLTO_Pos); + OSCCTRL_STATUS_DPLLLDRTO_Pos = 11; //brief (OSCCTRL_STATUS) DPLL Ratio Ready */ + OSCCTRL_STATUS_DPLLLDRTO = ($1 shl OSCCTRL_STATUS_DPLLLDRTO_Pos); + + + OSC32KCTRL_XOSC32K_ENABLE_Pos = 1; //brief (OSC32KCTRL_XOSC32K) Oscillator Enable */ + OSC32KCTRL_XOSC32K_ENABLE = ($1 shl OSC32KCTRL_XOSC32K_ENABLE_Pos); + OSC32KCTRL_XOSC32K_XTALEN_Pos = 2; //brief (OSC32KCTRL_XOSC32K) Crystal Oscillator Enable */ + OSC32KCTRL_XOSC32K_XTALEN = ($1 shl OSC32KCTRL_XOSC32K_XTALEN_Pos); + OSC32KCTRL_XOSC32K_EN32K_Pos = 3; //brief (OSC32KCTRL_XOSC32K) 32kHz Output Enable */ + OSC32KCTRL_XOSC32K_EN32K = ($1 shl OSC32KCTRL_XOSC32K_EN32K_Pos); + OSC32KCTRL_XOSC32K_EN1K_Pos = 4; //brief (OSC32KCTRL_XOSC32K) 1kHz Output Enable */ + OSC32KCTRL_XOSC32K_EN1K = ($1 shl OSC32KCTRL_XOSC32K_EN1K_Pos); + OSC32KCTRL_XOSC32K_RUNSTDBY_Pos = 6; //brief (OSC32KCTRL_XOSC32K) Run in Standby */ + OSC32KCTRL_XOSC32K_RUNSTDBY = ($1 shl OSC32KCTRL_XOSC32K_RUNSTDBY_Pos); + OSC32KCTRL_XOSC32K_ONDEMAND_Pos = 7; //brief (OSC32KCTRL_XOSC32K) On Demand Control */ + OSC32KCTRL_XOSC32K_ONDEMAND = ($1 shl OSC32KCTRL_XOSC32K_ONDEMAND_Pos); + OSC32KCTRL_XOSC32K_STARTUP_Pos = 8; //brief (OSC32KCTRL_XOSC32K) Oscillator Start-Up Time */ + OSC32KCTRL_XOSC32K_STARTUP_Msk = ($7 shl OSC32KCTRL_XOSC32K_STARTUP_Pos); + //OSC32KCTRL_XOSC32K_STARTUP(value) (OSC32KCTRL_XOSC32K_STARTUP_Msk & ((value) shl OSC32KCTRL_XOSC32K_STARTUP_Pos)) + OSC32KCTRL_XOSC32K_WRTLOCK_Pos = 12; //brief (OSC32KCTRL_XOSC32K) Write Lock */ + OSC32KCTRL_XOSC32K_WRTLOCK = ($1 shl OSC32KCTRL_XOSC32K_WRTLOCK_Pos); + + OSC32KCTRL_STATUS_XOSC32KRDY_Pos = 0; //brief (OSC32KCTRL_STATUS) XOSC32K Ready */ + OSC32KCTRL_STATUS_XOSC32KRDY = ($1 shl OSC32KCTRL_STATUS_XOSC32KRDY_Pos); + OSC32KCTRL_STATUS_OSC32KRDY_Pos = 1; //brief (OSC32KCTRL_STATUS) OSC32K Ready */ + OSC32KCTRL_STATUS_OSC32KRDY = ($1 shl OSC32KCTRL_STATUS_OSC32KRDY_Pos); + OSC32KCTRL_STATUS_CLKFAIL_Pos = 2; //brief (OSC32KCTRL_STATUS) XOSC32K Clock Failure Detector */ + OSC32KCTRL_STATUS_CLKFAIL = ($1 shl OSC32KCTRL_STATUS_CLKFAIL_Pos); + OSC32KCTRL_STATUS_CLKSW_Pos = 3; //brief (OSC32KCTRL_STATUS) XOSC32K Clock switch */ + OSC32KCTRL_STATUS_CLKSW = ($1 shl OSC32KCTRL_STATUS_CLKSW_Pos); + + + OSCCTRL_DPLLRATIO_LDR_Pos = 0; // \brief (OSCCTRL_DPLLRATIO) Loop Divider Ratio */ + OSCCTRL_DPLLRATIO_LDR_Msk = ($FFF shl OSCCTRL_DPLLRATIO_LDR_Pos); + //OSCCTRL_DPLLRATIO_LDR(value) (OSCCTRL_DPLLRATIO_LDR_Msk & ((value) << OSCCTRL_DPLLRATIO_LDR_Pos)) + OSCCTRL_DPLLRATIO_LDRFRAC_Pos = 16; // \brief (OSCCTRL_DPLLRATIO) Loop Divider Ratio Fractional Part */ + OSCCTRL_DPLLRATIO_LDRFRAC_Msk = ($F shl OSCCTRL_DPLLRATIO_LDRFRAC_Pos); + //OSCCTRL_DPLLRATIO_LDRFRAC(value) (OSCCTRL_DPLLRATIO_LDRFRAC_Msk & ((value) << OSCCTRL_DPLLRATIO_LDRFRAC_Pos)) + + + OSCCTRL_DPLLCTRLB_FILTER_Pos = 0; //brief (OSCCTRL_DPLLCTRLB) Proportional Integral Filter Selection */ + OSCCTRL_DPLLCTRLB_FILTER_Msk = ($3 shl OSCCTRL_DPLLCTRLB_FILTER_Pos); + //OSCCTRL_DPLLCTRLB_FILTER(value) (OSCCTRL_DPLLCTRLB_FILTER_Msk & ((value) shl OSCCTRL_DPLLCTRLB_FILTER_Pos)) + OSCCTRL_DPLLCTRLB_LPEN_Pos = 2; //brief (OSCCTRL_DPLLCTRLB) Low-Power Enable */ + OSCCTRL_DPLLCTRLB_LPEN = ($1 shl OSCCTRL_DPLLCTRLB_LPEN_Pos); + OSCCTRL_DPLLCTRLB_WUF_Pos = 3; //brief (OSCCTRL_DPLLCTRLB) Wake Up Fast */ + OSCCTRL_DPLLCTRLB_WUF = ($1 shl OSCCTRL_DPLLCTRLB_WUF_Pos); + OSCCTRL_DPLLCTRLB_REFCLK_Pos = 4; //brief (OSCCTRL_DPLLCTRLB) Reference Clock Selection */ + OSCCTRL_DPLLCTRLB_REFCLK_Msk = ($3 shl OSCCTRL_DPLLCTRLB_REFCLK_Pos); + //OSCCTRL_DPLLCTRLB_REFCLK(value) (OSCCTRL_DPLLCTRLB_REFCLK_Msk & ((value) shl OSCCTRL_DPLLCTRLB_REFCLK_Pos)) + OSCCTRL_DPLLCTRLB_LTIME_Pos = 8; //brief (OSCCTRL_DPLLCTRLB) Lock Time */ + OSCCTRL_DPLLCTRLB_LTIME_Msk = ($7 shl OSCCTRL_DPLLCTRLB_LTIME_Pos); + //OSCCTRL_DPLLCTRLB_LTIME(value) (OSCCTRL_DPLLCTRLB_LTIME_Msk & ((value) shl OSCCTRL_DPLLCTRLB_LTIME_Pos)) + OSCCTRL_DPLLCTRLB_LBYPASS_Pos = 12; //brief (OSCCTRL_DPLLCTRLB) Lock Bypass */ + OSCCTRL_DPLLCTRLB_LBYPASS = ($1 shl OSCCTRL_DPLLCTRLB_LBYPASS_Pos); + OSCCTRL_DPLLCTRLB_DIV_Pos = 16; //brief (OSCCTRL_DPLLCTRLB) Clock Divider */ + OSCCTRL_DPLLCTRLB_DIV_Msk = ($7FF shl OSCCTRL_DPLLCTRLB_DIV_Pos); + //OSCCTRL_DPLLCTRLB_DIV(value) (OSCCTRL_DPLLCTRLB_DIV_Msk & ((value) shl OSCCTRL_DPLLCTRLB_DIV_Pos)) + + + + {$endif} + + + SYSCTRL_PCLKSR_OFFSET = $0C; // (SYSCTRL_PCLKSR offset) Power and Clocks Status */ SYSCTRL_PCLKSR_RESETVALUE = $00000000; // (SYSCTRL_PCLKSR reset_value) Power and Clocks Status */ diff --git a/Source/atsamcd/samcd-tc.inc b/Source/atsamcd/samcd-tc.inc index 5fb9dbc..97fa66b 100644 --- a/Source/atsamcd/samcd-tc.inc +++ b/Source/atsamcd/samcd-tc.inc @@ -1,5 +1,12 @@ //* ========== Instance parameters for TC1 peripheral ========== */ const + {$ifdef samd20} + GCLK_CLKCTRL_ID_TC0_TC1_Val = $13; + GCLK_CLKCTRL_ID_TC2_TC3_Val = $14; + GCLK_CLKCTRL_ID_TC4_TC5_Val = $15; + GCLK_CLKCTRL_ID_TC6_TC7_Val = $16; + {$endif} + TC1_DMAC_ID_MC_0 = 13; TC1_DMAC_ID_MC_1 = 14; TC1_DMAC_ID_MC_LSB = 13;