This commit is contained in:
Michele Balistreri 2023-03-22 15:47:22 +01:00
parent 80a3132f85
commit 88325503e7
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
9 changed files with 1812 additions and 1069 deletions

View File

@ -20,6 +20,7 @@
#include "ethUstream.h"
#include "ethUtils.h"
#include "common.h"
#define MAX_INT256 32
#define MAX_ADDRESS 20
@ -87,7 +88,7 @@ static uint16_t processAccessList(txContext_t *context) {
return EXCEPTION;
}
if (context->currentFieldPos < context->currentFieldLength) {
uint32_t copySize = MIN(context->commandLength, context->currentFieldLength - context->currentFieldPos);
uint32_t copySize = APP_MIN(context->commandLength, context->currentFieldLength - context->currentFieldPos);
if (copyTxData(context, NULL, copySize) == EXCEPTION) {
return EXCEPTION;
}

View File

@ -464,7 +464,6 @@
<option id="gnu.c.compiler.option.preprocessor.undef.symbol.1473181615" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol" useByScannerDiscovery="false"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1814948021" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/zcbor}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/xip}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/device}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/CMSIS}&quot;"/>
@ -473,6 +472,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/freertos/freertos_kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/source}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/app}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/zcbor}&quot;"/>
</option>
<option id="gnu.c.compiler.option.include.files.271263686" name="Include files (-include)" superClass="gnu.c.compiler.option.include.files" useByScannerDiscovery="false"/>
<option id="gnu.c.compiler.option.optimization.flags.781262918" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-common" valueType="string"/>
@ -540,6 +540,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/freertos/freertos_kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/source}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/app}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/zcbor}&quot;"/>
</option>
<option id="gnu.both.asm.option.warnings.nowarn.708206456" name="Suppress warnings (-W)" superClass="gnu.both.asm.option.warnings.nowarn" useByScannerDiscovery="false"/>
<option id="gnu.both.asm.option.version.1433379675" name="Announce version (-v)" superClass="gnu.both.asm.option.version" useByScannerDiscovery="false"/>
@ -711,7 +712,7 @@
<storageModule moduleId="com.nxp.mcuxpresso.core.datamodels">
<sdkName>SDK_2.x_EVK-MIMXRT1064</sdkName>
<sdkVersion>2.13.0</sdkVersion>
<sdkComponents>platform.drivers.clock.MIMXRT1064;platform.drivers.xip_device.MIMXRT1064;platform.drivers.igpio.MIMXRT1064;platform.drivers.common.MIMXRT1064;platform.drivers.lpuart.MIMXRT1064;platform.drivers.iomuxc.MIMXRT1064;platform.drivers.lpi2c.MIMXRT1064;platform.drivers.trng.MIMXRT1064;platform.drivers.csi.MIMXRT1064;device.MIMXRT1064_CMSIS.MIMXRT1064;device.MIMXRT1064_system.MIMXRT1064;CMSIS_Include_core_cm.MIMXRT1064;platform.drivers.xip_board.evkmimxrt1064.MIMXRT1064;project_template.evkmimxrt1064.MIMXRT1064;device.MIMXRT1064_startup.MIMXRT1064;platform.drivers.dcp.MIMXRT1064;platform.drivers.cache_armv7_m7.MIMXRT1064;middleware.baremetal.MIMXRT1064;</sdkComponents>
<sdkComponents>platform.drivers.clock.MIMXRT1064;platform.drivers.xip_device.MIMXRT1064;platform.drivers.igpio.MIMXRT1064;platform.drivers.common.MIMXRT1064;platform.drivers.lpuart.MIMXRT1064;platform.drivers.iomuxc.MIMXRT1064;platform.drivers.lpi2c.MIMXRT1064;platform.drivers.trng.MIMXRT1064;platform.drivers.csi.MIMXRT1064;device.MIMXRT1064_CMSIS.MIMXRT1064;device.MIMXRT1064_system.MIMXRT1064;CMSIS_Include_core_cm.MIMXRT1064;platform.drivers.xip_board.evkmimxrt1064.MIMXRT1064;project_template.evkmimxrt1064.MIMXRT1064;device.MIMXRT1064_startup.MIMXRT1064;platform.drivers.dcp.MIMXRT1064;middleware.baremetal.MIMXRT1064;platform.drivers.flexio.MIMXRT1064;</sdkComponents>
<boardId>evkmimxrt1064</boardId>
<package>MIMXRT1064DVL6A</package>
<core>cm7</core>

View File

@ -1,602 +0,0 @@
/*
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_cache.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7"
#endif
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
#define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
#define L2CACHE_8WAYS_MASK 0xFFU
#define L2CACHE_16WAYS_MASK 0xFFFFU
#define L2CACHE_SMALLWAYS_NUM 8U
#define L2CACHE_1KBCOVERTOB 1024U
#define L2CACHE_SAMLLWAYS_SIZE 16U
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Set for all ways and waiting for the operation finished.
* This is provided for all the background operations.
*
* @param auxCtlReg The auxiliary control register.
* @param regAddr The register address to be operated.
*/
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
/*!
* @brief Invalidates the Level 2 cache line by physical address.
* This function invalidates a cache line by physcial address.
*
* @param address The physical addderss of the cache.
* The format of the address shall be :
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
* Tag | index | 0
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
* If the input address is not aligned, it will be changed to 32-byte aligned address.
* The n is varies according to the index width.
* @return The actual 32-byte aligned physical address be operated.
*/
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
/*!
* @brief Cleans the Level 2 cache line based on the physical address.
* This function cleans a cache line based on a physcial address.
*
* @param address The physical addderss of the cache.
* The format of the address shall be :
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
* Tag | index | 0
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
* If the input address is not aligned, it will be changed to 32-byte aligned address.
* The n is varies according to the index width.
* @return The actual 32-byte aligned physical address be operated.
*/
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
/*!
* @brief Cleans and invalidates the Level 2 cache line based on the physical address.
* This function cleans and invalidates a cache line based on a physcial address.
*
* @param address The physical addderss of the cache.
* The format of the address shall be :
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
* Tag | index | 0
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
* If the input address is not aligned, it will be changed to 32-byte aligned address.
* The n is varies according to the index width.
* @return The actual 32-byte aligned physical address be operated.
*/
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
/*!
* @brief Gets the number of the Level 2 cache and the way size.
* This function cleans and invalidates a cache line based on a physcial address.
*
* @param num_ways The number of the cache way.
* @param size_way The way size.
*/
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
/*******************************************************************************
* Code
******************************************************************************/
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
{
uint16_t mask = L2CACHE_8WAYS_MASK;
uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
/* Check the ways used at first. */
if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
{
mask = L2CACHE_16WAYS_MASK;
}
/* Set the opeartion for all ways/entries of the cache. */
*(uint32_t *)regAddr = mask;
/* Waiting for until the operation is complete. */
while ((*(volatile uint32_t *)regAddr & mask) && timeout)
{
__ASM("nop");
timeout--;
}
}
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
{
/* Align the address first. */
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
/* Invalidate the cache line by physical address. */
L2CACHEC->REG7_INV_PA = address;
return address;
}
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
{
/* Align the address first. */
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
/* Invalidate the cache line by physical address. */
L2CACHEC->REG7_CLEAN_PA = address;
return address;
}
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
{
/* Align the address first. */
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
/* Clean and invalidate the cache line by physical address. */
L2CACHEC->REG7_CLEAN_INV_PA = address;
return address;
}
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
{
assert(num_ways);
assert(size_way);
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
*num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
if (!size)
{
/* 0 internally mapped to the same size as 1 - 16KB.*/
size += 1;
}
*size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
}
/*!
* brief Initializes the level 2 cache controller module.
*
* param config Pointer to configuration structure. See "l2cache_config_t".
*/
void L2CACHE_Init(l2cache_config_t *config)
{
assert(config);
uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
uint8_t count;
uint32_t auxReg = 0;
/*The aux register must be configured when the cachec is disabled
* So disable first if the cache controller is enabled.
*/
if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
{
L2CACHE_Disable();
}
/* Unlock all entries. */
if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
{
waysNum = 0xFFFFU;
}
for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++)
{
L2CACHE_LockdownByWayEnable(count, waysNum, false);
}
/* Set the ways and way-size etc. */
auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
L2CACHEC->REG1_AUX_CONTROL = auxReg;
/* Set the tag/data ram latency. */
if (config->lateConfig)
{
uint32_t data = 0;
/* Tag latency. */
data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) |
L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
L2CACHEC->REG1_TAG_RAM_CONTROL = data;
/* Data latency. */
data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) |
L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
L2CACHEC->REG1_DATA_RAM_CONTROL = data;
}
}
/*!
* brief Gets an available default settings for the cache controller.
*
* This function initializes the cache controller configuration structure with default settings.
* The default values are:
* code
* config->waysNum = kL2CACHE_8ways;
* config->waySize = kL2CACHE_32KbSize;
* config->repacePolicy = kL2CACHE_Roundrobin;
* config->lateConfig = NULL;
* config->istrPrefetchEnable = false;
* config->dataPrefetchEnable = false;
* config->nsLockdownEnable = false;
* config->writeAlloc = kL2CACHE_UseAwcache;
* endcode
* param config Pointer to the configuration structure.
*/
void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
{
assert(config);
/* Initializes the configure structure to zero. */
memset(config, 0, sizeof(*config));
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
/* Get the default value */
config->wayNum = (l2cache_way_num_t)number;
config->waySize = (l2cache_way_size)size;
config->repacePolicy = kL2CACHE_Roundrobin;
config->lateConfig = NULL;
config->istrPrefetchEnable = false;
config->dataPrefetchEnable = false;
config->nsLockdownEnable = false;
config->writeAlloc = kL2CACHE_UseAwcache;
}
/*!
* brief Enables the level 2 cache controller.
* This function enables the cache controller. Must be written using a secure access.
* If write with a Non-secure access will cause a DECERR response.
*
*/
void L2CACHE_Enable(void)
{
/* Invalidate first. */
L2CACHE_Invalidate();
/* Enable the level 2 cache controller. */
L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
}
/*!
* brief Disables the level 2 cache controller.
* This function disables the cache controller. Must be written using a secure access.
* If write with a Non-secure access will cause a DECERR response.
*
*/
void L2CACHE_Disable(void)
{
/* First CleanInvalidate all enties in the cache. */
L2CACHE_CleanInvalidate();
/* Disable the level 2 cache controller. */
L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
/* DSB - data sync barrier.*/
__DSB();
}
/*!
* brief Invalidates the Level 2 cache.
* This function invalidates all entries in cache.
*
*/
void L2CACHE_Invalidate(void)
{
/* Invalidate all entries in cache. */
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
/*!
* brief Cleans the level 2 cache controller.
* This function cleans all entries in the level 2 cache controller.
*
*/
void L2CACHE_Clean(void)
{
/* Clean all entries of the cache. */
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
/*!
* brief Cleans and invalidates the level 2 cache controller.
* This function cleans and invalidates all entries in the level 2 cache controller.
*
*/
void L2CACHE_CleanInvalidate(void)
{
/* Clean all entries of the cache. */
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
/*!
* brief Invalidates the Level 2 cache lines in the range of two physical addresses.
* This function invalidates all cache lines between two physical addresses.
*
* param address The start address of the memory to be invalidated.
* param size_byte The memory size.
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
uint32_t endAddr = address + size_byte;
/* Invalidate addresses in the range. */
while (address < endAddr)
{
address = L2CACHE_InvalidateLineByAddr(address);
/* Update the size. */
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
}
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
/*!
* brief Cleans the Level 2 cache lines in the range of two physical addresses.
* This function cleans all cache lines between two physical addresses.
*
* param address The start address of the memory to be cleaned.
* param size_byte The memory size.
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
{
uint32_t num_ways = 0;
uint32_t size_way = 0;
uint32_t endAddr = address + size_byte;
/* Get the number and size of the cache way. */
L2CACHE_GetWayNumSize(&num_ways, &size_way);
/* Check if the clean size is over the cache size. */
if ((endAddr - address) > num_ways * size_way)
{
L2CACHE_Clean();
return;
}
/* Clean addresses in the range. */
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
{
/* Clean the address in the range. */
address = L2CACHE_CleanLineByAddr(address);
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
}
L2CACHEC->REG7_CACHE_SYNC = 0;
}
/*!
* brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
* This function cleans and invalidates all cache lines between two physical addresses.
*
* param address The start address of the memory to be cleaned and invalidated.
* param size_byte The memory size.
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
{
uint32_t num_ways = 0;
uint32_t size_way = 0;
uint32_t endAddr = address + size_byte;
/* Get the number and size of the cache way. */
L2CACHE_GetWayNumSize(&num_ways, &size_way);
/* Check if the clean size is over the cache size. */
if ((endAddr - address) > num_ways * size_way)
{
L2CACHE_CleanInvalidate();
return;
}
/* Clean addresses in the range. */
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
{
/* Clean the address in the range. */
address = L2CACHE_CleanInvalidateLineByAddr(address);
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
}
L2CACHEC->REG7_CACHE_SYNC = 0;
}
/*!
* brief Enables or disables to lock down the data and instruction by way.
* This function locks down the cached instruction/data by way and prevent the adresses from
* being allocated and prevent dara from being evicted out of the level 2 cache.
* But the normal cache maintenance operations that invalidate, clean or clean
* and validate cache contents affect the locked-down cache lines as normal.
*
* param masterId The master id, range from 0 ~ 7.
* param mask The ways to be enabled or disabled to lockdown.
* each bit in value is related to each way of the cache. for example:
* value: bit 0 ------ way 0.
* value: bit 1 ------ way 1.
* --------------------------
* value: bit 15 ------ way 15.
* Note: please make sure the value setting is align with your supported ways.
* param enable True enable the lockdown, false to disable the lockdown.
*/
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
{
uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
assert(mask < (1U << num_ways));
assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
if (enable)
{
/* Data lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
/* Instruction lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
}
else
{
/* Data lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
/* Instruction lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
}
}
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
/*!
* brief Invalidate cortex-m7 L1 instruction cache by range.
*
* param address The start address of the memory to be invalidated.
* param size_byte The memory size.
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 I-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
{
#if (__DCACHE_PRESENT == 1U)
uint32_t addr = address & ~((uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1U);
uint32_t align_len = address - addr;
int32_t size = (int32_t)size_byte + (int32_t)align_len;
__DSB();
while (size > 0)
{
SCB->ICIMVAU = addr;
addr += (uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
size -= (int32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
}
__DSB();
__ISB();
#endif
}
/*!
* brief Invalidates all instruction caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* param address The physical address.
* param size_byte size of the memory to be invalidated.
* note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_InvalidateByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
L1CACHE_InvalidateICacheByRange(address, size_byte);
}
/*!
* brief Invalidates all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* param address The physical address.
* param size_byte size of the memory to be invalidated.
* note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_InvalidateByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
L1CACHE_InvalidateDCacheByRange(address, size_byte);
}
/*!
* brief Cleans all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* param address The physical address.
* param size_byte size of the memory to be cleaned.
* note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
{
L1CACHE_CleanDCacheByRange(address, size_byte);
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_CleanByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
}
/*!
* brief Cleans and Invalidates all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* param address The physical address.
* param size_byte size of the memory to be cleaned and invalidated.
* note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
{
L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_CleanInvalidateByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
}

View File

@ -1,463 +0,0 @@
/*
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CACHE_H_
#define _FSL_CACHE_H_
#include "fsl_common.h"
/*!
* @addtogroup cache_armv7_m7
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief cache driver version 2.0.4. */
#define FSL_CACHE_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
#ifndef FSL_SDK_DISBLE_L2CACHE_PRESENT
#define FSL_SDK_DISBLE_L2CACHE_PRESENT 0
#endif
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
/*******************************************************************************
* Definitions
******************************************************************************/
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
/*! @brief Number of level 2 cache controller ways. */
typedef enum _l2cache_way_num
{
kL2CACHE_8ways = 0, /*!< 8 ways. */
#if defined(FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY) && FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY
kL2CACHE_16ways /*!< 16 ways. */
#endif /* FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY */
} l2cache_way_num_t;
/*! @brief Level 2 cache controller way size. */
typedef enum _l2cache_way_size
{
kL2CACHE_16KBSize = 1, /*!< 16 KB way size. */
kL2CACHE_32KBSize = 2, /*!< 32 KB way size. */
kL2CACHE_64KBSize = 3, /*!< 64 KB way size. */
kL2CACHE_128KBSize = 4, /*!< 128 KB way size. */
kL2CACHE_256KBSize = 5, /*!< 256 KB way size. */
kL2CACHE_512KBSize = 6 /*!< 512 KB way size. */
} l2cache_way_size;
/*! @brief Level 2 cache controller replacement policy. */
typedef enum _l2cache_replacement
{
kL2CACHE_Pseudorandom = 0U, /*!< Peseudo-random replacement policy using an lfsr. */
kL2CACHE_Roundrobin /*!< Round-robin replacemnt policy. */
} l2cache_replacement_t;
/*! @brief Level 2 cache controller force write allocate options. */
typedef enum _l2cache_writealloc
{
kL2CACHE_UseAwcache = 0, /*!< Use AWCAHE attribute for the write allocate. */
kL2CACHE_NoWriteallocate, /*!< Force no write allocate. */
kL2CACHE_forceWriteallocate /*!< Force write allocate when write misses. */
} l2cache_writealloc_t;
/*! @brief Level 2 cache controller tag/data ram latency. */
typedef enum _l2cache_latency
{
kL2CACHE_1CycleLate = 0, /*!< 1 cycle of latency. */
kL2CACHE_2CycleLate, /*!< 2 cycle of latency. */
kL2CACHE_3CycleLate, /*!< 3 cycle of latency. */
kL2CACHE_4CycleLate, /*!< 4 cycle of latency. */
kL2CACHE_5CycleLate, /*!< 5 cycle of latency. */
kL2CACHE_6CycleLate, /*!< 6 cycle of latency. */
kL2CACHE_7CycleLate, /*!< 7 cycle of latency. */
kL2CACHE_8CycleLate /*!< 8 cycle of latency. */
} l2cache_latency_t;
/*! @brief Level 2 cache controller tag/data ram latency configure structure. */
typedef struct _l2cache_latency_config
{
l2cache_latency_t tagWriteLate; /*!< Tag write latency. */
l2cache_latency_t tagReadLate; /*!< Tag Read latency. */
l2cache_latency_t tagSetupLate; /*!< Tag setup latency. */
l2cache_latency_t dataWriteLate; /*!< Data write latency. */
l2cache_latency_t dataReadLate; /*!< Data Read latency. */
l2cache_latency_t dataSetupLate; /*!< Data setup latency. */
} L2cache_latency_config_t;
/*! @brief Level 2 cache controller configure structure. */
typedef struct _l2cache_config
{
/* ------------------------ l2 cachec basic settings ---------------------------- */
l2cache_way_num_t wayNum; /*!< The number of ways. */
l2cache_way_size waySize; /*!< The way size = Cache Ram size / wayNum. */
l2cache_replacement_t repacePolicy; /*!< Replacemnet policy. */
/* ------------------------ tag/data ram latency settings ----------------------- */
L2cache_latency_config_t *lateConfig; /*!< Tag/data latency configure. Set NUll if not required. */
/* ------------------------ Prefetch enable settings ---------------------------- */
bool istrPrefetchEnable; /*!< Instruction prefetch enable. */
bool dataPrefetchEnable; /*!< Data prefetch enable. */
/* ------------------------ Non-secure access settings -------------------------- */
bool nsLockdownEnable; /*!< None-secure lockdown enable. */
/* ------------------------ other settings -------------------------------------- */
l2cache_writealloc_t writeAlloc; /*!< Write allcoate force option. */
} l2cache_config_t;
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Control for cortex-m7 L1 cache
*@{
*/
/*!
* @brief Enables cortex-m7 L1 instruction cache.
*
*/
static inline void L1CACHE_EnableICache(void)
{
SCB_EnableICache();
}
/*!
* @brief Disables cortex-m7 L1 instruction cache.
*
*/
static inline void L1CACHE_DisableICache(void)
{
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
}
}
/*!
* @brief Invalidate cortex-m7 L1 instruction cache.
*
*/
static inline void L1CACHE_InvalidateICache(void)
{
SCB_InvalidateICache();
}
/*!
* @brief Invalidate cortex-m7 L1 instruction cache by range.
*
* @param address The start address of the memory to be invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 I-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Enables cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_EnableDCache(void)
{
SCB_EnableDCache();
}
/*!
* @brief Disables cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_DisableDCache(void)
{
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
}
}
/*!
* @brief Invalidates cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_InvalidateDCache(void)
{
SCB_InvalidateDCache();
}
/*!
* @brief Cleans cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_CleanDCache(void)
{
SCB_CleanDCache();
}
/*!
* @brief Cleans and Invalidates cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_CleanInvalidateDCache(void)
{
SCB_CleanInvalidateDCache();
}
/*!
* @brief Invalidates cortex-m7 L1 data cache by range.
*
* @param address The start address of the memory to be invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 D-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void L1CACHE_InvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
{
SCB_InvalidateDCache_by_Addr((uint32_t *)address, (int32_t)size_byte);
}
/*!
* @brief Cleans cortex-m7 L1 data cache by range.
*
* @param address The start address of the memory to be cleaned.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 D-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void L1CACHE_CleanDCacheByRange(uint32_t address, uint32_t size_byte)
{
SCB_CleanDCache_by_Addr((uint32_t *)address, (int32_t)size_byte);
}
/*!
* @brief Cleans and Invalidates cortex-m7 L1 data cache by range.
*
* @param address The start address of the memory to be clean and invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 D-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void L1CACHE_CleanInvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
{
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)address, (int32_t)size_byte);
}
/*@}*/
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
/*!
* @name Control for L2 pl310 cache
*@{
*/
/*!
* @brief Initializes the level 2 cache controller module.
*
* @param config Pointer to configuration structure. See "l2cache_config_t".
*/
void L2CACHE_Init(l2cache_config_t *config);
/*!
* @brief Gets an available default settings for the cache controller.
*
* This function initializes the cache controller configuration structure with default settings.
* The default values are:
* @code
* config->waysNum = kL2CACHE_8ways;
* config->waySize = kL2CACHE_32KbSize;
* config->repacePolicy = kL2CACHE_Roundrobin;
* config->lateConfig = NULL;
* config->istrPrefetchEnable = false;
* config->dataPrefetchEnable = false;
* config->nsLockdownEnable = false;
* config->writeAlloc = kL2CACHE_UseAwcache;
* @endcode
* @param config Pointer to the configuration structure.
*/
void L2CACHE_GetDefaultConfig(l2cache_config_t *config);
/*!
* @brief Enables the level 2 cache controller.
* This function enables the cache controller. Must be written using a secure access.
* If write with a Non-secure access will cause a DECERR response.
*
*/
void L2CACHE_Enable(void);
/*!
* @brief Disables the level 2 cache controller.
* This function disables the cache controller. Must be written using a secure access.
* If write with a Non-secure access will cause a DECERR response.
*
*/
void L2CACHE_Disable(void);
/*!
* @brief Invalidates the Level 2 cache.
* This function invalidates all entries in cache.
*
*/
void L2CACHE_Invalidate(void);
/*!
* @brief Invalidates the Level 2 cache lines in the range of two physical addresses.
* This function invalidates all cache lines between two physical addresses.
*
* @param address The start address of the memory to be invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans the level 2 cache controller.
* This function cleans all entries in the level 2 cache controller.
*
*/
void L2CACHE_Clean(void);
/*!
* @brief Cleans the Level 2 cache lines in the range of two physical addresses.
* This function cleans all cache lines between two physical addresses.
*
* @param address The start address of the memory to be cleaned.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans and invalidates the level 2 cache controller.
* This function cleans and invalidates all entries in the level 2 cache controller.
*
*/
void L2CACHE_CleanInvalidate(void);
/*!
* @brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
* This function cleans and invalidates all cache lines between two physical addresses.
*
* @param address The start address of the memory to be cleaned and invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Enables or disables to lock down the data and instruction by way.
* This function locks down the cached instruction/data by way and prevent the adresses from
* being allocated and prevent dara from being evicted out of the level 2 cache.
* But the normal cache maintenance operations that invalidate, clean or clean
* and validate cache contents affect the locked-down cache lines as normal.
*
* @param masterId The master id, range from 0 ~ 7.
* @param mask The ways to be enabled or disabled to lockdown.
* each bit in value is related to each way of the cache. for example:
* value: bit 0 ------ way 0.
* value: bit 1 ------ way 1.
* --------------------------
* value: bit 15 ------ way 15.
* Note: please make sure the value setting is align with your supported ways.
* @param enable True enable the lockdown, false to disable the lockdown.
*/
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable);
/*@}*/
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
/*!
* @name Unified Cache Control for all caches (cortex-m7 L1 cache + l2 pl310)
* Mainly used for many drivers for easy cache operation.
*@{
*/
/*!
* @brief Invalidates all instruction caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be invalidated.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Invalidates all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be invalidated.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be cleaned.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans and Invalidates all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be cleaned and invalidated.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_CACHE_H_*/

View File

@ -7,7 +7,7 @@
*/
#include "fsl_dcp.h"
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && (DCP_USE_DCACHE == 1U)
#include "fsl_cache.h"
#endif
@ -1150,7 +1150,9 @@ static void dcp_hash_save_running_hash(dcp_hash_ctx_internal_t *ctxInternal)
}
if (srcAddr != NULL)
{
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
DCACHE_InvalidateByRange((uint32_t)srcAddr, sizeof(ctxInternal->runningHash));
#endif
(void)dcp_memcpy(ctxInternal->runningHash, srcAddr, sizeof(ctxInternal->runningHash));
}
}

433
nxp/drivers/fsl_flexio.c Normal file
View File

@ -0,0 +1,433 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.flexio"
#endif
/*< @brief user configurable flexio handle count. */
#define FLEXIO_HANDLE_COUNT 2
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to flexio bases for each instance. */
FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to flexio clocks for each instance. */
const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*< @brief pointer to array of FLEXIO handle. */
static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
/*< @brief pointer to array of FLEXIO IP types. */
static void *s_flexioType[FLEXIO_HANDLE_COUNT];
/*< @brief pointer to array of FLEXIO Isr. */
static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
/* FlexIO common IRQ Handler. */
static void FLEXIO_CommonIRQHandler(void);
/*******************************************************************************
* Codes
******************************************************************************/
/*!
* brief Get instance number for FLEXIO module.
*
* param base FLEXIO peripheral base address.
*/
uint32_t FLEXIO_GetInstance(FLEXIO_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++)
{
if (s_flexioBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_flexioBases));
return instance;
}
/*!
* brief Configures the FlexIO with a FlexIO configuration. The configuration structure
* can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig().
*
* Example
code
flexio_config_t config = {
.enableFlexio = true,
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false
};
FLEXIO_Configure(base, &config);
endcode
*
* param base FlexIO peripheral base address
* param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
{
uint32_t ctrlReg = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
FLEXIO_Reset(base);
ctrlReg = base->CTRL;
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
if (!userConfig->enableInDoze)
{
ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
}
base->CTRL = ctrlReg;
}
/*!
* brief Gates the FlexIO clock. Call this API to stop the FlexIO clock.
*
* note After calling this API, call the FLEXO_Init to use the FlexIO module.
*
* param base FlexIO peripheral base address
*/
void FLEXIO_Deinit(FLEXIO_Type *base)
{
FLEXIO_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Gets the default configuration to configure the FlexIO module. The configuration
* can used directly to call the FLEXIO_Configure().
*
* Example:
code
flexio_config_t config;
FLEXIO_GetDefaultConfig(&config);
endcode
*
* param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
{
assert(userConfig != NULL);
/* Initializes the configure structure to zero. */
(void)memset(userConfig, 0, sizeof(*userConfig));
userConfig->enableFlexio = true;
userConfig->enableInDoze = false;
userConfig->enableInDebug = true;
userConfig->enableFastAccess = false;
}
/*!
* brief Resets the FlexIO module.
*
* param base FlexIO peripheral base address
*/
void FLEXIO_Reset(FLEXIO_Type *base)
{
/*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
base->CTRL = 0;
}
/*!
* brief Gets the shifter buffer address for the DMA transfer usage.
*
* param base FlexIO peripheral base address
* param type Shifter type of flexio_shifter_buffer_type_t
* param index Shifter index
* return Corresponding shifter buffer index
*/
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
{
assert(index < FLEXIO_SHIFTBUF_COUNT);
uint32_t address = 0;
switch (type)
{
case kFLEXIO_ShifterBuffer:
address = (uint32_t) & (base->SHIFTBUF[index]);
break;
case kFLEXIO_ShifterBufferBitSwapped:
address = (uint32_t) & (base->SHIFTBUFBIS[index]);
break;
case kFLEXIO_ShifterBufferByteSwapped:
address = (uint32_t) & (base->SHIFTBUFBYS[index]);
break;
case kFLEXIO_ShifterBufferBitByteSwapped:
address = (uint32_t) & (base->SHIFTBUFBBS[index]);
break;
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
case kFLEXIO_ShifterBufferNibbleByteSwapped:
address = (uint32_t) & (base->SHIFTBUFNBS[index]);
break;
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
case kFLEXIO_ShifterBufferHalfWordSwapped:
address = (uint32_t) & (base->SHIFTBUFHWS[index]);
break;
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
case kFLEXIO_ShifterBufferNibbleSwapped:
address = (uint32_t) & (base->SHIFTBUFNIS[index]);
break;
#endif
default:
address = (uint32_t) & (base->SHIFTBUF[index]);
break;
}
return address;
}
/*!
* brief Configures the shifter with the shifter configuration. The configuration structure
* covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper
* mode, select which timer controls the shifter to shift, whether to generate start bit/stop
* bit, and the polarity of start bit and stop bit.
*
* Example
code
flexio_shifter_config_t config = {
.timerSelect = 0,
.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinPolarity = kFLEXIO_PinActiveLow,
.shifterMode = kFLEXIO_ShifterModeTransmit,
.inputSource = kFLEXIO_ShifterInputFromPin,
.shifterStop = kFLEXIO_ShifterStopBitHigh,
.shifterStart = kFLEXIO_ShifterStartBitLow
};
FLEXIO_SetShifterConfig(base, &config);
endcode
*
* param base FlexIO peripheral base address
* param index Shifter index
* param shifterConfig Pointer to flexio_shifter_config_t structure
*/
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
{
base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
| FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
| FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
base->SHIFTCTL[index] =
FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
}
/*!
* brief Configures the timer with the timer configuration. The configuration structure
* covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper
* mode, select trigger source for timer and the timer pin output and the timing for timer.
*
* Example
code
flexio_timer_config_t config = {
.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0),
.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow,
.triggerSource = kFLEXIO_TimerTriggerSourceInternal,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinSelect = 0,
.pinPolarity = kFLEXIO_PinActiveHigh,
.timerMode = kFLEXIO_TimerModeDual8BitBaudBit,
.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset,
.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput,
.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput,
.timerDisable = kFLEXIO_TimerDisableOnTimerCompare,
.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh,
.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable,
.timerStart = kFLEXIO_TimerStartBitEnabled
};
FLEXIO_SetTimerConfig(base, &config);
endcode
*
* param base FlexIO peripheral base address
* param index Timer index
* param timerConfig Pointer to the flexio_timer_config_t structure
*/
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
{
base->TIMCFG[index] =
FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
}
/*!
* brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* param base Pointer to the FlexIO simulated peripheral type.
* param handle Pointer to the handler for FlexIO simulated peripheral.
* param isr FlexIO simulated peripheral interrupt handler.
* retval kStatus_Success Successfully create the handle.
* retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
{
assert(base != NULL);
assert(handle != NULL);
assert(isr != NULL);
uint8_t index;
/* Find the an empty handle pointer to store the handle. */
for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioHandle[index] == NULL)
{
/* Register FLEXIO simulated driver base, handle and isr. */
s_flexioType[index] = base;
s_flexioHandle[index] = handle;
s_flexioIsr[index] = isr;
break;
}
}
if (index == (uint8_t)FLEXIO_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
else
{
return kStatus_Success;
}
}
/*!
* brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* param base Pointer to the FlexIO simulated peripheral type.
* retval kStatus_Success Successfully create the handle.
* retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_UnregisterHandleIRQ(void *base)
{
assert(base != NULL);
uint8_t index;
/* Find the index from base address mappings. */
for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioType[index] == base)
{
/* Unregister FLEXIO simulated driver handle and isr. */
s_flexioType[index] = NULL;
s_flexioHandle[index] = NULL;
s_flexioIsr[index] = NULL;
break;
}
}
if (index == (uint8_t)FLEXIO_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
else
{
return kStatus_Success;
}
}
static void FLEXIO_CommonIRQHandler(void)
{
uint8_t index;
for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioHandle[index] != NULL)
{
s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
}
}
SDK_ISR_EXIT_BARRIER;
}
void FLEXIO_DriverIRQHandler(void);
void FLEXIO_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO0_DriverIRQHandler(void);
void FLEXIO0_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO1_DriverIRQHandler(void);
void FLEXIO1_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void UART2_FLEXIO_DriverIRQHandler(void);
void UART2_FLEXIO_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO2_DriverIRQHandler(void);
void FLEXIO2_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO3_DriverIRQHandler(void);
void FLEXIO3_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}

735
nxp/drivers/fsl_flexio.h Normal file
View File

@ -0,0 +1,735 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020, 2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_FLEXIO_H_
#define _FSL_FLEXIO_H_
#include "fsl_common.h"
/*!
* @addtogroup flexio_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO driver version. */
#define FSL_FLEXIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/*! @brief Calculate FlexIO timer trigger.*/
#define FLEXIO_TIMER_TRIGGER_SEL_PININPUT(x) ((uint32_t)(x) << 1U)
#define FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(x) (((uint32_t)(x) << 2U) | 0x1U)
#define FLEXIO_TIMER_TRIGGER_SEL_TIMn(x) (((uint32_t)(x) << 2U) | 0x3U)
/*! @brief Define time of timer trigger polarity.*/
typedef enum _flexio_timer_trigger_polarity
{
kFLEXIO_TimerTriggerPolarityActiveHigh = 0x0U, /*!< Active high. */
kFLEXIO_TimerTriggerPolarityActiveLow = 0x1U, /*!< Active low. */
} flexio_timer_trigger_polarity_t;
/*! @brief Define type of timer trigger source.*/
typedef enum _flexio_timer_trigger_source
{
kFLEXIO_TimerTriggerSourceExternal = 0x0U, /*!< External trigger selected. */
kFLEXIO_TimerTriggerSourceInternal = 0x1U, /*!< Internal trigger selected. */
} flexio_timer_trigger_source_t;
/*! @brief Define type of timer/shifter pin configuration.*/
typedef enum _flexio_pin_config
{
kFLEXIO_PinConfigOutputDisabled = 0x0U, /*!< Pin output disabled. */
kFLEXIO_PinConfigOpenDrainOrBidirection = 0x1U, /*!< Pin open drain or bidirectional output enable. */
kFLEXIO_PinConfigBidirectionOutputData = 0x2U, /*!< Pin bidirectional output data. */
kFLEXIO_PinConfigOutput = 0x3U, /*!< Pin output. */
} flexio_pin_config_t;
/*! @brief Definition of pin polarity.*/
typedef enum _flexio_pin_polarity
{
kFLEXIO_PinActiveHigh = 0x0U, /*!< Active high. */
kFLEXIO_PinActiveLow = 0x1U, /*!< Active low. */
} flexio_pin_polarity_t;
/*! @brief Define type of timer work mode.*/
typedef enum _flexio_timer_mode
{
kFLEXIO_TimerModeDisabled = 0x0U, /*!< Timer Disabled. */
kFLEXIO_TimerModeDual8BitBaudBit = 0x1U, /*!< Dual 8-bit counters baud/bit mode. */
kFLEXIO_TimerModeDual8BitPWM = 0x2U, /*!< Dual 8-bit counters PWM mode. */
kFLEXIO_TimerModeSingle16Bit = 0x3U, /*!< Single 16-bit counter mode. */
} flexio_timer_mode_t;
/*! @brief Define type of timer initial output or timer reset condition.*/
typedef enum _flexio_timer_output
{
kFLEXIO_TimerOutputOneNotAffectedByReset = 0x0U, /*!< Logic one when enabled and is not affected by timer
reset. */
kFLEXIO_TimerOutputZeroNotAffectedByReset = 0x1U, /*!< Logic zero when enabled and is not affected by timer
reset. */
kFLEXIO_TimerOutputOneAffectedByReset = 0x2U, /*!< Logic one when enabled and on timer reset. */
kFLEXIO_TimerOutputZeroAffectedByReset = 0x3U, /*!< Logic zero when enabled and on timer reset. */
} flexio_timer_output_t;
/*! @brief Define type of timer decrement.*/
typedef enum _flexio_timer_decrement_source
{
kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput = 0x0U, /*!< Decrement counter on FlexIO clock, Shift clock
equals Timer output. */
kFLEXIO_TimerDecSrcOnTriggerInputShiftTimerOutput, /*!< Decrement counter on Trigger input (both edges),
Shift clock equals Timer output. */
kFLEXIO_TimerDecSrcOnPinInputShiftPinInput, /*!< Decrement counter on Pin input (both edges),
Shift clock equals Pin input. */
kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput /*!< Decrement counter on Trigger input (both edges),
Shift clock equals Trigger input. */
#if (defined(FSL_FEATURE_FLEXIO_TIMCFG_TIMDCE_FIELD_WIDTH) && (FSL_FEATURE_FLEXIO_TIMCFG_TIMDCE_FIELD_WIDTH == 3))
,
kFLEXIO_TimerDecSrcDiv16OnFlexIOClockShiftTimerOutput, /*!< Decrement counter on FlexIO clock divided by 16,
Shift clock equals Timer output. */
kFLEXIO_TimerDecSrcDiv256OnFlexIOClockShiftTimerOutput, /*!< Decrement counter on FlexIO clock divided by 256,
Shift clock equals Timer output. */
kFLEXIO_TimerRisSrcOnPinInputShiftPinInput, /*!< Decrement counter on Pin input (rising edges),
Shift clock equals Pin input. */
kFLEXIO_TimerRisSrcOnTriggerInputShiftTriggerInput /*!< Decrement counter on Trigger input (rising edges), Shift
clock equals Trigger input. */
#endif /* FSL_FEATURE_FLEXIO_TIMCFG_TIMDCE_FIELD_WIDTH */
} flexio_timer_decrement_source_t;
/*! @brief Define type of timer reset condition.*/
typedef enum _flexio_timer_reset_condition
{
kFLEXIO_TimerResetNever = 0x0U, /*!< Timer never reset. */
kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput = 0x2U, /*!< Timer reset on Timer Pin equal to Timer Output. */
kFLEXIO_TimerResetOnTimerTriggerEqualToTimerOutput = 0x3U, /*!< Timer reset on Timer Trigger equal to
Timer Output. */
kFLEXIO_TimerResetOnTimerPinRisingEdge = 0x4U, /*!< Timer reset on Timer Pin rising edge. */
kFLEXIO_TimerResetOnTimerTriggerRisingEdge = 0x6U, /*!< Timer reset on Trigger rising edge. */
kFLEXIO_TimerResetOnTimerTriggerBothEdge = 0x7U, /*!< Timer reset on Trigger rising or falling edge. */
} flexio_timer_reset_condition_t;
/*! @brief Define type of timer disable condition.*/
typedef enum _flexio_timer_disable_condition
{
kFLEXIO_TimerDisableNever = 0x0U, /*!< Timer never disabled. */
kFLEXIO_TimerDisableOnPreTimerDisable = 0x1U, /*!< Timer disabled on Timer N-1 disable. */
kFLEXIO_TimerDisableOnTimerCompare = 0x2U, /*!< Timer disabled on Timer compare. */
kFLEXIO_TimerDisableOnTimerCompareTriggerLow = 0x3U, /*!< Timer disabled on Timer compare and Trigger Low. */
kFLEXIO_TimerDisableOnPinBothEdge = 0x4U, /*!< Timer disabled on Pin rising or falling edge. */
kFLEXIO_TimerDisableOnPinBothEdgeTriggerHigh = 0x5U, /*!< Timer disabled on Pin rising or falling edge provided
Trigger is high. */
kFLEXIO_TimerDisableOnTriggerFallingEdge = 0x6U, /*!< Timer disabled on Trigger falling edge. */
} flexio_timer_disable_condition_t;
/*! @brief Define type of timer enable condition.*/
typedef enum _flexio_timer_enable_condition
{
kFLEXIO_TimerEnabledAlways = 0x0U, /*!< Timer always enabled. */
kFLEXIO_TimerEnableOnPrevTimerEnable = 0x1U, /*!< Timer enabled on Timer N-1 enable. */
kFLEXIO_TimerEnableOnTriggerHigh = 0x2U, /*!< Timer enabled on Trigger high. */
kFLEXIO_TimerEnableOnTriggerHighPinHigh = 0x3U, /*!< Timer enabled on Trigger high and Pin high. */
kFLEXIO_TimerEnableOnPinRisingEdge = 0x4U, /*!< Timer enabled on Pin rising edge. */
kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh = 0x5U, /*!< Timer enabled on Pin rising edge and Trigger high. */
kFLEXIO_TimerEnableOnTriggerRisingEdge = 0x6U, /*!< Timer enabled on Trigger rising edge. */
kFLEXIO_TimerEnableOnTriggerBothEdge = 0x7U, /*!< Timer enabled on Trigger rising or falling edge. */
} flexio_timer_enable_condition_t;
/*! @brief Define type of timer stop bit generate condition.*/
typedef enum _flexio_timer_stop_bit_condition
{
kFLEXIO_TimerStopBitDisabled = 0x0U, /*!< Stop bit disabled. */
kFLEXIO_TimerStopBitEnableOnTimerCompare = 0x1U, /*!< Stop bit is enabled on timer compare. */
kFLEXIO_TimerStopBitEnableOnTimerDisable = 0x2U, /*!< Stop bit is enabled on timer disable. */
kFLEXIO_TimerStopBitEnableOnTimerCompareDisable = 0x3U, /*!< Stop bit is enabled on timer compare and timer
disable. */
} flexio_timer_stop_bit_condition_t;
/*! @brief Define type of timer start bit generate condition.*/
typedef enum _flexio_timer_start_bit_condition
{
kFLEXIO_TimerStartBitDisabled = 0x0U, /*!< Start bit disabled. */
kFLEXIO_TimerStartBitEnabled = 0x1U, /*!< Start bit enabled. */
} flexio_timer_start_bit_condition_t;
/*! @brief FlexIO as PWM channel output state */
typedef enum _flexio_timer_output_state
{
kFLEXIO_PwmLow = 0, /*!< The output state of PWM channel is low */
kFLEXIO_PwmHigh, /*!< The output state of PWM channel is high */
} flexio_timer_output_state_t;
/*! @brief Define type of timer polarity for shifter control. */
typedef enum _flexio_shifter_timer_polarity
{
kFLEXIO_ShifterTimerPolarityOnPositive = 0x0U, /*!< Shift on positive edge of shift clock. */
kFLEXIO_ShifterTimerPolarityOnNegitive = 0x1U, /*!< Shift on negative edge of shift clock. */
} flexio_shifter_timer_polarity_t;
/*! @brief Define type of shifter working mode.*/
typedef enum _flexio_shifter_mode
{
kFLEXIO_ShifterDisabled = 0x0U, /*!< Shifter is disabled. */
kFLEXIO_ShifterModeReceive = 0x1U, /*!< Receive mode. */
kFLEXIO_ShifterModeTransmit = 0x2U, /*!< Transmit mode. */
kFLEXIO_ShifterModeMatchStore = 0x4U, /*!< Match store mode. */
kFLEXIO_ShifterModeMatchContinuous = 0x5U, /*!< Match continuous mode. */
#if FSL_FEATURE_FLEXIO_HAS_STATE_MODE
kFLEXIO_ShifterModeState = 0x6U, /*!< SHIFTBUF contents are used for storing
programmable state attributes. */
#endif /* FSL_FEATURE_FLEXIO_HAS_STATE_MODE */
#if FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE
kFLEXIO_ShifterModeLogic = 0x7U, /*!< SHIFTBUF contents are used for implementing
programmable logic look up table. */
#endif /* FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE */
} flexio_shifter_mode_t;
/*! @brief Define type of shifter input source.*/
typedef enum _flexio_shifter_input_source
{
kFLEXIO_ShifterInputFromPin = 0x0U, /*!< Shifter input from pin. */
kFLEXIO_ShifterInputFromNextShifterOutput = 0x1U, /*!< Shifter input from Shifter N+1. */
} flexio_shifter_input_source_t;
/*! @brief Define of STOP bit configuration.*/
typedef enum _flexio_shifter_stop_bit
{
kFLEXIO_ShifterStopBitDisable = 0x0U, /*!< Disable shifter stop bit. */
kFLEXIO_ShifterStopBitLow = 0x2U, /*!< Set shifter stop bit to logic low level. */
kFLEXIO_ShifterStopBitHigh = 0x3U, /*!< Set shifter stop bit to logic high level. */
} flexio_shifter_stop_bit_t;
/*! @brief Define type of START bit configuration.*/
typedef enum _flexio_shifter_start_bit
{
kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable = 0x0U, /*!< Disable shifter start bit, transmitter loads
data on enable. */
kFLEXIO_ShifterStartBitDisabledLoadDataOnShift = 0x1U, /*!< Disable shifter start bit, transmitter loads
data on first shift. */
kFLEXIO_ShifterStartBitLow = 0x2U, /*!< Set shifter start bit to logic low level. */
kFLEXIO_ShifterStartBitHigh = 0x3U, /*!< Set shifter start bit to logic high level. */
} flexio_shifter_start_bit_t;
/*! @brief Define FlexIO shifter buffer type*/
typedef enum _flexio_shifter_buffer_type
{
kFLEXIO_ShifterBuffer = 0x0U, /*!< Shifter Buffer N Register. */
kFLEXIO_ShifterBufferBitSwapped = 0x1U, /*!< Shifter Buffer N Bit Byte Swapped Register. */
kFLEXIO_ShifterBufferByteSwapped = 0x2U, /*!< Shifter Buffer N Byte Swapped Register. */
kFLEXIO_ShifterBufferBitByteSwapped = 0x3U, /*!< Shifter Buffer N Bit Swapped Register. */
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
kFLEXIO_ShifterBufferNibbleByteSwapped = 0x4U, /*!< Shifter Buffer N Nibble Byte Swapped Register. */
#endif /*FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP*/
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
kFLEXIO_ShifterBufferHalfWordSwapped = 0x5U, /*!< Shifter Buffer N Half Word Swapped Register. */
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
kFLEXIO_ShifterBufferNibbleSwapped = 0x6U, /*!< Shifter Buffer N Nibble Swapped Register. */
#endif
} flexio_shifter_buffer_type_t;
/*! @brief Define FlexIO user configuration structure. */
typedef struct _flexio_config_
{
bool enableFlexio; /*!< Enable/disable FlexIO module */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
the FlexIO clock to be at least twice the frequency of the bus clock. */
} flexio_config_t;
/*! @brief Define FlexIO timer configuration structure. */
typedef struct _flexio_timer_config
{
/* Trigger. */
uint32_t triggerSelect; /*!< The internal trigger selection number using MACROs. */
flexio_timer_trigger_polarity_t triggerPolarity; /*!< Trigger Polarity. */
flexio_timer_trigger_source_t triggerSource; /*!< Trigger Source, internal (see 'trgsel') or external. */
/* Pin. */
flexio_pin_config_t pinConfig; /*!< Timer Pin Configuration. */
uint32_t pinSelect; /*!< Timer Pin number Select. */
flexio_pin_polarity_t pinPolarity; /*!< Timer Pin Polarity. */
/* Timer. */
flexio_timer_mode_t timerMode; /*!< Timer work Mode. */
flexio_timer_output_t timerOutput; /*!< Configures the initial state of the Timer Output and
whether it is affected by the Timer reset. */
flexio_timer_decrement_source_t timerDecrement; /*!< Configures the source of the Timer decrement and the
source of the Shift clock. */
flexio_timer_reset_condition_t timerReset; /*!< Configures the condition that causes the timer counter
(and optionally the timer output) to be reset. */
flexio_timer_disable_condition_t timerDisable; /*!< Configures the condition that causes the Timer to be
disabled and stop decrementing. */
flexio_timer_enable_condition_t timerEnable; /*!< Configures the condition that causes the Timer to be
enabled and start decrementing. */
flexio_timer_stop_bit_condition_t timerStop; /*!< Timer STOP Bit generation. */
flexio_timer_start_bit_condition_t timerStart; /*!< Timer STRAT Bit generation. */
uint32_t timerCompare; /*!< Value for Timer Compare N Register. */
} flexio_timer_config_t;
/*! @brief Define FlexIO shifter configuration structure. */
typedef struct _flexio_shifter_config
{
/* Timer. */
uint32_t timerSelect; /*!< Selects which Timer is used for controlling the
logic/shift register and generating the Shift clock. */
flexio_shifter_timer_polarity_t timerPolarity; /*!< Timer Polarity. */
/* Pin. */
flexio_pin_config_t pinConfig; /*!< Shifter Pin Configuration. */
uint32_t pinSelect; /*!< Shifter Pin number Select. */
flexio_pin_polarity_t pinPolarity; /*!< Shifter Pin Polarity. */
/* Shifter. */
flexio_shifter_mode_t shifterMode; /*!< Configures the mode of the Shifter. */
#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
uint32_t parallelWidth; /*!< Configures the parallel width when using parallel mode.*/
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
flexio_shifter_input_source_t inputSource; /*!< Selects the input source for the shifter. */
flexio_shifter_stop_bit_t shifterStop; /*!< Shifter STOP bit. */
flexio_shifter_start_bit_t shifterStart; /*!< Shifter START bit. */
} flexio_shifter_config_t;
/*! @brief typedef for FlexIO simulated driver interrupt handler.*/
typedef void (*flexio_isr_t)(void *base, void *handle);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to flexio bases for each instance. */
extern FLEXIO_Type *const s_flexioBases[];
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to flexio clocks for each instance. */
extern const clock_ip_name_t s_flexioClocks[];
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name FlexIO Initialization and De-initialization
* @{
*/
/*!
* @brief Gets the default configuration to configure the FlexIO module. The configuration
* can used directly to call the FLEXIO_Configure().
*
* Example:
@code
flexio_config_t config;
FLEXIO_GetDefaultConfig(&config);
@endcode
*
* @param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig);
/*!
* @brief Configures the FlexIO with a FlexIO configuration. The configuration structure
* can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig().
*
* Example
@code
flexio_config_t config = {
.enableFlexio = true,
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false
};
FLEXIO_Configure(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig);
/*!
* @brief Gates the FlexIO clock. Call this API to stop the FlexIO clock.
*
* @note After calling this API, call the FLEXO_Init to use the FlexIO module.
*
* @param base FlexIO peripheral base address
*/
void FLEXIO_Deinit(FLEXIO_Type *base);
/*!
* @brief Get instance number for FLEXIO module.
*
* @param base FLEXIO peripheral base address.
*/
uint32_t FLEXIO_GetInstance(FLEXIO_Type *base);
/* @} */
/*!
* @name FlexIO Basic Operation
* @{
*/
/*!
* @brief Resets the FlexIO module.
*
* @param base FlexIO peripheral base address
*/
void FLEXIO_Reset(FLEXIO_Type *base);
/*!
* @brief Enables the FlexIO module operation.
*
* @param base FlexIO peripheral base address
* @param enable true to enable, false to disable.
*/
static inline void FLEXIO_Enable(FLEXIO_Type *base, bool enable)
{
if (enable)
{
base->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
/*!
* @brief Reads the input data on each of the FlexIO pins.
*
* @param base FlexIO peripheral base address
* @return FlexIO pin input data
*/
static inline uint32_t FLEXIO_ReadPinInput(FLEXIO_Type *base)
{
return base->PIN;
}
#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
#if defined(FSL_FEATURE_FLEXIO_HAS_STATE_MODE) && FSL_FEATURE_FLEXIO_HAS_STATE_MODE
/*!
* @brief Gets the current state pointer for state mode use.
*
* @param base FlexIO peripheral base address
* @return current State pointer
*/
static inline uint8_t FLEXIO_GetShifterState(FLEXIO_Type *base)
{
return ((uint8_t)(base->SHIFTSTATE) & FLEXIO_SHIFTSTATE_STATE_MASK);
}
#endif /*FSL_FEATURE_FLEXIO_HAS_STATE_MODE*/
/*!
* @brief Configures the shifter with the shifter configuration. The configuration structure
* covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper
* mode, select which timer controls the shifter to shift, whether to generate start bit/stop
* bit, and the polarity of start bit and stop bit.
*
* Example
@code
flexio_shifter_config_t config = {
.timerSelect = 0,
.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinPolarity = kFLEXIO_PinActiveLow,
.shifterMode = kFLEXIO_ShifterModeTransmit,
.inputSource = kFLEXIO_ShifterInputFromPin,
.shifterStop = kFLEXIO_ShifterStopBitHigh,
.shifterStart = kFLEXIO_ShifterStartBitLow
};
FLEXIO_SetShifterConfig(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param index Shifter index
* @param shifterConfig Pointer to flexio_shifter_config_t structure
*/
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig);
/*!
* @brief Configures the timer with the timer configuration. The configuration structure
* covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper
* mode, select trigger source for timer and the timer pin output and the timing for timer.
*
* Example
@code
flexio_timer_config_t config = {
.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0),
.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow,
.triggerSource = kFLEXIO_TimerTriggerSourceInternal,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinSelect = 0,
.pinPolarity = kFLEXIO_PinActiveHigh,
.timerMode = kFLEXIO_TimerModeDual8BitBaudBit,
.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset,
.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput,
.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput,
.timerDisable = kFLEXIO_TimerDisableOnTimerCompare,
.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh,
.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable,
.timerStart = kFLEXIO_TimerStartBitEnabled
};
FLEXIO_SetTimerConfig(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param index Timer index
* @param timerConfig Pointer to the flexio_timer_config_t structure
*/
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig);
/*!
* @brief This function set the value of the prescaler on flexio channels
*
* @param base Pointer to the FlexIO simulated peripheral type.
* @param clocksource Set clock value
*/
static inline void FLEXIO_SetClockMode(FLEXIO_Type *base, uint8_t index, flexio_timer_decrement_source_t clocksource)
{
uint32_t reg = base->TIMCFG[index];
reg &= ~FLEXIO_TIMCFG_TIMDEC_MASK;
reg |= FLEXIO_TIMCFG_TIMDEC(clocksource);
base->TIMCFG[index] = reg;
}
/* @} */
/*!
* @name FlexIO Interrupt Operation
* @{
*/
/*!
* @brief Enables the shifter status interrupt. The interrupt generates when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @note For multiple shifter status interrupt enable, for example, two shifter status enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_EnableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSIEN |= mask;
}
/*!
* @brief Disables the shifter status interrupt. The interrupt won't generate when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @note For multiple shifter status interrupt enable, for example, two shifter status enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_DisableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSIEN &= ~mask;
}
/*!
* @brief Enables the shifter error interrupt. The interrupt generates when the corresponding SEF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter error mask which can be calculated by (1 << shifter index)
* @note For multiple shifter error interrupt enable, for example, two shifter error enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_EnableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTEIEN |= mask;
}
/*!
* @brief Disables the shifter error interrupt. The interrupt won't generate when the corresponding SEF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter error mask which can be calculated by (1 << shifter index)
* @note For multiple shifter error interrupt enable, for example, two shifter error enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_DisableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTEIEN &= ~mask;
}
/*!
* @brief Enables the timer status interrupt. The interrupt generates when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The timer status mask which can be calculated by (1 << timer index)
* @note For multiple timer status interrupt enable, for example, two timer status enable, can calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_EnableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->TIMIEN |= mask;
}
/*!
* @brief Disables the timer status interrupt. The interrupt won't generate when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The timer status mask which can be calculated by (1 << timer index)
* @note For multiple timer status interrupt enable, for example, two timer status enable, can calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_DisableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->TIMIEN &= ~mask;
}
/* @} */
/*!
* @name FlexIO Status Operation
* @{
*/
/*!
* @brief Gets the shifter status flags.
*
* @param base FlexIO peripheral base address
* @return Shifter status flags
*/
static inline uint32_t FLEXIO_GetShifterStatusFlags(FLEXIO_Type *base)
{
return ((base->SHIFTSTAT) & FLEXIO_SHIFTSTAT_SSF_MASK);
}
/*!
* @brief Clears the shifter status flags.
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @note For clearing multiple shifter status flags, for example, two shifter status flags, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_ClearShifterStatusFlags(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSTAT = mask;
}
/*!
* @brief Gets the shifter error flags.
*
* @param base FlexIO peripheral base address
* @return Shifter error flags
*/
static inline uint32_t FLEXIO_GetShifterErrorFlags(FLEXIO_Type *base)
{
return ((base->SHIFTERR) & FLEXIO_SHIFTERR_SEF_MASK);
}
/*!
* @brief Clears the shifter error flags.
*
* @param base FlexIO peripheral base address
* @param mask The shifter error mask which can be calculated by (1 << shifter index)
* @note For clearing multiple shifter error flags, for example, two shifter error flags, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_ClearShifterErrorFlags(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTERR = mask;
}
/*!
* @brief Gets the timer status flags.
*
* @param base FlexIO peripheral base address
* @return Timer status flags
*/
static inline uint32_t FLEXIO_GetTimerStatusFlags(FLEXIO_Type *base)
{
return ((base->TIMSTAT) & FLEXIO_TIMSTAT_TSF_MASK);
}
/*!
* @brief Clears the timer status flags.
*
* @param base FlexIO peripheral base address
* @param mask The timer status mask which can be calculated by (1 << timer index)
* @note For clearing multiple timer status flags, for example, two timer status flags, can calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_ClearTimerStatusFlags(FLEXIO_Type *base, uint32_t mask)
{
base->TIMSTAT = mask;
}
/* @} */
/*!
* @name FlexIO DMA Operation
* @{
*/
/*!
* @brief Enables/disables the shifter status DMA. The DMA request generates when the corresponding SSF is set.
*
* @note For multiple shifter status DMA enables, for example, calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_EnableShifterStatusDMA(FLEXIO_Type *base, uint32_t mask, bool enable)
{
if (enable)
{
base->SHIFTSDEN |= mask;
}
else
{
base->SHIFTSDEN &= ~mask;
}
}
/*!
* @brief Gets the shifter buffer address for the DMA transfer usage.
*
* @param base FlexIO peripheral base address
* @param type Shifter type of flexio_shifter_buffer_type_t
* @param index Shifter index
* @return Corresponding shifter buffer index
*/
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index);
/*!
* @brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* @param base Pointer to the FlexIO simulated peripheral type.
* @param handle Pointer to the handler for FlexIO simulated peripheral.
* @param isr FlexIO simulated peripheral interrupt handler.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr);
/*!
* @brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* @param base Pointer to the FlexIO simulated peripheral type.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_UnregisterHandleIRQ(void *base);
/* @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_H_*/

127
nxp/drivers/fsl_gpt.c Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_gpt.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.gpt"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to GPT bases for each instance. */
static GPT_Type *const s_gptBases[] = GPT_BASE_PTRS;
/*! @brief Pointers to GPT clocks for each instance. */
static const clock_ip_name_t s_gptClocks[] = GPT_CLOCKS;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t GPT_GetInstance(GPT_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0U; instance < ARRAY_SIZE(s_gptBases); instance++)
{
if (s_gptBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_gptBases));
return instance;
}
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*!
* brief Initialize GPT to reset state and initialize running mode.
*
* param base GPT peripheral base address.
* param initConfig GPT mode setting configuration.
*/
void GPT_Init(GPT_Type *base, const gpt_config_t *initConfig)
{
assert(NULL != initConfig);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate the GPT clock*/
(void)CLOCK_EnableClock(s_gptClocks[GPT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
base->CR = 0U;
GPT_SoftwareReset(base);
base->CR =
(initConfig->enableFreeRun ? GPT_CR_FRR_MASK : 0UL) | (initConfig->enableRunInWait ? GPT_CR_WAITEN_MASK : 0UL) |
(initConfig->enableRunInStop ? GPT_CR_STOPEN_MASK : 0UL) |
(initConfig->enableRunInDoze ? GPT_CR_DOZEEN_MASK : 0UL) |
(initConfig->enableRunInDbg ? GPT_CR_DBGEN_MASK : 0UL) | (initConfig->enableMode ? GPT_CR_ENMOD_MASK : 0UL);
GPT_SetClockSource(base, initConfig->clockSource);
GPT_SetClockDivider(base, initConfig->divider);
}
/*!
* brief Disables the module and gates the GPT clock.
*
* param base GPT peripheral base address.
*/
void GPT_Deinit(GPT_Type *base)
{
/* Disable GPT timers */
base->CR = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the GPT clock*/
(void)CLOCK_DisableClock(s_gptClocks[GPT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Fills in the GPT configuration structure with default settings.
*
* The default values are:
* code
* config->clockSource = kGPT_ClockSource_Periph;
* config->divider = 1U;
* config->enableRunInStop = true;
* config->enableRunInWait = true;
* config->enableRunInDoze = false;
* config->enableRunInDbg = false;
* config->enableFreeRun = false;
* config->enableMode = true;
* endcode
* param config Pointer to the user configuration structure.
*/
void GPT_GetDefaultConfig(gpt_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->clockSource = kGPT_ClockSource_Periph;
config->divider = 1U;
config->enableRunInStop = true;
config->enableRunInWait = true;
config->enableRunInDoze = false;
config->enableRunInDbg = false;
config->enableFreeRun = false;
config->enableMode = true;
}

509
nxp/drivers/fsl_gpt.h Normal file
View File

@ -0,0 +1,509 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_GPT_H_
#define _FSL_GPT_H_
#include "fsl_common.h"
/*!
* @addtogroup gpt
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_GPT_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
/*!
* @brief List of clock sources
* @note Actual number of clock sources is SoC dependent
*/
typedef enum _gpt_clock_source
{
kGPT_ClockSource_Off = 0U, /*!< GPT Clock Source Off.*/
kGPT_ClockSource_Periph = 1U, /*!< GPT Clock Source from Peripheral Clock.*/
kGPT_ClockSource_HighFreq = 2U, /*!< GPT Clock Source from High Frequency Reference Clock.*/
kGPT_ClockSource_Ext = 3U, /*!< GPT Clock Source from external pin.*/
kGPT_ClockSource_LowFreq = 4U, /*!< GPT Clock Source from Low Frequency Reference Clock.*/
kGPT_ClockSource_Osc = 5U, /*!< GPT Clock Source from Crystal oscillator.*/
} gpt_clock_source_t;
/*! @brief List of input capture channel number. */
typedef enum _gpt_input_capture_channel
{
kGPT_InputCapture_Channel1 = 0U, /*!< GPT Input Capture Channel1.*/
kGPT_InputCapture_Channel2 = 1U, /*!< GPT Input Capture Channel2.*/
} gpt_input_capture_channel_t;
/*! @brief List of input capture operation mode. */
typedef enum _gpt_input_operation_mode
{
kGPT_InputOperation_Disabled = 0U, /*!< Don't capture.*/
kGPT_InputOperation_RiseEdge = 1U, /*!< Capture on rising edge of input pin.*/
kGPT_InputOperation_FallEdge = 2U, /*!< Capture on falling edge of input pin.*/
kGPT_InputOperation_BothEdge = 3U, /*!< Capture on both edges of input pin.*/
} gpt_input_operation_mode_t;
/*! @brief List of output compare channel number. */
typedef enum _gpt_output_compare_channel
{
kGPT_OutputCompare_Channel1 = 0U, /*!< Output Compare Channel1.*/
kGPT_OutputCompare_Channel2 = 1U, /*!< Output Compare Channel2.*/
kGPT_OutputCompare_Channel3 = 2U, /*!< Output Compare Channel3.*/
} gpt_output_compare_channel_t;
/*! @brief List of output compare operation mode. */
typedef enum _gpt_output_operation_mode
{
kGPT_OutputOperation_Disconnected = 0U, /*!< Don't change output pin.*/
kGPT_OutputOperation_Toggle = 1U, /*!< Toggle output pin.*/
kGPT_OutputOperation_Clear = 2U, /*!< Set output pin low.*/
kGPT_OutputOperation_Set = 3U, /*!< Set output pin high.*/
kGPT_OutputOperation_Activelow = 4U, /*!< Generate a active low pulse on output pin.*/
} gpt_output_operation_mode_t;
/*! @brief List of GPT interrupts */
typedef enum _gpt_interrupt_enable
{
kGPT_OutputCompare1InterruptEnable = GPT_IR_OF1IE_MASK, /*!< Output Compare Channel1 interrupt enable*/
kGPT_OutputCompare2InterruptEnable = GPT_IR_OF2IE_MASK, /*!< Output Compare Channel2 interrupt enable*/
kGPT_OutputCompare3InterruptEnable = GPT_IR_OF3IE_MASK, /*!< Output Compare Channel3 interrupt enable*/
kGPT_InputCapture1InterruptEnable = GPT_IR_IF1IE_MASK, /*!< Input Capture Channel1 interrupt enable*/
kGPT_InputCapture2InterruptEnable = GPT_IR_IF2IE_MASK, /*!< Input Capture Channel1 interrupt enable*/
kGPT_RollOverFlagInterruptEnable = GPT_IR_ROVIE_MASK, /*!< Counter rolled over interrupt enable*/
} gpt_interrupt_enable_t;
/*! @brief Status flag. */
typedef enum _gpt_status_flag
{
kGPT_OutputCompare1Flag = GPT_SR_OF1_MASK, /*!< Output compare channel 1 event.*/
kGPT_OutputCompare2Flag = GPT_SR_OF2_MASK, /*!< Output compare channel 2 event.*/
kGPT_OutputCompare3Flag = GPT_SR_OF3_MASK, /*!< Output compare channel 3 event.*/
kGPT_InputCapture1Flag = GPT_SR_IF1_MASK, /*!< Input Capture channel 1 event.*/
kGPT_InputCapture2Flag = GPT_SR_IF2_MASK, /*!< Input Capture channel 2 event.*/
kGPT_RollOverFlag = GPT_SR_ROV_MASK, /*!< Counter reaches maximum value and rolled over to 0 event.*/
} gpt_status_flag_t;
/*! @brief Structure to configure the running mode. */
typedef struct _gpt_init_config
{
gpt_clock_source_t clockSource; /*!< clock source for GPT module. */
uint32_t divider; /*!< clock divider (prescaler+1) from clock source to counter. */
bool enableFreeRun; /*!< true: FreeRun mode, false: Restart mode. */
bool enableRunInWait; /*!< GPT enabled in wait mode. */
bool enableRunInStop; /*!< GPT enabled in stop mode. */
bool enableRunInDoze; /*!< GPT enabled in doze mode. */
bool enableRunInDbg; /*!< GPT enabled in debug mode. */
bool enableMode; /*!< true: counter reset to 0 when enabled;
false: counter retain its value when enabled. */
} gpt_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initialize GPT to reset state and initialize running mode.
*
* @param base GPT peripheral base address.
* @param initConfig GPT mode setting configuration.
*/
void GPT_Init(GPT_Type *base, const gpt_config_t *initConfig);
/*!
* @brief Disables the module and gates the GPT clock.
*
* @param base GPT peripheral base address.
*/
void GPT_Deinit(GPT_Type *base);
/*!
* @brief Fills in the GPT configuration structure with default settings.
*
* The default values are:
* @code
* config->clockSource = kGPT_ClockSource_Periph;
* config->divider = 1U;
* config->enableRunInStop = true;
* config->enableRunInWait = true;
* config->enableRunInDoze = false;
* config->enableRunInDbg = false;
* config->enableFreeRun = false;
* config->enableMode = true;
* @endcode
* @param config Pointer to the user configuration structure.
*/
void GPT_GetDefaultConfig(gpt_config_t *config);
/*!
* @name Software Reset
* @{
*/
/*!
* @brief Software reset of GPT module.
*
* @param base GPT peripheral base address.
*/
static inline void GPT_SoftwareReset(GPT_Type *base)
{
base->CR |= GPT_CR_SWR_MASK;
/* Wait reset finished. */
while ((base->CR & GPT_CR_SWR_MASK) == GPT_CR_SWR_MASK)
{
}
}
/*!
* @name Clock source and frequency control
* @{
*/
/*!
* @brief Set clock source of GPT.
*
* @param base GPT peripheral base address.
* @param gptClkSource Clock source (see @ref gpt_clock_source_t typedef enumeration).
*/
static inline void GPT_SetClockSource(GPT_Type *base, gpt_clock_source_t gptClkSource)
{
if (gptClkSource == kGPT_ClockSource_Osc)
{
base->CR = (base->CR & ~GPT_CR_CLKSRC_MASK) | GPT_CR_EN_24M_MASK | GPT_CR_CLKSRC(gptClkSource);
}
else
{
base->CR = (base->CR & ~(GPT_CR_CLKSRC_MASK | GPT_CR_EN_24M_MASK)) | GPT_CR_CLKSRC(gptClkSource);
}
}
/*!
* @brief Get clock source of GPT.
*
* @param base GPT peripheral base address.
* @return clock source (see @ref gpt_clock_source_t typedef enumeration).
*/
static inline gpt_clock_source_t GPT_GetClockSource(GPT_Type *base)
{
return (gpt_clock_source_t)(uint8_t)((base->CR & GPT_CR_CLKSRC_MASK) >> GPT_CR_CLKSRC_SHIFT);
}
/*!
* @brief Set pre scaler of GPT.
*
* @param base GPT peripheral base address.
* @param divider Divider of GPT (1-4096).
*/
static inline void GPT_SetClockDivider(GPT_Type *base, uint32_t divider)
{
assert(divider - 1U <= GPT_PR_PRESCALER_MASK);
base->PR = (base->PR & ~GPT_PR_PRESCALER_MASK) | GPT_PR_PRESCALER(divider - 1U);
}
/*!
* @brief Get clock divider in GPT module.
*
* @param base GPT peripheral base address.
* @return clock divider in GPT module (1-4096).
*/
static inline uint32_t GPT_GetClockDivider(GPT_Type *base)
{
return ((base->PR & GPT_PR_PRESCALER_MASK) >> GPT_PR_PRESCALER_SHIFT) + 1U;
}
/*!
* @brief OSC 24M pre-scaler before selected by clock source.
*
* @param base GPT peripheral base address.
* @param divider OSC Divider(1-16).
*/
static inline void GPT_SetOscClockDivider(GPT_Type *base, uint32_t divider)
{
assert(divider - 1U <= (GPT_PR_PRESCALER24M_MASK >> GPT_PR_PRESCALER24M_SHIFT));
base->PR = (base->PR & ~GPT_PR_PRESCALER24M_MASK) | GPT_PR_PRESCALER24M(divider - 1U);
}
/*!
* @brief Get OSC 24M clock divider in GPT module.
*
* @param base GPT peripheral base address.
* @return OSC clock divider in GPT module (1-16).
*/
static inline uint32_t GPT_GetOscClockDivider(GPT_Type *base)
{
return ((base->PR & GPT_PR_PRESCALER24M_MASK) >> GPT_PR_PRESCALER24M_SHIFT) + 1U;
}
/*! @}*/
/*!
* @name Timer Start and Stop
* @{
*/
/*!
* @brief Start GPT timer.
*
* @param base GPT peripheral base address.
*/
static inline void GPT_StartTimer(GPT_Type *base)
{
base->CR |= GPT_CR_EN_MASK;
}
/*!
* @brief Stop GPT timer.
*
* @param base GPT peripheral base address.
*/
static inline void GPT_StopTimer(GPT_Type *base)
{
base->CR &= ~GPT_CR_EN_MASK;
}
/*!
* @name Read the timer period
* @{
*/
/*!
* @brief Reads the current GPT counting value.
*
* @param base GPT peripheral base address.
* @return Current GPT counter value.
*/
static inline uint32_t GPT_GetCurrentTimerCount(GPT_Type *base)
{
return base->CNT;
}
/*@}*/
/*!
* @name GPT Input/Output Signal Control
* @{
*/
/*!
* @brief Set GPT operation mode of input capture channel.
*
* @param base GPT peripheral base address.
* @param channel GPT capture channel (see @ref gpt_input_capture_channel_t typedef enumeration).
* @param mode GPT input capture operation mode (see @ref gpt_input_operation_mode_t typedef enumeration).
*/
static inline void GPT_SetInputOperationMode(GPT_Type *base,
gpt_input_capture_channel_t channel,
gpt_input_operation_mode_t mode)
{
assert(channel <= kGPT_InputCapture_Channel2);
base->CR =
(base->CR & ~(GPT_CR_IM1_MASK << ((uint32_t)channel * 2UL))) | (GPT_CR_IM1(mode) << ((uint32_t)channel * 2UL));
}
/*!
* @brief Get GPT operation mode of input capture channel.
*
* @param base GPT peripheral base address.
* @param channel GPT capture channel (see @ref gpt_input_capture_channel_t typedef enumeration).
* @return GPT input capture operation mode (see @ref gpt_input_operation_mode_t typedef enumeration).
*/
static inline gpt_input_operation_mode_t GPT_GetInputOperationMode(GPT_Type *base, gpt_input_capture_channel_t channel)
{
assert(channel <= kGPT_InputCapture_Channel2);
return (gpt_input_operation_mode_t)(uint8_t)((base->CR >> (GPT_CR_IM1_SHIFT + (uint32_t)channel * 2UL)) &
(GPT_CR_IM1_MASK >> GPT_CR_IM1_SHIFT));
}
/*!
* @brief Get GPT input capture value of certain channel.
*
* @param base GPT peripheral base address.
* @param channel GPT capture channel (see @ref gpt_input_capture_channel_t typedef enumeration).
* @return GPT input capture value.
*/
static inline uint32_t GPT_GetInputCaptureValue(GPT_Type *base, gpt_input_capture_channel_t channel)
{
assert(channel <= kGPT_InputCapture_Channel2);
return base->ICR[(uint32_t)channel];
}
/*!
* @brief Set GPT operation mode of output compare channel.
*
* @param base GPT peripheral base address.
* @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration).
* @param mode GPT output operation mode (see @ref gpt_output_operation_mode_t typedef enumeration).
*/
static inline void GPT_SetOutputOperationMode(GPT_Type *base,
gpt_output_compare_channel_t channel,
gpt_output_operation_mode_t mode)
{
assert(channel <= kGPT_OutputCompare_Channel3);
base->CR =
(base->CR & ~(GPT_CR_OM1_MASK << ((uint32_t)channel * 3UL))) | (GPT_CR_OM1(mode) << ((uint32_t)channel * 3UL));
}
/*!
* @brief Get GPT operation mode of output compare channel.
*
* @param base GPT peripheral base address.
* @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration).
* @return GPT output operation mode (see @ref gpt_output_operation_mode_t typedef enumeration).
*/
static inline gpt_output_operation_mode_t GPT_GetOutputOperationMode(GPT_Type *base,
gpt_output_compare_channel_t channel)
{
assert(channel <= kGPT_OutputCompare_Channel3);
return (gpt_output_operation_mode_t)(uint8_t)((base->CR >> (GPT_CR_OM1_SHIFT + (uint32_t)channel * 3UL)) &
(GPT_CR_OM1_MASK >> GPT_CR_OM1_SHIFT));
}
/*!
* @brief Set GPT output compare value of output compare channel.
*
* @param base GPT peripheral base address.
* @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration).
* @param value GPT output compare value.
*/
static inline void GPT_SetOutputCompareValue(GPT_Type *base, gpt_output_compare_channel_t channel, uint32_t value)
{
assert(channel <= kGPT_OutputCompare_Channel3);
base->OCR[(uint32_t)channel] = value;
}
/*!
* @brief Get GPT output compare value of output compare channel.
*
* @param base GPT peripheral base address.
* @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration).
* @return GPT output compare value.
*/
static inline uint32_t GPT_GetOutputCompareValue(GPT_Type *base, gpt_output_compare_channel_t channel)
{
assert(channel <= kGPT_OutputCompare_Channel3);
return base->OCR[(uint32_t)channel];
}
/*!
* @brief Force GPT output action on output compare channel, ignoring comparator.
*
* @param base GPT peripheral base address.
* @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration).
*/
static inline void GPT_ForceOutput(GPT_Type *base, gpt_output_compare_channel_t channel)
{
assert(channel <= kGPT_OutputCompare_Channel3);
base->CR |= (GPT_CR_FO1_MASK << (uint32_t)channel);
}
/*@}*/
/*!
* @name GPT Interrupt and Status Interface
* @{
*/
/*!
* @brief Enables the selected GPT interrupts.
*
* @param base GPT peripheral base address.
* @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::gpt_interrupt_enable_t
*/
static inline void GPT_EnableInterrupts(GPT_Type *base, uint32_t mask)
{
base->IR |= mask;
}
/*!
* @brief Disables the selected GPT interrupts.
*
* @param base GPT peripheral base address
* @param mask The interrupts to disable. This is a logical OR of members of the
* enumeration ::gpt_interrupt_enable_t
*/
static inline void GPT_DisableInterrupts(GPT_Type *base, uint32_t mask)
{
base->IR &= ~mask;
}
/*!
* @brief Gets the enabled GPT interrupts.
*
* @param base GPT peripheral base address
*
* @return The enabled interrupts. This is the logical OR of members of the
* enumeration ::gpt_interrupt_enable_t
*/
static inline uint32_t GPT_GetEnabledInterrupts(GPT_Type *base)
{
return (base->IR & (GPT_IR_OF1IE_MASK | GPT_IR_OF2IE_MASK | GPT_IR_OF3IE_MASK | GPT_IR_IF1IE_MASK |
GPT_IR_IF2IE_MASK | GPT_IR_ROVIE_MASK));
}
/*!
* @name Status Interface
* @{
*/
/*!
* @brief Get GPT status flags.
*
* @param base GPT peripheral base address.
* @param flags GPT status flag mask (see @ref gpt_status_flag_t for bit definition).
* @return GPT status, each bit represents one status flag.
*/
static inline uint32_t GPT_GetStatusFlags(GPT_Type *base, gpt_status_flag_t flags)
{
return base->SR & (uint32_t)flags;
}
/*!
* @brief Clears the GPT status flags.
*
* @param base GPT peripheral base address.
* @param flags GPT status flag mask (see @ref gpt_status_flag_t for bit definition).
*/
static inline void GPT_ClearStatusFlags(GPT_Type *base, gpt_status_flag_t flags)
{
base->SR = (uint32_t)flags;
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_GPT_H_ */