@@ -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__ */ |