| @@ -0,0 +1 @@ | |||
| IAR/Debug/ | |||
| @@ -0,0 +1,40 @@ | |||
| @REM This batch file has been generated by the IAR Embedded Workbench | |||
| @REM C-SPY Debugger, as an aid to preparing a command line for running | |||
| @REM the cspybat command line utility using the appropriate settings. | |||
| @REM | |||
| @REM Note that this file is generated every time a new debug session | |||
| @REM is initialized, so you may want to move or rename the file before | |||
| @REM making changes. | |||
| @REM | |||
| @REM You can launch cspybat by typing the name of this batch file followed | |||
| @REM by the name of the debug file (usually an ELF/DWARF or UBROF file). | |||
| @REM | |||
| @REM Read about available command line parameters in the C-SPY Debugging | |||
| @REM Guide. Hints about additional command line parameters that may be | |||
| @REM useful in specific cases: | |||
| @REM --download_only Downloads a code image without starting a debug | |||
| @REM session afterwards. | |||
| @REM --silent Omits the sign-on message. | |||
| @REM --timeout Limits the maximum allowed execution time. | |||
| @REM | |||
| @echo off | |||
| if not "%~1" == "" goto debugFile | |||
| @echo on | |||
| "F:\AAAAA\IAR\common\bin\cspybat" -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.general.xcl" --backend -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.driver.xcl" | |||
| @echo off | |||
| goto end | |||
| :debugFile | |||
| @echo on | |||
| "F:\AAAAA\IAR\common\bin\cspybat" -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.general.xcl" "--debug_file=%~1" --backend -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.driver.xcl" | |||
| @echo off | |||
| :end | |||
| @@ -0,0 +1,31 @@ | |||
| param([String]$debugfile = ""); | |||
| # This powershell file has been generated by the IAR Embedded Workbench | |||
| # C - SPY Debugger, as an aid to preparing a command line for running | |||
| # the cspybat command line utility using the appropriate settings. | |||
| # | |||
| # Note that this file is generated every time a new debug session | |||
| # is initialized, so you may want to move or rename the file before | |||
| # making changes. | |||
| # | |||
| # You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed | |||
| # by the name of the debug file (usually an ELF / DWARF or UBROF file). | |||
| # | |||
| # Read about available command line parameters in the C - SPY Debugging | |||
| # Guide. Hints about additional command line parameters that may be | |||
| # useful in specific cases : | |||
| # --download_only Downloads a code image without starting a debug | |||
| # session afterwards. | |||
| # --silent Omits the sign - on message. | |||
| # --timeout Limits the maximum allowed execution time. | |||
| # | |||
| if ($debugfile -eq "") | |||
| { | |||
| & "F:\AAAAA\IAR\common\bin\cspybat" -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.general.xcl" --backend -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.driver.xcl" | |||
| } | |||
| else | |||
| { | |||
| & "F:\AAAAA\IAR\common\bin\cspybat" -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.general.xcl" --debug_file=$debugfile --backend -f "F:\Project_IAR\NXP_MKV56_Task\IAR\settings\test01.Debug.driver.xcl" | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| "--endian=little" | |||
| "--cpu=Cortex-M7" | |||
| "--fpu=VFPv5_SP" | |||
| "-p" | |||
| "F:\AAAAA\IAR\arm\CONFIG\debugger\NXP\MKV56F512xxx24.ddf" | |||
| "--semihosting" | |||
| "--device=MKV56F512xxx24" | |||
| "--drv_communication=USB0" | |||
| "--drv_interface_speed=auto" | |||
| "--jlink_initial_speed=1000" | |||
| "--jlink_reset_strategy=0,0" | |||
| "--drv_interface=SWD" | |||
| "--drv_catch_exceptions=0x000" | |||
| @@ -0,0 +1,15 @@ | |||
| "F:\AAAAA\IAR\arm\bin\armproc.dll" | |||
| "F:\AAAAA\IAR\arm\bin\armjlink2.dll" | |||
| "F:\Project_IAR\NXP_MKV56_Task\IAR\Debug\Exe\test01.out" | |||
| --plugin="F:\AAAAA\IAR\arm\bin\armbat.dll" | |||
| --device_macro="F:\AAAAA\IAR\arm\config\debugger\NXP\KV5x.dmac" | |||
| --flash_loader="F:\AAAAA\IAR\arm\config\flashloader\NXP\FlashKV5xF512.board" | |||
| @@ -0,0 +1,13 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <crun> | |||
| <version>1</version> | |||
| <filter_entries> | |||
| <filter index="0" type="default"> | |||
| <type>*</type> | |||
| <start_file>*</start_file> | |||
| <end_file>*</end_file> | |||
| <action_debugger>0</action_debugger> | |||
| <action_log>1</action_log> | |||
| </filter> | |||
| </filter_entries> | |||
| </crun> | |||
| @@ -0,0 +1,165 @@ | |||
| <?xml version="1.0"?> | |||
| <settings> | |||
| <Stack> | |||
| <FillEnabled>0</FillEnabled> | |||
| <OverflowWarningsEnabled>1</OverflowWarningsEnabled> | |||
| <WarningThreshold>90</WarningThreshold> | |||
| <SpWarningsEnabled>1</SpWarningsEnabled> | |||
| <WarnLogOnly>1</WarnLogOnly> | |||
| <UseTrigger>1</UseTrigger> | |||
| <TriggerName>main</TriggerName> | |||
| <LimitSize>0</LimitSize> | |||
| <ByteLimit>50</ByteLimit> | |||
| </Stack> | |||
| <Interrupts> | |||
| <Enabled>1</Enabled> | |||
| </Interrupts> | |||
| <MemConfig> | |||
| <Base>1</Base> | |||
| <Manual>0</Manual> | |||
| <Ddf>1</Ddf> | |||
| <TypeViol>0</TypeViol> | |||
| <Stop>1</Stop> | |||
| </MemConfig> | |||
| <Trace1> | |||
| <Enabled>0</Enabled> | |||
| <ShowSource>1</ShowSource> | |||
| </Trace1> | |||
| <Simulator> | |||
| <Freq>10000000</Freq> | |||
| <FreqHi>0</FreqHi> | |||
| <MultiCoreRunAll>1</MultiCoreRunAll> | |||
| </Simulator> | |||
| <JLinkDriver> | |||
| <CStepIntDis>_ 0</CStepIntDis> | |||
| <LeaveTargetRunning>_ 0</LeaveTargetRunning> | |||
| </JLinkDriver> | |||
| <DebugChecksum> | |||
| <Checksum>2228608824</Checksum> | |||
| </DebugChecksum> | |||
| <Exceptions> | |||
| <StopOnUncaught>_ 0</StopOnUncaught> | |||
| <StopOnThrow>_ 0</StopOnThrow> | |||
| </Exceptions> | |||
| <Disassembly> | |||
| <MixedMode>1</MixedMode> | |||
| <InstrCount>0</InstrCount> | |||
| </Disassembly> | |||
| <CodeCoverage> | |||
| <Enabled>0</Enabled> | |||
| <ShowSource>0</ShowSource> | |||
| <HideCovered>0</HideCovered> | |||
| </CodeCoverage> | |||
| <CallStack> | |||
| <ShowArgs>0</ShowArgs> | |||
| </CallStack> | |||
| <SWOTraceHWSettings> | |||
| <OverrideDefaultClocks>0</OverrideDefaultClocks> | |||
| <CpuClock>72000000</CpuClock> | |||
| <ClockAutoDetect>0</ClockAutoDetect> | |||
| <ClockWanted>2000000</ClockWanted> | |||
| <JtagSpeed>2000000</JtagSpeed> | |||
| <Prescaler>36</Prescaler> | |||
| <TimeStampPrescIndex>0</TimeStampPrescIndex> | |||
| <TimeStampPrescData>0</TimeStampPrescData> | |||
| <PcSampCYCTAP>1</PcSampCYCTAP> | |||
| <PcSampPOSTCNT>15</PcSampPOSTCNT> | |||
| <PcSampIndex>0</PcSampIndex> | |||
| <DataLogMode>0</DataLogMode> | |||
| <ITMportsEnable>0</ITMportsEnable> | |||
| <ITMportsTermIO>0</ITMportsTermIO> | |||
| <ITMportsLogFile>0</ITMportsLogFile> | |||
| <ITMlogFile>$PROJ_DIR$\ITM.log</ITMlogFile> | |||
| </SWOTraceHWSettings> | |||
| <Trace2> | |||
| <Enabled>0</Enabled> | |||
| <ShowSource>0</ShowSource> | |||
| </Trace2> | |||
| <SWOTraceWindow> | |||
| <PcSampling>0</PcSampling> | |||
| <InterruptLogs>0</InterruptLogs> | |||
| <ForcedTimeStamps>0</ForcedTimeStamps> | |||
| <EventCPI>0</EventCPI> | |||
| <EventEXC>0</EventEXC> | |||
| <EventFOLD>0</EventFOLD> | |||
| <EventLSU>0</EventLSU> | |||
| <EventSLEEP>0</EventSLEEP> | |||
| </SWOTraceWindow> | |||
| <PowerLog> | |||
| <Title_0>I0</Title_0> | |||
| <Symbol_0>0 4 0</Symbol_0> | |||
| <LogEnabled>0</LogEnabled> | |||
| <GraphEnabled>0</GraphEnabled> | |||
| <ShowTimeLog>1</ShowTimeLog> | |||
| <LiveEnabled>0</LiveEnabled> | |||
| <LiveFile>PowerLogLive.log</LiveFile> | |||
| </PowerLog> | |||
| <DataLog> | |||
| <LogEnabled>0</LogEnabled> | |||
| <GraphEnabled>0</GraphEnabled> | |||
| <ShowTimeLog>1</ShowTimeLog> | |||
| <SumEnabled>0</SumEnabled> | |||
| <ShowTimeSum>1</ShowTimeSum> | |||
| </DataLog> | |||
| <InterruptLog> | |||
| <LogEnabled>0</LogEnabled> | |||
| <GraphEnabled>0</GraphEnabled> | |||
| <ShowTimeLog>1</ShowTimeLog> | |||
| <SumEnabled>0</SumEnabled> | |||
| <ShowTimeSum>1</ShowTimeSum> | |||
| <SumSortOrder>0</SumSortOrder> | |||
| </InterruptLog> | |||
| <EventLog> | |||
| <Title_0>Ch3</Title_0> | |||
| <Symbol_0>0 0 1</Symbol_0> | |||
| <Title_1>Ch2</Title_1> | |||
| <Symbol_1>0 0 1</Symbol_1> | |||
| <Title_2>Ch1</Title_2> | |||
| <Symbol_2>0 0 1</Symbol_2> | |||
| <Title_3>Ch0</Title_3> | |||
| <Symbol_3>0 0 1</Symbol_3> | |||
| <LogEnabled>0</LogEnabled> | |||
| <GraphEnabled>0</GraphEnabled> | |||
| <ShowTimeLog>1</ShowTimeLog> | |||
| <SumEnabled>0</SumEnabled> | |||
| <ShowTimeSum>1</ShowTimeSum> | |||
| <SumSortOrder>0</SumSortOrder> | |||
| </EventLog> | |||
| <TermIOLog> | |||
| <LoggingEnabled>_ 0</LoggingEnabled> | |||
| <LogFile>_ ""</LogFile> | |||
| </TermIOLog> | |||
| <LogFile> | |||
| <LoggingEnabled>_ 0</LoggingEnabled> | |||
| <LogFile>_ ""</LogFile> | |||
| <Category>_ 0</Category> | |||
| </LogFile> | |||
| <DriverProfiling> | |||
| <Enabled>0</Enabled> | |||
| <Mode>3</Mode> | |||
| <Graph>0</Graph> | |||
| <Symbiont>0</Symbiont> | |||
| <Exclusions /> | |||
| </DriverProfiling> | |||
| <CallStackLog> | |||
| <Enabled>0</Enabled> | |||
| </CallStackLog> | |||
| <CallStackStripe> | |||
| <ShowTiming>1</ShowTiming> | |||
| </CallStackStripe> | |||
| <PowerProbe> | |||
| <Frequency>10000</Frequency> | |||
| <Probe0>I0</Probe0> | |||
| <ProbeSetup0>2 1 1 2 0 0</ProbeSetup0> | |||
| </PowerProbe> | |||
| <DisassembleMode> | |||
| <mode>0</mode> | |||
| </DisassembleMode> | |||
| <Breakpoints2> | |||
| <Count>0</Count> | |||
| </Breakpoints2> | |||
| <Aliases> | |||
| <Count>0</Count> | |||
| <SuppressDialog>0</SuppressDialog> | |||
| </Aliases> | |||
| </settings> | |||
| @@ -0,0 +1 @@ | |||
| | |||
| @@ -0,0 +1,39 @@ | |||
| [BREAKPOINTS] | |||
| ForceImpTypeAny = 0 | |||
| ShowInfoWin = 1 | |||
| EnableFlashBP = 2 | |||
| BPDuringExecution = 0 | |||
| [CFI] | |||
| CFISize = 0x00 | |||
| CFIAddr = 0x00 | |||
| [CPU] | |||
| MonModeVTableAddr = 0xFFFFFFFF | |||
| MonModeDebug = 0 | |||
| MaxNumAPs = 0 | |||
| LowPowerHandlingMode = 0 | |||
| OverrideMemMap = 0 | |||
| AllowSimulation = 1 | |||
| ScriptFile="" | |||
| [FLASH] | |||
| CacheExcludeSize = 0x00 | |||
| CacheExcludeAddr = 0x00 | |||
| MinNumBytesFlashDL = 0 | |||
| SkipProgOnCRCMatch = 1 | |||
| VerifyDownload = 1 | |||
| AllowCaching = 1 | |||
| EnableFlashDL = 2 | |||
| Override = 0 | |||
| Device="ARM7" | |||
| [GENERAL] | |||
| WorkRAMSize = 0x00 | |||
| WorkRAMAddr = 0x00 | |||
| RAMUsageLimit = 0x00 | |||
| [SWO] | |||
| SWOLogFile="" | |||
| [MEM] | |||
| RdOverrideOrMask = 0x00 | |||
| RdOverrideAndMask = 0xFFFFFFFF | |||
| RdOverrideAddr = 0xFFFFFFFF | |||
| WrOverrideOrMask = 0x00 | |||
| WrOverrideAndMask = 0xFFFFFFFF | |||
| WrOverrideAddr = 0xFFFFFFFF | |||
| @@ -0,0 +1,296 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project> | |||
| <fileVersion>4</fileVersion> | |||
| <fileChecksum>2510143316</fileChecksum> | |||
| <configuration> | |||
| <name>Debug</name> | |||
| <outputs> | |||
| <file>$PROJ_DIR$\Debug\Obj\system_MKV56F24.__cstat.et</file> | |||
| <file>$PROJ_DIR$\..\startup\system_MKV56F24.c</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_clock.c</file> | |||
| <file>$PROJ_DIR$\..\user\main.c</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\DLib_Config_Normal.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\system_MKV56F24.xcl</file> | |||
| <file>$PROJ_DIR$\..\Include\core_cm7.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\ycheck.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_gpio.o</file> | |||
| <file>$PROJ_DIR$\..\startup\MKV56F24.h</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_common.c</file> | |||
| <file>$PROJ_DIR$\..\startup\startup_MKV56F24.s</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\DLib_Product_string.h</file> | |||
| <file>$TOOLKIT_DIR$\lib\rt7M_tl.a</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_port.h</file> | |||
| <file>$PROJ_DIR$\Debug\List\test01.map</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_gpio.c</file> | |||
| <file>$PROJ_DIR$\..\Include\cmsis_version.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\yvals.h</file> | |||
| <file>$TOOLKIT_DIR$\config\linker\NXP\MKV5xF512xxx24.icf</file> | |||
| <file>$TOOLKIT_DIR$\lib\m7M_tls.a</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\system_MKV56F24.o</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\iccarm_builtin.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\main.__cstat.et</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\startup_MKV56F24.o</file> | |||
| <file>$PROJ_DIR$\..\startup\system_MKV56F24.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_common.xcl</file> | |||
| <file>$PROJ_DIR$\..\Include\cmsis_iccarm.h</file> | |||
| <file>$TOOLKIT_DIR$\lib\dl7M_tln.a</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_common.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\DLib_Product_stdlib.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\string.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\ysizet.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\stdlib.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\assert.h</file> | |||
| <file>$TOOLKIT_DIR$\lib\shb_l.a</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\test01.pbd</file> | |||
| <file>$PROJ_DIR$\..\utilities\debug_console\fsl_debug_console.c</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_gpio.__cstat.et</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_common.__cstat.et</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_clock.xcl</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_clock.o</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\stdbool.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_assert.__cstat.et</file> | |||
| <file>$PROJ_DIR$\Debug\Exe\test01.out</file> | |||
| <file>$PROJ_DIR$\..\startup\MKV56F24_features.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\main.o</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_gpio.xcl</file> | |||
| <file>$PROJ_DIR$\..\Include\cmsis_compiler.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_common.o</file> | |||
| <file>$PROJ_DIR$\..\Include\mpu_armv7.h</file> | |||
| <file>$PROJ_DIR$\..\startup\fsl_device_registers.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\DLib_Defaults.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\stdint.h</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_clock.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\main.xcl</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\DLib_Product.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\stddef.h</file> | |||
| <file>$PROJ_DIR$\..\drivers\fsl_gpio.h</file> | |||
| <file>$PROJ_DIR$\..\utilities\str\fsl_str.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\stdarg.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\math.h</file> | |||
| <file>$TOOLKIT_DIR$\inc\c\DLib_float_setup.h</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_debug_console.xcl</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_assert.xcl</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_str.__cstat.et</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_str.o</file> | |||
| <file>$PROJ_DIR$\..\utilities\str\fsl_str.c</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_str.xcl</file> | |||
| <file>$PROJ_DIR$\..\utilities\debug_console\fsl_debug_console_conf.h</file> | |||
| <file>$PROJ_DIR$\..\utilities\fsl_assert.c</file> | |||
| <file>$PROJ_DIR$\Debug\Obj\fsl_assert.o</file> | |||
| <file>$PROJ_DIR$\..\..\NXP_TestSDK\startup\system_MKV56F24.c</file> | |||
| </outputs> | |||
| <file> | |||
| <name>[ROOT_NODE]</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ILINK</name> | |||
| <file> 44 15</file> | |||
| </tool> | |||
| </outputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\startup\system_MKV56F24.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 21</file> | |||
| </tool> | |||
| <tool> | |||
| <name>__cstat</name> | |||
| <file> 0</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 5</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 53 7 18 52 4 56 51 9 6 17 48 27 22 50 25 45</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\drivers\fsl_clock.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 41</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 40</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 54 29 34 7 18 52 4 56 42 53 31 32 12 33 30 57 51 9 6 17 48 27 22 50 25 45</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\user\main.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 46</file> | |||
| </tool> | |||
| <tool> | |||
| <name>__cstat</name> | |||
| <file> 23</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 55</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 9 6 53 7 18 52 4 56 17 48 27 22 50 25 29 34 42 31 32 12 33 30 57 51 45 54 58 14</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\drivers\fsl_common.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 49</file> | |||
| </tool> | |||
| <tool> | |||
| <name>__cstat</name> | |||
| <file> 39</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 26</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 29 34 7 18 52 4 56 42 53 31 32 12 33 30 57 51 9 6 17 48 27 22 50 25 45 54</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\startup\startup_MKV56F24.s</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>AARM</name> | |||
| <file> 24</file> | |||
| </tool> | |||
| </outputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\drivers\fsl_gpio.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 8</file> | |||
| </tool> | |||
| <tool> | |||
| <name>__cstat</name> | |||
| <file> 38</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 47</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 58 29 34 7 18 52 4 56 42 53 31 32 12 33 30 57 51 9 6 17 48 27 22 50 25 45 54</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\utilities\debug_console\fsl_debug_console.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 63</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 60 33 7 18 52 4 56 32 30 69 29 34 42 53 31 12 57 51 9 6 17 48 27 22 50 25 45 54 59</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\Debug\Exe\test01.out</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ILINK</name> | |||
| <file> 15</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ILINK</name> | |||
| <file> 19 41 49 8 46 24 21 35 13 20 28</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\utilities\str\fsl_str.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 66</file> | |||
| </tool> | |||
| <tool> | |||
| <name>__cstat</name> | |||
| <file> 65</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 68</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 61 7 18 52 4 56 62 60 33 32 30 59 29 34 42 53 31 12 57 51 9 6 17 48 27 22 50 25 45 54 69</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| <file> | |||
| <name>$PROJ_DIR$\..\utilities\fsl_assert.c</name> | |||
| <outputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 71</file> | |||
| </tool> | |||
| <tool> | |||
| <name>__cstat</name> | |||
| <file> 43</file> | |||
| </tool> | |||
| <tool> | |||
| <name>BICOMP</name> | |||
| <file> 64</file> | |||
| </tool> | |||
| </outputs> | |||
| <inputs> | |||
| <tool> | |||
| <name>ICCARM</name> | |||
| <file> 29 34 7 18 52 4 56 42 53 31 32 12 33 30 57 51 9 6 17 48 27 22 50 25 45 54</file> | |||
| </tool> | |||
| </inputs> | |||
| </file> | |||
| </configuration> | |||
| <configuration> | |||
| <name>Release</name> | |||
| <outputs /> | |||
| <forcedrebuild> | |||
| <name>[MULTI_TOOL]</name> | |||
| <tool>ILINK</tool> | |||
| </forcedrebuild> | |||
| </configuration> | |||
| </project> | |||
| @@ -0,0 +1,7 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <workspace> | |||
| <project> | |||
| <path>$WS_DIR$\test01.ewp</path> | |||
| </project> | |||
| <batchBuild /> | |||
| </workspace> | |||
| @@ -0,0 +1,378 @@ | |||
| /* ---------------------------------------------------------------------- | |||
| * Project: CMSIS DSP Library | |||
| * Title: arm_common_tables.h | |||
| * Description: Extern declaration for common tables | |||
| * | |||
| * $Date: 27. January 2017 | |||
| * $Revision: V.1.5.1 | |||
| * | |||
| * Target Processor: Cortex-M cores | |||
| * -------------------------------------------------------------------- */ | |||
| /* | |||
| * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef _ARM_COMMON_TABLES_H | |||
| #define _ARM_COMMON_TABLES_H | |||
| #include "arm_math.h" | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024) | |||
| extern const uint16_t armBitRevTable[1024]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) | |||
| extern const float32_t twiddleCoef_16[32]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) | |||
| extern const float32_t twiddleCoef_32[64]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) | |||
| extern const float32_t twiddleCoef_64[128]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) | |||
| extern const float32_t twiddleCoef_128[256]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) | |||
| extern const float32_t twiddleCoef_256[512]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) | |||
| extern const float32_t twiddleCoef_512[1024]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) | |||
| extern const float32_t twiddleCoef_1024[2048]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) | |||
| extern const float32_t twiddleCoef_2048[4096]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) | |||
| extern const float32_t twiddleCoef_4096[8192]; | |||
| #define twiddleCoef twiddleCoef_4096 | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) | |||
| extern const q31_t twiddleCoef_16_q31[24]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) | |||
| extern const q31_t twiddleCoef_32_q31[48]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) | |||
| extern const q31_t twiddleCoef_64_q31[96]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) | |||
| extern const q31_t twiddleCoef_128_q31[192]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) | |||
| extern const q31_t twiddleCoef_256_q31[384]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) | |||
| extern const q31_t twiddleCoef_512_q31[768]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) | |||
| extern const q31_t twiddleCoef_1024_q31[1536]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) | |||
| extern const q31_t twiddleCoef_2048_q31[3072]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) | |||
| extern const q31_t twiddleCoef_4096_q31[6144]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) | |||
| extern const q15_t twiddleCoef_16_q15[24]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) | |||
| extern const q15_t twiddleCoef_32_q15[48]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) | |||
| extern const q15_t twiddleCoef_64_q15[96]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) | |||
| extern const q15_t twiddleCoef_128_q15[192]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) | |||
| extern const q15_t twiddleCoef_256_q15[384]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) | |||
| extern const q15_t twiddleCoef_512_q15[768]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) | |||
| extern const q15_t twiddleCoef_1024_q15[1536]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) | |||
| extern const q15_t twiddleCoef_2048_q15[3072]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) | |||
| extern const q15_t twiddleCoef_4096_q15[6144]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32) | |||
| extern const float32_t twiddleCoef_rfft_32[32]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64) | |||
| extern const float32_t twiddleCoef_rfft_64[64]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128) | |||
| extern const float32_t twiddleCoef_rfft_128[128]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256) | |||
| extern const float32_t twiddleCoef_rfft_256[256]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512) | |||
| extern const float32_t twiddleCoef_rfft_512[512]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024) | |||
| extern const float32_t twiddleCoef_rfft_1024[1024]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048) | |||
| extern const float32_t twiddleCoef_rfft_2048[2048]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096) | |||
| extern const float32_t twiddleCoef_rfft_4096[4096]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| /* floating-point bit reversal tables */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16) | |||
| #define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) | |||
| extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32) | |||
| #define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) | |||
| extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64) | |||
| #define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) | |||
| extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128) | |||
| #define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) | |||
| extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256) | |||
| #define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) | |||
| extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512) | |||
| #define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) | |||
| extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024) | |||
| #define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) | |||
| extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048) | |||
| #define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) | |||
| extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096) | |||
| #define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) | |||
| extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| /* fixed-point bit reversal tables */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16) | |||
| #define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) | |||
| extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32) | |||
| #define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) | |||
| extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64) | |||
| #define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) | |||
| extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128) | |||
| #define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) | |||
| extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256) | |||
| #define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) | |||
| extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512) | |||
| #define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) | |||
| extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024) | |||
| #define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) | |||
| extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048) | |||
| #define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) | |||
| extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096) | |||
| #define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) | |||
| extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32) | |||
| extern const float32_t realCoefA[8192]; | |||
| extern const float32_t realCoefB[8192]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31) | |||
| extern const q31_t realCoefAQ31[8192]; | |||
| extern const q31_t realCoefBQ31[8192]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15) | |||
| extern const q15_t realCoefAQ15[8192]; | |||
| extern const q15_t realCoefBQ15[8192]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128) | |||
| extern const float32_t Weights_128[256]; | |||
| extern const float32_t cos_factors_128[128]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512) | |||
| extern const float32_t Weights_512[1024]; | |||
| extern const float32_t cos_factors_512[512]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048) | |||
| extern const float32_t Weights_2048[4096]; | |||
| extern const float32_t cos_factors_2048[2048]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192) | |||
| extern const float32_t Weights_8192[16384]; | |||
| extern const float32_t cos_factors_8192[8192]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128) | |||
| extern const q15_t WeightsQ15_128[256]; | |||
| extern const q15_t cos_factorsQ15_128[128]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512) | |||
| extern const q15_t WeightsQ15_512[1024]; | |||
| extern const q15_t cos_factorsQ15_512[512]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048) | |||
| extern const q15_t WeightsQ15_2048[4096]; | |||
| extern const q15_t cos_factorsQ15_2048[2048]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192) | |||
| extern const q15_t WeightsQ15_8192[16384]; | |||
| extern const q15_t cos_factorsQ15_8192[8192]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128) | |||
| extern const q31_t WeightsQ31_128[256]; | |||
| extern const q31_t cos_factorsQ31_128[128]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512) | |||
| extern const q31_t WeightsQ31_512[1024]; | |||
| extern const q31_t cos_factorsQ31_512[512]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048) | |||
| extern const q31_t WeightsQ31_2048[4096]; | |||
| extern const q31_t cos_factorsQ31_2048[2048]; | |||
| #endif | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192) | |||
| extern const q31_t WeightsQ31_8192[16384]; | |||
| extern const q31_t cos_factorsQ31_8192[8192]; | |||
| #endif | |||
| #endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES) | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15) | |||
| extern const q15_t armRecipTableQ15[64]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31) | |||
| extern const q31_t armRecipTableQ31[64]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ | |||
| /* Tables for Fast Math Sine and Cosine */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32) | |||
| extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31) | |||
| extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ | |||
| #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15) | |||
| extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; | |||
| #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ | |||
| #endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */ | |||
| #endif /* ARM_COMMON_TABLES_H */ | |||
| @@ -0,0 +1,66 @@ | |||
| /* ---------------------------------------------------------------------- | |||
| * Project: CMSIS DSP Library | |||
| * Title: arm_const_structs.h | |||
| * Description: Constant structs that are initialized for user convenience. | |||
| * For example, some can be given as arguments to the arm_cfft_f32() function. | |||
| * | |||
| * $Date: 27. January 2017 | |||
| * $Revision: V.1.5.1 | |||
| * | |||
| * Target Processor: Cortex-M cores | |||
| * -------------------------------------------------------------------- */ | |||
| /* | |||
| * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef _ARM_CONST_STRUCTS_H | |||
| #define _ARM_CONST_STRUCTS_H | |||
| #include "arm_math.h" | |||
| #include "arm_common_tables.h" | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; | |||
| extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; | |||
| extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; | |||
| extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; | |||
| #endif | |||
| @@ -0,0 +1,894 @@ | |||
| /**************************************************************************//** | |||
| * @file cmsis_armcc.h | |||
| * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file | |||
| * @version V5.1.0 | |||
| * @date 08. May 2019 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2009-2019 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef __CMSIS_ARMCC_H | |||
| #define __CMSIS_ARMCC_H | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) | |||
| #error "Please use Arm Compiler Toolchain V4.0.677 or later!" | |||
| #endif | |||
| /* CMSIS compiler control architecture macros */ | |||
| #if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ | |||
| (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) | |||
| #define __ARM_ARCH_6M__ 1 | |||
| #endif | |||
| #if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) | |||
| #define __ARM_ARCH_7M__ 1 | |||
| #endif | |||
| #if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) | |||
| #define __ARM_ARCH_7EM__ 1 | |||
| #endif | |||
| /* __ARM_ARCH_8M_BASE__ not applicable */ | |||
| /* __ARM_ARCH_8M_MAIN__ not applicable */ | |||
| /* CMSIS compiler control DSP macros */ | |||
| #if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) | |||
| #define __ARM_FEATURE_DSP 1 | |||
| #endif | |||
| /* CMSIS compiler specific defines */ | |||
| #ifndef __ASM | |||
| #define __ASM __asm | |||
| #endif | |||
| #ifndef __INLINE | |||
| #define __INLINE __inline | |||
| #endif | |||
| #ifndef __STATIC_INLINE | |||
| #define __STATIC_INLINE static __inline | |||
| #endif | |||
| #ifndef __STATIC_FORCEINLINE | |||
| #define __STATIC_FORCEINLINE static __forceinline | |||
| #endif | |||
| #ifndef __NO_RETURN | |||
| #define __NO_RETURN __declspec(noreturn) | |||
| #endif | |||
| #ifndef __USED | |||
| #define __USED __attribute__((used)) | |||
| #endif | |||
| #ifndef __WEAK | |||
| #define __WEAK __attribute__((weak)) | |||
| #endif | |||
| #ifndef __PACKED | |||
| #define __PACKED __attribute__((packed)) | |||
| #endif | |||
| #ifndef __PACKED_STRUCT | |||
| #define __PACKED_STRUCT __packed struct | |||
| #endif | |||
| #ifndef __PACKED_UNION | |||
| #define __PACKED_UNION __packed union | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32 /* deprecated */ | |||
| #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_WRITE | |||
| #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_READ | |||
| #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_WRITE | |||
| #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_READ | |||
| #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) | |||
| #endif | |||
| #ifndef __ALIGNED | |||
| #define __ALIGNED(x) __attribute__((aligned(x))) | |||
| #endif | |||
| #ifndef __RESTRICT | |||
| #define __RESTRICT __restrict | |||
| #endif | |||
| #ifndef __COMPILER_BARRIER | |||
| #define __COMPILER_BARRIER() __memory_changed() | |||
| #endif | |||
| /* ######################### Startup and Lowlevel Init ######################## */ | |||
| #ifndef __PROGRAM_START | |||
| #define __PROGRAM_START __main | |||
| #endif | |||
| #ifndef __INITIAL_SP | |||
| #define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit | |||
| #endif | |||
| #ifndef __STACK_LIMIT | |||
| #define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base | |||
| #endif | |||
| #ifndef __VECTOR_TABLE | |||
| #define __VECTOR_TABLE __Vectors | |||
| #endif | |||
| #ifndef __VECTOR_TABLE_ATTRIBUTE | |||
| #define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET"))) | |||
| #endif | |||
| /* ########################### Core Function Access ########################### */ | |||
| /** \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Enable IRQ Interrupts | |||
| \details Enables IRQ interrupts by clearing the I-bit in the CPSR. | |||
| Can only be executed in Privileged modes. | |||
| */ | |||
| /* intrinsic void __enable_irq(); */ | |||
| /** | |||
| \brief Disable IRQ Interrupts | |||
| \details Disables IRQ interrupts by setting the I-bit in the CPSR. | |||
| Can only be executed in Privileged modes. | |||
| */ | |||
| /* intrinsic void __disable_irq(); */ | |||
| /** | |||
| \brief Get Control Register | |||
| \details Returns the content of the Control Register. | |||
| \return Control Register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_CONTROL(void) | |||
| { | |||
| register uint32_t __regControl __ASM("control"); | |||
| return(__regControl); | |||
| } | |||
| /** | |||
| \brief Set Control Register | |||
| \details Writes the given value to the Control Register. | |||
| \param [in] control Control Register value to set | |||
| */ | |||
| __STATIC_INLINE void __set_CONTROL(uint32_t control) | |||
| { | |||
| register uint32_t __regControl __ASM("control"); | |||
| __regControl = control; | |||
| } | |||
| /** | |||
| \brief Get IPSR Register | |||
| \details Returns the content of the IPSR Register. | |||
| \return IPSR Register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_IPSR(void) | |||
| { | |||
| register uint32_t __regIPSR __ASM("ipsr"); | |||
| return(__regIPSR); | |||
| } | |||
| /** | |||
| \brief Get APSR Register | |||
| \details Returns the content of the APSR Register. | |||
| \return APSR Register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_APSR(void) | |||
| { | |||
| register uint32_t __regAPSR __ASM("apsr"); | |||
| return(__regAPSR); | |||
| } | |||
| /** | |||
| \brief Get xPSR Register | |||
| \details Returns the content of the xPSR Register. | |||
| \return xPSR Register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_xPSR(void) | |||
| { | |||
| register uint32_t __regXPSR __ASM("xpsr"); | |||
| return(__regXPSR); | |||
| } | |||
| /** | |||
| \brief Get Process Stack Pointer | |||
| \details Returns the current value of the Process Stack Pointer (PSP). | |||
| \return PSP Register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_PSP(void) | |||
| { | |||
| register uint32_t __regProcessStackPointer __ASM("psp"); | |||
| return(__regProcessStackPointer); | |||
| } | |||
| /** | |||
| \brief Set Process Stack Pointer | |||
| \details Assigns the given value to the Process Stack Pointer (PSP). | |||
| \param [in] topOfProcStack Process Stack Pointer value to set | |||
| */ | |||
| __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) | |||
| { | |||
| register uint32_t __regProcessStackPointer __ASM("psp"); | |||
| __regProcessStackPointer = topOfProcStack; | |||
| } | |||
| /** | |||
| \brief Get Main Stack Pointer | |||
| \details Returns the current value of the Main Stack Pointer (MSP). | |||
| \return MSP Register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_MSP(void) | |||
| { | |||
| register uint32_t __regMainStackPointer __ASM("msp"); | |||
| return(__regMainStackPointer); | |||
| } | |||
| /** | |||
| \brief Set Main Stack Pointer | |||
| \details Assigns the given value to the Main Stack Pointer (MSP). | |||
| \param [in] topOfMainStack Main Stack Pointer value to set | |||
| */ | |||
| __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) | |||
| { | |||
| register uint32_t __regMainStackPointer __ASM("msp"); | |||
| __regMainStackPointer = topOfMainStack; | |||
| } | |||
| /** | |||
| \brief Get Priority Mask | |||
| \details Returns the current state of the priority mask bit from the Priority Mask Register. | |||
| \return Priority Mask value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_PRIMASK(void) | |||
| { | |||
| register uint32_t __regPriMask __ASM("primask"); | |||
| return(__regPriMask); | |||
| } | |||
| /** | |||
| \brief Set Priority Mask | |||
| \details Assigns the given value to the Priority Mask Register. | |||
| \param [in] priMask Priority Mask | |||
| */ | |||
| __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) | |||
| { | |||
| register uint32_t __regPriMask __ASM("primask"); | |||
| __regPriMask = (priMask); | |||
| } | |||
| #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ | |||
| (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) | |||
| /** | |||
| \brief Enable FIQ | |||
| \details Enables FIQ interrupts by clearing the F-bit in the CPSR. | |||
| Can only be executed in Privileged modes. | |||
| */ | |||
| #define __enable_fault_irq __enable_fiq | |||
| /** | |||
| \brief Disable FIQ | |||
| \details Disables FIQ interrupts by setting the F-bit in the CPSR. | |||
| Can only be executed in Privileged modes. | |||
| */ | |||
| #define __disable_fault_irq __disable_fiq | |||
| /** | |||
| \brief Get Base Priority | |||
| \details Returns the current value of the Base Priority register. | |||
| \return Base Priority register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_BASEPRI(void) | |||
| { | |||
| register uint32_t __regBasePri __ASM("basepri"); | |||
| return(__regBasePri); | |||
| } | |||
| /** | |||
| \brief Set Base Priority | |||
| \details Assigns the given value to the Base Priority register. | |||
| \param [in] basePri Base Priority value to set | |||
| */ | |||
| __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) | |||
| { | |||
| register uint32_t __regBasePri __ASM("basepri"); | |||
| __regBasePri = (basePri & 0xFFU); | |||
| } | |||
| /** | |||
| \brief Set Base Priority with condition | |||
| \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, | |||
| or the new value increases the BASEPRI priority level. | |||
| \param [in] basePri Base Priority value to set | |||
| */ | |||
| __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) | |||
| { | |||
| register uint32_t __regBasePriMax __ASM("basepri_max"); | |||
| __regBasePriMax = (basePri & 0xFFU); | |||
| } | |||
| /** | |||
| \brief Get Fault Mask | |||
| \details Returns the current value of the Fault Mask register. | |||
| \return Fault Mask register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_FAULTMASK(void) | |||
| { | |||
| register uint32_t __regFaultMask __ASM("faultmask"); | |||
| return(__regFaultMask); | |||
| } | |||
| /** | |||
| \brief Set Fault Mask | |||
| \details Assigns the given value to the Fault Mask register. | |||
| \param [in] faultMask Fault Mask value to set | |||
| */ | |||
| __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) | |||
| { | |||
| register uint32_t __regFaultMask __ASM("faultmask"); | |||
| __regFaultMask = (faultMask & (uint32_t)1U); | |||
| } | |||
| #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ | |||
| (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ | |||
| /** | |||
| \brief Get FPSCR | |||
| \details Returns the current value of the Floating Point Status/Control register. | |||
| \return Floating Point Status/Control register value | |||
| */ | |||
| __STATIC_INLINE uint32_t __get_FPSCR(void) | |||
| { | |||
| #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | |||
| (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) | |||
| register uint32_t __regfpscr __ASM("fpscr"); | |||
| return(__regfpscr); | |||
| #else | |||
| return(0U); | |||
| #endif | |||
| } | |||
| /** | |||
| \brief Set FPSCR | |||
| \details Assigns the given value to the Floating Point Status/Control register. | |||
| \param [in] fpscr Floating Point Status/Control value to set | |||
| */ | |||
| __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) | |||
| { | |||
| #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | |||
| (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) | |||
| register uint32_t __regfpscr __ASM("fpscr"); | |||
| __regfpscr = (fpscr); | |||
| #else | |||
| (void)fpscr; | |||
| #endif | |||
| } | |||
| /*@} end of CMSIS_Core_RegAccFunctions */ | |||
| /* ########################## Core Instruction Access ######################### */ | |||
| /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface | |||
| Access to dedicated instructions | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief No Operation | |||
| \details No Operation does nothing. This instruction can be used for code alignment purposes. | |||
| */ | |||
| #define __NOP __nop | |||
| /** | |||
| \brief Wait For Interrupt | |||
| \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. | |||
| */ | |||
| #define __WFI __wfi | |||
| /** | |||
| \brief Wait For Event | |||
| \details Wait For Event is a hint instruction that permits the processor to enter | |||
| a low-power state until one of a number of events occurs. | |||
| */ | |||
| #define __WFE __wfe | |||
| /** | |||
| \brief Send Event | |||
| \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. | |||
| */ | |||
| #define __SEV __sev | |||
| /** | |||
| \brief Instruction Synchronization Barrier | |||
| \details Instruction Synchronization Barrier flushes the pipeline in the processor, | |||
| so that all instructions following the ISB are fetched from cache or memory, | |||
| after the instruction has been completed. | |||
| */ | |||
| #define __ISB() do {\ | |||
| __schedule_barrier();\ | |||
| __isb(0xF);\ | |||
| __schedule_barrier();\ | |||
| } while (0U) | |||
| /** | |||
| \brief Data Synchronization Barrier | |||
| \details Acts as a special kind of Data Memory Barrier. | |||
| It completes when all explicit memory accesses before this instruction complete. | |||
| */ | |||
| #define __DSB() do {\ | |||
| __schedule_barrier();\ | |||
| __dsb(0xF);\ | |||
| __schedule_barrier();\ | |||
| } while (0U) | |||
| /** | |||
| \brief Data Memory Barrier | |||
| \details Ensures the apparent order of the explicit memory operations before | |||
| and after the instruction, without ensuring their completion. | |||
| */ | |||
| #define __DMB() do {\ | |||
| __schedule_barrier();\ | |||
| __dmb(0xF);\ | |||
| __schedule_barrier();\ | |||
| } while (0U) | |||
| /** | |||
| \brief Reverse byte order (32 bit) | |||
| \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. | |||
| \param [in] value Value to reverse | |||
| \return Reversed value | |||
| */ | |||
| #define __REV __rev | |||
| /** | |||
| \brief Reverse byte order (16 bit) | |||
| \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. | |||
| \param [in] value Value to reverse | |||
| \return Reversed value | |||
| */ | |||
| #ifndef __NO_EMBEDDED_ASM | |||
| __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) | |||
| { | |||
| rev16 r0, r0 | |||
| bx lr | |||
| } | |||
| #endif | |||
| /** | |||
| \brief Reverse byte order (16 bit) | |||
| \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. | |||
| \param [in] value Value to reverse | |||
| \return Reversed value | |||
| */ | |||
| #ifndef __NO_EMBEDDED_ASM | |||
| __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) | |||
| { | |||
| revsh r0, r0 | |||
| bx lr | |||
| } | |||
| #endif | |||
| /** | |||
| \brief Rotate Right in unsigned value (32 bit) | |||
| \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. | |||
| \param [in] op1 Value to rotate | |||
| \param [in] op2 Number of Bits to rotate | |||
| \return Rotated value | |||
| */ | |||
| #define __ROR __ror | |||
| /** | |||
| \brief Breakpoint | |||
| \details Causes the processor to enter Debug state. | |||
| Debug tools can use this to investigate system state when the instruction at a particular address is reached. | |||
| \param [in] value is ignored by the processor. | |||
| If required, a debugger can use it to store additional information about the breakpoint. | |||
| */ | |||
| #define __BKPT(value) __breakpoint(value) | |||
| /** | |||
| \brief Reverse bit order of value | |||
| \details Reverses the bit order of the given value. | |||
| \param [in] value Value to reverse | |||
| \return Reversed value | |||
| */ | |||
| #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ | |||
| (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) | |||
| #define __RBIT __rbit | |||
| #else | |||
| __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) | |||
| { | |||
| uint32_t result; | |||
| uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ | |||
| result = value; /* r will be reversed bits of v; first get LSB of v */ | |||
| for (value >>= 1U; value != 0U; value >>= 1U) | |||
| { | |||
| result <<= 1U; | |||
| result |= value & 1U; | |||
| s--; | |||
| } | |||
| result <<= s; /* shift when v's highest bits are zero */ | |||
| return result; | |||
| } | |||
| #endif | |||
| /** | |||
| \brief Count leading zeros | |||
| \details Counts the number of leading zeros of a data value. | |||
| \param [in] value Value to count the leading zeros | |||
| \return number of leading zeros in value | |||
| */ | |||
| #define __CLZ __clz | |||
| #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ | |||
| (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) | |||
| /** | |||
| \brief LDR Exclusive (8 bit) | |||
| \details Executes a exclusive LDR instruction for 8 bit value. | |||
| \param [in] ptr Pointer to data | |||
| \return value of type uint8_t at (*ptr) | |||
| */ | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | |||
| #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) | |||
| #else | |||
| #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") | |||
| #endif | |||
| /** | |||
| \brief LDR Exclusive (16 bit) | |||
| \details Executes a exclusive LDR instruction for 16 bit values. | |||
| \param [in] ptr Pointer to data | |||
| \return value of type uint16_t at (*ptr) | |||
| */ | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | |||
| #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) | |||
| #else | |||
| #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") | |||
| #endif | |||
| /** | |||
| \brief LDR Exclusive (32 bit) | |||
| \details Executes a exclusive LDR instruction for 32 bit values. | |||
| \param [in] ptr Pointer to data | |||
| \return value of type uint32_t at (*ptr) | |||
| */ | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | |||
| #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) | |||
| #else | |||
| #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") | |||
| #endif | |||
| /** | |||
| \brief STR Exclusive (8 bit) | |||
| \details Executes a exclusive STR instruction for 8 bit values. | |||
| \param [in] value Value to store | |||
| \param [in] ptr Pointer to location | |||
| \return 0 Function succeeded | |||
| \return 1 Function failed | |||
| */ | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | |||
| #define __STREXB(value, ptr) __strex(value, ptr) | |||
| #else | |||
| #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") | |||
| #endif | |||
| /** | |||
| \brief STR Exclusive (16 bit) | |||
| \details Executes a exclusive STR instruction for 16 bit values. | |||
| \param [in] value Value to store | |||
| \param [in] ptr Pointer to location | |||
| \return 0 Function succeeded | |||
| \return 1 Function failed | |||
| */ | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | |||
| #define __STREXH(value, ptr) __strex(value, ptr) | |||
| #else | |||
| #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") | |||
| #endif | |||
| /** | |||
| \brief STR Exclusive (32 bit) | |||
| \details Executes a exclusive STR instruction for 32 bit values. | |||
| \param [in] value Value to store | |||
| \param [in] ptr Pointer to location | |||
| \return 0 Function succeeded | |||
| \return 1 Function failed | |||
| */ | |||
| #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) | |||
| #define __STREXW(value, ptr) __strex(value, ptr) | |||
| #else | |||
| #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") | |||
| #endif | |||
| /** | |||
| \brief Remove the exclusive lock | |||
| \details Removes the exclusive lock which is created by LDREX. | |||
| */ | |||
| #define __CLREX __clrex | |||
| /** | |||
| \brief Signed Saturate | |||
| \details Saturates a signed value. | |||
| \param [in] value Value to be saturated | |||
| \param [in] sat Bit position to saturate to (1..32) | |||
| \return Saturated value | |||
| */ | |||
| #define __SSAT __ssat | |||
| /** | |||
| \brief Unsigned Saturate | |||
| \details Saturates an unsigned value. | |||
| \param [in] value Value to be saturated | |||
| \param [in] sat Bit position to saturate to (0..31) | |||
| \return Saturated value | |||
| */ | |||
| #define __USAT __usat | |||
| /** | |||
| \brief Rotate Right with Extend (32 bit) | |||
| \details Moves each bit of a bitstring right by one bit. | |||
| The carry input is shifted in at the left end of the bitstring. | |||
| \param [in] value Value to rotate | |||
| \return Rotated value | |||
| */ | |||
| #ifndef __NO_EMBEDDED_ASM | |||
| __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) | |||
| { | |||
| rrx r0, r0 | |||
| bx lr | |||
| } | |||
| #endif | |||
| /** | |||
| \brief LDRT Unprivileged (8 bit) | |||
| \details Executes a Unprivileged LDRT instruction for 8 bit value. | |||
| \param [in] ptr Pointer to data | |||
| \return value of type uint8_t at (*ptr) | |||
| */ | |||
| #define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) | |||
| /** | |||
| \brief LDRT Unprivileged (16 bit) | |||
| \details Executes a Unprivileged LDRT instruction for 16 bit values. | |||
| \param [in] ptr Pointer to data | |||
| \return value of type uint16_t at (*ptr) | |||
| */ | |||
| #define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) | |||
| /** | |||
| \brief LDRT Unprivileged (32 bit) | |||
| \details Executes a Unprivileged LDRT instruction for 32 bit values. | |||
| \param [in] ptr Pointer to data | |||
| \return value of type uint32_t at (*ptr) | |||
| */ | |||
| #define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) | |||
| /** | |||
| \brief STRT Unprivileged (8 bit) | |||
| \details Executes a Unprivileged STRT instruction for 8 bit values. | |||
| \param [in] value Value to store | |||
| \param [in] ptr Pointer to location | |||
| */ | |||
| #define __STRBT(value, ptr) __strt(value, ptr) | |||
| /** | |||
| \brief STRT Unprivileged (16 bit) | |||
| \details Executes a Unprivileged STRT instruction for 16 bit values. | |||
| \param [in] value Value to store | |||
| \param [in] ptr Pointer to location | |||
| */ | |||
| #define __STRHT(value, ptr) __strt(value, ptr) | |||
| /** | |||
| \brief STRT Unprivileged (32 bit) | |||
| \details Executes a Unprivileged STRT instruction for 32 bit values. | |||
| \param [in] value Value to store | |||
| \param [in] ptr Pointer to location | |||
| */ | |||
| #define __STRT(value, ptr) __strt(value, ptr) | |||
| #else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ | |||
| (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ | |||
| /** | |||
| \brief Signed Saturate | |||
| \details Saturates a signed value. | |||
| \param [in] value Value to be saturated | |||
| \param [in] sat Bit position to saturate to (1..32) | |||
| \return Saturated value | |||
| */ | |||
| __attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) | |||
| { | |||
| if ((sat >= 1U) && (sat <= 32U)) | |||
| { | |||
| const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); | |||
| const int32_t min = -1 - max ; | |||
| if (val > max) | |||
| { | |||
| return max; | |||
| } | |||
| else if (val < min) | |||
| { | |||
| return min; | |||
| } | |||
| } | |||
| return val; | |||
| } | |||
| /** | |||
| \brief Unsigned Saturate | |||
| \details Saturates an unsigned value. | |||
| \param [in] value Value to be saturated | |||
| \param [in] sat Bit position to saturate to (0..31) | |||
| \return Saturated value | |||
| */ | |||
| __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) | |||
| { | |||
| if (sat <= 31U) | |||
| { | |||
| const uint32_t max = ((1U << sat) - 1U); | |||
| if (val > (int32_t)max) | |||
| { | |||
| return max; | |||
| } | |||
| else if (val < 0) | |||
| { | |||
| return 0U; | |||
| } | |||
| } | |||
| return (uint32_t)val; | |||
| } | |||
| #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ | |||
| (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ | |||
| /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ | |||
| /* ################### Compiler specific Intrinsics ########################### */ | |||
| /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics | |||
| Access to dedicated SIMD instructions | |||
| @{ | |||
| */ | |||
| #if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) | |||
| #define __SADD8 __sadd8 | |||
| #define __QADD8 __qadd8 | |||
| #define __SHADD8 __shadd8 | |||
| #define __UADD8 __uadd8 | |||
| #define __UQADD8 __uqadd8 | |||
| #define __UHADD8 __uhadd8 | |||
| #define __SSUB8 __ssub8 | |||
| #define __QSUB8 __qsub8 | |||
| #define __SHSUB8 __shsub8 | |||
| #define __USUB8 __usub8 | |||
| #define __UQSUB8 __uqsub8 | |||
| #define __UHSUB8 __uhsub8 | |||
| #define __SADD16 __sadd16 | |||
| #define __QADD16 __qadd16 | |||
| #define __SHADD16 __shadd16 | |||
| #define __UADD16 __uadd16 | |||
| #define __UQADD16 __uqadd16 | |||
| #define __UHADD16 __uhadd16 | |||
| #define __SSUB16 __ssub16 | |||
| #define __QSUB16 __qsub16 | |||
| #define __SHSUB16 __shsub16 | |||
| #define __USUB16 __usub16 | |||
| #define __UQSUB16 __uqsub16 | |||
| #define __UHSUB16 __uhsub16 | |||
| #define __SASX __sasx | |||
| #define __QASX __qasx | |||
| #define __SHASX __shasx | |||
| #define __UASX __uasx | |||
| #define __UQASX __uqasx | |||
| #define __UHASX __uhasx | |||
| #define __SSAX __ssax | |||
| #define __QSAX __qsax | |||
| #define __SHSAX __shsax | |||
| #define __USAX __usax | |||
| #define __UQSAX __uqsax | |||
| #define __UHSAX __uhsax | |||
| #define __USAD8 __usad8 | |||
| #define __USADA8 __usada8 | |||
| #define __SSAT16 __ssat16 | |||
| #define __USAT16 __usat16 | |||
| #define __UXTB16 __uxtb16 | |||
| #define __UXTAB16 __uxtab16 | |||
| #define __SXTB16 __sxtb16 | |||
| #define __SXTAB16 __sxtab16 | |||
| #define __SMUAD __smuad | |||
| #define __SMUADX __smuadx | |||
| #define __SMLAD __smlad | |||
| #define __SMLADX __smladx | |||
| #define __SMLALD __smlald | |||
| #define __SMLALDX __smlaldx | |||
| #define __SMUSD __smusd | |||
| #define __SMUSDX __smusdx | |||
| #define __SMLSD __smlsd | |||
| #define __SMLSDX __smlsdx | |||
| #define __SMLSLD __smlsld | |||
| #define __SMLSLDX __smlsldx | |||
| #define __SEL __sel | |||
| #define __QADD __qadd | |||
| #define __QSUB __qsub | |||
| #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ | |||
| ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) | |||
| #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ | |||
| ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) | |||
| #define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ | |||
| ((int64_t)(ARG3) << 32U) ) >> 32U)) | |||
| #endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ | |||
| /*@} end of group CMSIS_SIMD_intrinsics */ | |||
| #endif /* __CMSIS_ARMCC_H */ | |||
| @@ -0,0 +1,283 @@ | |||
| /**************************************************************************//** | |||
| * @file cmsis_compiler.h | |||
| * @brief CMSIS compiler generic header file | |||
| * @version V5.1.0 | |||
| * @date 09. October 2018 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef __CMSIS_COMPILER_H | |||
| #define __CMSIS_COMPILER_H | |||
| #include <stdint.h> | |||
| /* | |||
| * Arm Compiler 4/5 | |||
| */ | |||
| #if defined ( __CC_ARM ) | |||
| #include "cmsis_armcc.h" | |||
| /* | |||
| * Arm Compiler 6.6 LTM (armclang) | |||
| */ | |||
| #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) | |||
| #include "cmsis_armclang_ltm.h" | |||
| /* | |||
| * Arm Compiler above 6.10.1 (armclang) | |||
| */ | |||
| #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) | |||
| #include "cmsis_armclang.h" | |||
| /* | |||
| * GNU Compiler | |||
| */ | |||
| #elif defined ( __GNUC__ ) | |||
| #include "cmsis_gcc.h" | |||
| /* | |||
| * IAR Compiler | |||
| */ | |||
| #elif defined ( __ICCARM__ ) | |||
| #include <cmsis_iccarm.h> | |||
| /* | |||
| * TI Arm Compiler | |||
| */ | |||
| #elif defined ( __TI_ARM__ ) | |||
| #include <cmsis_ccs.h> | |||
| #ifndef __ASM | |||
| #define __ASM __asm | |||
| #endif | |||
| #ifndef __INLINE | |||
| #define __INLINE inline | |||
| #endif | |||
| #ifndef __STATIC_INLINE | |||
| #define __STATIC_INLINE static inline | |||
| #endif | |||
| #ifndef __STATIC_FORCEINLINE | |||
| #define __STATIC_FORCEINLINE __STATIC_INLINE | |||
| #endif | |||
| #ifndef __NO_RETURN | |||
| #define __NO_RETURN __attribute__((noreturn)) | |||
| #endif | |||
| #ifndef __USED | |||
| #define __USED __attribute__((used)) | |||
| #endif | |||
| #ifndef __WEAK | |||
| #define __WEAK __attribute__((weak)) | |||
| #endif | |||
| #ifndef __PACKED | |||
| #define __PACKED __attribute__((packed)) | |||
| #endif | |||
| #ifndef __PACKED_STRUCT | |||
| #define __PACKED_STRUCT struct __attribute__((packed)) | |||
| #endif | |||
| #ifndef __PACKED_UNION | |||
| #define __PACKED_UNION union __attribute__((packed)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32 /* deprecated */ | |||
| struct __attribute__((packed)) T_UINT32 { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_WRITE | |||
| __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | |||
| #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_READ | |||
| __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | |||
| #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_WRITE | |||
| __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_READ | |||
| __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) | |||
| #endif | |||
| #ifndef __ALIGNED | |||
| #define __ALIGNED(x) __attribute__((aligned(x))) | |||
| #endif | |||
| #ifndef __RESTRICT | |||
| #define __RESTRICT __restrict | |||
| #endif | |||
| #ifndef __COMPILER_BARRIER | |||
| #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. | |||
| #define __COMPILER_BARRIER() (void)0 | |||
| #endif | |||
| /* | |||
| * TASKING Compiler | |||
| */ | |||
| #elif defined ( __TASKING__ ) | |||
| /* | |||
| * The CMSIS functions have been implemented as intrinsics in the compiler. | |||
| * Please use "carm -?i" to get an up to date list of all intrinsics, | |||
| * Including the CMSIS ones. | |||
| */ | |||
| #ifndef __ASM | |||
| #define __ASM __asm | |||
| #endif | |||
| #ifndef __INLINE | |||
| #define __INLINE inline | |||
| #endif | |||
| #ifndef __STATIC_INLINE | |||
| #define __STATIC_INLINE static inline | |||
| #endif | |||
| #ifndef __STATIC_FORCEINLINE | |||
| #define __STATIC_FORCEINLINE __STATIC_INLINE | |||
| #endif | |||
| #ifndef __NO_RETURN | |||
| #define __NO_RETURN __attribute__((noreturn)) | |||
| #endif | |||
| #ifndef __USED | |||
| #define __USED __attribute__((used)) | |||
| #endif | |||
| #ifndef __WEAK | |||
| #define __WEAK __attribute__((weak)) | |||
| #endif | |||
| #ifndef __PACKED | |||
| #define __PACKED __packed__ | |||
| #endif | |||
| #ifndef __PACKED_STRUCT | |||
| #define __PACKED_STRUCT struct __packed__ | |||
| #endif | |||
| #ifndef __PACKED_UNION | |||
| #define __PACKED_UNION union __packed__ | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32 /* deprecated */ | |||
| struct __packed__ T_UINT32 { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_WRITE | |||
| __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | |||
| #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_READ | |||
| __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | |||
| #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_WRITE | |||
| __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_READ | |||
| __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) | |||
| #endif | |||
| #ifndef __ALIGNED | |||
| #define __ALIGNED(x) __align(x) | |||
| #endif | |||
| #ifndef __RESTRICT | |||
| #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. | |||
| #define __RESTRICT | |||
| #endif | |||
| #ifndef __COMPILER_BARRIER | |||
| #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. | |||
| #define __COMPILER_BARRIER() (void)0 | |||
| #endif | |||
| /* | |||
| * COSMIC Compiler | |||
| */ | |||
| #elif defined ( __CSMC__ ) | |||
| #include <cmsis_csm.h> | |||
| #ifndef __ASM | |||
| #define __ASM _asm | |||
| #endif | |||
| #ifndef __INLINE | |||
| #define __INLINE inline | |||
| #endif | |||
| #ifndef __STATIC_INLINE | |||
| #define __STATIC_INLINE static inline | |||
| #endif | |||
| #ifndef __STATIC_FORCEINLINE | |||
| #define __STATIC_FORCEINLINE __STATIC_INLINE | |||
| #endif | |||
| #ifndef __NO_RETURN | |||
| // NO RETURN is automatically detected hence no warning here | |||
| #define __NO_RETURN | |||
| #endif | |||
| #ifndef __USED | |||
| #warning No compiler specific solution for __USED. __USED is ignored. | |||
| #define __USED | |||
| #endif | |||
| #ifndef __WEAK | |||
| #define __WEAK __weak | |||
| #endif | |||
| #ifndef __PACKED | |||
| #define __PACKED @packed | |||
| #endif | |||
| #ifndef __PACKED_STRUCT | |||
| #define __PACKED_STRUCT @packed struct | |||
| #endif | |||
| #ifndef __PACKED_UNION | |||
| #define __PACKED_UNION @packed union | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32 /* deprecated */ | |||
| @packed struct T_UINT32 { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_WRITE | |||
| __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; | |||
| #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_READ | |||
| __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; | |||
| #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_WRITE | |||
| __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_READ | |||
| __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; | |||
| #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) | |||
| #endif | |||
| #ifndef __ALIGNED | |||
| #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. | |||
| #define __ALIGNED(x) | |||
| #endif | |||
| #ifndef __RESTRICT | |||
| #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. | |||
| #define __RESTRICT | |||
| #endif | |||
| #ifndef __COMPILER_BARRIER | |||
| #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. | |||
| #define __COMPILER_BARRIER() (void)0 | |||
| #endif | |||
| #else | |||
| #error Unknown compiler. | |||
| #endif | |||
| #endif /* __CMSIS_COMPILER_H */ | |||
| @@ -0,0 +1,964 @@ | |||
| /**************************************************************************//** | |||
| * @file cmsis_iccarm.h | |||
| * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file | |||
| * @version V5.1.0 | |||
| * @date 08. May 2019 | |||
| ******************************************************************************/ | |||
| //------------------------------------------------------------------------------ | |||
| // | |||
| // Copyright (c) 2017-2019 IAR Systems | |||
| // Copyright (c) 2017-2019 Arm Limited. All rights reserved. | |||
| // | |||
| // Licensed under the Apache License, Version 2.0 (the "License") | |||
| // you may not use this file except in compliance with the License. | |||
| // You may obtain a copy of the License at | |||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software | |||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| // See the License for the specific language governing permissions and | |||
| // limitations under the License. | |||
| // | |||
| //------------------------------------------------------------------------------ | |||
| #ifndef __CMSIS_ICCARM_H__ | |||
| #define __CMSIS_ICCARM_H__ | |||
| #ifndef __ICCARM__ | |||
| #error This file should only be compiled by ICCARM | |||
| #endif | |||
| #pragma system_include | |||
| #define __IAR_FT _Pragma("inline=forced") __intrinsic | |||
| #if (__VER__ >= 8000000) | |||
| #define __ICCARM_V8 1 | |||
| #else | |||
| #define __ICCARM_V8 0 | |||
| #endif | |||
| #ifndef __ALIGNED | |||
| #if __ICCARM_V8 | |||
| #define __ALIGNED(x) __attribute__((aligned(x))) | |||
| #elif (__VER__ >= 7080000) | |||
| /* Needs IAR language extensions */ | |||
| #define __ALIGNED(x) __attribute__((aligned(x))) | |||
| #else | |||
| #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. | |||
| #define __ALIGNED(x) | |||
| #endif | |||
| #endif | |||
| /* Define compiler macros for CPU architecture, used in CMSIS 5. | |||
| */ | |||
| #if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ | |||
| /* Macros already defined */ | |||
| #else | |||
| #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) | |||
| #define __ARM_ARCH_8M_MAIN__ 1 | |||
| #elif defined(__ARM8M_BASELINE__) | |||
| #define __ARM_ARCH_8M_BASE__ 1 | |||
| #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' | |||
| #if __ARM_ARCH == 6 | |||
| #define __ARM_ARCH_6M__ 1 | |||
| #elif __ARM_ARCH == 7 | |||
| #if __ARM_FEATURE_DSP | |||
| #define __ARM_ARCH_7EM__ 1 | |||
| #else | |||
| #define __ARM_ARCH_7M__ 1 | |||
| #endif | |||
| #endif /* __ARM_ARCH */ | |||
| #endif /* __ARM_ARCH_PROFILE == 'M' */ | |||
| #endif | |||
| /* Alternativ core deduction for older ICCARM's */ | |||
| #if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ | |||
| !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) | |||
| #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) | |||
| #define __ARM_ARCH_6M__ 1 | |||
| #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) | |||
| #define __ARM_ARCH_7M__ 1 | |||
| #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) | |||
| #define __ARM_ARCH_7EM__ 1 | |||
| #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) | |||
| #define __ARM_ARCH_8M_BASE__ 1 | |||
| #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) | |||
| #define __ARM_ARCH_8M_MAIN__ 1 | |||
| #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) | |||
| #define __ARM_ARCH_8M_MAIN__ 1 | |||
| #else | |||
| #error "Unknown target." | |||
| #endif | |||
| #endif | |||
| #if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 | |||
| #define __IAR_M0_FAMILY 1 | |||
| #elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 | |||
| #define __IAR_M0_FAMILY 1 | |||
| #else | |||
| #define __IAR_M0_FAMILY 0 | |||
| #endif | |||
| #ifndef __ASM | |||
| #define __ASM __asm | |||
| #endif | |||
| #ifndef __COMPILER_BARRIER | |||
| #define __COMPILER_BARRIER() __ASM volatile("":::"memory") | |||
| #endif | |||
| #ifndef __INLINE | |||
| #define __INLINE inline | |||
| #endif | |||
| #ifndef __NO_RETURN | |||
| #if __ICCARM_V8 | |||
| #define __NO_RETURN __attribute__((__noreturn__)) | |||
| #else | |||
| #define __NO_RETURN _Pragma("object_attribute=__noreturn") | |||
| #endif | |||
| #endif | |||
| #ifndef __PACKED | |||
| #if __ICCARM_V8 | |||
| #define __PACKED __attribute__((packed, aligned(1))) | |||
| #else | |||
| /* Needs IAR language extensions */ | |||
| #define __PACKED __packed | |||
| #endif | |||
| #endif | |||
| #ifndef __PACKED_STRUCT | |||
| #if __ICCARM_V8 | |||
| #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) | |||
| #else | |||
| /* Needs IAR language extensions */ | |||
| #define __PACKED_STRUCT __packed struct | |||
| #endif | |||
| #endif | |||
| #ifndef __PACKED_UNION | |||
| #if __ICCARM_V8 | |||
| #define __PACKED_UNION union __attribute__((packed, aligned(1))) | |||
| #else | |||
| /* Needs IAR language extensions */ | |||
| #define __PACKED_UNION __packed union | |||
| #endif | |||
| #endif | |||
| #ifndef __RESTRICT | |||
| #if __ICCARM_V8 | |||
| #define __RESTRICT __restrict | |||
| #else | |||
| /* Needs IAR language extensions */ | |||
| #define __RESTRICT restrict | |||
| #endif | |||
| #endif | |||
| #ifndef __STATIC_INLINE | |||
| #define __STATIC_INLINE static inline | |||
| #endif | |||
| #ifndef __FORCEINLINE | |||
| #define __FORCEINLINE _Pragma("inline=forced") | |||
| #endif | |||
| #ifndef __STATIC_FORCEINLINE | |||
| #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_READ | |||
| #pragma language=save | |||
| #pragma language=extended | |||
| __IAR_FT uint16_t __iar_uint16_read(void const *ptr) | |||
| { | |||
| return *(__packed uint16_t*)(ptr); | |||
| } | |||
| #pragma language=restore | |||
| #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT16_WRITE | |||
| #pragma language=save | |||
| #pragma language=extended | |||
| __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) | |||
| { | |||
| *(__packed uint16_t*)(ptr) = val;; | |||
| } | |||
| #pragma language=restore | |||
| #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_READ | |||
| #pragma language=save | |||
| #pragma language=extended | |||
| __IAR_FT uint32_t __iar_uint32_read(void const *ptr) | |||
| { | |||
| return *(__packed uint32_t*)(ptr); | |||
| } | |||
| #pragma language=restore | |||
| #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32_WRITE | |||
| #pragma language=save | |||
| #pragma language=extended | |||
| __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) | |||
| { | |||
| *(__packed uint32_t*)(ptr) = val;; | |||
| } | |||
| #pragma language=restore | |||
| #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) | |||
| #endif | |||
| #ifndef __UNALIGNED_UINT32 /* deprecated */ | |||
| #pragma language=save | |||
| #pragma language=extended | |||
| __packed struct __iar_u32 { uint32_t v; }; | |||
| #pragma language=restore | |||
| #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) | |||
| #endif | |||
| #ifndef __USED | |||
| #if __ICCARM_V8 | |||
| #define __USED __attribute__((used)) | |||
| #else | |||
| #define __USED _Pragma("__root") | |||
| #endif | |||
| #endif | |||
| #ifndef __WEAK | |||
| #if __ICCARM_V8 | |||
| #define __WEAK __attribute__((weak)) | |||
| #else | |||
| #define __WEAK _Pragma("__weak") | |||
| #endif | |||
| #endif | |||
| #ifndef __PROGRAM_START | |||
| #define __PROGRAM_START __iar_program_start | |||
| #endif | |||
| #ifndef __INITIAL_SP | |||
| #define __INITIAL_SP CSTACK$$Limit | |||
| #endif | |||
| #ifndef __STACK_LIMIT | |||
| #define __STACK_LIMIT CSTACK$$Base | |||
| #endif | |||
| #ifndef __VECTOR_TABLE | |||
| #define __VECTOR_TABLE __vector_table | |||
| #endif | |||
| #ifndef __VECTOR_TABLE_ATTRIBUTE | |||
| #define __VECTOR_TABLE_ATTRIBUTE @".intvec" | |||
| #endif | |||
| #ifndef __ICCARM_INTRINSICS_VERSION__ | |||
| #define __ICCARM_INTRINSICS_VERSION__ 0 | |||
| #endif | |||
| #if __ICCARM_INTRINSICS_VERSION__ == 2 | |||
| #if defined(__CLZ) | |||
| #undef __CLZ | |||
| #endif | |||
| #if defined(__REVSH) | |||
| #undef __REVSH | |||
| #endif | |||
| #if defined(__RBIT) | |||
| #undef __RBIT | |||
| #endif | |||
| #if defined(__SSAT) | |||
| #undef __SSAT | |||
| #endif | |||
| #if defined(__USAT) | |||
| #undef __USAT | |||
| #endif | |||
| #include "iccarm_builtin.h" | |||
| #define __disable_fault_irq __iar_builtin_disable_fiq | |||
| #define __disable_irq __iar_builtin_disable_interrupt | |||
| #define __enable_fault_irq __iar_builtin_enable_fiq | |||
| #define __enable_irq __iar_builtin_enable_interrupt | |||
| #define __arm_rsr __iar_builtin_rsr | |||
| #define __arm_wsr __iar_builtin_wsr | |||
| #define __get_APSR() (__arm_rsr("APSR")) | |||
| #define __get_BASEPRI() (__arm_rsr("BASEPRI")) | |||
| #define __get_CONTROL() (__arm_rsr("CONTROL")) | |||
| #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) | |||
| #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | |||
| (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) | |||
| #define __get_FPSCR() (__arm_rsr("FPSCR")) | |||
| #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) | |||
| #else | |||
| #define __get_FPSCR() ( 0 ) | |||
| #define __set_FPSCR(VALUE) ((void)VALUE) | |||
| #endif | |||
| #define __get_IPSR() (__arm_rsr("IPSR")) | |||
| #define __get_MSP() (__arm_rsr("MSP")) | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure MSPLIM is RAZ/WI | |||
| #define __get_MSPLIM() (0U) | |||
| #else | |||
| #define __get_MSPLIM() (__arm_rsr("MSPLIM")) | |||
| #endif | |||
| #define __get_PRIMASK() (__arm_rsr("PRIMASK")) | |||
| #define __get_PSP() (__arm_rsr("PSP")) | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| #define __get_PSPLIM() (0U) | |||
| #else | |||
| #define __get_PSPLIM() (__arm_rsr("PSPLIM")) | |||
| #endif | |||
| #define __get_xPSR() (__arm_rsr("xPSR")) | |||
| #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) | |||
| #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) | |||
| #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) | |||
| #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) | |||
| #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure MSPLIM is RAZ/WI | |||
| #define __set_MSPLIM(VALUE) ((void)(VALUE)) | |||
| #else | |||
| #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) | |||
| #endif | |||
| #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) | |||
| #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| #define __set_PSPLIM(VALUE) ((void)(VALUE)) | |||
| #else | |||
| #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) | |||
| #endif | |||
| #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) | |||
| #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) | |||
| #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) | |||
| #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) | |||
| #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) | |||
| #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) | |||
| #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) | |||
| #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) | |||
| #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) | |||
| #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) | |||
| #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) | |||
| #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) | |||
| #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) | |||
| #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| #define __TZ_get_PSPLIM_NS() (0U) | |||
| #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) | |||
| #else | |||
| #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) | |||
| #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) | |||
| #endif | |||
| #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) | |||
| #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) | |||
| #define __NOP __iar_builtin_no_operation | |||
| #define __CLZ __iar_builtin_CLZ | |||
| #define __CLREX __iar_builtin_CLREX | |||
| #define __DMB __iar_builtin_DMB | |||
| #define __DSB __iar_builtin_DSB | |||
| #define __ISB __iar_builtin_ISB | |||
| #define __LDREXB __iar_builtin_LDREXB | |||
| #define __LDREXH __iar_builtin_LDREXH | |||
| #define __LDREXW __iar_builtin_LDREX | |||
| #define __RBIT __iar_builtin_RBIT | |||
| #define __REV __iar_builtin_REV | |||
| #define __REV16 __iar_builtin_REV16 | |||
| __IAR_FT int16_t __REVSH(int16_t val) | |||
| { | |||
| return (int16_t) __iar_builtin_REVSH(val); | |||
| } | |||
| #define __ROR __iar_builtin_ROR | |||
| #define __RRX __iar_builtin_RRX | |||
| #define __SEV __iar_builtin_SEV | |||
| #if !__IAR_M0_FAMILY | |||
| #define __SSAT __iar_builtin_SSAT | |||
| #endif | |||
| #define __STREXB __iar_builtin_STREXB | |||
| #define __STREXH __iar_builtin_STREXH | |||
| #define __STREXW __iar_builtin_STREX | |||
| #if !__IAR_M0_FAMILY | |||
| #define __USAT __iar_builtin_USAT | |||
| #endif | |||
| #define __WFE __iar_builtin_WFE | |||
| #define __WFI __iar_builtin_WFI | |||
| #if __ARM_MEDIA__ | |||
| #define __SADD8 __iar_builtin_SADD8 | |||
| #define __QADD8 __iar_builtin_QADD8 | |||
| #define __SHADD8 __iar_builtin_SHADD8 | |||
| #define __UADD8 __iar_builtin_UADD8 | |||
| #define __UQADD8 __iar_builtin_UQADD8 | |||
| #define __UHADD8 __iar_builtin_UHADD8 | |||
| #define __SSUB8 __iar_builtin_SSUB8 | |||
| #define __QSUB8 __iar_builtin_QSUB8 | |||
| #define __SHSUB8 __iar_builtin_SHSUB8 | |||
| #define __USUB8 __iar_builtin_USUB8 | |||
| #define __UQSUB8 __iar_builtin_UQSUB8 | |||
| #define __UHSUB8 __iar_builtin_UHSUB8 | |||
| #define __SADD16 __iar_builtin_SADD16 | |||
| #define __QADD16 __iar_builtin_QADD16 | |||
| #define __SHADD16 __iar_builtin_SHADD16 | |||
| #define __UADD16 __iar_builtin_UADD16 | |||
| #define __UQADD16 __iar_builtin_UQADD16 | |||
| #define __UHADD16 __iar_builtin_UHADD16 | |||
| #define __SSUB16 __iar_builtin_SSUB16 | |||
| #define __QSUB16 __iar_builtin_QSUB16 | |||
| #define __SHSUB16 __iar_builtin_SHSUB16 | |||
| #define __USUB16 __iar_builtin_USUB16 | |||
| #define __UQSUB16 __iar_builtin_UQSUB16 | |||
| #define __UHSUB16 __iar_builtin_UHSUB16 | |||
| #define __SASX __iar_builtin_SASX | |||
| #define __QASX __iar_builtin_QASX | |||
| #define __SHASX __iar_builtin_SHASX | |||
| #define __UASX __iar_builtin_UASX | |||
| #define __UQASX __iar_builtin_UQASX | |||
| #define __UHASX __iar_builtin_UHASX | |||
| #define __SSAX __iar_builtin_SSAX | |||
| #define __QSAX __iar_builtin_QSAX | |||
| #define __SHSAX __iar_builtin_SHSAX | |||
| #define __USAX __iar_builtin_USAX | |||
| #define __UQSAX __iar_builtin_UQSAX | |||
| #define __UHSAX __iar_builtin_UHSAX | |||
| #define __USAD8 __iar_builtin_USAD8 | |||
| #define __USADA8 __iar_builtin_USADA8 | |||
| #define __SSAT16 __iar_builtin_SSAT16 | |||
| #define __USAT16 __iar_builtin_USAT16 | |||
| #define __UXTB16 __iar_builtin_UXTB16 | |||
| #define __UXTAB16 __iar_builtin_UXTAB16 | |||
| #define __SXTB16 __iar_builtin_SXTB16 | |||
| #define __SXTAB16 __iar_builtin_SXTAB16 | |||
| #define __SMUAD __iar_builtin_SMUAD | |||
| #define __SMUADX __iar_builtin_SMUADX | |||
| #define __SMMLA __iar_builtin_SMMLA | |||
| #define __SMLAD __iar_builtin_SMLAD | |||
| #define __SMLADX __iar_builtin_SMLADX | |||
| #define __SMLALD __iar_builtin_SMLALD | |||
| #define __SMLALDX __iar_builtin_SMLALDX | |||
| #define __SMUSD __iar_builtin_SMUSD | |||
| #define __SMUSDX __iar_builtin_SMUSDX | |||
| #define __SMLSD __iar_builtin_SMLSD | |||
| #define __SMLSDX __iar_builtin_SMLSDX | |||
| #define __SMLSLD __iar_builtin_SMLSLD | |||
| #define __SMLSLDX __iar_builtin_SMLSLDX | |||
| #define __SEL __iar_builtin_SEL | |||
| #define __QADD __iar_builtin_QADD | |||
| #define __QSUB __iar_builtin_QSUB | |||
| #define __PKHBT __iar_builtin_PKHBT | |||
| #define __PKHTB __iar_builtin_PKHTB | |||
| #endif | |||
| #else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ | |||
| #if __IAR_M0_FAMILY | |||
| /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ | |||
| #define __CLZ __cmsis_iar_clz_not_active | |||
| #define __SSAT __cmsis_iar_ssat_not_active | |||
| #define __USAT __cmsis_iar_usat_not_active | |||
| #define __RBIT __cmsis_iar_rbit_not_active | |||
| #define __get_APSR __cmsis_iar_get_APSR_not_active | |||
| #endif | |||
| #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | |||
| (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) | |||
| #define __get_FPSCR __cmsis_iar_get_FPSR_not_active | |||
| #define __set_FPSCR __cmsis_iar_set_FPSR_not_active | |||
| #endif | |||
| #ifdef __INTRINSICS_INCLUDED | |||
| #error intrinsics.h is already included previously! | |||
| #endif | |||
| #include <intrinsics.h> | |||
| #if __IAR_M0_FAMILY | |||
| /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ | |||
| #undef __CLZ | |||
| #undef __SSAT | |||
| #undef __USAT | |||
| #undef __RBIT | |||
| #undef __get_APSR | |||
| __STATIC_INLINE uint8_t __CLZ(uint32_t data) | |||
| { | |||
| if (data == 0U) { return 32U; } | |||
| uint32_t count = 0U; | |||
| uint32_t mask = 0x80000000U; | |||
| while ((data & mask) == 0U) | |||
| { | |||
| count += 1U; | |||
| mask = mask >> 1U; | |||
| } | |||
| return count; | |||
| } | |||
| __STATIC_INLINE uint32_t __RBIT(uint32_t v) | |||
| { | |||
| uint8_t sc = 31U; | |||
| uint32_t r = v; | |||
| for (v >>= 1U; v; v >>= 1U) | |||
| { | |||
| r <<= 1U; | |||
| r |= v & 1U; | |||
| sc--; | |||
| } | |||
| return (r << sc); | |||
| } | |||
| __STATIC_INLINE uint32_t __get_APSR(void) | |||
| { | |||
| uint32_t res; | |||
| __asm("MRS %0,APSR" : "=r" (res)); | |||
| return res; | |||
| } | |||
| #endif | |||
| #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ | |||
| (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) | |||
| #undef __get_FPSCR | |||
| #undef __set_FPSCR | |||
| #define __get_FPSCR() (0) | |||
| #define __set_FPSCR(VALUE) ((void)VALUE) | |||
| #endif | |||
| #pragma diag_suppress=Pe940 | |||
| #pragma diag_suppress=Pe177 | |||
| #define __enable_irq __enable_interrupt | |||
| #define __disable_irq __disable_interrupt | |||
| #define __NOP __no_operation | |||
| #define __get_xPSR __get_PSR | |||
| #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) | |||
| __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) | |||
| { | |||
| return __LDREX((unsigned long *)ptr); | |||
| } | |||
| __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) | |||
| { | |||
| return __STREX(value, (unsigned long *)ptr); | |||
| } | |||
| #endif | |||
| /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ | |||
| #if (__CORTEX_M >= 0x03) | |||
| __IAR_FT uint32_t __RRX(uint32_t value) | |||
| { | |||
| uint32_t result; | |||
| __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); | |||
| return(result); | |||
| } | |||
| __IAR_FT void __set_BASEPRI_MAX(uint32_t value) | |||
| { | |||
| __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); | |||
| } | |||
| #define __enable_fault_irq __enable_fiq | |||
| #define __disable_fault_irq __disable_fiq | |||
| #endif /* (__CORTEX_M >= 0x03) */ | |||
| __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) | |||
| { | |||
| return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); | |||
| } | |||
| #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ | |||
| (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) | |||
| __IAR_FT uint32_t __get_MSPLIM(void) | |||
| { | |||
| uint32_t res; | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure MSPLIM is RAZ/WI | |||
| res = 0U; | |||
| #else | |||
| __asm volatile("MRS %0,MSPLIM" : "=r" (res)); | |||
| #endif | |||
| return res; | |||
| } | |||
| __IAR_FT void __set_MSPLIM(uint32_t value) | |||
| { | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure MSPLIM is RAZ/WI | |||
| (void)value; | |||
| #else | |||
| __asm volatile("MSR MSPLIM,%0" :: "r" (value)); | |||
| #endif | |||
| } | |||
| __IAR_FT uint32_t __get_PSPLIM(void) | |||
| { | |||
| uint32_t res; | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| res = 0U; | |||
| #else | |||
| __asm volatile("MRS %0,PSPLIM" : "=r" (res)); | |||
| #endif | |||
| return res; | |||
| } | |||
| __IAR_FT void __set_PSPLIM(uint32_t value) | |||
| { | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| (void)value; | |||
| #else | |||
| __asm volatile("MSR PSPLIM,%0" :: "r" (value)); | |||
| #endif | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_PSP_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,PSP_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_PSP_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR PSP_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_MSP_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,MSP_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_MSP_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR MSP_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_SP_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,SP_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_SP_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR SP_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) | |||
| { | |||
| uint32_t res; | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| res = 0U; | |||
| #else | |||
| __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); | |||
| #endif | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) | |||
| { | |||
| #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ | |||
| (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) | |||
| // without main extensions, the non-secure PSPLIM is RAZ/WI | |||
| (void)value; | |||
| #else | |||
| __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); | |||
| #endif | |||
| } | |||
| __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) | |||
| { | |||
| uint32_t res; | |||
| __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); | |||
| return res; | |||
| } | |||
| __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) | |||
| { | |||
| __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); | |||
| } | |||
| #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ | |||
| #endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ | |||
| #define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) | |||
| #if __IAR_M0_FAMILY | |||
| __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) | |||
| { | |||
| if ((sat >= 1U) && (sat <= 32U)) | |||
| { | |||
| const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); | |||
| const int32_t min = -1 - max ; | |||
| if (val > max) | |||
| { | |||
| return max; | |||
| } | |||
| else if (val < min) | |||
| { | |||
| return min; | |||
| } | |||
| } | |||
| return val; | |||
| } | |||
| __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) | |||
| { | |||
| if (sat <= 31U) | |||
| { | |||
| const uint32_t max = ((1U << sat) - 1U); | |||
| if (val > (int32_t)max) | |||
| { | |||
| return max; | |||
| } | |||
| else if (val < 0) | |||
| { | |||
| return 0U; | |||
| } | |||
| } | |||
| return (uint32_t)val; | |||
| } | |||
| #endif | |||
| #if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ | |||
| __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) | |||
| { | |||
| uint32_t res; | |||
| __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); | |||
| return ((uint8_t)res); | |||
| } | |||
| __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) | |||
| { | |||
| uint32_t res; | |||
| __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); | |||
| return ((uint16_t)res); | |||
| } | |||
| __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) | |||
| { | |||
| uint32_t res; | |||
| __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); | |||
| return res; | |||
| } | |||
| __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) | |||
| { | |||
| __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); | |||
| } | |||
| __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) | |||
| { | |||
| __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); | |||
| } | |||
| __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) | |||
| { | |||
| __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); | |||
| } | |||
| #endif /* (__CORTEX_M >= 0x03) */ | |||
| #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ | |||
| (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) | |||
| __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | |||
| return ((uint8_t)res); | |||
| } | |||
| __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | |||
| return ((uint16_t)res); | |||
| } | |||
| __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | |||
| return res; | |||
| } | |||
| __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) | |||
| { | |||
| __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); | |||
| } | |||
| __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) | |||
| { | |||
| __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); | |||
| } | |||
| __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) | |||
| { | |||
| __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); | |||
| } | |||
| __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | |||
| return ((uint8_t)res); | |||
| } | |||
| __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | |||
| return ((uint16_t)res); | |||
| } | |||
| __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); | |||
| return res; | |||
| } | |||
| __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); | |||
| return res; | |||
| } | |||
| __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); | |||
| return res; | |||
| } | |||
| __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) | |||
| { | |||
| uint32_t res; | |||
| __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); | |||
| return res; | |||
| } | |||
| #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ | |||
| #undef __IAR_FT | |||
| #undef __IAR_M0_FAMILY | |||
| #undef __ICCARM_V8 | |||
| #pragma diag_default=Pe940 | |||
| #pragma diag_default=Pe177 | |||
| #endif /* __CMSIS_ICCARM_H__ */ | |||
| @@ -0,0 +1,39 @@ | |||
| /**************************************************************************//** | |||
| * @file cmsis_version.h | |||
| * @brief CMSIS Core(M) Version definitions | |||
| * @version V5.0.3 | |||
| * @date 24. June 2019 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2009-2019 ARM Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #if defined ( __ICCARM__ ) | |||
| #pragma system_include /* treat file as system include file for MISRA check */ | |||
| #elif defined (__clang__) | |||
| #pragma clang system_header /* treat file as system include file */ | |||
| #endif | |||
| #ifndef __CMSIS_VERSION_H | |||
| #define __CMSIS_VERSION_H | |||
| /* CMSIS Version definitions */ | |||
| #define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ | |||
| #define __CM_CMSIS_VERSION_SUB ( 3U) /*!< [15:0] CMSIS Core(M) sub version */ | |||
| #define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ | |||
| __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ | |||
| #endif | |||
| @@ -0,0 +1,952 @@ | |||
| /**************************************************************************//** | |||
| * @file core_cm0.h | |||
| * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File | |||
| * @version V5.0.6 | |||
| * @date 13. March 2019 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2009-2019 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #if defined ( __ICCARM__ ) | |||
| #pragma system_include /* treat file as system include file for MISRA check */ | |||
| #elif defined (__clang__) | |||
| #pragma clang system_header /* treat file as system include file */ | |||
| #endif | |||
| #ifndef __CORE_CM0_H_GENERIC | |||
| #define __CORE_CM0_H_GENERIC | |||
| #include <stdint.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /** | |||
| \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions | |||
| CMSIS violates the following MISRA-C:2004 rules: | |||
| \li Required Rule 8.5, object/function definition in header file.<br> | |||
| Function definitions in header files are used to allow 'inlining'. | |||
| \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br> | |||
| Unions are used for effective representation of core registers. | |||
| \li Advisory Rule 19.7, Function-like macro defined.<br> | |||
| Function-like macros are used to allow more efficient code. | |||
| */ | |||
| /******************************************************************************* | |||
| * CMSIS definitions | |||
| ******************************************************************************/ | |||
| /** | |||
| \ingroup Cortex_M0 | |||
| @{ | |||
| */ | |||
| #include "cmsis_version.h" | |||
| /* CMSIS CM0 definitions */ | |||
| #define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ | |||
| #define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ | |||
| #define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ | |||
| __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ | |||
| #define __CORTEX_M (0U) /*!< Cortex-M Core */ | |||
| /** __FPU_USED indicates whether an FPU is used or not. | |||
| This core does not support an FPU at all | |||
| */ | |||
| #define __FPU_USED 0U | |||
| #if defined ( __CC_ARM ) | |||
| #if defined __TARGET_FPU_VFP | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | |||
| #if defined __ARM_FP | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __GNUC__ ) | |||
| #if defined (__VFP_FP__) && !defined(__SOFTFP__) | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __ICCARM__ ) | |||
| #if defined __ARMVFP__ | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __TI_ARM__ ) | |||
| #if defined __TI_VFP_SUPPORT__ | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __TASKING__ ) | |||
| #if defined __FPU_VFP__ | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __CSMC__ ) | |||
| #if ( __CSMC__ & 0x400U) | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #endif | |||
| #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __CORE_CM0_H_GENERIC */ | |||
| #ifndef __CMSIS_GENERIC | |||
| #ifndef __CORE_CM0_H_DEPENDANT | |||
| #define __CORE_CM0_H_DEPENDANT | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /* check device defines and use defaults */ | |||
| #if defined __CHECK_DEVICE_DEFINES | |||
| #ifndef __CM0_REV | |||
| #define __CM0_REV 0x0000U | |||
| #warning "__CM0_REV not defined in device header file; using default!" | |||
| #endif | |||
| #ifndef __NVIC_PRIO_BITS | |||
| #define __NVIC_PRIO_BITS 2U | |||
| #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" | |||
| #endif | |||
| #ifndef __Vendor_SysTickConfig | |||
| #define __Vendor_SysTickConfig 0U | |||
| #warning "__Vendor_SysTickConfig not defined in device header file; using default!" | |||
| #endif | |||
| #endif | |||
| /* IO definitions (access restrictions to peripheral registers) */ | |||
| /** | |||
| \defgroup CMSIS_glob_defs CMSIS Global Defines | |||
| <strong>IO Type Qualifiers</strong> are used | |||
| \li to specify the access to peripheral variables. | |||
| \li for automatic generation of peripheral register debug information. | |||
| */ | |||
| #ifdef __cplusplus | |||
| #define __I volatile /*!< Defines 'read only' permissions */ | |||
| #else | |||
| #define __I volatile const /*!< Defines 'read only' permissions */ | |||
| #endif | |||
| #define __O volatile /*!< Defines 'write only' permissions */ | |||
| #define __IO volatile /*!< Defines 'read / write' permissions */ | |||
| /* following defines should be used for structure members */ | |||
| #define __IM volatile const /*! Defines 'read only' structure member permissions */ | |||
| #define __OM volatile /*! Defines 'write only' structure member permissions */ | |||
| #define __IOM volatile /*! Defines 'read / write' structure member permissions */ | |||
| /*@} end of group Cortex_M0 */ | |||
| /******************************************************************************* | |||
| * Register Abstraction | |||
| Core Register contain: | |||
| - Core Register | |||
| - Core NVIC Register | |||
| - Core SCB Register | |||
| - Core SysTick Register | |||
| ******************************************************************************/ | |||
| /** | |||
| \defgroup CMSIS_core_register Defines and Type Definitions | |||
| \brief Type definitions and defines for Cortex-M processor based devices. | |||
| */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_CORE Status and Control Registers | |||
| \brief Core Register type definitions. | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Union type to access the Application Program Status Register (APSR). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ | |||
| uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ | |||
| uint32_t C:1; /*!< bit: 29 Carry condition code flag */ | |||
| uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ | |||
| uint32_t N:1; /*!< bit: 31 Negative condition code flag */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } APSR_Type; | |||
| /* APSR Register Definitions */ | |||
| #define APSR_N_Pos 31U /*!< APSR: N Position */ | |||
| #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ | |||
| #define APSR_Z_Pos 30U /*!< APSR: Z Position */ | |||
| #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ | |||
| #define APSR_C_Pos 29U /*!< APSR: C Position */ | |||
| #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ | |||
| #define APSR_V_Pos 28U /*!< APSR: V Position */ | |||
| #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ | |||
| /** | |||
| \brief Union type to access the Interrupt Program Status Register (IPSR). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ | |||
| uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } IPSR_Type; | |||
| /* IPSR Register Definitions */ | |||
| #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ | |||
| #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ | |||
| /** | |||
| \brief Union type to access the Special-Purpose Program Status Registers (xPSR). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ | |||
| uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ | |||
| uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ | |||
| uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ | |||
| uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ | |||
| uint32_t C:1; /*!< bit: 29 Carry condition code flag */ | |||
| uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ | |||
| uint32_t N:1; /*!< bit: 31 Negative condition code flag */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } xPSR_Type; | |||
| /* xPSR Register Definitions */ | |||
| #define xPSR_N_Pos 31U /*!< xPSR: N Position */ | |||
| #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ | |||
| #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ | |||
| #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ | |||
| #define xPSR_C_Pos 29U /*!< xPSR: C Position */ | |||
| #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ | |||
| #define xPSR_V_Pos 28U /*!< xPSR: V Position */ | |||
| #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ | |||
| #define xPSR_T_Pos 24U /*!< xPSR: T Position */ | |||
| #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ | |||
| #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ | |||
| #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ | |||
| /** | |||
| \brief Union type to access the Control Registers (CONTROL). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t _reserved0:1; /*!< bit: 0 Reserved */ | |||
| uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ | |||
| uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } CONTROL_Type; | |||
| /* CONTROL Register Definitions */ | |||
| #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ | |||
| #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ | |||
| /*@} end of group CMSIS_CORE */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) | |||
| \brief Type definitions for the NVIC Registers | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). | |||
| */ | |||
| typedef struct | |||
| { | |||
| __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ | |||
| uint32_t RESERVED0[31U]; | |||
| __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ | |||
| uint32_t RESERVED1[31U]; | |||
| __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ | |||
| uint32_t RESERVED2[31U]; | |||
| __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ | |||
| uint32_t RESERVED3[31U]; | |||
| uint32_t RESERVED4[64U]; | |||
| __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ | |||
| } NVIC_Type; | |||
| /*@} end of group CMSIS_NVIC */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_SCB System Control Block (SCB) | |||
| \brief Type definitions for the System Control Block Registers | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the System Control Block (SCB). | |||
| */ | |||
| typedef struct | |||
| { | |||
| __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ | |||
| __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ | |||
| uint32_t RESERVED0; | |||
| __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ | |||
| __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ | |||
| __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ | |||
| uint32_t RESERVED1; | |||
| __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ | |||
| __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ | |||
| } SCB_Type; | |||
| /* SCB CPUID Register Definitions */ | |||
| #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ | |||
| #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ | |||
| #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ | |||
| #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ | |||
| #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ | |||
| #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ | |||
| #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ | |||
| #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ | |||
| #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ | |||
| #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ | |||
| /* SCB Interrupt Control State Register Definitions */ | |||
| #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ | |||
| #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ | |||
| #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ | |||
| #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ | |||
| #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ | |||
| #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ | |||
| #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ | |||
| #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ | |||
| #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ | |||
| #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ | |||
| #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ | |||
| #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ | |||
| #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ | |||
| #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ | |||
| #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ | |||
| #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ | |||
| #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ | |||
| #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ | |||
| /* SCB Application Interrupt and Reset Control Register Definitions */ | |||
| #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ | |||
| #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ | |||
| #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ | |||
| #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ | |||
| #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ | |||
| #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ | |||
| #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ | |||
| #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ | |||
| #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ | |||
| #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ | |||
| /* SCB System Control Register Definitions */ | |||
| #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ | |||
| #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ | |||
| #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ | |||
| #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ | |||
| #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ | |||
| #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ | |||
| /* SCB Configuration Control Register Definitions */ | |||
| #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ | |||
| #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ | |||
| #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ | |||
| #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ | |||
| /* SCB System Handler Control and State Register Definitions */ | |||
| #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ | |||
| #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ | |||
| /*@} end of group CMSIS_SCB */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_SysTick System Tick Timer (SysTick) | |||
| \brief Type definitions for the System Timer Registers. | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the System Timer (SysTick). | |||
| */ | |||
| typedef struct | |||
| { | |||
| __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ | |||
| __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ | |||
| __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ | |||
| __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ | |||
| } SysTick_Type; | |||
| /* SysTick Control / Status Register Definitions */ | |||
| #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ | |||
| #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ | |||
| #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ | |||
| #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ | |||
| #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ | |||
| #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ | |||
| #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ | |||
| #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ | |||
| /* SysTick Reload Register Definitions */ | |||
| #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ | |||
| #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ | |||
| /* SysTick Current Register Definitions */ | |||
| #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ | |||
| #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ | |||
| /* SysTick Calibration Register Definitions */ | |||
| #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ | |||
| #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ | |||
| #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ | |||
| #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ | |||
| #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ | |||
| #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ | |||
| /*@} end of group CMSIS_SysTick */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) | |||
| \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. | |||
| Therefore they are not covered by the Cortex-M0 header file. | |||
| @{ | |||
| */ | |||
| /*@} end of group CMSIS_CoreDebug */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_core_bitfield Core register bit field macros | |||
| \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Mask and shift a bit field value for use in a register bit range. | |||
| \param[in] field Name of the register bit field. | |||
| \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. | |||
| \return Masked and shifted value. | |||
| */ | |||
| #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) | |||
| /** | |||
| \brief Mask and shift a register value to extract a bit filed value. | |||
| \param[in] field Name of the register bit field. | |||
| \param[in] value Value of register. This parameter is interpreted as an uint32_t type. | |||
| \return Masked and shifted bit field value. | |||
| */ | |||
| #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) | |||
| /*@} end of group CMSIS_core_bitfield */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_core_base Core Definitions | |||
| \brief Definitions for base addresses, unions, and structures. | |||
| @{ | |||
| */ | |||
| /* Memory mapping of Core Hardware */ | |||
| #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ | |||
| #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ | |||
| #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ | |||
| #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ | |||
| #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ | |||
| #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ | |||
| #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ | |||
| /*@} */ | |||
| /******************************************************************************* | |||
| * Hardware Abstraction Layer | |||
| Core Function Interface contains: | |||
| - Core NVIC Functions | |||
| - Core SysTick Functions | |||
| - Core Register Access Functions | |||
| ******************************************************************************/ | |||
| /** | |||
| \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference | |||
| */ | |||
| /* ########################## NVIC functions #################################### */ | |||
| /** | |||
| \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_NVICFunctions NVIC Functions | |||
| \brief Functions that manage interrupts and exceptions via the NVIC. | |||
| @{ | |||
| */ | |||
| #ifdef CMSIS_NVIC_VIRTUAL | |||
| #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE | |||
| #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" | |||
| #endif | |||
| #include CMSIS_NVIC_VIRTUAL_HEADER_FILE | |||
| #else | |||
| #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping | |||
| #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping | |||
| #define NVIC_EnableIRQ __NVIC_EnableIRQ | |||
| #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ | |||
| #define NVIC_DisableIRQ __NVIC_DisableIRQ | |||
| #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ | |||
| #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ | |||
| #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ | |||
| /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ | |||
| #define NVIC_SetPriority __NVIC_SetPriority | |||
| #define NVIC_GetPriority __NVIC_GetPriority | |||
| #define NVIC_SystemReset __NVIC_SystemReset | |||
| #endif /* CMSIS_NVIC_VIRTUAL */ | |||
| #ifdef CMSIS_VECTAB_VIRTUAL | |||
| #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE | |||
| #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" | |||
| #endif | |||
| #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE | |||
| #else | |||
| #define NVIC_SetVector __NVIC_SetVector | |||
| #define NVIC_GetVector __NVIC_GetVector | |||
| #endif /* (CMSIS_VECTAB_VIRTUAL) */ | |||
| #define NVIC_USER_IRQ_OFFSET 16 | |||
| /* The following EXC_RETURN values are saved the LR on exception entry */ | |||
| #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ | |||
| #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ | |||
| #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ | |||
| /* Interrupt Priorities are WORD accessible only under Armv6-M */ | |||
| /* The following MACROS handle generation of the register offset and byte masks */ | |||
| #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) | |||
| #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) | |||
| #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) | |||
| #define __NVIC_SetPriorityGrouping(X) (void)(X) | |||
| #define __NVIC_GetPriorityGrouping() (0U) | |||
| /** | |||
| \brief Enable Interrupt | |||
| \details Enables a device specific interrupt in the NVIC interrupt controller. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| __COMPILER_BARRIER(); | |||
| NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| __COMPILER_BARRIER(); | |||
| } | |||
| } | |||
| /** | |||
| \brief Get Interrupt Enable status | |||
| \details Returns a device specific interrupt enable status from the NVIC interrupt controller. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \return 0 Interrupt is not enabled. | |||
| \return 1 Interrupt is enabled. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | |||
| } | |||
| else | |||
| { | |||
| return(0U); | |||
| } | |||
| } | |||
| /** | |||
| \brief Disable Interrupt | |||
| \details Disables a device specific interrupt in the NVIC interrupt controller. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| __DSB(); | |||
| __ISB(); | |||
| } | |||
| } | |||
| /** | |||
| \brief Get Pending Interrupt | |||
| \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \return 0 Interrupt status is not pending. | |||
| \return 1 Interrupt status is pending. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | |||
| } | |||
| else | |||
| { | |||
| return(0U); | |||
| } | |||
| } | |||
| /** | |||
| \brief Set Pending Interrupt | |||
| \details Sets the pending bit of a device specific interrupt in the NVIC pending register. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| } | |||
| } | |||
| /** | |||
| \brief Clear Pending Interrupt | |||
| \details Clears the pending bit of a device specific interrupt in the NVIC pending register. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| } | |||
| } | |||
| /** | |||
| \brief Set Interrupt Priority | |||
| \details Sets the priority of a device specific interrupt or a processor exception. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| \param [in] IRQn Interrupt number. | |||
| \param [in] priority Priority to set. | |||
| \note The priority cannot be set for every processor exception. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | |||
| (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | |||
| } | |||
| else | |||
| { | |||
| SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | |||
| (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | |||
| } | |||
| } | |||
| /** | |||
| \brief Get Interrupt Priority | |||
| \details Reads the priority of a device specific interrupt or a processor exception. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| \param [in] IRQn Interrupt number. | |||
| \return Interrupt Priority. | |||
| Value is aligned automatically to the implemented priority bits of the microcontroller. | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | |||
| } | |||
| else | |||
| { | |||
| return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | |||
| } | |||
| } | |||
| /** | |||
| \brief Encode Priority | |||
| \details Encodes the priority for an interrupt with the given priority group, | |||
| preemptive priority value, and subpriority value. | |||
| In case of a conflict between priority grouping and available | |||
| priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. | |||
| \param [in] PriorityGroup Used priority group. | |||
| \param [in] PreemptPriority Preemptive priority value (starting from 0). | |||
| \param [in] SubPriority Subpriority value (starting from 0). | |||
| \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). | |||
| */ | |||
| __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) | |||
| { | |||
| uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ | |||
| uint32_t PreemptPriorityBits; | |||
| uint32_t SubPriorityBits; | |||
| PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | |||
| SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | |||
| return ( | |||
| ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | | |||
| ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) | |||
| ); | |||
| } | |||
| /** | |||
| \brief Decode Priority | |||
| \details Decodes an interrupt priority value with a given priority group to | |||
| preemptive priority value and subpriority value. | |||
| In case of a conflict between priority grouping and available | |||
| priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. | |||
| \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). | |||
| \param [in] PriorityGroup Used priority group. | |||
| \param [out] pPreemptPriority Preemptive priority value (starting from 0). | |||
| \param [out] pSubPriority Subpriority value (starting from 0). | |||
| */ | |||
| __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) | |||
| { | |||
| uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ | |||
| uint32_t PreemptPriorityBits; | |||
| uint32_t SubPriorityBits; | |||
| PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | |||
| SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | |||
| *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); | |||
| *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); | |||
| } | |||
| /** | |||
| \brief Set Interrupt Vector | |||
| \details Sets an interrupt vector in SRAM based interrupt vector table. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| Address 0 must be mapped to SRAM. | |||
| \param [in] IRQn Interrupt number | |||
| \param [in] vector Address of interrupt handler function | |||
| */ | |||
| __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) | |||
| { | |||
| uint32_t vectors = 0x0U; | |||
| (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; | |||
| /* ARM Application Note 321 states that the M0 does not require the architectural barrier */ | |||
| } | |||
| /** | |||
| \brief Get Interrupt Vector | |||
| \details Reads an interrupt vector from interrupt vector table. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| \param [in] IRQn Interrupt number. | |||
| \return Address of interrupt handler function | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) | |||
| { | |||
| uint32_t vectors = 0x0U; | |||
| return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); | |||
| } | |||
| /** | |||
| \brief System Reset | |||
| \details Initiates a system reset request to reset the MCU. | |||
| */ | |||
| __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) | |||
| { | |||
| __DSB(); /* Ensure all outstanding memory accesses included | |||
| buffered write are completed before reset */ | |||
| SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | | |||
| SCB_AIRCR_SYSRESETREQ_Msk); | |||
| __DSB(); /* Ensure completion of memory access */ | |||
| for(;;) /* wait until reset */ | |||
| { | |||
| __NOP(); | |||
| } | |||
| } | |||
| /*@} end of CMSIS_Core_NVICFunctions */ | |||
| /* ########################## FPU functions #################################### */ | |||
| /** | |||
| \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_FpuFunctions FPU Functions | |||
| \brief Function that provides FPU type. | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief get FPU type | |||
| \details returns the FPU type | |||
| \returns | |||
| - \b 0: No FPU | |||
| - \b 1: Single precision FPU | |||
| - \b 2: Double + Single precision FPU | |||
| */ | |||
| __STATIC_INLINE uint32_t SCB_GetFPUType(void) | |||
| { | |||
| return 0U; /* No FPU */ | |||
| } | |||
| /*@} end of CMSIS_Core_FpuFunctions */ | |||
| /* ################################## SysTick function ############################################ */ | |||
| /** | |||
| \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_SysTickFunctions SysTick Functions | |||
| \brief Functions that configure the System. | |||
| @{ | |||
| */ | |||
| #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) | |||
| /** | |||
| \brief System Tick Configuration | |||
| \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. | |||
| Counter is in free running mode to generate periodic interrupts. | |||
| \param [in] ticks Number of ticks between two interrupts. | |||
| \return 0 Function succeeded. | |||
| \return 1 Function failed. | |||
| \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the | |||
| function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> | |||
| must contain a vendor-specific implementation of this function. | |||
| */ | |||
| __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) | |||
| { | |||
| if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) | |||
| { | |||
| return (1UL); /* Reload value impossible */ | |||
| } | |||
| SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ | |||
| NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ | |||
| SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ | |||
| SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | | |||
| SysTick_CTRL_TICKINT_Msk | | |||
| SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ | |||
| return (0UL); /* Function successful */ | |||
| } | |||
| #endif | |||
| /*@} end of CMSIS_Core_SysTickFunctions */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __CORE_CM0_H_DEPENDANT */ | |||
| #endif /* __CMSIS_GENERIC */ | |||
| @@ -0,0 +1,979 @@ | |||
| /**************************************************************************//** | |||
| * @file core_cm1.h | |||
| * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File | |||
| * @version V1.0.1 | |||
| * @date 12. November 2018 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2009-2018 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #if defined ( __ICCARM__ ) | |||
| #pragma system_include /* treat file as system include file for MISRA check */ | |||
| #elif defined (__clang__) | |||
| #pragma clang system_header /* treat file as system include file */ | |||
| #endif | |||
| #ifndef __CORE_CM1_H_GENERIC | |||
| #define __CORE_CM1_H_GENERIC | |||
| #include <stdint.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /** | |||
| \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions | |||
| CMSIS violates the following MISRA-C:2004 rules: | |||
| \li Required Rule 8.5, object/function definition in header file.<br> | |||
| Function definitions in header files are used to allow 'inlining'. | |||
| \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br> | |||
| Unions are used for effective representation of core registers. | |||
| \li Advisory Rule 19.7, Function-like macro defined.<br> | |||
| Function-like macros are used to allow more efficient code. | |||
| */ | |||
| /******************************************************************************* | |||
| * CMSIS definitions | |||
| ******************************************************************************/ | |||
| /** | |||
| \ingroup Cortex_M1 | |||
| @{ | |||
| */ | |||
| #include "cmsis_version.h" | |||
| /* CMSIS CM1 definitions */ | |||
| #define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ | |||
| #define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ | |||
| #define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ | |||
| __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ | |||
| #define __CORTEX_M (1U) /*!< Cortex-M Core */ | |||
| /** __FPU_USED indicates whether an FPU is used or not. | |||
| This core does not support an FPU at all | |||
| */ | |||
| #define __FPU_USED 0U | |||
| #if defined ( __CC_ARM ) | |||
| #if defined __TARGET_FPU_VFP | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) | |||
| #if defined __ARM_FP | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __GNUC__ ) | |||
| #if defined (__VFP_FP__) && !defined(__SOFTFP__) | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __ICCARM__ ) | |||
| #if defined __ARMVFP__ | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __TI_ARM__ ) | |||
| #if defined __TI_VFP_SUPPORT__ | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __TASKING__ ) | |||
| #if defined __FPU_VFP__ | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #elif defined ( __CSMC__ ) | |||
| #if ( __CSMC__ & 0x400U) | |||
| #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" | |||
| #endif | |||
| #endif | |||
| #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __CORE_CM1_H_GENERIC */ | |||
| #ifndef __CMSIS_GENERIC | |||
| #ifndef __CORE_CM1_H_DEPENDANT | |||
| #define __CORE_CM1_H_DEPENDANT | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /* check device defines and use defaults */ | |||
| #if defined __CHECK_DEVICE_DEFINES | |||
| #ifndef __CM1_REV | |||
| #define __CM1_REV 0x0100U | |||
| #warning "__CM1_REV not defined in device header file; using default!" | |||
| #endif | |||
| #ifndef __NVIC_PRIO_BITS | |||
| #define __NVIC_PRIO_BITS 2U | |||
| #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" | |||
| #endif | |||
| #ifndef __Vendor_SysTickConfig | |||
| #define __Vendor_SysTickConfig 0U | |||
| #warning "__Vendor_SysTickConfig not defined in device header file; using default!" | |||
| #endif | |||
| #endif | |||
| /* IO definitions (access restrictions to peripheral registers) */ | |||
| /** | |||
| \defgroup CMSIS_glob_defs CMSIS Global Defines | |||
| <strong>IO Type Qualifiers</strong> are used | |||
| \li to specify the access to peripheral variables. | |||
| \li for automatic generation of peripheral register debug information. | |||
| */ | |||
| #ifdef __cplusplus | |||
| #define __I volatile /*!< Defines 'read only' permissions */ | |||
| #else | |||
| #define __I volatile const /*!< Defines 'read only' permissions */ | |||
| #endif | |||
| #define __O volatile /*!< Defines 'write only' permissions */ | |||
| #define __IO volatile /*!< Defines 'read / write' permissions */ | |||
| /* following defines should be used for structure members */ | |||
| #define __IM volatile const /*! Defines 'read only' structure member permissions */ | |||
| #define __OM volatile /*! Defines 'write only' structure member permissions */ | |||
| #define __IOM volatile /*! Defines 'read / write' structure member permissions */ | |||
| /*@} end of group Cortex_M1 */ | |||
| /******************************************************************************* | |||
| * Register Abstraction | |||
| Core Register contain: | |||
| - Core Register | |||
| - Core NVIC Register | |||
| - Core SCB Register | |||
| - Core SysTick Register | |||
| ******************************************************************************/ | |||
| /** | |||
| \defgroup CMSIS_core_register Defines and Type Definitions | |||
| \brief Type definitions and defines for Cortex-M processor based devices. | |||
| */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_CORE Status and Control Registers | |||
| \brief Core Register type definitions. | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Union type to access the Application Program Status Register (APSR). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ | |||
| uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ | |||
| uint32_t C:1; /*!< bit: 29 Carry condition code flag */ | |||
| uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ | |||
| uint32_t N:1; /*!< bit: 31 Negative condition code flag */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } APSR_Type; | |||
| /* APSR Register Definitions */ | |||
| #define APSR_N_Pos 31U /*!< APSR: N Position */ | |||
| #define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ | |||
| #define APSR_Z_Pos 30U /*!< APSR: Z Position */ | |||
| #define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ | |||
| #define APSR_C_Pos 29U /*!< APSR: C Position */ | |||
| #define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ | |||
| #define APSR_V_Pos 28U /*!< APSR: V Position */ | |||
| #define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ | |||
| /** | |||
| \brief Union type to access the Interrupt Program Status Register (IPSR). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ | |||
| uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } IPSR_Type; | |||
| /* IPSR Register Definitions */ | |||
| #define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ | |||
| #define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ | |||
| /** | |||
| \brief Union type to access the Special-Purpose Program Status Registers (xPSR). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ | |||
| uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ | |||
| uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ | |||
| uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ | |||
| uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ | |||
| uint32_t C:1; /*!< bit: 29 Carry condition code flag */ | |||
| uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ | |||
| uint32_t N:1; /*!< bit: 31 Negative condition code flag */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } xPSR_Type; | |||
| /* xPSR Register Definitions */ | |||
| #define xPSR_N_Pos 31U /*!< xPSR: N Position */ | |||
| #define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ | |||
| #define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ | |||
| #define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ | |||
| #define xPSR_C_Pos 29U /*!< xPSR: C Position */ | |||
| #define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ | |||
| #define xPSR_V_Pos 28U /*!< xPSR: V Position */ | |||
| #define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ | |||
| #define xPSR_T_Pos 24U /*!< xPSR: T Position */ | |||
| #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ | |||
| #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ | |||
| #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ | |||
| /** | |||
| \brief Union type to access the Control Registers (CONTROL). | |||
| */ | |||
| typedef union | |||
| { | |||
| struct | |||
| { | |||
| uint32_t _reserved0:1; /*!< bit: 0 Reserved */ | |||
| uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ | |||
| uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ | |||
| } b; /*!< Structure used for bit access */ | |||
| uint32_t w; /*!< Type used for word access */ | |||
| } CONTROL_Type; | |||
| /* CONTROL Register Definitions */ | |||
| #define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ | |||
| #define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ | |||
| /*@} end of group CMSIS_CORE */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) | |||
| \brief Type definitions for the NVIC Registers | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). | |||
| */ | |||
| typedef struct | |||
| { | |||
| __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ | |||
| uint32_t RESERVED0[31U]; | |||
| __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ | |||
| uint32_t RSERVED1[31U]; | |||
| __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ | |||
| uint32_t RESERVED2[31U]; | |||
| __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ | |||
| uint32_t RESERVED3[31U]; | |||
| uint32_t RESERVED4[64U]; | |||
| __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ | |||
| } NVIC_Type; | |||
| /*@} end of group CMSIS_NVIC */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_SCB System Control Block (SCB) | |||
| \brief Type definitions for the System Control Block Registers | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the System Control Block (SCB). | |||
| */ | |||
| typedef struct | |||
| { | |||
| __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ | |||
| __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ | |||
| uint32_t RESERVED0; | |||
| __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ | |||
| __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ | |||
| __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ | |||
| uint32_t RESERVED1; | |||
| __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ | |||
| __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ | |||
| } SCB_Type; | |||
| /* SCB CPUID Register Definitions */ | |||
| #define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ | |||
| #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ | |||
| #define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ | |||
| #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ | |||
| #define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ | |||
| #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ | |||
| #define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ | |||
| #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ | |||
| #define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ | |||
| #define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ | |||
| /* SCB Interrupt Control State Register Definitions */ | |||
| #define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ | |||
| #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ | |||
| #define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ | |||
| #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ | |||
| #define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ | |||
| #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ | |||
| #define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ | |||
| #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ | |||
| #define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ | |||
| #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ | |||
| #define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ | |||
| #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ | |||
| #define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ | |||
| #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ | |||
| #define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ | |||
| #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ | |||
| #define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ | |||
| #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ | |||
| /* SCB Application Interrupt and Reset Control Register Definitions */ | |||
| #define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ | |||
| #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ | |||
| #define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ | |||
| #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ | |||
| #define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ | |||
| #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ | |||
| #define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ | |||
| #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ | |||
| #define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ | |||
| #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ | |||
| /* SCB System Control Register Definitions */ | |||
| #define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ | |||
| #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ | |||
| #define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ | |||
| #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ | |||
| #define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ | |||
| #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ | |||
| /* SCB Configuration Control Register Definitions */ | |||
| #define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ | |||
| #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ | |||
| #define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ | |||
| #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ | |||
| /* SCB System Handler Control and State Register Definitions */ | |||
| #define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ | |||
| #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ | |||
| /*@} end of group CMSIS_SCB */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) | |||
| \brief Type definitions for the System Control and ID Register not in the SCB | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the System Control and ID Register not in the SCB. | |||
| */ | |||
| typedef struct | |||
| { | |||
| uint32_t RESERVED0[2U]; | |||
| __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ | |||
| } SCnSCB_Type; | |||
| /* Auxiliary Control Register Definitions */ | |||
| #define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ | |||
| #define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ | |||
| #define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ | |||
| #define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ | |||
| /*@} end of group CMSIS_SCnotSCB */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_SysTick System Tick Timer (SysTick) | |||
| \brief Type definitions for the System Timer Registers. | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Structure type to access the System Timer (SysTick). | |||
| */ | |||
| typedef struct | |||
| { | |||
| __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ | |||
| __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ | |||
| __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ | |||
| __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ | |||
| } SysTick_Type; | |||
| /* SysTick Control / Status Register Definitions */ | |||
| #define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ | |||
| #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ | |||
| #define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ | |||
| #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ | |||
| #define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ | |||
| #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ | |||
| #define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ | |||
| #define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ | |||
| /* SysTick Reload Register Definitions */ | |||
| #define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ | |||
| #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ | |||
| /* SysTick Current Register Definitions */ | |||
| #define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ | |||
| #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ | |||
| /* SysTick Calibration Register Definitions */ | |||
| #define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ | |||
| #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ | |||
| #define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ | |||
| #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ | |||
| #define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ | |||
| #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ | |||
| /*@} end of group CMSIS_SysTick */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) | |||
| \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. | |||
| Therefore they are not covered by the Cortex-M1 header file. | |||
| @{ | |||
| */ | |||
| /*@} end of group CMSIS_CoreDebug */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_core_bitfield Core register bit field macros | |||
| \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief Mask and shift a bit field value for use in a register bit range. | |||
| \param[in] field Name of the register bit field. | |||
| \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. | |||
| \return Masked and shifted value. | |||
| */ | |||
| #define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) | |||
| /** | |||
| \brief Mask and shift a register value to extract a bit filed value. | |||
| \param[in] field Name of the register bit field. | |||
| \param[in] value Value of register. This parameter is interpreted as an uint32_t type. | |||
| \return Masked and shifted bit field value. | |||
| */ | |||
| #define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) | |||
| /*@} end of group CMSIS_core_bitfield */ | |||
| /** | |||
| \ingroup CMSIS_core_register | |||
| \defgroup CMSIS_core_base Core Definitions | |||
| \brief Definitions for base addresses, unions, and structures. | |||
| @{ | |||
| */ | |||
| /* Memory mapping of Core Hardware */ | |||
| #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ | |||
| #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ | |||
| #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ | |||
| #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ | |||
| #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ | |||
| #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ | |||
| #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ | |||
| #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ | |||
| /*@} */ | |||
| /******************************************************************************* | |||
| * Hardware Abstraction Layer | |||
| Core Function Interface contains: | |||
| - Core NVIC Functions | |||
| - Core SysTick Functions | |||
| - Core Register Access Functions | |||
| ******************************************************************************/ | |||
| /** | |||
| \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference | |||
| */ | |||
| /* ########################## NVIC functions #################################### */ | |||
| /** | |||
| \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_NVICFunctions NVIC Functions | |||
| \brief Functions that manage interrupts and exceptions via the NVIC. | |||
| @{ | |||
| */ | |||
| #ifdef CMSIS_NVIC_VIRTUAL | |||
| #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE | |||
| #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" | |||
| #endif | |||
| #include CMSIS_NVIC_VIRTUAL_HEADER_FILE | |||
| #else | |||
| #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping | |||
| #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping | |||
| #define NVIC_EnableIRQ __NVIC_EnableIRQ | |||
| #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ | |||
| #define NVIC_DisableIRQ __NVIC_DisableIRQ | |||
| #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ | |||
| #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ | |||
| #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ | |||
| /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ | |||
| #define NVIC_SetPriority __NVIC_SetPriority | |||
| #define NVIC_GetPriority __NVIC_GetPriority | |||
| #define NVIC_SystemReset __NVIC_SystemReset | |||
| #endif /* CMSIS_NVIC_VIRTUAL */ | |||
| #ifdef CMSIS_VECTAB_VIRTUAL | |||
| #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE | |||
| #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" | |||
| #endif | |||
| #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE | |||
| #else | |||
| #define NVIC_SetVector __NVIC_SetVector | |||
| #define NVIC_GetVector __NVIC_GetVector | |||
| #endif /* (CMSIS_VECTAB_VIRTUAL) */ | |||
| #define NVIC_USER_IRQ_OFFSET 16 | |||
| /* The following EXC_RETURN values are saved the LR on exception entry */ | |||
| #define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ | |||
| #define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ | |||
| #define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ | |||
| /* Interrupt Priorities are WORD accessible only under Armv6-M */ | |||
| /* The following MACROS handle generation of the register offset and byte masks */ | |||
| #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) | |||
| #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) | |||
| #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) | |||
| #define __NVIC_SetPriorityGrouping(X) (void)(X) | |||
| #define __NVIC_GetPriorityGrouping() (0U) | |||
| /** | |||
| \brief Enable Interrupt | |||
| \details Enables a device specific interrupt in the NVIC interrupt controller. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| __COMPILER_BARRIER(); | |||
| NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| __COMPILER_BARRIER(); | |||
| } | |||
| } | |||
| /** | |||
| \brief Get Interrupt Enable status | |||
| \details Returns a device specific interrupt enable status from the NVIC interrupt controller. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \return 0 Interrupt is not enabled. | |||
| \return 1 Interrupt is enabled. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | |||
| } | |||
| else | |||
| { | |||
| return(0U); | |||
| } | |||
| } | |||
| /** | |||
| \brief Disable Interrupt | |||
| \details Disables a device specific interrupt in the NVIC interrupt controller. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| __DSB(); | |||
| __ISB(); | |||
| } | |||
| } | |||
| /** | |||
| \brief Get Pending Interrupt | |||
| \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \return 0 Interrupt status is not pending. | |||
| \return 1 Interrupt status is pending. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); | |||
| } | |||
| else | |||
| { | |||
| return(0U); | |||
| } | |||
| } | |||
| /** | |||
| \brief Set Pending Interrupt | |||
| \details Sets the pending bit of a device specific interrupt in the NVIC pending register. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| } | |||
| } | |||
| /** | |||
| \brief Clear Pending Interrupt | |||
| \details Clears the pending bit of a device specific interrupt in the NVIC pending register. | |||
| \param [in] IRQn Device specific interrupt number. | |||
| \note IRQn must not be negative. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); | |||
| } | |||
| } | |||
| /** | |||
| \brief Set Interrupt Priority | |||
| \details Sets the priority of a device specific interrupt or a processor exception. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| \param [in] IRQn Interrupt number. | |||
| \param [in] priority Priority to set. | |||
| \note The priority cannot be set for every processor exception. | |||
| */ | |||
| __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | |||
| (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | |||
| } | |||
| else | |||
| { | |||
| SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | | |||
| (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); | |||
| } | |||
| } | |||
| /** | |||
| \brief Get Interrupt Priority | |||
| \details Reads the priority of a device specific interrupt or a processor exception. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| \param [in] IRQn Interrupt number. | |||
| \return Interrupt Priority. | |||
| Value is aligned automatically to the implemented priority bits of the microcontroller. | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) | |||
| { | |||
| if ((int32_t)(IRQn) >= 0) | |||
| { | |||
| return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | |||
| } | |||
| else | |||
| { | |||
| return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); | |||
| } | |||
| } | |||
| /** | |||
| \brief Encode Priority | |||
| \details Encodes the priority for an interrupt with the given priority group, | |||
| preemptive priority value, and subpriority value. | |||
| In case of a conflict between priority grouping and available | |||
| priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. | |||
| \param [in] PriorityGroup Used priority group. | |||
| \param [in] PreemptPriority Preemptive priority value (starting from 0). | |||
| \param [in] SubPriority Subpriority value (starting from 0). | |||
| \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). | |||
| */ | |||
| __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) | |||
| { | |||
| uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ | |||
| uint32_t PreemptPriorityBits; | |||
| uint32_t SubPriorityBits; | |||
| PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | |||
| SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | |||
| return ( | |||
| ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | | |||
| ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) | |||
| ); | |||
| } | |||
| /** | |||
| \brief Decode Priority | |||
| \details Decodes an interrupt priority value with a given priority group to | |||
| preemptive priority value and subpriority value. | |||
| In case of a conflict between priority grouping and available | |||
| priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. | |||
| \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). | |||
| \param [in] PriorityGroup Used priority group. | |||
| \param [out] pPreemptPriority Preemptive priority value (starting from 0). | |||
| \param [out] pSubPriority Subpriority value (starting from 0). | |||
| */ | |||
| __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) | |||
| { | |||
| uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ | |||
| uint32_t PreemptPriorityBits; | |||
| uint32_t SubPriorityBits; | |||
| PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); | |||
| SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); | |||
| *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); | |||
| *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); | |||
| } | |||
| /** | |||
| \brief Set Interrupt Vector | |||
| \details Sets an interrupt vector in SRAM based interrupt vector table. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| Address 0 must be mapped to SRAM. | |||
| \param [in] IRQn Interrupt number | |||
| \param [in] vector Address of interrupt handler function | |||
| */ | |||
| __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) | |||
| { | |||
| uint32_t *vectors = (uint32_t *)0x0U; | |||
| vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; | |||
| /* ARM Application Note 321 states that the M1 does not require the architectural barrier */ | |||
| } | |||
| /** | |||
| \brief Get Interrupt Vector | |||
| \details Reads an interrupt vector from interrupt vector table. | |||
| The interrupt number can be positive to specify a device specific interrupt, | |||
| or negative to specify a processor exception. | |||
| \param [in] IRQn Interrupt number. | |||
| \return Address of interrupt handler function | |||
| */ | |||
| __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) | |||
| { | |||
| uint32_t *vectors = (uint32_t *)0x0U; | |||
| return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; | |||
| } | |||
| /** | |||
| \brief System Reset | |||
| \details Initiates a system reset request to reset the MCU. | |||
| */ | |||
| __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) | |||
| { | |||
| __DSB(); /* Ensure all outstanding memory accesses included | |||
| buffered write are completed before reset */ | |||
| SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | | |||
| SCB_AIRCR_SYSRESETREQ_Msk); | |||
| __DSB(); /* Ensure completion of memory access */ | |||
| for(;;) /* wait until reset */ | |||
| { | |||
| __NOP(); | |||
| } | |||
| } | |||
| /*@} end of CMSIS_Core_NVICFunctions */ | |||
| /* ########################## FPU functions #################################### */ | |||
| /** | |||
| \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_FpuFunctions FPU Functions | |||
| \brief Function that provides FPU type. | |||
| @{ | |||
| */ | |||
| /** | |||
| \brief get FPU type | |||
| \details returns the FPU type | |||
| \returns | |||
| - \b 0: No FPU | |||
| - \b 1: Single precision FPU | |||
| - \b 2: Double + Single precision FPU | |||
| */ | |||
| __STATIC_INLINE uint32_t SCB_GetFPUType(void) | |||
| { | |||
| return 0U; /* No FPU */ | |||
| } | |||
| /*@} end of CMSIS_Core_FpuFunctions */ | |||
| /* ################################## SysTick function ############################################ */ | |||
| /** | |||
| \ingroup CMSIS_Core_FunctionInterface | |||
| \defgroup CMSIS_Core_SysTickFunctions SysTick Functions | |||
| \brief Functions that configure the System. | |||
| @{ | |||
| */ | |||
| #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) | |||
| /** | |||
| \brief System Tick Configuration | |||
| \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. | |||
| Counter is in free running mode to generate periodic interrupts. | |||
| \param [in] ticks Number of ticks between two interrupts. | |||
| \return 0 Function succeeded. | |||
| \return 1 Function failed. | |||
| \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the | |||
| function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> | |||
| must contain a vendor-specific implementation of this function. | |||
| */ | |||
| __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) | |||
| { | |||
| if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) | |||
| { | |||
| return (1UL); /* Reload value impossible */ | |||
| } | |||
| SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ | |||
| NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ | |||
| SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ | |||
| SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | | |||
| SysTick_CTRL_TICKINT_Msk | | |||
| SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ | |||
| return (0UL); /* Function successful */ | |||
| } | |||
| #endif | |||
| /*@} end of CMSIS_Core_SysTickFunctions */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __CORE_CM1_H_DEPENDANT */ | |||
| #endif /* __CMSIS_GENERIC */ | |||
| @@ -0,0 +1,74 @@ | |||
| /**************************************************************************//** | |||
| * @file cmsis_xcc.h | |||
| * @brief CMSIS DSP Core Peripheral Access Layer Header File | |||
| * @version V1.0 | |||
| * @date 20. January 2019 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2009-2019 ARM Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef __CORE_DSP_H_GENERIC | |||
| #define __CORE_DSP_H_GENERIC | |||
| #include <stdint.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /* IO definitions (access restrictions to peripheral registers) */ | |||
| /** | |||
| \defgroup CMSIS_glob_defs CMSIS Global Defines | |||
| <strong>IO Type Qualifiers</strong> are used | |||
| \li to specify the access to peripheral variables. | |||
| \li for automatic generation of peripheral register debug information. | |||
| */ | |||
| #ifdef __cplusplus | |||
| #define __I volatile /*!< Defines 'read only' permissions */ | |||
| #else | |||
| #define __I volatile const /*!< Defines 'read only' permissions */ | |||
| #endif | |||
| #define __O volatile /*!< Defines 'write only' permissions */ | |||
| #define __IO volatile /*!< Defines 'read / write' permissions */ | |||
| /* following defines should be used for structure members */ | |||
| #define __IM volatile const /*! Defines 'read only' structure member permissions */ | |||
| #define __OM volatile /*! Defines 'write only' structure member permissions */ | |||
| #define __IOM volatile /*! Defines 'read / write' structure member permissions */ | |||
| #define __STATIC_INLINE static inline | |||
| #define __BKPT(value) do {} while(0) | |||
| #define __NOP() do {} while(0) | |||
| #define NVIC_SetPriorityGrouping(value) do {} while(0) | |||
| #define NVIC_GetPriorityGrouping() do {} while(0) | |||
| #define NVIC_EnableIRQ(value) do {} while(0) | |||
| #define NVIC_GetEnableIRQ(value) do {} while(0) | |||
| #define NVIC_DisableIRQ(value) do {} while(0) | |||
| #define NVIC_GetPendingIRQ(value) do {} while(0) | |||
| #define NVIC_SetPendingIRQ(value) do {} while(0) | |||
| #define NVIC_ClearPendingIRQ(value) do {} while(0) | |||
| #define NVIC_GetActive(value) do {} while(0) | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __CORE_DSP_H_GENERIC */ | |||
| @@ -0,0 +1,272 @@ | |||
| /****************************************************************************** | |||
| * @file mpu_armv7.h | |||
| * @brief CMSIS MPU API for Armv7-M MPU | |||
| * @version V5.1.0 | |||
| * @date 08. March 2019 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2017-2019 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #if defined ( __ICCARM__ ) | |||
| #pragma system_include /* treat file as system include file for MISRA check */ | |||
| #elif defined (__clang__) | |||
| #pragma clang system_header /* treat file as system include file */ | |||
| #endif | |||
| #ifndef ARM_MPU_ARMV7_H | |||
| #define ARM_MPU_ARMV7_H | |||
| #define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes | |||
| #define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes | |||
| #define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes | |||
| #define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes | |||
| #define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes | |||
| #define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte | |||
| #define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes | |||
| #define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes | |||
| #define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes | |||
| #define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes | |||
| #define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes | |||
| #define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes | |||
| #define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes | |||
| #define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes | |||
| #define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes | |||
| #define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte | |||
| #define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes | |||
| #define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes | |||
| #define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes | |||
| #define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes | |||
| #define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes | |||
| #define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes | |||
| #define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes | |||
| #define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes | |||
| #define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes | |||
| #define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte | |||
| #define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes | |||
| #define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes | |||
| #define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access | |||
| #define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only | |||
| #define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only | |||
| #define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access | |||
| #define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only | |||
| #define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access | |||
| /** MPU Region Base Address Register Value | |||
| * | |||
| * \param Region The region to be configured, number 0 to 15. | |||
| * \param BaseAddress The base address for the region. | |||
| */ | |||
| #define ARM_MPU_RBAR(Region, BaseAddress) \ | |||
| (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ | |||
| ((Region) & MPU_RBAR_REGION_Msk) | \ | |||
| (MPU_RBAR_VALID_Msk)) | |||
| /** | |||
| * MPU Memory Access Attributes | |||
| * | |||
| * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. | |||
| * \param IsShareable Region is shareable between multiple bus masters. | |||
| * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. | |||
| * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. | |||
| */ | |||
| #define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ | |||
| ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ | |||
| (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ | |||
| (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ | |||
| (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) | |||
| /** | |||
| * MPU Region Attribute and Size Register Value | |||
| * | |||
| * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. | |||
| * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. | |||
| * \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. | |||
| * \param SubRegionDisable Sub-region disable field. | |||
| * \param Size Region size of the region to be configured, for example 4K, 8K. | |||
| */ | |||
| #define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ | |||
| ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ | |||
| (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ | |||
| (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ | |||
| (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ | |||
| (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ | |||
| (((MPU_RASR_ENABLE_Msk)))) | |||
| /** | |||
| * MPU Region Attribute and Size Register Value | |||
| * | |||
| * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. | |||
| * \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. | |||
| * \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. | |||
| * \param IsShareable Region is shareable between multiple bus masters. | |||
| * \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. | |||
| * \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. | |||
| * \param SubRegionDisable Sub-region disable field. | |||
| * \param Size Region size of the region to be configured, for example 4K, 8K. | |||
| */ | |||
| #define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ | |||
| ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) | |||
| /** | |||
| * MPU Memory Access Attribute for strongly ordered memory. | |||
| * - TEX: 000b | |||
| * - Shareable | |||
| * - Non-cacheable | |||
| * - Non-bufferable | |||
| */ | |||
| #define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) | |||
| /** | |||
| * MPU Memory Access Attribute for device memory. | |||
| * - TEX: 000b (if shareable) or 010b (if non-shareable) | |||
| * - Shareable or non-shareable | |||
| * - Non-cacheable | |||
| * - Bufferable (if shareable) or non-bufferable (if non-shareable) | |||
| * | |||
| * \param IsShareable Configures the device memory as shareable or non-shareable. | |||
| */ | |||
| #define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) | |||
| /** | |||
| * MPU Memory Access Attribute for normal memory. | |||
| * - TEX: 1BBb (reflecting outer cacheability rules) | |||
| * - Shareable or non-shareable | |||
| * - Cacheable or non-cacheable (reflecting inner cacheability rules) | |||
| * - Bufferable or non-bufferable (reflecting inner cacheability rules) | |||
| * | |||
| * \param OuterCp Configures the outer cache policy. | |||
| * \param InnerCp Configures the inner cache policy. | |||
| * \param IsShareable Configures the memory as shareable or non-shareable. | |||
| */ | |||
| #define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) | |||
| /** | |||
| * MPU Memory Access Attribute non-cacheable policy. | |||
| */ | |||
| #define ARM_MPU_CACHEP_NOCACHE 0U | |||
| /** | |||
| * MPU Memory Access Attribute write-back, write and read allocate policy. | |||
| */ | |||
| #define ARM_MPU_CACHEP_WB_WRA 1U | |||
| /** | |||
| * MPU Memory Access Attribute write-through, no write allocate policy. | |||
| */ | |||
| #define ARM_MPU_CACHEP_WT_NWA 2U | |||
| /** | |||
| * MPU Memory Access Attribute write-back, no write allocate policy. | |||
| */ | |||
| #define ARM_MPU_CACHEP_WB_NWA 3U | |||
| /** | |||
| * Struct for a single MPU Region | |||
| */ | |||
| typedef struct { | |||
| uint32_t RBAR; //!< The region base address register value (RBAR) | |||
| uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR | |||
| } ARM_MPU_Region_t; | |||
| /** Enable the MPU. | |||
| * \param MPU_Control Default access permissions for unconfigured regions. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) | |||
| { | |||
| MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; | |||
| #ifdef SCB_SHCSR_MEMFAULTENA_Msk | |||
| SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | |||
| #endif | |||
| __DSB(); | |||
| __ISB(); | |||
| } | |||
| /** Disable the MPU. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Disable(void) | |||
| { | |||
| __DMB(); | |||
| #ifdef SCB_SHCSR_MEMFAULTENA_Msk | |||
| SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; | |||
| #endif | |||
| MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; | |||
| } | |||
| /** Clear and disable the given MPU region. | |||
| * \param rnr Region number to be cleared. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) | |||
| { | |||
| MPU->RNR = rnr; | |||
| MPU->RASR = 0U; | |||
| } | |||
| /** Configure an MPU region. | |||
| * \param rbar Value for RBAR register. | |||
| * \param rsar Value for RSAR register. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) | |||
| { | |||
| MPU->RBAR = rbar; | |||
| MPU->RASR = rasr; | |||
| } | |||
| /** Configure the given MPU region. | |||
| * \param rnr Region number to be configured. | |||
| * \param rbar Value for RBAR register. | |||
| * \param rsar Value for RSAR register. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) | |||
| { | |||
| MPU->RNR = rnr; | |||
| MPU->RBAR = rbar; | |||
| MPU->RASR = rasr; | |||
| } | |||
| /** Memcopy with strictly ordered memory access, e.g. for register targets. | |||
| * \param dst Destination data is copied to. | |||
| * \param src Source data is copied from. | |||
| * \param len Amount of data words to be copied. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) | |||
| { | |||
| uint32_t i; | |||
| for (i = 0U; i < len; ++i) | |||
| { | |||
| dst[i] = src[i]; | |||
| } | |||
| } | |||
| /** Load the given number of MPU regions from a table. | |||
| * \param table Pointer to the MPU configuration table. | |||
| * \param cnt Amount of regions to be configured. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) | |||
| { | |||
| const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; | |||
| while (cnt > MPU_TYPE_RALIASES) { | |||
| ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); | |||
| table += MPU_TYPE_RALIASES; | |||
| cnt -= MPU_TYPE_RALIASES; | |||
| } | |||
| ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,346 @@ | |||
| /****************************************************************************** | |||
| * @file mpu_armv8.h | |||
| * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU | |||
| * @version V5.1.0 | |||
| * @date 08. March 2019 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2017-2019 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #if defined ( __ICCARM__ ) | |||
| #pragma system_include /* treat file as system include file for MISRA check */ | |||
| #elif defined (__clang__) | |||
| #pragma clang system_header /* treat file as system include file */ | |||
| #endif | |||
| #ifndef ARM_MPU_ARMV8_H | |||
| #define ARM_MPU_ARMV8_H | |||
| /** \brief Attribute for device memory (outer only) */ | |||
| #define ARM_MPU_ATTR_DEVICE ( 0U ) | |||
| /** \brief Attribute for non-cacheable, normal memory */ | |||
| #define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) | |||
| /** \brief Attribute for normal memory (outer and inner) | |||
| * \param NT Non-Transient: Set to 1 for non-transient data. | |||
| * \param WB Write-Back: Set to 1 to use write-back update policy. | |||
| * \param RA Read Allocation: Set to 1 to use cache allocation on read miss. | |||
| * \param WA Write Allocation: Set to 1 to use cache allocation on write miss. | |||
| */ | |||
| #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ | |||
| (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) | |||
| /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ | |||
| #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) | |||
| /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ | |||
| #define ARM_MPU_ATTR_DEVICE_nGnRE (1U) | |||
| /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ | |||
| #define ARM_MPU_ATTR_DEVICE_nGRE (2U) | |||
| /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ | |||
| #define ARM_MPU_ATTR_DEVICE_GRE (3U) | |||
| /** \brief Memory Attribute | |||
| * \param O Outer memory attributes | |||
| * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes | |||
| */ | |||
| #define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) | |||
| /** \brief Normal memory non-shareable */ | |||
| #define ARM_MPU_SH_NON (0U) | |||
| /** \brief Normal memory outer shareable */ | |||
| #define ARM_MPU_SH_OUTER (2U) | |||
| /** \brief Normal memory inner shareable */ | |||
| #define ARM_MPU_SH_INNER (3U) | |||
| /** \brief Memory access permissions | |||
| * \param RO Read-Only: Set to 1 for read-only memory. | |||
| * \param NP Non-Privileged: Set to 1 for non-privileged memory. | |||
| */ | |||
| #define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) | |||
| /** \brief Region Base Address Register value | |||
| * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. | |||
| * \param SH Defines the Shareability domain for this memory region. | |||
| * \param RO Read-Only: Set to 1 for a read-only memory region. | |||
| * \param NP Non-Privileged: Set to 1 for a non-privileged memory region. | |||
| * \oaram XN eXecute Never: Set to 1 for a non-executable memory region. | |||
| */ | |||
| #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ | |||
| ((BASE & MPU_RBAR_BASE_Msk) | \ | |||
| ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ | |||
| ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ | |||
| ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) | |||
| /** \brief Region Limit Address Register value | |||
| * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. | |||
| * \param IDX The attribute index to be associated with this memory region. | |||
| */ | |||
| #define ARM_MPU_RLAR(LIMIT, IDX) \ | |||
| ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ | |||
| ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ | |||
| (MPU_RLAR_EN_Msk)) | |||
| #if defined(MPU_RLAR_PXN_Pos) | |||
| /** \brief Region Limit Address Register with PXN value | |||
| * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. | |||
| * \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. | |||
| * \param IDX The attribute index to be associated with this memory region. | |||
| */ | |||
| #define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ | |||
| ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ | |||
| ((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ | |||
| ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ | |||
| (MPU_RLAR_EN_Msk)) | |||
| #endif | |||
| /** | |||
| * Struct for a single MPU Region | |||
| */ | |||
| typedef struct { | |||
| uint32_t RBAR; /*!< Region Base Address Register value */ | |||
| uint32_t RLAR; /*!< Region Limit Address Register value */ | |||
| } ARM_MPU_Region_t; | |||
| /** Enable the MPU. | |||
| * \param MPU_Control Default access permissions for unconfigured regions. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) | |||
| { | |||
| MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; | |||
| #ifdef SCB_SHCSR_MEMFAULTENA_Msk | |||
| SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | |||
| #endif | |||
| __DSB(); | |||
| __ISB(); | |||
| } | |||
| /** Disable the MPU. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Disable(void) | |||
| { | |||
| __DMB(); | |||
| #ifdef SCB_SHCSR_MEMFAULTENA_Msk | |||
| SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; | |||
| #endif | |||
| MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; | |||
| } | |||
| #ifdef MPU_NS | |||
| /** Enable the Non-secure MPU. | |||
| * \param MPU_Control Default access permissions for unconfigured regions. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) | |||
| { | |||
| MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; | |||
| #ifdef SCB_SHCSR_MEMFAULTENA_Msk | |||
| SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; | |||
| #endif | |||
| __DSB(); | |||
| __ISB(); | |||
| } | |||
| /** Disable the Non-secure MPU. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Disable_NS(void) | |||
| { | |||
| __DMB(); | |||
| #ifdef SCB_SHCSR_MEMFAULTENA_Msk | |||
| SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; | |||
| #endif | |||
| MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; | |||
| } | |||
| #endif | |||
| /** Set the memory attribute encoding to the given MPU. | |||
| * \param mpu Pointer to the MPU to be configured. | |||
| * \param idx The attribute index to be set [0-7] | |||
| * \param attr The attribute value to be set. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) | |||
| { | |||
| const uint8_t reg = idx / 4U; | |||
| const uint32_t pos = ((idx % 4U) * 8U); | |||
| const uint32_t mask = 0xFFU << pos; | |||
| if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { | |||
| return; // invalid index | |||
| } | |||
| mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); | |||
| } | |||
| /** Set the memory attribute encoding. | |||
| * \param idx The attribute index to be set [0-7] | |||
| * \param attr The attribute value to be set. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) | |||
| { | |||
| ARM_MPU_SetMemAttrEx(MPU, idx, attr); | |||
| } | |||
| #ifdef MPU_NS | |||
| /** Set the memory attribute encoding to the Non-secure MPU. | |||
| * \param idx The attribute index to be set [0-7] | |||
| * \param attr The attribute value to be set. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) | |||
| { | |||
| ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); | |||
| } | |||
| #endif | |||
| /** Clear and disable the given MPU region of the given MPU. | |||
| * \param mpu Pointer to MPU to be used. | |||
| * \param rnr Region number to be cleared. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) | |||
| { | |||
| mpu->RNR = rnr; | |||
| mpu->RLAR = 0U; | |||
| } | |||
| /** Clear and disable the given MPU region. | |||
| * \param rnr Region number to be cleared. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) | |||
| { | |||
| ARM_MPU_ClrRegionEx(MPU, rnr); | |||
| } | |||
| #ifdef MPU_NS | |||
| /** Clear and disable the given Non-secure MPU region. | |||
| * \param rnr Region number to be cleared. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) | |||
| { | |||
| ARM_MPU_ClrRegionEx(MPU_NS, rnr); | |||
| } | |||
| #endif | |||
| /** Configure the given MPU region of the given MPU. | |||
| * \param mpu Pointer to MPU to be used. | |||
| * \param rnr Region number to be configured. | |||
| * \param rbar Value for RBAR register. | |||
| * \param rlar Value for RLAR register. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) | |||
| { | |||
| mpu->RNR = rnr; | |||
| mpu->RBAR = rbar; | |||
| mpu->RLAR = rlar; | |||
| } | |||
| /** Configure the given MPU region. | |||
| * \param rnr Region number to be configured. | |||
| * \param rbar Value for RBAR register. | |||
| * \param rlar Value for RLAR register. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) | |||
| { | |||
| ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); | |||
| } | |||
| #ifdef MPU_NS | |||
| /** Configure the given Non-secure MPU region. | |||
| * \param rnr Region number to be configured. | |||
| * \param rbar Value for RBAR register. | |||
| * \param rlar Value for RLAR register. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) | |||
| { | |||
| ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); | |||
| } | |||
| #endif | |||
| /** Memcopy with strictly ordered memory access, e.g. for register targets. | |||
| * \param dst Destination data is copied to. | |||
| * \param src Source data is copied from. | |||
| * \param len Amount of data words to be copied. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) | |||
| { | |||
| uint32_t i; | |||
| for (i = 0U; i < len; ++i) | |||
| { | |||
| dst[i] = src[i]; | |||
| } | |||
| } | |||
| /** Load the given number of MPU regions from a table to the given MPU. | |||
| * \param mpu Pointer to the MPU registers to be used. | |||
| * \param rnr First region number to be configured. | |||
| * \param table Pointer to the MPU configuration table. | |||
| * \param cnt Amount of regions to be configured. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) | |||
| { | |||
| const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; | |||
| if (cnt == 1U) { | |||
| mpu->RNR = rnr; | |||
| ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); | |||
| } else { | |||
| uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); | |||
| uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; | |||
| mpu->RNR = rnrBase; | |||
| while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { | |||
| uint32_t c = MPU_TYPE_RALIASES - rnrOffset; | |||
| ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); | |||
| table += c; | |||
| cnt -= c; | |||
| rnrOffset = 0U; | |||
| rnrBase += MPU_TYPE_RALIASES; | |||
| mpu->RNR = rnrBase; | |||
| } | |||
| ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); | |||
| } | |||
| } | |||
| /** Load the given number of MPU regions from a table. | |||
| * \param rnr First region number to be configured. | |||
| * \param table Pointer to the MPU configuration table. | |||
| * \param cnt Amount of regions to be configured. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) | |||
| { | |||
| ARM_MPU_LoadEx(MPU, rnr, table, cnt); | |||
| } | |||
| #ifdef MPU_NS | |||
| /** Load the given number of MPU regions from a table to the Non-secure MPU. | |||
| * \param rnr First region number to be configured. | |||
| * \param table Pointer to the MPU configuration table. | |||
| * \param cnt Amount of regions to be configured. | |||
| */ | |||
| __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) | |||
| { | |||
| ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,70 @@ | |||
| /****************************************************************************** | |||
| * @file tz_context.h | |||
| * @brief Context Management for Armv8-M TrustZone | |||
| * @version V1.0.1 | |||
| * @date 10. January 2018 | |||
| ******************************************************************************/ | |||
| /* | |||
| * Copyright (c) 2017-2018 Arm Limited. All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: Apache-2.0 | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the License); you may | |||
| * not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an AS IS BASIS, WITHOUT | |||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #if defined ( __ICCARM__ ) | |||
| #pragma system_include /* treat file as system include file for MISRA check */ | |||
| #elif defined (__clang__) | |||
| #pragma clang system_header /* treat file as system include file */ | |||
| #endif | |||
| #ifndef TZ_CONTEXT_H | |||
| #define TZ_CONTEXT_H | |||
| #include <stdint.h> | |||
| #ifndef TZ_MODULEID_T | |||
| #define TZ_MODULEID_T | |||
| /// \details Data type that identifies secure software modules called by a process. | |||
| typedef uint32_t TZ_ModuleId_t; | |||
| #endif | |||
| /// \details TZ Memory ID identifies an allocated memory slot. | |||
| typedef uint32_t TZ_MemoryId_t; | |||
| /// Initialize secure context memory system | |||
| /// \return execution status (1: success, 0: error) | |||
| uint32_t TZ_InitContextSystem_S (void); | |||
| /// Allocate context memory for calling secure software modules in TrustZone | |||
| /// \param[in] module identifies software modules called from non-secure mode | |||
| /// \return value != 0 id TrustZone memory slot identifier | |||
| /// \return value 0 no memory available or internal error | |||
| TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); | |||
| /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S | |||
| /// \param[in] id TrustZone memory slot identifier | |||
| /// \return execution status (1: success, 0: error) | |||
| uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); | |||
| /// Load secure context (called on RTOS thread context switch) | |||
| /// \param[in] id TrustZone memory slot identifier | |||
| /// \return execution status (1: success, 0: error) | |||
| uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); | |||
| /// Store secure context (called on RTOS thread context switch) | |||
| /// \param[in] id TrustZone memory slot identifier | |||
| /// \return execution status (1: success, 0: error) | |||
| uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); | |||
| #endif // TZ_CONTEXT_H | |||
| @@ -0,0 +1,494 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_adc16.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.adc16" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Get instance number for ADC16 module. | |||
| * | |||
| * @param base ADC16 peripheral base address | |||
| */ | |||
| static uint32_t ADC16_GetInstance(ADC_Type *base); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Pointers to ADC16 bases for each instance. */ | |||
| static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Pointers to ADC16 clocks for each instance. */ | |||
| static const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| static uint32_t ADC16_GetInstance(ADC_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_adc16Bases); instance++) | |||
| { | |||
| if (s_adc16Bases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_adc16Bases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initializes the ADC16 module. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param config Pointer to configuration structure. See "adc16_config_t". | |||
| */ | |||
| void ADC16_Init(ADC_Type *base, const adc16_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint32_t tmp32; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Enable the clock. */ | |||
| CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /* ADCx_CFG1. */ | |||
| tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution); | |||
| if (kADC16_LongSampleDisabled != config->longSampleMode) | |||
| { | |||
| tmp32 |= ADC_CFG1_ADLSMP_MASK; | |||
| } | |||
| tmp32 |= ADC_CFG1_ADIV(config->clockDivider); | |||
| if (true == config->enableLowPower) | |||
| { | |||
| tmp32 |= ADC_CFG1_ADLPC_MASK; | |||
| } | |||
| base->CFG1 = tmp32; | |||
| /* ADCx_CFG2. */ | |||
| tmp32 = base->CFG2 & ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS_MASK); | |||
| if (kADC16_LongSampleDisabled != config->longSampleMode) | |||
| { | |||
| tmp32 |= ADC_CFG2_ADLSTS(config->longSampleMode); | |||
| } | |||
| if (true == config->enableHighSpeed) | |||
| { | |||
| tmp32 |= ADC_CFG2_ADHSC_MASK; | |||
| } | |||
| if (true == config->enableAsynchronousClock) | |||
| { | |||
| tmp32 |= ADC_CFG2_ADACKEN_MASK; | |||
| } | |||
| base->CFG2 = tmp32; | |||
| /* ADCx_SC2. */ | |||
| tmp32 = base->SC2 & ~(ADC_SC2_REFSEL_MASK); | |||
| tmp32 |= ADC_SC2_REFSEL(config->referenceVoltageSource); | |||
| base->SC2 = tmp32; | |||
| /* ADCx_SC3. */ | |||
| if (true == config->enableContinuousConversion) | |||
| { | |||
| base->SC3 |= ADC_SC3_ADCO_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->SC3 &= ~ADC_SC3_ADCO_MASK; | |||
| } | |||
| } | |||
| /*! | |||
| * brief De-initializes the ADC16 module. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| */ | |||
| void ADC16_Deinit(ADC_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Disable the clock. */ | |||
| CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Gets an available pre-defined settings for the converter's configuration. | |||
| * | |||
| * This function initializes the converter configuration structure with available settings. The default values are as | |||
| * follows. | |||
| * code | |||
| * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; | |||
| * config->clockSource = kADC16_ClockSourceAsynchronousClock; | |||
| * config->enableAsynchronousClock = true; | |||
| * config->clockDivider = kADC16_ClockDivider8; | |||
| * config->resolution = kADC16_ResolutionSE12Bit; | |||
| * config->longSampleMode = kADC16_LongSampleDisabled; | |||
| * config->enableHighSpeed = false; | |||
| * config->enableLowPower = false; | |||
| * config->enableContinuousConversion = false; | |||
| * endcode | |||
| * param config Pointer to the configuration structure. | |||
| */ | |||
| void ADC16_GetDefaultConfig(adc16_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; | |||
| config->clockSource = kADC16_ClockSourceAsynchronousClock; | |||
| config->enableAsynchronousClock = true; | |||
| config->clockDivider = kADC16_ClockDivider8; | |||
| config->resolution = kADC16_ResolutionSE12Bit; | |||
| config->longSampleMode = kADC16_LongSampleDisabled; | |||
| config->enableHighSpeed = false; | |||
| config->enableLowPower = false; | |||
| config->enableContinuousConversion = false; | |||
| } | |||
| #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION | |||
| /*! | |||
| * brief Automates the hardware calibration. | |||
| * | |||
| * This auto calibration helps to adjust the plus/minus side gain automatically. | |||
| * Execute the calibration before using the converter. Note that the hardware trigger should be used | |||
| * during the calibration. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * | |||
| * return Execution status. | |||
| * retval kStatus_Success Calibration is done successfully. | |||
| * retval kStatus_Fail Calibration has failed. | |||
| */ | |||
| status_t ADC16_DoAutoCalibration(ADC_Type *base) | |||
| { | |||
| bool bHWTrigger = false; | |||
| uint32_t tmp32; | |||
| status_t status = kStatus_Success; | |||
| /* The calibration would be failed when in hardwar mode. | |||
| * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/ | |||
| if (0U != (ADC_SC2_ADTRG_MASK & base->SC2)) | |||
| { | |||
| bHWTrigger = true; | |||
| base->SC2 &= ~ADC_SC2_ADTRG_MASK; | |||
| } | |||
| /* Clear the CALF and launch the calibration. */ | |||
| base->SC3 |= ADC_SC3_CAL_MASK | ADC_SC3_CALF_MASK; | |||
| while (0U == ((uint32_t)kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(base, 0U))) | |||
| { | |||
| /* Check the CALF when the calibration is active. */ | |||
| if (0U != ((uint32_t)kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base))) | |||
| { | |||
| status = kStatus_Fail; | |||
| break; | |||
| } | |||
| } | |||
| (void)base->R[0]; /* Dummy read to clear COCO caused by calibration. */ | |||
| /* Restore the hardware trigger setting if it was enabled before. */ | |||
| if (bHWTrigger) | |||
| { | |||
| base->SC2 |= ADC_SC2_ADTRG_MASK; | |||
| } | |||
| /* Check the CALF at the end of calibration. */ | |||
| if (0U != ((uint32_t)kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base))) | |||
| { | |||
| status = kStatus_Fail; | |||
| } | |||
| if (kStatus_Success != status) /* Check if the calibration process is succeed. */ | |||
| { | |||
| return status; | |||
| } | |||
| /* Calculate the calibration values. */ | |||
| tmp32 = base->CLP0; | |||
| tmp32 += base->CLP1; | |||
| tmp32 += base->CLP2; | |||
| tmp32 += base->CLP3; | |||
| tmp32 += base->CLP4; | |||
| tmp32 += base->CLPS; | |||
| tmp32 = 0x8000U | (tmp32 >> 1U); | |||
| base->PG = tmp32; | |||
| #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE | |||
| tmp32 = base->CLM0; | |||
| tmp32 += base->CLM1; | |||
| tmp32 += base->CLM2; | |||
| tmp32 += base->CLM3; | |||
| tmp32 += base->CLM4; | |||
| tmp32 += base->CLMS; | |||
| tmp32 = 0x8000U | (tmp32 >> 1U); | |||
| base->MG = tmp32; | |||
| #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ | |||
| return kStatus_Success; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT | |||
| /*! | |||
| * brief Sets the channel mux mode. | |||
| * | |||
| * Some sample pins share the same channel index. The channel mux mode decides which pin is used for an | |||
| * indicated channel. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param mode Setting channel mux mode. See "adc16_channel_mux_mode_t". | |||
| */ | |||
| void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode) | |||
| { | |||
| if (kADC16_ChannelMuxA == mode) | |||
| { | |||
| base->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; | |||
| } | |||
| else /* kADC16_ChannelMuxB. */ | |||
| { | |||
| base->CFG2 |= ADC_CFG2_MUXSEL_MASK; | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ | |||
| /*! | |||
| * brief Configures the hardware compare mode. | |||
| * | |||
| * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the | |||
| * result | |||
| * in the compare range is available. To compare the range, see "adc16_hardware_compare_mode_t" or the appopriate | |||
| * reference | |||
| * manual for more information. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param config Pointer to the "adc16_hardware_compare_config_t" structure. Passing "NULL" disables the feature. | |||
| */ | |||
| void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config) | |||
| { | |||
| uint32_t tmp32 = base->SC2 & ~(ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK); | |||
| if (NULL == config) /* Pass "NULL" to disable the feature. */ | |||
| { | |||
| base->SC2 = tmp32; | |||
| return; | |||
| } | |||
| /* Enable the feature. */ | |||
| tmp32 |= ADC_SC2_ACFE_MASK; | |||
| /* Select the hardware compare working mode. */ | |||
| switch (config->hardwareCompareMode) | |||
| { | |||
| case kADC16_HardwareCompareMode0: | |||
| break; | |||
| case kADC16_HardwareCompareMode1: | |||
| tmp32 |= ADC_SC2_ACFGT_MASK; | |||
| break; | |||
| case kADC16_HardwareCompareMode2: | |||
| tmp32 |= ADC_SC2_ACREN_MASK; | |||
| break; | |||
| case kADC16_HardwareCompareMode3: | |||
| tmp32 |= ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK; | |||
| break; | |||
| default: | |||
| assert(false); | |||
| break; | |||
| } | |||
| base->SC2 = tmp32; | |||
| /* Load the compare values. */ | |||
| base->CV1 = ADC_CV1_CV(config->value1); | |||
| base->CV2 = ADC_CV2_CV(config->value2); | |||
| } | |||
| #if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE | |||
| /*! | |||
| * brief Sets the hardware average mode. | |||
| * | |||
| * The hardware average mode provides a way to process the conversion result automatically by using hardware. The | |||
| * multiple | |||
| * conversion results are accumulated and averaged internally making them easier to read. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param mode Setting the hardware average mode. See "adc16_hardware_average_mode_t". | |||
| */ | |||
| void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode) | |||
| { | |||
| uint32_t tmp32 = base->SC3 & ~(ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK); | |||
| if (kADC16_HardwareAverageDisabled != mode) | |||
| { | |||
| tmp32 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(mode); | |||
| } | |||
| base->SC3 = tmp32; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA | |||
| /*! | |||
| * brief Configures the PGA for the converter's front end. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param config Pointer to the "adc16_pga_config_t" structure. Passing "NULL" disables the feature. | |||
| */ | |||
| void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config) | |||
| { | |||
| uint32_t tmp32; | |||
| if (!config) /* Passing "NULL" is to disable the feature. */ | |||
| { | |||
| base->PGA = 0U; | |||
| return; | |||
| } | |||
| /* Enable the PGA and set the gain value. */ | |||
| tmp32 = ADC_PGA_PGAEN_MASK | ADC_PGA_PGAG(config->pgaGain); | |||
| /* Configure the misc features for PGA. */ | |||
| if (config->enableRunInNormalMode) | |||
| { | |||
| tmp32 |= ADC_PGA_PGALPb_MASK; | |||
| } | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING | |||
| if (config->disablePgaChopping) | |||
| { | |||
| tmp32 |= ADC_PGA_PGACHPb_MASK; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT | |||
| if (config->enableRunInOffsetMeasurement) | |||
| { | |||
| tmp32 |= ADC_PGA_PGAOFSM_MASK; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */ | |||
| base->PGA = tmp32; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA */ | |||
| /*! | |||
| * brief Gets the status flags of the converter. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * | |||
| * return Flags' mask if indicated flags are asserted. See "_adc16_status_flags". | |||
| */ | |||
| uint32_t ADC16_GetStatusFlags(ADC_Type *base) | |||
| { | |||
| uint32_t ret = 0; | |||
| if (0U != (base->SC2 & ADC_SC2_ADACT_MASK)) | |||
| { | |||
| ret |= (uint32_t)kADC16_ActiveFlag; | |||
| } | |||
| #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION | |||
| if (0U != (base->SC3 & ADC_SC3_CALF_MASK)) | |||
| { | |||
| ret |= (uint32_t)kADC16_CalibrationFailedFlag; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ | |||
| return ret; | |||
| } | |||
| /*! | |||
| * brief Clears the status flags of the converter. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param mask Mask value for the cleared flags. See "_adc16_status_flags". | |||
| */ | |||
| void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask) | |||
| { | |||
| #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION | |||
| if (0U != (mask & (uint32_t)kADC16_CalibrationFailedFlag)) | |||
| { | |||
| base->SC3 |= ADC_SC3_CALF_MASK; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ | |||
| } | |||
| /*! | |||
| * brief Configures the conversion channel. | |||
| * | |||
| * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API | |||
| * configures the channel while the external trigger source helps to trigger the conversion. | |||
| * | |||
| * Note that the "Channel Group" has a detailed description. | |||
| * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one | |||
| * group of status and control registers, one for each conversion. The channel group parameter indicates which group of | |||
| * registers are used, for example, channel group 0 is for Group A registers and channel group 1 is for Group B | |||
| * registers. The | |||
| * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of | |||
| * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and | |||
| * hardware | |||
| * trigger modes. Channel group 1 and greater indicates multiple channel group registers for | |||
| * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual for | |||
| * the | |||
| * number of SC1n registers (channel groups) specific to this device. Channel group 1 or greater are not used | |||
| * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion. | |||
| * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and | |||
| * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a | |||
| * conversion aborts the current conversion. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param channelGroup Channel group index. | |||
| * param config Pointer to the "adc16_channel_config_t" structure for the conversion channel. | |||
| */ | |||
| void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config) | |||
| { | |||
| assert(channelGroup < ADC_SC1_COUNT); | |||
| assert(NULL != config); | |||
| uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE | |||
| /* Enable the differential conversion. */ | |||
| if (true == config->enableDifferentialConversion) | |||
| { | |||
| sc1 |= ADC_SC1_DIFF_MASK; | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ | |||
| /* Enable the interrupt when the conversion is done. */ | |||
| if (true == config->enableInterruptOnConversionCompleted) | |||
| { | |||
| sc1 |= ADC_SC1_AIEN_MASK; | |||
| } | |||
| base->SC1[channelGroup] = sc1; | |||
| } | |||
| /*! | |||
| * brief Gets the status flags of channel. | |||
| * | |||
| * param base ADC16 peripheral base address. | |||
| * param channelGroup Channel group index. | |||
| * | |||
| * return Flags' mask if indicated flags are asserted. See "_adc16_channel_status_flags". | |||
| */ | |||
| uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup) | |||
| { | |||
| assert(channelGroup < ADC_SC1_COUNT); | |||
| uint32_t ret = 0U; | |||
| if (0U != (base->SC1[channelGroup] & ADC_SC1_COCO_MASK)) | |||
| { | |||
| ret |= (uint32_t)kADC16_ChannelConversionDoneFlag; | |||
| } | |||
| return ret; | |||
| } | |||
| @@ -0,0 +1,512 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_ADC16_H_ | |||
| #define _FSL_ADC16_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup adc16 | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief ADC16 driver version 2.1.0. */ | |||
| #define FSL_ADC16_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Channel status flags. | |||
| */ | |||
| enum _adc16_channel_status_flags | |||
| { | |||
| kADC16_ChannelConversionDoneFlag = ADC_SC1_COCO_MASK, /*!< Conversion done. */ | |||
| }; | |||
| /*! | |||
| * @brief Converter status flags. | |||
| */ | |||
| enum _adc16_status_flags | |||
| { | |||
| kADC16_ActiveFlag = ADC_SC2_ADACT_MASK, /*!< Converter is active. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION | |||
| kADC16_CalibrationFailedFlag = ADC_SC3_CALF_MASK, /*!< Calibration is failed. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ | |||
| }; | |||
| #if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT | |||
| /*! | |||
| * @brief Channel multiplexer mode for each channel. | |||
| * | |||
| * For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b | |||
| * are the different channels that share the same channel number. | |||
| */ | |||
| typedef enum _adc_channel_mux_mode | |||
| { | |||
| kADC16_ChannelMuxA = 0U, /*!< For channel with channel mux a. */ | |||
| kADC16_ChannelMuxB = 1U, /*!< For channel with channel mux b. */ | |||
| } adc16_channel_mux_mode_t; | |||
| #endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ | |||
| /*! | |||
| * @brief Clock divider for the converter. | |||
| */ | |||
| typedef enum _adc16_clock_divider | |||
| { | |||
| kADC16_ClockDivider1 = 0U, /*!< For divider 1 from the input clock to the module. */ | |||
| kADC16_ClockDivider2 = 1U, /*!< For divider 2 from the input clock to the module. */ | |||
| kADC16_ClockDivider4 = 2U, /*!< For divider 4 from the input clock to the module. */ | |||
| kADC16_ClockDivider8 = 3U, /*!< For divider 8 from the input clock to the module. */ | |||
| } adc16_clock_divider_t; | |||
| /*! | |||
| *@brief Converter's resolution. | |||
| */ | |||
| typedef enum _adc16_resolution | |||
| { | |||
| /* This group of enumeration is for internal use which is related to register setting. */ | |||
| kADC16_Resolution8or9Bit = 0U, /*!< Single End 8-bit or Differential Sample 9-bit. */ | |||
| kADC16_Resolution12or13Bit = 1U, /*!< Single End 12-bit or Differential Sample 13-bit. */ | |||
| kADC16_Resolution10or11Bit = 2U, /*!< Single End 10-bit or Differential Sample 11-bit. */ | |||
| /* This group of enumeration is for a public user. */ | |||
| kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */ | |||
| kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */ | |||
| kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE | |||
| kADC16_ResolutionDF9Bit = kADC16_Resolution8or9Bit, /*!< Differential Sample 9-bit. */ | |||
| kADC16_ResolutionDF13Bit = kADC16_Resolution12or13Bit, /*!< Differential Sample 13-bit. */ | |||
| kADC16_ResolutionDF11Bit = kADC16_Resolution10or11Bit, /*!< Differential Sample 11-bit. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ | |||
| #if defined(FSL_FEATURE_ADC16_MAX_RESOLUTION) && (FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U) | |||
| /* 16-bit is supported by default. */ | |||
| kADC16_Resolution16Bit = 3U, /*!< Single End 16-bit or Differential Sample 16-bit. */ | |||
| kADC16_ResolutionSE16Bit = kADC16_Resolution16Bit, /*!< Single End 16-bit. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE | |||
| kADC16_ResolutionDF16Bit = kADC16_Resolution16Bit, /*!< Differential Sample 16-bit. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ | |||
| #endif /* FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U */ | |||
| } adc16_resolution_t; | |||
| /*! | |||
| * @brief Clock source. | |||
| */ | |||
| typedef enum _adc16_clock_source | |||
| { | |||
| kADC16_ClockSourceAlt0 = 0U, /*!< Selection 0 of the clock source. */ | |||
| kADC16_ClockSourceAlt1 = 1U, /*!< Selection 1 of the clock source. */ | |||
| kADC16_ClockSourceAlt2 = 2U, /*!< Selection 2 of the clock source. */ | |||
| kADC16_ClockSourceAlt3 = 3U, /*!< Selection 3 of the clock source. */ | |||
| /* Chip defined clock source */ | |||
| kADC16_ClockSourceAsynchronousClock = kADC16_ClockSourceAlt3, /*!< Using internal asynchronous clock. */ | |||
| } adc16_clock_source_t; | |||
| /*! | |||
| * @brief Long sample mode. | |||
| */ | |||
| typedef enum _adc16_long_sample_mode | |||
| { | |||
| kADC16_LongSampleCycle24 = 0U, /*!< 20 extra ADCK cycles, 24 ADCK cycles total. */ | |||
| kADC16_LongSampleCycle16 = 1U, /*!< 12 extra ADCK cycles, 16 ADCK cycles total. */ | |||
| kADC16_LongSampleCycle10 = 2U, /*!< 6 extra ADCK cycles, 10 ADCK cycles total. */ | |||
| kADC16_LongSampleCycle6 = 3U, /*!< 2 extra ADCK cycles, 6 ADCK cycles total. */ | |||
| kADC16_LongSampleDisabled = 4U, /*!< Disable the long sample feature. */ | |||
| } adc16_long_sample_mode_t; | |||
| /*! | |||
| * @brief Reference voltage source. | |||
| */ | |||
| typedef enum _adc16_reference_voltage_source | |||
| { | |||
| kADC16_ReferenceVoltageSourceVref = 0U, /*!< For external pins pair of VrefH and VrefL. */ | |||
| kADC16_ReferenceVoltageSourceValt = 1U, /*!< For alternate reference pair of ValtH and ValtL. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_VREF_BANDGAP) && FSL_FEATURE_ADC16_HAS_VREF_BANDGAP | |||
| kADC16_ReferenceVoltageSourceBandgap = 2U, /*!< For bandgap voltage from PMC. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_VREF_BANDGAP */ | |||
| } adc16_reference_voltage_source_t; | |||
| #if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE | |||
| /*! | |||
| * @brief Hardware average mode. | |||
| */ | |||
| typedef enum _adc16_hardware_average_mode | |||
| { | |||
| kADC16_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */ | |||
| kADC16_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */ | |||
| kADC16_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */ | |||
| kADC16_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */ | |||
| kADC16_HardwareAverageDisabled = 4U, /*!< Disable the hardware average feature.*/ | |||
| } adc16_hardware_average_mode_t; | |||
| #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ | |||
| /*! | |||
| * @brief Hardware compare mode. | |||
| */ | |||
| typedef enum _adc16_hardware_compare_mode | |||
| { | |||
| kADC16_HardwareCompareMode0 = 0U, /*!< x < value1. */ | |||
| kADC16_HardwareCompareMode1 = 1U, /*!< x > value1. */ | |||
| kADC16_HardwareCompareMode2 = 2U, /*!< if value1 <= value2, then x < value1 || x > value2; | |||
| else, value1 > x > value2. */ | |||
| kADC16_HardwareCompareMode3 = 3U, /*!< if value1 <= value2, then value1 <= x <= value2; | |||
| else x >= value1 || x <= value2. */ | |||
| } adc16_hardware_compare_mode_t; | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA | |||
| /*! | |||
| * @brief PGA's Gain mode. | |||
| */ | |||
| typedef enum _adc16_pga_gain | |||
| { | |||
| kADC16_PGAGainValueOf1 = 0U, /*!< For amplifier gain of 1. */ | |||
| kADC16_PGAGainValueOf2 = 1U, /*!< For amplifier gain of 2. */ | |||
| kADC16_PGAGainValueOf4 = 2U, /*!< For amplifier gain of 4. */ | |||
| kADC16_PGAGainValueOf8 = 3U, /*!< For amplifier gain of 8. */ | |||
| kADC16_PGAGainValueOf16 = 4U, /*!< For amplifier gain of 16. */ | |||
| kADC16_PGAGainValueOf32 = 5U, /*!< For amplifier gain of 32. */ | |||
| kADC16_PGAGainValueOf64 = 6U, /*!< For amplifier gain of 64. */ | |||
| } adc16_pga_gain_t; | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA */ | |||
| /*! | |||
| * @brief ADC16 converter configuration. | |||
| */ | |||
| typedef struct _adc16_config | |||
| { | |||
| adc16_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */ | |||
| adc16_clock_source_t clockSource; /*!< Select the input clock source to converter. */ | |||
| bool enableAsynchronousClock; /*!< Enable the asynchronous clock output. */ | |||
| adc16_clock_divider_t clockDivider; /*!< Select the divider of input clock source. */ | |||
| adc16_resolution_t resolution; /*!< Select the sample resolution mode. */ | |||
| adc16_long_sample_mode_t longSampleMode; /*!< Select the long sample mode. */ | |||
| bool enableHighSpeed; /*!< Enable the high-speed mode. */ | |||
| bool enableLowPower; /*!< Enable low power. */ | |||
| bool enableContinuousConversion; /*!< Enable continuous conversion mode. */ | |||
| } adc16_config_t; | |||
| /*! | |||
| * @brief ADC16 Hardware comparison configuration. | |||
| */ | |||
| typedef struct _adc16_hardware_compare_config | |||
| { | |||
| adc16_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode. | |||
| See "adc16_hardware_compare_mode_t". */ | |||
| int16_t value1; /*!< Setting value1 for hardware compare mode. */ | |||
| int16_t value2; /*!< Setting value2 for hardware compare mode. */ | |||
| } adc16_hardware_compare_config_t; | |||
| /*! | |||
| * @brief ADC16 channel conversion configuration. | |||
| */ | |||
| typedef struct _adc16_channel_config | |||
| { | |||
| uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31. | |||
| See channel connection information for each chip in Reference | |||
| Manual document. */ | |||
| bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE | |||
| bool enableDifferentialConversion; /*!< Using Differential sample mode. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ | |||
| } adc16_channel_config_t; | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA | |||
| /*! | |||
| * @brief ADC16 programmable gain amplifier configuration. | |||
| */ | |||
| typedef struct _adc16_pga_config | |||
| { | |||
| adc16_pga_gain_t pgaGain; /*!< Setting PGA gain. */ | |||
| bool enableRunInNormalMode; /*!< Enable PGA working in normal mode, or low power mode by default. */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING | |||
| bool disablePgaChopping; /*!< Disable the PGA chopping function. | |||
| The PGA employs chopping to remove/reduce offset and 1/f noise and offers | |||
| an offset measurement configuration that aids the offset calibration. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT | |||
| bool enableRunInOffsetMeasurement; /*!< Enable the PGA working in offset measurement mode. | |||
| When this feature is enabled, the PGA disconnects itself from the external | |||
| inputs and auto-configures into offset measurement mode. With this field | |||
| set, run the ADC in the recommended settings and enable the maximum hardware | |||
| averaging to get the PGA offset number. The output is the | |||
| (PGA offset * (64+1)) for the given PGA setting. */ | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */ | |||
| } adc16_pga_config_t; | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA */ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the ADC16 module. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param config Pointer to configuration structure. See "adc16_config_t". | |||
| */ | |||
| void ADC16_Init(ADC_Type *base, const adc16_config_t *config); | |||
| /*! | |||
| * @brief De-initializes the ADC16 module. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| */ | |||
| void ADC16_Deinit(ADC_Type *base); | |||
| /*! | |||
| * @brief Gets an available pre-defined settings for the converter's configuration. | |||
| * | |||
| * This function initializes the converter configuration structure with available settings. The default values are as | |||
| * follows. | |||
| * @code | |||
| * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; | |||
| * config->clockSource = kADC16_ClockSourceAsynchronousClock; | |||
| * config->enableAsynchronousClock = true; | |||
| * config->clockDivider = kADC16_ClockDivider8; | |||
| * config->resolution = kADC16_ResolutionSE12Bit; | |||
| * config->longSampleMode = kADC16_LongSampleDisabled; | |||
| * config->enableHighSpeed = false; | |||
| * config->enableLowPower = false; | |||
| * config->enableContinuousConversion = false; | |||
| * @endcode | |||
| * @param config Pointer to the configuration structure. | |||
| */ | |||
| void ADC16_GetDefaultConfig(adc16_config_t *config); | |||
| #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION | |||
| /*! | |||
| * @brief Automates the hardware calibration. | |||
| * | |||
| * This auto calibration helps to adjust the plus/minus side gain automatically. | |||
| * Execute the calibration before using the converter. Note that the hardware trigger should be used | |||
| * during the calibration. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * | |||
| * @return Execution status. | |||
| * @retval kStatus_Success Calibration is done successfully. | |||
| * @retval kStatus_Fail Calibration has failed. | |||
| */ | |||
| status_t ADC16_DoAutoCalibration(ADC_Type *base); | |||
| #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION) && FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION | |||
| /*! | |||
| * @brief Sets the offset value for the conversion result. | |||
| * | |||
| * This offset value takes effect on the conversion result. If the offset value is not zero, the reading result | |||
| * is subtracted by it. Note, the hardware calibration fills the offset value automatically. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param value Setting offset value. | |||
| */ | |||
| static inline void ADC16_SetOffsetValue(ADC_Type *base, int16_t value) | |||
| { | |||
| base->OFS = (uint32_t)(value); | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION */ | |||
| /* @} */ | |||
| /*! | |||
| * @name Advanced Features | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA | |||
| /*! | |||
| * @brief Enables generating the DMA trigger when the conversion is complete. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled. | |||
| */ | |||
| static inline void ADC16_EnableDMA(ADC_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->SC2 |= ADC_SC2_DMAEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->SC2 &= ~ADC_SC2_DMAEN_MASK; | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_ADC16_HAS_DMA */ | |||
| /*! | |||
| * @brief Enables the hardware trigger mode. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param enable Switcher of the hardware trigger feature. "true" means enabled, "false" means not enabled. | |||
| */ | |||
| static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->SC2 |= ADC_SC2_ADTRG_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->SC2 &= ~ADC_SC2_ADTRG_MASK; | |||
| } | |||
| } | |||
| #if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT | |||
| /*! | |||
| * @brief Sets the channel mux mode. | |||
| * | |||
| * Some sample pins share the same channel index. The channel mux mode decides which pin is used for an | |||
| * indicated channel. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param mode Setting channel mux mode. See "adc16_channel_mux_mode_t". | |||
| */ | |||
| void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode); | |||
| #endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */ | |||
| /*! | |||
| * @brief Configures the hardware compare mode. | |||
| * | |||
| * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the | |||
| * result | |||
| * in the compare range is available. To compare the range, see "adc16_hardware_compare_mode_t" or the appopriate | |||
| * reference | |||
| * manual for more information. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param config Pointer to the "adc16_hardware_compare_config_t" structure. Passing "NULL" disables the feature. | |||
| */ | |||
| void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config); | |||
| #if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE | |||
| /*! | |||
| * @brief Sets the hardware average mode. | |||
| * | |||
| * The hardware average mode provides a way to process the conversion result automatically by using hardware. The | |||
| * multiple | |||
| * conversion results are accumulated and averaged internally making them easier to read. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param mode Setting the hardware average mode. See "adc16_hardware_average_mode_t". | |||
| */ | |||
| void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode); | |||
| #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ | |||
| #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA | |||
| /*! | |||
| * @brief Configures the PGA for the converter's front end. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param config Pointer to the "adc16_pga_config_t" structure. Passing "NULL" disables the feature. | |||
| */ | |||
| void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config); | |||
| #endif /* FSL_FEATURE_ADC16_HAS_PGA */ | |||
| /*! | |||
| * @brief Gets the status flags of the converter. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * | |||
| * @return Flags' mask if indicated flags are asserted. See "_adc16_status_flags". | |||
| */ | |||
| uint32_t ADC16_GetStatusFlags(ADC_Type *base); | |||
| /*! | |||
| * @brief Clears the status flags of the converter. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param mask Mask value for the cleared flags. See "_adc16_status_flags". | |||
| */ | |||
| void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask); | |||
| /* @} */ | |||
| /*! | |||
| * @name Conversion Channel | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Configures the conversion channel. | |||
| * | |||
| * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API | |||
| * configures the channel while the external trigger source helps to trigger the conversion. | |||
| * | |||
| * Note that the "Channel Group" has a detailed description. | |||
| * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one | |||
| * group of status and control registers, one for each conversion. The channel group parameter indicates which group of | |||
| * registers are used, for example, channel group 0 is for Group A registers and channel group 1 is for Group B | |||
| * registers. The | |||
| * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of | |||
| * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and | |||
| * hardware | |||
| * trigger modes. Channel group 1 and greater indicates multiple channel group registers for | |||
| * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual for | |||
| * the | |||
| * number of SC1n registers (channel groups) specific to this device. Channel group 1 or greater are not used | |||
| * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion. | |||
| * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and | |||
| * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a | |||
| * conversion aborts the current conversion. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param channelGroup Channel group index. | |||
| * @param config Pointer to the "adc16_channel_config_t" structure for the conversion channel. | |||
| */ | |||
| void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config); | |||
| /*! | |||
| * @brief Gets the conversion value. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param channelGroup Channel group index. | |||
| * | |||
| * @return Conversion value. | |||
| */ | |||
| static inline uint32_t ADC16_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup) | |||
| { | |||
| assert(channelGroup < (uint32_t)FSL_FEATURE_ADC16_CONVERSION_CONTROL_COUNT); | |||
| return base->R[channelGroup]; | |||
| } | |||
| /*! | |||
| * @brief Gets the status flags of channel. | |||
| * | |||
| * @param base ADC16 peripheral base address. | |||
| * @param channelGroup Channel group index. | |||
| * | |||
| * @return Flags' mask if indicated flags are asserted. See "_adc16_channel_status_flags". | |||
| */ | |||
| uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup); | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| * @} | |||
| */ | |||
| #endif /* _FSL_ADC16_H_ */ | |||
| @@ -0,0 +1,214 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_aoi.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.aoi" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Pointers to aoi bases for each instance. */ | |||
| static AOI_Type *const s_aoiBases[] = AOI_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Pointers to aoi clocks for each instance. */ | |||
| static const clock_ip_name_t s_aoiClocks[] = AOI_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Get instance number for AOI module. | |||
| * | |||
| * @param base AOI peripheral base address | |||
| * | |||
| * @return The AOI instance | |||
| */ | |||
| static uint32_t AOI_GetInstance(AOI_Type *base); | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| static uint32_t AOI_GetInstance(AOI_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_aoiBases); instance++) | |||
| { | |||
| if (s_aoiBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_aoiBases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initializes an AOI instance for operation. | |||
| * | |||
| * This function un-gates the AOI clock. | |||
| * | |||
| * param base AOI peripheral address. | |||
| */ | |||
| void AOI_Init(AOI_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Enable the clock gate from clock manager. */ | |||
| CLOCK_EnableClock(s_aoiClocks[AOI_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Deinitializes an AOI instance for operation. | |||
| * | |||
| * This function shutdowns AOI module. | |||
| * | |||
| * param base AOI peripheral address. | |||
| */ | |||
| void AOI_Deinit(AOI_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Disable the clock gate from clock manager */ | |||
| CLOCK_DisableClock(s_aoiClocks[AOI_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Gets the Boolean evaluation associated. | |||
| * | |||
| * This function returns the Boolean evaluation associated. | |||
| * | |||
| * Example: | |||
| code | |||
| aoi_event_config_t demoEventLogicStruct; | |||
| AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct); | |||
| endcode | |||
| * | |||
| * param base AOI peripheral address. | |||
| * param event Index of the event which will be set of type aoi_event_t. | |||
| * param config Selected input configuration . | |||
| */ | |||
| void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config) | |||
| { | |||
| assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT); | |||
| assert(config != NULL); | |||
| uint16_t value; | |||
| uint16_t temp; | |||
| /* Read BFCRT01 register at event index. */ | |||
| value = base->BFCRT[event].BFCRT01; | |||
| temp = (value & AOI_BFCRT01_PT0_AC_MASK) >> AOI_BFCRT01_PT0_AC_SHIFT; | |||
| config->PT0AC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT0_BC_MASK) >> AOI_BFCRT01_PT0_BC_SHIFT; | |||
| config->PT0BC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT0_CC_MASK) >> AOI_BFCRT01_PT0_CC_SHIFT; | |||
| config->PT0CC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT0_DC_MASK) >> AOI_BFCRT01_PT0_DC_SHIFT; | |||
| config->PT0DC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT1_AC_MASK) >> AOI_BFCRT01_PT1_AC_SHIFT; | |||
| config->PT1AC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT1_BC_MASK) >> AOI_BFCRT01_PT1_BC_SHIFT; | |||
| config->PT1BC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT1_CC_MASK) >> AOI_BFCRT01_PT1_CC_SHIFT; | |||
| config->PT1CC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT01_PT1_DC_MASK) >> AOI_BFCRT01_PT1_DC_SHIFT; | |||
| config->PT1DC = (aoi_input_config_t)temp; | |||
| /* Read BFCRT23 register at event index. */ | |||
| value = base->BFCRT[event].BFCRT23; | |||
| temp = (value & AOI_BFCRT23_PT2_AC_MASK) >> AOI_BFCRT23_PT2_AC_SHIFT; | |||
| config->PT2AC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT2_BC_MASK) >> AOI_BFCRT23_PT2_BC_SHIFT; | |||
| config->PT2BC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT2_CC_MASK) >> AOI_BFCRT23_PT2_CC_SHIFT; | |||
| config->PT2CC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT2_DC_MASK) >> AOI_BFCRT23_PT2_DC_SHIFT; | |||
| config->PT2DC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT3_AC_MASK) >> AOI_BFCRT23_PT3_AC_SHIFT; | |||
| config->PT3AC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT3_BC_MASK) >> AOI_BFCRT23_PT3_BC_SHIFT; | |||
| config->PT3BC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT3_CC_MASK) >> AOI_BFCRT23_PT3_CC_SHIFT; | |||
| config->PT3CC = (aoi_input_config_t)temp; | |||
| temp = (value & AOI_BFCRT23_PT3_DC_MASK) >> AOI_BFCRT23_PT3_DC_SHIFT; | |||
| config->PT3DC = (aoi_input_config_t)temp; | |||
| } | |||
| /*! | |||
| * brief Configures an AOI event. | |||
| * | |||
| * This function configures an AOI event according | |||
| * to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D) | |||
| * of all product terms (0, 1, 2, and 3) of a desired event. | |||
| * | |||
| * Example: | |||
| code | |||
| aoi_event_config_t demoEventLogicStruct; | |||
| demoEventLogicStruct.PT0AC = kAOI_InvInputSignal; | |||
| demoEventLogicStruct.PT0BC = kAOI_InputSignal; | |||
| demoEventLogicStruct.PT0CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT0DC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT1AC = kAOI_LogicZero; | |||
| demoEventLogicStruct.PT1BC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT1CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT1DC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT2AC = kAOI_LogicZero; | |||
| demoEventLogicStruct.PT2BC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT2CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT2DC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT3AC = kAOI_LogicZero; | |||
| demoEventLogicStruct.PT3BC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT3CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT3DC = kAOI_LogicOne; | |||
| AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct); | |||
| endcode | |||
| * | |||
| * param base AOI peripheral address. | |||
| * param event Event which will be configured of type aoi_event_t. | |||
| * param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for | |||
| * filling out the members of this structure and passing the pointer to this function. | |||
| */ | |||
| void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig) | |||
| { | |||
| assert(eventConfig != NULL); | |||
| assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT); | |||
| uint16_t value; | |||
| /* Calculate value to configure product term 0, 1 */ | |||
| value = AOI_BFCRT01_PT0_AC(eventConfig->PT0AC) | AOI_BFCRT01_PT0_BC(eventConfig->PT0BC) | | |||
| AOI_BFCRT01_PT0_CC(eventConfig->PT0CC) | AOI_BFCRT01_PT0_DC(eventConfig->PT0DC) | | |||
| AOI_BFCRT01_PT1_AC(eventConfig->PT1AC) | AOI_BFCRT01_PT1_BC(eventConfig->PT1BC) | | |||
| AOI_BFCRT01_PT1_CC(eventConfig->PT1CC) | AOI_BFCRT01_PT1_DC(eventConfig->PT1DC); | |||
| /* Write value to register */ | |||
| base->BFCRT[event].BFCRT01 = value; | |||
| /* Reset and calculate value to configure product term 2, 3 */ | |||
| value = AOI_BFCRT23_PT2_AC(eventConfig->PT2AC) | AOI_BFCRT23_PT2_BC(eventConfig->PT2BC) | | |||
| AOI_BFCRT23_PT2_CC(eventConfig->PT2CC) | AOI_BFCRT23_PT2_DC(eventConfig->PT2DC) | | |||
| AOI_BFCRT23_PT3_AC(eventConfig->PT3AC) | AOI_BFCRT23_PT3_BC(eventConfig->PT3BC) | | |||
| AOI_BFCRT23_PT3_CC(eventConfig->PT3CC) | AOI_BFCRT23_PT3_DC(eventConfig->PT3DC); | |||
| /* Write value to register */ | |||
| base->BFCRT[event].BFCRT23 = value; | |||
| } | |||
| @@ -0,0 +1,186 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_AOI_H_ | |||
| #define _FSL_AOI_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup aoi | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| #ifndef AOI | |||
| #define AOI AOI0 /*!< AOI peripheral address */ | |||
| #endif | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| #define FSL_AOI_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */ | |||
| /*@}*/ | |||
| /*! | |||
| * @brief AOI input configurations. | |||
| * | |||
| * The selection item represents the Boolean evaluations. | |||
| */ | |||
| typedef enum _aoi_input_config | |||
| { | |||
| kAOI_LogicZero = 0x0U, /*!< Forces the input to logical zero. */ | |||
| kAOI_InputSignal = 0x1U, /*!< Passes the input signal. */ | |||
| kAOI_InvInputSignal = 0x2U, /*!< Inverts the input signal. */ | |||
| kAOI_LogicOne = 0x3U /*!< Forces the input to logical one. */ | |||
| } aoi_input_config_t; | |||
| /*! | |||
| * @brief AOI event indexes, where an event is the collection of the four product | |||
| * terms (0, 1, 2, and 3) and the four signal inputs (A, B, C, and D). | |||
| */ | |||
| typedef enum _aoi_event | |||
| { | |||
| kAOI_Event0 = 0x0U, /*!< Event 0 index */ | |||
| kAOI_Event1 = 0x1U, /*!< Event 1 index */ | |||
| kAOI_Event2 = 0x2U, /*!< Event 2 index */ | |||
| kAOI_Event3 = 0x3U /*!< Event 3 index */ | |||
| } aoi_event_t; | |||
| /*! | |||
| * @brief AOI event configuration structure | |||
| * | |||
| * Defines structure _aoi_event_config and use the AOI_SetEventLogicConfig() function to make | |||
| * whole event configuration. | |||
| */ | |||
| typedef struct _aoi_event_config | |||
| { | |||
| aoi_input_config_t PT0AC; /*!< Product term 0 input A */ | |||
| aoi_input_config_t PT0BC; /*!< Product term 0 input B */ | |||
| aoi_input_config_t PT0CC; /*!< Product term 0 input C */ | |||
| aoi_input_config_t PT0DC; /*!< Product term 0 input D */ | |||
| aoi_input_config_t PT1AC; /*!< Product term 1 input A */ | |||
| aoi_input_config_t PT1BC; /*!< Product term 1 input B */ | |||
| aoi_input_config_t PT1CC; /*!< Product term 1 input C */ | |||
| aoi_input_config_t PT1DC; /*!< Product term 1 input D */ | |||
| aoi_input_config_t PT2AC; /*!< Product term 2 input A */ | |||
| aoi_input_config_t PT2BC; /*!< Product term 2 input B */ | |||
| aoi_input_config_t PT2CC; /*!< Product term 2 input C */ | |||
| aoi_input_config_t PT2DC; /*!< Product term 2 input D */ | |||
| aoi_input_config_t PT3AC; /*!< Product term 3 input A */ | |||
| aoi_input_config_t PT3BC; /*!< Product term 3 input B */ | |||
| aoi_input_config_t PT3CC; /*!< Product term 3 input C */ | |||
| aoi_input_config_t PT3DC; /*!< Product term 3 input D */ | |||
| } aoi_event_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /* __cplusplus*/ | |||
| /*! | |||
| * @name AOI Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes an AOI instance for operation. | |||
| * | |||
| * This function un-gates the AOI clock. | |||
| * | |||
| * @param base AOI peripheral address. | |||
| */ | |||
| void AOI_Init(AOI_Type *base); | |||
| /*! | |||
| * @brief Deinitializes an AOI instance for operation. | |||
| * | |||
| * This function shutdowns AOI module. | |||
| * | |||
| * @param base AOI peripheral address. | |||
| */ | |||
| void AOI_Deinit(AOI_Type *base); | |||
| /*@}*/ | |||
| /*! | |||
| * @name AOI Get Set Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Gets the Boolean evaluation associated. | |||
| * | |||
| * This function returns the Boolean evaluation associated. | |||
| * | |||
| * Example: | |||
| @code | |||
| aoi_event_config_t demoEventLogicStruct; | |||
| AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct); | |||
| @endcode | |||
| * | |||
| * @param base AOI peripheral address. | |||
| * @param event Index of the event which will be set of type aoi_event_t. | |||
| * @param config Selected input configuration . | |||
| */ | |||
| void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config); | |||
| /*! | |||
| * @brief Configures an AOI event. | |||
| * | |||
| * This function configures an AOI event according | |||
| * to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D) | |||
| * of all product terms (0, 1, 2, and 3) of a desired event. | |||
| * | |||
| * Example: | |||
| @code | |||
| aoi_event_config_t demoEventLogicStruct; | |||
| demoEventLogicStruct.PT0AC = kAOI_InvInputSignal; | |||
| demoEventLogicStruct.PT0BC = kAOI_InputSignal; | |||
| demoEventLogicStruct.PT0CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT0DC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT1AC = kAOI_LogicZero; | |||
| demoEventLogicStruct.PT1BC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT1CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT1DC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT2AC = kAOI_LogicZero; | |||
| demoEventLogicStruct.PT2BC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT2CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT2DC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT3AC = kAOI_LogicZero; | |||
| demoEventLogicStruct.PT3BC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT3CC = kAOI_LogicOne; | |||
| demoEventLogicStruct.PT3DC = kAOI_LogicOne; | |||
| AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct); | |||
| @endcode | |||
| * | |||
| * @param base AOI peripheral address. | |||
| * @param event Event which will be configured of type aoi_event_t. | |||
| * @param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for | |||
| * filling out the members of this structure and passing the pointer to this function. | |||
| */ | |||
| void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig); | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /* __cplusplus*/ | |||
| /*@}*/ | |||
| /*!* @} */ | |||
| #endif /* _FSL_AOI_H_*/ | |||
| @@ -0,0 +1,371 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_cmp.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.cmp" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Get instance number for CMP module. | |||
| * | |||
| * @param base CMP peripheral base address | |||
| */ | |||
| static uint32_t CMP_GetInstance(CMP_Type *base); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Pointers to CMP bases for each instance. */ | |||
| static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Pointers to CMP clocks for each instance. */ | |||
| static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Codes | |||
| ******************************************************************************/ | |||
| static uint32_t CMP_GetInstance(CMP_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++) | |||
| { | |||
| if (s_cmpBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_cmpBases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initializes the CMP. | |||
| * | |||
| * This function initializes the CMP module. The operations included are as follows. | |||
| * - Enabling the clock for CMP module. | |||
| * - Configuring the comparator. | |||
| * - Enabling the CMP module. | |||
| * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for | |||
| * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param config Pointer to the configuration structure. | |||
| */ | |||
| void CMP_Init(CMP_Type *base, const cmp_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint8_t tmp8; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Enable the clock. */ | |||
| CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /* Configure. */ | |||
| CMP_Enable(base, false); /* Disable the CMP module during configuring. */ | |||
| /* CMPx_CR1. */ | |||
| tmp8 = (uint8_t)(base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK)); | |||
| if (true == config->enableHighSpeed) | |||
| { | |||
| tmp8 |= CMP_CR1_PMODE_MASK; | |||
| } | |||
| if (true == config->enableInvertOutput) | |||
| { | |||
| tmp8 |= CMP_CR1_INV_MASK; | |||
| } | |||
| if (true == config->useUnfilteredOutput) | |||
| { | |||
| tmp8 |= CMP_CR1_COS_MASK; | |||
| } | |||
| if (true == config->enablePinOut) | |||
| { | |||
| tmp8 |= CMP_CR1_OPE_MASK; | |||
| } | |||
| #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE | |||
| if (true == config->enableTriggerMode) | |||
| { | |||
| tmp8 |= CMP_CR1_TRIGM_MASK; | |||
| } | |||
| else | |||
| { | |||
| tmp8 &= ~(uint8_t)CMP_CR1_TRIGM_MASK; | |||
| } | |||
| #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ | |||
| base->CR1 = tmp8; | |||
| /* CMPx_CR0. */ | |||
| tmp8 = base->CR0 & ~(uint8_t)CMP_CR0_HYSTCTR_MASK; | |||
| tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode); | |||
| base->CR0 = tmp8; | |||
| CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */ | |||
| } | |||
| /*! | |||
| * brief De-initializes the CMP module. | |||
| * | |||
| * This function de-initializes the CMP module. The operations included are as follows. | |||
| * - Disabling the CMP module. | |||
| * - Disabling the clock for CMP module. | |||
| * | |||
| * This function disables the clock for the CMP. | |||
| * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the | |||
| * clock for the CMP, ensure that all the CMP instances are not used. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| */ | |||
| void CMP_Deinit(CMP_Type *base) | |||
| { | |||
| /* Disable the CMP module. */ | |||
| CMP_Enable(base, false); | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Disable the clock. */ | |||
| CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Initializes the CMP user configuration structure. | |||
| * | |||
| * This function initializes the user configuration structure to these default values. | |||
| * code | |||
| * config->enableCmp = true; | |||
| * config->hysteresisMode = kCMP_HysteresisLevel0; | |||
| * config->enableHighSpeed = false; | |||
| * config->enableInvertOutput = false; | |||
| * config->useUnfilteredOutput = false; | |||
| * config->enablePinOut = false; | |||
| * config->enableTriggerMode = false; | |||
| * endcode | |||
| * param config Pointer to the configuration structure. | |||
| */ | |||
| void CMP_GetDefaultConfig(cmp_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->enableCmp = true; /* Enable the CMP module after initialization. */ | |||
| config->hysteresisMode = kCMP_HysteresisLevel0; | |||
| config->enableHighSpeed = false; | |||
| config->enableInvertOutput = false; | |||
| config->useUnfilteredOutput = false; | |||
| config->enablePinOut = false; | |||
| #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE | |||
| config->enableTriggerMode = false; | |||
| #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ | |||
| } | |||
| /*! | |||
| * brief Sets the input channels for the comparator. | |||
| * | |||
| * This function sets the input channels for the comparator. | |||
| * Note that two input channels cannot be set the same way in the application. When the user selects the same input | |||
| * from the analog mux to the positive and negative port, the comparator is disabled automatically. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param positiveChannel Positive side input channel number. Available range is 0-7. | |||
| * param negativeChannel Negative side input channel number. Available range is 0-7. | |||
| */ | |||
| void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel) | |||
| { | |||
| uint8_t tmp8 = base->MUXCR; | |||
| tmp8 &= ~(uint8_t)(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK); | |||
| tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel); | |||
| base->MUXCR = tmp8; | |||
| } | |||
| #if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA | |||
| /*! | |||
| * brief Enables/disables the DMA request for rising/falling events. | |||
| * | |||
| * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of | |||
| * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from | |||
| * the CMP | |||
| * if the DMA is disabled. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param enable Enables or disables the feature. | |||
| */ | |||
| void CMP_EnableDMA(CMP_Type *base, bool enable) | |||
| { | |||
| uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ | |||
| if (enable) | |||
| { | |||
| tmp8 |= CMP_SCR_DMAEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| tmp8 &= ~(uint8_t)CMP_SCR_DMAEN_MASK; | |||
| } | |||
| base->SCR = tmp8; | |||
| } | |||
| #endif /* FSL_FEATURE_CMP_HAS_DMA */ | |||
| /*! | |||
| * brief Configures the filter. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param config Pointer to the configuration structure. | |||
| */ | |||
| void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint8_t tmp8; | |||
| #if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT | |||
| /* Choose the clock source for sampling. */ | |||
| if (config->enableSample) | |||
| { | |||
| base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */ | |||
| } | |||
| else | |||
| { | |||
| base->CR1 &= (uint8_t)(~CMP_CR1_SE_MASK); /* Choose the internal divided bus clock. */ | |||
| } | |||
| #endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ | |||
| /* Set the filter count. */ | |||
| tmp8 = (uint8_t)(base->CR0 & ~CMP_CR0_FILTER_CNT_MASK); | |||
| tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount); | |||
| base->CR0 = tmp8; | |||
| /* Set the filter period. It is used as the divider to bus clock. */ | |||
| base->FPR = CMP_FPR_FILT_PER(config->filterPeriod); | |||
| } | |||
| /*! | |||
| * brief Configures the internal DAC. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param config Pointer to the configuration structure. "NULL" disables the feature. | |||
| */ | |||
| void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config) | |||
| { | |||
| uint8_t tmp8 = 0U; | |||
| if (NULL == config) | |||
| { | |||
| /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/ | |||
| base->DACCR = 0U; | |||
| return; | |||
| } | |||
| /* CMPx_DACCR. */ | |||
| tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */ | |||
| if (kCMP_VrefSourceVin2 == config->referenceVoltageSource) | |||
| { | |||
| tmp8 |= CMP_DACCR_VRSEL_MASK; | |||
| } | |||
| tmp8 |= CMP_DACCR_VOSEL(config->DACValue); | |||
| base->DACCR = tmp8; | |||
| } | |||
| /*! | |||
| * brief Enables the interrupts. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param mask Mask value for interrupts. See "_cmp_interrupt_enable". | |||
| */ | |||
| void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask) | |||
| { | |||
| uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ | |||
| if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask)) | |||
| { | |||
| tmp8 |= CMP_SCR_IER_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask)) | |||
| { | |||
| tmp8 |= CMP_SCR_IEF_MASK; | |||
| } | |||
| base->SCR = tmp8; | |||
| } | |||
| /*! | |||
| * brief Disables the interrupts. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param mask Mask value for interrupts. See "_cmp_interrupt_enable". | |||
| */ | |||
| void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask) | |||
| { | |||
| uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ | |||
| if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask)) | |||
| { | |||
| tmp8 &= ~(uint8_t)CMP_SCR_IER_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask)) | |||
| { | |||
| tmp8 &= ~(uint8_t)CMP_SCR_IEF_MASK; | |||
| } | |||
| base->SCR = tmp8; | |||
| } | |||
| /*! | |||
| * brief Gets the status flags. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * | |||
| * return Mask value for the asserted flags. See "_cmp_status_flags". | |||
| */ | |||
| uint32_t CMP_GetStatusFlags(CMP_Type *base) | |||
| { | |||
| uint32_t ret32 = 0U; | |||
| if (0U != (CMP_SCR_CFR_MASK & base->SCR)) | |||
| { | |||
| ret32 |= (uint32_t)kCMP_OutputRisingEventFlag; | |||
| } | |||
| if (0U != (CMP_SCR_CFF_MASK & base->SCR)) | |||
| { | |||
| ret32 |= (uint32_t)kCMP_OutputFallingEventFlag; | |||
| } | |||
| if (0U != (CMP_SCR_COUT_MASK & base->SCR)) | |||
| { | |||
| ret32 |= (uint32_t)kCMP_OutputAssertEventFlag; | |||
| } | |||
| return ret32; | |||
| } | |||
| /*! | |||
| * brief Clears the status flags. | |||
| * | |||
| * param base CMP peripheral base address. | |||
| * param mask Mask value for the flags. See "_cmp_status_flags". | |||
| */ | |||
| void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask) | |||
| { | |||
| uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ | |||
| if (0U != ((uint32_t)kCMP_OutputRisingEventFlag & mask)) | |||
| { | |||
| tmp8 |= CMP_SCR_CFR_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kCMP_OutputFallingEventFlag & mask)) | |||
| { | |||
| tmp8 |= CMP_SCR_CFF_MASK; | |||
| } | |||
| base->SCR = tmp8; | |||
| } | |||
| @@ -0,0 +1,321 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_CMP_H_ | |||
| #define _FSL_CMP_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup cmp | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief CMP driver version 2.0.2. */ | |||
| #define FSL_CMP_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Interrupt enable/disable mask. | |||
| */ | |||
| enum _cmp_interrupt_enable | |||
| { | |||
| kCMP_OutputRisingInterruptEnable = CMP_SCR_IER_MASK, /*!< Comparator interrupt enable rising. */ | |||
| kCMP_OutputFallingInterruptEnable = CMP_SCR_IEF_MASK, /*!< Comparator interrupt enable falling. */ | |||
| }; | |||
| /*! | |||
| * @brief Status flags' mask. | |||
| */ | |||
| enum _cmp_status_flags | |||
| { | |||
| kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */ | |||
| kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */ | |||
| kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */ | |||
| }; | |||
| /*! | |||
| * @brief CMP Hysteresis mode. | |||
| */ | |||
| typedef enum _cmp_hysteresis_mode | |||
| { | |||
| kCMP_HysteresisLevel0 = 0U, /*!< Hysteresis level 0. */ | |||
| kCMP_HysteresisLevel1 = 1U, /*!< Hysteresis level 1. */ | |||
| kCMP_HysteresisLevel2 = 2U, /*!< Hysteresis level 2. */ | |||
| kCMP_HysteresisLevel3 = 3U, /*!< Hysteresis level 3. */ | |||
| } cmp_hysteresis_mode_t; | |||
| /*! | |||
| * @brief CMP Voltage Reference source. | |||
| */ | |||
| typedef enum _cmp_reference_voltage_source | |||
| { | |||
| kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as a resistor ladder network supply reference Vin. */ | |||
| kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as a resistor ladder network supply reference Vin. */ | |||
| } cmp_reference_voltage_source_t; | |||
| /*! | |||
| * @brief Configures the comparator. | |||
| */ | |||
| typedef struct _cmp_config | |||
| { | |||
| bool enableCmp; /*!< Enable the CMP module. */ | |||
| cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */ | |||
| bool enableHighSpeed; /*!< Enable High-speed (HS) comparison mode. */ | |||
| bool enableInvertOutput; /*!< Enable the inverted comparator output. */ | |||
| bool useUnfilteredOutput; /*!< Set the compare output(COUT) to equal COUTA(true) or COUT(false). */ | |||
| bool enablePinOut; /*!< The comparator output is available on the associated pin. */ | |||
| #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE | |||
| bool enableTriggerMode; /*!< Enable the trigger mode. */ | |||
| #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ | |||
| } cmp_config_t; | |||
| /*! | |||
| * @brief Configures the filter. | |||
| */ | |||
| typedef struct _cmp_filter_config | |||
| { | |||
| #if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT | |||
| bool enableSample; /*!< Using the external SAMPLE as a sampling clock input or using a divided bus clock. */ | |||
| #endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ | |||
| uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter.*/ | |||
| uint8_t filterPeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. */ | |||
| } cmp_filter_config_t; | |||
| /*! | |||
| * @brief Configures the internal DAC. | |||
| */ | |||
| typedef struct _cmp_dac_config | |||
| { | |||
| cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */ | |||
| uint8_t DACValue; /*!< Value for the DAC Output Voltage. Available range is 0-63.*/ | |||
| } cmp_dac_config_t; | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the CMP. | |||
| * | |||
| * This function initializes the CMP module. The operations included are as follows. | |||
| * - Enabling the clock for CMP module. | |||
| * - Configuring the comparator. | |||
| * - Enabling the CMP module. | |||
| * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for | |||
| * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param config Pointer to the configuration structure. | |||
| */ | |||
| void CMP_Init(CMP_Type *base, const cmp_config_t *config); | |||
| /*! | |||
| * @brief De-initializes the CMP module. | |||
| * | |||
| * This function de-initializes the CMP module. The operations included are as follows. | |||
| * - Disabling the CMP module. | |||
| * - Disabling the clock for CMP module. | |||
| * | |||
| * This function disables the clock for the CMP. | |||
| * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the | |||
| * clock for the CMP, ensure that all the CMP instances are not used. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| */ | |||
| void CMP_Deinit(CMP_Type *base); | |||
| /*! | |||
| * @brief Enables/disables the CMP module. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param enable Enables or disables the module. | |||
| */ | |||
| static inline void CMP_Enable(CMP_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->CR1 |= CMP_CR1_EN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->CR1 &= ~(uint8_t)CMP_CR1_EN_MASK; | |||
| } | |||
| } | |||
| /*! | |||
| * @brief Initializes the CMP user configuration structure. | |||
| * | |||
| * This function initializes the user configuration structure to these default values. | |||
| * @code | |||
| * config->enableCmp = true; | |||
| * config->hysteresisMode = kCMP_HysteresisLevel0; | |||
| * config->enableHighSpeed = false; | |||
| * config->enableInvertOutput = false; | |||
| * config->useUnfilteredOutput = false; | |||
| * config->enablePinOut = false; | |||
| * config->enableTriggerMode = false; | |||
| * @endcode | |||
| * @param config Pointer to the configuration structure. | |||
| */ | |||
| void CMP_GetDefaultConfig(cmp_config_t *config); | |||
| /*! | |||
| * @brief Sets the input channels for the comparator. | |||
| * | |||
| * This function sets the input channels for the comparator. | |||
| * Note that two input channels cannot be set the same way in the application. When the user selects the same input | |||
| * from the analog mux to the positive and negative port, the comparator is disabled automatically. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param positiveChannel Positive side input channel number. Available range is 0-7. | |||
| * @param negativeChannel Negative side input channel number. Available range is 0-7. | |||
| */ | |||
| void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel); | |||
| /* @} */ | |||
| /*! | |||
| * @name Advanced Features | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA | |||
| /*! | |||
| * @brief Enables/disables the DMA request for rising/falling events. | |||
| * | |||
| * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of | |||
| * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from | |||
| * the CMP | |||
| * if the DMA is disabled. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param enable Enables or disables the feature. | |||
| */ | |||
| void CMP_EnableDMA(CMP_Type *base, bool enable); | |||
| #endif /* FSL_FEATURE_CMP_HAS_DMA */ | |||
| #if defined(FSL_FEATURE_CMP_HAS_WINDOW_MODE) && FSL_FEATURE_CMP_HAS_WINDOW_MODE | |||
| /*! | |||
| * @brief Enables/disables the window mode. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param enable Enables or disables the feature. | |||
| */ | |||
| static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->CR1 |= CMP_CR1_WE_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->CR1 &= (uint8_t)(~CMP_CR1_WE_MASK); | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_CMP_HAS_WINDOW_MODE */ | |||
| #if defined(FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE) && FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE | |||
| /*! | |||
| * @brief Enables/disables the pass through mode. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param enable Enables or disables the feature. | |||
| */ | |||
| static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->MUXCR |= CMP_MUXCR_PSTM_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->MUXCR &= (uint8_t)(~CMP_MUXCR_PSTM_MASK); | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE */ | |||
| /*! | |||
| * @brief Configures the filter. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param config Pointer to the configuration structure. | |||
| */ | |||
| void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config); | |||
| /*! | |||
| * @brief Configures the internal DAC. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param config Pointer to the configuration structure. "NULL" disables the feature. | |||
| */ | |||
| void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config); | |||
| /*! | |||
| * @brief Enables the interrupts. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param mask Mask value for interrupts. See "_cmp_interrupt_enable". | |||
| */ | |||
| void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Disables the interrupts. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param mask Mask value for interrupts. See "_cmp_interrupt_enable". | |||
| */ | |||
| void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask); | |||
| /* @} */ | |||
| /*! | |||
| * @name Results | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Gets the status flags. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * | |||
| * @return Mask value for the asserted flags. See "_cmp_status_flags". | |||
| */ | |||
| uint32_t CMP_GetStatusFlags(CMP_Type *base); | |||
| /*! | |||
| * @brief Clears the status flags. | |||
| * | |||
| * @param base CMP peripheral base address. | |||
| * @param mask Mask value for the flags. See "_cmp_status_flags". | |||
| */ | |||
| void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask); | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| * @} | |||
| */ | |||
| #endif /* _FSL_CMP_H_ */ | |||
| @@ -0,0 +1,280 @@ | |||
| /* | |||
| * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_common.h" | |||
| #define SDK_MEM_MAGIC_NUMBER 12345U | |||
| typedef struct _mem_align_control_block | |||
| { | |||
| uint16_t identifier; /*!< Identifier for the memory control block. */ | |||
| uint16_t offset; /*!< offset from aligned address to real address */ | |||
| } mem_align_cb_t; | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.common" | |||
| #endif | |||
| #ifndef __GIC_PRIO_BITS | |||
| #if defined(ENABLE_RAM_VECTOR_TABLE) | |||
| uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) | |||
| { | |||
| /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ | |||
| #if defined(__CC_ARM) || defined(__ARMCC_VERSION) | |||
| extern uint32_t Image$$VECTOR_ROM$$Base[]; | |||
| extern uint32_t Image$$VECTOR_RAM$$Base[]; | |||
| extern uint32_t Image$$RW_m_data$$Base[]; | |||
| #define __VECTOR_TABLE Image$$VECTOR_ROM$$Base | |||
| #define __VECTOR_RAM Image$$VECTOR_RAM$$Base | |||
| #define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) | |||
| #elif defined(__ICCARM__) | |||
| extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; | |||
| extern uint32_t __VECTOR_TABLE[]; | |||
| extern uint32_t __VECTOR_RAM[]; | |||
| #elif defined(__GNUC__) | |||
| extern uint32_t __VECTOR_TABLE[]; | |||
| extern uint32_t __VECTOR_RAM[]; | |||
| extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; | |||
| uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); | |||
| #endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */ | |||
| uint32_t n; | |||
| uint32_t ret; | |||
| uint32_t irqMaskValue; | |||
| irqMaskValue = DisableGlobalIRQ(); | |||
| if (SCB->VTOR != (uint32_t)__VECTOR_RAM) | |||
| { | |||
| /* Copy the vector table from ROM to RAM */ | |||
| for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) | |||
| { | |||
| __VECTOR_RAM[n] = __VECTOR_TABLE[n]; | |||
| } | |||
| /* Point the VTOR to the position of vector table */ | |||
| SCB->VTOR = (uint32_t)__VECTOR_RAM; | |||
| } | |||
| ret = __VECTOR_RAM[irq + 16]; | |||
| /* make sure the __VECTOR_RAM is noncachable */ | |||
| __VECTOR_RAM[irq + 16] = irqHandler; | |||
| EnableGlobalIRQ(irqMaskValue); | |||
| SDK_ISR_EXIT_BARRIER; | |||
| return ret; | |||
| } | |||
| #endif /* ENABLE_RAM_VECTOR_TABLE. */ | |||
| #endif /* __GIC_PRIO_BITS. */ | |||
| #if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) | |||
| #if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) | |||
| void EnableDeepSleepIRQ(IRQn_Type interrupt) | |||
| { | |||
| uint32_t intNumber = (uint32_t)interrupt; | |||
| uint32_t index = 0; | |||
| while (intNumber >= 32u) | |||
| { | |||
| index++; | |||
| intNumber -= 32u; | |||
| } | |||
| SYSCON->STARTERSET[index] = 1u << intNumber; | |||
| EnableIRQ(interrupt); /* also enable interrupt at NVIC */ | |||
| } | |||
| void DisableDeepSleepIRQ(IRQn_Type interrupt) | |||
| { | |||
| uint32_t intNumber = (uint32_t)interrupt; | |||
| DisableIRQ(interrupt); /* also disable interrupt at NVIC */ | |||
| uint32_t index = 0; | |||
| while (intNumber >= 32u) | |||
| { | |||
| index++; | |||
| intNumber -= 32u; | |||
| } | |||
| SYSCON->STARTERCLR[index] = 1u << intNumber; | |||
| } | |||
| #endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */ | |||
| #endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ | |||
| void *SDK_Malloc(size_t size, size_t alignbytes) | |||
| { | |||
| mem_align_cb_t *p_cb = NULL; | |||
| uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t); | |||
| union | |||
| { | |||
| void *pointer_value; | |||
| uint32_t unsigned_value; | |||
| } p_align_addr, p_addr; | |||
| p_addr.pointer_value = malloc(alignedsize); | |||
| if (p_addr.pointer_value == NULL) | |||
| { | |||
| return NULL; | |||
| } | |||
| p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes); | |||
| p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U); | |||
| p_cb->identifier = SDK_MEM_MAGIC_NUMBER; | |||
| p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value); | |||
| return p_align_addr.pointer_value; | |||
| } | |||
| void SDK_Free(void *ptr) | |||
| { | |||
| union | |||
| { | |||
| void *pointer_value; | |||
| uint32_t unsigned_value; | |||
| } p_free; | |||
| p_free.pointer_value = ptr; | |||
| mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U); | |||
| if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER) | |||
| { | |||
| return; | |||
| } | |||
| p_free.unsigned_value = p_free.unsigned_value - p_cb->offset; | |||
| free(p_free.pointer_value); | |||
| } | |||
| /*! | |||
| * @brief Delay function bases on while loop, every loop includes three instructions. | |||
| * | |||
| * @param count Counts of loop needed for dalay. | |||
| */ | |||
| #if defined(SDK_DELAY_USE_DWT) && defined(DWT) | |||
| void enableCpuCycleCounter(void) | |||
| { | |||
| /* Make sure the DWT trace fucntion is enabled. */ | |||
| if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR)) | |||
| { | |||
| CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; | |||
| } | |||
| /* CYCCNT not supported on this device. */ | |||
| assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk)); | |||
| /* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */ | |||
| if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL)) | |||
| { | |||
| DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; | |||
| } | |||
| } | |||
| uint32_t getCpuCycleCount(void) | |||
| { | |||
| return DWT->CYCCNT; | |||
| } | |||
| #elif defined __XCC__ | |||
| extern uint32_t xthal_get_ccount(void); | |||
| void enableCpuCycleCounter(void) | |||
| { | |||
| /* do nothing */ | |||
| } | |||
| uint32_t getCpuCycleCount(void) | |||
| { | |||
| return xthal_get_ccount(); | |||
| } | |||
| #endif | |||
| #ifndef __XCC__ | |||
| #if (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) | |||
| #if defined(__CC_ARM) /* This macro is arm v5 specific */ | |||
| /* clang-format off */ | |||
| __ASM static void DelayLoop(uint32_t count) | |||
| { | |||
| loop | |||
| SUBS R0, R0, #1 | |||
| CMP R0, #0 | |||
| BNE loop | |||
| BX LR | |||
| } | |||
| /* clang-format on */ | |||
| #elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__) | |||
| /* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler, | |||
| * use SUB and CMP here for compatibility */ | |||
| static void DelayLoop(uint32_t count) | |||
| { | |||
| __ASM volatile(" MOV R0, %0" : : "r"(count)); | |||
| __ASM volatile( | |||
| "loop: \n" | |||
| #if defined(__GNUC__) && !defined(__ARMCC_VERSION) | |||
| " SUB R0, R0, #1 \n" | |||
| #else | |||
| " SUBS R0, R0, #1 \n" | |||
| #endif | |||
| " CMP R0, #0 \n" | |||
| " BNE loop \n"); | |||
| } | |||
| #endif /* defined(__CC_ARM) */ | |||
| #endif /* (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) */ | |||
| #endif /* __XCC__ */ | |||
| /*! | |||
| * @brief Delay at least for some time. | |||
| * Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have | |||
| * effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delay_us and | |||
| * coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delay_us only supports | |||
| * up to 4294967 in current code. If long time delay is needed, please implement a new delay function. | |||
| * | |||
| * @param delay_us Delay time in unit of microsecond. | |||
| * @param coreClock_Hz Core clock frequency with Hz. | |||
| */ | |||
| void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz) | |||
| { | |||
| assert(0U != delay_us); | |||
| uint64_t count = USEC_TO_COUNT(delay_us, coreClock_Hz); | |||
| assert(count <= UINT32_MAX); | |||
| #if defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) /* Use DWT for better accuracy */ | |||
| enableCpuCycleCounter(); | |||
| /* Calculate the count ticks. */ | |||
| count += getCpuCycleCount(); | |||
| if (count > UINT32_MAX) | |||
| { | |||
| count -= UINT32_MAX; | |||
| /* Wait for cyccnt overflow. */ | |||
| while (count < getCpuCycleCount()) | |||
| { | |||
| } | |||
| } | |||
| /* Wait for cyccnt reach count value. */ | |||
| while (count > getCpuCycleCount()) | |||
| { | |||
| } | |||
| #else | |||
| /* Divide value may be different in various environment to ensure delay is precise. | |||
| * Every loop count includes three instructions, due to Cortex-M7 sometimes executes | |||
| * two instructions in one period, through test here set divide 1.5. Other M cores use | |||
| * divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does | |||
| * not matter because other instructions outside while loop is enough to fill the time. | |||
| */ | |||
| #if (__CORTEX_M == 7) | |||
| count = count / 3U * 2U; | |||
| #else | |||
| count = count / 4U; | |||
| #endif | |||
| DelayLoop((uint32_t)count); | |||
| #endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) */ | |||
| } | |||
| @@ -0,0 +1,672 @@ | |||
| /* | |||
| * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_COMMON_H_ | |||
| #define _FSL_COMMON_H_ | |||
| #include <assert.h> | |||
| #include <stdbool.h> | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <stdlib.h> | |||
| #if defined(__ICCARM__) | |||
| #include <stddef.h> | |||
| #endif | |||
| /* | |||
| * For CMSIS pack RTE. | |||
| * CMSIS pack RTE generates "RTC_Components.h" which contains the statements | |||
| * of the related <RTE_Components_h> element for all selected software components. | |||
| */ | |||
| #ifdef _RTE_ | |||
| #include "RTE_Components.h" | |||
| #endif | |||
| #include "fsl_device_registers.h" | |||
| /*! | |||
| * @addtogroup ksdk_common | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @brief Construct a status code value from a group and code number. */ | |||
| #define MAKE_STATUS(group, code) ((((group)*100) + (code))) | |||
| /*! @brief Construct the version number for drivers. */ | |||
| #define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief common driver version 2.2.4. */ | |||
| #define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 2, 4)) | |||
| /*@}*/ | |||
| /* Debug console type definition. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */ | |||
| #define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */ | |||
| /*! @brief Status group numbers. */ | |||
| enum _status_groups | |||
| { | |||
| kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ | |||
| kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */ | |||
| kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */ | |||
| kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */ | |||
| kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */ | |||
| kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */ | |||
| kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */ | |||
| kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */ | |||
| kStatusGroup_UART = 10, /*!< Group number for UART status codes. */ | |||
| kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */ | |||
| kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */ | |||
| kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */ | |||
| kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/ | |||
| kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/ | |||
| kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/ | |||
| kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */ | |||
| kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ | |||
| kStatusGroup_SAI = 19, /*!< Group number for SAI status code */ | |||
| kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */ | |||
| kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ | |||
| kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ | |||
| kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ | |||
| kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */ | |||
| kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */ | |||
| kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */ | |||
| kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */ | |||
| kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */ | |||
| kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */ | |||
| kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */ | |||
| kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ | |||
| kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ | |||
| kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ | |||
| kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */ | |||
| kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */ | |||
| kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */ | |||
| kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */ | |||
| kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */ | |||
| kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */ | |||
| kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */ | |||
| kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */ | |||
| kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ | |||
| kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ | |||
| kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ | |||
| kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */ | |||
| kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */ | |||
| kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */ | |||
| kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/ | |||
| kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */ | |||
| kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */ | |||
| kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */ | |||
| kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */ | |||
| kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */ | |||
| kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/ | |||
| kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/ | |||
| kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/ | |||
| kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/ | |||
| kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */ | |||
| kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */ | |||
| kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */ | |||
| kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */ | |||
| kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */ | |||
| kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */ | |||
| kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */ | |||
| kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */ | |||
| kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */ | |||
| kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */ | |||
| kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */ | |||
| kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */ | |||
| kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ | |||
| kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ | |||
| kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */ | |||
| kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */ | |||
| kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */ | |||
| kStatusGroup_SFA = 103, /*!< Group number for SFA status codes*/ | |||
| kStatusGroup_SPC = 104, /*!< Group number for SPC status codes. */ | |||
| kStatusGroup_PUF = 105, /*!< Group number for PUF status codes. */ | |||
| kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */ | |||
| kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */ | |||
| kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */ | |||
| kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */ | |||
| kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */ | |||
| kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */ | |||
| kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */ | |||
| kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */ | |||
| kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */ | |||
| kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */ | |||
| kStatusGroup_LED = 137, /*!< Group number for LED status codes. */ | |||
| kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */ | |||
| kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */ | |||
| kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */ | |||
| kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */ | |||
| kStatusGroup_LIST = 142, /*!< Group number for List status codes. */ | |||
| kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */ | |||
| kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */ | |||
| kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */ | |||
| kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */ | |||
| kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/ | |||
| kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */ | |||
| kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */ | |||
| kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */ | |||
| kStatusGroup_SDIOSLV = 151, /*!< Group number for SDIOSLV status codes. */ | |||
| }; | |||
| /*! \public | |||
| * @brief Generic status return codes. | |||
| */ | |||
| enum | |||
| { | |||
| kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< Generic status for Success. */ | |||
| kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< Generic status for Fail. */ | |||
| kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< Generic status for read only failure. */ | |||
| kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< Generic status for out of range access. */ | |||
| kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Generic status for invalid argument check. */ | |||
| kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Generic status for timeout. */ | |||
| kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Generic status for no transfer in progress. */ | |||
| }; | |||
| /*! @brief Type used for all status and error return values. */ | |||
| typedef int32_t status_t; | |||
| /* | |||
| * Macro guard for whether to use default weak IRQ implementation in drivers | |||
| */ | |||
| #ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ | |||
| #define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1 | |||
| #endif | |||
| /*! @name Min/max macros */ | |||
| /* @{ */ | |||
| #if !defined(MIN) | |||
| #define MIN(a, b) (((a) < (b)) ? (a) : (b)) | |||
| #endif | |||
| #if !defined(MAX) | |||
| #define MAX(a, b) (((a) > (b)) ? (a) : (b)) | |||
| #endif | |||
| /* @} */ | |||
| /*! @brief Computes the number of elements in an array. */ | |||
| #if !defined(ARRAY_SIZE) | |||
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | |||
| #endif | |||
| /*! @name UINT16_MAX/UINT32_MAX value */ | |||
| /* @{ */ | |||
| #if !defined(UINT16_MAX) | |||
| #define UINT16_MAX ((uint16_t)-1) | |||
| #endif | |||
| #if !defined(UINT32_MAX) | |||
| #define UINT32_MAX ((uint32_t)-1) | |||
| #endif | |||
| /* @} */ | |||
| /*! @name Timer utilities */ | |||
| /* @{ */ | |||
| /*! Macro to convert a microsecond period to raw count value */ | |||
| #define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U) | |||
| /*! Macro to convert a raw count value to microsecond */ | |||
| #define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000000U / (clockFreqInHz)) | |||
| /*! Macro to convert a millisecond period to raw count value */ | |||
| #define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U) | |||
| /*! Macro to convert a raw count value to millisecond */ | |||
| #define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count) * 1000U / (clockFreqInHz)) | |||
| /* @} */ | |||
| /*! @name ISR exit barrier | |||
| * @{ | |||
| * | |||
| * ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping | |||
| * exception return operation might vector to incorrect interrupt. | |||
| * For Cortex-M7, if core speed much faster than peripheral register write speed, | |||
| * the peripheral interrupt flags may be still set after exiting ISR, this results to | |||
| * the same error similar with errata 83869. | |||
| */ | |||
| #if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U)) | |||
| #define SDK_ISR_EXIT_BARRIER __DSB() | |||
| #else | |||
| #define SDK_ISR_EXIT_BARRIER | |||
| #endif | |||
| /* @} */ | |||
| /*! @name Alignment variable definition macros */ | |||
| /* @{ */ | |||
| #if (defined(__ICCARM__)) | |||
| /** | |||
| * Workaround to disable MISRA C message suppress warnings for IAR compiler. | |||
| * http:/ /supp.iar.com/Support/?note=24725 | |||
| */ | |||
| _Pragma("diag_suppress=Pm120") | |||
| #define SDK_PRAGMA(x) _Pragma(#x) | |||
| _Pragma("diag_error=Pm120") | |||
| /*! Macro to define a variable with alignbytes alignment */ | |||
| #define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var | |||
| /*! Macro to define a variable with L1 d-cache line size alignment */ | |||
| #if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | |||
| #define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var | |||
| #endif | |||
| /*! Macro to define a variable with L2 cache line size alignment */ | |||
| #if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) | |||
| #define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var | |||
| #endif | |||
| #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) | |||
| /*! Macro to define a variable with alignbytes alignment */ | |||
| #define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var | |||
| /*! Macro to define a variable with L1 d-cache line size alignment */ | |||
| #if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | |||
| #define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var | |||
| #endif | |||
| /*! Macro to define a variable with L2 cache line size alignment */ | |||
| #if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) | |||
| #define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var | |||
| #endif | |||
| #elif defined(__GNUC__) | |||
| /*! Macro to define a variable with alignbytes alignment */ | |||
| #define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) | |||
| /*! Macro to define a variable with L1 d-cache line size alignment */ | |||
| #if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | |||
| #define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) | |||
| #endif | |||
| /*! Macro to define a variable with L2 cache line size alignment */ | |||
| #if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) | |||
| #define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) | |||
| #endif | |||
| #else | |||
| #error Toolchain not supported | |||
| #define SDK_ALIGN(var, alignbytes) var | |||
| #if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | |||
| #define SDK_L1DCACHE_ALIGN(var) var | |||
| #endif | |||
| #if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) | |||
| #define SDK_L2CACHE_ALIGN(var) var | |||
| #endif | |||
| #endif | |||
| /*! Macro to change a value to a given size aligned value */ | |||
| #define SDK_SIZEALIGN(var, alignbytes) \ | |||
| ((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U))) | |||
| /* @} */ | |||
| /*! @name Non-cacheable region definition macros */ | |||
| /* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or | |||
| * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables, | |||
| * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables | |||
| * will be initialized to zero in system startup. | |||
| */ | |||
| /* @{ */ | |||
| #if (defined(__ICCARM__)) | |||
| #if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) | |||
| #define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable" | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable" | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init" | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init" | |||
| #else | |||
| #define AT_NONCACHEABLE_SECTION(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var | |||
| #endif | |||
| #elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) | |||
| #if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ | |||
| __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var | |||
| #if(defined(__CC_ARM)) | |||
| #define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ | |||
| __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var | |||
| #else | |||
| #define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ | |||
| __attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var | |||
| #endif | |||
| #else | |||
| #define AT_NONCACHEABLE_SECTION(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var | |||
| #endif | |||
| #elif(defined(__XCC__)) | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ | |||
| __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes))) | |||
| #define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ | |||
| __attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes))) | |||
| #elif(defined(__GNUC__)) | |||
| /* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA" | |||
| * in your projects to make sure the non-cacheable section variables will be initialized in system startup. | |||
| */ | |||
| #if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ | |||
| __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes))) | |||
| #define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ | |||
| __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes))) | |||
| #else | |||
| #define AT_NONCACHEABLE_SECTION(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes))) | |||
| #endif | |||
| #else | |||
| #error Toolchain not supported. | |||
| #define AT_NONCACHEABLE_SECTION(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var | |||
| #define AT_NONCACHEABLE_SECTION_INIT(var) var | |||
| #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var | |||
| #endif | |||
| /* @} */ | |||
| /*! @name Time sensitive region */ | |||
| /* @{ */ | |||
| #if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE | |||
| #if (defined(__ICCARM__)) | |||
| #define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess" | |||
| #define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess" | |||
| #elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) | |||
| #define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func | |||
| #define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func | |||
| #elif(defined(__GNUC__)) | |||
| #define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func | |||
| #define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func | |||
| #else | |||
| #error Toolchain not supported. | |||
| #endif /* defined(__ICCARM__) */ | |||
| #else | |||
| #if (defined(__ICCARM__)) | |||
| #define AT_QUICKACCESS_SECTION_CODE(func) func | |||
| #define AT_QUICKACCESS_SECTION_DATA(func) func | |||
| #elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) | |||
| #define AT_QUICKACCESS_SECTION_CODE(func) func | |||
| #define AT_QUICKACCESS_SECTION_DATA(func) func | |||
| #elif(defined(__GNUC__)) | |||
| #define AT_QUICKACCESS_SECTION_CODE(func) func | |||
| #define AT_QUICKACCESS_SECTION_DATA(func) func | |||
| #else | |||
| #error Toolchain not supported. | |||
| #endif | |||
| #endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */ | |||
| /* @} */ | |||
| /*! @name Ram Function */ | |||
| #if (defined(__ICCARM__)) | |||
| #define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction" | |||
| #elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) | |||
| #define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func | |||
| #elif(defined(__GNUC__)) | |||
| #define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func | |||
| #else | |||
| #error Toolchain not supported. | |||
| #endif /* defined(__ICCARM__) */ | |||
| /* @} */ | |||
| /*! @name Suppress fallthrough warning macro */ | |||
| /* For switch case code block, if case section ends without "break;" statement, there wil be | |||
| fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc. | |||
| To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each | |||
| case section which misses "break;"statement. | |||
| */ | |||
| /* @{ */ | |||
| #if defined(__GNUC__) && !defined(__ARMCC_VERSION) | |||
| #define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough)) | |||
| #else | |||
| #define SUPPRESS_FALL_THROUGH_WARNING() | |||
| #endif | |||
| /* @} */ | |||
| #if defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) | |||
| void DefaultISR(void); | |||
| #endif | |||
| /* | |||
| * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t | |||
| * defined in previous of this file. | |||
| */ | |||
| #include "fsl_clock.h" | |||
| /* | |||
| * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral | |||
| */ | |||
| #if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ | |||
| (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) | |||
| #include "fsl_reset.h" | |||
| #endif | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" | |||
| { | |||
| #endif | |||
| /*! | |||
| * @brief Enable specific interrupt. | |||
| * | |||
| * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt | |||
| * levels. For example, there are NVIC and intmux. Here the interrupts connected | |||
| * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. | |||
| * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed | |||
| * to NVIC first then routed to core. | |||
| * | |||
| * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts | |||
| * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. | |||
| * | |||
| * @param interrupt The IRQ number. | |||
| * @retval kStatus_Success Interrupt enabled successfully | |||
| * @retval kStatus_Fail Failed to enable the interrupt | |||
| */ | |||
| static inline status_t EnableIRQ(IRQn_Type interrupt) | |||
| { | |||
| if (NotAvail_IRQn == interrupt) | |||
| { | |||
| return kStatus_Fail; | |||
| } | |||
| #if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) | |||
| if ((uint32_t)interrupt >= (uint32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) | |||
| { | |||
| return kStatus_Fail; | |||
| } | |||
| #endif | |||
| #if defined(__GIC_PRIO_BITS) | |||
| GIC_EnableIRQ(interrupt); | |||
| #else | |||
| NVIC_EnableIRQ(interrupt); | |||
| #endif | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * @brief Disable specific interrupt. | |||
| * | |||
| * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt | |||
| * levels. For example, there are NVIC and intmux. Here the interrupts connected | |||
| * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. | |||
| * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed | |||
| * to NVIC first then routed to core. | |||
| * | |||
| * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts | |||
| * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. | |||
| * | |||
| * @param interrupt The IRQ number. | |||
| * @retval kStatus_Success Interrupt disabled successfully | |||
| * @retval kStatus_Fail Failed to disable the interrupt | |||
| */ | |||
| static inline status_t DisableIRQ(IRQn_Type interrupt) | |||
| { | |||
| if (NotAvail_IRQn == interrupt) | |||
| { | |||
| return kStatus_Fail; | |||
| } | |||
| #if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) | |||
| if ((uint32_t)interrupt >= (uint32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) | |||
| { | |||
| return kStatus_Fail; | |||
| } | |||
| #endif | |||
| #if defined(__GIC_PRIO_BITS) | |||
| GIC_DisableIRQ(interrupt); | |||
| #else | |||
| NVIC_DisableIRQ(interrupt); | |||
| #endif | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * @brief Disable the global IRQ | |||
| * | |||
| * Disable the global interrupt and return the current primask register. User is required to provided the primask | |||
| * register for the EnableGlobalIRQ(). | |||
| * | |||
| * @return Current primask value. | |||
| */ | |||
| static inline uint32_t DisableGlobalIRQ(void) | |||
| { | |||
| #if defined (__XCC__) | |||
| return 0; | |||
| #else | |||
| #if defined(CPSR_I_Msk) | |||
| uint32_t cpsr = __get_CPSR() & CPSR_I_Msk; | |||
| __disable_irq(); | |||
| return cpsr; | |||
| #else | |||
| uint32_t regPrimask = __get_PRIMASK(); | |||
| __disable_irq(); | |||
| return regPrimask; | |||
| #endif | |||
| #endif | |||
| } | |||
| /*! | |||
| * @brief Enable the global IRQ | |||
| * | |||
| * Set the primask register with the provided primask value but not just enable the primask. The idea is for the | |||
| * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to | |||
| * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair. | |||
| * | |||
| * @param primask value of primask register to be restored. The primask value is supposed to be provided by the | |||
| * DisableGlobalIRQ(). | |||
| */ | |||
| static inline void EnableGlobalIRQ(uint32_t primask) | |||
| { | |||
| #if defined (__XCC__) | |||
| #else | |||
| #if defined(CPSR_I_Msk) | |||
| __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask); | |||
| #else | |||
| __set_PRIMASK(primask); | |||
| #endif | |||
| #endif | |||
| } | |||
| #if defined(ENABLE_RAM_VECTOR_TABLE) | |||
| /*! | |||
| * @brief install IRQ handler | |||
| * | |||
| * @param irq IRQ number | |||
| * @param irqHandler IRQ handler address | |||
| * @return The old IRQ handler address | |||
| */ | |||
| uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); | |||
| #endif /* ENABLE_RAM_VECTOR_TABLE. */ | |||
| #if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) | |||
| /*! | |||
| * @brief Enable specific interrupt for wake-up from deep-sleep mode. | |||
| * | |||
| * Enable the interrupt for wake-up from deep sleep mode. | |||
| * Some interrupts are typically used in sleep mode only and will not occur during | |||
| * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable | |||
| * those clocks (significantly increasing power consumption in the reduced power mode), | |||
| * making these wake-ups possible. | |||
| * | |||
| * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly). | |||
| * | |||
| * @param interrupt The IRQ number. | |||
| */ | |||
| void EnableDeepSleepIRQ(IRQn_Type interrupt); | |||
| /*! | |||
| * @brief Disable specific interrupt for wake-up from deep-sleep mode. | |||
| * | |||
| * Disable the interrupt for wake-up from deep sleep mode. | |||
| * Some interrupts are typically used in sleep mode only and will not occur during | |||
| * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable | |||
| * those clocks (significantly increasing power consumption in the reduced power mode), | |||
| * making these wake-ups possible. | |||
| * | |||
| * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly). | |||
| * | |||
| * @param interrupt The IRQ number. | |||
| */ | |||
| void DisableDeepSleepIRQ(IRQn_Type interrupt); | |||
| #endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ | |||
| /*! | |||
| * @brief Allocate memory with given alignment and aligned size. | |||
| * | |||
| * This is provided to support the dynamically allocated memory | |||
| * used in cache-able region. | |||
| * @param size The length required to malloc. | |||
| * @param alignbytes The alignment size. | |||
| * @retval The allocated memory. | |||
| */ | |||
| void *SDK_Malloc(size_t size, size_t alignbytes); | |||
| /*! | |||
| * @brief Free memory. | |||
| * | |||
| * @param ptr The memory to be release. | |||
| */ | |||
| void SDK_Free(void *ptr); | |||
| /*! | |||
| * @brief Delay at least for some time. | |||
| * Please note that, this API uses while loop for delay, different run-time environments make the time not precise, | |||
| * if precise delay count was needed, please implement a new delay function with hardware timer. | |||
| * | |||
| * @param delay_us Delay time in unit of microsecond. | |||
| * @param coreClock_Hz Core clock frequency with Hz. | |||
| */ | |||
| void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz); | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @} */ | |||
| #endif /* _FSL_COMMON_H_ */ | |||
| @@ -0,0 +1,322 @@ | |||
| /* | |||
| * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_crc.h" | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.crc" | |||
| #endif | |||
| /*! @internal @brief Has data register with name CRC. */ | |||
| #if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG | |||
| #define DATA CRC | |||
| #define DATALL CRCLL | |||
| #endif | |||
| #if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT | |||
| /* @brief Default user configuration structure for CRC-16-CCITT */ | |||
| #define CRC_DRIVER_DEFAULT_POLYNOMIAL 0x1021U | |||
| /*< CRC-16-CCIT polynomial x**16 + x**12 + x**5 + x**0 */ | |||
| #define CRC_DRIVER_DEFAULT_SEED 0xFFFFU | |||
| /*< Default initial checksum */ | |||
| #define CRC_DRIVER_DEFAULT_REFLECT_IN false | |||
| /*< Default is no transpose */ | |||
| #define CRC_DRIVER_DEFAULT_REFLECT_OUT false | |||
| /*< Default is transpose bytes */ | |||
| #define CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM false | |||
| /*< Default is without complement of CRC data register read data */ | |||
| #define CRC_DRIVER_DEFAULT_CRC_BITS kCrcBits16 | |||
| /*< Default is 16-bit CRC protocol */ | |||
| #define CRC_DRIVER_DEFAULT_CRC_RESULT kCrcFinalChecksum | |||
| /*< Default is resutl type is final checksum */ | |||
| #endif /* CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT */ | |||
| /*! @brief CRC type of transpose of read write data */ | |||
| typedef enum _crc_transpose_type | |||
| { | |||
| kCrcTransposeNone = 0U, /*! No transpose */ | |||
| kCrcTransposeBits = 1U, /*! Tranpose bits in bytes */ | |||
| kCrcTransposeBitsAndBytes = 2U, /*! Transpose bytes and bits in bytes */ | |||
| kCrcTransposeBytes = 3U, /*! Transpose bytes */ | |||
| } crc_transpose_type_t; | |||
| /*! | |||
| * @brief CRC module configuration. | |||
| * | |||
| * This structure holds the configuration for the CRC module. | |||
| */ | |||
| typedef struct _crc_module_config | |||
| { | |||
| uint32_t polynomial; /*!< CRC Polynomial, MSBit first.@n | |||
| Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */ | |||
| uint32_t seed; /*!< Starting checksum value */ | |||
| crc_transpose_type_t readTranspose; /*!< Type of transpose when reading CRC result. */ | |||
| crc_transpose_type_t writeTranspose; /*!< Type of transpose when writing CRC input data. */ | |||
| bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */ | |||
| crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */ | |||
| } crc_module_config_t; | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Returns transpose type for CRC protocol reflect in parameter. | |||
| * | |||
| * This functions helps to set writeTranspose member of crc_config_t structure. Reflect in is CRC protocol parameter. | |||
| * | |||
| * @param enable True or false for the selected CRC protocol Reflect In (refin) parameter. | |||
| */ | |||
| static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectIn(bool enable) | |||
| { | |||
| return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes); | |||
| } | |||
| /*! | |||
| * @brief Returns transpose type for CRC protocol reflect out parameter. | |||
| * | |||
| * This functions helps to set readTranspose member of crc_config_t structure. Reflect out is CRC protocol parameter. | |||
| * | |||
| * @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter. | |||
| */ | |||
| static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectOut(bool enable) | |||
| { | |||
| return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone); | |||
| } | |||
| /*! | |||
| * @brief Starts checksum computation. | |||
| * | |||
| * Configures the CRC module for the specified CRC protocol. @n | |||
| * Starts the checksum computation by writing the seed value | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @param config Pointer to protocol configuration structure. | |||
| */ | |||
| static void CRC_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config) | |||
| { | |||
| uint32_t crcControl; | |||
| /* pre-compute value for CRC control registger based on user configuraton without WAS field */ | |||
| crcControl = 0U | CRC_CTRL_TOT(config->writeTranspose) | CRC_CTRL_TOTR(config->readTranspose) | | |||
| CRC_CTRL_FXOR(config->complementChecksum) | CRC_CTRL_TCRC(config->crcBits); | |||
| /* make sure the control register is clear - WAS is deasserted, and protocol is set */ | |||
| base->CTRL = crcControl; | |||
| /* write polynomial register */ | |||
| base->GPOLY = config->polynomial; | |||
| /* write pre-computed control register value along with WAS to start checksum computation */ | |||
| base->CTRL = crcControl | CRC_CTRL_WAS(true); | |||
| /* write seed (initial checksum) */ | |||
| base->DATA = config->seed; | |||
| /* deassert WAS by writing pre-computed CRC control register value */ | |||
| base->CTRL = crcControl; | |||
| } | |||
| /*! | |||
| * @brief Starts final checksum computation. | |||
| * | |||
| * Configures the CRC module for the specified CRC protocol. @n | |||
| * Starts final checksum computation by writing the seed value. | |||
| * @note CRC_Get16bitResult() or CRC_Get32bitResult() return final checksum | |||
| * (output reflection and xor functions are applied). | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @param protocolConfig Pointer to protocol configuration structure. | |||
| */ | |||
| static void CRC_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) | |||
| { | |||
| crc_module_config_t moduleConfig; | |||
| /* convert protocol to CRC peripheral module configuration, prepare for final checksum */ | |||
| moduleConfig.polynomial = protocolConfig->polynomial; | |||
| moduleConfig.seed = protocolConfig->seed; | |||
| moduleConfig.readTranspose = CRC_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut); | |||
| moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); | |||
| moduleConfig.complementChecksum = protocolConfig->complementChecksum; | |||
| moduleConfig.crcBits = protocolConfig->crcBits; | |||
| CRC_ConfigureAndStart(base, &moduleConfig); | |||
| } | |||
| /*! | |||
| * @brief Starts intermediate checksum computation. | |||
| * | |||
| * Configures the CRC module for the specified CRC protocol. @n | |||
| * Starts intermediate checksum computation by writing the seed value. | |||
| * @note CRC_Get16bitResult() or CRC_Get32bitResult() return intermediate checksum (raw data register value). | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @param protocolConfig Pointer to protocol configuration structure. | |||
| */ | |||
| static void CRC_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) | |||
| { | |||
| crc_module_config_t moduleConfig; | |||
| /* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */ | |||
| moduleConfig.polynomial = protocolConfig->polynomial; | |||
| moduleConfig.seed = protocolConfig->seed; | |||
| moduleConfig.readTranspose = | |||
| kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */ | |||
| moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); | |||
| moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */ | |||
| moduleConfig.crcBits = protocolConfig->crcBits; | |||
| CRC_ConfigureAndStart(base, &moduleConfig); | |||
| } | |||
| /*! | |||
| * brief Enables and configures the CRC peripheral module. | |||
| * | |||
| * This function enables the clock gate in the SIM module for the CRC peripheral. | |||
| * It also configures the CRC module and starts a checksum computation by writing the seed. | |||
| * | |||
| * param base CRC peripheral address. | |||
| * param config CRC module configuration structure. | |||
| */ | |||
| void CRC_Init(CRC_Type *base, const crc_config_t *config) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* ungate clock */ | |||
| CLOCK_EnableClock(kCLOCK_Crc0); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /* configure CRC module and write the seed */ | |||
| if (config->crcResult == kCrcFinalChecksum) | |||
| { | |||
| CRC_SetProtocolConfig(base, config); | |||
| } | |||
| else | |||
| { | |||
| CRC_SetRawProtocolConfig(base, config); | |||
| } | |||
| } | |||
| /*! | |||
| * brief Loads default values to the CRC protocol configuration structure. | |||
| * | |||
| * Loads default values to the CRC protocol configuration structure. The default values are as follows. | |||
| * code | |||
| * config->polynomial = 0x1021; | |||
| * config->seed = 0xFFFF; | |||
| * config->reflectIn = false; | |||
| * config->reflectOut = false; | |||
| * config->complementChecksum = false; | |||
| * config->crcBits = kCrcBits16; | |||
| * config->crcResult = kCrcFinalChecksum; | |||
| * endcode | |||
| * | |||
| * param config CRC protocol configuration structure. | |||
| */ | |||
| void CRC_GetDefaultConfig(crc_config_t *config) | |||
| { | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| static const crc_config_t crc16ccit = { | |||
| CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_SEED, | |||
| CRC_DRIVER_DEFAULT_REFLECT_IN, CRC_DRIVER_DEFAULT_REFLECT_OUT, | |||
| CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM, CRC_DRIVER_DEFAULT_CRC_BITS, | |||
| CRC_DRIVER_DEFAULT_CRC_RESULT, | |||
| }; | |||
| *config = crc16ccit; | |||
| } | |||
| /*! | |||
| * brief Writes data to the CRC module. | |||
| * | |||
| * Writes input data buffer bytes to the CRC data register. | |||
| * The configured type of transpose is applied. | |||
| * | |||
| * param base CRC peripheral address. | |||
| * param data Input data stream, MSByte in data[0]. | |||
| * param dataSize Size in bytes of the input data buffer. | |||
| */ | |||
| void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize) | |||
| { | |||
| const uint32_t *data32; | |||
| /* 8-bit reads and writes till source address is aligned 4 bytes */ | |||
| while ((dataSize) && ((uint32_t)data & 3U)) | |||
| { | |||
| base->ACCESS8BIT.DATALL = *data; | |||
| data++; | |||
| dataSize--; | |||
| } | |||
| /* use 32-bit reads and writes as long as possible */ | |||
| data32 = (const uint32_t *)data; | |||
| while (dataSize >= sizeof(uint32_t)) | |||
| { | |||
| base->DATA = *data32; | |||
| data32++; | |||
| dataSize -= sizeof(uint32_t); | |||
| } | |||
| data = (const uint8_t *)data32; | |||
| /* 8-bit reads and writes till end of data buffer */ | |||
| while (dataSize != 0U) | |||
| { | |||
| base->ACCESS8BIT.DATALL = *data; | |||
| data++; | |||
| dataSize--; | |||
| } | |||
| } | |||
| /*! | |||
| * brief Reads the 32-bit checksum from the CRC module. | |||
| * | |||
| * Reads the CRC data register (either an intermediate or the final checksum). | |||
| * The configured type of transpose and complement is applied. | |||
| * | |||
| * param base CRC peripheral address. | |||
| * return An intermediate or the final 32-bit checksum, after configured transpose and complement operations. | |||
| */ | |||
| uint32_t CRC_Get32bitResult(CRC_Type *base) | |||
| { | |||
| return base->DATA; | |||
| } | |||
| /*! | |||
| * brief Reads a 16-bit checksum from the CRC module. | |||
| * | |||
| * Reads the CRC data register (either an intermediate or the final checksum). | |||
| * The configured type of transpose and complement is applied. | |||
| * | |||
| * param base CRC peripheral address. | |||
| * return An intermediate or the final 16-bit checksum, after configured transpose and complement operations. | |||
| */ | |||
| uint16_t CRC_Get16bitResult(CRC_Type *base) | |||
| { | |||
| uint32_t retval; | |||
| uint32_t totr; /* type of transpose read bitfield */ | |||
| retval = base->DATA; | |||
| totr = (base->CTRL & CRC_CTRL_TOTR_MASK) >> CRC_CTRL_TOTR_SHIFT; | |||
| /* check transpose type to get 16-bit out of 32-bit register */ | |||
| if (totr >= 2U) | |||
| { | |||
| /* transpose of bytes for read is set, the result CRC is in CRC_DATA[HU:HL] */ | |||
| retval &= 0xFFFF0000U; | |||
| retval = retval >> 16U; | |||
| } | |||
| else | |||
| { | |||
| /* no transpose of bytes for read, the result CRC is in CRC_DATA[LU:LL] */ | |||
| retval &= 0x0000FFFFU; | |||
| } | |||
| return (uint16_t)retval; | |||
| } | |||
| @@ -0,0 +1,173 @@ | |||
| /* | |||
| * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_CRC_H_ | |||
| #define _FSL_CRC_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup crc | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief CRC driver version. Version 2.0.1. | |||
| * | |||
| * Current version: 2.0.1 | |||
| * | |||
| * Change log: | |||
| * - Version 2.0.1 | |||
| * - move DATA and DATALL macro definition from header file to source file | |||
| * - Version 2.0.2 | |||
| * - Fix MISRA issues | |||
| */ | |||
| #define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) | |||
| /*@}*/ | |||
| #ifndef CRC_DRIVER_CUSTOM_DEFAULTS | |||
| /*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */ | |||
| #define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1 | |||
| #endif | |||
| /*! @brief CRC bit width */ | |||
| typedef enum _crc_bits | |||
| { | |||
| kCrcBits16 = 0U, /*!< Generate 16-bit CRC code */ | |||
| kCrcBits32 = 1U /*!< Generate 32-bit CRC code */ | |||
| } crc_bits_t; | |||
| /*! @brief CRC result type */ | |||
| typedef enum _crc_result | |||
| { | |||
| kCrcFinalChecksum = 0U, /*!< CRC data register read value is the final checksum. | |||
| Reflect out and final xor protocol features are applied. */ | |||
| kCrcIntermediateChecksum = 1U /*!< CRC data register read value is intermediate checksum (raw value). | |||
| Reflect out and final xor protocol feature are not applied. | |||
| Intermediate checksum can be used as a seed for CRC_Init() | |||
| to continue adding data to this checksum. */ | |||
| } crc_result_t; | |||
| /*! | |||
| * @brief CRC protocol configuration. | |||
| * | |||
| * This structure holds the configuration for the CRC protocol. | |||
| * | |||
| */ | |||
| typedef struct _crc_config | |||
| { | |||
| uint32_t polynomial; /*!< CRC Polynomial, MSBit first. | |||
| Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */ | |||
| uint32_t seed; /*!< Starting checksum value */ | |||
| bool reflectIn; /*!< Reflect bits on input. */ | |||
| bool reflectOut; /*!< Reflect bits on output. */ | |||
| bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */ | |||
| crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */ | |||
| crc_result_t crcResult; /*!< Selects final or intermediate checksum return from CRC_Get16bitResult() or | |||
| CRC_Get32bitResult() */ | |||
| } crc_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @brief Enables and configures the CRC peripheral module. | |||
| * | |||
| * This function enables the clock gate in the SIM module for the CRC peripheral. | |||
| * It also configures the CRC module and starts a checksum computation by writing the seed. | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @param config CRC module configuration structure. | |||
| */ | |||
| void CRC_Init(CRC_Type *base, const crc_config_t *config); | |||
| /*! | |||
| * @brief Disables the CRC peripheral module. | |||
| * | |||
| * This function disables the clock gate in the SIM module for the CRC peripheral. | |||
| * | |||
| * @param base CRC peripheral address. | |||
| */ | |||
| static inline void CRC_Deinit(CRC_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* gate clock */ | |||
| CLOCK_DisableClock(kCLOCK_Crc0); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * @brief Loads default values to the CRC protocol configuration structure. | |||
| * | |||
| * Loads default values to the CRC protocol configuration structure. The default values are as follows. | |||
| * @code | |||
| * config->polynomial = 0x1021; | |||
| * config->seed = 0xFFFF; | |||
| * config->reflectIn = false; | |||
| * config->reflectOut = false; | |||
| * config->complementChecksum = false; | |||
| * config->crcBits = kCrcBits16; | |||
| * config->crcResult = kCrcFinalChecksum; | |||
| * @endcode | |||
| * | |||
| * @param config CRC protocol configuration structure. | |||
| */ | |||
| void CRC_GetDefaultConfig(crc_config_t *config); | |||
| /*! | |||
| * @brief Writes data to the CRC module. | |||
| * | |||
| * Writes input data buffer bytes to the CRC data register. | |||
| * The configured type of transpose is applied. | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @param data Input data stream, MSByte in data[0]. | |||
| * @param dataSize Size in bytes of the input data buffer. | |||
| */ | |||
| void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize); | |||
| /*! | |||
| * @brief Reads the 32-bit checksum from the CRC module. | |||
| * | |||
| * Reads the CRC data register (either an intermediate or the final checksum). | |||
| * The configured type of transpose and complement is applied. | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @return An intermediate or the final 32-bit checksum, after configured transpose and complement operations. | |||
| */ | |||
| uint32_t CRC_Get32bitResult(CRC_Type *base); | |||
| /*! | |||
| * @brief Reads a 16-bit checksum from the CRC module. | |||
| * | |||
| * Reads the CRC data register (either an intermediate or the final checksum). | |||
| * The configured type of transpose and complement is applied. | |||
| * | |||
| * @param base CRC peripheral address. | |||
| * @return An intermediate or the final 16-bit checksum, after configured transpose and complement operations. | |||
| */ | |||
| uint16_t CRC_Get16bitResult(CRC_Type *base); | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| *@} | |||
| */ | |||
| #endif /* _FSL_CRC_H_ */ | |||
| @@ -0,0 +1,300 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_dac.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.dac" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Get instance number for DAC module. | |||
| * | |||
| * @param base DAC peripheral base address | |||
| */ | |||
| static uint32_t DAC_GetInstance(DAC_Type *base); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Pointers to DAC bases for each instance. */ | |||
| static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Pointers to DAC clocks for each instance. */ | |||
| static const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Codes | |||
| ******************************************************************************/ | |||
| static uint32_t DAC_GetInstance(DAC_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_dacBases); instance++) | |||
| { | |||
| if (s_dacBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_dacBases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initializes the DAC module. | |||
| * | |||
| * This function initializes the DAC module including the following operations. | |||
| * - Enabling the clock for DAC module. | |||
| * - Configuring the DAC converter with a user configuration. | |||
| * - Enabling the DAC module. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param config Pointer to the configuration structure. See "dac_config_t". | |||
| */ | |||
| void DAC_Init(DAC_Type *base, const dac_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint8_t tmp8; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Enable the clock. */ | |||
| CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /* Configure. */ | |||
| /* DACx_C0. */ | |||
| tmp8 = base->C0 & (uint8_t)(~(DAC_C0_DACRFS_MASK | DAC_C0_LPEN_MASK)); | |||
| if (kDAC_ReferenceVoltageSourceVref2 == config->referenceVoltageSource) | |||
| { | |||
| tmp8 |= DAC_C0_DACRFS_MASK; | |||
| } | |||
| if (config->enableLowPowerMode) | |||
| { | |||
| tmp8 |= DAC_C0_LPEN_MASK; | |||
| } | |||
| base->C0 = tmp8; | |||
| /* DAC_Enable(base, true); */ | |||
| /* Tip: The DAC output can be enabled till then after user sets their own available data in application. */ | |||
| } | |||
| /*! | |||
| * brief De-initializes the DAC module. | |||
| * | |||
| * This function de-initializes the DAC module including the following operations. | |||
| * - Disabling the DAC module. | |||
| * - Disabling the clock for the DAC module. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| */ | |||
| void DAC_Deinit(DAC_Type *base) | |||
| { | |||
| DAC_Enable(base, false); | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Disable the clock. */ | |||
| CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Initializes the DAC user configuration structure. | |||
| * | |||
| * This function initializes the user configuration structure to a default value. The default values are as follows. | |||
| * code | |||
| * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; | |||
| * config->enableLowPowerMode = false; | |||
| * endcode | |||
| * param config Pointer to the configuration structure. See "dac_config_t". | |||
| */ | |||
| void DAC_GetDefaultConfig(dac_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; | |||
| config->enableLowPowerMode = false; | |||
| } | |||
| /*! | |||
| * brief Configures the CMP buffer. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param config Pointer to the configuration structure. See "dac_buffer_config_t". | |||
| */ | |||
| void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint8_t tmp8; | |||
| /* DACx_C0. */ | |||
| tmp8 = base->C0 & (uint8_t)(~DAC_C0_DACTRGSEL_MASK); | |||
| if (kDAC_BufferTriggerBySoftwareMode == config->triggerMode) | |||
| { | |||
| tmp8 |= DAC_C0_DACTRGSEL_MASK; | |||
| } | |||
| base->C0 = tmp8; | |||
| /* DACx_C1. */ | |||
| tmp8 = base->C1 & (uint8_t)(~( | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION | |||
| DAC_C1_DACBFWM_MASK | | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ | |||
| DAC_C1_DACBFMD_MASK)); | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION | |||
| tmp8 |= DAC_C1_DACBFWM(config->watermark); | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ | |||
| tmp8 |= DAC_C1_DACBFMD(config->workMode); | |||
| base->C1 = tmp8; | |||
| /* DACx_C2. */ | |||
| tmp8 = base->C2 & (uint8_t)(~DAC_C2_DACBFUP_MASK); | |||
| tmp8 |= DAC_C2_DACBFUP(config->upperLimit); | |||
| base->C2 = tmp8; | |||
| } | |||
| /*! | |||
| * brief Initializes the DAC buffer configuration structure. | |||
| * | |||
| * This function initializes the DAC buffer configuration structure to default values. The default values are as | |||
| * follows. | |||
| * code | |||
| * config->triggerMode = kDAC_BufferTriggerBySoftwareMode; | |||
| * config->watermark = kDAC_BufferWatermark1Word; | |||
| * config->workMode = kDAC_BufferWorkAsNormalMode; | |||
| * config->upperLimit = DAC_DATL_COUNT - 1U; | |||
| * endcode | |||
| * param config Pointer to the configuration structure. See "dac_buffer_config_t". | |||
| */ | |||
| void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->triggerMode = kDAC_BufferTriggerBySoftwareMode; | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION | |||
| config->watermark = kDAC_BufferWatermark1Word; | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ | |||
| config->workMode = kDAC_BufferWorkAsNormalMode; | |||
| config->upperLimit = DAC_DATL_COUNT - 1U; | |||
| } | |||
| /*! | |||
| * brief Sets the value for items in the buffer. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param index Setting the index for items in the buffer. The available index should not exceed the size of the DAC | |||
| * buffer. | |||
| * param value Setting the value for items in the buffer. 12-bits are available. | |||
| */ | |||
| void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value) | |||
| { | |||
| assert(index < DAC_DATL_COUNT); | |||
| base->DAT[index].DATL = (uint8_t)(0xFFU & value); /* Low 8-bit. */ | |||
| base->DAT[index].DATH = (uint8_t)((0xF00U & value) >> 8); /* High 4-bit. */ | |||
| } | |||
| /*! | |||
| * brief Sets the current read pointer of the DAC buffer. | |||
| * | |||
| * This function sets the current read pointer of the DAC buffer. | |||
| * The current output value depends on the item indexed by the read pointer. It is updated either by a | |||
| * software trigger or a hardware trigger. After the read pointer changes, the DAC output value also changes. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param index Setting an index value for the pointer. | |||
| */ | |||
| void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index) | |||
| { | |||
| assert(index < DAC_DATL_COUNT); | |||
| uint8_t tmp8 = base->C2 & (uint8_t)(~DAC_C2_DACBFRP_MASK); | |||
| tmp8 |= DAC_C2_DACBFRP(index); | |||
| base->C2 = tmp8; | |||
| } | |||
| /*! | |||
| * brief Enables interrupts for the DAC buffer. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". | |||
| */ | |||
| void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask) | |||
| { | |||
| mask &= ( | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION | |||
| DAC_C0_DACBWIEN_MASK | | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ | |||
| DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK); | |||
| base->C0 |= ((uint8_t)mask); /* Write 1 to enable. */ | |||
| } | |||
| /*! | |||
| * brief Disables interrupts for the DAC buffer. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". | |||
| */ | |||
| void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask) | |||
| { | |||
| mask &= ( | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION | |||
| DAC_C0_DACBWIEN_MASK | | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ | |||
| DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK); | |||
| base->C0 &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to disable. */ | |||
| } | |||
| /*! | |||
| * brief Gets the flags of events for the DAC buffer. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * | |||
| * return Mask value for the asserted flags. See "_dac_buffer_status_flags". | |||
| */ | |||
| uint8_t DAC_GetBufferStatusFlags(DAC_Type *base) | |||
| { | |||
| return base->SR & ( | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION | |||
| DAC_SR_DACBFWMF_MASK | | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ | |||
| DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK); | |||
| } | |||
| /*! | |||
| * brief Clears the flags of events for the DAC buffer. | |||
| * | |||
| * param base DAC peripheral base address. | |||
| * param mask Mask value for flags. See "_dac_buffer_status_flags_t". | |||
| */ | |||
| void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask) | |||
| { | |||
| mask &= ( | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION | |||
| DAC_SR_DACBFWMF_MASK | | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ | |||
| DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK); | |||
| base->SR &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to clear flags. */ | |||
| } | |||
| @@ -0,0 +1,357 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_DAC_H_ | |||
| #define _FSL_DAC_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup dac | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief DAC driver version 2.0.2. */ | |||
| #define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) | |||
| /*@}*/ | |||
| /*! | |||
| * @brief DAC buffer flags. | |||
| */ | |||
| enum _dac_buffer_status_flags | |||
| { | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION | |||
| kDAC_BufferWatermarkFlag = DAC_SR_DACBFWMF_MASK, /*!< DAC Buffer Watermark Flag. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ | |||
| kDAC_BufferReadPointerTopPositionFlag = DAC_SR_DACBFRPTF_MASK, /*!< DAC Buffer Read Pointer Top Position Flag. */ | |||
| kDAC_BufferReadPointerBottomPositionFlag = DAC_SR_DACBFRPBF_MASK, /*!< DAC Buffer Read Pointer Bottom Position | |||
| Flag. */ | |||
| }; | |||
| /*! | |||
| * @brief DAC buffer interrupts. | |||
| */ | |||
| enum _dac_buffer_interrupt_enable | |||
| { | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION | |||
| kDAC_BufferWatermarkInterruptEnable = DAC_C0_DACBWIEN_MASK, /*!< DAC Buffer Watermark Interrupt Enable. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */ | |||
| kDAC_BufferReadPointerTopInterruptEnable = DAC_C0_DACBTIEN_MASK, /*!< DAC Buffer Read Pointer Top Flag Interrupt | |||
| Enable. */ | |||
| kDAC_BufferReadPointerBottomInterruptEnable = DAC_C0_DACBBIEN_MASK, /*!< DAC Buffer Read Pointer Bottom Flag | |||
| Interrupt Enable */ | |||
| }; | |||
| /*! | |||
| * @brief DAC reference voltage source. | |||
| */ | |||
| typedef enum _dac_reference_voltage_source | |||
| { | |||
| kDAC_ReferenceVoltageSourceVref1 = 0U, /*!< The DAC selects DACREF_1 as the reference voltage. */ | |||
| kDAC_ReferenceVoltageSourceVref2 = 1U, /*!< The DAC selects DACREF_2 as the reference voltage. */ | |||
| } dac_reference_voltage_source_t; | |||
| /*! | |||
| * @brief DAC buffer trigger mode. | |||
| */ | |||
| typedef enum _dac_buffer_trigger_mode | |||
| { | |||
| kDAC_BufferTriggerByHardwareMode = 0U, /*!< The DAC hardware trigger is selected. */ | |||
| kDAC_BufferTriggerBySoftwareMode = 1U, /*!< The DAC software trigger is selected. */ | |||
| } dac_buffer_trigger_mode_t; | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION | |||
| /*! | |||
| * @brief DAC buffer watermark. | |||
| */ | |||
| typedef enum _dac_buffer_watermark | |||
| { | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD | |||
| kDAC_BufferWatermark1Word = 0U, /*!< 1 word away from the upper limit. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */ | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS | |||
| kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS */ | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS | |||
| kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS */ | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS | |||
| kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS */ | |||
| } dac_buffer_watermark_t; | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ | |||
| /*! | |||
| * @brief DAC buffer work mode. | |||
| */ | |||
| typedef enum _dac_buffer_work_mode | |||
| { | |||
| kDAC_BufferWorkAsNormalMode = 0U, /*!< Normal mode. */ | |||
| #if defined(FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE | |||
| kDAC_BufferWorkAsSwingMode, /*!< Swing mode. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE */ | |||
| kDAC_BufferWorkAsOneTimeScanMode, /*!< One-Time Scan mode. */ | |||
| #if defined(FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE) && FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE | |||
| kDAC_BufferWorkAsFIFOMode, /*!< FIFO mode. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE */ | |||
| } dac_buffer_work_mode_t; | |||
| /*! | |||
| * @brief DAC module configuration. | |||
| */ | |||
| typedef struct _dac_config | |||
| { | |||
| dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */ | |||
| bool enableLowPowerMode; /*!< Enable the low-power mode. */ | |||
| } dac_config_t; | |||
| /*! | |||
| * @brief DAC buffer configuration. | |||
| */ | |||
| typedef struct _dac_buffer_config | |||
| { | |||
| dac_buffer_trigger_mode_t triggerMode; /*!< Select the buffer's trigger mode. */ | |||
| #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION | |||
| dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */ | |||
| #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ | |||
| dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */ | |||
| uint8_t upperLimit; /*!< Set the upper limit for the buffer index. | |||
| Normally, 0-15 is available for a buffer with 16 items. */ | |||
| } dac_buffer_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the DAC module. | |||
| * | |||
| * This function initializes the DAC module including the following operations. | |||
| * - Enabling the clock for DAC module. | |||
| * - Configuring the DAC converter with a user configuration. | |||
| * - Enabling the DAC module. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param config Pointer to the configuration structure. See "dac_config_t". | |||
| */ | |||
| void DAC_Init(DAC_Type *base, const dac_config_t *config); | |||
| /*! | |||
| * @brief De-initializes the DAC module. | |||
| * | |||
| * This function de-initializes the DAC module including the following operations. | |||
| * - Disabling the DAC module. | |||
| * - Disabling the clock for the DAC module. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| */ | |||
| void DAC_Deinit(DAC_Type *base); | |||
| /*! | |||
| * @brief Initializes the DAC user configuration structure. | |||
| * | |||
| * This function initializes the user configuration structure to a default value. The default values are as follows. | |||
| * @code | |||
| * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; | |||
| * config->enableLowPowerMode = false; | |||
| * @endcode | |||
| * @param config Pointer to the configuration structure. See "dac_config_t". | |||
| */ | |||
| void DAC_GetDefaultConfig(dac_config_t *config); | |||
| /*! | |||
| * @brief Enables the DAC module. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param enable Enables or disables the feature. | |||
| */ | |||
| static inline void DAC_Enable(DAC_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->C0 |= (uint8_t)DAC_C0_DACEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->C0 &= (uint8_t)(~DAC_C0_DACEN_MASK); | |||
| } | |||
| } | |||
| /* @} */ | |||
| /*! | |||
| * @name Buffer | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enables the DAC buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param enable Enables or disables the feature. | |||
| */ | |||
| static inline void DAC_EnableBuffer(DAC_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->C1 |= (uint8_t)DAC_C1_DACBFEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->C1 &= (uint8_t)(~DAC_C1_DACBFEN_MASK); | |||
| } | |||
| } | |||
| /*! | |||
| * @brief Configures the CMP buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param config Pointer to the configuration structure. See "dac_buffer_config_t". | |||
| */ | |||
| void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config); | |||
| /*! | |||
| * @brief Initializes the DAC buffer configuration structure. | |||
| * | |||
| * This function initializes the DAC buffer configuration structure to default values. The default values are as | |||
| * follows. | |||
| * @code | |||
| * config->triggerMode = kDAC_BufferTriggerBySoftwareMode; | |||
| * config->watermark = kDAC_BufferWatermark1Word; | |||
| * config->workMode = kDAC_BufferWorkAsNormalMode; | |||
| * config->upperLimit = DAC_DATL_COUNT - 1U; | |||
| * @endcode | |||
| * @param config Pointer to the configuration structure. See "dac_buffer_config_t". | |||
| */ | |||
| void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config); | |||
| /*! | |||
| * @brief Enables the DMA for DAC buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param enable Enables or disables the feature. | |||
| */ | |||
| static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->C1 |= (uint8_t)DAC_C1_DMAEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->C1 &= (uint8_t)(~DAC_C1_DMAEN_MASK); | |||
| } | |||
| } | |||
| /*! | |||
| * @brief Sets the value for items in the buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param index Setting the index for items in the buffer. The available index should not exceed the size of the DAC | |||
| * buffer. | |||
| * @param value Setting the value for items in the buffer. 12-bits are available. | |||
| */ | |||
| void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value); | |||
| /*! | |||
| * @brief Triggers the buffer using software and updates the read pointer of the DAC buffer. | |||
| * | |||
| * This function triggers the function using software. The read pointer of the DAC buffer is updated with one step | |||
| * after this function is called. Changing the read pointer depends on the buffer's work mode. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| */ | |||
| static inline void DAC_DoSoftwareTriggerBuffer(DAC_Type *base) | |||
| { | |||
| base->C0 |= DAC_C0_DACSWTRG_MASK; | |||
| } | |||
| /*! | |||
| * @brief Gets the current read pointer of the DAC buffer. | |||
| * | |||
| * This function gets the current read pointer of the DAC buffer. | |||
| * The current output value depends on the item indexed by the read pointer. It is updated either | |||
| * by a software trigger or a hardware trigger. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * | |||
| * @return The current read pointer of the DAC buffer. | |||
| */ | |||
| static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base) | |||
| { | |||
| return ((base->C2 & DAC_C2_DACBFRP_MASK) >> DAC_C2_DACBFRP_SHIFT); | |||
| } | |||
| /*! | |||
| * @brief Sets the current read pointer of the DAC buffer. | |||
| * | |||
| * This function sets the current read pointer of the DAC buffer. | |||
| * The current output value depends on the item indexed by the read pointer. It is updated either by a | |||
| * software trigger or a hardware trigger. After the read pointer changes, the DAC output value also changes. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param index Setting an index value for the pointer. | |||
| */ | |||
| void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index); | |||
| /*! | |||
| * @brief Enables interrupts for the DAC buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". | |||
| */ | |||
| void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Disables interrupts for the DAC buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable". | |||
| */ | |||
| void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Gets the flags of events for the DAC buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * | |||
| * @return Mask value for the asserted flags. See "_dac_buffer_status_flags". | |||
| */ | |||
| uint8_t DAC_GetBufferStatusFlags(DAC_Type *base); | |||
| /*! | |||
| * @brief Clears the flags of events for the DAC buffer. | |||
| * | |||
| * @param base DAC peripheral base address. | |||
| * @param mask Mask value for flags. See "_dac_buffer_status_flags_t". | |||
| */ | |||
| void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask); | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| * @} | |||
| */ | |||
| #endif /* _FSL_DAC_H_ */ | |||
| @@ -0,0 +1,91 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_dmamux.h" | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.dmamux" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Get instance number for DMAMUX. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| */ | |||
| static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Array to map DMAMUX instance number to base pointer. */ | |||
| static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Array to map DMAMUX instance number to clock name. */ | |||
| static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++) | |||
| { | |||
| if (s_dmamuxBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_dmamuxBases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initializes the DMAMUX peripheral. | |||
| * | |||
| * This function ungates the DMAMUX clock. | |||
| * | |||
| * param base DMAMUX peripheral base address. | |||
| * | |||
| */ | |||
| void DMAMUX_Init(DMAMUX_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Deinitializes the DMAMUX peripheral. | |||
| * | |||
| * This function gates the DMAMUX clock. | |||
| * | |||
| * param base DMAMUX peripheral base address. | |||
| */ | |||
| void DMAMUX_Deinit(DMAMUX_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| @@ -0,0 +1,177 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_DMAMUX_H_ | |||
| #define _FSL_DMAMUX_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup dmamux | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief DMAMUX driver version 2.0.4. */ | |||
| #define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 4)) | |||
| /*@}*/ | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /* __cplusplus */ | |||
| /*! | |||
| * @name DMAMUX Initialization and de-initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the DMAMUX peripheral. | |||
| * | |||
| * This function ungates the DMAMUX clock. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| * | |||
| */ | |||
| void DMAMUX_Init(DMAMUX_Type *base); | |||
| /*! | |||
| * @brief Deinitializes the DMAMUX peripheral. | |||
| * | |||
| * This function gates the DMAMUX clock. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| */ | |||
| void DMAMUX_Deinit(DMAMUX_Type *base); | |||
| /* @} */ | |||
| /*! | |||
| * @name DMAMUX Channel Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enables the DMAMUX channel. | |||
| * | |||
| * This function enables the DMAMUX channel. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| * @param channel DMAMUX channel number. | |||
| */ | |||
| static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; | |||
| } | |||
| /*! | |||
| * @brief Disables the DMAMUX channel. | |||
| * | |||
| * This function disables the DMAMUX channel. | |||
| * | |||
| * @note The user must disable the DMAMUX channel before configuring it. | |||
| * @param base DMAMUX peripheral base address. | |||
| * @param channel DMAMUX channel number. | |||
| */ | |||
| static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->CHCFG[channel] &= ~(uint8_t)DMAMUX_CHCFG_ENBL_MASK; | |||
| } | |||
| /*! | |||
| * @brief Configures the DMAMUX channel source. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| * @param channel DMAMUX channel number. | |||
| * @param source Channel source, which is used to trigger the DMA transfer. | |||
| */ | |||
| static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->CHCFG[channel] = (uint8_t)((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source)); | |||
| } | |||
| #if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U | |||
| /*! | |||
| * @brief Enables the DMAMUX period trigger. | |||
| * | |||
| * This function enables the DMAMUX period trigger feature. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| * @param channel DMAMUX channel number. | |||
| */ | |||
| static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK; | |||
| } | |||
| /*! | |||
| * @brief Disables the DMAMUX period trigger. | |||
| * | |||
| * This function disables the DMAMUX period trigger. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| * @param channel DMAMUX channel number. | |||
| */ | |||
| static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->CHCFG[channel] &= ~(uint8_t)DMAMUX_CHCFG_TRIG_MASK; | |||
| } | |||
| #endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */ | |||
| #if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON) | |||
| /*! | |||
| * @brief Enables the DMA channel to be always ON. | |||
| * | |||
| * This function enables the DMAMUX channel always ON feature. | |||
| * | |||
| * @param base DMAMUX peripheral base address. | |||
| * @param channel DMAMUX channel number. | |||
| * @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled. | |||
| */ | |||
| static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| if (enable) | |||
| { | |||
| base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK; | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */ | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /* __cplusplus */ | |||
| /* @} */ | |||
| #endif /* _FSL_DMAMUX_H_ */ | |||
| @@ -0,0 +1,296 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_DSPI_EDMA_H_ | |||
| #define _FSL_DSPI_EDMA_H_ | |||
| #include "fsl_dspi.h" | |||
| #include "fsl_edma.h" | |||
| /*! | |||
| * @addtogroup dspi_edma_driver | |||
| * @{ | |||
| */ | |||
| /*********************************************************************************************************************** | |||
| * Definitions | |||
| **********************************************************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief DSPI EDMA driver version 2.2.4 */ | |||
| #define FSL_DSPI_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 4)) | |||
| /*@}*/ | |||
| /*! @brief DSPI EDMA max transfer data size calculate | |||
| * @param base DSPI peripheral base address. | |||
| * @param width Transfer width | |||
| */ | |||
| #define DSPI_EDMA_MAX_TRANSFER_SIZE(base, width) \ | |||
| ((1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) ? ((width > 8U) ? 65534U : 32767U) : \ | |||
| ((width > 8U) ? 1022U : 511U)) | |||
| /*! | |||
| * @brief Forward declaration of the DSPI eDMA master handle typedefs. | |||
| */ | |||
| typedef struct _dspi_master_edma_handle dspi_master_edma_handle_t; | |||
| /*! | |||
| * @brief Forward declaration of the DSPI eDMA slave handle typedefs. | |||
| */ | |||
| typedef struct _dspi_slave_edma_handle dspi_slave_edma_handle_t; | |||
| /*! | |||
| * @brief Completion callback function pointer type. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the handle for the DSPI master. | |||
| * @param status Success or error code describing whether the transfer completed. | |||
| * @param userData An arbitrary pointer-dataSized value passed from the application. | |||
| */ | |||
| typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base, | |||
| dspi_master_edma_handle_t *handle, | |||
| status_t status, | |||
| void *userData); | |||
| /*! | |||
| * @brief Completion callback function pointer type. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the handle for the DSPI slave. | |||
| * @param status Success or error code describing whether the transfer completed. | |||
| * @param userData An arbitrary pointer-dataSized value passed from the application. | |||
| */ | |||
| typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base, | |||
| dspi_slave_edma_handle_t *handle, | |||
| status_t status, | |||
| void *userData); | |||
| /*! @brief DSPI master eDMA transfer handle structure used for the transactional API. */ | |||
| struct _dspi_master_edma_handle | |||
| { | |||
| uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ | |||
| volatile uint32_t command; /*!< The desired data command. */ | |||
| volatile uint32_t lastCommand; /*!< The desired last data command. */ | |||
| uint8_t fifoSize; /*!< FIFO dataSize. */ | |||
| volatile bool | |||
| isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/ | |||
| uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ | |||
| volatile uint8_t state; /*!< DSPI transfer state, see @ref _dspi_transfer_state.*/ | |||
| uint8_t *volatile txData; /*!< Send buffer. */ | |||
| uint8_t *volatile rxData; /*!< Receive buffer. */ | |||
| volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ | |||
| volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ | |||
| size_t totalByteCount; /*!< A number of transfer bytes*/ | |||
| uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/ | |||
| uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/ | |||
| dspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */ | |||
| void *userData; /*!< Callback user data. */ | |||
| edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/ | |||
| edma_handle_t *edmaTxDataToIntermediaryHandle; /*!<edma_handle_t handle point used for TxData to Intermediary*/ | |||
| edma_handle_t *edmaIntermediaryToTxRegHandle; /*!<edma_handle_t handle point used for Intermediary to TxReg*/ | |||
| edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/ | |||
| }; | |||
| /*! @brief DSPI slave eDMA transfer handle structure used for the transactional API.*/ | |||
| struct _dspi_slave_edma_handle | |||
| { | |||
| uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ | |||
| uint8_t *volatile txData; /*!< Send buffer. */ | |||
| uint8_t *volatile rxData; /*!< Receive buffer. */ | |||
| volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ | |||
| volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ | |||
| size_t totalByteCount; /*!< A number of transfer bytes*/ | |||
| uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/ | |||
| uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/ | |||
| uint32_t txLastData; /*!< Used if there is an extra byte when 16bits per frame for DMA purpose.*/ | |||
| uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ | |||
| volatile uint8_t state; /*!< DSPI transfer state.*/ | |||
| dspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */ | |||
| void *userData; /*!< Callback user data. */ | |||
| edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/ | |||
| edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/ | |||
| }; | |||
| /*********************************************************************************************************************** | |||
| * API | |||
| **********************************************************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /*_cplusplus*/ | |||
| /*! @name Transactional APIs*/ | |||
| /*! | |||
| * @brief Initializes the DSPI master eDMA handle. | |||
| * | |||
| * This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a | |||
| * specified DSPI instance, call this API once to get the initialized handle. | |||
| * | |||
| * @note DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request | |||
| * source. | |||
| * - For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and | |||
| * TX DMAMUX source for edmaIntermediaryToTxRegHandle. | |||
| * - For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle DSPI handle pointer to @ref _dspi_master_edma_handle. | |||
| * @param callback DSPI callback. | |||
| * @param userData A callback function parameter. | |||
| * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t. | |||
| * @param edmaTxDataToIntermediaryHandle edmaTxDataToIntermediaryHandle pointer to edma_handle_t. | |||
| * @param edmaIntermediaryToTxRegHandle edmaIntermediaryToTxRegHandle pointer to edma_handle_t. | |||
| */ | |||
| void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base, | |||
| dspi_master_edma_handle_t *handle, | |||
| dspi_master_edma_transfer_callback_t callback, | |||
| void *userData, | |||
| edma_handle_t *edmaRxRegToRxDataHandle, | |||
| edma_handle_t *edmaTxDataToIntermediaryHandle, | |||
| edma_handle_t *edmaIntermediaryToTxRegHandle); | |||
| /*! | |||
| * @brief DSPI master transfer data using eDMA. | |||
| * | |||
| * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data | |||
| * is transferred, the callback function is called. | |||
| * | |||
| * @note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If | |||
| * <b>FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x)</b> is true, then the max transfer size is 32767 datawidth of data, | |||
| * otherwise is 511. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state. | |||
| * @param transfer A pointer to the @ref dspi_transfer_t structure. | |||
| * @return status of status_t. | |||
| */ | |||
| status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer); | |||
| /*! | |||
| * @brief Transfers a block of data using a eDMA method. | |||
| * | |||
| * This function transfers data using eDNA, the transfer mechanism is half-duplex. This is a non-blocking function, | |||
| * which returns right away. When all data is transferred, the callback function is called. | |||
| * | |||
| * @param base DSPI base pointer | |||
| * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state. | |||
| * @param xfer A pointer to the @ref dspi_half_duplex_transfer_t structure. | |||
| * @return status of status_t. | |||
| */ | |||
| status_t DSPI_MasterHalfDuplexTransferEDMA(SPI_Type *base, | |||
| dspi_master_edma_handle_t *handle, | |||
| dspi_half_duplex_transfer_t *xfer); | |||
| /*! | |||
| * @brief DSPI master aborts a transfer which is using eDMA. | |||
| * | |||
| * This function aborts a transfer which is using eDMA. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state. | |||
| */ | |||
| void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle); | |||
| /*! | |||
| * @brief Gets the master eDMA transfer count. | |||
| * | |||
| * This function gets the master eDMA transfer count. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state. | |||
| * @param count A number of bytes transferred by the non-blocking transaction. | |||
| * @return status of status_t. | |||
| */ | |||
| status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count); | |||
| /*! | |||
| * @brief Initializes the DSPI slave eDMA handle. | |||
| * | |||
| * This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a | |||
| * specified DSPI instance, call this API once to get the initialized handle. | |||
| * | |||
| * @note DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request | |||
| * source. | |||
| * - For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and | |||
| * TX DMAMUX source for edmaTxDataToTxRegHandle. | |||
| * - For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle DSPI handle pointer to @ref _dspi_slave_edma_handle. | |||
| * @param callback DSPI callback. | |||
| * @param userData A callback function parameter. | |||
| * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t. | |||
| * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t. | |||
| */ | |||
| void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base, | |||
| dspi_slave_edma_handle_t *handle, | |||
| dspi_slave_edma_transfer_callback_t callback, | |||
| void *userData, | |||
| edma_handle_t *edmaRxRegToRxDataHandle, | |||
| edma_handle_t *edmaTxDataToTxRegHandle); | |||
| /*! | |||
| * @brief DSPI slave transfer data using eDMA. | |||
| * | |||
| * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data | |||
| * is transferred, the callback function is called. | |||
| * Note that the slave eDMA transfer doesn't support transfer_size is 1 when the bitsPerFrame is greater | |||
| * than eight. | |||
| * | |||
| * @note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If | |||
| * <b>FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x)</b> is true, then the max transfer size is 32767 datawidth of data, | |||
| * otherwise is 511. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state. | |||
| * @param transfer A pointer to the @ref dspi_transfer_t structure. | |||
| * @return status of status_t. | |||
| */ | |||
| status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer); | |||
| /*! | |||
| * @brief DSPI slave aborts a transfer which is using eDMA. | |||
| * | |||
| * This function aborts a transfer which is using eDMA. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state. | |||
| */ | |||
| void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle); | |||
| /*! | |||
| * @brief Gets the slave eDMA transfer count. | |||
| * | |||
| * This function gets the slave eDMA transfer count. | |||
| * | |||
| * @param base DSPI peripheral base address. | |||
| * @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state. | |||
| * @param count A number of bytes transferred so far by the non-blocking transaction. | |||
| * @return status of status_t. | |||
| */ | |||
| status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count); | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /*_cplusplus*/ | |||
| /*! | |||
| *@} | |||
| */ | |||
| #endif /*_FSL_DSPI_EDMA_H_*/ | |||
| @@ -0,0 +1,134 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_dspi_freertos.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.dspi_freertos" | |||
| #endif | |||
| static void DSPI_RTOS_Callback(SPI_Type *base, dspi_master_handle_t *drv_handle, status_t status, void *userData) | |||
| { | |||
| dspi_rtos_handle_t *handle = (dspi_rtos_handle_t *)userData; | |||
| BaseType_t reschedule; | |||
| handle->async_status = status; | |||
| xSemaphoreGiveFromISR(handle->event, &reschedule); | |||
| portYIELD_FROM_ISR(reschedule); | |||
| } | |||
| /*! | |||
| * brief Initializes the DSPI. | |||
| * | |||
| * This function initializes the DSPI module and the related RTOS context. | |||
| * | |||
| * param handle The RTOS DSPI handle, the pointer to an allocated space for RTOS context. | |||
| * param base The pointer base address of the DSPI instance to initialize. | |||
| * param masterConfig A configuration structure to set-up the DSPI in master mode. | |||
| * param srcClock_Hz A frequency of the input clock of the DSPI module. | |||
| * return status of the operation. | |||
| */ | |||
| status_t DSPI_RTOS_Init(dspi_rtos_handle_t *handle, | |||
| SPI_Type *base, | |||
| const dspi_master_config_t *masterConfig, | |||
| uint32_t srcClock_Hz) | |||
| { | |||
| if (handle == NULL) | |||
| { | |||
| return kStatus_InvalidArgument; | |||
| } | |||
| if (base == NULL) | |||
| { | |||
| return kStatus_InvalidArgument; | |||
| } | |||
| memset(handle, 0, sizeof(dspi_rtos_handle_t)); | |||
| #if (configSUPPORT_STATIC_ALLOCATION == 1) | |||
| handle->mutex = xSemaphoreCreateMutexStatic(&handle->mutexBuffer); | |||
| #else | |||
| handle->mutex = xSemaphoreCreateMutex(); | |||
| #endif | |||
| if (handle->mutex == NULL) | |||
| { | |||
| return kStatus_Fail; | |||
| } | |||
| #if (configSUPPORT_STATIC_ALLOCATION == 1) | |||
| handle->event = xSemaphoreCreateBinaryStatic(&handle->semaphoreBuffer); | |||
| #else | |||
| handle->event = xSemaphoreCreateBinary(); | |||
| #endif | |||
| if (handle->event == NULL) | |||
| { | |||
| vSemaphoreDelete(handle->mutex); | |||
| return kStatus_Fail; | |||
| } | |||
| handle->base = base; | |||
| DSPI_MasterInit(handle->base, masterConfig, srcClock_Hz); | |||
| DSPI_MasterTransferCreateHandle(handle->base, &handle->drv_handle, DSPI_RTOS_Callback, (void *)handle); | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * brief Deinitializes the DSPI. | |||
| * | |||
| * This function deinitializes the DSPI module and the related RTOS context. | |||
| * | |||
| * param handle The RTOS DSPI handle. | |||
| */ | |||
| status_t DSPI_RTOS_Deinit(dspi_rtos_handle_t *handle) | |||
| { | |||
| DSPI_Deinit(handle->base); | |||
| vSemaphoreDelete(handle->event); | |||
| vSemaphoreDelete(handle->mutex); | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * brief Performs the SPI transfer. | |||
| * | |||
| * This function performs the SPI transfer according to the data given in the transfer structure. | |||
| * | |||
| * param handle The RTOS DSPI handle. | |||
| * param transfer A structure specifying the transfer parameters. | |||
| * return status of the operation. | |||
| */ | |||
| status_t DSPI_RTOS_Transfer(dspi_rtos_handle_t *handle, dspi_transfer_t *transfer) | |||
| { | |||
| status_t status; | |||
| /* Lock resource mutex */ | |||
| if (xSemaphoreTake(handle->mutex, portMAX_DELAY) != pdTRUE) | |||
| { | |||
| return kStatus_DSPI_Busy; | |||
| } | |||
| status = DSPI_MasterTransferNonBlocking(handle->base, &handle->drv_handle, transfer); | |||
| if (status != kStatus_Success) | |||
| { | |||
| xSemaphoreGive(handle->mutex); | |||
| return status; | |||
| } | |||
| /* Wait for transfer to finish */ | |||
| if (xSemaphoreTake(handle->event, portMAX_DELAY) != pdTRUE) | |||
| { | |||
| return kStatus_DSPI_Error; | |||
| } | |||
| /* Unlock resource mutex */ | |||
| xSemaphoreGive(handle->mutex); | |||
| /* Return status captured by callback function */ | |||
| return handle->async_status; | |||
| } | |||
| @@ -0,0 +1,111 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef __FSL_DSPI_FREERTOS_H__ | |||
| #define __FSL_DSPI_FREERTOS_H__ | |||
| #include "FreeRTOS.h" | |||
| #include "portable.h" | |||
| #include "semphr.h" | |||
| #include "fsl_dspi.h" | |||
| /*! | |||
| * @addtogroup dspi_freertos_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief DSPI FreeRTOS driver version 2.2.4. */ | |||
| #define FSL_DSPI_FREERTOS_DRIVER_VERSION (MAKE_VERSION(2, 2, 4)) | |||
| /*@}*/ | |||
| /*! | |||
| * @cond RTOS_PRIVATE | |||
| * @brief DSPI FreeRTOS handle | |||
| */ | |||
| typedef struct _dspi_rtos_handle | |||
| { | |||
| SPI_Type *base; /*!< DSPI base address */ | |||
| dspi_master_handle_t drv_handle; /*!< Handle of the underlying driver, treated as opaque by the RTOS layer */ | |||
| status_t async_status; /*!< Transactional state of the underlying driver */ | |||
| SemaphoreHandle_t mutex; /*!< Mutex to lock the handle during a transfer */ | |||
| SemaphoreHandle_t event; /*!< Semaphore to notify and unblock a task when a transfer ends */ | |||
| #if (configSUPPORT_STATIC_ALLOCATION == 1) | |||
| StaticSemaphore_t mutexBuffer; /*!< Statically allocated memory for mutex */ | |||
| StaticSemaphore_t semaphoreBuffer; /*!< Statically allocated memory for event */ | |||
| #endif | |||
| } dspi_rtos_handle_t; | |||
| /*! \endcond */ | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name DSPI RTOS Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the DSPI. | |||
| * | |||
| * This function initializes the DSPI module and the related RTOS context. | |||
| * | |||
| * @param handle The RTOS DSPI handle, the pointer to an allocated space for RTOS context. | |||
| * @param base The pointer base address of the DSPI instance to initialize. | |||
| * @param masterConfig A configuration structure to set-up the DSPI in master mode. | |||
| * @param srcClock_Hz A frequency of the input clock of the DSPI module. | |||
| * @return status of the operation. | |||
| */ | |||
| status_t DSPI_RTOS_Init(dspi_rtos_handle_t *handle, | |||
| SPI_Type *base, | |||
| const dspi_master_config_t *masterConfig, | |||
| uint32_t srcClock_Hz); | |||
| /*! | |||
| * @brief Deinitializes the DSPI. | |||
| * | |||
| * This function deinitializes the DSPI module and the related RTOS context. | |||
| * | |||
| * @param handle The RTOS DSPI handle. | |||
| */ | |||
| status_t DSPI_RTOS_Deinit(dspi_rtos_handle_t *handle); | |||
| /*! | |||
| * @brief Performs the SPI transfer. | |||
| * | |||
| * This function performs the SPI transfer according to the data given in the transfer structure. | |||
| * | |||
| * @param handle The RTOS DSPI handle. | |||
| * @param transfer A structure specifying the transfer parameters. | |||
| * @return status of the operation. | |||
| */ | |||
| status_t DSPI_RTOS_Transfer(dspi_rtos_handle_t *handle, dspi_transfer_t *transfer); | |||
| /*! | |||
| * @} | |||
| */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| * @} | |||
| */ | |||
| #endif /* __FSL_DSPI_FREERTOS_H__ */ | |||
| @@ -0,0 +1,951 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_EDMA_H_ | |||
| #define _FSL_EDMA_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup edma | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief eDMA driver version */ | |||
| #define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 3, 2)) /*!< Version 2.3.2. */ | |||
| /*@}*/ | |||
| /*! @brief Compute the offset unit from DCHPRI3 */ | |||
| #define DMA_DCHPRI_INDEX(channel) (((channel) & ~0x03U) | (3U - ((channel)&0x03U))) | |||
| /*! @brief eDMA transfer configuration */ | |||
| typedef enum _edma_transfer_size | |||
| { | |||
| kEDMA_TransferSize1Bytes = 0x0U, /*!< Source/Destination data transfer size is 1 byte every time */ | |||
| kEDMA_TransferSize2Bytes = 0x1U, /*!< Source/Destination data transfer size is 2 bytes every time */ | |||
| kEDMA_TransferSize4Bytes = 0x2U, /*!< Source/Destination data transfer size is 4 bytes every time */ | |||
| kEDMA_TransferSize8Bytes = 0x3U, /*!< Source/Destination data transfer size is 8 bytes every time */ | |||
| kEDMA_TransferSize16Bytes = 0x4U, /*!< Source/Destination data transfer size is 16 bytes every time */ | |||
| kEDMA_TransferSize32Bytes = 0x5U, /*!< Source/Destination data transfer size is 32 bytes every time */ | |||
| } edma_transfer_size_t; | |||
| /*! @brief eDMA modulo configuration */ | |||
| typedef enum _edma_modulo | |||
| { | |||
| kEDMA_ModuloDisable = 0x0U, /*!< Disable modulo */ | |||
| kEDMA_Modulo2bytes, /*!< Circular buffer size is 2 bytes. */ | |||
| kEDMA_Modulo4bytes, /*!< Circular buffer size is 4 bytes. */ | |||
| kEDMA_Modulo8bytes, /*!< Circular buffer size is 8 bytes. */ | |||
| kEDMA_Modulo16bytes, /*!< Circular buffer size is 16 bytes. */ | |||
| kEDMA_Modulo32bytes, /*!< Circular buffer size is 32 bytes. */ | |||
| kEDMA_Modulo64bytes, /*!< Circular buffer size is 64 bytes. */ | |||
| kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ | |||
| kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ | |||
| kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ | |||
| kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ | |||
| kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ | |||
| kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ | |||
| kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ | |||
| kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ | |||
| kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ | |||
| kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ | |||
| kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ | |||
| kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ | |||
| kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ | |||
| kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ | |||
| kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ | |||
| kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ | |||
| kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ | |||
| kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ | |||
| kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ | |||
| kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ | |||
| kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ | |||
| kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ | |||
| kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ | |||
| kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ | |||
| kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ | |||
| } edma_modulo_t; | |||
| /*! @brief Bandwidth control */ | |||
| typedef enum _edma_bandwidth | |||
| { | |||
| kEDMA_BandwidthStallNone = 0x0U, /*!< No eDMA engine stalls. */ | |||
| kEDMA_BandwidthStall4Cycle = 0x2U, /*!< eDMA engine stalls for 4 cycles after each read/write. */ | |||
| kEDMA_BandwidthStall8Cycle = 0x3U, /*!< eDMA engine stalls for 8 cycles after each read/write. */ | |||
| } edma_bandwidth_t; | |||
| /*! @brief Channel link type */ | |||
| typedef enum _edma_channel_link_type | |||
| { | |||
| kEDMA_LinkNone = 0x0U, /*!< No channel link */ | |||
| kEDMA_MinorLink, /*!< Channel link after each minor loop */ | |||
| kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */ | |||
| } edma_channel_link_type_t; | |||
| /*!@brief _edma_channel_status_flags eDMA channel status flags. */ | |||
| enum | |||
| { | |||
| kEDMA_DoneFlag = 0x1U, /*!< DONE flag, set while transfer finished, CITER value exhausted*/ | |||
| kEDMA_ErrorFlag = 0x2U, /*!< eDMA error flag, an error occurred in a transfer */ | |||
| kEDMA_InterruptFlag = 0x4U, /*!< eDMA interrupt flag, set while an interrupt occurred of this channel */ | |||
| }; | |||
| /*! @brief _edma_error_status_flags eDMA channel error status flags. */ | |||
| enum | |||
| { | |||
| kEDMA_DestinationBusErrorFlag = DMA_ES_DBE_MASK, /*!< Bus error on destination address */ | |||
| kEDMA_SourceBusErrorFlag = DMA_ES_SBE_MASK, /*!< Bus error on the source address */ | |||
| kEDMA_ScatterGatherErrorFlag = DMA_ES_SGE_MASK, /*!< Error on the Scatter/Gather address, not 32byte aligned. */ | |||
| kEDMA_NbytesErrorFlag = DMA_ES_NCE_MASK, /*!< NBYTES/CITER configuration error */ | |||
| kEDMA_DestinationOffsetErrorFlag = DMA_ES_DOE_MASK, /*!< Destination offset not aligned with destination size */ | |||
| kEDMA_DestinationAddressErrorFlag = DMA_ES_DAE_MASK, /*!< Destination address not aligned with destination size */ | |||
| kEDMA_SourceOffsetErrorFlag = DMA_ES_SOE_MASK, /*!< Source offset not aligned with source size */ | |||
| kEDMA_SourceAddressErrorFlag = DMA_ES_SAE_MASK, /*!< Source address not aligned with source size*/ | |||
| kEDMA_ErrorChannelFlag = DMA_ES_ERRCHN_MASK, /*!< Error channel number of the cancelled channel number */ | |||
| kEDMA_ChannelPriorityErrorFlag = DMA_ES_CPE_MASK, /*!< Channel priority is not unique. */ | |||
| kEDMA_TransferCanceledFlag = DMA_ES_ECX_MASK, /*!< Transfer cancelled */ | |||
| #if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && (FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1) | |||
| kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */ | |||
| #endif | |||
| kEDMA_ValidFlag = (int)DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */ | |||
| }; | |||
| /*! @brief eDMA interrupt source */ | |||
| typedef enum _edma_interrupt_enable | |||
| { | |||
| kEDMA_ErrorInterruptEnable = 0x1U, /*!< Enable interrupt while channel error occurs. */ | |||
| kEDMA_MajorInterruptEnable = DMA_CSR_INTMAJOR_MASK, /*!< Enable interrupt while major count exhausted. */ | |||
| kEDMA_HalfInterruptEnable = DMA_CSR_INTHALF_MASK, /*!< Enable interrupt while major count to half value. */ | |||
| } edma_interrupt_enable_t; | |||
| /*! @brief eDMA transfer type */ | |||
| typedef enum _edma_transfer_type | |||
| { | |||
| kEDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory */ | |||
| kEDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory */ | |||
| kEDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral */ | |||
| kEDMA_PeripheralToPeripheral, /*!< Transfer from Peripheral to peripheral */ | |||
| } edma_transfer_type_t; | |||
| /*! @brief _edma_transfer_status eDMA transfer status */ | |||
| enum | |||
| { | |||
| kStatus_EDMA_QueueFull = MAKE_STATUS(kStatusGroup_EDMA, 0), /*!< TCD queue is full. */ | |||
| kStatus_EDMA_Busy = MAKE_STATUS(kStatusGroup_EDMA, 1), /*!< Channel is busy and can't handle the | |||
| transfer request. */ | |||
| }; | |||
| /*! @brief eDMA global configuration structure.*/ | |||
| typedef struct _edma_config | |||
| { | |||
| bool enableContinuousLinkMode; /*!< Enable (true) continuous link mode. Upon minor loop completion, the channel | |||
| activates again if that channel has a minor loop channel link enabled and | |||
| the link channel is itself. */ | |||
| bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. | |||
| Subsequently, all service requests are ignored until the HALT bit is cleared.*/ | |||
| bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority | |||
| arbitration is used for channel selection */ | |||
| bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of | |||
| a new channel. Executing channels are allowed to complete. */ | |||
| } edma_config_t; | |||
| /*! | |||
| * @brief eDMA transfer configuration | |||
| * | |||
| * This structure configures the source/destination transfer attribute. | |||
| */ | |||
| typedef struct _edma_transfer_config | |||
| { | |||
| uint32_t srcAddr; /*!< Source data address. */ | |||
| uint32_t destAddr; /*!< Destination data address. */ | |||
| edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */ | |||
| edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */ | |||
| int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to | |||
| form the next-state value as each source read is completed. */ | |||
| int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to | |||
| form the next-state value as each destination write is completed. */ | |||
| uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ | |||
| uint32_t majorLoopCounts; /*!< Major loop iteration count. */ | |||
| } edma_transfer_config_t; | |||
| /*! @brief eDMA channel priority configuration */ | |||
| typedef struct _edma_channel_Preemption_config | |||
| { | |||
| bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ | |||
| bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ | |||
| uint8_t channelPriority; /*!< Channel priority */ | |||
| } edma_channel_Preemption_config_t; | |||
| /*! @brief eDMA minor offset configuration */ | |||
| typedef struct _edma_minor_offset_config | |||
| { | |||
| bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ | |||
| bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ | |||
| uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ | |||
| } edma_minor_offset_config_t; | |||
| /*! | |||
| * @brief eDMA TCD. | |||
| * | |||
| * This structure is same as TCD register which is described in reference manual, | |||
| * and is used to configure the scatter/gather feature as a next hardware TCD. | |||
| */ | |||
| typedef struct _edma_tcd | |||
| { | |||
| __IO uint32_t SADDR; /*!< SADDR register, used to save source address */ | |||
| __IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */ | |||
| __IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */ | |||
| __IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */ | |||
| __IO uint32_t SLAST; /*!< SLAST register */ | |||
| __IO uint32_t DADDR; /*!< DADDR register, used for destination address */ | |||
| __IO uint16_t DOFF; /*!< DOFF register, used for destination offset */ | |||
| __IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/ | |||
| __IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next tcd address used in scatter-gather mode */ | |||
| __IO uint16_t CSR; /*!< CSR register, for TCD control status */ | |||
| __IO uint16_t BITER; /*!< BITER register, begin minor loop count. */ | |||
| } edma_tcd_t; | |||
| /*! @brief Callback for eDMA */ | |||
| struct _edma_handle; | |||
| /*! @brief Define callback function for eDMA. | |||
| * | |||
| * This callback function is called in the EDMA interrupt handle. | |||
| * In normal mode, run into callback function means the transfer users need is done. | |||
| * In scatter gather mode, run into callback function means a transfer control block (tcd) is finished. Not | |||
| * all transfer finished, users can get the finished tcd numbers using interface EDMA_GetUnusedTCDNumber. | |||
| * | |||
| * @param handle EDMA handle pointer, users shall not touch the values inside. | |||
| * @param userData The callback user parameter pointer. Users can use this parameter to involve things users need to | |||
| * change in EDMA callback function. | |||
| * @param transferDone If the current loaded transfer done. In normal mode it means if all transfer done. In scatter | |||
| * gather mode, this parameter shows is the current transfer block in EDMA register is done. As the | |||
| * load of core is different, it will be different if the new tcd loaded into EDMA registers while | |||
| * this callback called. If true, it always means new tcd still not loaded into registers, while | |||
| * false means new tcd already loaded into registers. | |||
| * @param tcds How many tcds are done from the last callback. This parameter only used in scatter gather mode. It | |||
| * tells user how many tcds are finished between the last callback and this. | |||
| */ | |||
| typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); | |||
| /*! @brief eDMA transfer handle structure */ | |||
| typedef struct _edma_handle | |||
| { | |||
| edma_callback callback; /*!< Callback function for major count exhausted. */ | |||
| void *userData; /*!< Callback function parameter. */ | |||
| DMA_Type *base; /*!< eDMA peripheral base address. */ | |||
| edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ | |||
| uint8_t channel; /*!< eDMA channel number. */ | |||
| volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ | |||
| volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ | |||
| volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in | |||
| the memory. */ | |||
| volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ | |||
| uint8_t flags; /*!< The status of the current channel. */ | |||
| } edma_handle_t; | |||
| /******************************************************************************* | |||
| * APIs | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /* __cplusplus */ | |||
| /*! | |||
| * @name eDMA initialization and de-initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the eDMA peripheral. | |||
| * | |||
| * This function ungates the eDMA clock and configures the eDMA peripheral according | |||
| * to the configuration structure. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param config A pointer to the configuration structure, see "edma_config_t". | |||
| * @note This function enables the minor loop map feature. | |||
| */ | |||
| void EDMA_Init(DMA_Type *base, const edma_config_t *config); | |||
| /*! | |||
| * @brief Deinitializes the eDMA peripheral. | |||
| * | |||
| * This function gates the eDMA clock. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| */ | |||
| void EDMA_Deinit(DMA_Type *base); | |||
| /*! | |||
| * @brief Push content of TCD structure into hardware TCD register. | |||
| * | |||
| * @param base EDMA peripheral base address. | |||
| * @param channel EDMA channel number. | |||
| * @param tcd Point to TCD structure. | |||
| */ | |||
| void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd); | |||
| /*! | |||
| * @brief Gets the eDMA default configuration structure. | |||
| * | |||
| * This function sets the configuration structure to default values. | |||
| * The default configuration is set to the following values. | |||
| * @code | |||
| * config.enableContinuousLinkMode = false; | |||
| * config.enableHaltOnError = true; | |||
| * config.enableRoundRobinArbitration = false; | |||
| * config.enableDebugMode = false; | |||
| * @endcode | |||
| * | |||
| * @param config A pointer to the eDMA configuration structure. | |||
| */ | |||
| void EDMA_GetDefaultConfig(edma_config_t *config); | |||
| /* @} */ | |||
| /*! | |||
| * @name eDMA Channel Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Sets all TCD registers to default values. | |||
| * | |||
| * This function sets TCD registers for this channel to default values. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @note This function must not be called while the channel transfer is ongoing | |||
| * or it causes unpredictable results. | |||
| * @note This function enables the auto stop request feature. | |||
| */ | |||
| void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); | |||
| /*! | |||
| * @brief Configures the eDMA transfer attribute. | |||
| * | |||
| * This function configures the transfer attribute, including source address, destination address, | |||
| * transfer size, address offset, and so on. It also configures the scatter gather feature if the | |||
| * user supplies the TCD address. | |||
| * Example: | |||
| * @code | |||
| * edma_transfer_t config; | |||
| * edma_tcd_t tcd; | |||
| * config.srcAddr = ..; | |||
| * config.destAddr = ..; | |||
| * ... | |||
| * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd); | |||
| * @endcode | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param config Pointer to eDMA transfer configuration structure. | |||
| * @param nextTcd Point to TCD structure. It can be NULL if users | |||
| * do not want to enable scatter/gather feature. | |||
| * @note If nextTcd is not NULL, it means scatter gather feature is enabled | |||
| * and DREQ bit is cleared in the previous transfer configuration, which | |||
| * is set in the eDMA_ResetChannel. | |||
| */ | |||
| void EDMA_SetTransferConfig(DMA_Type *base, | |||
| uint32_t channel, | |||
| const edma_transfer_config_t *config, | |||
| edma_tcd_t *nextTcd); | |||
| /*! | |||
| * @brief Configures the eDMA minor offset feature. | |||
| * | |||
| * The minor offset means that the signed-extended value is added to the source address or destination | |||
| * address after each minor loop. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param config A pointer to the minor offset configuration structure. | |||
| */ | |||
| void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); | |||
| /*! | |||
| * @brief Configures the eDMA channel preemption feature. | |||
| * | |||
| * This function configures the channel preemption attribute and the priority of the channel. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number | |||
| * @param config A pointer to the channel preemption configuration structure. | |||
| */ | |||
| void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, const edma_channel_Preemption_config_t *config); | |||
| /*! | |||
| * @brief Sets the channel link for the eDMA transfer. | |||
| * | |||
| * This function configures either the minor link or the major link mode. The minor link means that the channel link is | |||
| * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is | |||
| * exhausted. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param type A channel link type, which can be one of the following: | |||
| * @arg kEDMA_LinkNone | |||
| * @arg kEDMA_MinorLink | |||
| * @arg kEDMA_MajorLink | |||
| * @param linkedChannel The linked channel number. | |||
| * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. | |||
| */ | |||
| void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel); | |||
| /*! | |||
| * @brief Sets the bandwidth for the eDMA transfer. | |||
| * | |||
| * Because the eDMA processes the minor loop, it continuously generates read/write sequences | |||
| * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of | |||
| * each read/write access to control the bus request bandwidth seen by the crossbar switch. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param bandWidth A bandwidth setting, which can be one of the following: | |||
| * @arg kEDMABandwidthStallNone | |||
| * @arg kEDMABandwidthStall4Cycle | |||
| * @arg kEDMABandwidthStall8Cycle | |||
| */ | |||
| void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); | |||
| /*! | |||
| * @brief Sets the source modulo and the destination modulo for the eDMA transfer. | |||
| * | |||
| * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) | |||
| * calculation is performed or the original register value. It provides the ability to implement a circular data | |||
| * queue easily. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param srcModulo A source modulo value. | |||
| * @param destModulo A destination modulo value. | |||
| */ | |||
| void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); | |||
| #if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT | |||
| /*! | |||
| * @brief Enables an async request for the eDMA transfer. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param enable The command to enable (true) or disable (false). | |||
| */ | |||
| static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->EARS &= ~((uint32_t)1U << channel); | |||
| base->EARS |= ((uint32_t)(true == enable ? 1U : 0U) << channel); | |||
| } | |||
| #endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */ | |||
| /*! | |||
| * @brief Enables an auto stop request for the eDMA transfer. | |||
| * | |||
| * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param enable The command to enable (true) or disable (false). | |||
| */ | |||
| static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->TCD[channel].CSR = | |||
| (uint16_t)((base->TCD[channel].CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ((true == enable ? 1U : 0U))); | |||
| } | |||
| /*! | |||
| * @brief Enables the interrupt source for the eDMA transfer. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param mask The mask of interrupt source to be set. Users need to use | |||
| * the defined edma_interrupt_enable_t type. | |||
| */ | |||
| void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); | |||
| /*! | |||
| * @brief Disables the interrupt source for the eDMA transfer. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param mask The mask of the interrupt source to be set. Use | |||
| * the defined edma_interrupt_enable_t type. | |||
| */ | |||
| void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); | |||
| /* @} */ | |||
| /*! | |||
| * @name eDMA TCD Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Sets all fields to default values for the TCD structure. | |||
| * | |||
| * This function sets all fields for this TCD structure to default value. | |||
| * | |||
| * @param tcd Pointer to the TCD structure. | |||
| * @note This function enables the auto stop request feature. | |||
| */ | |||
| void EDMA_TcdReset(edma_tcd_t *tcd); | |||
| /*! | |||
| * @brief Configures the eDMA TCD transfer attribute. | |||
| * | |||
| * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. | |||
| * The STCD is used in the scatter-gather mode. | |||
| * This function configures the TCD transfer attribute, including source address, destination address, | |||
| * transfer size, address offset, and so on. It also configures the scatter gather feature if the | |||
| * user supplies the next TCD address. | |||
| * Example: | |||
| * @code | |||
| * edma_transfer_t config = { | |||
| * ... | |||
| * } | |||
| * edma_tcd_t tcd __aligned(32); | |||
| * edma_tcd_t nextTcd __aligned(32); | |||
| * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd); | |||
| * @endcode | |||
| * | |||
| * @param tcd Pointer to the TCD structure. | |||
| * @param config Pointer to eDMA transfer configuration structure. | |||
| * @param nextTcd Pointer to the next TCD structure. It can be NULL if users | |||
| * do not want to enable scatter/gather feature. | |||
| * @note TCD address should be 32 bytes aligned or it causes an eDMA error. | |||
| * @note If the nextTcd is not NULL, the scatter gather feature is enabled | |||
| * and DREQ bit is cleared in the previous transfer configuration, which | |||
| * is set in the EDMA_TcdReset. | |||
| */ | |||
| void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); | |||
| /*! | |||
| * @brief Configures the eDMA TCD minor offset feature. | |||
| * | |||
| * A minor offset is a signed-extended value added to the source address or a destination | |||
| * address after each minor loop. | |||
| * | |||
| * @param tcd A point to the TCD structure. | |||
| * @param config A pointer to the minor offset configuration structure. | |||
| */ | |||
| void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); | |||
| /*! | |||
| * @brief Sets the channel link for the eDMA TCD. | |||
| * | |||
| * This function configures either a minor link or a major link. The minor link means the channel link is | |||
| * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is | |||
| * exhausted. | |||
| * | |||
| * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. | |||
| * @param tcd Point to the TCD structure. | |||
| * @param type Channel link type, it can be one of: | |||
| * @arg kEDMA_LinkNone | |||
| * @arg kEDMA_MinorLink | |||
| * @arg kEDMA_MajorLink | |||
| * @param linkedChannel The linked channel number. | |||
| */ | |||
| void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel); | |||
| /*! | |||
| * @brief Sets the bandwidth for the eDMA TCD. | |||
| * | |||
| * Because the eDMA processes the minor loop, it continuously generates read/write sequences | |||
| * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of | |||
| * each read/write access to control the bus request bandwidth seen by the crossbar switch. | |||
| * @param tcd A pointer to the TCD structure. | |||
| * @param bandWidth A bandwidth setting, which can be one of the following: | |||
| * @arg kEDMABandwidthStallNone | |||
| * @arg kEDMABandwidthStall4Cycle | |||
| * @arg kEDMABandwidthStall8Cycle | |||
| */ | |||
| static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWidth) | |||
| { | |||
| assert(tcd != NULL); | |||
| assert(((uint32_t)tcd & 0x1FU) == 0U); | |||
| tcd->CSR = (uint16_t)((tcd->CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth)); | |||
| } | |||
| /*! | |||
| * @brief Sets the source modulo and the destination modulo for the eDMA TCD. | |||
| * | |||
| * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) | |||
| * calculation is performed or the original register value. It provides the ability to implement a circular data | |||
| * queue easily. | |||
| * | |||
| * @param tcd A pointer to the TCD structure. | |||
| * @param srcModulo A source modulo value. | |||
| * @param destModulo A destination modulo value. | |||
| */ | |||
| void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); | |||
| /*! | |||
| * @brief Sets the auto stop request for the eDMA TCD. | |||
| * | |||
| * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. | |||
| * | |||
| * @param tcd A pointer to the TCD structure. | |||
| * @param enable The command to enable (true) or disable (false). | |||
| */ | |||
| static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) | |||
| { | |||
| assert(tcd != NULL); | |||
| assert(((uint32_t)tcd & 0x1FU) == 0U); | |||
| tcd->CSR = (uint16_t)((tcd->CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ((true == enable ? 1U : 0U))); | |||
| } | |||
| /*! | |||
| * @brief Enables the interrupt source for the eDMA TCD. | |||
| * | |||
| * @param tcd Point to the TCD structure. | |||
| * @param mask The mask of interrupt source to be set. Users need to use | |||
| * the defined edma_interrupt_enable_t type. | |||
| */ | |||
| void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); | |||
| /*! | |||
| * @brief Disables the interrupt source for the eDMA TCD. | |||
| * | |||
| * @param tcd Point to the TCD structure. | |||
| * @param mask The mask of interrupt source to be set. Users need to use | |||
| * the defined edma_interrupt_enable_t type. | |||
| */ | |||
| void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); | |||
| /*! @} */ | |||
| /*! | |||
| * @name eDMA Channel Transfer Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enables the eDMA hardware channel request. | |||
| * | |||
| * This function enables the hardware channel request. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| */ | |||
| static inline void EDMA_EnableChannelRequest(DMA_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->SERQ = DMA_SERQ_SERQ(channel); | |||
| } | |||
| /*! | |||
| * @brief Disables the eDMA hardware channel request. | |||
| * | |||
| * This function disables the hardware channel request. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| */ | |||
| static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->CERQ = DMA_CERQ_CERQ(channel); | |||
| } | |||
| /*! | |||
| * @brief Starts the eDMA transfer by using the software trigger. | |||
| * | |||
| * This function starts a minor loop transfer. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| */ | |||
| static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) | |||
| { | |||
| assert(channel < (uint32_t)FSL_FEATURE_DMAMUX_MODULE_CHANNEL); | |||
| base->SSRT = DMA_SSRT_SSRT(channel); | |||
| } | |||
| /*! @} */ | |||
| /*! | |||
| * @name eDMA Channel Status Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Gets the remaining major loop count from the eDMA current channel TCD. | |||
| * | |||
| * This function checks the TCD (Task Control Descriptor) status for a specified | |||
| * eDMA channel and returns the number of major loop count that has not finished. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @return Major loop count which has not been transferred yet for the current TCD. | |||
| * @note 1. This function can only be used to get unfinished major loop count of transfer without | |||
| * the next TCD, or it might be inaccuracy. | |||
| * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while | |||
| * the channel is running. | |||
| * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO | |||
| * register is needed while the eDMA IP does not support getting it while a channel is active. | |||
| * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine | |||
| * is working with while a channel is running. | |||
| * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example | |||
| * copied before enabling the channel) is needed. The formula to calculate it is shown below: | |||
| * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) | |||
| */ | |||
| uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); | |||
| /*! | |||
| * @brief Gets the eDMA channel error status flags. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @return The mask of error status flags. Users need to use the | |||
| * _edma_error_status_flags type to decode the return variables. | |||
| */ | |||
| static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) | |||
| { | |||
| return base->ES; | |||
| } | |||
| /*! | |||
| * @brief Gets the eDMA channel status flags. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @return The mask of channel status flags. Users need to use the | |||
| * _edma_channel_status_flags type to decode the return variables. | |||
| */ | |||
| uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); | |||
| /*! | |||
| * @brief Clears the eDMA channel status flags. | |||
| * | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| * @param mask The mask of channel status to be cleared. Users need to use | |||
| * the defined _edma_channel_status_flags type. | |||
| */ | |||
| void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); | |||
| /*! @} */ | |||
| /*! | |||
| * @name eDMA Transactional Operation | |||
| */ | |||
| /*! | |||
| * @brief Creates the eDMA handle. | |||
| * | |||
| * This function is called if using the transactional API for eDMA. This function | |||
| * initializes the internal state of the eDMA handle. | |||
| * | |||
| * @param handle eDMA handle pointer. The eDMA handle stores callback function and | |||
| * parameters. | |||
| * @param base eDMA peripheral base address. | |||
| * @param channel eDMA channel number. | |||
| */ | |||
| void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); | |||
| /*! | |||
| * @brief Installs the TCDs memory pool into the eDMA handle. | |||
| * | |||
| * This function is called after the EDMA_CreateHandle to use scatter/gather feature. This function shall only be used | |||
| * while users need to use scatter gather mode. Scatter gather mode enables EDMA to load a new transfer control block | |||
| * (tcd) in hardware, and automatically reconfigure that DMA channel for a new transfer. | |||
| * Users need to prepare tcd memory and also configure tcds using interface EDMA_SubmitTransfer. | |||
| * | |||
| * @param handle eDMA handle pointer. | |||
| * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. | |||
| * @param tcdSize The number of TCD slots. | |||
| */ | |||
| void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); | |||
| /*! | |||
| * @brief Installs a callback function for the eDMA transfer. | |||
| * | |||
| * This callback is called in the eDMA IRQ handler. Use the callback to do something after | |||
| * the current major loop transfer completes. This function will be called every time one tcd finished transfer. | |||
| * | |||
| * @param handle eDMA handle pointer. | |||
| * @param callback eDMA callback function pointer. | |||
| * @param userData A parameter for the callback function. | |||
| */ | |||
| void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); | |||
| /*! | |||
| * @brief Prepares the eDMA transfer structure configurations. | |||
| * | |||
| * This function prepares the transfer configuration structure according to the user input. | |||
| * | |||
| * @param config The user configuration structure of type edma_transfer_t. | |||
| * @param srcAddr eDMA transfer source address. | |||
| * @param srcWidth eDMA transfer source address width(bytes). | |||
| * @param srcOffset source address offset. | |||
| * @param destAddr eDMA transfer destination address. | |||
| * @param destWidth eDMA transfer destination address width(bytes). | |||
| * @param destOffset destination address offset. | |||
| * @param bytesEachRequest eDMA transfer bytes per channel request. | |||
| * @param transferBytes eDMA transfer bytes to be transferred. | |||
| * @note The data address and the data width must be consistent. For example, if the SRC | |||
| * is 4 bytes, the source address must be 4 bytes aligned, or it results in | |||
| * source address error (SAE). | |||
| */ | |||
| void EDMA_PrepareTransferConfig(edma_transfer_config_t *config, | |||
| void *srcAddr, | |||
| uint32_t srcWidth, | |||
| int16_t srcOffset, | |||
| void *destAddr, | |||
| uint32_t destWidth, | |||
| int16_t destOffset, | |||
| uint32_t bytesEachRequest, | |||
| uint32_t transferBytes); | |||
| /*! | |||
| * @brief Prepares the eDMA transfer structure. | |||
| * | |||
| * This function prepares the transfer configuration structure according to the user input. | |||
| * | |||
| * @param config The user configuration structure of type edma_transfer_t. | |||
| * @param srcAddr eDMA transfer source address. | |||
| * @param srcWidth eDMA transfer source address width(bytes). | |||
| * @param destAddr eDMA transfer destination address. | |||
| * @param destWidth eDMA transfer destination address width(bytes). | |||
| * @param bytesEachRequest eDMA transfer bytes per channel request. | |||
| * @param transferBytes eDMA transfer bytes to be transferred. | |||
| * @param type eDMA transfer type. | |||
| * @note The data address and the data width must be consistent. For example, if the SRC | |||
| * is 4 bytes, the source address must be 4 bytes aligned, or it results in | |||
| * source address error (SAE). | |||
| */ | |||
| void EDMA_PrepareTransfer(edma_transfer_config_t *config, | |||
| void *srcAddr, | |||
| uint32_t srcWidth, | |||
| void *destAddr, | |||
| uint32_t destWidth, | |||
| uint32_t bytesEachRequest, | |||
| uint32_t transferBytes, | |||
| edma_transfer_type_t type); | |||
| /*! | |||
| * @brief Submits the eDMA transfer request. | |||
| * | |||
| * This function submits the eDMA transfer request according to the transfer configuration structure. | |||
| * In scatter gather mode, call this function will add a configured tcd to the circular list of tcd pool. | |||
| * The tcd pools is setup by call function EDMA_InstallTCDMemory before. | |||
| * | |||
| * @param handle eDMA handle pointer. | |||
| * @param config Pointer to eDMA transfer configuration structure. | |||
| * @retval kStatus_EDMA_Success It means submit transfer request succeed. | |||
| * @retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed. | |||
| * @retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later. | |||
| */ | |||
| status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); | |||
| /*! | |||
| * @brief eDMA starts transfer. | |||
| * | |||
| * This function enables the channel request. Users can call this function after submitting the transfer request | |||
| * or before submitting the transfer request. | |||
| * | |||
| * @param handle eDMA handle pointer. | |||
| */ | |||
| void EDMA_StartTransfer(edma_handle_t *handle); | |||
| /*! | |||
| * @brief eDMA stops transfer. | |||
| * | |||
| * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() | |||
| * again to resume the transfer. | |||
| * | |||
| * @param handle eDMA handle pointer. | |||
| */ | |||
| void EDMA_StopTransfer(edma_handle_t *handle); | |||
| /*! | |||
| * @brief eDMA aborts transfer. | |||
| * | |||
| * This function disables the channel request and clear transfer status bits. | |||
| * Users can submit another transfer after calling this API. | |||
| * | |||
| * @param handle DMA handle pointer. | |||
| */ | |||
| void EDMA_AbortTransfer(edma_handle_t *handle); | |||
| /*! | |||
| * @brief Get unused TCD slot number. | |||
| * | |||
| * This function gets current tcd index which is run. If the TCD pool pointer is NULL, it will return 0. | |||
| * | |||
| * @param handle DMA handle pointer. | |||
| * @return The unused tcd slot number. | |||
| */ | |||
| static inline uint32_t EDMA_GetUnusedTCDNumber(edma_handle_t *handle) | |||
| { | |||
| int8_t tmpTcdSize = handle->tcdSize; | |||
| int8_t tmpTcdUsed = handle->tcdUsed; | |||
| return ((uint32_t)tmpTcdSize - (uint32_t)tmpTcdUsed); | |||
| } | |||
| /*! | |||
| * @brief Get the next tcd address. | |||
| * | |||
| * This function gets the next tcd address. If this is last TCD, return 0. | |||
| * | |||
| * @param handle DMA handle pointer. | |||
| * @return The next TCD address. | |||
| */ | |||
| static inline uint32_t EDMA_GetNextTCDAddress(edma_handle_t *handle) | |||
| { | |||
| return (handle->base->TCD[handle->channel].DLAST_SGA); | |||
| } | |||
| /*! | |||
| * @brief eDMA IRQ handler for the current major loop transfer completion. | |||
| * | |||
| * This function clears the channel major interrupt flag and calls | |||
| * the callback function if it is not NULL. | |||
| * | |||
| * Note: | |||
| * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. | |||
| * These include the final address adjustments and reloading of the BITER field into the CITER. | |||
| * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from | |||
| * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). | |||
| * | |||
| * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. | |||
| * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index | |||
| * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be | |||
| * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have | |||
| * been loaded into the eDMA engine at this point already.). | |||
| * | |||
| * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not | |||
| * load a new TCD) from the memory pool to the eDMA engine when major loop completes. | |||
| * Therefore, ensure that the header and tcdUsed updated are identical for them. | |||
| * tcdUsed are both 0 in this case as no TCD to be loaded. | |||
| * | |||
| * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for | |||
| * further details. | |||
| * | |||
| * @param handle eDMA handle pointer. | |||
| */ | |||
| void EDMA_HandleIRQ(edma_handle_t *handle); | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /* __cplusplus */ | |||
| /* @} */ | |||
| #endif /*_FSL_EDMA_H_*/ | |||
| @@ -0,0 +1,593 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_enc.h" | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.enc" | |||
| #endif | |||
| #define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK) | |||
| #define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK) | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Get instance number for ENC module. | |||
| * | |||
| * @param base ENC peripheral base address | |||
| */ | |||
| static uint32_t ENC_GetInstance(ENC_Type *base); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Pointers to ENC bases for each instance. */ | |||
| static ENC_Type *const s_encBases[] = ENC_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Pointers to ENC clocks for each instance. */ | |||
| static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| static uint32_t ENC_GetInstance(ENC_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++) | |||
| { | |||
| if (s_encBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_encBases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initialization for the ENC module. | |||
| * | |||
| * This function is to make the initialization for the ENC module. It should be called firstly before any operation to | |||
| * the ENC with the operations like: | |||
| * - Enable the clock for ENC module. | |||
| * - Configure the ENC's working attributes. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * param config Pointer to configuration structure. See to "enc_config_t". | |||
| */ | |||
| void ENC_Init(ENC_Type *base, const enc_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint16_t tmp16; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Enable the clock. */ | |||
| CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /* ENC_CTRL. */ | |||
| tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK | | |||
| ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK)); | |||
| /* For HOME trigger. */ | |||
| if (kENC_HOMETriggerDisabled != config->HOMETriggerMode) | |||
| { | |||
| tmp16 |= ENC_CTRL_HIP_MASK; | |||
| if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode) | |||
| { | |||
| tmp16 |= ENC_CTRL_HNE_MASK; | |||
| } | |||
| } | |||
| /* For encoder work mode. */ | |||
| if (config->enableReverseDirection) | |||
| { | |||
| tmp16 |= ENC_CTRL_REV_MASK; | |||
| } | |||
| if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode) | |||
| { | |||
| tmp16 |= ENC_CTRL_PH1_MASK; | |||
| } | |||
| /* For INDEX trigger. */ | |||
| if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode) | |||
| { | |||
| tmp16 |= ENC_CTRL_XIP_MASK; | |||
| if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode) | |||
| { | |||
| tmp16 |= ENC_CTRL_XNE_MASK; | |||
| } | |||
| } | |||
| /* Watchdog. */ | |||
| if (config->enableWatchdog) | |||
| { | |||
| tmp16 |= ENC_CTRL_WDE_MASK; | |||
| base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */ | |||
| } | |||
| base->CTRL = tmp16; | |||
| /* ENC_FILT. */ | |||
| base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod); | |||
| /* ENC_CTRL2. */ | |||
| tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK | | |||
| ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK)); | |||
| if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode) | |||
| { | |||
| tmp16 |= ENC_CTRL2_OUTCTL_MASK; | |||
| } | |||
| if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition) | |||
| { | |||
| tmp16 |= ENC_CTRL2_REVMOD_MASK; | |||
| } | |||
| if (config->enableModuloCountMode) | |||
| { | |||
| tmp16 |= ENC_CTRL2_MOD_MASK; | |||
| /* Set modulus value. */ | |||
| base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */ | |||
| base->LMOD = (uint16_t)(config->positionModulusValue); /* Lower 16 bits. */ | |||
| } | |||
| if (config->enableTRIGGERClearPositionCounter) | |||
| { | |||
| tmp16 |= ENC_CTRL2_UPDPOS_MASK; | |||
| } | |||
| if (config->enableTRIGGERClearHoldPositionCounter) | |||
| { | |||
| tmp16 |= ENC_CTRL2_UPDHLD_MASK; | |||
| } | |||
| base->CTRL2 = tmp16; | |||
| /* ENC_UCOMP & ENC_LCOMP. */ | |||
| base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */ | |||
| base->LCOMP = (uint16_t)(config->positionCompareValue); /* Lower 16 bits. */ | |||
| /* ENC_UINIT & ENC_LINIT. */ | |||
| base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */ | |||
| base->LINIT = (uint16_t)(config->positionInitialValue); /* Lower 16 bits. */ | |||
| } | |||
| /*! | |||
| * brief De-initialization for the ENC module. | |||
| * | |||
| * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with | |||
| * the operations like: | |||
| * - Disable the clock for ENC module. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| */ | |||
| void ENC_Deinit(ENC_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Disable the clock. */ | |||
| CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Get an available pre-defined settings for ENC's configuration. | |||
| * | |||
| * This function initializes the ENC configuration structure with an available settings, the default value are: | |||
| * code | |||
| * config->enableReverseDirection = false; | |||
| * config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; | |||
| * config->HOMETriggerMode = kENC_HOMETriggerDisabled; | |||
| * config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; | |||
| * config->enableTRIGGERClearPositionCounter = false; | |||
| * config->enableTRIGGERClearHoldPositionCounter = false; | |||
| * config->enableWatchdog = false; | |||
| * config->watchdogTimeoutValue = 0U; | |||
| * config->filterCount = 0U; | |||
| * config->filterSamplePeriod = 0U; | |||
| * config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; | |||
| * config->positionCompareValue = 0xFFFFFFFFU; | |||
| * config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; | |||
| * config->enableModuloCountMode = false; | |||
| * config->positionModulusValue = 0U; | |||
| * config->positionInitialValue = 0U; | |||
| * endcode | |||
| * param config Pointer to a variable of configuration structure. See to "enc_config_t". | |||
| */ | |||
| void ENC_GetDefaultConfig(enc_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->enableReverseDirection = false; | |||
| config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; | |||
| config->HOMETriggerMode = kENC_HOMETriggerDisabled; | |||
| config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; | |||
| config->enableTRIGGERClearPositionCounter = false; | |||
| config->enableTRIGGERClearHoldPositionCounter = false; | |||
| config->enableWatchdog = false; | |||
| config->watchdogTimeoutValue = 0U; | |||
| config->filterCount = 0U; | |||
| config->filterSamplePeriod = 0U; | |||
| config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; | |||
| config->positionCompareValue = 0xFFFFFFFFU; | |||
| config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; | |||
| config->enableModuloCountMode = false; | |||
| config->positionModulusValue = 0U; | |||
| config->positionInitialValue = 0U; | |||
| } | |||
| /*! | |||
| * brief Load the initial position value to position counter. | |||
| * | |||
| * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and | |||
| * LPOS), so that to provide the consistent operation the position counter registers. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| */ | |||
| void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base) | |||
| { | |||
| uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS); | |||
| tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */ | |||
| base->CTRL = tmp16; | |||
| } | |||
| /*! | |||
| * brief Enable and configure the self test function. | |||
| * | |||
| * This function is to enable and configuration the self test function. It controls and sets the frequency of a | |||
| * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module. | |||
| * It is a factory test feature; however, it may be useful to customers' software development and testing. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable. | |||
| */ | |||
| void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config) | |||
| { | |||
| uint16_t tmp16 = 0U; | |||
| if (NULL == config) /* Pass "NULL" to disable the feature. */ | |||
| { | |||
| tmp16 = 0U; | |||
| } | |||
| else | |||
| { | |||
| tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) | | |||
| ENC_TST_TEST_COUNT(config->signalCount); | |||
| if (kENC_SelfTestDirectionNegative == config->signalDirection) | |||
| { | |||
| tmp16 |= ENC_TST_QDN_MASK; | |||
| } | |||
| } | |||
| base->TST = tmp16; | |||
| } | |||
| /*! | |||
| * brief Enable watchdog for ENC module. | |||
| * | |||
| * param base ENC peripheral base address | |||
| * param enable Enables or disables the watchdog | |||
| */ | |||
| void ENC_EnableWatchdog(ENC_Type *base, bool enable) | |||
| { | |||
| uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK)); | |||
| if (enable) | |||
| { | |||
| tmp16 |= ENC_CTRL_WDE_MASK; | |||
| } | |||
| base->CTRL = tmp16; | |||
| } | |||
| /*! | |||
| * brief Get the status flags. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * | |||
| * return Mask value of status flags. For available mask, see to "_enc_status_flags". | |||
| */ | |||
| uint32_t ENC_GetStatusFlags(ENC_Type *base) | |||
| { | |||
| uint32_t ret32 = 0U; | |||
| /* ENC_CTRL. */ | |||
| if (0U != (ENC_CTRL_HIRQ_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_HOMETransitionFlag; | |||
| } | |||
| if (0U != (ENC_CTRL_XIRQ_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_INDEXPulseFlag; | |||
| } | |||
| if (0U != (ENC_CTRL_DIRQ_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_WatchdogTimeoutFlag; | |||
| } | |||
| if (0U != (ENC_CTRL_CMPIRQ_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_PositionCompareFlag; | |||
| } | |||
| /* ENC_CTRL2. */ | |||
| if (0U != (ENC_CTRL2_SABIRQ_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_SimultBothPhaseChangeFlag; | |||
| } | |||
| if (0U != (ENC_CTRL2_ROIRQ_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_PositionRollOverFlag; | |||
| } | |||
| if (0U != (ENC_CTRL2_RUIRQ_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_PositionRollUnderFlag; | |||
| } | |||
| if (0U != (ENC_CTRL2_DIR_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_LastCountDirectionFlag; | |||
| } | |||
| return ret32; | |||
| } | |||
| /*! | |||
| * brief Clear the status flags. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags". | |||
| */ | |||
| void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask) | |||
| { | |||
| uint32_t tmp16 = 0U; | |||
| /* ENC_CTRL. */ | |||
| if (0U != ((uint32_t)kENC_HOMETransitionFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_HIRQ_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_INDEXPulseFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_XIRQ_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_WatchdogTimeoutFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_DIRQ_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionCompareFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_CMPIRQ_MASK; | |||
| } | |||
| if (0U != tmp16) | |||
| { | |||
| base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16); | |||
| } | |||
| /* ENC_CTRL2. */ | |||
| tmp16 = 0U; | |||
| if (0U != ((uint32_t)kENC_SimultBothPhaseChangeFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_SABIRQ_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionRollOverFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_ROIRQ_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionRollUnderFlag & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_RUIRQ_MASK; | |||
| } | |||
| if (0U != tmp16) | |||
| { | |||
| base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16); | |||
| } | |||
| } | |||
| /*! | |||
| * brief Enable the interrupts. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable". | |||
| */ | |||
| void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask) | |||
| { | |||
| uint32_t tmp16 = 0U; | |||
| /* ENC_CTRL. */ | |||
| if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_HIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_XIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_DIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_CMPIE_MASK; | |||
| } | |||
| if (tmp16 != 0U) | |||
| { | |||
| base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16); | |||
| } | |||
| /* ENC_CTRL2. */ | |||
| tmp16 = 0U; | |||
| if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_SABIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_ROIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_RUIE_MASK; | |||
| } | |||
| if (tmp16 != 0U) | |||
| { | |||
| base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16); | |||
| } | |||
| } | |||
| /*! | |||
| * brief Disable the interrupts. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable". | |||
| */ | |||
| void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask) | |||
| { | |||
| uint16_t tmp16 = 0U; | |||
| /* ENC_CTRL. */ | |||
| if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_HIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_XIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_DIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL_CMPIE_MASK; | |||
| } | |||
| if (0U != tmp16) | |||
| { | |||
| base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16); | |||
| } | |||
| /* ENC_CTRL2. */ | |||
| tmp16 = 0U; | |||
| if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_SABIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_ROIE_MASK; | |||
| } | |||
| if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask)) | |||
| { | |||
| tmp16 |= ENC_CTRL2_RUIE_MASK; | |||
| } | |||
| if (tmp16 != 0U) | |||
| { | |||
| base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16); | |||
| } | |||
| } | |||
| /*! | |||
| * brief Get the enabled interrupts' flags. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * | |||
| * return Mask value of enabled interrupts. | |||
| */ | |||
| uint32_t ENC_GetEnabledInterrupts(ENC_Type *base) | |||
| { | |||
| uint32_t ret32 = 0U; | |||
| /* ENC_CTRL. */ | |||
| if (0U != (ENC_CTRL_HIE_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_HOMETransitionInterruptEnable; | |||
| } | |||
| if (0U != (ENC_CTRL_XIE_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_INDEXPulseInterruptEnable; | |||
| } | |||
| if (0U != (ENC_CTRL_DIE_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_WatchdogTimeoutInterruptEnable; | |||
| } | |||
| if (0U != (ENC_CTRL_CMPIE_MASK & base->CTRL)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_PositionCompareInerruptEnable; | |||
| } | |||
| /* ENC_CTRL2. */ | |||
| if (0U != (ENC_CTRL2_SABIE_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_SimultBothPhaseChangeInterruptEnable; | |||
| } | |||
| if (0U != (ENC_CTRL2_ROIE_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_PositionRollOverInterruptEnable; | |||
| } | |||
| if (0U != (ENC_CTRL2_RUIE_MASK & base->CTRL2)) | |||
| { | |||
| ret32 |= (uint32_t)kENC_PositionRollUnderInterruptEnable; | |||
| } | |||
| return ret32; | |||
| } | |||
| /*! | |||
| * brief Set initial position value for ENC module. | |||
| * | |||
| * param base ENC peripheral base address | |||
| * param value Positive initial value | |||
| */ | |||
| void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value) | |||
| { | |||
| base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */ | |||
| base->LINIT = (uint16_t)(value); /* Set lower 16 bits. */ | |||
| } | |||
| /*! | |||
| * brief Get the current position counter's value. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * | |||
| * return Current position counter's value. | |||
| */ | |||
| uint32_t ENC_GetPositionValue(ENC_Type *base) | |||
| { | |||
| uint32_t ret32; | |||
| ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */ | |||
| ret32 <<= 16U; | |||
| ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */ | |||
| return ret32; | |||
| } | |||
| /*! | |||
| * brief Get the hold position counter's value. | |||
| * | |||
| * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold | |||
| * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to | |||
| * be attained. | |||
| * | |||
| * param base ENC peripheral base address. | |||
| * | |||
| * return Hold position counter's value. | |||
| */ | |||
| uint32_t ENC_GetHoldPositionValue(ENC_Type *base) | |||
| { | |||
| uint32_t ret32; | |||
| ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */ | |||
| ret32 <<= 16U; | |||
| ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */ | |||
| return ret32; | |||
| } | |||
| @@ -0,0 +1,458 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_ENC_H_ | |||
| #define _FSL_ENC_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup enc | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| #define FSL_ENC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) | |||
| /*! | |||
| * @brief Interrupt enable/disable mask. | |||
| */ | |||
| enum _enc_interrupt_enable | |||
| { | |||
| kENC_HOMETransitionInterruptEnable = (1U << 0U), /*!< HOME interrupt enable. */ | |||
| kENC_INDEXPulseInterruptEnable = (1U << 1U), /*!< INDEX pulse interrupt enable. */ | |||
| kENC_WatchdogTimeoutInterruptEnable = (1U << 2U), /*!< Watchdog timeout interrupt enable. */ | |||
| kENC_PositionCompareInerruptEnable = (1U << 3U), /*!< Position compare interrupt enable. */ | |||
| kENC_SimultBothPhaseChangeInterruptEnable = | |||
| (1U << 4U), /*!< Simultaneous PHASEA and PHASEB change interrupt enable. */ | |||
| kENC_PositionRollOverInterruptEnable = (1U << 5U), /*!< Roll-over interrupt enable. */ | |||
| kENC_PositionRollUnderInterruptEnable = (1U << 6U), /*!< Roll-under interrupt enable. */ | |||
| }; | |||
| /*! | |||
| * @brief Status flag mask. | |||
| * | |||
| * These flags indicate the counter's events. | |||
| */ | |||
| enum _enc_status_flags | |||
| { | |||
| kENC_HOMETransitionFlag = (1U << 0U), /*!< HOME signal transition interrupt request. */ | |||
| kENC_INDEXPulseFlag = (1U << 1U), /*!< INDEX Pulse Interrupt Request. */ | |||
| kENC_WatchdogTimeoutFlag = (1U << 2U), /*!< Watchdog timeout interrupt request. */ | |||
| kENC_PositionCompareFlag = (1U << 3U), /*!< Position compare interrupt request. */ | |||
| kENC_SimultBothPhaseChangeFlag = (1U << 4U), /*!< Simultaneous PHASEA and PHASEB change interrupt request. */ | |||
| kENC_PositionRollOverFlag = (1U << 5U), /*!< Roll-over interrupt request. */ | |||
| kENC_PositionRollUnderFlag = (1U << 6U), /*!< Roll-under interrupt request. */ | |||
| kENC_LastCountDirectionFlag = (1U << 7U), /*!< Last count was in the up direction, or the down direction. */ | |||
| }; | |||
| /*! | |||
| * @brief Signal status flag mask. | |||
| * | |||
| * These flags indicate the counter's signal. | |||
| */ | |||
| enum _enc_signal_status_flags | |||
| { | |||
| kENC_RawHOMEStatusFlag = ENC_IMR_HOME_MASK, /*!< Raw HOME input. */ | |||
| kENC_RawINDEXStatusFlag = ENC_IMR_INDEX_MASK, /*!< Raw INDEX input. */ | |||
| kENC_RawPHBStatusFlag = ENC_IMR_PHB_MASK, /*!< Raw PHASEB input. */ | |||
| kENC_RawPHAEXStatusFlag = ENC_IMR_PHA_MASK, /*!< Raw PHASEA input. */ | |||
| kENC_FilteredHOMEStatusFlag = ENC_IMR_FHOM_MASK, /*!< The filtered version of HOME input. */ | |||
| kENC_FilteredINDEXStatusFlag = ENC_IMR_FIND_MASK, /*!< The filtered version of INDEX input. */ | |||
| kENC_FilteredPHBStatusFlag = ENC_IMR_FPHB_MASK, /*!< The filtered version of PHASEB input. */ | |||
| kENC_FilteredPHAStatusFlag = ENC_IMR_FPHA_MASK, /*!< The filtered version of PHASEA input. */ | |||
| }; | |||
| /*! | |||
| * @brief Define HOME signal's trigger mode. | |||
| * | |||
| * The ENC would count the trigger from HOME signal line. | |||
| */ | |||
| typedef enum _enc_home_trigger_mode | |||
| { | |||
| kENC_HOMETriggerDisabled = 0U, /*!< HOME signal's trigger is disabled. */ | |||
| kENC_HOMETriggerOnRisingEdge, /*!< Use positive going edge-to-trigger initialization of position counters. */ | |||
| kENC_HOMETriggerOnFallingEdge, /*!< Use negative going edge-to-trigger initialization of position counters. */ | |||
| } enc_home_trigger_mode_t; | |||
| /*! | |||
| * @brief Define INDEX signal's trigger mode. | |||
| * | |||
| * The ENC would count the trigger from INDEX signal line. | |||
| */ | |||
| typedef enum _enc_index_trigger_mode | |||
| { | |||
| kENC_INDEXTriggerDisabled = 0U, /*!< INDEX signal's trigger is disabled. */ | |||
| kENC_INDEXTriggerOnRisingEdge, /*!< Use positive going edge-to-trigger initialization of position counters. */ | |||
| kENC_INDEXTriggerOnFallingEdge, /*!< Use negative going edge-to-trigger initialization of position counters. */ | |||
| } enc_index_trigger_mode_t; | |||
| /*! | |||
| * @brief Define type for decoder work mode. | |||
| * | |||
| * The normal work mode uses the standard quadrature decoder with PHASEA and PHASEB. When in signal phase count mode, | |||
| * a positive transition of the PHASEA input generates a count signal while the PHASEB input and the reverse direction | |||
| * control the counter direction. If the reverse direction is not enabled, PHASEB = 0 means counting up and PHASEB = 1 | |||
| * means counting down. Otherwise, the direction is reversed. | |||
| */ | |||
| typedef enum _enc_decoder_work_mode | |||
| { | |||
| kENC_DecoderWorkAsNormalMode = 0U, /*!< Use standard quadrature decoder with PHASEA and PHASEB. */ | |||
| kENC_DecoderWorkAsSignalPhaseCountMode, /*!< PHASEA input generates a count signal while PHASEB input control the | |||
| direction. */ | |||
| } enc_decoder_work_mode_t; | |||
| /*! | |||
| * @brief Define type for the condition of POSMATCH pulses. | |||
| */ | |||
| typedef enum _enc_position_match_mode | |||
| { | |||
| kENC_POSMATCHOnPositionCounterEqualToComapreValue = 0U, /*!< POSMATCH pulses when a match occurs between the | |||
| position counters (POS) and the compare value (COMP). */ | |||
| kENC_POSMATCHOnReadingAnyPositionCounter, /*!< POSMATCH pulses when any position counter register is read. */ | |||
| } enc_position_match_mode_t; | |||
| /*! | |||
| * @brief Define type for determining how the revolution counter (REV) is incremented/decremented. | |||
| */ | |||
| typedef enum _enc_revolution_count_condition | |||
| { | |||
| kENC_RevolutionCountOnINDEXPulse = 0U, /*!< Use INDEX pulse to increment/decrement revolution counter. */ | |||
| kENC_RevolutionCountOnRollOverModulus, /*!< Use modulus counting roll-over/under to increment/decrement revolution | |||
| counter. */ | |||
| } enc_revolution_count_condition_t; | |||
| /*! | |||
| * @brief Define type for direction of self test generated signal. | |||
| */ | |||
| typedef enum _enc_self_test_direction | |||
| { | |||
| kENC_SelfTestDirectionPositive = 0U, /*!< Self test generates the signal in positive direction. */ | |||
| kENC_SelfTestDirectionNegative, /*!< Self test generates the signal in negative direction. */ | |||
| } enc_self_test_direction_t; | |||
| /*! | |||
| * @brief Define user configuration structure for ENC module. | |||
| */ | |||
| typedef struct _enc_config | |||
| { | |||
| /* Basic counter. */ | |||
| bool enableReverseDirection; /*!< Enable reverse direction counting. */ | |||
| enc_decoder_work_mode_t decoderWorkMode; /*!< Enable signal phase count mode. */ | |||
| /* Signal detection. */ | |||
| enc_home_trigger_mode_t HOMETriggerMode; /*!< Enable HOME to initialize position counters. */ | |||
| enc_index_trigger_mode_t INDEXTriggerMode; /*!< Enable INDEX to initialize position counters. */ | |||
| bool enableTRIGGERClearPositionCounter; /*!< Clear POSD, REV, UPOS and LPOS on rising edge of TRIGGER, or not. */ | |||
| bool enableTRIGGERClearHoldPositionCounter; /*!< Enable update of hold registers on rising edge of TRIGGER, or not. | |||
| */ | |||
| /* Watchdog. */ | |||
| bool enableWatchdog; /*!< Enable the watchdog to detect if the target is moving or not. */ | |||
| uint16_t watchdogTimeoutValue; /*!< Watchdog timeout count value. It stores the timeout count for the quadrature | |||
| decoder module watchdog timer. This field is only available when | |||
| "enableWatchdog" = true. The available value is a 16-bit unsigned number.*/ | |||
| /* Filter for PHASEA, PHASEB, INDEX and HOME. */ | |||
| uint16_t filterCount; /*!< Input Filter Sample Count. This value should be chosen to reduce the probability of | |||
| noisy samples causing an incorrect transition to be recognized. The value represent the | |||
| number of consecutive samples that must agree prior to the input filter accepting an | |||
| input transition. A value of 0x0 represents 3 samples. A value of 0x7 represents 10 | |||
| samples. The Available range is 0 - 7.*/ | |||
| uint16_t filterSamplePeriod; /*!< Input Filter Sample Period. This value should be set such that the sampling period | |||
| is larger than the period of the expected noise. This value represents the | |||
| sampling period (in IPBus clock cycles) of the decoder input signals. | |||
| The available range is 0 - 255. */ | |||
| /* Position compare. */ | |||
| enc_position_match_mode_t positionMatchMode; /*!< The condition of POSMATCH pulses. */ | |||
| uint32_t positionCompareValue; /*!< Position compare value. The available value is a 32-bit number.*/ | |||
| /* Modulus counting. */ | |||
| enc_revolution_count_condition_t revolutionCountCondition; /*!< Revolution Counter Modulus Enable. */ | |||
| bool enableModuloCountMode; /*!< Enable Modulo Counting. */ | |||
| uint32_t positionModulusValue; /*!< Position modulus value. This value would be available only when | |||
| "enableModuloCountMode" = true. The available value is a 32-bit number. */ | |||
| uint32_t positionInitialValue; /*!< Position initial value. The available value is a 32-bit number. */ | |||
| } enc_config_t; | |||
| /*! | |||
| * @brief Define configuration structure for self test module. | |||
| * | |||
| * The self test module provides a quadrature test signal to the inputs of the quadrature decoder module. | |||
| * This is a factory test feature. It is also useful to customers' software development and testing. | |||
| */ | |||
| typedef struct _enc_self_test_config | |||
| { | |||
| enc_self_test_direction_t signalDirection; /*!< Direction of self test generated signal. */ | |||
| uint16_t signalCount; /*!< Hold the number of quadrature advances to generate. The available range is 0 - 255.*/ | |||
| uint16_t signalPeriod; /*!< Hold the period of quadrature phase in IPBus clock cycles. | |||
| The available range is 0 - 31. */ | |||
| } enc_self_test_config_t; | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name Initialization and De-initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initialization for the ENC module. | |||
| * | |||
| * This function is to make the initialization for the ENC module. It should be called firstly before any operation to | |||
| * the ENC with the operations like: | |||
| * - Enable the clock for ENC module. | |||
| * - Configure the ENC's working attributes. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * @param config Pointer to configuration structure. See to "enc_config_t". | |||
| */ | |||
| void ENC_Init(ENC_Type *base, const enc_config_t *config); | |||
| /*! | |||
| * @brief De-initialization for the ENC module. | |||
| * | |||
| * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with | |||
| * the operations like: | |||
| * - Disable the clock for ENC module. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| */ | |||
| void ENC_Deinit(ENC_Type *base); | |||
| /*! | |||
| * @brief Get an available pre-defined settings for ENC's configuration. | |||
| * | |||
| * This function initializes the ENC configuration structure with an available settings, the default value are: | |||
| * @code | |||
| * config->enableReverseDirection = false; | |||
| * config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; | |||
| * config->HOMETriggerMode = kENC_HOMETriggerDisabled; | |||
| * config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; | |||
| * config->enableTRIGGERClearPositionCounter = false; | |||
| * config->enableTRIGGERClearHoldPositionCounter = false; | |||
| * config->enableWatchdog = false; | |||
| * config->watchdogTimeoutValue = 0U; | |||
| * config->filterCount = 0U; | |||
| * config->filterSamplePeriod = 0U; | |||
| * config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; | |||
| * config->positionCompareValue = 0xFFFFFFFFU; | |||
| * config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; | |||
| * config->enableModuloCountMode = false; | |||
| * config->positionModulusValue = 0U; | |||
| * config->positionInitialValue = 0U; | |||
| * @endcode | |||
| * @param config Pointer to a variable of configuration structure. See to "enc_config_t". | |||
| */ | |||
| void ENC_GetDefaultConfig(enc_config_t *config); | |||
| /*! | |||
| * @brief Load the initial position value to position counter. | |||
| * | |||
| * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and | |||
| * LPOS), so that to provide the consistent operation the position counter registers. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| */ | |||
| void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base); | |||
| /*! | |||
| * @brief Enable and configure the self test function. | |||
| * | |||
| * This function is to enable and configuration the self test function. It controls and sets the frequency of a | |||
| * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module. | |||
| * It is a factory test feature; however, it may be useful to customers' software development and testing. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * @param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable. | |||
| */ | |||
| void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config); | |||
| /*! | |||
| * @brief Enable watchdog for ENC module. | |||
| * | |||
| * @param base ENC peripheral base address | |||
| * @param enable Enables or disables the watchdog | |||
| */ | |||
| void ENC_EnableWatchdog(ENC_Type *base, bool enable); | |||
| /*! | |||
| * @brief Set initial position value for ENC module. | |||
| * | |||
| * @param base ENC peripheral base address | |||
| * @param value Positive initial value | |||
| */ | |||
| void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value); | |||
| /* @} */ | |||
| /*! | |||
| * @name Status | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Get the status flags. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Mask value of status flags. For available mask, see to "_enc_status_flags". | |||
| */ | |||
| uint32_t ENC_GetStatusFlags(ENC_Type *base); | |||
| /*! | |||
| * @brief Clear the status flags. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * @param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags". | |||
| */ | |||
| void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Get the signals' real-time status. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Mask value of signals' real-time status. For available mask, see to "_enc_signal_status_flags" | |||
| */ | |||
| static inline uint16_t ENC_GetSignalStatusFlags(ENC_Type *base) | |||
| { | |||
| return base->IMR; | |||
| } | |||
| /* @} */ | |||
| /*! | |||
| * @name Interrupts | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enable the interrupts. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * @param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable". | |||
| */ | |||
| void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Disable the interrupts. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * @param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable". | |||
| */ | |||
| void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Get the enabled interrupts' flags. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Mask value of enabled interrupts. | |||
| */ | |||
| uint32_t ENC_GetEnabledInterrupts(ENC_Type *base); | |||
| /* @} */ | |||
| /*! | |||
| * @name Value Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Get the current position counter's value. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Current position counter's value. | |||
| */ | |||
| uint32_t ENC_GetPositionValue(ENC_Type *base); | |||
| /*! | |||
| * @brief Get the hold position counter's value. | |||
| * | |||
| * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold | |||
| * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to | |||
| * be attained. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Hold position counter's value. | |||
| */ | |||
| uint32_t ENC_GetHoldPositionValue(ENC_Type *base); | |||
| /*! | |||
| * @brief Get the position difference counter's value. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return The position difference counter's value. | |||
| */ | |||
| static inline uint16_t ENC_GetPositionDifferenceValue(ENC_Type *base) | |||
| { | |||
| return base->POSD; | |||
| } | |||
| /*! | |||
| * @brief Get the hold position difference counter's value. | |||
| * | |||
| * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold | |||
| * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to | |||
| * be attained. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Hold position difference counter's value. | |||
| */ | |||
| static inline uint16_t ENC_GetHoldPositionDifferenceValue(ENC_Type *base) | |||
| { | |||
| return base->POSDH; | |||
| } | |||
| /*! | |||
| * @brief Get the position revolution counter's value. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return The position revolution counter's value. | |||
| */ | |||
| static inline uint16_t ENC_GetRevolutionValue(ENC_Type *base) | |||
| { | |||
| return base->REV; | |||
| } | |||
| /*! | |||
| * @brief Get the hold position revolution counter's value. | |||
| * | |||
| * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold | |||
| * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to | |||
| * be attained. | |||
| * | |||
| * @param base ENC peripheral base address. | |||
| * | |||
| * @return Hold position revolution counter's value. | |||
| */ | |||
| static inline uint16_t ENC_GetHoldRevolutionValue(ENC_Type *base) | |||
| { | |||
| return base->REVH; | |||
| } | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /* @} */ | |||
| #endif /* _FSL_ENC_H_ */ | |||
| @@ -0,0 +1,140 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017, 2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_ewm.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.ewm" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| /*! | |||
| * brief Initializes the EWM peripheral. | |||
| * | |||
| * This function is used to initialize the EWM. After calling, the EWM | |||
| * runs immediately according to the configuration. | |||
| * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a | |||
| * CPU reset. Modifying them more than once generates a bus transfer error. | |||
| * | |||
| * This is an example. | |||
| * code | |||
| * ewm_config_t config; | |||
| * EWM_GetDefaultConfig(&config); | |||
| * config.compareHighValue = 0xAAU; | |||
| * EWM_Init(ewm_base,&config); | |||
| * endcode | |||
| * | |||
| * param base EWM peripheral base address | |||
| * param config The configuration of the EWM | |||
| */ | |||
| void EWM_Init(EWM_Type *base, const ewm_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint8_t value = 0U; | |||
| #if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \ | |||
| (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE)) | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| CLOCK_EnableClock(kCLOCK_Ewm0); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| #endif | |||
| value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) | | |||
| EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt); | |||
| #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER | |||
| base->CLKPRESCALER = config->prescaler; | |||
| #endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ | |||
| #if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT | |||
| base->CLKCTRL = (uint8_t)config->clockSource; | |||
| #endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/ | |||
| base->CMPL = config->compareLowValue; | |||
| base->CMPH = config->compareHighValue; | |||
| base->CTRL = value; | |||
| } | |||
| /*! | |||
| * brief Deinitializes the EWM peripheral. | |||
| * | |||
| * This function is used to shut down the EWM. | |||
| * | |||
| * param base EWM peripheral base address | |||
| */ | |||
| void EWM_Deinit(EWM_Type *base) | |||
| { | |||
| EWM_DisableInterrupts(base, (uint32_t)kEWM_InterruptEnable); | |||
| #if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \ | |||
| (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE)) | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| CLOCK_DisableClock(kCLOCK_Ewm0); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| #endif /* FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE */ | |||
| } | |||
| /*! | |||
| * brief Initializes the EWM configuration structure. | |||
| * | |||
| * This function initializes the EWM configuration structure to default values. The default | |||
| * values are as follows. | |||
| * code | |||
| * ewmConfig->enableEwm = true; | |||
| * ewmConfig->enableEwmInput = false; | |||
| * ewmConfig->setInputAssertLogic = false; | |||
| * ewmConfig->enableInterrupt = false; | |||
| * ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0; | |||
| * ewmConfig->prescaler = 0; | |||
| * ewmConfig->compareLowValue = 0; | |||
| * ewmConfig->compareHighValue = 0xFEU; | |||
| * endcode | |||
| * | |||
| * param config Pointer to the EWM configuration structure. | |||
| * see ewm_config_t | |||
| */ | |||
| void EWM_GetDefaultConfig(ewm_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->enableEwm = true; | |||
| config->enableEwmInput = false; | |||
| config->setInputAssertLogic = false; | |||
| config->enableInterrupt = false; | |||
| #if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT | |||
| config->clockSource = kEWM_LpoClockSource0; | |||
| #endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/ | |||
| #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER | |||
| config->prescaler = 0U; | |||
| #endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ | |||
| config->compareLowValue = 0U; | |||
| config->compareHighValue = 0xFEU; | |||
| } | |||
| /*! | |||
| * brief Services the EWM. | |||
| * | |||
| * This function resets the EWM counter to zero. | |||
| * | |||
| * param base EWM peripheral base address | |||
| */ | |||
| void EWM_Refresh(EWM_Type *base) | |||
| { | |||
| uint32_t primaskValue = 0U; | |||
| /* Disable the global interrupt to protect refresh sequence */ | |||
| primaskValue = DisableGlobalIRQ(); | |||
| base->SERV = (uint8_t)0xB4U; | |||
| base->SERV = (uint8_t)0x2CU; | |||
| EnableGlobalIRQ(primaskValue); | |||
| } | |||
| @@ -0,0 +1,218 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2017, 2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_EWM_H_ | |||
| #define _FSL_EWM_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup ewm | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| *******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief EWM driver version 2.0.2. */ | |||
| #define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) | |||
| /*@}*/ | |||
| /*! @brief Describes EWM clock source. */ | |||
| #if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT | |||
| typedef enum _ewm_lpo_clock_source | |||
| { | |||
| kEWM_LpoClockSource0 = 0U, /*!< EWM clock sourced from lpo_clk[0]*/ | |||
| kEWM_LpoClockSource1 = 1U, /*!< EWM clock sourced from lpo_clk[1]*/ | |||
| kEWM_LpoClockSource2 = 2U, /*!< EWM clock sourced from lpo_clk[2]*/ | |||
| kEWM_LpoClockSource3 = 3U, /*!< EWM clock sourced from lpo_clk[3]*/ | |||
| } ewm_lpo_clock_source_t; | |||
| #endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */ | |||
| /*! | |||
| * @brief Data structure for EWM configuration. | |||
| * | |||
| * This structure is used to configure the EWM. | |||
| */ | |||
| typedef struct _ewm_config | |||
| { | |||
| bool enableEwm; /*!< Enable EWM module */ | |||
| bool enableEwmInput; /*!< Enable EWM_in input */ | |||
| bool setInputAssertLogic; /*!< EWM_in signal assertion state */ | |||
| bool enableInterrupt; /*!< Enable EWM interrupt */ | |||
| #if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT | |||
| ewm_lpo_clock_source_t clockSource; /*!< Clock source select */ | |||
| #endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */ | |||
| #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER | |||
| uint8_t prescaler; /*!< Clock prescaler value */ | |||
| #endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ | |||
| uint8_t compareLowValue; /*!< Compare low-register value */ | |||
| uint8_t compareHighValue; /*!< Compare high-register value */ | |||
| } ewm_config_t; | |||
| /*! | |||
| * @brief EWM interrupt configuration structure with default settings all disabled. | |||
| * | |||
| * This structure contains the settings for all of EWM interrupt configurations. | |||
| */ | |||
| enum _ewm_interrupt_enable_t | |||
| { | |||
| kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable the EWM to generate an interrupt*/ | |||
| }; | |||
| /*! | |||
| * @brief EWM status flags. | |||
| * | |||
| * This structure contains the constants for the EWM status flags for use in the EWM functions. | |||
| */ | |||
| enum _ewm_status_flags_t | |||
| { | |||
| kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when EWM is enabled*/ | |||
| }; | |||
| /******************************************************************************* | |||
| * API | |||
| *******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /* __cplusplus */ | |||
| /*! | |||
| * @name EWM initialization and de-initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the EWM peripheral. | |||
| * | |||
| * This function is used to initialize the EWM. After calling, the EWM | |||
| * runs immediately according to the configuration. | |||
| * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a | |||
| * CPU reset. Modifying them more than once generates a bus transfer error. | |||
| * | |||
| * This is an example. | |||
| * @code | |||
| * ewm_config_t config; | |||
| * EWM_GetDefaultConfig(&config); | |||
| * config.compareHighValue = 0xAAU; | |||
| * EWM_Init(ewm_base,&config); | |||
| * @endcode | |||
| * | |||
| * @param base EWM peripheral base address | |||
| * @param config The configuration of the EWM | |||
| */ | |||
| void EWM_Init(EWM_Type *base, const ewm_config_t *config); | |||
| /*! | |||
| * @brief Deinitializes the EWM peripheral. | |||
| * | |||
| * This function is used to shut down the EWM. | |||
| * | |||
| * @param base EWM peripheral base address | |||
| */ | |||
| void EWM_Deinit(EWM_Type *base); | |||
| /*! | |||
| * @brief Initializes the EWM configuration structure. | |||
| * | |||
| * This function initializes the EWM configuration structure to default values. The default | |||
| * values are as follows. | |||
| * @code | |||
| * ewmConfig->enableEwm = true; | |||
| * ewmConfig->enableEwmInput = false; | |||
| * ewmConfig->setInputAssertLogic = false; | |||
| * ewmConfig->enableInterrupt = false; | |||
| * ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0; | |||
| * ewmConfig->prescaler = 0; | |||
| * ewmConfig->compareLowValue = 0; | |||
| * ewmConfig->compareHighValue = 0xFEU; | |||
| * @endcode | |||
| * | |||
| * @param config Pointer to the EWM configuration structure. | |||
| * @see ewm_config_t | |||
| */ | |||
| void EWM_GetDefaultConfig(ewm_config_t *config); | |||
| /* @} */ | |||
| /*! | |||
| * @name EWM functional Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enables the EWM interrupt. | |||
| * | |||
| * This function enables the EWM interrupt. | |||
| * | |||
| * @param base EWM peripheral base address | |||
| * @param mask The interrupts to enable | |||
| * The parameter can be combination of the following source if defined | |||
| * @arg kEWM_InterruptEnable | |||
| */ | |||
| static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask) | |||
| { | |||
| base->CTRL |= (uint8_t)mask; | |||
| } | |||
| /*! | |||
| * @brief Disables the EWM interrupt. | |||
| * | |||
| * This function enables the EWM interrupt. | |||
| * | |||
| * @param base EWM peripheral base address | |||
| * @param mask The interrupts to disable | |||
| * The parameter can be combination of the following source if defined | |||
| * @arg kEWM_InterruptEnable | |||
| */ | |||
| static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask) | |||
| { | |||
| base->CTRL &= (uint8_t)(~mask); | |||
| } | |||
| /*! | |||
| * @brief Gets all status flags. | |||
| * | |||
| * This function gets all status flags. | |||
| * | |||
| * This is an example for getting the running flag. | |||
| * @code | |||
| * uint32_t status; | |||
| * status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag; | |||
| * @endcode | |||
| * @param base EWM peripheral base address | |||
| * @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t | |||
| * - True: a related status flag has been set. | |||
| * - False: a related status flag is not set. | |||
| */ | |||
| static inline uint32_t EWM_GetStatusFlags(EWM_Type *base) | |||
| { | |||
| return ((uint32_t)base->CTRL & EWM_CTRL_EWMEN_MASK); | |||
| } | |||
| /*! | |||
| * @brief Services the EWM. | |||
| * | |||
| * This function resets the EWM counter to zero. | |||
| * | |||
| * @param base EWM peripheral base address | |||
| */ | |||
| void EWM_Refresh(EWM_Type *base); | |||
| /*@}*/ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /* __cplusplus */ | |||
| /*! @}*/ | |||
| #endif /* _FSL_EWM_H_ */ | |||
| @@ -0,0 +1,41 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FLASH_H | |||
| #define FSL_FLASH_H | |||
| #include "fsl_ftfx_cache.h" | |||
| #include "fsl_ftfx_flash.h" | |||
| #if FSL_FEATURE_FLASH_HAS_FLEX_NVM | |||
| #include "fsl_ftfx_flexnvm.h" | |||
| #endif | |||
| /*! | |||
| * @addtogroup flash_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* FSL_FLASH_H */ | |||
| @@ -0,0 +1,254 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_flexbus.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.flexbus" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief Gets the instance from the base address | |||
| * | |||
| * @param base FLEXBUS peripheral base address | |||
| * | |||
| * @return The FLEXBUS instance | |||
| */ | |||
| static uint32_t FLEXBUS_GetInstance(FB_Type *base); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*! @brief Pointers to FLEXBUS bases for each instance. */ | |||
| static FB_Type *const s_flexbusBases[] = FB_BASE_PTRS; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Pointers to FLEXBUS clocks for each instance. */ | |||
| static const clock_ip_name_t s_flexbusClocks[] = FLEXBUS_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| static uint32_t FLEXBUS_GetInstance(FB_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_flexbusBases); instance++) | |||
| { | |||
| if (s_flexbusBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_flexbusBases)); | |||
| return instance; | |||
| } | |||
| /*! | |||
| * brief Initializes and configures the FlexBus module. | |||
| * | |||
| * This function enables the clock gate for FlexBus module. | |||
| * Only chip 0 is validated and set to known values. Other chips are disabled. | |||
| * Note that in this function, certain parameters, depending on external memories, must | |||
| * be set before using the FLEXBUS_Init() function. | |||
| * This example shows how to set up the uart_state_t and the | |||
| * flexbus_config_t parameters and how to call the FLEXBUS_Init function by passing | |||
| * in these parameters. | |||
| code | |||
| flexbus_config_t flexbusConfig; | |||
| FLEXBUS_GetDefaultConfig(&flexbusConfig); | |||
| flexbusConfig.waitStates = 2U; | |||
| flexbusConfig.chipBaseAddress = 0x60000000U; | |||
| flexbusConfig.chipBaseAddressMask = 7U; | |||
| FLEXBUS_Init(FB, &flexbusConfig); | |||
| endcode | |||
| * | |||
| * param base FlexBus peripheral address. | |||
| * param config Pointer to the configuration structure | |||
| */ | |||
| void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config) | |||
| { | |||
| assert(config != NULL); | |||
| assert(config->chip < FB_CSAR_COUNT); | |||
| assert(config->waitStates <= 0x3FU); | |||
| assert(config->secondaryWaitStates <= 0x3FU); | |||
| uint32_t chip = config->chip; | |||
| uint32_t reg_value = 0; | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Ungate clock for FLEXBUS */ | |||
| CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| /* Reset the associated register to default state */ | |||
| /* Set CSMR register, all chips not valid (disabled) */ | |||
| base->CS[chip].CSMR = 0x0000U; | |||
| /* Set default base address */ | |||
| base->CS[chip].CSAR &= (~FB_CSAR_BA_MASK); | |||
| /* Reset FB_CSCRx register */ | |||
| base->CS[chip].CSCR = 0x0000U; | |||
| /* Set FB_CSPMCR register */ | |||
| /* FlexBus signal group 1 multiplex control */ | |||
| reg_value |= (uint32_t)kFLEXBUS_MultiplexGroup1_FB_ALE << FB_CSPMCR_GROUP1_SHIFT; | |||
| /* FlexBus signal group 2 multiplex control */ | |||
| reg_value |= (uint32_t)kFLEXBUS_MultiplexGroup2_FB_CS4 << FB_CSPMCR_GROUP2_SHIFT; | |||
| /* FlexBus signal group 3 multiplex control */ | |||
| reg_value |= (uint32_t)kFLEXBUS_MultiplexGroup3_FB_CS5 << FB_CSPMCR_GROUP3_SHIFT; | |||
| /* FlexBus signal group 4 multiplex control */ | |||
| reg_value |= (uint32_t)kFLEXBUS_MultiplexGroup4_FB_TBST << FB_CSPMCR_GROUP4_SHIFT; | |||
| /* FlexBus signal group 5 multiplex control */ | |||
| reg_value |= (uint32_t)kFLEXBUS_MultiplexGroup5_FB_TA << FB_CSPMCR_GROUP5_SHIFT; | |||
| /* Write to CSPMCR register */ | |||
| base->CSPMCR = reg_value; | |||
| /* Base address */ | |||
| reg_value = config->chipBaseAddress; | |||
| /* Write to CSAR register */ | |||
| base->CS[chip].CSAR = reg_value; | |||
| /* Chip-select validation */ | |||
| reg_value = 0x1U << FB_CSMR_V_SHIFT; | |||
| /* Write protect */ | |||
| reg_value |= ((uint32_t)config->writeProtect) << FB_CSMR_WP_SHIFT; | |||
| /* Base address mask */ | |||
| reg_value |= config->chipBaseAddressMask << FB_CSMR_BAM_SHIFT; | |||
| /* Write to CSMR register */ | |||
| base->CS[chip].CSMR = reg_value; | |||
| /* Burst write */ | |||
| reg_value = ((uint32_t)config->burstWrite) << FB_CSCR_BSTW_SHIFT; | |||
| /* Burst read */ | |||
| reg_value |= ((uint32_t)config->burstRead) << FB_CSCR_BSTR_SHIFT; | |||
| /* Byte-enable mode */ | |||
| reg_value |= ((uint32_t)config->byteEnableMode) << FB_CSCR_BEM_SHIFT; | |||
| /* Port size */ | |||
| reg_value |= (uint32_t)config->portSize << FB_CSCR_PS_SHIFT; | |||
| /* The internal transfer acknowledge for accesses */ | |||
| reg_value |= ((uint32_t)config->autoAcknowledge) << FB_CSCR_AA_SHIFT; | |||
| /* Byte-Lane shift */ | |||
| reg_value |= (uint32_t)config->byteLaneShift << FB_CSCR_BLS_SHIFT; | |||
| /* The number of wait states */ | |||
| reg_value |= (uint32_t)config->waitStates << FB_CSCR_WS_SHIFT; | |||
| /* Write address hold or deselect */ | |||
| reg_value |= (uint32_t)config->writeAddressHold << FB_CSCR_WRAH_SHIFT; | |||
| /* Read address hold or deselect */ | |||
| reg_value |= (uint32_t)config->readAddressHold << FB_CSCR_RDAH_SHIFT; | |||
| /* Address setup */ | |||
| reg_value |= (uint32_t)config->addressSetup << FB_CSCR_ASET_SHIFT; | |||
| /* Extended transfer start/extended address latch */ | |||
| reg_value |= ((uint32_t)config->extendTransferAddress) << FB_CSCR_EXTS_SHIFT; | |||
| /* Secondary wait state */ | |||
| if (config->secondaryWaitStatesEnable) | |||
| { | |||
| reg_value |= FB_CSCR_SWSEN_MASK; | |||
| reg_value |= (uint32_t)(config->secondaryWaitStates) << FB_CSCR_SWS_SHIFT; | |||
| } | |||
| /* Write to CSCR register */ | |||
| base->CS[chip].CSCR = reg_value; | |||
| /* FlexBus signal group 1 multiplex control */ | |||
| reg_value = (uint32_t)config->group1MultiplexControl << FB_CSPMCR_GROUP1_SHIFT; | |||
| /* FlexBus signal group 2 multiplex control */ | |||
| reg_value |= (uint32_t)config->group2MultiplexControl << FB_CSPMCR_GROUP2_SHIFT; | |||
| /* FlexBus signal group 3 multiplex control */ | |||
| reg_value |= (uint32_t)config->group3MultiplexControl << FB_CSPMCR_GROUP3_SHIFT; | |||
| /* FlexBus signal group 4 multiplex control */ | |||
| reg_value |= (uint32_t)config->group4MultiplexControl << FB_CSPMCR_GROUP4_SHIFT; | |||
| /* FlexBus signal group 5 multiplex control */ | |||
| reg_value |= (uint32_t)config->group5MultiplexControl << FB_CSPMCR_GROUP5_SHIFT; | |||
| /* Write to CSPMCR register */ | |||
| base->CSPMCR = reg_value; | |||
| /* Enable CSPMCR0[V] to make all chip select registers take effect. */ | |||
| if (chip != 0UL) | |||
| { | |||
| base->CS[0].CSMR |= FB_CSMR_V_MASK; | |||
| } | |||
| } | |||
| /*! | |||
| * brief De-initializes a FlexBus instance. | |||
| * | |||
| * This function disables the clock gate of the FlexBus module clock. | |||
| * | |||
| * param base FlexBus peripheral address. | |||
| */ | |||
| void FLEXBUS_Deinit(FB_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Gate clock for FLEXBUS */ | |||
| CLOCK_DisableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| /*! | |||
| * brief Initializes the FlexBus configuration structure. | |||
| * | |||
| * This function initializes the FlexBus configuration structure to default value. The default | |||
| * values are. | |||
| code | |||
| fbConfig->chip = 0; | |||
| fbConfig->writeProtect = false; | |||
| fbConfig->burstWrite = false; | |||
| fbConfig->burstRead = false; | |||
| fbConfig->byteEnableMode = false; | |||
| fbConfig->autoAcknowledge = true; | |||
| fbConfig->extendTransferAddress = false; | |||
| fbConfig->secondaryWaitStatesEnable = false; | |||
| fbConfig->byteLaneShift = kFLEXBUS_NotShifted; | |||
| fbConfig->writeAddressHold = kFLEXBUS_Hold1Cycle; | |||
| fbConfig->readAddressHold = kFLEXBUS_Hold1Or0Cycles; | |||
| fbConfig->addressSetup = kFLEXBUS_FirstRisingEdge; | |||
| fbConfig->portSize = kFLEXBUS_1Byte; | |||
| fbConfig->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE; | |||
| fbConfig->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4 ; | |||
| fbConfig->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5; | |||
| fbConfig->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST; | |||
| fbConfig->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA; | |||
| endcode | |||
| * param config Pointer to the initialization structure. | |||
| * see FLEXBUS_Init | |||
| */ | |||
| void FLEXBUS_GetDefaultConfig(flexbus_config_t *config) | |||
| { | |||
| /* Initializes the configure structure to zero. */ | |||
| (void)memset(config, 0, sizeof(*config)); | |||
| config->chip = 0; /* Chip 0 FlexBus for validation */ | |||
| config->writeProtect = false; /* Write accesses are allowed */ | |||
| config->burstWrite = false; /* Burst-Write disable */ | |||
| config->burstRead = false; /* Burst-Read disable */ | |||
| config->byteEnableMode = false; /* Byte-Enable mode is asserted for data write only */ | |||
| config->autoAcknowledge = true; /* Auto-Acknowledge enable */ | |||
| config->extendTransferAddress = false; /* Extend transfer start/extend address latch disable */ | |||
| config->secondaryWaitStatesEnable = false; /* Secondary wait state disable */ | |||
| config->byteLaneShift = kFLEXBUS_NotShifted; /* Byte-Lane shift disable */ | |||
| config->writeAddressHold = kFLEXBUS_Hold1Cycle; /* Write address hold 1 cycles */ | |||
| config->readAddressHold = kFLEXBUS_Hold1Or0Cycles; /* Read address hold 0 cycles */ | |||
| config->addressSetup = | |||
| kFLEXBUS_FirstRisingEdge; /* Assert ~FB_CSn on the first rising clock edge after the address is asserted */ | |||
| config->portSize = kFLEXBUS_1Byte; /* 1 byte port size of transfer */ | |||
| config->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE; /* FB_ALE */ | |||
| config->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4; /* FB_CS4 */ | |||
| config->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5; /* FB_CS5 */ | |||
| config->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST; /* FB_TBST */ | |||
| config->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA; /* FB_TA */ | |||
| } | |||
| @@ -0,0 +1,243 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_FLEXBUS_H_ | |||
| #define _FSL_FLEXBUS_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup flexbus | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| #define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Defines port size for FlexBus peripheral. | |||
| */ | |||
| typedef enum _flexbus_port_size | |||
| { | |||
| kFLEXBUS_4Bytes = 0x00U, /*!< 32-bit port size */ | |||
| kFLEXBUS_1Byte = 0x01U, /*!< 8-bit port size */ | |||
| kFLEXBUS_2Bytes = 0x02U /*!< 16-bit port size */ | |||
| } flexbus_port_size_t; | |||
| /*! | |||
| * @brief Defines number of cycles to hold address and attributes for FlexBus peripheral. | |||
| */ | |||
| typedef enum _flexbus_write_address_hold | |||
| { | |||
| kFLEXBUS_Hold1Cycle = 0x00U, /*!< Hold address and attributes one cycles after FB_CSn negates on writes */ | |||
| kFLEXBUS_Hold2Cycles = 0x01U, /*!< Hold address and attributes two cycles after FB_CSn negates on writes */ | |||
| kFLEXBUS_Hold3Cycles = 0x02U, /*!< Hold address and attributes three cycles after FB_CSn negates on writes */ | |||
| kFLEXBUS_Hold4Cycles = 0x03U /*!< Hold address and attributes four cycles after FB_CSn negates on writes */ | |||
| } flexbus_write_address_hold_t; | |||
| /*! | |||
| * @brief Defines number of cycles to hold address and attributes for FlexBus peripheral. | |||
| */ | |||
| typedef enum _flexbus_read_address_hold | |||
| { | |||
| kFLEXBUS_Hold1Or0Cycles = 0x00U, /*!< Hold address and attributes 1 or 0 cycles on reads */ | |||
| kFLEXBUS_Hold2Or1Cycles = 0x01U, /*!< Hold address and attributes 2 or 1 cycles on reads */ | |||
| kFLEXBUS_Hold3Or2Cycle = 0x02U, /*!< Hold address and attributes 3 or 2 cycles on reads */ | |||
| kFLEXBUS_Hold4Or3Cycle = 0x03U /*!< Hold address and attributes 4 or 3 cycles on reads */ | |||
| } flexbus_read_address_hold_t; | |||
| /*! | |||
| * @brief Address setup for FlexBus peripheral. | |||
| */ | |||
| typedef enum _flexbus_address_setup | |||
| { | |||
| kFLEXBUS_FirstRisingEdge = 0x00U, /*!< Assert FB_CSn on first rising clock edge after address is asserted */ | |||
| kFLEXBUS_SecondRisingEdge = 0x01U, /*!< Assert FB_CSn on second rising clock edge after address is asserted */ | |||
| kFLEXBUS_ThirdRisingEdge = 0x02U, /*!< Assert FB_CSn on third rising clock edge after address is asserted */ | |||
| kFLEXBUS_FourthRisingEdge = 0x03U, /*!< Assert FB_CSn on fourth rising clock edge after address is asserted */ | |||
| } flexbus_address_setup_t; | |||
| /*! | |||
| * @brief Defines byte-lane shift for FlexBus peripheral. | |||
| */ | |||
| typedef enum _flexbus_bytelane_shift | |||
| { | |||
| kFLEXBUS_NotShifted = 0x00U, /*!< Not shifted. Data is left-justified on FB_AD */ | |||
| kFLEXBUS_Shifted = 0x01U, /*!< Shifted. Data is right justified on FB_AD */ | |||
| } flexbus_bytelane_shift_t; | |||
| /*! | |||
| * @brief Defines multiplex group1 valid signals. | |||
| */ | |||
| typedef enum _flexbus_multiplex_group1_signal | |||
| { | |||
| kFLEXBUS_MultiplexGroup1_FB_ALE = 0x00U, /*!< FB_ALE */ | |||
| kFLEXBUS_MultiplexGroup1_FB_CS1 = 0x01U, /*!< FB_CS1 */ | |||
| kFLEXBUS_MultiplexGroup1_FB_TS = 0x02U, /*!< FB_TS */ | |||
| } flexbus_multiplex_group1_t; | |||
| /*! | |||
| * @brief Defines multiplex group2 valid signals. | |||
| */ | |||
| typedef enum _flexbus_multiplex_group2_signal | |||
| { | |||
| kFLEXBUS_MultiplexGroup2_FB_CS4 = 0x00U, /*!< FB_CS4 */ | |||
| kFLEXBUS_MultiplexGroup2_FB_TSIZ0 = 0x01U, /*!< FB_TSIZ0 */ | |||
| kFLEXBUS_MultiplexGroup2_FB_BE_31_24 = 0x02U, /*!< FB_BE_31_24 */ | |||
| } flexbus_multiplex_group2_t; | |||
| /*! | |||
| * @brief Defines multiplex group3 valid signals. | |||
| */ | |||
| typedef enum _flexbus_multiplex_group3_signal | |||
| { | |||
| kFLEXBUS_MultiplexGroup3_FB_CS5 = 0x00U, /*!< FB_CS5 */ | |||
| kFLEXBUS_MultiplexGroup3_FB_TSIZ1 = 0x01U, /*!< FB_TSIZ1 */ | |||
| kFLEXBUS_MultiplexGroup3_FB_BE_23_16 = 0x02U, /*!< FB_BE_23_16 */ | |||
| } flexbus_multiplex_group3_t; | |||
| /*! | |||
| * @brief Defines multiplex group4 valid signals. | |||
| */ | |||
| typedef enum _flexbus_multiplex_group4_signal | |||
| { | |||
| kFLEXBUS_MultiplexGroup4_FB_TBST = 0x00U, /*!< FB_TBST */ | |||
| kFLEXBUS_MultiplexGroup4_FB_CS2 = 0x01U, /*!< FB_CS2 */ | |||
| kFLEXBUS_MultiplexGroup4_FB_BE_15_8 = 0x02U, /*!< FB_BE_15_8 */ | |||
| } flexbus_multiplex_group4_t; | |||
| /*! | |||
| * @brief Defines multiplex group5 valid signals. | |||
| */ | |||
| typedef enum _flexbus_multiplex_group5_signal | |||
| { | |||
| kFLEXBUS_MultiplexGroup5_FB_TA = 0x00U, /*!< FB_TA */ | |||
| kFLEXBUS_MultiplexGroup5_FB_CS3 = 0x01U, /*!< FB_CS3 */ | |||
| kFLEXBUS_MultiplexGroup5_FB_BE_7_0 = 0x02U, /*!< FB_BE_7_0 */ | |||
| } flexbus_multiplex_group5_t; | |||
| /*! | |||
| * @brief Configuration structure that the user needs to set. | |||
| */ | |||
| typedef struct _flexbus_config | |||
| { | |||
| uint8_t chip; /*!< Chip FlexBus for validation */ | |||
| uint8_t waitStates; /*!< Value of wait states */ | |||
| uint8_t secondaryWaitStates; /*!< Value of secondary wait states */ | |||
| uint32_t chipBaseAddress; /*!< Chip base address for using FlexBus */ | |||
| uint32_t chipBaseAddressMask; /*!< Chip base address mask */ | |||
| bool writeProtect; /*!< Write protected */ | |||
| bool burstWrite; /*!< Burst-Write enable */ | |||
| bool burstRead; /*!< Burst-Read enable */ | |||
| bool byteEnableMode; /*!< Byte-enable mode support */ | |||
| bool autoAcknowledge; /*!< Auto acknowledge setting */ | |||
| bool extendTransferAddress; /*!< Extend transfer start/extend address latch enable */ | |||
| bool secondaryWaitStatesEnable; /*!< Enable secondary wait states */ | |||
| flexbus_port_size_t portSize; /*!< Port size of transfer */ | |||
| flexbus_bytelane_shift_t byteLaneShift; /*!< Byte-lane shift enable */ | |||
| flexbus_write_address_hold_t writeAddressHold; /*!< Write address hold or deselect option */ | |||
| flexbus_read_address_hold_t readAddressHold; /*!< Read address hold or deselect option */ | |||
| flexbus_address_setup_t addressSetup; /*!< Address setup setting */ | |||
| flexbus_multiplex_group1_t group1MultiplexControl; /*!< FlexBus Signal Group 1 Multiplex control */ | |||
| flexbus_multiplex_group2_t group2MultiplexControl; /*!< FlexBus Signal Group 2 Multiplex control */ | |||
| flexbus_multiplex_group3_t group3MultiplexControl; /*!< FlexBus Signal Group 3 Multiplex control */ | |||
| flexbus_multiplex_group4_t group4MultiplexControl; /*!< FlexBus Signal Group 4 Multiplex control */ | |||
| flexbus_multiplex_group5_t group5MultiplexControl; /*!< FlexBus Signal Group 5 Multiplex control */ | |||
| } flexbus_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /* __cplusplus */ | |||
| /*! | |||
| * @name FlexBus functional operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes and configures the FlexBus module. | |||
| * | |||
| * This function enables the clock gate for FlexBus module. | |||
| * Only chip 0 is validated and set to known values. Other chips are disabled. | |||
| * Note that in this function, certain parameters, depending on external memories, must | |||
| * be set before using the FLEXBUS_Init() function. | |||
| * This example shows how to set up the uart_state_t and the | |||
| * flexbus_config_t parameters and how to call the FLEXBUS_Init function by passing | |||
| * in these parameters. | |||
| @code | |||
| flexbus_config_t flexbusConfig; | |||
| FLEXBUS_GetDefaultConfig(&flexbusConfig); | |||
| flexbusConfig.waitStates = 2U; | |||
| flexbusConfig.chipBaseAddress = 0x60000000U; | |||
| flexbusConfig.chipBaseAddressMask = 7U; | |||
| FLEXBUS_Init(FB, &flexbusConfig); | |||
| @endcode | |||
| * | |||
| * @param base FlexBus peripheral address. | |||
| * @param config Pointer to the configuration structure | |||
| */ | |||
| void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config); | |||
| /*! | |||
| * @brief De-initializes a FlexBus instance. | |||
| * | |||
| * This function disables the clock gate of the FlexBus module clock. | |||
| * | |||
| * @param base FlexBus peripheral address. | |||
| */ | |||
| void FLEXBUS_Deinit(FB_Type *base); | |||
| /*! | |||
| * @brief Initializes the FlexBus configuration structure. | |||
| * | |||
| * This function initializes the FlexBus configuration structure to default value. The default | |||
| * values are. | |||
| @code | |||
| fbConfig->chip = 0; | |||
| fbConfig->writeProtect = 0; | |||
| fbConfig->burstWrite = 0; | |||
| fbConfig->burstRead = 0; | |||
| fbConfig->byteEnableMode = 0; | |||
| fbConfig->autoAcknowledge = true; | |||
| fbConfig->extendTransferAddress = 0; | |||
| fbConfig->secondaryWaitStates = 0; | |||
| fbConfig->byteLaneShift = kFLEXBUS_NotShifted; | |||
| fbConfig->writeAddressHold = kFLEXBUS_Hold1Cycle; | |||
| fbConfig->readAddressHold = kFLEXBUS_Hold1Or0Cycles; | |||
| fbConfig->addressSetup = kFLEXBUS_FirstRisingEdge; | |||
| fbConfig->portSize = kFLEXBUS_1Byte; | |||
| fbConfig->group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_ALE; | |||
| fbConfig->group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_CS4 ; | |||
| fbConfig->group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_CS5; | |||
| fbConfig->group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST; | |||
| fbConfig->group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA; | |||
| @endcode | |||
| * @param config Pointer to the initialization structure. | |||
| * @see FLEXBUS_Init | |||
| */ | |||
| void FLEXBUS_GetDefaultConfig(flexbus_config_t *config); | |||
| /*! @}*/ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /* __cplusplus */ | |||
| /*! @}*/ | |||
| #endif /* _FSL_FLEXBUS_H_ */ | |||
| @@ -0,0 +1,239 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_flexcan_edma.h" | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.flexcan_edma" | |||
| #endif | |||
| /*<! Structure definition for flexcan_edma_private_handle_t. The structure is private. */ | |||
| typedef struct _flexcan_edma_private_handle | |||
| { | |||
| CAN_Type *base; | |||
| flexcan_edma_handle_t *handle; | |||
| } flexcan_edma_private_handle_t; | |||
| /* FlexCAN EDMA transfer handle. */ | |||
| enum _flexcan_edma_tansfer_state | |||
| { | |||
| KFLEXCAN_RxFifoIdle = 0U, /* Rx Fifo idle. */ | |||
| KFLEXCAN_RxFifoBusy = 1U, /* Rx Fifo busy. */ | |||
| }; | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*<! Private handle only used for internally. */ | |||
| static flexcan_edma_private_handle_t s_flexcanEdmaPrivateHandle[FSL_FEATURE_SOC_FLEXCAN_COUNT]; | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief FlexCAN EDMA receive finished callback function. | |||
| * | |||
| * This function is called when FlexCAN Rx FIFO EDMA receive finished. | |||
| * It disables the FlexCAN Rx FIFO EDMA request and sends | |||
| * @ref kStatus_FLEXCAN_RxFifoIdle to FlexCAN EDMA callback. | |||
| * | |||
| * @param handle The EDMA handle. | |||
| * @param param Callback function parameter. | |||
| */ | |||
| static void FLEXCAN_ReceiveFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds); | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| static void FLEXCAN_ReceiveFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) | |||
| { | |||
| handle = handle; | |||
| tcds = tcds; | |||
| flexcan_edma_private_handle_t *flexcanPrivateHandle = (flexcan_edma_private_handle_t *)param; | |||
| if (transferDone) | |||
| { | |||
| /* Disable transfer. */ | |||
| FLEXCAN_TransferAbortReceiveFifoEDMA(flexcanPrivateHandle->base, flexcanPrivateHandle->handle); | |||
| if (NULL != flexcanPrivateHandle->handle->callback) | |||
| { | |||
| flexcanPrivateHandle->handle->callback(flexcanPrivateHandle->base, flexcanPrivateHandle->handle, | |||
| kStatus_FLEXCAN_RxFifoIdle, flexcanPrivateHandle->handle->userData); | |||
| } | |||
| } | |||
| } | |||
| /*! | |||
| * brief Initializes the FlexCAN handle, which is used in transactional functions. | |||
| * | |||
| * param base FlexCAN peripheral base address. | |||
| * param handle Pointer to flexcan_edma_handle_t structure. | |||
| * param callback The callback function. | |||
| * param userData The parameter of the callback function. | |||
| * param rxFifoEdmaHandle User-requested DMA handle for Rx FIFO DMA transfer. | |||
| */ | |||
| void FLEXCAN_TransferCreateHandleEDMA(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| flexcan_edma_transfer_callback_t callback, | |||
| void *userData, | |||
| edma_handle_t *rxFifoEdmaHandle) | |||
| { | |||
| assert(NULL != handle); | |||
| uint32_t instance = FLEXCAN_GetInstance(base); | |||
| s_flexcanEdmaPrivateHandle[instance].base = base; | |||
| s_flexcanEdmaPrivateHandle[instance].handle = handle; | |||
| (void)memset(handle, 0, sizeof(flexcan_edma_handle_t)); | |||
| handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoIdle; | |||
| handle->rxFifoEdmaHandle = rxFifoEdmaHandle; | |||
| /* Register Callback. */ | |||
| handle->callback = callback; | |||
| handle->userData = userData; | |||
| /* Configure Rx FIFO DMA. */ | |||
| EDMA_SetCallback(handle->rxFifoEdmaHandle, FLEXCAN_ReceiveFifoEDMACallback, &s_flexcanEdmaPrivateHandle[instance]); | |||
| } | |||
| /*! | |||
| * brief Prepares the eDMA transfer configuration for FLEXCAN Legacy RX FIFO. | |||
| * | |||
| * This function prepares the eDMA transfer configuration structure according to FLEXCAN Legacy RX FIFO. | |||
| * | |||
| * param base FlexCAN peripheral base address. | |||
| * param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t. | |||
| * param pEdmaConfig The user configuration structure of type edma_transfer_t. | |||
| * | |||
| */ | |||
| void FLEXCAN_PrepareTransfConfiguration(CAN_Type *base, | |||
| flexcan_fifo_transfer_t *pFifoXfer, | |||
| edma_transfer_config_t *pEdmaConfig) | |||
| { | |||
| assert(NULL != pFifoXfer); | |||
| assert(NULL != pFifoXfer->frame); | |||
| assert(NULL != pEdmaConfig); | |||
| flexcan_frame_t *fifoAddr = (flexcan_frame_t *)FLEXCAN_GetRxFifoHeadAddr(base); | |||
| #if (defined(FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER) && FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER) | |||
| EDMA_PrepareTransfer(pEdmaConfig, (void *)fifoAddr, sizeof(flexcan_frame_t), (void *)pFifoXfer->frame, | |||
| sizeof(uint32_t), sizeof(flexcan_frame_t), sizeof(flexcan_frame_t), kEDMA_PeripheralToMemory); | |||
| #else | |||
| /* The Data Size of FLEXCAN Legacy RX FIFO output port is 16 Bytes, but lots of chips not support 16Bytes width DMA | |||
| * transfer. These chips always support 4Byte width memory transfer, so we need prepare Memory to Memory mode by 4 | |||
| * Bytes width mode. | |||
| */ | |||
| EDMA_PrepareTransfer(pEdmaConfig, (void *)fifoAddr, 4U, (void *)pFifoXfer->frame, sizeof(uint32_t), | |||
| sizeof(flexcan_frame_t), sizeof(flexcan_frame_t), kEDMA_MemoryToMemory); | |||
| #endif | |||
| } | |||
| /*! | |||
| * brief Start Transfer Data from the FLEXCAN Legacy Rx FIFO using eDMA. | |||
| * | |||
| * This function to Update edma transfer confiugration and Start eDMA transfer | |||
| * | |||
| * param base FlexCAN peripheral base address. | |||
| * param handle Pointer to flexcan_edma_handle_t structure. | |||
| * param pEdmaConfig The user configuration structure of type edma_transfer_t. | |||
| * retval kStatus_Success if succeed, others failed. | |||
| * retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing. | |||
| */ | |||
| status_t FLEXCAN_StartTransferDatafromRxFIFO(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| edma_transfer_config_t *pEdmaConfig) | |||
| { | |||
| assert(NULL != handle->rxFifoEdmaHandle); | |||
| assert(NULL != pEdmaConfig); | |||
| status_t status; | |||
| /* If previous Rx FIFO receive not finished. */ | |||
| if ((uint8_t)KFLEXCAN_RxFifoBusy == handle->rxFifoState) | |||
| { | |||
| status = kStatus_FLEXCAN_RxFifoBusy; | |||
| } | |||
| else | |||
| { | |||
| handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoBusy; | |||
| /* Enable FlexCAN Rx FIFO EDMA. */ | |||
| FLEXCAN_EnableRxFifoDMA(base, true); | |||
| /* Submit configuration. */ | |||
| (void)EDMA_SubmitTransfer(handle->rxFifoEdmaHandle, (const edma_transfer_config_t *)pEdmaConfig); | |||
| /* Start transfer. */ | |||
| EDMA_StartTransfer(handle->rxFifoEdmaHandle); | |||
| status = kStatus_Success; | |||
| } | |||
| return status; | |||
| } | |||
| /*! | |||
| * brief Receives the CAN Message from the Rx FIFO using eDMA. | |||
| * | |||
| * This function receives the CAN Message using eDMA. This is a non-blocking function, which returns | |||
| * right away. After the CAN Message is received, the receive callback function is called. | |||
| * | |||
| * param base FlexCAN peripheral base address. | |||
| * param handle Pointer to flexcan_edma_handle_t structure. | |||
| * param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t. | |||
| * retval kStatus_Success if succeed, others failed. | |||
| * retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing. | |||
| */ | |||
| status_t FLEXCAN_TransferReceiveFifoEDMA(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| flexcan_fifo_transfer_t *pFifoXfer) | |||
| { | |||
| assert(NULL != handle->rxFifoEdmaHandle); | |||
| edma_transfer_config_t dmaXferConfig; | |||
| status_t status; | |||
| /* Prepare transfer. */ | |||
| FLEXCAN_PrepareTransfConfiguration(base, pFifoXfer, &dmaXferConfig); | |||
| /* Submit configuration and start edma transfer. */ | |||
| status = FLEXCAN_StartTransferDatafromRxFIFO(base, handle, &dmaXferConfig); | |||
| return status; | |||
| } | |||
| /*! | |||
| * brief Aborts the receive process which used eDMA. | |||
| * | |||
| * This function aborts the receive process which used eDMA. | |||
| * | |||
| * param base FlexCAN peripheral base address. | |||
| * param handle Pointer to flexcan_edma_handle_t structure. | |||
| */ | |||
| void FLEXCAN_TransferAbortReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle) | |||
| { | |||
| assert(NULL != handle->rxFifoEdmaHandle); | |||
| /* Stop transfer. */ | |||
| EDMA_AbortTransfer(handle->rxFifoEdmaHandle); | |||
| handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoIdle; | |||
| /* Disable FlexCAN Rx FIFO EDMA. */ | |||
| FLEXCAN_EnableRxFifoDMA(base, false); | |||
| } | |||
| @@ -0,0 +1,140 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_FLEXCAN_EDMA_H_ | |||
| #define _FSL_FLEXCAN_EDMA_H_ | |||
| #include "fsl_flexcan.h" | |||
| #include "fsl_edma.h" | |||
| /*! | |||
| * @addtogroup flexcan_edma_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief FlexCAN EDMA driver version. */ | |||
| #define FSL_FLEXCAN_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 5, 2)) | |||
| /*@}*/ | |||
| /* Forward declaration of the handle typedef. */ | |||
| typedef struct _flexcan_edma_handle flexcan_edma_handle_t; | |||
| /*! @brief FlexCAN transfer callback function. */ | |||
| typedef void (*flexcan_edma_transfer_callback_t)(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| status_t status, | |||
| void *userData); | |||
| /*! | |||
| * @brief FlexCAN eDMA handle | |||
| */ | |||
| struct _flexcan_edma_handle | |||
| { | |||
| flexcan_edma_transfer_callback_t callback; /*!< Callback function. */ | |||
| void *userData; /*!< FlexCAN callback function parameter.*/ | |||
| edma_handle_t *rxFifoEdmaHandle; /*!< The EDMA Rx FIFO channel used. */ | |||
| volatile uint8_t rxFifoState; /*!< Rx FIFO transfer state. */ | |||
| }; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name eDMA transactional | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the FlexCAN handle, which is used in transactional functions. | |||
| * | |||
| * @param base FlexCAN peripheral base address. | |||
| * @param handle Pointer to flexcan_edma_handle_t structure. | |||
| * @param callback The callback function. | |||
| * @param userData The parameter of the callback function. | |||
| * @param rxFifoEdmaHandle User-requested DMA handle for Rx FIFO DMA transfer. | |||
| */ | |||
| void FLEXCAN_TransferCreateHandleEDMA(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| flexcan_edma_transfer_callback_t callback, | |||
| void *userData, | |||
| edma_handle_t *rxFifoEdmaHandle); | |||
| /*! | |||
| * @brief Prepares the eDMA transfer configuration for FLEXCAN Legacy RX FIFO. | |||
| * | |||
| * This function prepares the eDMA transfer configuration structure according to FLEXCAN Legacy RX FIFO. | |||
| * | |||
| * @param base FlexCAN peripheral base address. | |||
| * @param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t. | |||
| * @param pEdmaConfig The user configuration structure of type edma_transfer_t. | |||
| * | |||
| */ | |||
| void FLEXCAN_PrepareTransfConfiguration(CAN_Type *base, | |||
| flexcan_fifo_transfer_t *pFifoXfer, | |||
| edma_transfer_config_t *pEdmaConfig); | |||
| /*! | |||
| * @brief Start Transfer Data from the FLEXCAN Legacy Rx FIFO using eDMA. | |||
| * | |||
| * This function to Update edma transfer confiugration and Start eDMA transfer | |||
| * | |||
| * @param base FlexCAN peripheral base address. | |||
| * @param handle Pointer to flexcan_edma_handle_t structure. | |||
| * @param pEdmaConfig The user configuration structure of type edma_transfer_t. | |||
| * @retval kStatus_Success if succeed, others failed. | |||
| * @retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing. | |||
| */ | |||
| status_t FLEXCAN_StartTransferDatafromRxFIFO(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| edma_transfer_config_t *pEdmaConfig); | |||
| /*! | |||
| * @brief Receives the CAN Message from the Rx FIFO using eDMA. | |||
| * | |||
| * This function receives the CAN Message using eDMA. This is a non-blocking function, which returns | |||
| * right away. After the CAN Message is received, the receive callback function is called. | |||
| * | |||
| * @param base FlexCAN peripheral base address. | |||
| * @param handle Pointer to flexcan_edma_handle_t structure. | |||
| * @param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t. | |||
| * @retval kStatus_Success if succeed, others failed. | |||
| * @retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing. | |||
| */ | |||
| status_t FLEXCAN_TransferReceiveFifoEDMA(CAN_Type *base, | |||
| flexcan_edma_handle_t *handle, | |||
| flexcan_fifo_transfer_t *pFifoXfer); | |||
| /*! | |||
| * @brief Aborts the receive process which used eDMA. | |||
| * | |||
| * This function aborts the receive process which used eDMA. | |||
| * | |||
| * @param base FlexCAN peripheral base address. | |||
| * @param handle Pointer to flexcan_edma_handle_t structure. | |||
| */ | |||
| void FLEXCAN_TransferAbortReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle); | |||
| /*@}*/ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* _FSL_FLEXCAN_EDMA_H_ */ | |||
| @@ -0,0 +1,393 @@ | |||
| /* | |||
| * Copyright 2017-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_ADAPTER_H | |||
| #define FSL_FTFX_ADAPTER_H | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| #define INVALID_REG_MASK (0) | |||
| #define INVALID_REG_SHIFT (0) | |||
| #define INVALID_REG_ADDRESS (NULL) | |||
| #define INVALID_REG_VALUE (0x00U) | |||
| /* @brief Flash register access type defines */ | |||
| #define FTFx_REG8_ACCESS_TYPE volatile uint8_t * | |||
| #define FTFx_REG32_ACCESS_TYPE volatile uint32_t * | |||
| /*! | |||
| * @name Common flash register info defines | |||
| * @{ | |||
| */ | |||
| #if defined(FTFA) | |||
| #define FTFx FTFA | |||
| #define FTFx_BASE FTFA_BASE | |||
| #define FTFx_FSTAT_CCIF_MASK FTFA_FSTAT_CCIF_MASK | |||
| #define FTFx_FSTAT_RDCOLERR_MASK FTFA_FSTAT_RDCOLERR_MASK | |||
| #define FTFx_FSTAT_ACCERR_MASK FTFA_FSTAT_ACCERR_MASK | |||
| #define FTFx_FSTAT_FPVIOL_MASK FTFA_FSTAT_FPVIOL_MASK | |||
| #define FTFx_FSTAT_MGSTAT0_MASK FTFA_FSTAT_MGSTAT0_MASK | |||
| #define FTFx_FSEC_SEC_MASK FTFA_FSEC_SEC_MASK | |||
| #define FTFx_FSEC_KEYEN_MASK FTFA_FSEC_KEYEN_MASK | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM | |||
| #define FTFx_FCNFG_RAMRDY_MASK FTFA_FCNFG_RAMRDY_MASK | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM | |||
| #define FTFx_FCNFG_EEERDY_MASK FTFA_FCNFG_EEERDY_MASK | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ | |||
| #elif defined(FTFE) | |||
| #define FTFx FTFE | |||
| #define FTFx_BASE FTFE_BASE | |||
| #define FTFx_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK | |||
| #define FTFx_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK | |||
| #define FTFx_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK | |||
| #define FTFx_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK | |||
| #define FTFx_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK | |||
| #define FTFx_FSEC_SEC_MASK FTFE_FSEC_SEC_MASK | |||
| #define FTFx_FSEC_KEYEN_MASK FTFE_FSEC_KEYEN_MASK | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM | |||
| #define FTFx_FCNFG_RAMRDY_MASK FTFE_FCNFG_RAMRDY_MASK | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM | |||
| #define FTFx_FCNFG_EEERDY_MASK FTFE_FCNFG_EEERDY_MASK | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ | |||
| #elif defined(FTFL) | |||
| #define FTFx FTFL | |||
| #define FTFx_BASE FTFL_BASE | |||
| #define FTFx_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK | |||
| #define FTFx_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK | |||
| #define FTFx_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK | |||
| #define FTFx_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK | |||
| #define FTFx_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK | |||
| #define FTFx_FSEC_SEC_MASK FTFL_FSEC_SEC_MASK | |||
| #define FTFx_FSEC_KEYEN_MASK FTFL_FSEC_KEYEN_MASK | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM | |||
| #define FTFx_FCNFG_RAMRDY_MASK FTFL_FCNFG_RAMRDY_MASK | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM | |||
| #define FTFx_FCNFG_EEERDY_MASK FTFL_FCNFG_EEERDY_MASK | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ | |||
| #else | |||
| #error "Unknown flash controller" | |||
| #endif | |||
| /*@}*/ | |||
| /*! | |||
| * @name Common flash register access info defines | |||
| * @{ | |||
| */ | |||
| #define FTFx_FCCOB3_REG (FTFx->FCCOB3) | |||
| #define FTFx_FCCOB5_REG (FTFx->FCCOB5) | |||
| #define FTFx_FCCOB6_REG (FTFx->FCCOB6) | |||
| #define FTFx_FCCOB7_REG (FTFx->FCCOB7) | |||
| #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) || defined(FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS) | |||
| #if defined(FTFA_FPROTSL_PROTS_MASK) || defined(FTFE_FPROTSL_PROTS_MASK) || defined(FTFL_FPROTSL_PROTS_MASK) | |||
| #define FTFx_FLASH1_HAS_INT_PROT_REG (1) | |||
| #define FTFx_FPROTSH_REG (FTFx->FPROTSH) | |||
| #define FTFx_FPROTSL_REG (FTFx->FPROTSL) | |||
| #else | |||
| #define FTFx_FLASH1_HAS_INT_PROT_REG (0) | |||
| #endif | |||
| #endif | |||
| #if defined(FTFA_FPROTH0_PROT_MASK) || defined(FTFE_FPROTH0_PROT_MASK) || defined(FTFL_FPROTH0_PROT_MASK) | |||
| #define FTFx_FLASH0_HAS_HIGH_PROT_REG (1) | |||
| #define FTFx_FPROT_HIGH_REG (FTFx->FPROTH3) | |||
| #define FTFx_FPROTH3_REG (FTFx->FPROTH3) | |||
| #define FTFx_FPROTH2_REG (FTFx->FPROTH2) | |||
| #define FTFx_FPROTH1_REG (FTFx->FPROTH1) | |||
| #define FTFx_FPROTH0_REG (FTFx->FPROTH0) | |||
| #else | |||
| #define FTFx_FLASH0_HAS_HIGH_PROT_REG (0) | |||
| #endif | |||
| #if defined(FTFA_FPROTL0_PROT_MASK) || defined(FTFE_FPROTL0_PROT_MASK) || defined(FTFL_FPROTL0_PROT_MASK) | |||
| #define FTFx_FPROT_LOW_REG (FTFx->FPROTL3) | |||
| #define FTFx_FPROTL3_REG (FTFx->FPROTL3) | |||
| #define FTFx_FPROTL2_REG (FTFx->FPROTL2) | |||
| #define FTFx_FPROTL1_REG (FTFx->FPROTL1) | |||
| #define FTFx_FPROTL0_REG (FTFx->FPROTL0) | |||
| #elif defined(FTFA_FPROT0_PROT_MASK) || defined(FTFE_FPROT0_PROT_MASK) || defined(FTFL_FPROT0_PROT_MASK) | |||
| #define FTFx_FPROT_LOW_REG (FTFx->FPROT3) | |||
| #define FTFx_FPROTL3_REG (FTFx->FPROT3) | |||
| #define FTFx_FPROTL2_REG (FTFx->FPROT2) | |||
| #define FTFx_FPROTL1_REG (FTFx->FPROT1) | |||
| #define FTFx_FPROTL0_REG (FTFx->FPROT0) | |||
| #endif | |||
| #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) || defined(FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS) | |||
| #if defined(FTFA_FACSSS_SGSIZE_S_MASK) || defined(FTFE_FACSSS_SGSIZE_S_MASK) || defined(FTFL_FACSSS_SGSIZE_S_MASK) | |||
| #define FTFx_FLASH1_HAS_INT_XACC_REG (1) | |||
| #define FTFx_XACCSH_REG (FTFx->XACCSH) | |||
| #define FTFx_XACCSL_REG (FTFx->XACCSL) | |||
| #define FTFx_FACSSS_REG (FTFx->FACSSS) | |||
| #define FTFx_FACSNS_REG (FTFx->FACSNS) | |||
| #else | |||
| #define FTFx_FLASH1_HAS_INT_XACC_REG (0) | |||
| #endif | |||
| #endif | |||
| #if (defined(FTFA_FACSS_SGSIZE_MASK) || defined(FTFE_FACSS_SGSIZE_MASK) || defined(FTFL_FACSS_SGSIZE_MASK) || \ | |||
| defined(FTFA_FACSS_SGSIZE_S_MASK) || defined(FTFE_FACSS_SGSIZE_S_MASK) || defined(FTFL_FACSS_SGSIZE_S_MASK)) | |||
| #define FTFx_FLASH0_HAS_INT_XACC_REG (1) | |||
| #define FTFx_XACCH3_REG (FTFx->XACCH3) | |||
| #define FTFx_XACCL3_REG (FTFx->XACCL3) | |||
| #define FTFx_FACSS_REG (FTFx->FACSS) | |||
| #define FTFx_FACSN_REG (FTFx->FACSN) | |||
| #else | |||
| #define FTFx_FLASH0_HAS_INT_XACC_REG (0) | |||
| #endif | |||
| /*@}*/ | |||
| /*! | |||
| * @brief MCM cache register access info defines. | |||
| */ | |||
| #if defined(MCM_PLACR_CFCC_MASK) | |||
| #define MCM_CACHE_CLEAR_MASK MCM_PLACR_CFCC_MASK | |||
| #define MCM_CACHE_CLEAR_SHIFT MCM_PLACR_CFCC_SHIFT | |||
| #if defined(MCM0) | |||
| #define MCM0_CACHE_REG MCM0->PLACR | |||
| #elif defined(MCM) && (!defined(MCM1)) | |||
| #define MCM0_CACHE_REG MCM->PLACR | |||
| #endif | |||
| #if defined(MCM1) | |||
| #define MCM1_CACHE_REG MCM1->PLACR | |||
| #elif defined(MCM) && (!defined(MCM0)) | |||
| #define MCM1_CACHE_REG MCM->PLACR | |||
| #endif | |||
| #else | |||
| #define MCM_CACHE_CLEAR_MASK INVALID_REG_MASK | |||
| #define MCM_CACHE_CLEAR_SHIFT INVALID_REG_SHIFT | |||
| #define MCM0_CACHE_REG (INVALID_REG_ADDRESS) | |||
| #define MCM1_CACHE_REG (INVALID_REG_ADDRESS) | |||
| #endif | |||
| /*! | |||
| * @brief FMC cache register access info defines. | |||
| */ | |||
| #if defined(FMC_PFB01CR_S_INV_MASK) | |||
| #define FMC_SPECULATION_INVALIDATE_MASK FMC_PFB01CR_S_INV_MASK | |||
| #define FMC_SPECULATION_INVALIDATE_SHIFT FMC_PFB01CR_S_INV_SHIFT | |||
| #define FMC_SPECULATION_INVALIDATE_REG FMC->PFB01CR | |||
| #elif defined(FMC_PFB01CR_S_B_INV_MASK) | |||
| #define FMC_SPECULATION_INVALIDATE_MASK FMC_PFB01CR_S_B_INV_MASK | |||
| #define FMC_SPECULATION_INVALIDATE_SHIFT FMC_PFB01CR_S_B_INV_SHIFT | |||
| #define FMC_SPECULATION_INVALIDATE_REG FMC->PFB01CR | |||
| #elif defined(FMC_PFB0CR_S_INV_MASK) | |||
| #define FMC_SPECULATION_INVALIDATE_MASK FMC_PFB0CR_S_INV_MASK | |||
| #define FMC_SPECULATION_INVALIDATE_SHIFT FMC_PFB0CR_S_INV_SHIFT | |||
| #define FMC_SPECULATION_INVALIDATE_REG FMC->PFB0CR | |||
| #elif defined(FMC_PFB0CR_S_B_INV_MASK) | |||
| #define FMC_SPECULATION_INVALIDATE_MASK FMC_PFB0CR_S_B_INV_MASK | |||
| #define FMC_SPECULATION_INVALIDATE_SHIFT FMC_PFB0CR_S_B_INV_SHIFT | |||
| #define FMC_SPECULATION_INVALIDATE_REG FMC->PFB0CR | |||
| #else | |||
| #define FMC_SPECULATION_INVALIDATE_MASK INVALID_REG_MASK | |||
| #define FMC_SPECULATION_INVALIDATE_SHIFT INVALID_REG_SHIFT | |||
| #define FMC_SPECULATION_INVALIDATE(x) (((uint32_t)(((uint32_t)(x)) << INVALID_REG_SHIFT)) & INVALID_REG_MASK) | |||
| #define FMC_SPECULATION_INVALIDATE_REG (INVALID_REG_ADDRESS) | |||
| #endif | |||
| #if defined(FMC_PFB01CR_CINV_WAY_MASK) | |||
| #define FMC_CACHE_CLEAR_MASK FMC_PFB01CR_CINV_WAY_MASK | |||
| #define FMC_CACHE_CLEAR_SHIFT FMC_PFB01CR_CINV_WAY_SHIFT | |||
| #define FMC_CACHE_CLEAR(x) FMC_PFB01CR_CINV_WAY(x) | |||
| #elif defined(FMC_PFB0CR_CINV_WAY_MASK) | |||
| #define FMC_CACHE_CLEAR_MASK FMC_PFB0CR_CINV_WAY_MASK | |||
| #define FMC_CACHE_CLEAR_SHIFT FMC_PFB0CR_CINV_WAY_SHIFT | |||
| #define FMC_CACHE_CLEAR(x) FMC_PFB0CR_CINV_WAY(x) | |||
| #else | |||
| #define FMC_CACHE_CLEAR_MASK INVALID_REG_MASK | |||
| #define FMC_CACHE_CLEAR_SHIFT INVALID_REG_SHIFT | |||
| #define FMC_CACHE_CLEAR(x) (((uint32_t)(((uint32_t)(x)) << INVALID_REG_SHIFT)) & INVALID_REG_MASK) | |||
| #endif | |||
| #if defined(FMC_PFB01CR_B0DPE_MASK) | |||
| #define FMC_CACHE_B0DPE_MASK FMC_PFB01CR_B0DPE_MASK | |||
| #define FMC_CACHE_B0IPE_MASK FMC_PFB01CR_B0IPE_MASK | |||
| #define FMC_CACHE_REG FMC->PFB01CR | |||
| #elif defined(FMC_PFB0CR_B0DPE_MASK) | |||
| #define FMC_CACHE_B0DPE_MASK FMC_PFB0CR_B0DPE_MASK | |||
| #define FMC_CACHE_B0IPE_MASK FMC_PFB0CR_B0IPE_MASK | |||
| #define FMC_CACHE_REG FMC->PFB0CR | |||
| #else | |||
| #define FMC_CACHE_B0DPE_MASK INVALID_REG_MASK | |||
| #define FMC_CACHE_B0IPE_MASK INVALID_REG_MASK | |||
| #define FMC_CACHE_REG (INVALID_REG_ADDRESS) | |||
| #endif | |||
| /*! | |||
| * @brief MSCM cache register access info defines. | |||
| */ | |||
| #if defined(MSCM_OCMDR_OCM1_MASK) | |||
| #define MSCM_SPECULATION_SET_MASK MSCM_OCMDR_OCM1_MASK | |||
| #define MSCM_SPECULATION_SET_SHIFT MSCM_OCMDR_OCM1_SHIFT | |||
| #define MSCM_SPECULATION_SET(x) MSCM_OCMDR_OCM1(x) | |||
| #elif defined(MSCM_OCMDR0_OCM1_MASK) || defined(MSCM_OCMDR1_OCM1_MASK) | |||
| #define MSCM_SPECULATION_SET_MASK MSCM_OCMDR0_OCM1_MASK | |||
| #define MSCM_SPECULATION_SET_SHIFT MSCM_OCMDR0_OCM1_SHIFT | |||
| #define MSCM_SPECULATION_SET(x) MSCM_OCMDR0_OCM1(x) | |||
| #elif defined(MSCM_OCMDR_OCMC1_MASK) | |||
| #define MSCM_SPECULATION_SET_MASK MSCM_OCMDR_OCMC1_MASK | |||
| #define MSCM_SPECULATION_SET_SHIFT MSCM_OCMDR_OCMC1_SHIFT | |||
| #define MSCM_SPECULATION_SET(x) MSCM_OCMDR_OCMC1(x) | |||
| #else | |||
| #define MSCM_SPECULATION_SET_MASK INVALID_REG_MASK | |||
| #define MSCM_SPECULATION_SET_SHIFT INVALID_REG_SHIFT | |||
| #define MSCM_SPECULATION_SET(x) (((uint32_t)(((uint32_t)(x)) << INVALID_REG_SHIFT)) & INVALID_REG_MASK) | |||
| #endif | |||
| #if defined(MSCM_OCMDR_OCM2_MASK) | |||
| #define MSCM_CACHE_CLEAR_MASK MSCM_OCMDR_OCM2_MASK | |||
| #define MSCM_CACHE_CLEAR_SHIFT MSCM_OCMDR_OCM2_SHIFT | |||
| #define MSCM_CACHE_CLEAR(x) MSCM_OCMDR_OCM2(x) | |||
| #else | |||
| #define MSCM_CACHE_CLEAR_MASK INVALID_REG_MASK | |||
| #define MSCM_CACHE_CLEAR_SHIFT INVALID_REG_SHIFT | |||
| #define MSCM_CACHE_CLEAR(x) (((uint32_t)(((uint32_t)(x)) << INVALID_REG_SHIFT)) & INVALID_REG_MASK) | |||
| #endif | |||
| #if defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR_OCMC1_MASK) | |||
| #define MSCM_OCMDR0_REG MSCM->OCMDR[0] | |||
| #define MSCM_OCMDR1_REG MSCM->OCMDR[1] | |||
| #elif defined(MSCM_OCMDR0_OCM1_MASK) || defined(MSCM_OCMDR1_OCM1_MASK) | |||
| #define MSCM_OCMDR0_REG MSCM->OCMDR0 | |||
| #define MSCM_OCMDR1_REG MSCM->OCMDR1 | |||
| #else | |||
| #define MSCM_OCMDR0_REG (INVALID_REG_ADDRESS) | |||
| #define MSCM_OCMDR1_REG (INVALID_REG_ADDRESS) | |||
| #endif | |||
| /*! | |||
| * @brief MSCM prefetch speculation defines. | |||
| */ | |||
| #define MSCM_OCMDR_OCMC1_DFDS_MASK (0x10U) | |||
| #define MSCM_OCMDR_OCMC1_DFCS_MASK (0x20U) | |||
| #define MSCM_OCMDR_OCMC1_DFDS_SHIFT (4U) | |||
| #define MSCM_OCMDR_OCMC1_DFCS_SHIFT (5U) | |||
| /*! | |||
| * @brief SIM PFSIZE register access info defines. | |||
| */ | |||
| #if defined(SIM_FCFG1_CORE0_PFSIZE_MASK) | |||
| #define SIM_FLASH0_PFSIZE_MASK SIM_FCFG1_CORE0_PFSIZE_MASK | |||
| #define SIM_FLASH0_PFSIZE_SHIFT SIM_FCFG1_CORE0_PFSIZE_SHIFT | |||
| #define SIM_FCFG1_REG SIM->FCFG1 | |||
| #elif defined(SIM_FCFG1_PFSIZE_MASK) | |||
| #define SIM_FLASH0_PFSIZE_MASK SIM_FCFG1_PFSIZE_MASK | |||
| #define SIM_FLASH0_PFSIZE_SHIFT SIM_FCFG1_PFSIZE_SHIFT | |||
| #define SIM_FCFG1_REG SIM->FCFG1 | |||
| #else | |||
| #define SIM_FLASH0_PFSIZE_MASK INVALID_REG_MASK | |||
| #define SIM_FLASH0_PFSIZE_SHIFT INVALID_REG_SHIFT | |||
| #define SIM_FCFG1_REG INVALID_REG_VALUE | |||
| #endif | |||
| #if defined(SIM_FCFG1_CORE1_PFSIZE_MASK) | |||
| #define SIM_FLASH1_PFSIZE_MASK SIM_FCFG1_CORE1_PFSIZE_MASK | |||
| #define SIM_FLASH1_PFSIZE_SHIFT SIM_FCFG1_CORE1_PFSIZE_SHIFT | |||
| #else | |||
| #define SIM_FLASH1_PFSIZE_MASK INVALID_REG_MASK | |||
| #define SIM_FLASH1_PFSIZE_SHIFT INVALID_REG_SHIFT | |||
| #endif | |||
| /*! | |||
| * @name Dual core/flash configuration | |||
| * @{ | |||
| */ | |||
| /*! @brief Redefines some flash features. */ | |||
| #if defined(FSL_FEATURE_FLASH_CURRENT_CORE_ID) | |||
| #if (FSL_FEATURE_FLASH_CURRENT_CORE_ID == 0u) | |||
| #define FLASH0_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_START_ADDRESS | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH0_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH0_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT | |||
| #define FLASH1_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE | |||
| #if defined(FSL_FEATURE_FLASH_PFLASH_1_SECTOR_CMD_ADDRESS_ALIGMENT) && \ | |||
| defined(FSL_FEATURE_FLASH_PFLASH_1_SECTION_CMD_ADDRESS_ALIGMENT) | |||
| #define FLASH1_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH1_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #else | |||
| #define FLASH1_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH1_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #endif | |||
| #define FLASH1_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_1_PROTECTION_REGION_COUNT | |||
| #elif (FSL_FEATURE_FLASH_CURRENT_CORE_ID == 1u) | |||
| #define FLASH0_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE | |||
| #if defined(FSL_FEATURE_FLASH_PFLASH_1_SECTOR_CMD_ADDRESS_ALIGMENT) && \ | |||
| defined(FSL_FEATURE_FLASH_PFLASH_1_SECTION_CMD_ADDRESS_ALIGMENT) | |||
| #define FLASH0_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH0_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #else | |||
| #define FLASH0_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH0_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #endif | |||
| #define FLASH0_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_1_PROTECTION_REGION_COUNT | |||
| #define FLASH1_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_START_ADDRESS | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH1_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH1_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT | |||
| #endif | |||
| #else /* undfine FSL_FEATURE_FLASH_CURRENT_CORE_ID */ | |||
| #define FLASH0_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_START_ADDRESS | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE | |||
| #define FLASH0_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH0_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH0_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT | |||
| #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) || defined(FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS) | |||
| #define FLASH1_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE | |||
| #define FLASH1_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH1_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT | |||
| #define FLASH1_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT | |||
| #else /* undfine FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH or FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS */ | |||
| #define FLASH1_FEATURE_PFLASH_START_ADDRESS 0 | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_COUNT 0 | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SIZE 0 | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_SECTOR_SIZE 0 | |||
| #define FLASH1_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE 0 | |||
| #define FLASH1_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT 0 | |||
| #define FLASH1_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT 0 | |||
| #define FLASH1_FEATURE_PFLASH_PROTECTION_REGION_COUNT 0 | |||
| #endif | |||
| #endif | |||
| #if FLASH0_FEATURE_PFLASH_PROTECTION_REGION_COUNT > FLASH1_FEATURE_PFLASH_PROTECTION_REGION_COUNT | |||
| #define MAX_FLASH_PROT_REGION_COUNT FLASH0_FEATURE_PFLASH_PROTECTION_REGION_COUNT | |||
| #else | |||
| #define MAX_FLASH_PROT_REGION_COUNT FLASH1_FEATURE_PFLASH_PROTECTION_REGION_COUNT | |||
| #endif | |||
| /*@}*/ | |||
| #endif /* FSL_FTFX_ADAPTER_H */ | |||
| @@ -0,0 +1,549 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #include "fsl_ftfx_cache.h" | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name Flash cache and speculation control defines | |||
| * @{ | |||
| */ | |||
| #if defined(MCM_PLACR_CFCC_MASK) | |||
| #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (1u) | |||
| #else | |||
| #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (0u) | |||
| #endif | |||
| #define FLASH_CACHE_IS_CONTROLLED_BY_MSCM (0u) | |||
| #if defined(FMC_PFB0CR_CINV_WAY_MASK) || defined(FMC_PFB01CR_CINV_WAY_MASK) | |||
| #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (1u) | |||
| #else | |||
| #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (0u) | |||
| #endif | |||
| #if defined(MCM_PLACR_DFCS_MASK) | |||
| #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (1u) | |||
| #else | |||
| #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (0u) | |||
| #endif | |||
| #if defined(MSCM_OCMDR_OCMC1_MASK) || defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR0_OCM1_MASK) || \ | |||
| defined(MSCM_OCMDR1_OCM1_MASK) | |||
| #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (1u) | |||
| #else | |||
| #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (0u) | |||
| #endif | |||
| #if defined(FMC_PFB0CR_S_INV_MASK) || defined(FMC_PFB0CR_S_B_INV_MASK) || defined(FMC_PFB01CR_S_INV_MASK) || \ | |||
| defined(FMC_PFB01CR_S_B_INV_MASK) | |||
| #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (1u) | |||
| #else | |||
| #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (0u) | |||
| #endif | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM || FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC || \ | |||
| FLASH_CACHE_IS_CONTROLLED_BY_MCM || FLASH_CACHE_IS_CONTROLLED_BY_FMC || FLASH_CACHE_IS_CONTROLLED_BY_MSCM | |||
| #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (1) | |||
| #else | |||
| #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (0u) | |||
| #endif | |||
| /*@}*/ | |||
| /*! @brief A function pointer used to point to relocated ftfx_common_bit_operation() */ | |||
| typedef void (*callftfxCommonBitOperation_t)(FTFx_REG32_ACCESS_TYPE base, | |||
| uint32_t bitMask, | |||
| uint32_t bitShift, | |||
| uint32_t bitValue); | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_MCM | |||
| /*! @brief Performs the cache clear to the flash by MCM.*/ | |||
| void mcm_flash_cache_clear(ftfx_cache_config_t *config); | |||
| #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */ | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM | |||
| /*! @brief Performs the cache clear to the flash by MSCM.*/ | |||
| void mscm_flash_cache_clear(ftfx_cache_config_t *config); | |||
| #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MSCM */ | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_FMC | |||
| /*! @brief Performs the cache clear to the flash by FMC.*/ | |||
| void fmc_flash_cache_clear(ftfx_cache_config_t *config); | |||
| #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */ | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM | |||
| /*! @brief Sets the prefetch speculation buffer to the flash by MSCM.*/ | |||
| void mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t *config, bool enable); | |||
| #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */ | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC | |||
| /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/ | |||
| void fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t *config); | |||
| #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| static void ftfx_common_bit_operation_command_sequence( | |||
| ftfx_cache_config_t *config, FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t bitValue); | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE | |||
| /*! @brief Copy flash_cache_clear_command() to RAM*/ | |||
| static void ftfx_copy_common_bit_operation_to_ram(uint32_t *ftfxCommonBitOperation); | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE | |||
| /*! | |||
| * @brief Position independent code of ftfx_common_bit_operation() | |||
| * | |||
| * Note1: The prototype of C function is shown as below: | |||
| * @code | |||
| * void ftfx_common_bit_operation(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t | |||
| * bitValue) | |||
| * { | |||
| * if (bitMask) | |||
| * { | |||
| * uint32_t value = (((uint32_t)(((uint32_t)(bitValue)) << bitShift)) & bitMask); | |||
| * *base = (*base & (~bitMask)) | value; | |||
| * } | |||
| * | |||
| * __ISB(); | |||
| * __DSB(); | |||
| * } | |||
| * @endcode | |||
| * Note2: The binary code is generated by IAR 7.70.1 | |||
| */ | |||
| static const uint32_t s_ftfxCommonBitOperationFunctionCode[] = { | |||
| 0x2900b510u, 0x6804d005u, 0x4093438cu, 0x43214019u, 0xf3bf6001u, 0xf3bf8f6fu, 0xbd108f4fu, | |||
| }; | |||
| #if (!FTFx_DRIVER_IS_EXPORTED) | |||
| /*! @brief A static buffer used to hold ftfx_common_bit_operation() */ | |||
| static uint32_t s_ftfxCommonBitOperation[kFTFx_CACHE_RamFuncMaxSizeInWords]; | |||
| #endif /* (!FTFx_DRIVER_IS_EXPORTED) */ | |||
| #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE && FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| status_t FTFx_CACHE_Init(ftfx_cache_config_t *config) | |||
| { | |||
| if (config == NULL) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| /* copy required flash commands to RAM */ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE | |||
| if (NULL == config->bitOperFuncAddr.callFlashCommand) | |||
| { | |||
| #if FTFx_DRIVER_IS_EXPORTED | |||
| return kStatus_FTFx_ExecuteInRamFunctionNotReady; | |||
| #else | |||
| config->bitOperFuncAddr.commadAddr = (uint32_t)s_ftfxCommonBitOperation; | |||
| #endif /* FTFx_DRIVER_IS_EXPORTED */ | |||
| } | |||
| ftfx_copy_common_bit_operation_to_ram((uint32_t *)config->bitOperFuncAddr.commadAddr); | |||
| #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE && FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| /*! | |||
| * @brief Flash Cache/Prefetch/Speculation Clear Process | |||
| * | |||
| * This function is used to perform the cache and prefetch speculation clear process to the flash. | |||
| */ | |||
| status_t FTFx_CACHE_ClearCachePrefetchSpeculation(ftfx_cache_config_t *config, bool isPreProcess) | |||
| { | |||
| /* We pass the ftfx register address as a parameter to ftfx_common_bit_operation() instead of using | |||
| * pre-processed MACROs or a global variable in ftfx_common_bit_operation() | |||
| * to make sure that ftfx_common_bit_operation() will be compiled into position-independent code (PIC). */ | |||
| if (!isPreProcess) | |||
| { | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_MCM | |||
| mcm_flash_cache_clear(config); | |||
| #endif | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM | |||
| mscm_flash_cache_clear(config); | |||
| #endif | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_FMC | |||
| fmc_flash_cache_clear(config); | |||
| #endif | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM | |||
| mscm_flash_prefetch_speculation_enable(config, true); | |||
| #endif | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC | |||
| fmc_flash_prefetch_speculation_clear(config); | |||
| #endif | |||
| } | |||
| if (isPreProcess) | |||
| { | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM | |||
| mscm_flash_prefetch_speculation_enable(config, false); | |||
| #endif | |||
| } | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| status_t FTFx_CACHE_PflashSetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus) | |||
| { | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM | |||
| { | |||
| if (true == speculationStatus->instructionOff) | |||
| { | |||
| if (false == speculationStatus->dataOff) | |||
| { | |||
| return kStatus_FTFx_InvalidSpeculationOption; | |||
| } | |||
| else | |||
| { | |||
| MCM0_CACHE_REG |= MCM_PLACR_DFCS_MASK; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| MCM0_CACHE_REG &= ~MCM_PLACR_DFCS_MASK; | |||
| if (false == speculationStatus->dataOff) | |||
| { | |||
| MCM0_CACHE_REG |= MCM_PLACR_EFDS_MASK; | |||
| } | |||
| else | |||
| { | |||
| MCM0_CACHE_REG &= ~MCM_PLACR_EFDS_MASK; | |||
| } | |||
| } | |||
| } | |||
| #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC | |||
| { | |||
| if (false == speculationStatus->instructionOff) | |||
| { | |||
| FMC_CACHE_REG |= FMC_CACHE_B0IPE_MASK; | |||
| } | |||
| else | |||
| { | |||
| FMC_CACHE_REG &= ~FMC_CACHE_B0IPE_MASK; | |||
| } | |||
| if (false == speculationStatus->dataOff) | |||
| { | |||
| FMC_CACHE_REG |= FMC_CACHE_B0DPE_MASK; | |||
| } | |||
| else | |||
| { | |||
| FMC_CACHE_REG &= ~FMC_CACHE_B0DPE_MASK; | |||
| } | |||
| /* Invalidate Prefetch Speculation Buffer */ | |||
| FMC_SPECULATION_INVALIDATE_REG |= FMC_SPECULATION_INVALIDATE_MASK; | |||
| } | |||
| #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM | |||
| { | |||
| if (true == speculationStatus->instructionOff) | |||
| { | |||
| if (false == speculationStatus->dataOff) | |||
| { | |||
| return kStatus_FTFx_InvalidSpeculationOption; | |||
| } | |||
| else | |||
| { | |||
| MSCM_OCMDR0_REG |= MSCM_OCMDR_OCMC1_DFCS_MASK; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| MSCM_OCMDR0_REG &= ~MSCM_OCMDR_OCMC1_DFCS_MASK; | |||
| if (false == speculationStatus->dataOff) | |||
| { | |||
| MSCM_OCMDR0_REG &= ~MSCM_OCMDR_OCMC1_DFDS_MASK; | |||
| } | |||
| else | |||
| { | |||
| MSCM_OCMDR0_REG |= MSCM_OCMDR_OCMC1_DFDS_MASK; | |||
| } | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| status_t FTFx_CACHE_PflashGetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus) | |||
| { | |||
| (void)memset(speculationStatus, 0U, sizeof(ftfx_prefetch_speculation_status_t)); | |||
| /* Assuming that all speculation options are enabled. */ | |||
| speculationStatus->instructionOff = false; | |||
| speculationStatus->dataOff = false; | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM | |||
| { | |||
| uint32_t value = MCM0_CACHE_REG; | |||
| if (0U != (value & MCM_PLACR_DFCS_MASK)) | |||
| { | |||
| /* Speculation buffer is off. */ | |||
| speculationStatus->instructionOff = true; | |||
| speculationStatus->dataOff = true; | |||
| } | |||
| else | |||
| { | |||
| /* Speculation buffer is on for instruction. */ | |||
| if (0U == (value & MCM_PLACR_EFDS_MASK)) | |||
| { | |||
| /* Speculation buffer is off for data. */ | |||
| speculationStatus->dataOff = true; | |||
| } | |||
| } | |||
| } | |||
| #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC | |||
| { | |||
| uint32_t value = FMC_CACHE_REG; | |||
| if (0U == (value & FMC_CACHE_B0DPE_MASK)) | |||
| { | |||
| /* Do not prefetch in response to data references. */ | |||
| speculationStatus->dataOff = true; | |||
| } | |||
| if (0U == (value & FMC_CACHE_B0IPE_MASK)) | |||
| { | |||
| /* Do not prefetch in response to instruction fetches. */ | |||
| speculationStatus->instructionOff = true; | |||
| } | |||
| } | |||
| #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM | |||
| { | |||
| uint32_t value = MSCM_OCMDR0_REG; | |||
| if (0U != (value & MSCM_OCMDR_OCMC1_DFCS_MASK)) | |||
| { | |||
| /* Speculation buffer is off. */ | |||
| speculationStatus->instructionOff = true; | |||
| speculationStatus->dataOff = true; | |||
| } | |||
| else | |||
| { | |||
| /* Speculation buffer is on for instruction. */ | |||
| if (0U != (value & MSCM_OCMDR_OCMC1_DFDS_MASK)) | |||
| { | |||
| /* Speculation buffer is off for data. */ | |||
| speculationStatus->dataOff = true; | |||
| } | |||
| } | |||
| } | |||
| #endif | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE | |||
| /*! @brief Copy PIC of ftfx_common_bit_operation() to RAM */ | |||
| static void ftfx_copy_common_bit_operation_to_ram(uint32_t *ftfxCommonBitOperation) | |||
| { | |||
| assert(sizeof(s_ftfxCommonBitOperationFunctionCode) <= ((uint32_t)kFTFx_CACHE_RamFuncMaxSizeInWords * 4U)); | |||
| (void)memcpy(ftfxCommonBitOperation, s_ftfxCommonBitOperationFunctionCode, | |||
| sizeof(s_ftfxCommonBitOperationFunctionCode)); | |||
| } | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE */ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| static void ftfx_common_bit_operation_command_sequence( | |||
| ftfx_cache_config_t *config, FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t bitValue) | |||
| { | |||
| uint32_t *ftfxCommonBitOperationAddr; | |||
| ftfxCommonBitOperationAddr = &config->bitOperFuncAddr.commadAddr; | |||
| /* Since the value of ARM function pointer is always odd, but the real start | |||
| * address | |||
| * of function memory should be even, that's why +1 operation exist. */ | |||
| *ftfxCommonBitOperationAddr += 1UL; | |||
| callftfxCommonBitOperation_t ftfxCommonBitOperationCommand = config->bitOperFuncAddr.callFlashCommand; | |||
| /* Workround for some devices which doesn't need this function */ | |||
| ftfxCommonBitOperationCommand((FTFx_REG32_ACCESS_TYPE)base, bitMask, bitShift, bitValue); | |||
| *ftfxCommonBitOperationAddr -= 1UL; | |||
| } | |||
| #endif /*FTFx_DRIVER_IS_FLASH_RESIDENT*/ | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_MCM | |||
| /*! @brief Performs the cache clear to the flash by MCM.*/ | |||
| void mcm_flash_cache_clear(ftfx_cache_config_t *config) | |||
| { | |||
| FTFx_REG32_ACCESS_TYPE regBase; | |||
| #if defined(MCM0_CACHE_REG) | |||
| regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0_CACHE_REG; | |||
| #elif defined(MCM1_CACHE_REG) | |||
| regBase = (FTFx_REG32_ACCESS_TYPE)&MCM1_CACHE_REG; | |||
| #endif | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, regBase, MCM_CACHE_CLEAR_MASK, MCM_CACHE_CLEAR_SHIFT, 1UL); | |||
| #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| *regBase |= MCM_CACHE_CLEAR_MASK; | |||
| /* Memory barriers for good measure. | |||
| * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ | |||
| __ISB(); | |||
| __DSB(); | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| } | |||
| #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */ | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM | |||
| /*! @brief Performs the cache clear to the flash by MSCM.*/ | |||
| void mscm_flash_cache_clear(ftfx_cache_config_t *config) | |||
| { | |||
| uint8_t setValue = 0x1U; | |||
| /* The OCMDR[0] is always used to cache main Pflash*/ | |||
| /* For device with FlexNVM support, the OCMDR[1] is used to cache Dflash. | |||
| * For device with secondary flash support, the OCMDR[1] is used to cache secondary Pflash. */ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| switch (config->flashMemoryIndex) | |||
| { | |||
| case kFLASH_MemoryIndexSecondaryFlash: | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG, | |||
| MSCM_CACHE_CLEAR_MASK, | |||
| MSCM_CACHE_CLEAR_SHIFT, setValue); | |||
| break; | |||
| case kFLASH_MemoryIndexPrimaryFlash: | |||
| default: | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG, | |||
| MSCM_CACHE_CLEAR_MASK, | |||
| MSCM_CACHE_CLEAR_SHIFT, setValue); | |||
| break; | |||
| } | |||
| #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| switch (config->flashMemoryIndex) | |||
| { | |||
| case kFLASH_MemoryIndexSecondaryFlash: | |||
| MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_CACHE_CLEAR_MASK)) | MSCM_CACHE_CLEAR(setValue); | |||
| /* Each cache clear instruction should be followed by below code*/ | |||
| __ISB(); | |||
| __DSB(); | |||
| break; | |||
| case kFLASH_MemoryIndexPrimaryFlash: | |||
| default: | |||
| MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_CACHE_CLEAR_MASK)) | MSCM_CACHE_CLEAR(setValue); | |||
| /* Memory barriers for good measure. | |||
| * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ | |||
| __ISB(); | |||
| __DSB(); | |||
| break; | |||
| } | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| } | |||
| #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MSCM */ | |||
| #if FLASH_CACHE_IS_CONTROLLED_BY_FMC | |||
| /*! @brief Performs the cache clear to the flash by FMC.*/ | |||
| void fmc_flash_cache_clear(ftfx_cache_config_t *config) | |||
| { | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&FMC_CACHE_REG, | |||
| FMC_CACHE_CLEAR_MASK, FMC_CACHE_CLEAR_SHIFT, 0xFUL); | |||
| #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| FMC_CACHE_REG = (FMC_CACHE_REG & (~FMC_CACHE_CLEAR_MASK)) | FMC_CACHE_CLEAR(~0); | |||
| /* Memory barriers for good measure. | |||
| * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ | |||
| __ISB(); | |||
| __DSB(); | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| } | |||
| #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */ | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM | |||
| /*! @brief Performs the prefetch speculation buffer clear to the flash by MSCM.*/ | |||
| void mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t *config, bool enable) | |||
| { | |||
| uint8_t setValue; | |||
| if (enable) | |||
| { | |||
| setValue = 0x0U; | |||
| } | |||
| else | |||
| { | |||
| setValue = 0x3U; | |||
| } | |||
| /* The OCMDR[0] is always used to prefetch main Pflash*/ | |||
| /* For device with FlexNVM support, the OCMDR[1] is used to prefetch Dflash. | |||
| * For device with secondary flash support, the OCMDR[1] is used to prefetch secondary Pflash. */ | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| switch (config->flashMemoryIndex) | |||
| { | |||
| case 1: | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG, | |||
| MSCM_SPECULATION_SET_MASK, | |||
| MSCM_SPECULATION_SET_SHIFT, setValue); | |||
| break; | |||
| case 0: | |||
| default: | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG, | |||
| MSCM_SPECULATION_SET_MASK, | |||
| MSCM_SPECULATION_SET_SHIFT, setValue); | |||
| break; | |||
| } | |||
| #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| switch (config->flashMemoryIndex) | |||
| { | |||
| case kFLASH_MemoryIndexSecondaryFlash: | |||
| MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_SPECULATION_SET_MASK)) | MSCM_SPECULATION_SET(setValue); | |||
| /* Each cache clear instruction should be followed by below code*/ | |||
| __ISB(); | |||
| __DSB(); | |||
| break; | |||
| case kFLASH_MemoryIndexPrimaryFlash: | |||
| default: | |||
| MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_SPECULATION_SET_MASK)) | MSCM_SPECULATION_SET(setValue); | |||
| /* Memory barriers for good measure. | |||
| * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ | |||
| __ISB(); | |||
| __DSB(); | |||
| break; | |||
| } | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| } | |||
| #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */ | |||
| #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC | |||
| /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/ | |||
| void fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t *config) | |||
| { | |||
| #if FTFx_DRIVER_IS_FLASH_RESIDENT | |||
| /* calling flash command sequence function to execute the command */ | |||
| ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&FMC_SPECULATION_INVALIDATE_REG, | |||
| FMC_SPECULATION_INVALIDATE_MASK, | |||
| FMC_SPECULATION_INVALIDATE_SHIFT, 1UL); | |||
| #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| FMC_SPECULATION_INVALIDATE_REG |= FMC_SPECULATION_INVALIDATE_MASK; | |||
| /* Memory barriers for good measure. | |||
| * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ | |||
| __ISB(); | |||
| __DSB(); | |||
| #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ | |||
| } | |||
| #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */ | |||
| @@ -0,0 +1,124 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_CACHE_H | |||
| #define FSL_FTFX_CACHE_H | |||
| #include "fsl_ftfx_controller.h" | |||
| /*! | |||
| * @addtogroup ftfx_cache_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name FTFx cache version | |||
| * @{ | |||
| */ | |||
| /*! @brief Flexnvm driver version for SDK*/ | |||
| #define FSL_FTFX_CACHE_DRIVER_VERSION (MAKE_VERSION(3, 0, 0)) /*!< Version 1.0.0. */ | |||
| /*@}*/ | |||
| /*! | |||
| * @brief FTFx prefetch speculation status. | |||
| */ | |||
| typedef struct _flash_prefetch_speculation_status | |||
| { | |||
| bool instructionOff; /*!< Instruction speculation.*/ | |||
| bool dataOff; /*!< Data speculation.*/ | |||
| } ftfx_prefetch_speculation_status_t; | |||
| /*! | |||
| * @brief Constants for execute-in-RAM flash function. | |||
| */ | |||
| enum _ftfx_cache_ram_func_constants | |||
| { | |||
| kFTFx_CACHE_RamFuncMaxSizeInWords = 16U, /*!< The maximum size of execute-in-RAM function.*/ | |||
| }; | |||
| typedef union | |||
| { | |||
| uint32_t commadAddr; | |||
| void (*callFlashCommand)(FTFx_REG32_ACCESS_TYPE base, | |||
| uint32_t bitMask, | |||
| uint32_t bitShift, | |||
| uint32_t bitValue); | |||
| }function_bit_operation_ptr_t; | |||
| /*! @brief FTFx cache driver state information. | |||
| * | |||
| * An instance of this structure is allocated by the user of the flash driver and | |||
| * passed into each of the driver APIs. | |||
| */ | |||
| typedef struct _ftfx_cache_config | |||
| { | |||
| uint8_t flashMemoryIndex; /*!< 0 - primary flash; 1 - secondary flash*/ | |||
| uint8_t reserved[3]; | |||
| function_bit_operation_ptr_t bitOperFuncAddr; /*!< An buffer point to the flash execute-in-RAM function. */ | |||
| } ftfx_cache_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @brief Initializes the global FTFx cache structure members. | |||
| * | |||
| * This function checks and initializes the Flash module for the other FTFx cache APIs. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| */ | |||
| status_t FTFx_CACHE_Init(ftfx_cache_config_t *config); | |||
| /*! | |||
| * @brief Process the cache/prefetch/speculation to the flash. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param isPreProcess The possible option used to control flash cache/prefetch/speculation | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument Invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| */ | |||
| status_t FTFx_CACHE_ClearCachePrefetchSpeculation(ftfx_cache_config_t *config, bool isPreProcess); | |||
| /*! | |||
| * @brief Sets the PFlash prefetch speculation to the intended speculation status. | |||
| * | |||
| * @param speculationStatus The expected protect status to set to the PFlash protection register. Each bit is | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidSpeculationOption An invalid speculation option argument is provided. | |||
| */ | |||
| status_t FTFx_CACHE_PflashSetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus); | |||
| /*! | |||
| * @brief Gets the PFlash prefetch speculation status. | |||
| * | |||
| * @param speculationStatus Speculation status returned by the PFlash IP. | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| */ | |||
| status_t FTFx_CACHE_PflashGetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus); | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* FSL_FTFX_CACHE_H */ | |||
| @@ -0,0 +1,822 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_CONTROLLER_H | |||
| #define FSL_FTFX_CONTROLLER_H | |||
| #include "fsl_ftfx_features.h" | |||
| #include "fsl_ftfx_utilities.h" | |||
| /*! | |||
| * @addtogroup ftfx_controller | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.flash" | |||
| #endif | |||
| /*! | |||
| * @name FTFx status | |||
| * @{ | |||
| */ | |||
| /*! @brief FTFx driver status group. */ | |||
| #if defined(kStatusGroup_FlashDriver) | |||
| #define kStatusGroupGeneric kStatusGroup_Generic | |||
| #define kStatusGroupFtfxDriver kStatusGroup_FlashDriver | |||
| #elif defined(kStatusGroup_FLASH) | |||
| #define kStatusGroupGeneric kStatusGroup_Generic | |||
| #define kStatusGroupFtfxDriver kStatusGroup_FLASH | |||
| #else | |||
| #define kStatusGroupGeneric 0 | |||
| #define kStatusGroupFtfxDriver 1 | |||
| #endif | |||
| /*! | |||
| * @brief FTFx driver status codes. | |||
| */ | |||
| enum | |||
| { | |||
| kStatus_FTFx_Success = MAKE_STATUS(kStatusGroupGeneric, 0), /*!< API is executed successfully*/ | |||
| kStatus_FTFx_InvalidArgument = MAKE_STATUS(kStatusGroupGeneric, 4), /*!< Invalid argument*/ | |||
| kStatus_FTFx_SizeError = MAKE_STATUS(kStatusGroupFtfxDriver, 0), /*!< Error size*/ | |||
| kStatus_FTFx_AlignmentError = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 1), /*!< Parameter is not aligned with the specified baseline*/ | |||
| kStatus_FTFx_AddressError = MAKE_STATUS(kStatusGroupFtfxDriver, 2), /*!< Address is out of range */ | |||
| kStatus_FTFx_AccessError = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 3), /*!< Invalid instruction codes and out-of bound addresses */ | |||
| kStatus_FTFx_ProtectionViolation = MAKE_STATUS( | |||
| kStatusGroupFtfxDriver, 4), /*!< The program/erase operation is requested to execute on protected areas */ | |||
| kStatus_FTFx_CommandFailure = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 5), /*!< Run-time error during command execution. */ | |||
| kStatus_FTFx_UnknownProperty = MAKE_STATUS(kStatusGroupFtfxDriver, 6), /*!< Unknown property.*/ | |||
| kStatus_FTFx_EraseKeyError = MAKE_STATUS(kStatusGroupFtfxDriver, 7), /*!< API erase key is invalid.*/ | |||
| kStatus_FTFx_RegionExecuteOnly = MAKE_STATUS(kStatusGroupFtfxDriver, 8), /*!< The current region is execute-only.*/ | |||
| kStatus_FTFx_ExecuteInRamFunctionNotReady = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 9), /*!< Execute-in-RAM function is not available.*/ | |||
| kStatus_FTFx_PartitionStatusUpdateFailure = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 10), /*!< Failed to update partition status.*/ | |||
| kStatus_FTFx_SetFlexramAsEepromError = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 11), /*!< Failed to set FlexRAM as EEPROM.*/ | |||
| kStatus_FTFx_RecoverFlexramAsRamError = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 12), /*!< Failed to recover FlexRAM as RAM.*/ | |||
| kStatus_FTFx_SetFlexramAsRamError = MAKE_STATUS(kStatusGroupFtfxDriver, 13), /*!< Failed to set FlexRAM as RAM.*/ | |||
| kStatus_FTFx_RecoverFlexramAsEepromError = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 14), /*!< Failed to recover FlexRAM as EEPROM.*/ | |||
| kStatus_FTFx_CommandNotSupported = MAKE_STATUS(kStatusGroupFtfxDriver, 15), /*!< Flash API is not supported.*/ | |||
| kStatus_FTFx_SwapSystemNotInUninitialized = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 16), /*!< Swap system is not in an uninitialzed state.*/ | |||
| kStatus_FTFx_SwapIndicatorAddressError = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 17), /*!< The swap indicator address is invalid.*/ | |||
| kStatus_FTFx_ReadOnlyProperty = MAKE_STATUS(kStatusGroupFtfxDriver, 18), /*!< The flash property is read-only.*/ | |||
| kStatus_FTFx_InvalidPropertyValue = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 19), /*!< The flash property value is out of range.*/ | |||
| kStatus_FTFx_InvalidSpeculationOption = | |||
| MAKE_STATUS(kStatusGroupFtfxDriver, 20), /*!< The option of flash prefetch speculation is invalid.*/ | |||
| }; | |||
| /*@}*/ | |||
| /*! | |||
| * @name FTFx API key | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enumeration for FTFx driver API keys. | |||
| * | |||
| * @note The resulting value is built with a byte order such that the string | |||
| * being readable in expected order when viewed in a hex editor, if the value | |||
| * is treated as a 32-bit little endian value. | |||
| */ | |||
| enum _ftfx_driver_api_keys | |||
| { | |||
| kFTFx_ApiEraseKey = FOUR_CHAR_CODE('k', 'f', 'e', 'k') /*!< Key value used to validate all FTFx erase APIs.*/ | |||
| }; | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Enumeration for the FlexRAM load during reset option. | |||
| */ | |||
| typedef enum _ftfx_partition_flexram_load_option | |||
| { | |||
| kFTFx_PartitionFlexramLoadOptLoadedWithValidEepromData = | |||
| 0x00U, /*!< FlexRAM is loaded with valid EEPROM data during reset sequence.*/ | |||
| kFTFx_PartitionFlexramLoadOptNotLoaded = 0x01U /*!< FlexRAM is not loaded during reset sequence.*/ | |||
| } ftfx_partition_flexram_load_opt_t; | |||
| /*! | |||
| * @brief Enumeration for the two possible options of flash read resource command. | |||
| */ | |||
| typedef enum _ftfx_read_resource_opt | |||
| { | |||
| kFTFx_ResourceOptionFlashIfr = | |||
| 0x00U, /*!< Select code for Program flash 0 IFR, Program flash swap 0 IFR, Data flash 0 IFR */ | |||
| kFTFx_ResourceOptionVersionId = 0x01U /*!< Select code for the version ID*/ | |||
| } ftfx_read_resource_opt_t; | |||
| /*! | |||
| * @brief Enumeration for supported FTFx margin levels. | |||
| */ | |||
| typedef enum _ftfx_margin_value | |||
| { | |||
| kFTFx_MarginValueNormal, /*!< Use the 'normal' read level for 1s.*/ | |||
| kFTFx_MarginValueUser, /*!< Apply the 'User' margin to the normal read-1 level.*/ | |||
| kFTFx_MarginValueFactory, /*!< Apply the 'Factory' margin to the normal read-1 level.*/ | |||
| kFTFx_MarginValueInvalid /*!< Not real margin level, Used to determine the range of valid margin level. */ | |||
| } ftfx_margin_value_t; | |||
| /*! | |||
| * @brief Enumeration for the three possible FTFx security states. | |||
| */ | |||
| typedef enum _ftfx_security_state | |||
| { | |||
| kFTFx_SecurityStateNotSecure = (int)0xc33cc33cu, /*!< Flash is not secure.*/ | |||
| kFTFx_SecurityStateBackdoorEnabled = (int)0x5aa55aa5u, /*!< Flash backdoor is enabled.*/ | |||
| kFTFx_SecurityStateBackdoorDisabled = (int)0x5ac33ca5u /*!< Flash backdoor is disabled.*/ | |||
| } ftfx_security_state_t; | |||
| /*! | |||
| * @brief Enumeration for the two possilbe options of set FlexRAM function command. | |||
| */ | |||
| typedef enum _ftfx_flexram_function_option | |||
| { | |||
| kFTFx_FlexramFuncOptAvailableAsRam = 0xFFU, /*!< An option used to make FlexRAM available as RAM */ | |||
| kFTFx_FlexramFuncOptAvailableForEeprom = 0x00U /*!< An option used to make FlexRAM available for EEPROM */ | |||
| } ftfx_flexram_func_opt_t; | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD | |||
| /*! | |||
| * @brief Enumeration for the possible options of Swap control commands | |||
| */ | |||
| typedef enum _ftfx_swap_control_option | |||
| { | |||
| kFTFx_SwapControlOptionIntializeSystem = 0x01U, /*!< An option used to initialize the Swap system */ | |||
| kFTFx_SwapControlOptionSetInUpdateState = 0x02U, /*!< An option used to set the Swap in an update state */ | |||
| kFTFx_SwapControlOptionSetInCompleteState = 0x04U, /*!< An option used to set the Swap in a complete state */ | |||
| kFTFx_SwapControlOptionReportStatus = 0x08U, /*!< An option used to report the Swap status */ | |||
| kFTFx_SwapControlOptionDisableSystem = 0x10U /*!< An option used to disable the Swap status */ | |||
| } ftfx_swap_control_opt_t; | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ | |||
| /*! | |||
| * @brief Enumeration for the possible flash Swap status. | |||
| */ | |||
| typedef enum _ftfx_swap_state | |||
| { | |||
| kFTFx_SwapStateUninitialized = 0x00U, /*!< Flash Swap system is in an uninitialized state.*/ | |||
| kFTFx_SwapStateReady = 0x01U, /*!< Flash Swap system is in a ready state.*/ | |||
| kFTFx_SwapStateUpdate = 0x02U, /*!< Flash Swap system is in an update state.*/ | |||
| kFTFx_SwapStateUpdateErased = 0x03U, /*!< Flash Swap system is in an updateErased state.*/ | |||
| kFTFx_SwapStateComplete = 0x04U, /*!< Flash Swap system is in a complete state.*/ | |||
| kFTFx_SwapStateDisabled = 0x05U /*!< Flash Swap system is in a disabled state.*/ | |||
| } ftfx_swap_state_t; | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD | |||
| /*! | |||
| * @brief Enumeration for the possible flash Swap block status | |||
| */ | |||
| typedef enum _ftfx_swap_block_status | |||
| { | |||
| kFTFx_SwapBlockStatusLowerHalfProgramBlocksAtZero = | |||
| 0x00U, /*!< Swap block status is that lower half program block at zero.*/ | |||
| kFTFx_SwapBlockStatusUpperHalfProgramBlocksAtZero = | |||
| 0x01U, /*!< Swap block status is that upper half program block at zero.*/ | |||
| } ftfx_swap_block_status_t; | |||
| /*! | |||
| * @brief Flash Swap information | |||
| */ | |||
| typedef struct _ftfx_swap_state_config | |||
| { | |||
| ftfx_swap_state_t flashSwapState; /*!<The current Swap system status.*/ | |||
| ftfx_swap_block_status_t currentSwapBlockStatus; /*!< The current Swap block status.*/ | |||
| ftfx_swap_block_status_t nextSwapBlockStatus; /*!< The next Swap block status.*/ | |||
| } ftfx_swap_state_config_t; | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ | |||
| /*! | |||
| * @brief Enumeration for FTFx memory type. | |||
| */ | |||
| enum _ftfx_memory_type | |||
| { | |||
| kFTFx_MemTypePflash = 0x00U, | |||
| kFTFx_MemTypeFlexnvm = 0x01U | |||
| }; | |||
| /*! | |||
| * @brief ftfx special memory access information. | |||
| */ | |||
| typedef struct _ftfx_special_mem | |||
| { | |||
| uint32_t base; /*!< Base address of flash special memory.*/ | |||
| uint32_t size; /*!< size of flash special memory.*/ | |||
| uint32_t count; /*!< flash special memory count.*/ | |||
| } ftfx_spec_mem_t; | |||
| #if defined(__CC_ARM) | |||
| #pragma anon_unions | |||
| #endif | |||
| /*! | |||
| * @brief Flash memory descriptor. | |||
| */ | |||
| typedef struct _ftfx_mem_descriptor | |||
| { | |||
| struct | |||
| { | |||
| uint8_t type; /*!< Type of flash block.*/ | |||
| uint8_t index; /*!< Index of flash block.*/ | |||
| uint8_t reserved[2]; | |||
| }; | |||
| struct | |||
| { | |||
| uint32_t isIndBlock : 1; | |||
| uint32_t hasIndPfsizeReg : 1; | |||
| uint32_t hasProtControl : 1; | |||
| uint32_t hasIndProtReg : 1; | |||
| uint32_t hasXaccControl : 1; | |||
| uint32_t hasIndXaccReg : 1; | |||
| uint32_t : 18; | |||
| uint32_t ProtRegBits : 8; | |||
| } feature; | |||
| uint32_t blockBase; /*!< A base address of the flash block */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS) && FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS | |||
| uint32_t aliasBlockBase; /*!< A base address of the alias flash block */ | |||
| #endif | |||
| uint32_t totalSize; /*!< The size of the flash block. */ | |||
| uint32_t sectorSize; /*!< The size in bytes of a sector of flash. */ | |||
| uint32_t blockCount; /*!< A number of flash blocks. */ | |||
| ftfx_spec_mem_t accessSegmentMem; | |||
| ftfx_spec_mem_t protectRegionMem; | |||
| } ftfx_mem_desc_t; | |||
| /*! | |||
| * @brief Active FTFx information for the current operation. | |||
| */ | |||
| typedef struct _ftfx_ops_config | |||
| { | |||
| uint32_t convertedAddress; /*!< A converted address for the current flash type.*/ | |||
| struct | |||
| { | |||
| uint8_t sectorCmd; | |||
| uint8_t sectionCmd; | |||
| uint8_t resourceCmd; | |||
| uint8_t checkCmd; | |||
| uint8_t swapCtrlCmd; | |||
| uint8_t blockWriteUnitSize; | |||
| uint8_t reserved[2]; | |||
| } addrAligment; | |||
| } ftfx_ops_config_t; | |||
| /*! | |||
| * @brief Flash IFR memory descriptor. | |||
| */ | |||
| typedef struct _ftfx_ifr_descriptor | |||
| { | |||
| struct | |||
| { | |||
| uint32_t has4ByteIdxSupport : 1; | |||
| uint32_t has8ByteIdxSupport : 1; | |||
| uint32_t : 30; | |||
| } feature; | |||
| struct | |||
| { | |||
| uint8_t versionIdStart; /*!< Version ID start address */ | |||
| uint8_t versionIdSize; | |||
| uint16_t ifrMemSize; | |||
| uint32_t pflashIfrStart; /*!< Program Flash 0 IFR start address */ | |||
| uint32_t dflashIfrStart; /*!< Data Flash 0 IFR start address */ | |||
| uint32_t pflashSwapIfrStart; /*!< Program Flash Swap IFR start address*/ | |||
| } resRange; | |||
| struct | |||
| { | |||
| uint16_t mix8byteIdxStart; | |||
| uint16_t mix8byteIdxEnd; | |||
| } idxInfo; | |||
| } ftfx_ifr_desc_t; | |||
| typedef union | |||
| { | |||
| uint32_t commadAddr; | |||
| void (*callFlashCommand)(FTFx_REG8_ACCESS_TYPE FTMRx_fstat); | |||
| } function_ptr_t; | |||
| /*! @brief Flash driver state information. | |||
| * | |||
| * An instance of this structure is allocated by the user of the flash driver and | |||
| * passed into each of the driver APIs. | |||
| */ | |||
| typedef struct _ftfx_config | |||
| { | |||
| ftfx_mem_desc_t flashDesc; | |||
| ftfx_ops_config_t opsConfig; | |||
| uint32_t flexramBlockBase; /*!< The base address of the FlexRAM/acceleration RAM */ | |||
| uint32_t flexramTotalSize; /*!< The size of the FlexRAM/acceleration RAM */ | |||
| uint16_t eepromTotalSize; /*!< The size of EEPROM area which was partitioned from FlexRAM */ | |||
| uint16_t reserved; | |||
| function_ptr_t runCmdFuncAddr; /*!< An buffer point to the flash execute-in-RAM function. */ | |||
| ftfx_ifr_desc_t ifrDesc; | |||
| } ftfx_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the global flash properties structure members. | |||
| * | |||
| * This function checks and initializes the Flash module for the other Flash APIs. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * | |||
| */ | |||
| void FTFx_API_Init(ftfx_config_t *config); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM | |||
| /*! | |||
| * @brief Updates FlexNVM memory partition status according to data flash 0 IFR. | |||
| * | |||
| * This function updates FlexNVM memory partition status. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FTFx_API_UpdateFlexnvmPartitionStatus(ftfx_config_t *config); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Erasing | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Erases the flash sectors encompassed by parameters passed into function. | |||
| * | |||
| * This function erases the appropriate number of flash sectors based on the | |||
| * desired start address and length. | |||
| * | |||
| * @param config The pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be erased. | |||
| * The start address does not need to be sector-aligned but must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words) | |||
| * to be erased. Must be word-aligned. | |||
| * @param key The value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError The parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError The address is out of range. | |||
| * @retval #kStatus_FTFx_EraseKeyError The API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_Erase(ftfx_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key); | |||
| /*! | |||
| * @brief Erases entire flash | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FTFx_CMD_EraseAll(ftfx_config_t *config, uint32_t key); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD | |||
| /*! | |||
| * @brief Erases the entire flash, including protected sectors. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FTFx_CMD_EraseAllUnsecure(ftfx_config_t *config, uint32_t key); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ | |||
| /*! | |||
| * @brief Erases all program flash execute-only segments defined by the FXACC registers. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_EraseAllExecuteOnlySegments(ftfx_config_t *config, uint32_t key); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Programming | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters. | |||
| * | |||
| * This function programs the flash memory with the desired data for a given | |||
| * flash area as determined by the start address and the length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_Program(ftfx_config_t *config, uint32_t start, const uint8_t *src, uint32_t lengthInBytes); | |||
| /*! | |||
| * @brief Programs Program Once Field through parameters. | |||
| * | |||
| * This function programs the Program Once Field with the desired data for a given | |||
| * flash area as determined by the index and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param index The index indicating which area of the Program Once Field to be programmed. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the Program Once Field. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_ProgramOnce(ftfx_config_t *config, uint32_t index, const uint8_t *src, uint32_t lengthInBytes); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters via the Program Section command. | |||
| * | |||
| * This function programs the flash memory with the desired data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_SetFlexramAsRamError Failed to set flexram as RAM. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_RecoverFlexramAsEepromError Failed to recover FlexRAM as EEPROM. | |||
| */ | |||
| status_t FTFx_CMD_ProgramSection(ftfx_config_t *config, uint32_t start, const uint8_t *src, uint32_t lengthInBytes); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD | |||
| /*! | |||
| * @brief Prepares the FlexNVM block for use as data flash, EEPROM backup, or a combination of both and initializes the | |||
| * FlexRAM. | |||
| * | |||
| * @param config Pointer to storage for the driver runtime state. | |||
| * @param option The option used to set FlexRAM load behavior during reset. | |||
| * @param eepromDataSizeCode Determines the amount of FlexRAM used in each of the available EEPROM subsystems. | |||
| * @param flexnvmPartitionCode Specifies how to split the FlexNVM block between data flash memory and EEPROM backup | |||
| * memory supporting EEPROM functions. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument Invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| */ | |||
| status_t FTFx_CMD_ProgramPartition(ftfx_config_t *config, | |||
| ftfx_partition_flexram_load_opt_t option, | |||
| uint32_t eepromDataSizeCode, | |||
| uint32_t flexnvmPartitionCode); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Reading | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Reads the Program Once Field through parameters. | |||
| * | |||
| * This function reads the read once feild with given index and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param index The index indicating the area of program once field to be read. | |||
| * @param dst A pointer to the destination buffer of data that is used to store | |||
| * data to be read. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_ReadOnce(ftfx_config_t *config, uint32_t index, uint8_t *dst, uint32_t lengthInBytes); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD | |||
| /*! | |||
| * @brief Reads the resource with data at locations passed in through parameters. | |||
| * | |||
| * This function reads the flash memory with the desired location for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param dst A pointer to the destination buffer of data that is used to store | |||
| * data to be read. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be read. Must be word-aligned. | |||
| * @param option The resource option which indicates which area should be read back. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_ReadResource( | |||
| ftfx_config_t *config, uint32_t start, uint8_t *dst, uint32_t lengthInBytes, ftfx_read_resource_opt_t option); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Verification | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Verifies an erasure of the desired flash area at a specified margin level. | |||
| * | |||
| * This function checks the appropriate number of flash sectors based on | |||
| * the desired start address and length to check whether the flash is erased | |||
| * to the specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be verified. | |||
| * The start address does not need to be sector-aligned but must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be verified. Must be word-aligned. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_VerifyErase(ftfx_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies erasure of the entire flash at a specified margin level. | |||
| * | |||
| * This function checks whether the flash is erased to the | |||
| * specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_VerifyEraseAll(ftfx_config_t *config, ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies whether the program flash execute-only segments have been erased to | |||
| * the specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_VerifyEraseAllExecuteOnlySegments(ftfx_config_t *config, ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies programming of the desired flash area at a specified margin level. | |||
| * | |||
| * This function verifies the data programed in the flash memory using the | |||
| * Flash Program Check Command and compares it to the expected data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be verified. Must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be verified. Must be word-aligned. | |||
| * @param expectedData A pointer to the expected data that is to be | |||
| * verified against. | |||
| * @param margin Read margin choice. | |||
| * @param failedAddress A pointer to the returned failing address. | |||
| * @param failedData A pointer to the returned failing data. Some derivatives do | |||
| * not include failed data as part of the FCCOBx registers. In this | |||
| * case, zeros are returned upon failure. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_VerifyProgram(ftfx_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| const uint8_t *expectedData, | |||
| ftfx_margin_value_t margin, | |||
| uint32_t *failedAddress, | |||
| uint32_t *failedData); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Security | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Returns the security state via the pointer passed into the function. | |||
| * | |||
| * This function retrieves the current flash security status, including the | |||
| * security enabling state and the backdoor key enabling state. | |||
| * | |||
| * @param config A pointer to storage for the driver runtime state. | |||
| * @param state A pointer to the value returned for the current security status code: | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| */ | |||
| status_t FTFx_REG_GetSecurityState(ftfx_config_t *config, ftfx_security_state_t *state); | |||
| /*! | |||
| * @brief Allows users to bypass security with a backdoor key. | |||
| * | |||
| * If the MCU is in secured state, this function unsecures the MCU by | |||
| * comparing the provided backdoor key with ones in the flash configuration | |||
| * field. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param backdoorKey A pointer to the user buffer containing the backdoor key. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_SecurityBypass(ftfx_config_t *config, const uint8_t *backdoorKey); | |||
| /*@}*/ | |||
| /*! | |||
| * @name FlexRAM | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD | |||
| /*! | |||
| * @brief Sets the FlexRAM function command. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param option The option used to set the work mode of FlexRAM. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_SetFlexramFunction(ftfx_config_t *config, ftfx_flexram_func_opt_t option); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Swap | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD | |||
| /*! | |||
| * @brief Configures the Swap function or checks the swap state of the Flash module. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param address Address used to configure the flash Swap function. | |||
| * @param option The possible option used to configure Flash Swap function or check the flash Swap status | |||
| * @param returnInfo A pointer to the data which is used to return the information of flash Swap. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_SwapIndicatorAddressError Swap indicator address is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FTFx_CMD_SwapControl(ftfx_config_t *config, | |||
| uint32_t address, | |||
| ftfx_swap_control_opt_t option, | |||
| ftfx_swap_state_config_t *returnInfo); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */ | |||
| /*@}*/ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* FSL_FTFX_CONTROLLER_H */ | |||
| @@ -0,0 +1,90 @@ | |||
| /* | |||
| * Copyright 2017-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_FEATURES_H | |||
| #define FSL_FTFX_FEATURES_H | |||
| #if (defined(BL_TARGET_FLASH) || defined(BL_TARGET_ROM) || defined(BL_TARGET_RAM)) | |||
| #include <assert.h> | |||
| #include <string.h> | |||
| #include "fsl_device_registers.h" | |||
| #include "bootloader_common.h" | |||
| #else | |||
| #include "fsl_common.h" | |||
| #endif | |||
| #include "fsl_ftfx_adapter.h" | |||
| /*! | |||
| * @addtogroup ftfx_feature | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name FTFx configuration | |||
| * @{ | |||
| */ | |||
| /*! @brief Flash driver location. */ | |||
| #if !defined(FTFx_DRIVER_IS_FLASH_RESIDENT) | |||
| #if (!defined(BL_TARGET_ROM) && !defined(BL_TARGET_RAM)) | |||
| #define FTFx_DRIVER_IS_FLASH_RESIDENT 1U /*!< Used for the flash resident application. */ | |||
| #else | |||
| #define FTFx_DRIVER_IS_FLASH_RESIDENT 0U /*!< Used for the non-flash resident application. */ | |||
| #endif | |||
| #endif | |||
| /*! @brief Flash Driver Export option */ | |||
| #if !defined(FTFx_DRIVER_IS_EXPORTED) | |||
| #if defined(BL_TARGET_ROM) | |||
| #define FTFx_DRIVER_IS_EXPORTED 1U /*!< Used for the ROM bootloader. */ | |||
| #else | |||
| #define FTFx_DRIVER_IS_EXPORTED 0U /*!< Used for the MCUXpresso SDK application. */ | |||
| #endif | |||
| #endif | |||
| /*@}*/ | |||
| /*! @brief Indicates whether the secondary flash is supported in the Flash driver */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) || defined(FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS) | |||
| #define FTFx_DRIVER_HAS_FLASH1_SUPPORT (1U) | |||
| #define FTFx_FLASH_COUNT (2U) | |||
| #else | |||
| #define FTFx_DRIVER_HAS_FLASH1_SUPPORT (0U) | |||
| #define FTFx_FLASH_COUNT (1U) | |||
| #endif | |||
| /*! | |||
| * @name Secondary flash configuration | |||
| * @{ | |||
| */ | |||
| /*! @brief Indicates whether the secondary flash has its own protection register in flash module. */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FPROTS_PROTS_MASK) | |||
| #define FTFx_FLASH1_HAS_PROT_CONTROL (1U) | |||
| #else | |||
| #define FTFx_FLASH1_HAS_PROT_CONTROL (0U) | |||
| #endif | |||
| /*! @brief Indicates whether the secondary flash has its own Execute-Only access register in flash module. */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FACSSS_SGSIZE_S_MASK) | |||
| #define FTFx_FLASH1_HAS_XACC_CONTROL (1U) | |||
| #else | |||
| #define FTFx_FLASH1_HAS_XACC_CONTROL (0U) | |||
| #endif | |||
| /*@}*/ | |||
| #if FTFx_FLASH1_HAS_XACC_CONTROL || FTFx_FLASH1_HAS_PROT_CONTROL | |||
| #define FTFx_FLASH1_IS_INDEPENDENT_BLOCK (1U) | |||
| #else | |||
| #define FTFx_FLASH1_IS_INDEPENDENT_BLOCK (0U) | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* FSL_FTFX_FEATURES_H */ | |||
| @@ -0,0 +1,663 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_FLASH_H | |||
| #define FSL_FTFX_FLASH_H | |||
| #include "fsl_ftfx_controller.h" | |||
| /*! | |||
| * @addtogroup ftfx_flash_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| #define kStatus_FLASH_Success kStatus_FTFx_Success | |||
| #define kFLASH_ApiEraseKey kFTFx_ApiEraseKey | |||
| /*! | |||
| * @name Flash version | |||
| * @{ | |||
| */ | |||
| /*! @brief Flash driver version for SDK*/ | |||
| #define FSL_FLASH_DRIVER_VERSION (MAKE_VERSION(3U, 0U, 2U)) /*!< Version 3.0.2. */ | |||
| /*! @brief Flash driver version for ROM*/ | |||
| #define FSL_FLASH_DRIVER_VERSION_ROM (MAKE_VERSION(3U, 0U, 0U)) /*!< Version 3.0.0. */ | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Enumeration for the three possible flash protection levels. | |||
| */ | |||
| typedef enum _flash_protection_state | |||
| { | |||
| kFLASH_ProtectionStateUnprotected, /*!< Flash region is not protected.*/ | |||
| kFLASH_ProtectionStateProtected, /*!< Flash region is protected.*/ | |||
| kFLASH_ProtectionStateMixed /*!< Flash is mixed with protected and unprotected region.*/ | |||
| } flash_prot_state_t; | |||
| /*! | |||
| * @brief PFlash protection status | |||
| */ | |||
| typedef union _pflash_protection_status | |||
| { | |||
| uint32_t protl; /*!< PROT[31:0] .*/ | |||
| uint32_t proth; /*!< PROT[63:32].*/ | |||
| uint8_t protsl; /*!< PROTS[7:0] .*/ | |||
| uint8_t protsh; /*!< PROTS[15:8] .*/ | |||
| uint8_t reserved[2]; | |||
| } pflash_prot_status_t; | |||
| #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL | |||
| /*! | |||
| * @brief Enumeration for the three possible flash execute access levels. | |||
| */ | |||
| typedef enum _flash_execute_only_access_state | |||
| { | |||
| kFLASH_AccessStateUnLimited, /*!< Flash region is unlimited.*/ | |||
| kFLASH_AccessStateExecuteOnly, /*!< Flash region is execute only.*/ | |||
| kFLASH_AccessStateMixed /*!< Flash is mixed with unlimited and execute only region.*/ | |||
| } flash_xacc_state_t; | |||
| #endif /* not define FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ | |||
| /*! | |||
| * @brief Enumeration for various flash properties. | |||
| */ | |||
| typedef enum _flash_property_tag | |||
| { | |||
| kFLASH_PropertyPflash0SectorSize = 0x00U, /*!< Pflash sector size property.*/ | |||
| kFLASH_PropertyPflash0TotalSize = 0x01U, /*!< Pflash total size property.*/ | |||
| kFLASH_PropertyPflash0BlockSize = 0x02U, /*!< Pflash block size property.*/ | |||
| kFLASH_PropertyPflash0BlockCount = 0x03U, /*!< Pflash block count property.*/ | |||
| kFLASH_PropertyPflash0BlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/ | |||
| kFLASH_PropertyPflash0FacSupport = 0x05U, /*!< Pflash fac support property.*/ | |||
| kFLASH_PropertyPflash0AccessSegmentSize = 0x06U, /*!< Pflash access segment size property.*/ | |||
| kFLASH_PropertyPflash0AccessSegmentCount = 0x07U, /*!< Pflash access segment count property.*/ | |||
| kFLASH_PropertyPflash1SectorSize = 0x10U, /*!< Pflash sector size property.*/ | |||
| kFLASH_PropertyPflash1TotalSize = 0x11U, /*!< Pflash total size property.*/ | |||
| kFLASH_PropertyPflash1BlockSize = 0x12U, /*!< Pflash block size property.*/ | |||
| kFLASH_PropertyPflash1BlockCount = 0x13U, /*!< Pflash block count property.*/ | |||
| kFLASH_PropertyPflash1BlockBaseAddr = 0x14U, /*!< Pflash block base address property.*/ | |||
| kFLASH_PropertyPflash1FacSupport = 0x15U, /*!< Pflash fac support property.*/ | |||
| kFLASH_PropertyPflash1AccessSegmentSize = 0x16U, /*!< Pflash access segment size property.*/ | |||
| kFLASH_PropertyPflash1AccessSegmentCount = 0x17U, /*!< Pflash access segment count property.*/ | |||
| kFLASH_PropertyFlexRamBlockBaseAddr = 0x20U, /*!< FlexRam block base address property.*/ | |||
| kFLASH_PropertyFlexRamTotalSize = 0x21U, /*!< FlexRam total size property.*/ | |||
| } flash_property_tag_t; | |||
| /*! @brief Flash driver state information. | |||
| * | |||
| * An instance of this structure is allocated by the user of the flash driver and | |||
| * passed into each of the driver APIs. | |||
| */ | |||
| typedef struct _flash_config | |||
| { | |||
| ftfx_config_t ftfxConfig[FTFx_FLASH_COUNT]; | |||
| } flash_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the global flash properties structure members. | |||
| * | |||
| * This function checks and initializes the Flash module for the other Flash APIs. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FLASH_Init(flash_config_t *config); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Erasing | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Erases the Dflash sectors encompassed by parameters passed into function. | |||
| * | |||
| * This function erases the appropriate number of flash sectors based on the | |||
| * desired start address and length. | |||
| * | |||
| * @param config The pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be erased. | |||
| * The start address does not need to be sector-aligned but must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words) | |||
| * to be erased. Must be word-aligned. | |||
| * @param key The value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the appropriate number of flash sectors based on the | |||
| * desired start address and length were erased successfully. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError The parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError The address is out of range. | |||
| * @retval #kStatus_FTFx_EraseKeyError The API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key); | |||
| /*! | |||
| * @brief Erases entire flexnvm | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the all pflash and flexnvm were erased successfully, | |||
| * the swap and eeprom have been reset to unconfigured state. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FLASH_EraseAll(flash_config_t *config, uint32_t key); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD | |||
| /*! | |||
| * @brief Erases the entire flexnvm, including protected sectors. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; | |||
| * the protected sectors of flash were reset to unprotected status. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Programming | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters. | |||
| * | |||
| * This function programs the flash memory with the desired data for a given | |||
| * flash area as determined by the start address and the length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desired data were programed successfully | |||
| * into flash based on desired start address and length. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_Program(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes); | |||
| /*! | |||
| * @brief Program the Program-Once-Field through parameters. | |||
| * | |||
| * This function Program the Program-once-feild with given index and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param index The index indicating the area of program once field to be read. | |||
| * @param src A pointer to the source buffer of data that is used to store | |||
| * data to be write. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; The index indicating the area | |||
| * of program once field was programed successfully. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint8_t *src, uint32_t lengthInBytes); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters via the Program Section command. | |||
| * | |||
| * This function programs the flash memory with the desired data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desired data have been programed successfully into | |||
| * flash based on start address and length. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_SetFlexramAsRamError Failed to set flexram as RAM. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_RecoverFlexramAsEepromError Failed to recover FlexRAM as EEPROM. | |||
| */ | |||
| status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Reading | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD | |||
| /*! | |||
| * @brief Reads the resource with data at locations passed in through parameters. | |||
| * | |||
| * This function reads the flash memory with the desired location for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param dst A pointer to the destination buffer of data that is used to store | |||
| * data to be read. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be read. Must be word-aligned. | |||
| * @param option The resource option which indicates which area should be read back. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the data have been read successfully from | |||
| * program flash IFR, data flash IFR space, and the Version ID field. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_ReadResource( | |||
| flash_config_t *config, uint32_t start, uint8_t *dst, uint32_t lengthInBytes, ftfx_read_resource_opt_t option); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ | |||
| /*! | |||
| * @brief Reads the Program Once Field through parameters. | |||
| * | |||
| * This function reads the read once feild with given index and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param index The index indicating the area of program once field to be read. | |||
| * @param dst A pointer to the destination buffer of data that is used to store | |||
| * data to be read. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the data have been successfuly | |||
| * read form Program flash0 IFR map and Program Once field based on index and length. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_ReadOnce(flash_config_t *config, uint32_t index, uint8_t *dst, uint32_t lengthInBytes); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Verification | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Verifies an erasure of the desired flash area at a specified margin level. | |||
| * | |||
| * This function checks the appropriate number of flash sectors based on | |||
| * the desired start address and length to check whether the flash is erased | |||
| * to the specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be verified. | |||
| * The start address does not need to be sector-aligned but must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be verified. Must be word-aligned. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the specified FLASH region has been erased. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies erasure of the entire flash at a specified margin level. | |||
| * | |||
| * This function checks whether the flash is erased to the | |||
| * specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; all program flash and flexnvm were in erased state. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_VerifyEraseAll(flash_config_t *config, ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies programming of the desired flash area at a specified margin level. | |||
| * | |||
| * This function verifies the data programmed in the flash memory using the | |||
| * Flash Program Check Command and compares it to the expected data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be verified. Must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be verified. Must be word-aligned. | |||
| * @param expectedData A pointer to the expected data that is to be | |||
| * verified against. | |||
| * @param margin Read margin choice. | |||
| * @param failedAddress A pointer to the returned failing address. | |||
| * @param failedData A pointer to the returned failing data. Some derivatives do | |||
| * not include failed data as part of the FCCOBx registers. In this | |||
| * case, zeros are returned upon failure. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desired data have been successfully programed into | |||
| * specified FLASH region. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_VerifyProgram(flash_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| const uint8_t *expectedData, | |||
| ftfx_margin_value_t margin, | |||
| uint32_t *failedAddress, | |||
| uint32_t *failedData); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Security | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Returns the security state via the pointer passed into the function. | |||
| * | |||
| * This function retrieves the current flash security status, including the | |||
| * security enabling state and the backdoor key enabling state. | |||
| * | |||
| * @param config A pointer to storage for the driver runtime state. | |||
| * @param state A pointer to the value returned for the current security status code: | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the security state of flash was stored to state. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| */ | |||
| status_t FLASH_GetSecurityState(flash_config_t *config, ftfx_security_state_t *state); | |||
| /*! | |||
| * @brief Allows users to bypass security with a backdoor key. | |||
| * | |||
| * If the MCU is in secured state, this function unsecures the MCU by | |||
| * comparing the provided backdoor key with ones in the flash configuration | |||
| * field. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param backdoorKey A pointer to the user buffer containing the backdoor key. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey); | |||
| /*@}*/ | |||
| /*! | |||
| * @name FlexRAM | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD | |||
| /*! | |||
| * @brief Sets the FlexRAM function command. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param option The option used to set the work mode of FlexRAM. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the FlexRAM has been successfully configured as RAM or | |||
| * EEPROM. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLASH_SetFlexramFunction(flash_config_t *config, ftfx_flexram_func_opt_t option); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Swap | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP | |||
| /*! | |||
| * @brief Swaps the lower half flash with the higher half flash. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param address Address used to configure the flash swap function | |||
| * @param isSetEnable The possible option used to configure the Flash Swap function or check the flash Swap status. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the lower half flash and higher half flash have been | |||
| * swaped. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_SwapIndicatorAddressError Swap indicator address is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_SwapSystemNotInUninitialized Swap system is not in an uninitialized state. | |||
| */ | |||
| status_t FLASH_Swap(flash_config_t *config, uint32_t address, bool isSetEnable); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Protection | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Returns the protection state of the desired flash area via the pointer passed into the function. | |||
| * | |||
| * This function retrieves the current flash protect status for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be checked. Must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words) | |||
| * to be checked. Must be word-aligned. | |||
| * @param protection_state A pointer to the value returned for the current | |||
| * protection status code for the desired flash area. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the protection state of specified FLASH region was | |||
| * stored to protection_state. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError The address is out of range. | |||
| */ | |||
| status_t FLASH_IsProtected(flash_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| flash_prot_state_t *protection_state); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL | |||
| /*! | |||
| * @brief Returns the access state of the desired flash area via the pointer passed into the function. | |||
| * | |||
| * This function retrieves the current flash access status for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be checked. Must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be checked. Must be word-aligned. | |||
| * @param access_state A pointer to the value returned for the current | |||
| * access status code for the desired flash area. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the executeOnly state of specified FLASH region was | |||
| * stored to access_state. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError The parameter is not aligned to the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError The address is out of range. | |||
| */ | |||
| status_t FLASH_IsExecuteOnly(flash_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| flash_xacc_state_t *access_state); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ | |||
| /*! | |||
| * @brief Sets the PFlash Protection to the intended protection status. | |||
| * | |||
| * @param config A pointer to storage for the driver runtime state. | |||
| * @param protectStatus The expected protect status to set to the PFlash protection register. Each bit is | |||
| * corresponding to protection of 1/32(64) of the total PFlash. The least significant bit is corresponding to the lowest | |||
| * address area of PFlash. The most significant bit is corresponding to the highest address area of PFlash. There are | |||
| * two possible cases as shown below: | |||
| * 0: this area is protected. | |||
| * 1: this area is unprotected. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the specified FLASH region is protected. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| */ | |||
| status_t FLASH_PflashSetProtection(flash_config_t *config, pflash_prot_status_t *protectStatus); | |||
| /*! | |||
| * @brief Gets the PFlash protection status. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param protectStatus Protect status returned by the PFlash IP. Each bit is corresponding to the protection of | |||
| * 1/32(64) | |||
| * of the | |||
| * total PFlash. The least significant bit corresponds to the lowest address area of the PFlash. The most significant | |||
| * bit corresponds to the highest address area of PFlash. There are two possible cases as shown below: | |||
| * 0: this area is protected. | |||
| * 1: this area is unprotected. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the Protection state was stored to protectStatus; | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| */ | |||
| status_t FLASH_PflashGetProtection(flash_config_t *config, pflash_prot_status_t *protectStatus); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Properties | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Returns the desired flash property. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param whichProperty The desired property from the list of properties in | |||
| * enum flash_property_tag_t | |||
| * @param value A pointer to the value returned for the desired flash property. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the flash property was stored to value. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_UnknownProperty An unknown property tag. | |||
| */ | |||
| status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value); | |||
| /*@}*/ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* FSL_FTFX_FLASH_H */ | |||
| @@ -0,0 +1,506 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #include "fsl_ftfx_flexnvm.h" | |||
| #if FSL_FEATURE_FLASH_HAS_FLEX_NVM | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! @brief Convert address for Flexnvm dflash.*/ | |||
| static status_t flexnvm_convert_start_address(flexnvm_config_t *config, uint32_t start); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| status_t FLEXNVM_Init(flexnvm_config_t *config) | |||
| { | |||
| status_t returnCode; | |||
| if (config == NULL) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| config->ftfxConfig.flashDesc.type = (uint8_t)kFTFx_MemTypeFlexnvm; | |||
| config->ftfxConfig.flashDesc.index = 0U; | |||
| /* Set Flexnvm memory operation parameters */ | |||
| config->ftfxConfig.opsConfig.addrAligment.blockWriteUnitSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE; | |||
| config->ftfxConfig.opsConfig.addrAligment.sectorCmd = FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT; | |||
| config->ftfxConfig.opsConfig.addrAligment.sectionCmd = FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT; | |||
| config->ftfxConfig.opsConfig.addrAligment.resourceCmd = FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT; | |||
| config->ftfxConfig.opsConfig.addrAligment.checkCmd = FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT; | |||
| /* Set Flexnvm memory properties */ | |||
| config->ftfxConfig.flashDesc.blockBase = FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS; | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS) && FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS | |||
| config->ftfxConfig.flashDesc.aliasBlockBase = FSL_FEATURE_FLASH_FLEX_NVM_ALIAS_START_ADDRESS; | |||
| #endif | |||
| config->ftfxConfig.flashDesc.sectorSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; | |||
| config->ftfxConfig.flashDesc.blockCount = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; | |||
| /* Init FTFx Kernel */ | |||
| FTFx_API_Init(&config->ftfxConfig); | |||
| returnCode = FTFx_API_UpdateFlexnvmPartitionStatus(&config->ftfxConfig); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return returnCode; | |||
| } | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| /*! | |||
| * @brief Erases the Dflash sectors encompassed by parameters passed into function. | |||
| */ | |||
| status_t FLEXNVM_DflashErase(flexnvm_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key) | |||
| { | |||
| status_t returnCode; | |||
| returnCode = flexnvm_convert_start_address(config, start); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return returnCode; | |||
| } | |||
| return FTFx_CMD_Erase(&config->ftfxConfig, start, lengthInBytes, key); | |||
| } | |||
| /*! | |||
| * @brief Erases entire flexnvm | |||
| */ | |||
| status_t FLEXNVM_EraseAll(flexnvm_config_t *config, uint32_t key) | |||
| { | |||
| return FTFx_CMD_EraseAll(&config->ftfxConfig, key); | |||
| } | |||
| #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD | |||
| /*! | |||
| * @brief Erases the entire flexnvm, including protected sectors. | |||
| */ | |||
| status_t FLEXNVM_EraseAllUnsecure(flexnvm_config_t *config, uint32_t key) | |||
| { | |||
| return FTFx_CMD_EraseAllUnsecure(&config->ftfxConfig, key); | |||
| } | |||
| #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters. | |||
| */ | |||
| status_t FLEXNVM_DflashProgram(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes) | |||
| { | |||
| status_t returnCode; | |||
| returnCode = flexnvm_convert_start_address(config, start); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return returnCode; | |||
| } | |||
| return FTFx_CMD_Program(&config->ftfxConfig, start, src, lengthInBytes); | |||
| } | |||
| #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters via the Program Section command. | |||
| */ | |||
| status_t FLEXNVM_DflashProgramSection(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes) | |||
| { | |||
| status_t returnCode; | |||
| /* Convert address for Flexnvm dflash */ | |||
| returnCode = flexnvm_convert_start_address(config, start); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return returnCode; | |||
| } | |||
| return FTFx_CMD_ProgramSection(&config->ftfxConfig, start, src, lengthInBytes); | |||
| } | |||
| #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ | |||
| /*! | |||
| * @brief Prepares the FlexNVM block for use as data flash, EEPROM backup, or a combination | |||
| * of both and initializes the FlexRAM. | |||
| */ | |||
| status_t FLEXNVM_ProgramPartition(flexnvm_config_t *config, | |||
| ftfx_partition_flexram_load_opt_t option, | |||
| uint32_t eepromDataSizeCode, | |||
| uint32_t flexnvmPartitionCode) | |||
| { | |||
| return FTFx_CMD_ProgramPartition(&config->ftfxConfig, option, eepromDataSizeCode, flexnvmPartitionCode); | |||
| } | |||
| #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD | |||
| /*! | |||
| * @brief Reads the resource with data at locations passed in through parameters. | |||
| */ | |||
| status_t FLEXNVM_ReadResource( | |||
| flexnvm_config_t *config, uint32_t start, uint8_t *dst, uint32_t lengthInBytes, ftfx_read_resource_opt_t option) | |||
| { | |||
| return FTFx_CMD_ReadResource(&config->ftfxConfig, start, dst, lengthInBytes, option); | |||
| } | |||
| #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ | |||
| /*! | |||
| * @brief Verifies an erasure of the desired flash area at a specified margin level. | |||
| */ | |||
| status_t FLEXNVM_DflashVerifyErase(flexnvm_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| ftfx_margin_value_t margin) | |||
| { | |||
| status_t returnCode; | |||
| returnCode = flexnvm_convert_start_address(config, start); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return returnCode; | |||
| } | |||
| return FTFx_CMD_VerifyErase(&config->ftfxConfig, start, lengthInBytes, margin); | |||
| } | |||
| /*! | |||
| * @brief Verifies erasure of the entire flash at a specified margin level. | |||
| */ | |||
| status_t FLEXNVM_VerifyEraseAll(flexnvm_config_t *config, ftfx_margin_value_t margin) | |||
| { | |||
| return FTFx_CMD_VerifyEraseAll(&config->ftfxConfig, margin); | |||
| } | |||
| /*! | |||
| * @brief Verifies programming of the desired flash area at a specified margin level. | |||
| */ | |||
| status_t FLEXNVM_DflashVerifyProgram(flexnvm_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| const uint8_t *expectedData, | |||
| ftfx_margin_value_t margin, | |||
| uint32_t *failedAddress, | |||
| uint32_t *failedData) | |||
| { | |||
| status_t returnCode; | |||
| returnCode = flexnvm_convert_start_address(config, start); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return returnCode; | |||
| } | |||
| return FTFx_CMD_VerifyProgram(&config->ftfxConfig, start, lengthInBytes, expectedData, margin, failedAddress, | |||
| failedData); | |||
| } | |||
| /*! | |||
| * @brief Returns the security state via the pointer passed into the function. | |||
| */ | |||
| status_t FLEXNVM_GetSecurityState(flexnvm_config_t *config, ftfx_security_state_t *state) | |||
| { | |||
| return FTFx_REG_GetSecurityState(&config->ftfxConfig, state); | |||
| } | |||
| /*! | |||
| * @brief Allows users to bypass security with a backdoor key. | |||
| */ | |||
| status_t FLEXNVM_SecurityBypass(flexnvm_config_t *config, const uint8_t *backdoorKey) | |||
| { | |||
| return FTFx_CMD_SecurityBypass(&config->ftfxConfig, backdoorKey); | |||
| } | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD | |||
| /*! | |||
| * @brief Sets the FlexRAM function command. | |||
| */ | |||
| status_t FLEXNVM_SetFlexramFunction(flexnvm_config_t *config, ftfx_flexram_func_opt_t option) | |||
| { | |||
| return FTFx_CMD_SetFlexramFunction(&config->ftfxConfig, option); | |||
| } | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ | |||
| /*! | |||
| * @brief Programs the EEPROM with data at locations passed in through parameters. | |||
| */ | |||
| status_t FLEXNVM_EepromWrite(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes) | |||
| { | |||
| status_t returnCode; | |||
| bool needSwitchFlexRamMode = false; | |||
| if (config == NULL) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| /* Validates the range of the given address */ | |||
| if ((start < config->ftfxConfig.flexramBlockBase) || | |||
| ((start + lengthInBytes) > (config->ftfxConfig.flexramBlockBase + config->ftfxConfig.eepromTotalSize))) | |||
| { | |||
| return kStatus_FTFx_AddressError; | |||
| } | |||
| returnCode = kStatus_FTFx_Success; | |||
| /* Switch function of FlexRAM if needed */ | |||
| if (0U == (FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) | |||
| { | |||
| needSwitchFlexRamMode = true; | |||
| returnCode = FTFx_CMD_SetFlexramFunction(&config->ftfxConfig, kFTFx_FlexramFuncOptAvailableForEeprom); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return kStatus_FTFx_SetFlexramAsEepromError; | |||
| } | |||
| } | |||
| /* Write data to FlexRAM when it is used as EEPROM emulator */ | |||
| while (lengthInBytes > 0U) | |||
| { | |||
| if ((0U == (start & 0x3U)) && (0U == ((uint32_t)src & 0x3U)) && (lengthInBytes >= 4U)) | |||
| { | |||
| *(uint32_t *)start = *(uint32_t *)(uint32_t)src; | |||
| start += 4U; | |||
| src = &src[4]; | |||
| lengthInBytes -= 4U; | |||
| } | |||
| else if ((0U == (start & 0x1U)) && (0U == ((uint32_t)src & 0x1U)) && (lengthInBytes >= 2U)) | |||
| { | |||
| *(uint16_t *)start = *(uint16_t *)(uint32_t)src; | |||
| start += 2U; | |||
| src = &src[2]; | |||
| lengthInBytes -= 2U; | |||
| } | |||
| else | |||
| { | |||
| *(uint8_t *)start = *src; | |||
| start += 1U; | |||
| src = &src[1]; | |||
| lengthInBytes -= 1U; | |||
| } | |||
| /* Wait till EEERDY bit is set */ | |||
| while (0U == (FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK)) | |||
| { | |||
| } | |||
| /* Check for protection violation error */ | |||
| if (0U != (FTFx->FSTAT & FTFx_FSTAT_FPVIOL_MASK)) | |||
| { | |||
| return kStatus_FTFx_ProtectionViolation; | |||
| } | |||
| } | |||
| /* Switch function of FlexRAM if needed */ | |||
| if (needSwitchFlexRamMode) | |||
| { | |||
| returnCode = FTFx_CMD_SetFlexramFunction(&config->ftfxConfig, kFTFx_FlexramFuncOptAvailableAsRam); | |||
| if (returnCode != kStatus_FTFx_Success) | |||
| { | |||
| return kStatus_FTFx_RecoverFlexramAsRamError; | |||
| } | |||
| } | |||
| return returnCode; | |||
| } | |||
| /*! | |||
| * @brief Sets the DFlash protection to the intended protection status. | |||
| */ | |||
| status_t FLEXNVM_DflashSetProtection(flexnvm_config_t *config, uint8_t protectStatus) | |||
| { | |||
| if (config == NULL) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| if ((config->ftfxConfig.flashDesc.totalSize == 0U) || (config->ftfxConfig.flashDesc.totalSize == 0xFFFFFFFFU)) | |||
| { | |||
| return kStatus_FTFx_CommandNotSupported; | |||
| } | |||
| /* Individual data flash regions will be protected from program and erase operations by setting the | |||
| * associated DPROT bit to the protected state. Each FDPROT bit only be changed from 1s to 0s, | |||
| * meaning the protection can only be increased */ | |||
| FTFx->FDPROT = protectStatus; | |||
| if (FTFx->FDPROT != protectStatus) | |||
| { | |||
| return kStatus_FTFx_CommandFailure; | |||
| } | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| /*! | |||
| * @brief Gets the DFlash protection status. | |||
| */ | |||
| status_t FLEXNVM_DflashGetProtection(flexnvm_config_t *config, uint8_t *protectStatus) | |||
| { | |||
| if ((config == NULL) || (protectStatus == NULL)) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| if ((config->ftfxConfig.flashDesc.totalSize == 0U) || (config->ftfxConfig.flashDesc.totalSize == 0xFFFFFFFFU)) | |||
| { | |||
| return kStatus_FTFx_CommandNotSupported; | |||
| } | |||
| /* return the flexnvm DFlash protection status */ | |||
| *protectStatus = FTFx->FDPROT; | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| /*! | |||
| * @brief Sets the EEPROM protection to the intended protection status. | |||
| */ | |||
| status_t FLEXNVM_EepromSetProtection(flexnvm_config_t *config, uint8_t protectStatus) | |||
| { | |||
| if (config == NULL) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| if ((config->ftfxConfig.eepromTotalSize == 0U) || (config->ftfxConfig.eepromTotalSize == 0xFFFFU)) | |||
| { | |||
| return kStatus_FTFx_CommandNotSupported; | |||
| } | |||
| /* Individual data flash regions will be protected from program and erase operations by setting the | |||
| * associated FEPROT bit to the protected state; Each FEPROT bit only be changed from 1s to 0s, | |||
| * meaning the protection can only be increased. */ | |||
| FTFx->FEPROT = protectStatus; | |||
| if (FTFx->FEPROT != protectStatus) | |||
| { | |||
| return kStatus_FTFx_CommandFailure; | |||
| } | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| /*! | |||
| * @brief Gets the EEPROM protection status. | |||
| */ | |||
| status_t FLEXNVM_EepromGetProtection(flexnvm_config_t *config, uint8_t *protectStatus) | |||
| { | |||
| if ((config == NULL) || (protectStatus == NULL)) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| if ((config->ftfxConfig.eepromTotalSize == 0U) || (config->ftfxConfig.eepromTotalSize == 0xFFFFU)) | |||
| { | |||
| return kStatus_FTFx_CommandNotSupported; | |||
| } | |||
| /* return EEPROM protection status */ | |||
| *protectStatus = FTFx->FEPROT; | |||
| return kStatus_FTFx_Success; | |||
| } | |||
| /*! | |||
| * @brief Returns the desired flexnvm property. | |||
| */ | |||
| status_t FLEXNVM_GetProperty(flexnvm_config_t *config, flexnvm_property_tag_t whichProperty, uint32_t *value) | |||
| { | |||
| if ((config == NULL) || (value == NULL)) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| status_t status = kStatus_FTFx_Success; | |||
| switch (whichProperty) | |||
| { | |||
| /* get flexnvm date flash sector size */ | |||
| case kFLEXNVM_PropertyDflashSectorSize: | |||
| *value = config->ftfxConfig.flashDesc.sectorSize; | |||
| break; | |||
| /* get flexnvm date flash total size */ | |||
| case kFLEXNVM_PropertyDflashTotalSize: | |||
| *value = config->ftfxConfig.flashDesc.totalSize; | |||
| break; | |||
| /* get flexnvm date flash block size */ | |||
| case kFLEXNVM_PropertyDflashBlockSize: | |||
| *value = config->ftfxConfig.flashDesc.totalSize / config->ftfxConfig.flashDesc.blockCount; | |||
| break; | |||
| /* get flexnvm date flash block cont */ | |||
| case kFLEXNVM_PropertyDflashBlockCount: | |||
| *value = config->ftfxConfig.flashDesc.blockCount; | |||
| break; | |||
| /* get flexnvm date flash block base address */ | |||
| case kFLEXNVM_PropertyDflashBlockBaseAddr: | |||
| *value = config->ftfxConfig.flashDesc.blockBase; | |||
| break; | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS) && FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS | |||
| case kFLEXNVM_PropertyAliasDflashBlockBaseAddr: | |||
| *value = config->ftfxConfig.flashDesc.aliasBlockBase; | |||
| break; | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS */ | |||
| case kFLEXNVM_PropertyFlexRamBlockBaseAddr: | |||
| *value = config->ftfxConfig.flexramBlockBase; | |||
| break; | |||
| /* get flexram total size */ | |||
| case kFLEXNVM_PropertyFlexRamTotalSize: | |||
| *value = config->ftfxConfig.flexramTotalSize; | |||
| break; | |||
| /* get flexnvm eeprom total size */ | |||
| case kFLEXNVM_PropertyEepromTotalSize: | |||
| *value = config->ftfxConfig.eepromTotalSize; | |||
| break; | |||
| /* catch inputs that are not recognized */ | |||
| default: | |||
| status = kStatus_FTFx_UnknownProperty; | |||
| break; | |||
| } | |||
| return status; | |||
| } | |||
| /*! @brief Convert address for Flexnvm dflash.*/ | |||
| static status_t flexnvm_convert_start_address(flexnvm_config_t *config, uint32_t start) | |||
| { | |||
| status_t status = kStatus_FTFx_AddressError; | |||
| if (config == NULL) | |||
| { | |||
| return kStatus_FTFx_InvalidArgument; | |||
| } | |||
| /* From Spec: When required by the command, address bit 23 selects between program flash memory | |||
| * (=0) and data flash memory (=1).*/ | |||
| if (start >= config->ftfxConfig.flashDesc.blockBase) | |||
| { | |||
| config->ftfxConfig.opsConfig.convertedAddress = start - config->ftfxConfig.flashDesc.blockBase + 0x800000U; | |||
| status = kStatus_FTFx_Success; | |||
| } | |||
| #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS) && FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS | |||
| /* for MKW39/38/37 which have alias blockBase */ | |||
| else if (start >= config->ftfxConfig.flashDesc.aliasBlockBase) | |||
| { | |||
| config->ftfxConfig.opsConfig.convertedAddress = start - config->ftfxConfig.flashDesc.aliasBlockBase + 0x800000U; | |||
| status = kStatus_FTFx_Success; | |||
| } | |||
| else | |||
| { | |||
| status = kStatus_FTFx_Success; | |||
| } | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM_ALIAS */ | |||
| return status; | |||
| } | |||
| #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */ | |||
| @@ -0,0 +1,572 @@ | |||
| /* | |||
| * Copyright 2013-2016 Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_FLEXNVM_H | |||
| #define FSL_FTFX_FLEXNVM_H | |||
| #include "fsl_ftfx_controller.h" | |||
| /*! | |||
| * @addtogroup ftfx_flexnvm_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @name Flexnvm version | |||
| * @{ | |||
| */ | |||
| /*! @brief Flexnvm driver version for SDK*/ | |||
| #define FSL_FLEXNVM_DRIVER_VERSION (MAKE_VERSION(3, 0, 2)) /*!< Version 3.0.2. */ | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Enumeration for various flexnvm properties. | |||
| */ | |||
| typedef enum _flexnvm_property_tag | |||
| { | |||
| kFLEXNVM_PropertyDflashSectorSize = 0x00U, /*!< Dflash sector size property.*/ | |||
| kFLEXNVM_PropertyDflashTotalSize = 0x01U, /*!< Dflash total size property.*/ | |||
| kFLEXNVM_PropertyDflashBlockSize = 0x02U, /*!< Dflash block size property.*/ | |||
| kFLEXNVM_PropertyDflashBlockCount = 0x03U, /*!< Dflash block count property.*/ | |||
| kFLEXNVM_PropertyDflashBlockBaseAddr = 0x04U, /*!< Dflash block base address property.*/ | |||
| kFLEXNVM_PropertyAliasDflashBlockBaseAddr = 0x05U, /*!< Dflash block base address Alias property.*/ | |||
| kFLEXNVM_PropertyFlexRamBlockBaseAddr = 0x06U, /*!< FlexRam block base address property.*/ | |||
| kFLEXNVM_PropertyFlexRamTotalSize = 0x07U, /*!< FlexRam total size property.*/ | |||
| kFLEXNVM_PropertyEepromTotalSize = 0x08U, /*!< EEPROM total size property.*/ | |||
| } flexnvm_property_tag_t; | |||
| /*! @brief Flexnvm driver state information. | |||
| * | |||
| * An instance of this structure is allocated by the user of the Flexnvm driver and | |||
| * passed into each of the driver APIs. | |||
| */ | |||
| typedef struct _flexnvm_config | |||
| { | |||
| ftfx_config_t ftfxConfig; | |||
| } flexnvm_config_t; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name Initialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the global flash properties structure members. | |||
| * | |||
| * This function checks and initializes the Flash module for the other Flash APIs. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FLEXNVM_Init(flexnvm_config_t *config); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Erasing | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Erases the Dflash sectors encompassed by parameters passed into function. | |||
| * | |||
| * This function erases the appropriate number of flash sectors based on the | |||
| * desired start address and length. | |||
| * | |||
| * @param config The pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be erased. | |||
| * The start address does not need to be sector-aligned but must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words) | |||
| * to be erased. Must be word-aligned. | |||
| * @param key The value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the appropriate number of date flash sectors based on | |||
| * the desired start address and length were erased successfully. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError The parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError The address is out of range. | |||
| * @retval #kStatus_FTFx_EraseKeyError The API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_DflashErase(flexnvm_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key); | |||
| /*! | |||
| * @brief Erases entire flexnvm | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the entire flexnvm has been erased successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FLEXNVM_EraseAll(flexnvm_config_t *config, uint32_t key); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD | |||
| /*! | |||
| * @brief Erases the entire flexnvm, including protected sectors. | |||
| * | |||
| * @param config Pointer to the storage for the driver runtime state. | |||
| * @param key A value used to validate all flash erase APIs. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the flexnvm is not in securityi state. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_EraseKeyError API erase key is invalid. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_PartitionStatusUpdateFailure Failed to update the partition status. | |||
| */ | |||
| status_t FLEXNVM_EraseAllUnsecure(flexnvm_config_t *config, uint32_t key); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Programming | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters. | |||
| * | |||
| * This function programs the flash memory with the desired data for a given | |||
| * flash area as determined by the start address and the length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desired date have been successfully | |||
| * programed into specified date flash region. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_DflashProgram(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes); | |||
| #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD | |||
| /*! | |||
| * @brief Programs flash with data at locations passed in through parameters via the Program Section command. | |||
| * | |||
| * This function programs the flash memory with the desired data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desired date have been successfully | |||
| * programed into specified date flash area. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_SetFlexramAsRamError Failed to set flexram as RAM. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| * @retval #kStatus_FTFx_RecoverFlexramAsEepromError Failed to recover FlexRAM as EEPROM. | |||
| */ | |||
| status_t FLEXNVM_DflashProgramSection(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */ | |||
| /*! | |||
| * @brief Prepares the FlexNVM block for use as data flash, EEPROM backup, or a combination of both and initializes the | |||
| * FlexRAM. | |||
| * | |||
| * @param config Pointer to storage for the driver runtime state. | |||
| * @param option The option used to set FlexRAM load behavior during reset. | |||
| * @param eepromDataSizeCode Determines the amount of FlexRAM used in each of the available EEPROM subsystems. | |||
| * @param flexnvmPartitionCode Specifies how to split the FlexNVM block between data flash memory and EEPROM backup | |||
| * memory supporting EEPROM functions. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the FlexNVM block for use as data flash, EEPROM backup, | |||
| * or a combination of both have been Prepared. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument Invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| */ | |||
| status_t FLEXNVM_ProgramPartition(flexnvm_config_t *config, | |||
| ftfx_partition_flexram_load_opt_t option, | |||
| uint32_t eepromDataSizeCode, | |||
| uint32_t flexnvmPartitionCode); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Reading | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD | |||
| /*! | |||
| * @brief Reads the resource with data at locations passed in through parameters. | |||
| * | |||
| * This function reads the flash memory with the desired location for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param dst A pointer to the destination buffer of data that is used to store | |||
| * data to be read. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be read. Must be word-aligned. | |||
| * @param option The resource option which indicates which area should be read back. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the data have been read successfully from | |||
| * program flash IFR, data flash IFR space, and the Version ID field | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with the specified baseline. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_ReadResource( | |||
| flexnvm_config_t *config, uint32_t start, uint8_t *dst, uint32_t lengthInBytes, ftfx_read_resource_opt_t option); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @name Verification | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Verifies an erasure of the desired flash area at a specified margin level. | |||
| * | |||
| * This function checks the appropriate number of flash sectors based on | |||
| * the desired start address and length to check whether the flash is erased | |||
| * to the specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be verified. | |||
| * The start address does not need to be sector-aligned but must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be verified. Must be word-aligned. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the specified data flash region is in erased state. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_DflashVerifyErase(flexnvm_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies erasure of the entire flash at a specified margin level. | |||
| * | |||
| * This function checks whether the flash is erased to the | |||
| * specified read margin level. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param margin Read margin choice. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the entire flexnvm region is in erased state. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_VerifyEraseAll(flexnvm_config_t *config, ftfx_margin_value_t margin); | |||
| /*! | |||
| * @brief Verifies programming of the desired flash area at a specified margin level. | |||
| * | |||
| * This function verifies the data programmed in the flash memory using the | |||
| * Flash Program Check Command and compares it to the expected data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be verified. Must be word-aligned. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be verified. Must be word-aligned. | |||
| * @param expectedData A pointer to the expected data that is to be | |||
| * verified against. | |||
| * @param margin Read margin choice. | |||
| * @param failedAddress A pointer to the returned failing address. | |||
| * @param failedData A pointer to the returned failing data. Some derivatives do | |||
| * not include failed data as part of the FCCOBx registers. In this | |||
| * case, zeros are returned upon failure. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desired data hve been programed successfully into | |||
| * specified data flash region. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AlignmentError Parameter is not aligned with specified baseline. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_DflashVerifyProgram(flexnvm_config_t *config, | |||
| uint32_t start, | |||
| uint32_t lengthInBytes, | |||
| const uint8_t *expectedData, | |||
| ftfx_margin_value_t margin, | |||
| uint32_t *failedAddress, | |||
| uint32_t *failedData); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Security | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Returns the security state via the pointer passed into the function. | |||
| * | |||
| * This function retrieves the current flash security status, including the | |||
| * security enabling state and the backdoor key enabling state. | |||
| * | |||
| * @param config A pointer to storage for the driver runtime state. | |||
| * @param state A pointer to the value returned for the current security status code: | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; | |||
| * the security state of flexnvm was stored to state. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| */ | |||
| status_t FLEXNVM_GetSecurityState(flexnvm_config_t *config, ftfx_security_state_t *state); | |||
| /*! | |||
| * @brief Allows users to bypass security with a backdoor key. | |||
| * | |||
| * If the MCU is in secured state, this function unsecures the MCU by | |||
| * comparing the provided backdoor key with ones in the flash configuration | |||
| * field. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param backdoorKey A pointer to the user buffer containing the backdoor key. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_SecurityBypass(flexnvm_config_t *config, const uint8_t *backdoorKey); | |||
| /*@}*/ | |||
| /*! | |||
| * @name FlexRAM | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD | |||
| /*! | |||
| * @brief Sets the FlexRAM function command. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param option The option used to set the work mode of FlexRAM. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; | |||
| * the FlexRAM has been successfully configured as RAM or EEPROM | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available. | |||
| * @retval #kStatus_FTFx_AccessError Invalid instruction codes and out-of bounds addresses. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during the command execution. | |||
| */ | |||
| status_t FLEXNVM_SetFlexramFunction(flexnvm_config_t *config, ftfx_flexram_func_opt_t option); | |||
| #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ | |||
| /*@}*/ | |||
| /*! | |||
| * @brief Programs the EEPROM with data at locations passed in through parameters. | |||
| * | |||
| * This function programs the emulated EEPROM with the desired data for a given | |||
| * flash area as determined by the start address and length. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param start The start address of the desired flash memory to be programmed. Must be | |||
| * word-aligned. | |||
| * @param src A pointer to the source buffer of data that is to be programmed | |||
| * into the flash. | |||
| * @param lengthInBytes The length, given in bytes (not words or long-words), | |||
| * to be programmed. Must be word-aligned. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the desires data have been successfully programed | |||
| * into specified eeprom region. | |||
| * | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_AddressError Address is out of range. | |||
| * @retval #kStatus_FTFx_SetFlexramAsEepromError Failed to set flexram as eeprom. | |||
| * @retval #kStatus_FTFx_ProtectionViolation The program/erase operation is requested to execute on protected areas. | |||
| * @retval #kStatus_FTFx_RecoverFlexramAsRamError Failed to recover the FlexRAM as RAM. | |||
| */ | |||
| status_t FLEXNVM_EepromWrite(flexnvm_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes); | |||
| /*! | |||
| * @name Flash Protection Utilities | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Sets the DFlash protection to the intended protection status. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param protectStatus The expected protect status to set to the DFlash protection register. Each bit | |||
| * corresponds to the protection of the 1/8 of the total DFlash. The least significant bit corresponds to the lowest | |||
| * address area of the DFlash. The most significant bit corresponds to the highest address area of the DFlash. There | |||
| * are | |||
| * two possible cases as shown below: | |||
| * 0: this area is protected. | |||
| * 1: this area is unprotected. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully; the specified DFlash region is protected. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_CommandNotSupported Flash API is not supported. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| */ | |||
| status_t FLEXNVM_DflashSetProtection(flexnvm_config_t *config, uint8_t protectStatus); | |||
| /*! | |||
| * @brief Gets the DFlash protection status. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param protectStatus DFlash Protect status returned by the PFlash IP. Each bit corresponds to the protection of the | |||
| * 1/8 of | |||
| * the total DFlash. The least significant bit corresponds to the lowest address area of the DFlash. The most | |||
| * significant bit corresponds to the highest address area of the DFlash, and so on. There are two possible cases as | |||
| * below: | |||
| * 0: this area is protected. | |||
| * 1: this area is unprotected. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_CommandNotSupported Flash API is not supported. | |||
| */ | |||
| status_t FLEXNVM_DflashGetProtection(flexnvm_config_t *config, uint8_t *protectStatus); | |||
| /*! | |||
| * @brief Sets the EEPROM protection to the intended protection status. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param protectStatus The expected protect status to set to the EEPROM protection register. Each bit | |||
| * corresponds to the protection of the 1/8 of the total EEPROM. The least significant bit corresponds to the lowest | |||
| * address area of the EEPROM. The most significant bit corresponds to the highest address area of EEPROM, and so on. | |||
| * There are two possible cases as shown below: | |||
| * 0: this area is protected. | |||
| * 1: this area is unprotected. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_CommandNotSupported Flash API is not supported. | |||
| * @retval #kStatus_FTFx_CommandFailure Run-time error during command execution. | |||
| */ | |||
| status_t FLEXNVM_EepromSetProtection(flexnvm_config_t *config, uint8_t protectStatus); | |||
| /*! | |||
| * @brief Gets the EEPROM protection status. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param protectStatus DFlash Protect status returned by the PFlash IP. Each bit corresponds to the protection of the | |||
| * 1/8 of | |||
| * the total EEPROM. The least significant bit corresponds to the lowest address area of the EEPROM. The most | |||
| * significant bit corresponds to the highest address area of the EEPROM. There are two possible cases as below: | |||
| * 0: this area is protected. | |||
| * 1: this area is unprotected. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_CommandNotSupported Flash API is not supported. | |||
| */ | |||
| status_t FLEXNVM_EepromGetProtection(flexnvm_config_t *config, uint8_t *protectStatus); | |||
| /*@}*/ | |||
| /*! | |||
| * @name Properties | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Returns the desired flexnvm property. | |||
| * | |||
| * @param config A pointer to the storage for the driver runtime state. | |||
| * @param whichProperty The desired property from the list of properties in | |||
| * enum flexnvm_property_tag_t | |||
| * @param value A pointer to the value returned for the desired flexnvm property. | |||
| * | |||
| * @retval #kStatus_FTFx_Success API was executed successfully. | |||
| * @retval #kStatus_FTFx_InvalidArgument An invalid argument is provided. | |||
| * @retval #kStatus_FTFx_UnknownProperty An unknown property tag. | |||
| */ | |||
| status_t FLEXNVM_GetProperty(flexnvm_config_t *config, flexnvm_property_tag_t whichProperty, uint32_t *value); | |||
| /*@}*/ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! @}*/ | |||
| #endif /* FSL_FTFX_FLEXNVM_H */ | |||
| @@ -0,0 +1,67 @@ | |||
| /* | |||
| * Copyright 2017-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| * | |||
| */ | |||
| #ifndef FSL_FTFX_UTILITIES_H | |||
| #define FSL_FTFX_UTILITIES_H | |||
| /*! | |||
| * @addtogroup ftfx_utilities | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @brief Constructs the version number for drivers. */ | |||
| #if !defined(MAKE_VERSION) | |||
| #define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) | |||
| #endif | |||
| /*! @brief Constructs a status code value from a group and a code number. */ | |||
| #if !defined(MAKE_STATUS) | |||
| #define MAKE_STATUS(group, code) ((((group)*100) + (code))) | |||
| #endif | |||
| /*! @brief Constructs the four character code for the Flash driver API key. */ | |||
| #if !defined(FOUR_CHAR_CODE) | |||
| #define FOUR_CHAR_CODE(a, b, c, d) \ | |||
| (((uint32_t)(d) << 24u) | ((uint32_t)(c) << 16u) | ((uint32_t)(b) << 8u) | ((uint32_t)(a))) | |||
| #endif | |||
| /*! @brief Alignment(down) utility. */ | |||
| #if !defined(ALIGN_DOWN) | |||
| #define ALIGN_DOWN(x, a) (((uint32_t)(x)) & ~((uint32_t)(a)-1u)) | |||
| #endif | |||
| /*! @brief Alignment(up) utility. */ | |||
| #if !defined(ALIGN_UP) | |||
| #define ALIGN_UP(x, a) ALIGN_DOWN((uint32_t)(x) + (uint32_t)(a)-1u, a) | |||
| #endif | |||
| /*! @brief bytes2word utility. */ | |||
| #define B1P4(b) (((uint32_t)(b)&0xFFU) << 24U) | |||
| #define B1P3(b) (((uint32_t)(b)&0xFFU) << 16U) | |||
| #define B1P2(b) (((uint32_t)(b)&0xFFU) << 8U) | |||
| #define B1P1(b) ((uint32_t)(b)&0xFFU) | |||
| #define B2P3(b) (((uint32_t)(b)&0xFFFFU) << 16U) | |||
| #define B2P2(b) (((uint32_t)(b)&0xFFFFU) << 8U) | |||
| #define B2P1(b) ((uint32_t)(b)&0xFFFFU) | |||
| #define B3P2(b) (((uint32_t)(b)&0xFFFFFFU) << 8U) | |||
| #define B3P1(b) ((uint32_t)(b)&0xFFFFFFU) | |||
| #define BYTE2WORD_1_3(x, y) (B1P4(x) | B3P1(y)) | |||
| #define BYTE2WORD_2_2(x, y) (B2P3(x) | B2P1(y)) | |||
| #define BYTE2WORD_3_1(x, y) (B3P2(x) | B1P1(y)) | |||
| #define BYTE2WORD_1_1_2(x, y, z) (B1P4(x) | B1P3(y) | B2P1(z)) | |||
| #define BYTE2WORD_1_2_1(x, y, z) (B1P4(x) | B2P2(y) | B1P1(z)) | |||
| #define BYTE2WORD_2_1_1(x, y, z) (B2P3(x) | B1P2(y) | B1P1(z)) | |||
| #define BYTE2WORD_1_1_1_1(x, y, z, w) (B1P4(x) | B1P3(y) | B1P2(z) | B1P1(w)) | |||
| /*! @}*/ | |||
| #endif /* FSL_FTFX_UTILITIES_H */ | |||
| @@ -0,0 +1,382 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_gpio.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.gpio" | |||
| #endif | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| static PORT_Type *const s_portBases[] = PORT_BASE_PTRS; | |||
| static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS; | |||
| #endif | |||
| #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT | |||
| #if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /*! @brief Array to map FGPIO instance number to clock name. */ | |||
| static const clock_ip_name_t s_fgpioClockName[] = FGPIO_CLOCKS; | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| #endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */ | |||
| #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * @brief Gets the GPIO instance according to the GPIO base | |||
| * | |||
| * @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.) | |||
| * @retval GPIO instance | |||
| */ | |||
| static uint32_t GPIO_GetInstance(GPIO_Type *base); | |||
| #endif | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| static uint32_t GPIO_GetInstance(GPIO_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++) | |||
| { | |||
| if (s_gpioBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_gpioBases)); | |||
| return instance; | |||
| } | |||
| #endif | |||
| /*! | |||
| * brief Initializes a GPIO pin used by the board. | |||
| * | |||
| * To initialize the GPIO, define a pin configuration, as either input or output, in the user file. | |||
| * Then, call the GPIO_PinInit() function. | |||
| * | |||
| * This is an example to define an input pin or an output pin configuration. | |||
| * code | |||
| * Define a digital input pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalInput, | |||
| * 0, | |||
| * } | |||
| * Define a digital output pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalOutput, | |||
| * 0, | |||
| * } | |||
| * endcode | |||
| * | |||
| * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * param pin GPIO port pin number | |||
| * param config GPIO pin configuration pointer | |||
| */ | |||
| void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint32_t u32flag = 1; | |||
| if (config->pinDirection == kGPIO_DigitalInput) | |||
| { | |||
| base->PDDR &= GPIO_FIT_REG(~(u32flag << pin)); | |||
| } | |||
| else | |||
| { | |||
| GPIO_PinWrite(base, pin, config->outputLogic); | |||
| base->PDDR |= GPIO_FIT_REG((u32flag << pin)); | |||
| } | |||
| } | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * brief Reads the GPIO port interrupt status flag. | |||
| * | |||
| * If a pin is configured to generate the DMA request, the corresponding flag | |||
| * is cleared automatically at the completion of the requested DMA transfer. | |||
| * Otherwise, the flag remains set until a logic one is written to that flag. | |||
| * If configured for a level sensitive interrupt that remains asserted, the flag | |||
| * is set again immediately. | |||
| * | |||
| * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * retval The current GPIO port interrupt status flag, for example, 0x00010001 means the | |||
| * pin 0 and 17 have the interrupt. | |||
| */ | |||
| uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base) | |||
| { | |||
| uint8_t instance; | |||
| PORT_Type *portBase; | |||
| instance = (uint8_t)GPIO_GetInstance(base); | |||
| portBase = s_portBases[instance]; | |||
| return portBase->ISFR; | |||
| } | |||
| #else | |||
| /*! | |||
| * brief Read the GPIO interrupt status flags. | |||
| * | |||
| * param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * return The current GPIO's interrupt status flag. | |||
| * '1' means the related pin's flag is set, '0' means the related pin's flag not set. | |||
| * For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending. | |||
| */ | |||
| uint32_t GPIO_GpioGetInterruptFlags(GPIO_Type *base) | |||
| { | |||
| return base->ISFR[0]; | |||
| } | |||
| /*! | |||
| * brief Read individual pin's interrupt status flag. | |||
| * | |||
| * param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on) | |||
| * param pin GPIO specific pin number. | |||
| * return The current selected pin's interrupt status flag. | |||
| */ | |||
| uint8_t GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin) | |||
| { | |||
| return (uint8_t)((base->ICR[pin] & GPIO_ICR_ISF_MASK) >> GPIO_ICR_ISF_SHIFT); | |||
| } | |||
| #endif /* FSL_FEATURE_PORT_HAS_NO_INTERRUPT */ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * brief Clears multiple GPIO pin interrupt status flags. | |||
| * | |||
| * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * param mask GPIO pin number macro | |||
| */ | |||
| void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask) | |||
| { | |||
| uint8_t instance; | |||
| PORT_Type *portBase; | |||
| instance = (uint8_t)GPIO_GetInstance(base); | |||
| portBase = s_portBases[instance]; | |||
| portBase->ISFR = mask; | |||
| } | |||
| #else | |||
| /*! | |||
| * brief Clears GPIO pin interrupt status flags. | |||
| * | |||
| * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * param mask GPIO pin number macro | |||
| */ | |||
| void GPIO_GpioClearInterruptFlags(GPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->ISFR[0] = GPIO_FIT_REG(mask); | |||
| } | |||
| /*! | |||
| * brief Clear GPIO individual pin's interrupt status flag. | |||
| * | |||
| * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on). | |||
| * param pin GPIO specific pin number. | |||
| */ | |||
| void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t pin) | |||
| { | |||
| base->ICR[pin] |= GPIO_FIT_REG(GPIO_ICR_ISF(1U)); | |||
| } | |||
| #endif /* FSL_FEATURE_PORT_HAS_NO_INTERRUPT */ | |||
| #if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER | |||
| /*! | |||
| * brief The GPIO module supports a device-specific number of data ports, organized as 32-bit | |||
| * words/8-bit Bytes. Each 32-bit/8-bit data port includes a GACR register, which defines the byte-level | |||
| * attributes required for a successful access to the GPIO programming model. If the GPIO module's GACR register | |||
| * organized as 32-bit words, the attribute controls for the 4 data bytes in the GACR follow a standard little | |||
| * endian data convention. | |||
| * | |||
| * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * param attribute GPIO checker attribute | |||
| */ | |||
| void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute) | |||
| { | |||
| #if defined(FSL_FEATURE_GPIO_REGISTERS_WIDTH) && (FSL_FEATURE_GPIO_REGISTERS_WIDTH == 8U) | |||
| base->GACR = ((uint8_t)attribute << GPIO_GACR_ACB_SHIFT); | |||
| #else | |||
| base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) | | |||
| ((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT); | |||
| #endif /* FSL_FEATURE_GPIO_REGISTERS_WIDTH */ | |||
| } | |||
| #endif | |||
| #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS; | |||
| #endif | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * @brief Gets the FGPIO instance according to the GPIO base | |||
| * | |||
| * @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.) | |||
| * @retval FGPIO instance | |||
| */ | |||
| static uint32_t FGPIO_GetInstance(FGPIO_Type *base); | |||
| #endif | |||
| /******************************************************************************* | |||
| * Code | |||
| ******************************************************************************/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| static uint32_t FGPIO_GetInstance(FGPIO_Type *base) | |||
| { | |||
| uint32_t instance; | |||
| /* Find the instance index from base address mappings. */ | |||
| for (instance = 0; instance < ARRAY_SIZE(s_fgpioBases); instance++) | |||
| { | |||
| if (s_fgpioBases[instance] == base) | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| assert(instance < ARRAY_SIZE(s_fgpioBases)); | |||
| return instance; | |||
| } | |||
| #endif | |||
| #if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL | |||
| /*! | |||
| * brief Initializes the FGPIO peripheral. | |||
| * | |||
| * This function ungates the FGPIO clock. | |||
| * | |||
| * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| */ | |||
| void FGPIO_PortInit(FGPIO_Type *base) | |||
| { | |||
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | |||
| /* Ungate FGPIO periphral clock */ | |||
| CLOCK_EnableClock(s_fgpioClockName[FGPIO_GetInstance(base)]); | |||
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | |||
| } | |||
| #endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */ | |||
| /*! | |||
| * brief Initializes a FGPIO pin used by the board. | |||
| * | |||
| * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file. | |||
| * Then, call the FGPIO_PinInit() function. | |||
| * | |||
| * This is an example to define an input pin or an output pin configuration: | |||
| * code | |||
| * Define a digital input pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalInput, | |||
| * 0, | |||
| * } | |||
| * Define a digital output pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalOutput, | |||
| * 0, | |||
| * } | |||
| * endcode | |||
| * | |||
| * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * param pin FGPIO port pin number | |||
| * param config FGPIO pin configuration pointer | |||
| */ | |||
| void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config) | |||
| { | |||
| assert(NULL != config); | |||
| uint32_t u32flag = 1; | |||
| if (config->pinDirection == kGPIO_DigitalInput) | |||
| { | |||
| base->PDDR &= ~(u32flag << pin); | |||
| } | |||
| else | |||
| { | |||
| FGPIO_PinWrite(base, pin, config->outputLogic); | |||
| base->PDDR |= (u32flag << pin); | |||
| } | |||
| } | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * brief Reads the FGPIO port interrupt status flag. | |||
| * | |||
| * If a pin is configured to generate the DMA request, the corresponding flag | |||
| * is cleared automatically at the completion of the requested DMA transfer. | |||
| * Otherwise, the flag remains set until a logic one is written to that flag. | |||
| * If configured for a level-sensitive interrupt that remains asserted, the flag | |||
| * is set again immediately. | |||
| * | |||
| * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the | |||
| * pin 0 and 17 have the interrupt. | |||
| */ | |||
| uint32_t FGPIO_PortGetInterruptFlags(FGPIO_Type *base) | |||
| { | |||
| uint8_t instance; | |||
| instance = (uint8_t)FGPIO_GetInstance(base); | |||
| PORT_Type *portBase; | |||
| portBase = s_portBases[instance]; | |||
| return portBase->ISFR; | |||
| } | |||
| /*! | |||
| * brief Clears the multiple FGPIO pin interrupt status flag. | |||
| * | |||
| * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * param mask FGPIO pin number macro | |||
| */ | |||
| void FGPIO_PortClearInterruptFlags(FGPIO_Type *base, uint32_t mask) | |||
| { | |||
| uint8_t instance; | |||
| instance = (uint8_t)FGPIO_GetInstance(base); | |||
| PORT_Type *portBase; | |||
| portBase = s_portBases[instance]; | |||
| portBase->ISFR = mask; | |||
| } | |||
| #endif | |||
| #if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER | |||
| /*! | |||
| * brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit | |||
| * words. Each 32-bit data port includes a GACR register, which defines the byte-level | |||
| * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data | |||
| * bytes in the GACR follow a standard little endian | |||
| * data convention. | |||
| * | |||
| * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * param attribute FGPIO checker attribute | |||
| */ | |||
| void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute) | |||
| { | |||
| base->GACR = ((uint32_t)attribute << FGPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << FGPIO_GACR_ACB1_SHIFT) | | |||
| ((uint32_t)attribute << FGPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << FGPIO_GACR_ACB3_SHIFT); | |||
| } | |||
| #endif | |||
| #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ | |||
| @@ -0,0 +1,574 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_GPIO_H_ | |||
| #define _FSL_GPIO_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup gpio | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief GPIO driver version 2.5.1. */ | |||
| #define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 5, 1)) | |||
| /*@}*/ | |||
| #if defined(FSL_FEATURE_GPIO_REGISTERS_WIDTH) && (FSL_FEATURE_GPIO_REGISTERS_WIDTH == 8U) | |||
| #define GPIO_FIT_REG(value) \ | |||
| ((uint8_t)(value)) /*!< For some platforms with 8-bit register width, cast the type to uint8_t */ | |||
| #else | |||
| #define GPIO_FIT_REG(value) (value) | |||
| #endif /*FSL_FEATURE_GPIO_REGISTERS_WIDTH*/ | |||
| /*! @brief GPIO direction definition */ | |||
| typedef enum _gpio_pin_direction | |||
| { | |||
| kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ | |||
| kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ | |||
| } gpio_pin_direction_t; | |||
| #if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER | |||
| /*! @brief GPIO checker attribute */ | |||
| typedef enum _gpio_checker_attribute | |||
| { | |||
| kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW = | |||
| 0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */ | |||
| kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW = | |||
| 0x01U, /*!< User nonsecure:Read; User Secure:Read+Write; Privileged Secure:Read+Write */ | |||
| kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW = | |||
| 0x02U, /*!< User nonsecure:None; User Secure:Read+Write; Privileged Secure:Read+Write */ | |||
| kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW = | |||
| 0x03U, /*!< User nonsecure:Read; User Secure:Read; Privileged Secure:Read+Write */ | |||
| kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW = | |||
| 0x04U, /*!< User nonsecure:None; User Secure:Read; Privileged Secure:Read+Write */ | |||
| kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW = | |||
| 0x05U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read+Write */ | |||
| kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR = | |||
| 0x06U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read */ | |||
| kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN = | |||
| 0x07U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:None */ | |||
| kGPIO_IgnoreAttributeCheck = 0x80U, /*!< Ignores the attribute check */ | |||
| } gpio_checker_attribute_t; | |||
| #endif | |||
| /*! | |||
| * @brief The GPIO pin configuration structure. | |||
| * | |||
| * Each pin can only be configured as either an output pin or an input pin at a time. | |||
| * If configured as an input pin, leave the outputConfig unused. | |||
| * Note that in some use cases, the corresponding port property should be configured in advance | |||
| * with the PORT_SetPinConfig(). | |||
| */ | |||
| typedef struct _gpio_pin_config | |||
| { | |||
| gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */ | |||
| /* Output configurations; ignore if configured as an input pin */ | |||
| uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */ | |||
| } gpio_pin_config_t; | |||
| #if (defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! @brief Configures the interrupt generation condition. */ | |||
| typedef enum _gpio_interrupt_config | |||
| { | |||
| kGPIO_InterruptStatusFlagDisabled = 0x0U, /*!< Interrupt status flag is disabled. */ | |||
| kGPIO_DMARisingEdge = 0x1U, /*!< ISF flag and DMA request on rising edge. */ | |||
| kGPIO_DMAFallingEdge = 0x2U, /*!< ISF flag and DMA request on falling edge. */ | |||
| kGPIO_DMAEitherEdge = 0x3U, /*!< ISF flag and DMA request on either edge. */ | |||
| kGPIO_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */ | |||
| kGPIO_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */ | |||
| kGPIO_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */ | |||
| kGPIO_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */ | |||
| kGPIO_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */ | |||
| kGPIO_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */ | |||
| kGPIO_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */ | |||
| kGPIO_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */ | |||
| kGPIO_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */ | |||
| kGPIO_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */ | |||
| } gpio_interrupt_config_t; | |||
| #endif | |||
| /*! @} */ | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @addtogroup gpio_driver | |||
| * @{ | |||
| */ | |||
| /*! @name GPIO Configuration */ | |||
| /*@{*/ | |||
| /*! | |||
| * @brief Initializes a GPIO pin used by the board. | |||
| * | |||
| * To initialize the GPIO, define a pin configuration, as either input or output, in the user file. | |||
| * Then, call the GPIO_PinInit() function. | |||
| * | |||
| * This is an example to define an input pin or an output pin configuration. | |||
| * @code | |||
| * Define a digital input pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalInput, | |||
| * 0, | |||
| * } | |||
| * Define a digital output pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalOutput, | |||
| * 0, | |||
| * } | |||
| * @endcode | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param pin GPIO port pin number | |||
| * @param config GPIO pin configuration pointer | |||
| */ | |||
| void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config); | |||
| /*@}*/ | |||
| /*! @name GPIO Output Operations */ | |||
| /*@{*/ | |||
| /*! | |||
| * @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param pin GPIO pin number | |||
| * @param output GPIO pin output logic level. | |||
| * - 0: corresponding pin output low-logic level. | |||
| * - 1: corresponding pin output high-logic level. | |||
| */ | |||
| static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output) | |||
| { | |||
| uint32_t u32flag = 1; | |||
| if (output == 0U) | |||
| { | |||
| base->PCOR = GPIO_FIT_REG(u32flag << pin); | |||
| } | |||
| else | |||
| { | |||
| base->PSOR = GPIO_FIT_REG(u32flag << pin); | |||
| } | |||
| } | |||
| /*! | |||
| * @brief Sets the output level of the multiple GPIO pins to the logic 1. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param mask GPIO pin number macro | |||
| */ | |||
| static inline void GPIO_PortSet(GPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->PSOR = GPIO_FIT_REG(mask); | |||
| } | |||
| /*! | |||
| * @brief Sets the output level of the multiple GPIO pins to the logic 0. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param mask GPIO pin number macro | |||
| */ | |||
| static inline void GPIO_PortClear(GPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->PCOR = GPIO_FIT_REG(mask); | |||
| } | |||
| /*! | |||
| * @brief Reverses the current output logic of the multiple GPIO pins. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param mask GPIO pin number macro | |||
| */ | |||
| static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->PTOR = GPIO_FIT_REG(mask); | |||
| } | |||
| /*@}*/ | |||
| /*! @name GPIO Input Operations */ | |||
| /*@{*/ | |||
| /*! | |||
| * @brief Reads the current input value of the GPIO port. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param pin GPIO pin number | |||
| * @retval GPIO port input value | |||
| * - 0: corresponding pin input low-logic level. | |||
| * - 1: corresponding pin input high-logic level. | |||
| */ | |||
| static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t pin) | |||
| { | |||
| return (((uint32_t)(base->PDIR) >> pin) & 0x01UL); | |||
| } | |||
| /*@}*/ | |||
| /*! @name GPIO Interrupt */ | |||
| /*@{*/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * @brief Reads the GPIO port interrupt status flag. | |||
| * | |||
| * If a pin is configured to generate the DMA request, the corresponding flag | |||
| * is cleared automatically at the completion of the requested DMA transfer. | |||
| * Otherwise, the flag remains set until a logic one is written to that flag. | |||
| * If configured for a level sensitive interrupt that remains asserted, the flag | |||
| * is set again immediately. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the | |||
| * pin 0 and 17 have the interrupt. | |||
| */ | |||
| uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base); | |||
| /*! | |||
| * @brief Clears multiple GPIO pin interrupt status flags. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param mask GPIO pin number macro | |||
| */ | |||
| void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask); | |||
| #else | |||
| /*! | |||
| * @brief Configures the gpio pin interrupt/DMA request. | |||
| * | |||
| * @param base GPIO peripheral base pointer. | |||
| * @param pin GPIO pin number. | |||
| * @param config GPIO pin interrupt configuration. | |||
| * - #kGPIO_InterruptStatusFlagDisabled: Interrupt/DMA request disabled. | |||
| * - #kGPIO_DMARisingEdge : DMA request on rising edge(if the DMA requests exit). | |||
| * - #kGPIO_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit). | |||
| * - #kGPIO_DMAEitherEdge : DMA request on either edge(if the DMA requests exit). | |||
| * - #kGPIO_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit). | |||
| * - #kGPIO_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit). | |||
| * - #kGPIO_FlagEitherEdge : Flag sets on either edge(if the Flag states exit). | |||
| * - #kGPIO_InterruptLogicZero : Interrupt when logic zero. | |||
| * - #kGPIO_InterruptRisingEdge : Interrupt on rising edge. | |||
| * - #kGPIO_InterruptFallingEdge: Interrupt on falling edge. | |||
| * - #kGPIO_InterruptEitherEdge : Interrupt on either edge. | |||
| * - #kGPIO_InterruptLogicOne : Interrupt when logic one. | |||
| * - #kGPIO_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit). | |||
| * - #kGPIO_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit). | |||
| */ | |||
| static inline void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_config_t config) | |||
| { | |||
| assert(base); | |||
| base->ICR[pin] = GPIO_FIT_REG((base->ICR[pin] & ~GPIO_ICR_IRQC_MASK) | GPIO_ICR_IRQC(config)); | |||
| } | |||
| /*! | |||
| * @brief Read the GPIO interrupt status flags. | |||
| * | |||
| * @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @return The current GPIO's interrupt status flag. | |||
| * '1' means the related pin's flag is set, '0' means the related pin's flag not set. | |||
| * For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending. | |||
| */ | |||
| uint32_t GPIO_GpioGetInterruptFlags(GPIO_Type *base); | |||
| /*! | |||
| * @brief Read individual pin's interrupt status flag. | |||
| * | |||
| * @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on) | |||
| * @param pin GPIO specific pin number. | |||
| * @return The current selected pin's interrupt status flag. | |||
| */ | |||
| uint8_t GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin); | |||
| /*! | |||
| * @brief Clears GPIO pin interrupt status flags. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param mask GPIO pin number macro | |||
| */ | |||
| void GPIO_GpioClearInterruptFlags(GPIO_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Clear GPIO individual pin's interrupt status flag. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on). | |||
| * @param pin GPIO specific pin number. | |||
| */ | |||
| void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t pin); | |||
| /*! | |||
| * @brief Reads the GPIO DMA request flags. | |||
| * The corresponding flag will be cleared automatically at the completion of the requested | |||
| * DMA transfer | |||
| */ | |||
| static inline uint32_t GPIO_GetPinsDMARequestFlags(GPIO_Type *base) | |||
| { | |||
| assert(base); | |||
| return (base->ISFR[1]); | |||
| } | |||
| /*! | |||
| * @brief Sets the GPIO interrupt configuration in PCR register for multiple pins. | |||
| * | |||
| * @param base GPIO peripheral base pointer. | |||
| * @param mask GPIO pin number macro. | |||
| * @param config GPIO pin interrupt configuration. | |||
| * - #kGPIO_InterruptStatusFlagDisabled: Interrupt disabled. | |||
| * - #kGPIO_DMARisingEdge : DMA request on rising edge(if the DMA requests exit). | |||
| * - #kGPIO_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit). | |||
| * - #kGPIO_DMAEitherEdge : DMA request on either edge(if the DMA requests exit). | |||
| * - #kGPIO_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit). | |||
| * - #kGPIO_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit). | |||
| * - #kGPIO_FlagEitherEdge : Flag sets on either edge(if the Flag states exit). | |||
| * - #kGPIO_InterruptLogicZero : Interrupt when logic zero. | |||
| * - #kGPIO_InterruptRisingEdge : Interrupt on rising edge. | |||
| * - #kGPIO_InterruptFallingEdge: Interrupt on falling edge. | |||
| * - #kGPIO_InterruptEitherEdge : Interrupt on either edge. | |||
| * - #kGPIO_InterruptLogicOne : Interrupt when logic one. | |||
| * - #kGPIO_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit). | |||
| * - #kGPIO_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit).. | |||
| */ | |||
| static inline void GPIO_SetMultipleInterruptPinsConfig(GPIO_Type *base, uint32_t mask, gpio_interrupt_config_t config) | |||
| { | |||
| assert(base); | |||
| if (mask & 0xffffU) | |||
| { | |||
| base->GICLR = GPIO_FIT_REG((GPIO_ICR_IRQC(config)) | (mask & 0xffffU)); | |||
| } | |||
| mask = mask >> 16U; | |||
| if (mask) | |||
| { | |||
| base->GICHR = GPIO_FIT_REG((GPIO_ICR_IRQC(config)) | (mask & 0xffffU)); | |||
| } | |||
| } | |||
| #endif | |||
| #if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER | |||
| /*! | |||
| * brief The GPIO module supports a device-specific number of data ports, organized as 32-bit | |||
| * words/8-bit Bytes. Each 32-bit/8-bit data port includes a GACR register, which defines the byte-level | |||
| * attributes required for a successful access to the GPIO programming model. If the GPIO module's GACR register | |||
| * organized as 32-bit words, the attribute controls for the 4 data bytes in the GACR follow a standard little | |||
| * endian data convention. | |||
| * | |||
| * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) | |||
| * @param attribute GPIO checker attribute | |||
| */ | |||
| void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute); | |||
| #endif | |||
| /*@}*/ | |||
| /*! @} */ | |||
| /*! | |||
| * @addtogroup fgpio_driver | |||
| * @{ | |||
| */ | |||
| /* | |||
| * Introduces the FGPIO feature. | |||
| * | |||
| * The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT | |||
| * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and | |||
| * complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO. | |||
| */ | |||
| #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT | |||
| /*! @name FGPIO Configuration */ | |||
| /*@{*/ | |||
| #if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL | |||
| /*! | |||
| * @brief Initializes the FGPIO peripheral. | |||
| * | |||
| * This function ungates the FGPIO clock. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| */ | |||
| void FGPIO_PortInit(FGPIO_Type *base); | |||
| #endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */ | |||
| /*! | |||
| * @brief Initializes a FGPIO pin used by the board. | |||
| * | |||
| * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file. | |||
| * Then, call the FGPIO_PinInit() function. | |||
| * | |||
| * This is an example to define an input pin or an output pin configuration: | |||
| * @code | |||
| * Define a digital input pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalInput, | |||
| * 0, | |||
| * } | |||
| * Define a digital output pin configuration, | |||
| * gpio_pin_config_t config = | |||
| * { | |||
| * kGPIO_DigitalOutput, | |||
| * 0, | |||
| * } | |||
| * @endcode | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param pin FGPIO port pin number | |||
| * @param config FGPIO pin configuration pointer | |||
| */ | |||
| void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config); | |||
| /*@}*/ | |||
| /*! @name FGPIO Output Operations */ | |||
| /*@{*/ | |||
| /*! | |||
| * @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param pin FGPIO pin number | |||
| * @param output FGPIOpin output logic level. | |||
| * - 0: corresponding pin output low-logic level. | |||
| * - 1: corresponding pin output high-logic level. | |||
| */ | |||
| static inline void FGPIO_PinWrite(FGPIO_Type *base, uint32_t pin, uint8_t output) | |||
| { | |||
| uint32_t u32flag = 1; | |||
| if (output == 0U) | |||
| { | |||
| base->PCOR = u32flag << pin; | |||
| } | |||
| else | |||
| { | |||
| base->PSOR = u32flag << pin; | |||
| } | |||
| } | |||
| /*! | |||
| * @brief Sets the output level of the multiple FGPIO pins to the logic 1. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param mask FGPIO pin number macro | |||
| */ | |||
| static inline void FGPIO_PortSet(FGPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->PSOR = mask; | |||
| } | |||
| /*! | |||
| * @brief Sets the output level of the multiple FGPIO pins to the logic 0. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param mask FGPIO pin number macro | |||
| */ | |||
| static inline void FGPIO_PortClear(FGPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->PCOR = mask; | |||
| } | |||
| /*! | |||
| * @brief Reverses the current output logic of the multiple FGPIO pins. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param mask FGPIO pin number macro | |||
| */ | |||
| static inline void FGPIO_PortToggle(FGPIO_Type *base, uint32_t mask) | |||
| { | |||
| base->PTOR = mask; | |||
| } | |||
| /*@}*/ | |||
| /*! @name FGPIO Input Operations */ | |||
| /*@{*/ | |||
| /*! | |||
| * @brief Reads the current input value of the FGPIO port. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param pin FGPIO pin number | |||
| * @retval FGPIO port input value | |||
| * - 0: corresponding pin input low-logic level. | |||
| * - 1: corresponding pin input high-logic level. | |||
| */ | |||
| static inline uint32_t FGPIO_PinRead(FGPIO_Type *base, uint32_t pin) | |||
| { | |||
| return (((base->PDIR) >> pin) & 0x01U); | |||
| } | |||
| /*@}*/ | |||
| /*! @name FGPIO Interrupt */ | |||
| /*@{*/ | |||
| #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) | |||
| /*! | |||
| * @brief Reads the FGPIO port interrupt status flag. | |||
| * | |||
| * If a pin is configured to generate the DMA request, the corresponding flag | |||
| * is cleared automatically at the completion of the requested DMA transfer. | |||
| * Otherwise, the flag remains set until a logic one is written to that flag. | |||
| * If configured for a level-sensitive interrupt that remains asserted, the flag | |||
| * is set again immediately. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the | |||
| * pin 0 and 17 have the interrupt. | |||
| */ | |||
| uint32_t FGPIO_PortGetInterruptFlags(FGPIO_Type *base); | |||
| /*! | |||
| * @brief Clears the multiple FGPIO pin interrupt status flag. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param mask FGPIO pin number macro | |||
| */ | |||
| void FGPIO_PortClearInterruptFlags(FGPIO_Type *base, uint32_t mask); | |||
| #endif | |||
| #if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER | |||
| /*! | |||
| * @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit | |||
| * words. Each 32-bit data port includes a GACR register, which defines the byte-level | |||
| * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data | |||
| * bytes in the GACR follow a standard little endian | |||
| * data convention. | |||
| * | |||
| * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) | |||
| * @param attribute FGPIO checker attribute | |||
| */ | |||
| void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute); | |||
| #endif /* FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER */ | |||
| /*@}*/ | |||
| #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| * @} | |||
| */ | |||
| #endif /* _FSL_GPIO_H_*/ | |||
| @@ -0,0 +1,805 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_I2C_H_ | |||
| #define _FSL_I2C_H_ | |||
| #include "fsl_common.h" | |||
| /*! | |||
| * @addtogroup i2c_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief I2C driver version 2.0.8. */ | |||
| #define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 8)) | |||
| /*@}*/ | |||
| /*! @brief Retry times for waiting flag. */ | |||
| #ifndef I2C_RETRY_TIMES | |||
| #define I2C_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */ | |||
| #endif | |||
| /*! @brief Mater Fast ack control, control if master needs to manually write ack, this is used to | |||
| low the speed of transfer for SoCs with feature FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */ | |||
| #ifndef I2C_MASTER_FACK_CONTROL | |||
| #define I2C_MASTER_FACK_CONTROL 0U /* Default defines to zero means master will send ack automatically. */ | |||
| #endif | |||
| #if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \ | |||
| defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT) | |||
| #define I2C_HAS_STOP_DETECT | |||
| #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */ | |||
| /*! @brief I2C status return codes. */ | |||
| enum | |||
| { | |||
| kStatus_I2C_Busy = MAKE_STATUS(kStatusGroup_I2C, 0), /*!< I2C is busy with current transfer. */ | |||
| kStatus_I2C_Idle = MAKE_STATUS(kStatusGroup_I2C, 1), /*!< Bus is Idle. */ | |||
| kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!< NAK received during transfer. */ | |||
| kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!< Arbitration lost during transfer. */ | |||
| kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Timeout polling status flags. */ | |||
| kStatus_I2C_Addr_Nak = MAKE_STATUS(kStatusGroup_I2C, 5), /*!< NAK received during the address probe. */ | |||
| }; | |||
| /*! | |||
| * @brief I2C peripheral flags | |||
| * | |||
| * @note These enumerations are meant to be OR'd together to form a bit mask. | |||
| * | |||
| */ | |||
| enum _i2c_flags | |||
| { | |||
| kI2C_ReceiveNakFlag = I2C_S_RXAK_MASK, /*!< I2C receive NAK flag. */ | |||
| kI2C_IntPendingFlag = I2C_S_IICIF_MASK, /*!< I2C interrupt pending flag. This flag can be cleared. */ | |||
| kI2C_TransferDirectionFlag = I2C_S_SRW_MASK, /*!< I2C transfer direction flag. */ | |||
| kI2C_RangeAddressMatchFlag = I2C_S_RAM_MASK, /*!< I2C range address match flag. */ | |||
| kI2C_ArbitrationLostFlag = I2C_S_ARBL_MASK, /*!< I2C arbitration lost flag. This flag can be cleared. */ | |||
| kI2C_BusBusyFlag = I2C_S_BUSY_MASK, /*!< I2C bus busy flag. */ | |||
| kI2C_AddressMatchFlag = I2C_S_IAAS_MASK, /*!< I2C address match flag. */ | |||
| kI2C_TransferCompleteFlag = I2C_S_TCF_MASK, /*!< I2C transfer complete flag. */ | |||
| #ifdef I2C_HAS_STOP_DETECT | |||
| kI2C_StopDetectFlag = I2C_FLT_STOPF_MASK << 8, /*!< I2C stop detect flag. This flag can be cleared. */ | |||
| #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT / FSL_FEATURE_I2C_HAS_STOP_DETECT */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT | |||
| kI2C_StartDetectFlag = I2C_FLT_STARTF_MASK << 8, /*!< I2C start detect flag. This flag can be cleared. */ | |||
| #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ | |||
| }; | |||
| /*! @brief I2C feature interrupt source. */ | |||
| enum _i2c_interrupt_enable | |||
| { | |||
| kI2C_GlobalInterruptEnable = I2C_C1_IICIE_MASK, /*!< I2C global interrupt. */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT | |||
| kI2C_StopDetectInterruptEnable = I2C_FLT_STOPIE_MASK, /*!< I2C stop detect interrupt. */ | |||
| #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT | |||
| kI2C_StartStopDetectInterruptEnable = I2C_FLT_SSIE_MASK, /*!< I2C start&stop detect interrupt. */ | |||
| #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ | |||
| }; | |||
| /*! @brief The direction of master and slave transfers. */ | |||
| typedef enum _i2c_direction | |||
| { | |||
| kI2C_Write = 0x0U, /*!< Master transmits to the slave. */ | |||
| kI2C_Read = 0x1U, /*!< Master receives from the slave. */ | |||
| } i2c_direction_t; | |||
| /*! @brief Addressing mode. */ | |||
| typedef enum _i2c_slave_address_mode | |||
| { | |||
| kI2C_Address7bit = 0x0U, /*!< 7-bit addressing mode. */ | |||
| kI2C_RangeMatch = 0X2U, /*!< Range address match addressing mode. */ | |||
| } i2c_slave_address_mode_t; | |||
| /*! @brief I2C transfer control flag. */ | |||
| enum _i2c_master_transfer_flags | |||
| { | |||
| kI2C_TransferDefaultFlag = 0x0U, /*!< A transfer starts with a start signal, stops with a stop signal. */ | |||
| kI2C_TransferNoStartFlag = 0x1U, /*!< A transfer starts without a start signal, only support write only or | |||
| write+read with no start flag, do not support read only with no start flag. */ | |||
| kI2C_TransferRepeatedStartFlag = 0x2U, /*!< A transfer starts with a repeated start signal. */ | |||
| kI2C_TransferNoStopFlag = 0x4U, /*!< A transfer ends without a stop signal. */ | |||
| }; | |||
| /*! | |||
| * @brief Set of events sent to the callback for nonblocking slave transfers. | |||
| * | |||
| * These event enumerations are used for two related purposes. First, a bit mask created by OR'ing together | |||
| * events is passed to I2C_SlaveTransferNonBlocking() to specify which events to enable. | |||
| * Then, when the slave callback is invoked, it is passed the current event through its @a transfer | |||
| * parameter. | |||
| * | |||
| * @note These enumerations are meant to be OR'd together to form a bit mask of events. | |||
| */ | |||
| typedef enum _i2c_slave_transfer_event | |||
| { | |||
| kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */ | |||
| kI2C_SlaveTransmitEvent = 0x02U, /*!< A callback is requested to provide data to transmit | |||
| (slave-transmitter role). */ | |||
| kI2C_SlaveReceiveEvent = 0x04U, /*!< A callback is requested to provide a buffer in which to place received | |||
| data (slave-receiver role). */ | |||
| kI2C_SlaveTransmitAckEvent = 0x08U, /*!< A callback needs to either transmit an ACK or NACK. */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT | |||
| kI2C_SlaveStartEvent = 0x10U, /*!< A start/repeated start was detected. */ | |||
| #endif | |||
| kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */ | |||
| kI2C_SlaveGenaralcallEvent = 0x40U, /*!< Received the general call address after a start or repeated start. */ | |||
| /*! A bit mask of all available events. */ | |||
| kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | | |||
| #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT | |||
| kI2C_SlaveStartEvent | | |||
| #endif | |||
| kI2C_SlaveCompletionEvent | kI2C_SlaveGenaralcallEvent, | |||
| } i2c_slave_transfer_event_t; | |||
| /*! @brief Common sets of flags used by the driver. */ | |||
| enum | |||
| { | |||
| /*! All flags which are cleared by the driver upon starting a transfer. */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT | |||
| kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag, | |||
| kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StartStopDetectInterruptEnable, | |||
| #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT | |||
| kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag, | |||
| kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StopDetectInterruptEnable, | |||
| #else | |||
| kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag, | |||
| kIrqFlags = kI2C_GlobalInterruptEnable, | |||
| #endif | |||
| }; | |||
| /*! @brief I2C master user configuration. */ | |||
| typedef struct _i2c_master_config | |||
| { | |||
| bool enableMaster; /*!< Enables the I2C peripheral at initialization time. */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF | |||
| bool enableStopHold; /*!< Controls the stop hold enable. */ | |||
| #endif | |||
| #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE | |||
| bool enableDoubleBuffering; /*!< Controls double buffer enable; notice that | |||
| enabling the double buffer disables the clock stretch. */ | |||
| #endif | |||
| uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */ | |||
| uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */ | |||
| } i2c_master_config_t; | |||
| /*! @brief I2C slave user configuration. */ | |||
| typedef struct _i2c_slave_config | |||
| { | |||
| bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */ | |||
| bool enableGeneralCall; /*!< Enables the general call addressing mode. */ | |||
| bool enableWakeUp; /*!< Enables/disables waking up MCU from low-power mode. */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE | |||
| bool enableDoubleBuffering; /*!< Controls a double buffer enable; notice that | |||
| enabling the double buffer disables the clock stretch. */ | |||
| #endif | |||
| bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */ | |||
| uint16_t slaveAddress; /*!< A slave address configuration. */ | |||
| uint16_t upperAddress; /*!< A maximum boundary slave address used in a range matching mode. */ | |||
| i2c_slave_address_mode_t | |||
| addressingMode; /*!< An addressing mode configuration of i2c_slave_address_mode_config_t. */ | |||
| uint32_t sclStopHoldTime_ns; /*!< the delay from the rising edge of SCL (I2C clock) to the rising edge of SDA (I2C | |||
| data) while SCL is high (stop condition), SDA hold time and SCL start hold time | |||
| are also configured according to the SCL stop hold time. */ | |||
| } i2c_slave_config_t; | |||
| /*! @brief I2C master handle typedef. */ | |||
| typedef struct _i2c_master_handle i2c_master_handle_t; | |||
| /*! @brief I2C master transfer callback typedef. */ | |||
| typedef void (*i2c_master_transfer_callback_t)(I2C_Type *base, | |||
| i2c_master_handle_t *handle, | |||
| status_t status, | |||
| void *userData); | |||
| /*! @brief I2C slave handle typedef. */ | |||
| typedef struct _i2c_slave_handle i2c_slave_handle_t; | |||
| /*! @brief I2C master transfer structure. */ | |||
| typedef struct _i2c_master_transfer | |||
| { | |||
| uint32_t flags; /*!< A transfer flag which controls the transfer. */ | |||
| uint8_t slaveAddress; /*!< 7-bit slave address. */ | |||
| i2c_direction_t direction; /*!< A transfer direction, read or write. */ | |||
| uint32_t subaddress; /*!< A sub address. Transferred MSB first. */ | |||
| uint8_t subaddressSize; /*!< A size of the command buffer. */ | |||
| uint8_t *volatile data; /*!< A transfer buffer. */ | |||
| volatile size_t dataSize; /*!< A transfer size. */ | |||
| } i2c_master_transfer_t; | |||
| /*! @brief I2C master handle structure. */ | |||
| struct _i2c_master_handle | |||
| { | |||
| i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */ | |||
| size_t transferSize; /*!< Total bytes to be transferred. */ | |||
| uint8_t state; /*!< A transfer state maintained during transfer. */ | |||
| i2c_master_transfer_callback_t completionCallback; /*!< A callback function called when the transfer is finished. */ | |||
| void *userData; /*!< A callback parameter passed to the callback function. */ | |||
| }; | |||
| /*! @brief I2C slave transfer structure. */ | |||
| typedef struct _i2c_slave_transfer | |||
| { | |||
| i2c_slave_transfer_event_t event; /*!< A reason that the callback is invoked. */ | |||
| uint8_t *volatile data; /*!< A transfer buffer. */ | |||
| volatile size_t dataSize; /*!< A transfer size. */ | |||
| status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for | |||
| #kI2C_SlaveCompletionEvent. */ | |||
| size_t transferredCount; /*!< A number of bytes actually transferred since the start or since the last repeated | |||
| start. */ | |||
| } i2c_slave_transfer_t; | |||
| /*! @brief I2C slave transfer callback typedef. */ | |||
| typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userData); | |||
| /*! @brief I2C slave handle structure. */ | |||
| struct _i2c_slave_handle | |||
| { | |||
| volatile bool isBusy; /*!< Indicates whether a transfer is busy. */ | |||
| i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */ | |||
| uint32_t eventMask; /*!< A mask of enabled events. */ | |||
| i2c_slave_transfer_callback_t callback; /*!< A callback function called at the transfer event. */ | |||
| void *userData; /*!< A callback parameter passed to the callback. */ | |||
| }; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /*_cplusplus. */ | |||
| /*! | |||
| * @name Initialization and deinitialization | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock | |||
| * and configure the I2C with master configuration. | |||
| * | |||
| * @note This API should be called at the beginning of the application. | |||
| * Otherwise, any operation to the I2C module can cause a hard fault | |||
| * because the clock is not enabled. The configuration structure can be custom filled | |||
| * or it can be set with default values by using the I2C_MasterGetDefaultConfig(). | |||
| * After calling this API, the master is ready to transfer. | |||
| * This is an example. | |||
| * @code | |||
| * i2c_master_config_t config = { | |||
| * .enableMaster = true, | |||
| * .enableStopHold = false, | |||
| * .highDrive = false, | |||
| * .baudRate_Bps = 100000, | |||
| * .glitchFilterWidth = 0 | |||
| * }; | |||
| * I2C_MasterInit(I2C0, &config, 12000000U); | |||
| * @endcode | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param masterConfig A pointer to the master configuration structure | |||
| * @param srcClock_Hz I2C peripheral clock frequency in Hz | |||
| */ | |||
| void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); | |||
| /*! | |||
| * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock | |||
| * and initialize the I2C with the slave configuration. | |||
| * | |||
| * @note This API should be called at the beginning of the application. | |||
| * Otherwise, any operation to the I2C module can cause a hard fault | |||
| * because the clock is not enabled. The configuration structure can partly be set | |||
| * with default values by I2C_SlaveGetDefaultConfig() or it can be custom filled by the user. | |||
| * This is an example. | |||
| * @code | |||
| * i2c_slave_config_t config = { | |||
| * .enableSlave = true, | |||
| * .enableGeneralCall = false, | |||
| * .addressingMode = kI2C_Address7bit, | |||
| * .slaveAddress = 0x1DU, | |||
| * .enableWakeUp = false, | |||
| * .enablehighDrive = false, | |||
| * .enableBaudRateCtl = false, | |||
| * .sclStopHoldTime_ns = 4000 | |||
| * }; | |||
| * I2C_SlaveInit(I2C0, &config, 12000000U); | |||
| * @endcode | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param slaveConfig A pointer to the slave configuration structure | |||
| * @param srcClock_Hz I2C peripheral clock frequency in Hz | |||
| */ | |||
| void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz); | |||
| /*! | |||
| * @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock. | |||
| * The I2C master module can't work unless the I2C_MasterInit is called. | |||
| * @param base I2C base pointer | |||
| */ | |||
| void I2C_MasterDeinit(I2C_Type *base); | |||
| /*! | |||
| * @brief De-initializes the I2C slave peripheral. Calling this API gates the I2C clock. | |||
| * The I2C slave module can't work unless the I2C_SlaveInit is called to enable the clock. | |||
| * @param base I2C base pointer | |||
| */ | |||
| void I2C_SlaveDeinit(I2C_Type *base); | |||
| /*! | |||
| * @brief Get instance number for I2C module. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| */ | |||
| uint32_t I2C_GetInstance(I2C_Type *base); | |||
| /*! | |||
| * @brief Sets the I2C master configuration structure to default values. | |||
| * | |||
| * The purpose of this API is to get the configuration structure initialized for use in the I2C_MasterConfigure(). | |||
| * Use the initialized structure unchanged in the I2C_MasterConfigure() or modify | |||
| * the structure before calling the I2C_MasterConfigure(). | |||
| * This is an example. | |||
| * @code | |||
| * i2c_master_config_t config; | |||
| * I2C_MasterGetDefaultConfig(&config); | |||
| * @endcode | |||
| * @param masterConfig A pointer to the master configuration structure. | |||
| */ | |||
| void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig); | |||
| /*! | |||
| * @brief Sets the I2C slave configuration structure to default values. | |||
| * | |||
| * The purpose of this API is to get the configuration structure initialized for use in the I2C_SlaveConfigure(). | |||
| * Modify fields of the structure before calling the I2C_SlaveConfigure(). | |||
| * This is an example. | |||
| * @code | |||
| * i2c_slave_config_t config; | |||
| * I2C_SlaveGetDefaultConfig(&config); | |||
| * @endcode | |||
| * @param slaveConfig A pointer to the slave configuration structure. | |||
| */ | |||
| void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); | |||
| /*! | |||
| * @brief Enables or disables the I2C peripheral operation. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param enable Pass true to enable and false to disable the module. | |||
| */ | |||
| static inline void I2C_Enable(I2C_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->C1 |= I2C_C1_IICEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->C1 &= ~(uint8_t)I2C_C1_IICEN_MASK; | |||
| } | |||
| } | |||
| /* @} */ | |||
| /*! | |||
| * @name Status | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Gets the I2C status flags. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @return status flag, use status flag to AND #_i2c_flags to get the related status. | |||
| */ | |||
| uint32_t I2C_MasterGetStatusFlags(I2C_Type *base); | |||
| /*! | |||
| * @brief Gets the I2C status flags. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @return status flag, use status flag to AND #_i2c_flags to get the related status. | |||
| */ | |||
| static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base) | |||
| { | |||
| return I2C_MasterGetStatusFlags(base); | |||
| } | |||
| /*! | |||
| * @brief Clears the I2C status flag state. | |||
| * | |||
| * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param statusMask The status flag mask, defined in type i2c_status_flag_t. | |||
| * The parameter can be any combination of the following values: | |||
| * @arg kI2C_StartDetectFlag (if available) | |||
| * @arg kI2C_StopDetectFlag (if available) | |||
| * @arg kI2C_ArbitrationLostFlag | |||
| * @arg kI2C_IntPendingFlagFlag | |||
| */ | |||
| static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMask) | |||
| { | |||
| /* Must clear the STARTF / STOPF bits prior to clearing IICIF */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT | |||
| if ((uint32_t)kI2C_StartDetectFlag == (statusMask & (uint32_t)kI2C_StartDetectFlag)) | |||
| { | |||
| /* Shift the odd-ball flags back into place. */ | |||
| base->FLT |= (uint8_t)(statusMask >> 8U); | |||
| } | |||
| #endif | |||
| #ifdef I2C_HAS_STOP_DETECT | |||
| if ((uint32_t)kI2C_StopDetectFlag == (statusMask & (uint32_t)kI2C_StopDetectFlag)) | |||
| { | |||
| /* Shift the odd-ball flags back into place. */ | |||
| base->FLT |= (uint8_t)(statusMask >> 8U); | |||
| } | |||
| #endif | |||
| base->S = (uint8_t)statusMask; | |||
| } | |||
| /*! | |||
| * @brief Clears the I2C status flag state. | |||
| * | |||
| * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param statusMask The status flag mask, defined in type i2c_status_flag_t. | |||
| * The parameter can be any combination of the following values: | |||
| * @arg kI2C_StartDetectFlag (if available) | |||
| * @arg kI2C_StopDetectFlag (if available) | |||
| * @arg kI2C_ArbitrationLostFlag | |||
| * @arg kI2C_IntPendingFlagFlag | |||
| */ | |||
| static inline void I2C_SlaveClearStatusFlags(I2C_Type *base, uint32_t statusMask) | |||
| { | |||
| I2C_MasterClearStatusFlags(base, statusMask); | |||
| } | |||
| /* @} */ | |||
| /*! | |||
| * @name Interrupts | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Enables I2C interrupt requests. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param mask interrupt source | |||
| * The parameter can be combination of the following source if defined: | |||
| * @arg kI2C_GlobalInterruptEnable | |||
| * @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable | |||
| * @arg kI2C_SdaTimeoutInterruptEnable | |||
| */ | |||
| void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask); | |||
| /*! | |||
| * @brief Disables I2C interrupt requests. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param mask interrupt source | |||
| * The parameter can be combination of the following source if defined: | |||
| * @arg kI2C_GlobalInterruptEnable | |||
| * @arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable | |||
| * @arg kI2C_SdaTimeoutInterruptEnable | |||
| */ | |||
| void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask); | |||
| /*! | |||
| * @name DMA Control | |||
| * @{ | |||
| */ | |||
| #if defined(FSL_FEATURE_I2C_HAS_DMA_SUPPORT) && FSL_FEATURE_I2C_HAS_DMA_SUPPORT | |||
| /*! | |||
| * @brief Enables/disables the I2C DMA interrupt. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param enable true to enable, false to disable | |||
| */ | |||
| static inline void I2C_EnableDMA(I2C_Type *base, bool enable) | |||
| { | |||
| if (enable) | |||
| { | |||
| base->C1 |= I2C_C1_DMAEN_MASK; | |||
| } | |||
| else | |||
| { | |||
| base->C1 &= ~(uint8_t)I2C_C1_DMAEN_MASK; | |||
| } | |||
| } | |||
| #endif /* FSL_FEATURE_I2C_HAS_DMA_SUPPORT */ | |||
| /*! | |||
| * @brief Gets the I2C tx/rx data register address. This API is used to provide a transfer address | |||
| * for I2C DMA transfer configuration. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @return data register address | |||
| */ | |||
| static inline uint32_t I2C_GetDataRegAddr(I2C_Type *base) | |||
| { | |||
| return (uint32_t)(&(base->D)); | |||
| } | |||
| /* @} */ | |||
| /*! | |||
| * @name Bus Operations | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Sets the I2C master transfer baud rate. | |||
| * | |||
| * @param base I2C base pointer | |||
| * @param baudRate_Bps the baud rate value in bps | |||
| * @param srcClock_Hz Source clock | |||
| */ | |||
| void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); | |||
| /*! | |||
| * @brief Sends a START on the I2C bus. | |||
| * | |||
| * This function is used to initiate a new master mode transfer by sending the START signal. | |||
| * The slave address is sent following the I2C START signal. | |||
| * | |||
| * @param base I2C peripheral base pointer | |||
| * @param address 7-bit slave device address. | |||
| * @param direction Master transfer directions(transmit/receive). | |||
| * @retval kStatus_Success Successfully send the start signal. | |||
| * @retval kStatus_I2C_Busy Current bus is busy. | |||
| */ | |||
| status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); | |||
| /*! | |||
| * @brief Sends a STOP signal on the I2C bus. | |||
| * | |||
| * @retval kStatus_Success Successfully send the stop signal. | |||
| * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. | |||
| */ | |||
| status_t I2C_MasterStop(I2C_Type *base); | |||
| /*! | |||
| * @brief Sends a REPEATED START on the I2C bus. | |||
| * | |||
| * @param base I2C peripheral base pointer | |||
| * @param address 7-bit slave device address. | |||
| * @param direction Master transfer directions(transmit/receive). | |||
| * @retval kStatus_Success Successfully send the start signal. | |||
| * @retval kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master. | |||
| */ | |||
| status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); | |||
| /*! | |||
| * @brief Performs a polling send transaction on the I2C bus. | |||
| * | |||
| * @param base The I2C peripheral base pointer. | |||
| * @param txBuff The pointer to the data to be transferred. | |||
| * @param txSize The length in bytes of the data to be transferred. | |||
| * @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag | |||
| * to issue a stop and kI2C_TransferNoStop to not send a stop. | |||
| * @retval kStatus_Success Successfully complete the data transmission. | |||
| * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. | |||
| * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. | |||
| */ | |||
| status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags); | |||
| /*! | |||
| * @brief Performs a polling receive transaction on the I2C bus. | |||
| * | |||
| * @note The I2C_MasterReadBlocking function stops the bus before reading the final byte. | |||
| * Without stopping the bus prior for the final read, the bus issues another read, resulting | |||
| * in garbage data being read into the data register. | |||
| * | |||
| * @param base I2C peripheral base pointer. | |||
| * @param rxBuff The pointer to the data to store the received data. | |||
| * @param rxSize The length in bytes of the data to be received. | |||
| * @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag | |||
| * to issue a stop and kI2C_TransferNoStop to not send a stop. | |||
| * @retval kStatus_Success Successfully complete the data transmission. | |||
| * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. | |||
| */ | |||
| status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags); | |||
| /*! | |||
| * @brief Performs a polling send transaction on the I2C bus. | |||
| * | |||
| * @param base The I2C peripheral base pointer. | |||
| * @param txBuff The pointer to the data to be transferred. | |||
| * @param txSize The length in bytes of the data to be transferred. | |||
| * @retval kStatus_Success Successfully complete the data transmission. | |||
| * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. | |||
| * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. | |||
| */ | |||
| status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); | |||
| /*! | |||
| * @brief Performs a polling receive transaction on the I2C bus. | |||
| * | |||
| * @param base I2C peripheral base pointer. | |||
| * @param rxBuff The pointer to the data to store the received data. | |||
| * @param rxSize The length in bytes of the data to be received. | |||
| * @retval kStatus_Success Successfully complete data receive. | |||
| * @retval kStatus_I2C_Timeout Wait status flag timeout. | |||
| */ | |||
| status_t I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); | |||
| /*! | |||
| * @brief Performs a master polling transfer on the I2C bus. | |||
| * | |||
| * @note The API does not return until the transfer succeeds or fails due | |||
| * to arbitration lost or receiving a NAK. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param xfer Pointer to the transfer structure. | |||
| * @retval kStatus_Success Successfully complete the data transmission. | |||
| * @retval kStatus_I2C_Busy Previous transmission still not finished. | |||
| * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. | |||
| * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. | |||
| * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. | |||
| */ | |||
| status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer); | |||
| /* @} */ | |||
| /*! | |||
| * @name Transactional | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the I2C handle which is used in transactional functions. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_master_handle_t structure to store the transfer state. | |||
| * @param callback pointer to user callback function. | |||
| * @param userData user parameter passed to the callback function. | |||
| */ | |||
| void I2C_MasterTransferCreateHandle(I2C_Type *base, | |||
| i2c_master_handle_t *handle, | |||
| i2c_master_transfer_callback_t callback, | |||
| void *userData); | |||
| /*! | |||
| * @brief Performs a master interrupt non-blocking transfer on the I2C bus. | |||
| * | |||
| * @note Calling the API returns immediately after transfer initiates. The user needs | |||
| * to call I2C_MasterGetTransferCount to poll the transfer status to check whether | |||
| * the transfer is finished. If the return status is not kStatus_I2C_Busy, the transfer | |||
| * is finished. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. | |||
| * @param xfer pointer to i2c_master_transfer_t structure. | |||
| * @retval kStatus_Success Successfully start the data transmission. | |||
| * @retval kStatus_I2C_Busy Previous transmission still not finished. | |||
| * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. | |||
| */ | |||
| status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); | |||
| /*! | |||
| * @brief Gets the master transfer status during a interrupt non-blocking transfer. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. | |||
| * @param count Number of bytes transferred so far by the non-blocking transaction. | |||
| * @retval kStatus_InvalidArgument count is Invalid. | |||
| * @retval kStatus_Success Successfully return the count. | |||
| */ | |||
| status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count); | |||
| /*! | |||
| * @brief Aborts an interrupt non-blocking transfer early. | |||
| * | |||
| * @note This API can be called at any time when an interrupt non-blocking transfer initiates | |||
| * to abort the transfer early. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_master_handle_t structure which stores the transfer state | |||
| * @retval kStatus_I2C_Timeout Timeout during polling flag. | |||
| * @retval kStatus_Success Successfully abort the transfer. | |||
| */ | |||
| status_t I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle); | |||
| /*! | |||
| * @brief Master interrupt handler. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param i2cHandle pointer to i2c_master_handle_t structure. | |||
| */ | |||
| void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle); | |||
| /*! | |||
| * @brief Initializes the I2C handle which is used in transactional functions. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_slave_handle_t structure to store the transfer state. | |||
| * @param callback pointer to user callback function. | |||
| * @param userData user parameter passed to the callback function. | |||
| */ | |||
| void I2C_SlaveTransferCreateHandle(I2C_Type *base, | |||
| i2c_slave_handle_t *handle, | |||
| i2c_slave_transfer_callback_t callback, | |||
| void *userData); | |||
| /*! | |||
| * @brief Starts accepting slave transfers. | |||
| * | |||
| * Call this API after calling the I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing | |||
| * transactions driven by an I2C master. The slave monitors the I2C bus and passes events to the | |||
| * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked | |||
| * from the interrupt context. | |||
| * | |||
| * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to | |||
| * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive. | |||
| * The kI2C_SlaveTransmitEvent and kLPI2C_SlaveReceiveEvent events are always enabled and do not need | |||
| * to be included in the mask. Alternatively, pass 0 to get a default set of only the transmit and | |||
| * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as | |||
| * a convenient way to enable all events. | |||
| * | |||
| * @param base The I2C peripheral base address. | |||
| * @param handle Pointer to i2c_slave_handle_t structure which stores the transfer state. | |||
| * @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify | |||
| * which events to send to the callback. Other accepted values are 0 to get a default set of | |||
| * only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events. | |||
| * | |||
| * @retval kStatus_Success Slave transfers were successfully started. | |||
| * @retval kStatus_I2C_Busy Slave transfers have already been started on this handle. | |||
| */ | |||
| status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask); | |||
| /*! | |||
| * @brief Aborts the slave transfer. | |||
| * | |||
| * @note This API can be called at any time to stop slave for handling the bus events. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_slave_handle_t structure which stores the transfer state. | |||
| */ | |||
| void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle); | |||
| /*! | |||
| * @brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param handle pointer to i2c_slave_handle_t structure. | |||
| * @param count Number of bytes transferred so far by the non-blocking transaction. | |||
| * @retval kStatus_InvalidArgument count is Invalid. | |||
| * @retval kStatus_Success Successfully return the count. | |||
| */ | |||
| status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count); | |||
| /*! | |||
| * @brief Slave interrupt handler. | |||
| * | |||
| * @param base I2C base pointer. | |||
| * @param i2cHandle pointer to i2c_slave_handle_t structure which stores the transfer state | |||
| */ | |||
| void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle); | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /*_cplusplus. */ | |||
| /*@}*/ | |||
| #endif /* _FSL_I2C_H_*/ | |||
| @@ -0,0 +1,617 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_i2c_edma.h" | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.i2c_edma" | |||
| #endif | |||
| /*<! @breif Structure definition for i2c_master_edma_private_handle_t. The structure is private. */ | |||
| typedef struct _i2c_master_edma_private_handle | |||
| { | |||
| I2C_Type *base; | |||
| i2c_master_edma_handle_t *handle; | |||
| } i2c_master_edma_private_handle_t; | |||
| /*! @brief i2c master DMA transfer state. */ | |||
| enum _i2c_master_dma_transfer_states | |||
| { | |||
| kIdleState = 0x0U, /*!< I2C bus idle. */ | |||
| kTransferDataState = 0x1U, /*!< 7-bit address check state. */ | |||
| }; | |||
| /******************************************************************************* | |||
| * Prototypes | |||
| ******************************************************************************/ | |||
| /*! | |||
| * @brief EDMA callback for I2C master EDMA driver. | |||
| * | |||
| * @param handle EDMA handler for I2C master EDMA driver | |||
| * @param userData user param passed to the callback function | |||
| */ | |||
| static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds); | |||
| /*! | |||
| * @brief Check and clear status operation. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param status current i2c hardware status. | |||
| * @retval kStatus_Success No error found. | |||
| * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. | |||
| * @retval kStatus_I2C_Nak Received Nak error. | |||
| */ | |||
| static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status); | |||
| /*! | |||
| * @brief EDMA config for I2C master driver. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state | |||
| */ | |||
| static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle); | |||
| /*! | |||
| * @brief Set up master transfer, send slave address and sub address(if any), wait until the | |||
| * wait until address sent status return. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state | |||
| * @param xfer pointer to i2c_master_transfer_t structure | |||
| */ | |||
| static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, | |||
| i2c_master_edma_handle_t *handle, | |||
| i2c_master_transfer_t *xfer); | |||
| /******************************************************************************* | |||
| * Variables | |||
| ******************************************************************************/ | |||
| /*<! Private handle only used for internally. */ | |||
| static i2c_master_edma_private_handle_t s_i2cEdmaPrivateHandle[FSL_FEATURE_SOC_I2C_COUNT]; | |||
| /******************************************************************************* | |||
| * Codes | |||
| ******************************************************************************/ | |||
| static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds) | |||
| { | |||
| i2c_master_edma_private_handle_t *i2cPrivateHandle = (i2c_master_edma_private_handle_t *)userData; | |||
| status_t result = kStatus_Success; | |||
| uint8_t tmpReg; | |||
| size_t tmpdataSize; | |||
| /* Disable DMA. */ | |||
| I2C_EnableDMA(i2cPrivateHandle->base, false); | |||
| /* Send stop if kI2C_TransferNoStop flag is not asserted. */ | |||
| if (0U == (i2cPrivateHandle->handle->transfer.flags & (uint32_t)kI2C_TransferNoStopFlag)) | |||
| { | |||
| if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read) | |||
| { | |||
| /* Change to send NAK at the last byte. */ | |||
| i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK; | |||
| /* Wait the last data to be received. */ | |||
| while (0U == (i2cPrivateHandle->base->S & (uint8_t)kI2C_TransferCompleteFlag)) | |||
| { | |||
| } | |||
| /* Send stop signal. */ | |||
| result = I2C_MasterStop(i2cPrivateHandle->base); | |||
| /* Read the last data byte. */ | |||
| tmpReg = i2cPrivateHandle->base->D; | |||
| tmpdataSize = i2cPrivateHandle->handle->transfer.dataSize; | |||
| *(i2cPrivateHandle->handle->transfer.data + tmpdataSize - 1U) = tmpReg; | |||
| } | |||
| else | |||
| { | |||
| /* Wait the last data to be sent. */ | |||
| while (0U == (i2cPrivateHandle->base->S & (uint8_t)kI2C_TransferCompleteFlag)) | |||
| { | |||
| } | |||
| /* Send stop signal. */ | |||
| result = I2C_MasterStop(i2cPrivateHandle->base); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read) | |||
| { | |||
| /* Change to send NAK at the last byte. */ | |||
| i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK; | |||
| /* Wait the last data to be received. */ | |||
| while (0U == (i2cPrivateHandle->base->S & (uint8_t)kI2C_TransferCompleteFlag)) | |||
| { | |||
| } | |||
| /* Change direction to send. */ | |||
| i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK; | |||
| /* Read the last data byte. */ | |||
| tmpReg = i2cPrivateHandle->base->D; | |||
| tmpdataSize = i2cPrivateHandle->handle->transfer.dataSize; | |||
| *(i2cPrivateHandle->handle->transfer.data + tmpdataSize - 1U) = tmpReg; | |||
| } | |||
| } | |||
| i2cPrivateHandle->handle->state = (uint8_t)kIdleState; | |||
| if (NULL != i2cPrivateHandle->handle->completionCallback) | |||
| { | |||
| i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result, | |||
| i2cPrivateHandle->handle->userData); | |||
| } | |||
| } | |||
| static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status) | |||
| { | |||
| status_t result = kStatus_Success; | |||
| /* Check arbitration lost. */ | |||
| if (0U != (status & (uint32_t)kI2C_ArbitrationLostFlag)) | |||
| { | |||
| /* Clear arbitration lost flag. */ | |||
| base->S = (uint8_t)kI2C_ArbitrationLostFlag; | |||
| result = kStatus_I2C_ArbitrationLost; | |||
| } | |||
| /* Check NAK */ | |||
| else if (0U != (status & (uint32_t)kI2C_ReceiveNakFlag)) | |||
| { | |||
| result = kStatus_I2C_Nak; | |||
| } | |||
| else | |||
| { | |||
| /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ | |||
| } | |||
| return result; | |||
| } | |||
| static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, | |||
| i2c_master_edma_handle_t *handle, | |||
| i2c_master_transfer_t *xfer) | |||
| { | |||
| assert(NULL != handle); | |||
| assert(NULL != xfer); | |||
| status_t result = kStatus_Success; | |||
| #if I2C_RETRY_TIMES | |||
| uint32_t waitTimes = I2C_RETRY_TIMES; | |||
| #endif | |||
| if (handle->state != (uint8_t)kIdleState) | |||
| { | |||
| return kStatus_I2C_Busy; | |||
| } | |||
| else | |||
| { | |||
| i2c_direction_t direction = xfer->direction; | |||
| /* Init the handle member. */ | |||
| handle->transfer = *xfer; | |||
| /* Save total transfer size. */ | |||
| handle->transferSize = xfer->dataSize; | |||
| handle->state = (uint8_t)kTransferDataState; | |||
| /* Clear all status before transfer. */ | |||
| I2C_MasterClearStatusFlags(base, (uint32_t)kClearFlags); | |||
| /* Change to send write address when it's a read operation with command. */ | |||
| if ((xfer->subaddressSize > 0U) && (0U != (uint8_t)(xfer->direction == kI2C_Read))) | |||
| { | |||
| direction = kI2C_Write; | |||
| } | |||
| /* If repeated start is requested, send repeated start. */ | |||
| if (0U != (handle->transfer.flags & (uint32_t)kI2C_TransferRepeatedStartFlag)) | |||
| { | |||
| result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction); | |||
| } | |||
| else /* For normal transfer, send start. */ | |||
| { | |||
| result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); | |||
| } | |||
| if (kStatus_Success != result) | |||
| { | |||
| return result; | |||
| } | |||
| #if I2C_RETRY_TIMES | |||
| while ((0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) && (0U != --waitTimes)) | |||
| { | |||
| } | |||
| if (waitTimes == 0) | |||
| { | |||
| return kStatus_I2C_Timeout; | |||
| } | |||
| #else | |||
| while (0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) | |||
| { | |||
| } | |||
| #endif | |||
| /* Check if there's transfer error. */ | |||
| result = I2C_CheckAndClearError(base, base->S); | |||
| /* Return if error. */ | |||
| if (kStatus_Success != result) | |||
| { | |||
| if (result == kStatus_I2C_Nak) | |||
| { | |||
| result = kStatus_I2C_Addr_Nak; | |||
| if (I2C_MasterStop(base) != kStatus_Success) | |||
| { | |||
| result = kStatus_I2C_Timeout; | |||
| } | |||
| if (NULL != handle->completionCallback) | |||
| { | |||
| (handle->completionCallback)(base, handle, result, handle->userData); | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| /* Send subaddress. */ | |||
| if (0U != handle->transfer.subaddressSize) | |||
| { | |||
| do | |||
| { | |||
| /* Clear interrupt pending flag. */ | |||
| base->S = (uint8_t)kI2C_IntPendingFlag; | |||
| handle->transfer.subaddressSize--; | |||
| base->D = (uint8_t)((handle->transfer.subaddress) >> (8U * handle->transfer.subaddressSize)); | |||
| /* Wait until data transfer complete. */ | |||
| #if I2C_RETRY_TIMES | |||
| waitTimes = I2C_RETRY_TIMES; | |||
| while ((0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) && (0U != --waitTimes)) | |||
| { | |||
| } | |||
| if (waitTimes == 0) | |||
| { | |||
| return kStatus_I2C_Timeout; | |||
| } | |||
| #else | |||
| while (0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) | |||
| { | |||
| } | |||
| #endif | |||
| /* Check if there's transfer error. */ | |||
| result = I2C_CheckAndClearError(base, base->S); | |||
| if (0 != result) | |||
| { | |||
| return result; | |||
| } | |||
| } while (handle->transfer.subaddressSize > 0U); | |||
| if (handle->transfer.direction == kI2C_Read) | |||
| { | |||
| /* Clear pending flag. */ | |||
| base->S = (uint8_t)kI2C_IntPendingFlag; | |||
| /* Send repeated start and slave address. */ | |||
| result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); | |||
| if (0 != result) | |||
| { | |||
| return result; | |||
| } | |||
| /* Wait until data transfer complete. */ | |||
| #if I2C_RETRY_TIMES | |||
| waitTimes = I2C_RETRY_TIMES; | |||
| while ((0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) && (0U != --waitTimes)) | |||
| { | |||
| } | |||
| if (waitTimes == 0) | |||
| { | |||
| return kStatus_I2C_Timeout; | |||
| } | |||
| #else | |||
| while (0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) | |||
| { | |||
| } | |||
| #endif | |||
| /* Check if there's transfer error. */ | |||
| result = I2C_CheckAndClearError(base, base->S); | |||
| if (0 != result) | |||
| { | |||
| return result; | |||
| } | |||
| } | |||
| } | |||
| /* Clear pending flag. */ | |||
| base->S = (uint8_t)kI2C_IntPendingFlag; | |||
| } | |||
| return result; | |||
| } | |||
| static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle) | |||
| { | |||
| edma_transfer_config_t transfer_config = {0}; | |||
| if (handle->transfer.direction == kI2C_Read) | |||
| { | |||
| transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base); | |||
| transfer_config.destAddr = (uint32_t)(handle->transfer.data); | |||
| transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1U); | |||
| transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes; | |||
| transfer_config.srcOffset = 0; | |||
| transfer_config.destTransferSize = kEDMA_TransferSize1Bytes; | |||
| transfer_config.destOffset = 1; | |||
| transfer_config.minorLoopBytes = 1; | |||
| } | |||
| else | |||
| { | |||
| transfer_config.srcAddr = ((uint32_t)handle->transfer.data + 1U); | |||
| transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base); | |||
| transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1U); | |||
| transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes; | |||
| transfer_config.srcOffset = 1; | |||
| transfer_config.destTransferSize = kEDMA_TransferSize1Bytes; | |||
| transfer_config.destOffset = 0; | |||
| transfer_config.minorLoopBytes = 1; | |||
| } | |||
| /* Store the initially configured eDMA minor byte transfer count into the I2C handle */ | |||
| handle->nbytes = (uint8_t)(transfer_config.minorLoopBytes); | |||
| (void)EDMA_SubmitTransfer(handle->dmaHandle, (const edma_transfer_config_t *)(uint32_t)&transfer_config); | |||
| EDMA_StartTransfer(handle->dmaHandle); | |||
| } | |||
| /*! | |||
| * brief Initializes the I2C handle which is used in transactional functions. | |||
| * | |||
| * param base I2C peripheral base address. | |||
| * param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| * param callback A pointer to the user callback function. | |||
| * param userData A user parameter passed to the callback function. | |||
| * param edmaHandle eDMA handle pointer. | |||
| */ | |||
| void I2C_MasterCreateEDMAHandle(I2C_Type *base, | |||
| i2c_master_edma_handle_t *handle, | |||
| i2c_master_edma_transfer_callback_t callback, | |||
| void *userData, | |||
| edma_handle_t *edmaHandle) | |||
| { | |||
| assert(NULL != handle); | |||
| assert(NULL != edmaHandle); | |||
| uint32_t instance = I2C_GetInstance(base); | |||
| /* Zero handle. */ | |||
| (void)memset(handle, 0, sizeof(*handle)); | |||
| /* Set the user callback and userData. */ | |||
| handle->completionCallback = callback; | |||
| handle->userData = userData; | |||
| /* Set the base for the handle. */ | |||
| base = base; | |||
| /* Set the handle for EDMA. */ | |||
| handle->dmaHandle = edmaHandle; | |||
| s_i2cEdmaPrivateHandle[instance].base = base; | |||
| s_i2cEdmaPrivateHandle[instance].handle = handle; | |||
| EDMA_SetCallback(edmaHandle, (edma_callback)I2C_MasterTransferCallbackEDMA, &s_i2cEdmaPrivateHandle[instance]); | |||
| } | |||
| /*! | |||
| * brief Performs a master eDMA non-blocking transfer on the I2C bus. | |||
| * | |||
| * param base I2C peripheral base address. | |||
| * param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| * param xfer A pointer to the transfer structure of i2c_master_transfer_t. | |||
| * retval kStatus_Success Successfully completed the data transmission. | |||
| * retval kStatus_I2C_Busy A previous transmission is still not finished. | |||
| * retval kStatus_I2C_Timeout Transfer error, waits for a signal timeout. | |||
| * retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. | |||
| * retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. | |||
| */ | |||
| status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer) | |||
| { | |||
| assert(NULL != handle); | |||
| assert(NULL != xfer); | |||
| status_t result; | |||
| uint8_t tmpReg; | |||
| volatile uint8_t dummy = 0; | |||
| /* Add this to avoid build warning. */ | |||
| dummy++; | |||
| /* Disable dma xfer. */ | |||
| I2C_EnableDMA(base, false); | |||
| /* Send address and command buffer(if there is), until senddata phase or receive data phase. */ | |||
| result = I2C_InitTransferStateMachineEDMA(base, handle, xfer); | |||
| if (0 != result) | |||
| { | |||
| /* Send stop if received Nak. */ | |||
| if (result == kStatus_I2C_Nak) | |||
| { | |||
| if (I2C_MasterStop(base) != kStatus_Success) | |||
| { | |||
| result = kStatus_I2C_Timeout; | |||
| } | |||
| } | |||
| /* Reset the state to idle state. */ | |||
| handle->state = (uint8_t)kIdleState; | |||
| return result; | |||
| } | |||
| /* Configure dma transfer. */ | |||
| /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read, | |||
| need to send stop before reading the last byte, so the dma transfer size should | |||
| be (xSize - 1). */ | |||
| if (handle->transfer.dataSize > 1U) | |||
| { | |||
| I2C_MasterTransferEDMAConfig(base, handle); | |||
| if (handle->transfer.direction == kI2C_Read) | |||
| { | |||
| /* Change direction for receive. */ | |||
| base->C1 &= ~(uint8_t)(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); | |||
| /* Read dummy to release the bus. */ | |||
| dummy = base->D; | |||
| /* Enabe dma transfer. */ | |||
| I2C_EnableDMA(base, true); | |||
| } | |||
| else | |||
| { | |||
| /* Enabe dma transfer. */ | |||
| I2C_EnableDMA(base, true); | |||
| /* Send the first data. */ | |||
| base->D = *handle->transfer.data; | |||
| } | |||
| } | |||
| else /* If transfer size is 1, use polling method. */ | |||
| { | |||
| if (handle->transfer.direction == kI2C_Read) | |||
| { | |||
| tmpReg = base->C1; | |||
| /* Change direction to Rx. */ | |||
| tmpReg &= ~(uint8_t)I2C_C1_TX_MASK; | |||
| /* Configure send NAK */ | |||
| tmpReg |= I2C_C1_TXAK_MASK; | |||
| base->C1 = tmpReg; | |||
| /* Read dummy to release the bus. */ | |||
| dummy = base->D; | |||
| } | |||
| else | |||
| { | |||
| base->D = *handle->transfer.data; | |||
| } | |||
| /* Wait until data transfer complete. */ | |||
| #if I2C_RETRY_TIMES | |||
| uint32_t waitTimes = I2C_RETRY_TIMES; | |||
| while ((0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) && (0U != --waitTimes)) | |||
| { | |||
| } | |||
| if (waitTimes == 0U) | |||
| { | |||
| return kStatus_I2C_Timeout; | |||
| } | |||
| #else | |||
| while (0U == (base->S & (uint8_t)kI2C_IntPendingFlag)) | |||
| { | |||
| } | |||
| #endif | |||
| /* Clear pending flag. */ | |||
| base->S = (uint8_t)kI2C_IntPendingFlag; | |||
| /* Send stop if kI2C_TransferNoStop flag is not asserted. */ | |||
| if (0U == (handle->transfer.flags & (uint32_t)kI2C_TransferNoStopFlag)) | |||
| { | |||
| result = I2C_MasterStop(base); | |||
| } | |||
| else | |||
| { | |||
| /* Change direction to send. */ | |||
| base->C1 |= I2C_C1_TX_MASK; | |||
| } | |||
| /* Read the last byte of data. */ | |||
| if (handle->transfer.direction == kI2C_Read) | |||
| { | |||
| tmpReg = base->D; | |||
| *handle->transfer.data = tmpReg; | |||
| } | |||
| /* Reset the state to idle. */ | |||
| handle->state = (uint8_t)kIdleState; | |||
| } | |||
| return result; | |||
| } | |||
| /*! | |||
| * brief Gets a master transfer status during the eDMA non-blocking transfer. | |||
| * | |||
| * param base I2C peripheral base address. | |||
| * param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| * param count A number of bytes transferred by the non-blocking transaction. | |||
| */ | |||
| status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count) | |||
| { | |||
| assert(NULL != handle->dmaHandle); | |||
| if (NULL == count) | |||
| { | |||
| return kStatus_InvalidArgument; | |||
| } | |||
| if ((uint8_t)kIdleState != handle->state) | |||
| { | |||
| *count = (handle->transferSize - | |||
| (uint32_t)handle->nbytes * | |||
| EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); | |||
| } | |||
| else | |||
| { | |||
| *count = handle->transferSize; | |||
| } | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * brief Aborts a master eDMA non-blocking transfer early. | |||
| * | |||
| * param base I2C peripheral base address. | |||
| * param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| */ | |||
| void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle) | |||
| { | |||
| EDMA_AbortTransfer(handle->dmaHandle); | |||
| /* Disable dma transfer. */ | |||
| I2C_EnableDMA(base, false); | |||
| /* Reset the state to idle. */ | |||
| handle->state = (uint8_t)kIdleState; | |||
| } | |||
| @@ -0,0 +1,120 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef _FSL_I2C_DMA_H_ | |||
| #define _FSL_I2C_DMA_H_ | |||
| #include "fsl_i2c.h" | |||
| #include "fsl_edma.h" | |||
| /*! | |||
| * @addtogroup i2c_edma_driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief I2C EDMA driver version 2.0.8. */ | |||
| #define FSL_I2C_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 8)) | |||
| /*@}*/ | |||
| /*! @brief Retry times for waiting flag. */ | |||
| #ifndef I2C_RETRY_TIMES | |||
| #define I2C_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */ | |||
| #endif | |||
| /*! @brief I2C master eDMA handle typedef. */ | |||
| typedef struct _i2c_master_edma_handle i2c_master_edma_handle_t; | |||
| /*! @brief I2C master eDMA transfer callback typedef. */ | |||
| typedef void (*i2c_master_edma_transfer_callback_t)(I2C_Type *base, | |||
| i2c_master_edma_handle_t *handle, | |||
| status_t status, | |||
| void *userData); | |||
| /*! @brief I2C master eDMA transfer structure. */ | |||
| struct _i2c_master_edma_handle | |||
| { | |||
| i2c_master_transfer_t transfer; /*!< I2C master transfer structure. */ | |||
| size_t transferSize; /*!< Total bytes to be transferred. */ | |||
| uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ | |||
| uint8_t state; /*!< I2C master transfer status. */ | |||
| edma_handle_t *dmaHandle; /*!< The eDMA handler used. */ | |||
| i2c_master_edma_transfer_callback_t | |||
| completionCallback; /*!< A callback function called after the eDMA transfer is finished. */ | |||
| void *userData; /*!< A callback parameter passed to the callback function. */ | |||
| }; | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif /*_cplusplus. */ | |||
| /*! | |||
| * @name I2C Block eDMA Transfer Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes the I2C handle which is used in transactional functions. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| * @param callback A pointer to the user callback function. | |||
| * @param userData A user parameter passed to the callback function. | |||
| * @param edmaHandle eDMA handle pointer. | |||
| */ | |||
| void I2C_MasterCreateEDMAHandle(I2C_Type *base, | |||
| i2c_master_edma_handle_t *handle, | |||
| i2c_master_edma_transfer_callback_t callback, | |||
| void *userData, | |||
| edma_handle_t *edmaHandle); | |||
| /*! | |||
| * @brief Performs a master eDMA non-blocking transfer on the I2C bus. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| * @param xfer A pointer to the transfer structure of i2c_master_transfer_t. | |||
| * @retval kStatus_Success Successfully completed the data transmission. | |||
| * @retval kStatus_I2C_Busy A previous transmission is still not finished. | |||
| * @retval kStatus_I2C_Timeout Transfer error, waits for a signal timeout. | |||
| * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. | |||
| * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. | |||
| */ | |||
| status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer); | |||
| /*! | |||
| * @brief Gets a master transfer status during the eDMA non-blocking transfer. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| * @param count A number of bytes transferred by the non-blocking transaction. | |||
| */ | |||
| status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count); | |||
| /*! | |||
| * @brief Aborts a master eDMA non-blocking transfer early. | |||
| * | |||
| * @param base I2C peripheral base address. | |||
| * @param handle A pointer to the i2c_master_edma_handle_t structure. | |||
| */ | |||
| void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle); | |||
| /* @} */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif /*_cplusplus. */ | |||
| /*@}*/ | |||
| #endif /*_FSL_I2C_DMA_H_*/ | |||
| @@ -0,0 +1,131 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2019 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #include "fsl_i2c_freertos.h" | |||
| /* Component ID definition, used by tools. */ | |||
| #ifndef FSL_COMPONENT_ID | |||
| #define FSL_COMPONENT_ID "platform.drivers.i2c_freertos" | |||
| #endif | |||
| static void I2C_RTOS_Callback(I2C_Type *base, i2c_master_handle_t *drv_handle, status_t status, void *userData) | |||
| { | |||
| i2c_rtos_handle_t *handle = (i2c_rtos_handle_t *)userData; | |||
| BaseType_t reschedule; | |||
| handle->async_status = status; | |||
| xSemaphoreGiveFromISR(handle->semaphore, &reschedule); | |||
| portYIELD_FROM_ISR(reschedule); | |||
| } | |||
| /*! | |||
| * brief Initializes I2C. | |||
| * | |||
| * This function initializes the I2C module and the related RTOS context. | |||
| * | |||
| * param handle The RTOS I2C handle, the pointer to an allocated space for RTOS context. | |||
| * param base The pointer base address of the I2C instance to initialize. | |||
| * param masterConfig The configuration structure to set-up I2C in master mode. | |||
| * param srcClock_Hz The frequency of an input clock of the I2C module. | |||
| * return status of the operation. | |||
| */ | |||
| status_t I2C_RTOS_Init(i2c_rtos_handle_t *handle, | |||
| I2C_Type *base, | |||
| const i2c_master_config_t *masterConfig, | |||
| uint32_t srcClock_Hz) | |||
| { | |||
| if (handle == NULL) | |||
| { | |||
| return kStatus_InvalidArgument; | |||
| } | |||
| if (base == NULL) | |||
| { | |||
| return kStatus_InvalidArgument; | |||
| } | |||
| memset(handle, 0, sizeof(i2c_rtos_handle_t)); | |||
| #if (configSUPPORT_STATIC_ALLOCATION == 1) | |||
| handle->mutex = xSemaphoreCreateMutexStatic(&handle->mutexBuffer); | |||
| #else | |||
| handle->mutex = xSemaphoreCreateMutex(); | |||
| #endif | |||
| if (handle->mutex == NULL) | |||
| { | |||
| return kStatus_Fail; | |||
| } | |||
| #if (configSUPPORT_STATIC_ALLOCATION == 1) | |||
| handle->semaphore = xSemaphoreCreateBinaryStatic(&handle->semaphoreBuffer); | |||
| #else | |||
| handle->semaphore = xSemaphoreCreateBinary(); | |||
| #endif | |||
| if (handle->semaphore == NULL) | |||
| { | |||
| vSemaphoreDelete(handle->mutex); | |||
| return kStatus_Fail; | |||
| } | |||
| handle->base = base; | |||
| I2C_MasterInit(handle->base, masterConfig, srcClock_Hz); | |||
| I2C_MasterTransferCreateHandle(base, &handle->drv_handle, I2C_RTOS_Callback, (void *)handle); | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * brief Deinitializes the I2C. | |||
| * | |||
| * This function deinitializes the I2C module and the related RTOS context. | |||
| * | |||
| * param handle The RTOS I2C handle. | |||
| */ | |||
| status_t I2C_RTOS_Deinit(i2c_rtos_handle_t *handle) | |||
| { | |||
| I2C_MasterDeinit(handle->base); | |||
| vSemaphoreDelete(handle->semaphore); | |||
| vSemaphoreDelete(handle->mutex); | |||
| return kStatus_Success; | |||
| } | |||
| /*! | |||
| * brief Performs the I2C transfer. | |||
| * | |||
| * This function performs the I2C transfer according to the data given in the transfer structure. | |||
| * | |||
| * param handle The RTOS I2C handle. | |||
| * param transfer A structure specifying the transfer parameters. | |||
| * return status of the operation. | |||
| */ | |||
| status_t I2C_RTOS_Transfer(i2c_rtos_handle_t *handle, i2c_master_transfer_t *transfer) | |||
| { | |||
| status_t status; | |||
| /* Lock resource mutex */ | |||
| if (xSemaphoreTake(handle->mutex, portMAX_DELAY) != pdTRUE) | |||
| { | |||
| return kStatus_I2C_Busy; | |||
| } | |||
| status = I2C_MasterTransferNonBlocking(handle->base, &handle->drv_handle, transfer); | |||
| if (status != kStatus_Success) | |||
| { | |||
| xSemaphoreGive(handle->mutex); | |||
| return status; | |||
| } | |||
| /* Wait for transfer to finish */ | |||
| (void)xSemaphoreTake(handle->semaphore, portMAX_DELAY); | |||
| /* Unlock resource mutex */ | |||
| xSemaphoreGive(handle->mutex); | |||
| /* Return status captured by callback function */ | |||
| return handle->async_status; | |||
| } | |||
| @@ -0,0 +1,111 @@ | |||
| /* | |||
| * Copyright (c) 2015, Freescale Semiconductor, Inc. | |||
| * Copyright 2016-2020 NXP | |||
| * All rights reserved. | |||
| * | |||
| * SPDX-License-Identifier: BSD-3-Clause | |||
| */ | |||
| #ifndef __FSL_I2C_FREERTOS_H__ | |||
| #define __FSL_I2C_FREERTOS_H__ | |||
| #include "FreeRTOS.h" | |||
| #include "portable.h" | |||
| #include "semphr.h" | |||
| #include "fsl_i2c.h" | |||
| /*! | |||
| * @addtogroup i2c_freertos_driver I2C FreeRTOS Driver | |||
| * @{ | |||
| */ | |||
| /******************************************************************************* | |||
| * Definitions | |||
| ******************************************************************************/ | |||
| /*! @name Driver version */ | |||
| /*@{*/ | |||
| /*! @brief I2C FreeRTOS driver version 2.0.8. */ | |||
| #define FSL_I2C_FREERTOS_DRIVER_VERSION (MAKE_VERSION(2, 0, 8)) | |||
| /*@}*/ | |||
| /*! | |||
| * @cond RTOS_PRIVATE | |||
| * @brief I2C FreeRTOS handle | |||
| */ | |||
| typedef struct _i2c_rtos_handle | |||
| { | |||
| I2C_Type *base; /*!< I2C base address */ | |||
| i2c_master_handle_t drv_handle; /*!< A handle of the underlying driver, treated as opaque by the RTOS layer */ | |||
| status_t async_status; /*!< Transactional state of the underlying driver */ | |||
| SemaphoreHandle_t mutex; /*!< A mutex to lock the handle during a transfer */ | |||
| SemaphoreHandle_t semaphore; /*!< A semaphore to notify and unblock task when the transfer ends */ | |||
| #if (configSUPPORT_STATIC_ALLOCATION == 1) | |||
| StaticSemaphore_t mutexBuffer; /*!< Statically allocated memory for mutex */ | |||
| StaticSemaphore_t semaphoreBuffer; /*!< Statically allocated memory for semaphore */ | |||
| #endif | |||
| } i2c_rtos_handle_t; | |||
| /*! \endcond */ | |||
| /******************************************************************************* | |||
| * API | |||
| ******************************************************************************/ | |||
| #if defined(__cplusplus) | |||
| extern "C" { | |||
| #endif | |||
| /*! | |||
| * @name I2C RTOS Operation | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @brief Initializes I2C. | |||
| * | |||
| * This function initializes the I2C module and the related RTOS context. | |||
| * | |||
| * @param handle The RTOS I2C handle, the pointer to an allocated space for RTOS context. | |||
| * @param base The pointer base address of the I2C instance to initialize. | |||
| * @param masterConfig The configuration structure to set-up I2C in master mode. | |||
| * @param srcClock_Hz The frequency of an input clock of the I2C module. | |||
| * @return status of the operation. | |||
| */ | |||
| status_t I2C_RTOS_Init(i2c_rtos_handle_t *handle, | |||
| I2C_Type *base, | |||
| const i2c_master_config_t *masterConfig, | |||
| uint32_t srcClock_Hz); | |||
| /*! | |||
| * @brief Deinitializes the I2C. | |||
| * | |||
| * This function deinitializes the I2C module and the related RTOS context. | |||
| * | |||
| * @param handle The RTOS I2C handle. | |||
| */ | |||
| status_t I2C_RTOS_Deinit(i2c_rtos_handle_t *handle); | |||
| /*! | |||
| * @brief Performs the I2C transfer. | |||
| * | |||
| * This function performs the I2C transfer according to the data given in the transfer structure. | |||
| * | |||
| * @param handle The RTOS I2C handle. | |||
| * @param transfer A structure specifying the transfer parameters. | |||
| * @return status of the operation. | |||
| */ | |||
| status_t I2C_RTOS_Transfer(i2c_rtos_handle_t *handle, i2c_master_transfer_t *transfer); | |||
| /*! | |||
| * @} | |||
| */ | |||
| #if defined(__cplusplus) | |||
| } | |||
| #endif | |||
| /*! | |||
| * @} | |||
| */ | |||
| #endif /* __FSL_I2C_FREERTOS_H__ */ | |||