Browse Source

新建工程

div1
QQyyblithe 2 years ago
commit
43a709f15f
100 changed files with 93204 additions and 0 deletions
  1. +1
    -0
      .gitignore
  2. +40
    -0
      IAR/settings/test01.Debug.cspy.bat
  3. +31
    -0
      IAR/settings/test01.Debug.cspy.ps1
  4. +29
    -0
      IAR/settings/test01.Debug.driver.xcl
  5. +15
    -0
      IAR/settings/test01.Debug.general.xcl
  6. +13
    -0
      IAR/settings/test01.crun
  7. +1117
    -0
      IAR/settings/test01.dbgdt
  8. +165
    -0
      IAR/settings/test01.dnx
  9. +1
    -0
      IAR/settings/test01.reggroups
  10. +431
    -0
      IAR/settings/test01.wsdt
  11. +39
    -0
      IAR/settings/test01_Debug.jlink
  12. +296
    -0
      IAR/test01.dep
  13. +2966
    -0
      IAR/test01.ewd
  14. +2143
    -0
      IAR/test01.ewp
  15. +2405
    -0
      IAR/test01.ewt
  16. +7
    -0
      IAR/test01.eww
  17. +378
    -0
      Include/arm_common_tables.h
  18. +66
    -0
      Include/arm_const_structs.h
  19. +7361
    -0
      Include/arm_math.h
  20. +894
    -0
      Include/cmsis_armcc.h
  21. +1444
    -0
      Include/cmsis_armclang.h
  22. +1891
    -0
      Include/cmsis_armclang_ltm.h
  23. +283
    -0
      Include/cmsis_compiler.h
  24. +2168
    -0
      Include/cmsis_gcc.h
  25. +964
    -0
      Include/cmsis_iccarm.h
  26. +39
    -0
      Include/cmsis_version.h
  27. +2968
    -0
      Include/core_armv81mml.h
  28. +1921
    -0
      Include/core_armv8mbl.h
  29. +2835
    -0
      Include/core_armv8mml.h
  30. +952
    -0
      Include/core_cm0.h
  31. +1085
    -0
      Include/core_cm0plus.h
  32. +979
    -0
      Include/core_cm1.h
  33. +1996
    -0
      Include/core_cm23.h
  34. +1937
    -0
      Include/core_cm3.h
  35. +2910
    -0
      Include/core_cm33.h
  36. +2910
    -0
      Include/core_cm35p.h
  37. +2124
    -0
      Include/core_cm4.h
  38. +2725
    -0
      Include/core_cm7.h
  39. +74
    -0
      Include/core_dsp.h
  40. +1025
    -0
      Include/core_sc000.h
  41. +1912
    -0
      Include/core_sc300.h
  42. +272
    -0
      Include/mpu_armv7.h
  43. +346
    -0
      Include/mpu_armv8.h
  44. +70
    -0
      Include/tz_context.h
  45. +494
    -0
      drivers/fsl_adc16.c
  46. +512
    -0
      drivers/fsl_adc16.h
  47. +214
    -0
      drivers/fsl_aoi.c
  48. +186
    -0
      drivers/fsl_aoi.h
  49. +2212
    -0
      drivers/fsl_clock.c
  50. +1532
    -0
      drivers/fsl_clock.h
  51. +371
    -0
      drivers/fsl_cmp.c
  52. +321
    -0
      drivers/fsl_cmp.h
  53. +280
    -0
      drivers/fsl_common.c
  54. +672
    -0
      drivers/fsl_common.h
  55. +322
    -0
      drivers/fsl_crc.c
  56. +173
    -0
      drivers/fsl_crc.h
  57. +300
    -0
      drivers/fsl_dac.c
  58. +357
    -0
      drivers/fsl_dac.h
  59. +91
    -0
      drivers/fsl_dmamux.c
  60. +177
    -0
      drivers/fsl_dmamux.h
  61. +2242
    -0
      drivers/fsl_dspi.c
  62. +1237
    -0
      drivers/fsl_dspi.h
  63. +1530
    -0
      drivers/fsl_dspi_edma.c
  64. +296
    -0
      drivers/fsl_dspi_edma.h
  65. +134
    -0
      drivers/fsl_dspi_freertos.c
  66. +111
    -0
      drivers/fsl_dspi_freertos.h
  67. +2849
    -0
      drivers/fsl_edma.c
  68. +951
    -0
      drivers/fsl_edma.h
  69. +593
    -0
      drivers/fsl_enc.c
  70. +458
    -0
      drivers/fsl_enc.h
  71. +140
    -0
      drivers/fsl_ewm.c
  72. +218
    -0
      drivers/fsl_ewm.h
  73. +41
    -0
      drivers/fsl_flash.h
  74. +254
    -0
      drivers/fsl_flexbus.c
  75. +243
    -0
      drivers/fsl_flexbus.h
  76. +3564
    -0
      drivers/fsl_flexcan.c
  77. +1422
    -0
      drivers/fsl_flexcan.h
  78. +239
    -0
      drivers/fsl_flexcan_edma.c
  79. +140
    -0
      drivers/fsl_flexcan_edma.h
  80. +393
    -0
      drivers/fsl_ftfx_adapter.h
  81. +549
    -0
      drivers/fsl_ftfx_cache.c
  82. +124
    -0
      drivers/fsl_ftfx_cache.h
  83. +1444
    -0
      drivers/fsl_ftfx_controller.c
  84. +822
    -0
      drivers/fsl_ftfx_controller.h
  85. +90
    -0
      drivers/fsl_ftfx_features.h
  86. +1475
    -0
      drivers/fsl_ftfx_flash.c
  87. +663
    -0
      drivers/fsl_ftfx_flash.h
  88. +506
    -0
      drivers/fsl_ftfx_flexnvm.c
  89. +572
    -0
      drivers/fsl_ftfx_flexnvm.h
  90. +67
    -0
      drivers/fsl_ftfx_utilities.h
  91. +1205
    -0
      drivers/fsl_ftm.c
  92. +1027
    -0
      drivers/fsl_ftm.h
  93. +382
    -0
      drivers/fsl_gpio.c
  94. +574
    -0
      drivers/fsl_gpio.h
  95. +2423
    -0
      drivers/fsl_i2c.c
  96. +805
    -0
      drivers/fsl_i2c.h
  97. +617
    -0
      drivers/fsl_i2c_edma.c
  98. +120
    -0
      drivers/fsl_i2c_edma.h
  99. +131
    -0
      drivers/fsl_i2c_freertos.c
  100. +111
    -0
      drivers/fsl_i2c_freertos.h

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
IAR/Debug/

+ 40
- 0
IAR/settings/test01.Debug.cspy.bat View File

@@ -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

+ 31
- 0
IAR/settings/test01.Debug.cspy.ps1 View File

@@ -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"
}

+ 29
- 0
IAR/settings/test01.Debug.driver.xcl View File

@@ -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"





+ 15
- 0
IAR/settings/test01.Debug.general.xcl View File

@@ -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"





+ 13
- 0
IAR/settings/test01.crun View File

@@ -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>

+ 1117
- 0
IAR/settings/test01.dbgdt
File diff suppressed because it is too large
View File


+ 165
- 0
IAR/settings/test01.dnx View File

@@ -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>

+ 1
- 0
IAR/settings/test01.reggroups View File

@@ -0,0 +1 @@


+ 431
- 0
IAR/settings/test01.wsdt
File diff suppressed because it is too large
View File


+ 39
- 0
IAR/settings/test01_Debug.jlink View File

@@ -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

+ 296
- 0
IAR/test01.dep View File

@@ -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>

+ 2966
- 0
IAR/test01.ewd
File diff suppressed because it is too large
View File


+ 2143
- 0
IAR/test01.ewp
File diff suppressed because it is too large
View File


+ 2405
- 0
IAR/test01.ewt
File diff suppressed because it is too large
View File


+ 7
- 0
IAR/test01.eww View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<workspace>
<project>
<path>$WS_DIR$\test01.ewp</path>
</project>
<batchBuild />
</workspace>

+ 378
- 0
Include/arm_common_tables.h View File

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

+ 66
- 0
Include/arm_const_structs.h View File

@@ -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

+ 7361
- 0
Include/arm_math.h
File diff suppressed because it is too large
View File


+ 894
- 0
Include/cmsis_armcc.h View File

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

+ 1444
- 0
Include/cmsis_armclang.h
File diff suppressed because it is too large
View File


+ 1891
- 0
Include/cmsis_armclang_ltm.h
File diff suppressed because it is too large
View File


+ 283
- 0
Include/cmsis_compiler.h View File

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


+ 2168
- 0
Include/cmsis_gcc.h
File diff suppressed because it is too large
View File


+ 964
- 0
Include/cmsis_iccarm.h View File

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

+ 39
- 0
Include/cmsis_version.h View File

@@ -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

+ 2968
- 0
Include/core_armv81mml.h
File diff suppressed because it is too large
View File


+ 1921
- 0
Include/core_armv8mbl.h
File diff suppressed because it is too large
View File


+ 2835
- 0
Include/core_armv8mml.h
File diff suppressed because it is too large
View File


+ 952
- 0
Include/core_cm0.h View File

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

+ 1085
- 0
Include/core_cm0plus.h
File diff suppressed because it is too large
View File


+ 979
- 0
Include/core_cm1.h View File

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

+ 1996
- 0
Include/core_cm23.h
File diff suppressed because it is too large
View File


+ 1937
- 0
Include/core_cm3.h
File diff suppressed because it is too large
View File


+ 2910
- 0
Include/core_cm33.h
File diff suppressed because it is too large
View File


+ 2910
- 0
Include/core_cm35p.h
File diff suppressed because it is too large
View File


+ 2124
- 0
Include/core_cm4.h
File diff suppressed because it is too large
View File


+ 2725
- 0
Include/core_cm7.h
File diff suppressed because it is too large
View File


+ 74
- 0
Include/core_dsp.h View File

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

+ 1025
- 0
Include/core_sc000.h
File diff suppressed because it is too large
View File


+ 1912
- 0
Include/core_sc300.h
File diff suppressed because it is too large
View File


+ 272
- 0
Include/mpu_armv7.h View File

@@ -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

+ 346
- 0
Include/mpu_armv8.h View File

@@ -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


+ 70
- 0
Include/tz_context.h View File

@@ -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

+ 494
- 0
drivers/fsl_adc16.c View File

@@ -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;
}

+ 512
- 0
drivers/fsl_adc16.h View File

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

+ 214
- 0
drivers/fsl_aoi.c View File

@@ -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;
}

+ 186
- 0
drivers/fsl_aoi.h View File

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

+ 2212
- 0
drivers/fsl_clock.c
File diff suppressed because it is too large
View File


+ 1532
- 0
drivers/fsl_clock.h
File diff suppressed because it is too large
View File


+ 371
- 0
drivers/fsl_cmp.c View File

@@ -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;
}

+ 321
- 0
drivers/fsl_cmp.h View File

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

+ 280
- 0
drivers/fsl_common.c View File

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

+ 672
- 0
drivers/fsl_common.h View File

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

+ 322
- 0
drivers/fsl_crc.c View File

@@ -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;
}

+ 173
- 0
drivers/fsl_crc.h View File

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

+ 300
- 0
drivers/fsl_dac.c View File

@@ -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. */
}

+ 357
- 0
drivers/fsl_dac.h View File

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

+ 91
- 0
drivers/fsl_dmamux.c View File

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

+ 177
- 0
drivers/fsl_dmamux.h View File

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

+ 2242
- 0
drivers/fsl_dspi.c
File diff suppressed because it is too large
View File


+ 1237
- 0
drivers/fsl_dspi.h
File diff suppressed because it is too large
View File


+ 1530
- 0
drivers/fsl_dspi_edma.c
File diff suppressed because it is too large
View File


+ 296
- 0
drivers/fsl_dspi_edma.h View File

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

+ 134
- 0
drivers/fsl_dspi_freertos.c View File

@@ -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;
}

+ 111
- 0
drivers/fsl_dspi_freertos.h View File

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

+ 2849
- 0
drivers/fsl_edma.c
File diff suppressed because it is too large
View File


+ 951
- 0
drivers/fsl_edma.h View File

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

+ 593
- 0
drivers/fsl_enc.c View File

@@ -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;
}

+ 458
- 0
drivers/fsl_enc.h View File

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

+ 140
- 0
drivers/fsl_ewm.c View File

@@ -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);
}

+ 218
- 0
drivers/fsl_ewm.h View File

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

+ 41
- 0
drivers/fsl_flash.h View File

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

+ 254
- 0
drivers/fsl_flexbus.c View File

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

+ 243
- 0
drivers/fsl_flexbus.h View File

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

+ 3564
- 0
drivers/fsl_flexcan.c
File diff suppressed because it is too large
View File


+ 1422
- 0
drivers/fsl_flexcan.h
File diff suppressed because it is too large
View File


+ 239
- 0
drivers/fsl_flexcan_edma.c View File

@@ -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);
}

+ 140
- 0
drivers/fsl_flexcan_edma.h View File

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

+ 393
- 0
drivers/fsl_ftfx_adapter.h View File

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

+ 549
- 0
drivers/fsl_ftfx_cache.c View File

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

+ 124
- 0
drivers/fsl_ftfx_cache.h View File

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

+ 1444
- 0
drivers/fsl_ftfx_controller.c
File diff suppressed because it is too large
View File


+ 822
- 0
drivers/fsl_ftfx_controller.h View File

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

+ 90
- 0
drivers/fsl_ftfx_features.h View File

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

+ 1475
- 0
drivers/fsl_ftfx_flash.c
File diff suppressed because it is too large
View File


+ 663
- 0
drivers/fsl_ftfx_flash.h View File

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

+ 506
- 0
drivers/fsl_ftfx_flexnvm.c View File

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

+ 572
- 0
drivers/fsl_ftfx_flexnvm.h View File

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

+ 67
- 0
drivers/fsl_ftfx_utilities.h View File

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

+ 1205
- 0
drivers/fsl_ftm.c
File diff suppressed because it is too large
View File


+ 1027
- 0
drivers/fsl_ftm.h
File diff suppressed because it is too large
View File


+ 382
- 0
drivers/fsl_gpio.c View File

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

+ 574
- 0
drivers/fsl_gpio.h View File

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

+ 2423
- 0
drivers/fsl_i2c.c
File diff suppressed because it is too large
View File


+ 805
- 0
drivers/fsl_i2c.h View File

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

+ 617
- 0
drivers/fsl_i2c_edma.c View File

@@ -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;
}

+ 120
- 0
drivers/fsl_i2c_edma.h View File

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

+ 131
- 0
drivers/fsl_i2c_freertos.c View File

@@ -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;
}

+ 111
- 0
drivers/fsl_i2c_freertos.h View File

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

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save