Bsp nxp support (#8530)

Co-authored-by: StackYuan <yuanjyjyj@outlook.com>
This commit is contained in:
杨熙 2024-02-16 00:30:50 +08:00 committed by GitHub
parent 35eea4bc46
commit 41e08084f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
132 changed files with 108661 additions and 25 deletions

8
bsp/nxp/README.md Normal file
View File

@ -0,0 +1,8 @@
# NXP BSP 说明
存放RT-Thread NXP BSP目录目前支持MCX系列之前一些老的IC支持(如LPC/Kinetis/I.MXRT)会逐步放到此目录下
| BSP 文件夹名称 | 开发板名称 |
|:------------------------- |:-------------------------- |
| mcxn | frdm-mcxn947 |
| mcxa | frdm-mcxa153 |

View File

@ -0,0 +1,4 @@
# files format check exclude path, please follow the instructions below to modify;
dir_path:
- MCXA153

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.1.0
* @date 09. October 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.4
* @date 23. July 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 4U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,352 @@
/******************************************************************************
* @file mpu_armv8.h
* @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU
* @version V5.1.3
* @date 03. February 2021
******************************************************************************/
/*
* Copyright (c) 2017-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV8_H
#define ARM_MPU_ARMV8_H
/** \brief Attribute for device memory (outer only) */
#define ARM_MPU_ATTR_DEVICE ( 0U )
/** \brief Attribute for non-cacheable, normal memory */
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
/** \brief Attribute for normal memory (outer and inner)
* \param NT Non-Transient: Set to 1 for non-transient data.
* \param WB Write-Back: Set to 1 to use write-back update policy.
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
*/
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U))
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
/** \brief Memory Attribute
* \param O Outer memory attributes
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
*/
#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U)))
/** \brief Normal memory non-shareable */
#define ARM_MPU_SH_NON (0U)
/** \brief Normal memory outer shareable */
#define ARM_MPU_SH_OUTER (2U)
/** \brief Normal memory inner shareable */
#define ARM_MPU_SH_INNER (3U)
/** \brief Memory access permissions
* \param RO Read-Only: Set to 1 for read-only memory.
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
*/
#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U))
/** \brief Region Base Address Register value
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
* \param SH Defines the Shareability domain for this memory region.
* \param RO Read-Only: Set to 1 for a read-only memory region.
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
*/
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
(((BASE) & MPU_RBAR_BASE_Msk) | \
(((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
(((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
/** \brief Region Limit Address Register value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR(LIMIT, IDX) \
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#if defined(MPU_RLAR_PXN_Pos)
/** \brief Region Limit Address Register with PXN value
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
* \param IDX The attribute index to be associated with this memory region.
*/
#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
(((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
(MPU_RLAR_EN_Msk))
#endif
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; /*!< Region Base Address Register value */
uint32_t RLAR; /*!< Region Limit Address Register value */
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DMB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
#ifdef MPU_NS
/** Enable the Non-secure MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
{
__DMB();
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the Non-secure MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
__DSB();
__ISB();
}
#endif
/** Set the memory attribute encoding to the given MPU.
* \param mpu Pointer to the MPU to be configured.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
{
const uint8_t reg = idx / 4U;
const uint32_t pos = ((idx % 4U) * 8U);
const uint32_t mask = 0xFFU << pos;
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
return; // invalid index
}
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
}
/** Set the memory attribute encoding.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
}
#ifdef MPU_NS
/** Set the memory attribute encoding to the Non-secure MPU.
* \param idx The attribute index to be set [0-7]
* \param attr The attribute value to be set.
*/
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
{
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
}
#endif
/** Clear and disable the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
{
mpu->RNR = rnr;
mpu->RLAR = 0U;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU, rnr);
}
#ifdef MPU_NS
/** Clear and disable the given Non-secure MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
{
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
}
#endif
/** Configure the given MPU region of the given MPU.
* \param mpu Pointer to MPU to be used.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
mpu->RNR = rnr;
mpu->RBAR = rbar;
mpu->RLAR = rlar;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
}
#ifdef MPU_NS
/** Configure the given Non-secure MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rlar Value for RLAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
{
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
}
#endif
/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_LoadEx()
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table to the given MPU.
* \param mpu Pointer to the MPU registers to be used.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
if (cnt == 1U) {
mpu->RNR = rnr;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
} else {
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
table += c;
cnt -= c;
rnrOffset = 0U;
rnrBase += MPU_TYPE_RALIASES;
mpu->RNR = rnrBase;
}
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
}
}
/** Load the given number of MPU regions from a table.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
}
#ifdef MPU_NS
/** Load the given number of MPU regions from a table to the Non-secure MPU.
* \param rnr First region number to be configured.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
{
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
}
#endif
#endif

View File

@ -0,0 +1,70 @@
/******************************************************************************
* @file tz_context.h
* @brief Context Management for Armv8-M TrustZone
* @version V1.0.1
* @date 10. January 2018
******************************************************************************/
/*
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef TZ_CONTEXT_H
#define TZ_CONTEXT_H
#include <stdint.h>
#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif
/// \details TZ Memory ID identifies an allocated memory slot.
typedef uint32_t TZ_MemoryId_t;
/// Initialize secure context memory system
/// \return execution status (1: success, 0: error)
uint32_t TZ_InitContextSystem_S (void);
/// Allocate context memory for calling secure software modules in TrustZone
/// \param[in] module identifies software modules called from non-secure mode
/// \return value != 0 id TrustZone memory slot identifier
/// \return value 0 no memory available or internal error
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
/// Load secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
/// Store secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
#endif // TZ_CONTEXT_H

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,4 @@
config SOC_MCX
bool
select ARCH_ARM_CORTEX_M33
select ARCH_ARM_CORTEX_FPU

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,593 @@
/*
** ###################################################################
** Version: rev. 1.0, 2022-03-29
** Build: b231012
**
** Abstract:
** Chip specific module features.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2022-03-29)
** Initial version based on v0.1UM
**
** ###################################################################
*/
#ifndef _MCXA153_FEATURES_H_
#define _MCXA153_FEATURES_H_
/* SOC module features */
/* @brief AOI availability on the SoC. */
#define FSL_FEATURE_SOC_AOI_COUNT (1)
/* @brief CDOG availability on the SoC. */
#define FSL_FEATURE_SOC_CDOG_COUNT (1)
/* @brief CMC availability on the SoC. */
#define FSL_FEATURE_SOC_CMC_COUNT (1)
/* @brief CRC availability on the SoC. */
#define FSL_FEATURE_SOC_CRC_COUNT (1)
/* @brief CTIMER availability on the SoC. */
#define FSL_FEATURE_SOC_CTIMER_COUNT (3)
/* @brief EDMA availability on the SoC. */
#define FSL_FEATURE_SOC_EDMA_COUNT (1)
/* @brief EIM availability on the SoC. */
#define FSL_FEATURE_SOC_EIM_COUNT (1)
/* @brief EQDC availability on the SoC. */
#define FSL_FEATURE_SOC_EQDC_COUNT (1)
/* @brief FMC availability on the SoC. */
#define FSL_FEATURE_SOC_FMC_COUNT (1)
/* @brief FREQME availability on the SoC. */
#define FSL_FEATURE_SOC_FREQME_COUNT (1)
/* @brief GPIO availability on the SoC. */
#define FSL_FEATURE_SOC_GPIO_COUNT (4)
/* @brief SPC availability on the SoC. */
#define FSL_FEATURE_SOC_SPC_COUNT (1)
/* @brief I3C availability on the SoC. */
#define FSL_FEATURE_SOC_I3C_COUNT (1)
/* @brief INPUTMUX availability on the SoC. */
#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1)
/* @brief LPADC availability on the SoC. */
#define FSL_FEATURE_SOC_LPADC_COUNT (1)
/* @brief LPCMP availability on the SoC. */
#define FSL_FEATURE_SOC_LPCMP_COUNT (2)
/* @brief LPI2C availability on the SoC. */
#define FSL_FEATURE_SOC_LPI2C_COUNT (1)
/* @brief LPSPI availability on the SoC. */
#define FSL_FEATURE_SOC_LPSPI_COUNT (2)
/* @brief LPTMR availability on the SoC. */
#define FSL_FEATURE_SOC_LPTMR_COUNT (1)
/* @brief LPUART availability on the SoC. */
#define FSL_FEATURE_SOC_LPUART_COUNT (3)
/* @brief OSTIMER availability on the SoC. */
#define FSL_FEATURE_SOC_OSTIMER_COUNT (1)
/* @brief PORT availability on the SoC. */
#define FSL_FEATURE_SOC_PORT_COUNT (4)
/* @brief PWM availability on the SoC. */
#define FSL_FEATURE_SOC_PWM_COUNT (1)
/* @brief SCG availability on the SoC. */
#define FSL_FEATURE_SOC_SCG_COUNT (1)
/* @brief SYSCON availability on the SoC. */
#define FSL_FEATURE_SOC_SYSCON_COUNT (1)
/* @brief USB availability on the SoC. */
#define FSL_FEATURE_SOC_USB_COUNT (1)
/* @brief UTICK availability on the SoC. */
#define FSL_FEATURE_SOC_UTICK_COUNT (1)
/* @brief WAKETIMER availability on the SoC. */
#define FSL_FEATURE_SOC_WAKETIMER_COUNT (1)
/* @brief WWDT availability on the SoC. */
#define FSL_FEATURE_SOC_WWDT_COUNT (1)
/* @brief WUU availability on the SoC. */
#define FSL_FEATURE_SOC_WUU_COUNT (1)
/* LPADC module features */
/* @brief FIFO availability on the SoC. */
#define FSL_FEATURE_LPADC_FIFO_COUNT (1)
/* @brief Has subsequent trigger priority (bitfield CFG[TPRICTRL]). */
#define FSL_FEATURE_LPADC_HAS_CFG_SUBSEQUENT_PRIORITY (1)
/* @brief Has differential mode (bitfield CMDLn[DIFF]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_DIFF (0)
/* @brief Has channel scale (bitfield CMDLn[CSCALE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_CSCALE (0)
/* @brief Has conversion type select (bitfield CMDLn[CTYPE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_CTYPE (1)
/* @brief Has conversion resolution select (bitfield CMDLn[MODE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_MODE (1)
/* @brief Has compare function enable (bitfield CMDHn[CMPEN]). */
#define FSL_FEATURE_LPADC_HAS_CMDH_CMPEN (1)
/* @brief Has Wait for trigger assertion before execution (bitfield CMDHn[WAIT_TRIG]). */
#define FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG (1)
/* @brief Has offset calibration (bitfield CTRL[CALOFS]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CALOFS (1)
/* @brief Has gain calibration (bitfield CTRL[CAL_REQ]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ (1)
/* @brief Has calibration average (bitfield CTRL[CAL_AVGS]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS (1)
/* @brief Has internal clock (bitfield CFG[ADCKEN]). */
#define FSL_FEATURE_LPADC_HAS_CFG_ADCKEN (0)
/* @brief Enable support for low voltage reference on option 1 reference (bitfield CFG[VREF1RNG]). */
#define FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG (0)
/* @brief Has calibration (bitfield CFG[CALOFS]). */
#define FSL_FEATURE_LPADC_HAS_CFG_CALOFS (0)
/* @brief Has offset trim (register OFSTRIM). */
#define FSL_FEATURE_LPADC_HAS_OFSTRIM (1)
/* @brief OFSTRIM availability on the SoC. */
#define FSL_FEATURE_LPADC_OFSTRIM_COUNT (1)
/* @brief Has Trigger status register. */
#define FSL_FEATURE_LPADC_HAS_TSTAT (1)
/* @brief Has power select (bitfield CFG[PWRSEL]). */
#define FSL_FEATURE_LPADC_HAS_CFG_PWRSEL (1)
/* @brief Has alternate channel B scale (bitfield CMDLn[ALTB_CSCALE]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE (0)
/* @brief Has alternate channel B select enable (bitfield CMDLn[ALTBEN]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN (0)
/* @brief Has alternate channel input (bitfield CMDLn[ALTB_ADCH]). */
#define FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH (0)
/* @brief Has offset calibration mode (bitfield CTRL[CALOFSMODE]). */
#define FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE (0)
/* @brief Conversion averaged bitfiled width. */
#define FSL_FEATURE_LPADC_CONVERSIONS_AVERAGED_BITFIELD_WIDTH (4)
/* @brief Has B side channels. */
#define FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS (0)
/* @brief Indicate whether the LPADC STAT register has trigger exception interrupt function (bitfield STAT[TEXC_INT]). */
#define FSL_FEATURE_LPADC_HAS_STAT_TEXC_INT (1)
/* @brief Indicate whether the LPADC STAT register has trigger completion interrupt function (bitfield STAT[TCOMP_INT]). */
#define FSL_FEATURE_LPADC_HAS_STAT_TCOMP_INT (1)
/* @brief Indicate whether the LPADC STAT register has calibration ready function (bitfield STAT[CAL_RDY]). */
#define FSL_FEATURE_LPADC_HAS_STAT_CAL_RDY (1)
/* @brief Indicate whether the LPADC STAT register has ADC active function (bitfield STAT[ADC_ACTIVE]). */
#define FSL_FEATURE_LPADC_HAS_STAT_ADC_ACTIVE (1)
/* @brief Indicate whether the LPADC IE register has trigger exception interrupt enable function (bitfield IE[TEXC_IE]). */
#define FSL_FEATURE_LPADC_HAS_IE_TEXC_IE (1)
/* @brief Indicate whether the LPADC IE register has trigger completion interrupt enable function (bitfield IE[TCOMP_IE]). */
#define FSL_FEATURE_LPADC_HAS_IE_TCOMP_IE (1)
/* @brief Indicate whether the LPADC CFG register has trigger resume/restart enable function (bitfield CFG[TRES]). */
#define FSL_FEATURE_LPADC_HAS_CFG_TRES (1)
/* @brief Indicate whether the LPADC CFG register has trigger command resume/restart enable function (bitfield CFG[TCMDRES]). */
#define FSL_FEATURE_LPADC_HAS_CFG_TCMDRES (1)
/* @brief Indicate whether the LPADC CFG register has high priority trigger exception disable function (bitfield CFG[HPT_EXDI]). */
#define FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI (1)
/* @brief Indicate LPADC CFG register TPRICTRL bitfield width. */
#define FSL_FEATURE_LPADC_CFG_TPRICTRL_BITFIELD_WIDTH (2)
/* AOI module features */
/* @brief Maximum value of input mux. */
#define FSL_FEATURE_AOI_MODULE_INPUTS (4)
/* @brief Number of events related to number of registers AOIx_BFCRT01n/AOIx_BFCRT23n. */
#define FSL_FEATURE_AOI_EVENT_COUNT (4)
/* CDOG module features */
/* No feature definitions */
/* CMC module features */
/* @brief Has SRAM_DIS register */
#define FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG (0)
/* @brief Has BSR register */
#define FSL_FEATURE_MCX_CMC_HAS_BSR_REG (0)
/* @brief Has RSTCNT register */
#define FSL_FEATURE_MCX_CMC_HAS_RSTCNT_REG (1)
/* @brief Has BLR register */
#define FSL_FEATURE_MCX_CMC_HAS_BLR_REG (1)
/* LPCMP module features */
/* @brief Has CCR1 FUNC_CLK_SEL bitfield. */
#define FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL (1)
/* @brief Has IER RRF_IE bitfield. */
#define FSL_FEATURE_LPCMP_HAS_IER_RRF_IE (1)
/* @brief Has CSR RRF bitfield. */
#define FSL_FEATURE_LPCMP_HAS_CSR_RRF (1)
/* @brief Has Round Robin mode (related to existence of registers RRCR0). */
#define FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE (1)
/* @brief Has window mode (related to existence of CCR1.WINDOW_CLS). */
#define FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL (1)
/* CTIMER module features */
/* @brief CTIMER has no capture channel. */
#define FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE (0)
/* @brief CTIMER has no capture 2 interrupt. */
#define FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT (0)
/* @brief CTIMER capture 3 interrupt. */
#define FSL_FEATURE_CTIMER_HAS_IR_CR3INT (1)
/* @brief Has CTIMER CCR_CAP2 (register bits CCR[CAP2RE][CAP2FE][CAP2I]. */
#define FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 (0)
/* @brief Has CTIMER CCR_CAP3 (register bits CCR[CAP3RE][CAP3FE][CAP3I]). */
#define FSL_FEATURE_CTIMER_HAS_CCR_CAP3 (1)
/* @brief CTIMER Has register MSR */
#define FSL_FEATURE_CTIMER_HAS_MSR (1)
/* EDMA module features */
/* @brief Number of DMA channels (related to number of registers TCD, DCHPRI, bit fields ERQ[ERQn], EEI[EEIn], INT[INTn], ERR[ERRn], HRS[HRSn] and bit field widths ES[ERRCHN], CEEI[CEEI], SEEI[SEEI], CERQ[CERQ], SERQ[SERQ], CDNE[CDNE], SSRT[SSRT], CERR[CERR], CINT[CINT], TCDn_CITER_ELINKYES[LINKCH], TCDn_CSR[MAJORLINKCH], TCDn_BITER_ELINKYES[LINKCH]). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_MODULE_CHANNEL (4)
/* @brief If 8 bytes transfer supported. */
#define FSL_FEATURE_EDMA_SUPPORT_8_BYTES_TRANSFER (1)
/* @brief Number of DMA channel groups (register bit fields CR[ERGA], CR[GRPnPRI], ES[GPE], DCHPRIn[GRPPRI]). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT (1)
/* @brief If 16 bytes transfer supported. */
#define FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER (1)
/* @brief Has DMA_Error interrupt vector. */
#define FSL_FEATURE_EDMA_HAS_ERROR_IRQ (1)
/* @brief If 64 bytes transfer supported. */
#define FSL_FEATURE_EDMA_SUPPORT_64_BYTES_TRANSFER (1)
/* @brief If channel clock controlled independently */
#define FSL_FEATURE_EDMA_CHANNEL_HAS_OWN_CLOCK_GATE (1)
/* @brief If 128 bytes transfer supported. */
#define FSL_FEATURE_EDMA_SUPPORT_128_BYTES_TRANSFER (1)
/* @brief Number of channel for each EDMA instance, (only defined for soc with different channel numbers for difference instance) */
#define FSL_FEATURE_EDMA_INSTANCE_CHANNELn(x) (4)
/* @brief If 128 bytes transfer supported. */
#define FSL_FEATURE_EDMA_INSTANCE_SUPPORT_128_BYTES_TRANSFERn(x) (1)
/* @brief Has no register bit fields MP_CSR[EBW]. */
#define FSL_FEATURE_EDMA_HAS_NO_MP_CSR_EBW (1)
/* @brief Has register CH_CSR. */
#define FSL_FEATURE_EDMA_HAS_CHANNEL_CONFIG (1)
/* @brief If dma has common clock gate */
#define FSL_FEATURE_EDMA_HAS_COMMON_CLOCK_GATE (0)
/* @brief Has channel mux */
#define FSL_FEATURE_EDMA_HAS_CHANNEL_MUX (1)
/* @brief If dma channel IRQ support parameter */
#define FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SUPPORT_PARAMETER (0)
/* @brief Instance has channel mux */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_CHANNEL_MUXn(x) (1)
/* @brief NBYTES must be multiple of 8 when using scatter gather. */
#define FSL_FEATURE_EDMA_HAS_ERRATA_51327 (0)
/* @brief Has register CH_SBR. */
#define FSL_FEATURE_EDMA_HAS_SBR (1)
/* @brief NBYTES must be multiple of 8 when using scatter gather. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_ERRATA_51327n(x) (0)
/* @brief Has no register bit fields CH_SBR[ATTR]. */
#define FSL_FEATURE_EDMA_HAS_NO_CH_SBR_ATTR (1)
/* @brief Has register bit fields MP_CSR[GMRC]. */
#define FSL_FEATURE_EDMA_HAS_GLOBAL_MASTER_ID_REPLICATION (1)
/* @brief Has register bit field CH_CSR[SWAP]. */
#define FSL_FEATURE_EDMA_HAS_CHANNEL_SWAP_SIZE (0)
/* @brief Instance has register bit field CH_CSR[SWAP]. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_CHANNEL_SWAP_SIZEn(x) (0)
/* @brief Has register bit field CH_SBR[INSTR]. */
#define FSL_FEATURE_EDMA_HAS_CHANNEL_ACCESS_TYPE (0)
/* @brief Instance has register bit field CH_SBR[INSTR]. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_CHANNEL_ACCESS_TYPEn(x) (0)
/* @brief Has register bit fields CH_MATTR[WCACHE], CH_MATTR[RCACHE]. */
#define FSL_FEATURE_EDMA_HAS_CHANNEL_MEMORY_ATTRIBUTE (0)
/* @brief Instance has register CH_MATTR. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_CHANNEL_MEMORY_ATTRIBUTEn(x) (0)
/* @brief Has register bit field CH_CSR[SIGNEXT]. */
#define FSL_FEATURE_EDMA_HAS_CHANNEL_SIGN_EXTENSION (0)
/* @brief Instance Has register bit field CH_CSR[SIGNEXT]. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_CHANNEL_SIGN_EXTENSIONn(x) (0)
/* @brief Has register bit field TCD_CSR[BWC]. */
#define FSL_FEATURE_EDMA_HAS_BANDWIDTH (1)
/* @brief Instance has register bit field TCD_CSR[BWC]. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_BANDWIDTHn(x) (1)
/* @brief Has register bit fields TCD_CSR[TMC]. */
#define FSL_FEATURE_EDMA_HAS_TRANSFER_MODE (0)
/* @brief Instance has register bit fields TCD_CSR[TMC]. */
#define FSL_FEATURE_EDMA_INSTANCE_HAS_TRANSFER_MODEn(x) (0)
/* @brief Has no register bit fields CH_SBR[SEC]. */
#define FSL_FEATURE_EDMA_HAS_NO_CH_SBR_SEC (1)
/* PWM module features */
/* @brief If (e)FlexPWM has module A channels (outputs). */
#define FSL_FEATURE_PWM_HAS_CHANNELA (1)
/* @brief If (e)FlexPWM has module B channels (outputs). */
#define FSL_FEATURE_PWM_HAS_CHANNELB (1)
/* @brief If (e)FlexPWM has module X channels (outputs). */
#define FSL_FEATURE_PWM_HAS_CHANNELX (1)
/* @brief If (e)FlexPWM has fractional feature. */
#define FSL_FEATURE_PWM_HAS_FRACTIONAL (0)
/* @brief If (e)FlexPWM has mux trigger source select bit field. */
#define FSL_FEATURE_PWM_HAS_MUX_TRIGGER_SOURCE_SEL (1)
/* @brief Number of submodules in each (e)FlexPWM module. */
#define FSL_FEATURE_PWM_SUBMODULE_COUNT (3)
/* @brief Number of fault channel in each (e)FlexPWM module. */
#define FSL_FEATURE_PWM_FAULT_CH_COUNT (1)
/* @brief (e)FlexPWM has no WAITEN Bitfield In CTRL2 Register. */
#define FSL_FEATURE_PWM_HAS_NO_WAITEN (1)
/* @brief If (e)FlexPWM has phase delay feature. */
#define FSL_FEATURE_PWM_HAS_PHASE_DELAY (1)
/* @brief If (e)FlexPWM has input filter capture feature. */
#define FSL_FEATURE_PWM_HAS_INPUT_FILTER_CAPTURE (1)
/* @brief If (e)FlexPWM has module capture functionality on A channels (inputs). */
#define FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA (0)
/* @brief If (e)FlexPWM has module capture functionality on B channels (inputs). */
#define FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB (0)
/* @brief If (e)FlexPWM has module capture functionality on X channels (inputs). */
#define FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX (1)
/* GPIO module features */
/* @brief Has GPIO attribute checker register (GACR). */
#define FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER (0)
/* @brief Has GPIO version ID register (VERID). */
#define FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER (1)
/* @brief Has secure/non-secure access protection registers (LOCK, PCNS, PCNP, ICNS, ICNP). */
#define FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL (0)
/* @brief Has GPIO port input disable register (PIDR). */
#define FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL (1)
/* @brief Has GPIO interrupt/DMA request/trigger output selection. */
#define FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT (0)
/* I3C module features */
/* @brief Has TERM bitfile in MERRWARN register. */
#define FSL_FEATURE_I3C_HAS_NO_MERRWARN_TERM (0)
/* @brief SOC has no reset driver. */
#define FSL_FEATURE_I3C_HAS_NO_RESET (0)
/* @brief Use fixed BAMATCH count, do not provide editable BAMATCH. */
#define FSL_FEATURE_I3C_HAS_NO_SCONFIG_BAMATCH (0)
/* @brief Register SCONFIG do not have IDRAND bitfield. */
#define FSL_FEATURE_I3C_HAS_NO_SCONFIG_IDRAND (1)
/* @brief Register SCONFIG has HDROK bitfield. */
#define FSL_FEATURE_I3C_HAS_HDROK (1)
/* @brief Has IBI bytes. */
#define FSL_FEATURE_I3C_HAS_IBI_PAYLOAD_SIZE_OPTIONAL_BYTE (1)
/* LPI2C module features */
/* @brief Has separate DMA RX and TX requests. */
#define FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPI2C_FIFO_SIZEn(x) (4)
/* LPSPI module features */
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPSPI_FIFO_SIZEn(x) (4)
/* @brief Has separate DMA RX and TX requests. */
#define FSL_FEATURE_LPSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
/* @brief Has CCR1 (related to existence of registers CCR1). */
#define FSL_FEATURE_LPSPI_HAS_CCR1 (1)
/* LPTMR module features */
/* @brief Has shared interrupt handler with another LPTMR module. */
#define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (0)
/* @brief Whether LPTMR counter is 32 bits width. */
#define FSL_FEATURE_LPTMR_CNR_WIDTH_IS_32B (1)
/* @brief Has timer DMA request enable (register bit CSR[TDRE]). */
#define FSL_FEATURE_LPTMR_HAS_CSR_TDRE (1)
/* @brief Do not has prescaler clock source 1. */
#define FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT (0)
/* @brief Do not has prescaler clock source 3. */
#define FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_3_SUPPORT (0)
/* LPUART module features */
/* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */
#define FSL_FEATURE_LPUART_HAS_IRQ_EXTENDED_FUNCTIONS (0)
/* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_LOW_POWER_UART_SUPPORT (1)
/* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1)
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPUART_HAS_FIFO (1)
/* @brief Has 32-bit register MODIR */
#define FSL_FEATURE_LPUART_HAS_MODIR (1)
/* @brief Hardware flow control (RTS, CTS) is supported. */
#define FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT (1)
/* @brief Infrared (modulation) is supported. */
#define FSL_FEATURE_LPUART_HAS_IR_SUPPORT (1)
/* @brief 2 bits long stop bit is available. */
#define FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT (1)
/* @brief If 10-bit mode is supported. */
#define FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT (1)
/* @brief If 7-bit mode is supported. */
#define FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT (1)
/* @brief Baud rate fine adjustment is available. */
#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (0)
/* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (1)
/* @brief Baud rate oversampling is available. */
#define FSL_FEATURE_LPUART_HAS_RX_RESYNC_SUPPORT (1)
/* @brief Baud rate oversampling is available. */
#define FSL_FEATURE_LPUART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (1)
/* @brief Peripheral type. */
#define FSL_FEATURE_LPUART_IS_SCI (1)
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPUART_FIFO_SIZEn(x) (4)
/* @brief Supports two match addresses to filter incoming frames. */
#define FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING (1)
/* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_DMA_ENABLE (1)
/* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */
#define FSL_FEATURE_LPUART_HAS_DMA_SELECT (0)
/* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_BIT_ORDER_SELECT (1)
/* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */
#define FSL_FEATURE_LPUART_HAS_SMART_CARD_SUPPORT (0)
/* @brief Has improved smart card (ISO7816 protocol) support. */
#define FSL_FEATURE_LPUART_HAS_IMPROVED_SMART_CARD_SUPPORT (0)
/* @brief Has local operation network (CEA709.1-B protocol) support. */
#define FSL_FEATURE_LPUART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0)
/* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */
#define FSL_FEATURE_LPUART_HAS_32BIT_REGISTERS (1)
/* @brief Lin break detect available (has bit BAUD[LBKDIE]). */
#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (1)
/* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */
#define FSL_FEATURE_LPUART_HAS_WAIT_MODE_OPERATION (0)
/* @brief Has separate DMA RX and TX requests. */
#define FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
/* @brief Has separate RX and TX interrupts. */
#define FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ (0)
/* @brief Has LPAURT_PARAM. */
#define FSL_FEATURE_LPUART_HAS_PARAM (1)
/* @brief Has LPUART_VERID. */
#define FSL_FEATURE_LPUART_HAS_VERID (1)
/* @brief Has LPUART_GLOBAL. */
#define FSL_FEATURE_LPUART_HAS_GLOBAL (1)
/* @brief Has LPUART_PINCFG. */
#define FSL_FEATURE_LPUART_HAS_PINCFG (1)
/* @brief Has register MODEM Control. */
#define FSL_FEATURE_LPUART_HAS_MCR (0)
/* @brief Has register Half Duplex Control. */
#define FSL_FEATURE_LPUART_HAS_HDCR (0)
/* @brief Has register Timeout. */
#define FSL_FEATURE_LPUART_HAS_TIMEOUT (0)
/* PORT module features */
/* @brief Has control lock (register bit PCR[LK]). */
#define FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK (1)
/* @brief Has open drain control (register bit PCR[ODE]). */
#define FSL_FEATURE_PORT_HAS_OPEN_DRAIN (1)
/* @brief Has digital filter (registers DFER, DFCR and DFWR). */
#define FSL_FEATURE_PORT_HAS_DIGITAL_FILTER (0)
/* @brief Has DMA request (register bit field PCR[IRQC] or ICR[IRQC] values). */
#define FSL_FEATURE_PORT_HAS_DMA_REQUEST (0)
/* @brief Has pull resistor selection available. */
#define FSL_FEATURE_PORT_HAS_PULL_SELECTION (1)
/* @brief Has pull resistor enable (register bit PCR[PE]). */
#define FSL_FEATURE_PORT_HAS_PULL_ENABLE (1)
/* @brief Has slew rate control (register bit PCR[SRE]). */
#define FSL_FEATURE_PORT_HAS_SLEW_RATE (1)
/* @brief Has passive filter (register bit field PCR[PFE]). */
#define FSL_FEATURE_PORT_HAS_PASSIVE_FILTER (1)
/* @brief Do not has interrupt control (register ISFR). */
#define FSL_FEATURE_PORT_HAS_NO_INTERRUPT (1)
/* @brief Has pull value (register bit field PCR[PV]). */
#define FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE (1)
/* @brief Has drive strength1 control (register bit PCR[DSE1]). */
#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1 (1)
/* @brief Has version ID register (register VERID). */
#define FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER (1)
/* @brief Has voltage range control (register bit CONFIG[RANGE]). */
#define FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE (1)
/* @brief Has EFT detect (registers EDFR, EDIER and EDCR). */
#define FSL_FEATURE_PORT_SUPPORT_EFT (0)
/* @brief Has drive strength control (register bit PCR[DSE]). */
#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH (1)
/* @brief Defines width of PCR[MUX] field. */
#define FSL_FEATURE_PORT_PCR_MUX_WIDTH (4)
/* @brief Has dedicated interrupt vector. */
#define FSL_FEATURE_PORT_HAS_INTERRUPT_VECTOR (1)
/* @brief Has independent interrupt control(register ICR). */
#define FSL_FEATURE_PORT_HAS_INDEPENDENT_INTERRUPT_CONTROL (0)
/* @brief Has multiple pin IRQ configuration (register GICLR and GICHR). */
#define FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG (0)
/* @brief Has Input Buffer Enable (register bit field PCR[IBE]). */
#define FSL_FEATURE_PORT_HAS_INPUT_BUFFER (1)
/* @brief Has Invert Input (register bit field PCR[INV]). */
#define FSL_FEATURE_PORT_HAS_INVERT_INPUT (1)
/* @brief Defines whether PCR[IRQC] bit-field has flag states. */
#define FSL_FEATURE_PORT_HAS_IRQC_FLAG (0)
/* @brief Defines whether PCR[IRQC] bit-field has trigger states. */
#define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0)
/* EQDC module features */
/* @brief If EQDC CTRL2 register has EMIP bit field. */
#define FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD (1)
/* SPC module features */
/* @brief Has DCDC */
#define FSL_FEATURE_MCX_SPC_HAS_DCDC (0)
/* @brief Has SYS LDO */
#define FSL_FEATURE_MCX_SPC_HAS_SYS_LDO (0)
/* @brief Has IOVDD_LVDF */
#define FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD (0)
/* @brief Has COREVDD_HVDF */
#define FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD (0)
/* @brief Has CORELDO_VDD_DS */
#define FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS (1)
/* @brief Has LPBUFF_EN */
#define FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT (0)
/* @brief Has COREVDD_IVS_EN */
#define FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT (0)
/* @brief Has SWITCH_STATE */
#define FSL_FEATURE_MCX_SPC_HAS_SWITCH_STATE_BIT (1)
/* @brief Has SRAMRETLDO */
#define FSL_FEATURE_MCX_SPC_HAS_SRAMRETLDO_REG (1)
/* @brief Has CFG register */
#define FSL_FEATURE_MCX_SPC_HAS_CFG_REG (1)
/* @brief Has SRAMLDO_DPD_ON */
#define FSL_FEATURE_MCX_SPC_HAS_SRAMLDO_DPD_ON_BIT (1)
/* @brief Has CNTRL register */
#define FSL_FEATURE_MCX_SPC_HAS_CNTRL_REG (0)
/* @brief Has DPDOWN_PULLDOWN_DISABLE */
#define FSL_FEATURE_MCX_SPC_HAS_DPDOWN_PULLDOWN_DISABLE_BIT (0)
/* SYSCON module features */
/* @brief Flash page size in bytes */
#define FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES (128)
/* @brief Flash sector size in bytes */
#define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (8192)
/* @brief Flash size in bytes */
#define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (131072)
/* @brief Support ROMAPI */
#define FSL_FEATURE_SYSCON_ROMAPI (1)
/* @brief Powerlib API is different with other series devices */
#define FSL_FEATURE_POWERLIB_EXTEND (1)
/* @brief No OSTIMER register in PMC */
#define FSL_FEATURE_PMC_HAS_NO_OSTIMER_REG (1)
/* @brief Starter register discontinuous. */
#define FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS (1)
/* USB module features */
/* @brief KHCI module instance count */
#define FSL_FEATURE_USB_KHCI_COUNT (1)
/* @brief HOST mode enabled */
#define FSL_FEATURE_USB_KHCI_HOST_ENABLED (0)
/* @brief OTG mode enabled */
#define FSL_FEATURE_USB_KHCI_OTG_ENABLED (0)
/* @brief Size of the USB dedicated RAM */
#define FSL_FEATURE_USB_KHCI_USB_RAM (0)
/* @brief Has KEEP_ALIVE_CTRL register */
#define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (0)
/* @brief Has the Dynamic SOF threshold compare support */
#define FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED (0)
/* @brief Has the VBUS detect support */
#define FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED (1)
/* @brief Has the IRC48M module clock support */
#define FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED (1)
/* @brief Number of endpoints supported */
#define FSL_FEATURE_USB_ENDPT_COUNT (16)
/* @brief Has STALL_IL/OL_DIS registers */
#define FSL_FEATURE_USB_KHCI_HAS_STALL_LOW (1)
/* @brief Has STALL_IH/OH_DIS registers */
#define FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH (1)
/* UTICK module features */
/* @brief UTICK does not support PD configure. */
#define FSL_FEATURE_UTICK_HAS_NO_PDCFG (1)
/* VBAT module features */
/* @brief Has STATUS register */
#define FSL_FEATURE_MCX_VBAT_HAS_STATUS_REG (0)
/* @brief Has TAMPER register */
#define FSL_FEATURE_MCX_VBAT_HAS_TAMPER_REG (0)
/* @brief Has BANDGAP register */
#define FSL_FEATURE_MCX_VBAT_HAS_BANDGAP_TIMER (0)
/* @brief Has LDOCTL register */
#define FSL_FEATURE_MCX_VBAT_HAS_LDOCTL_REG (0)
/* @brief Has OSCCTL register */
#define FSL_FEATURE_MCX_VBAT_HAS_OSCCTL_REG (0)
/* @brief Has SWICTL register */
#define FSL_FEATURE_MCX_VBAT_HAS_SWICTL_REG (0)
/* @brief Has CLKMON register */
#define FSL_FEATURE_MCX_VBAT_HAS_CLKMON_REG (0)
/* WWDT module features */
/* @brief Has no RESET register. */
#define FSL_FEATURE_WWDT_HAS_NO_RESET (1)
#endif /* _MCXA153_FEATURES_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,230 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_aoi.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.aoi"
#endif
#if defined(AOI_RSTS)
#define AOI_RESETS_ARRAY AOI_RSTS
#endif
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to aoi bases for each instance. */
static AOI_Type *const s_aoiBases[] = AOI_BASE_PTRS;
#if defined(AOI_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_aoiResets[] = AOI_RESETS_ARRAY;
#endif
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to aoi clocks for each instance. */
static const clock_ip_name_t s_aoiClocks[] = AOI_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for AOI module.
*
* @param base AOI peripheral base address
*
* @return The AOI instance
*/
static uint32_t AOI_GetInstance(AOI_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t AOI_GetInstance(AOI_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_aoiBases); instance++)
{
if (s_aoiBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_aoiBases));
return instance;
}
/*!
* brief Initializes an AOI instance for operation.
*
* This function un-gates the AOI clock.
*
* param base AOI peripheral address.
*/
void AOI_Init(AOI_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock gate from clock manager. */
CLOCK_EnableClock(s_aoiClocks[AOI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(AOI_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_aoiResets[AOI_GetInstance(base)]);
#endif
}
/*!
* brief Deinitializes an AOI instance for operation.
*
* This function shutdowns AOI module.
*
* param base AOI peripheral address.
*/
void AOI_Deinit(AOI_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock gate from clock manager */
CLOCK_DisableClock(s_aoiClocks[AOI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Gets the Boolean evaluation associated.
*
* This function returns the Boolean evaluation associated.
*
* Example:
code
aoi_event_config_t demoEventLogicStruct;
AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct);
endcode
*
* param base AOI peripheral address.
* param event Index of the event which will be set of type aoi_event_t.
* param config Selected input configuration .
*/
void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config)
{
assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT);
assert(config != NULL);
uint16_t value;
uint16_t temp;
/* Read BFCRT01 register at event index. */
value = base->BFCRT[event].BFCRT01;
temp = (value & AOI_BFCRT01_PT0_AC_MASK) >> AOI_BFCRT01_PT0_AC_SHIFT;
config->PT0AC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT0_BC_MASK) >> AOI_BFCRT01_PT0_BC_SHIFT;
config->PT0BC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT0_CC_MASK) >> AOI_BFCRT01_PT0_CC_SHIFT;
config->PT0CC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT0_DC_MASK) >> AOI_BFCRT01_PT0_DC_SHIFT;
config->PT0DC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT1_AC_MASK) >> AOI_BFCRT01_PT1_AC_SHIFT;
config->PT1AC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT1_BC_MASK) >> AOI_BFCRT01_PT1_BC_SHIFT;
config->PT1BC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT1_CC_MASK) >> AOI_BFCRT01_PT1_CC_SHIFT;
config->PT1CC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT01_PT1_DC_MASK) >> AOI_BFCRT01_PT1_DC_SHIFT;
config->PT1DC = (aoi_input_config_t)temp;
/* Read BFCRT23 register at event index. */
value = base->BFCRT[event].BFCRT23;
temp = (value & AOI_BFCRT23_PT2_AC_MASK) >> AOI_BFCRT23_PT2_AC_SHIFT;
config->PT2AC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT2_BC_MASK) >> AOI_BFCRT23_PT2_BC_SHIFT;
config->PT2BC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT2_CC_MASK) >> AOI_BFCRT23_PT2_CC_SHIFT;
config->PT2CC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT2_DC_MASK) >> AOI_BFCRT23_PT2_DC_SHIFT;
config->PT2DC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT3_AC_MASK) >> AOI_BFCRT23_PT3_AC_SHIFT;
config->PT3AC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT3_BC_MASK) >> AOI_BFCRT23_PT3_BC_SHIFT;
config->PT3BC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT3_CC_MASK) >> AOI_BFCRT23_PT3_CC_SHIFT;
config->PT3CC = (aoi_input_config_t)temp;
temp = (value & AOI_BFCRT23_PT3_DC_MASK) >> AOI_BFCRT23_PT3_DC_SHIFT;
config->PT3DC = (aoi_input_config_t)temp;
}
/*!
* brief Configures an AOI event.
*
* This function configures an AOI event according
* to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D)
* of all product terms (0, 1, 2, and 3) of a desired event.
*
* Example:
code
aoi_event_config_t demoEventLogicStruct;
demoEventLogicStruct.PT0AC = kAOI_InvInputSignal;
demoEventLogicStruct.PT0BC = kAOI_InputSignal;
demoEventLogicStruct.PT0CC = kAOI_LogicOne;
demoEventLogicStruct.PT0DC = kAOI_LogicOne;
demoEventLogicStruct.PT1AC = kAOI_LogicZero;
demoEventLogicStruct.PT1BC = kAOI_LogicOne;
demoEventLogicStruct.PT1CC = kAOI_LogicOne;
demoEventLogicStruct.PT1DC = kAOI_LogicOne;
demoEventLogicStruct.PT2AC = kAOI_LogicZero;
demoEventLogicStruct.PT2BC = kAOI_LogicOne;
demoEventLogicStruct.PT2CC = kAOI_LogicOne;
demoEventLogicStruct.PT2DC = kAOI_LogicOne;
demoEventLogicStruct.PT3AC = kAOI_LogicZero;
demoEventLogicStruct.PT3BC = kAOI_LogicOne;
demoEventLogicStruct.PT3CC = kAOI_LogicOne;
demoEventLogicStruct.PT3DC = kAOI_LogicOne;
AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct);
endcode
*
* param base AOI peripheral address.
* param event Event which will be configured of type aoi_event_t.
* param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for
* filling out the members of this structure and passing the pointer to this function.
*/
void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig)
{
assert(eventConfig != NULL);
assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT);
uint16_t value;
/* Calculate value to configure product term 0, 1 */
value = AOI_BFCRT01_PT0_AC(eventConfig->PT0AC) | AOI_BFCRT01_PT0_BC(eventConfig->PT0BC) |
AOI_BFCRT01_PT0_CC(eventConfig->PT0CC) | AOI_BFCRT01_PT0_DC(eventConfig->PT0DC) |
AOI_BFCRT01_PT1_AC(eventConfig->PT1AC) | AOI_BFCRT01_PT1_BC(eventConfig->PT1BC) |
AOI_BFCRT01_PT1_CC(eventConfig->PT1CC) | AOI_BFCRT01_PT1_DC(eventConfig->PT1DC);
/* Write value to register */
base->BFCRT[event].BFCRT01 = value;
/* Reset and calculate value to configure product term 2, 3 */
value = AOI_BFCRT23_PT2_AC(eventConfig->PT2AC) | AOI_BFCRT23_PT2_BC(eventConfig->PT2BC) |
AOI_BFCRT23_PT2_CC(eventConfig->PT2CC) | AOI_BFCRT23_PT2_DC(eventConfig->PT2DC) |
AOI_BFCRT23_PT3_AC(eventConfig->PT3AC) | AOI_BFCRT23_PT3_BC(eventConfig->PT3BC) |
AOI_BFCRT23_PT3_CC(eventConfig->PT3CC) | AOI_BFCRT23_PT3_DC(eventConfig->PT3DC);
/* Write value to register */
base->BFCRT[event].BFCRT23 = value;
}

View File

@ -0,0 +1,186 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_AOI_H_
#define _FSL_AOI_H_
#include "fsl_common.h"
/*!
* @addtogroup aoi
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef AOI
#define AOI AOI0 /*!< AOI peripheral address */
#endif
/*! @name Driver version */
/*@{*/
#define FSL_AOI_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2. */
/*@}*/
/*!
* @brief AOI input configurations.
*
* The selection item represents the Boolean evaluations.
*/
typedef enum _aoi_input_config
{
kAOI_LogicZero = 0x0U, /*!< Forces the input to logical zero. */
kAOI_InputSignal = 0x1U, /*!< Passes the input signal. */
kAOI_InvInputSignal = 0x2U, /*!< Inverts the input signal. */
kAOI_LogicOne = 0x3U /*!< Forces the input to logical one. */
} aoi_input_config_t;
/*!
* @brief AOI event indexes, where an event is the collection of the four product
* terms (0, 1, 2, and 3) and the four signal inputs (A, B, C, and D).
*/
typedef enum _aoi_event
{
kAOI_Event0 = 0x0U, /*!< Event 0 index */
kAOI_Event1 = 0x1U, /*!< Event 1 index */
kAOI_Event2 = 0x2U, /*!< Event 2 index */
kAOI_Event3 = 0x3U /*!< Event 3 index */
} aoi_event_t;
/*!
* @brief AOI event configuration structure
*
* Defines structure _aoi_event_config and use the AOI_SetEventLogicConfig() function to make
* whole event configuration.
*/
typedef struct _aoi_event_config
{
aoi_input_config_t PT0AC; /*!< Product term 0 input A */
aoi_input_config_t PT0BC; /*!< Product term 0 input B */
aoi_input_config_t PT0CC; /*!< Product term 0 input C */
aoi_input_config_t PT0DC; /*!< Product term 0 input D */
aoi_input_config_t PT1AC; /*!< Product term 1 input A */
aoi_input_config_t PT1BC; /*!< Product term 1 input B */
aoi_input_config_t PT1CC; /*!< Product term 1 input C */
aoi_input_config_t PT1DC; /*!< Product term 1 input D */
aoi_input_config_t PT2AC; /*!< Product term 2 input A */
aoi_input_config_t PT2BC; /*!< Product term 2 input B */
aoi_input_config_t PT2CC; /*!< Product term 2 input C */
aoi_input_config_t PT2DC; /*!< Product term 2 input D */
aoi_input_config_t PT3AC; /*!< Product term 3 input A */
aoi_input_config_t PT3BC; /*!< Product term 3 input B */
aoi_input_config_t PT3CC; /*!< Product term 3 input C */
aoi_input_config_t PT3DC; /*!< Product term 3 input D */
} aoi_event_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @name AOI Initialization
* @{
*/
/*!
* @brief Initializes an AOI instance for operation.
*
* This function un-gates the AOI clock.
*
* @param base AOI peripheral address.
*/
void AOI_Init(AOI_Type *base);
/*!
* @brief Deinitializes an AOI instance for operation.
*
* This function shutdowns AOI module.
*
* @param base AOI peripheral address.
*/
void AOI_Deinit(AOI_Type *base);
/*@}*/
/*!
* @name AOI Get Set Operation
* @{
*/
/*!
* @brief Gets the Boolean evaluation associated.
*
* This function returns the Boolean evaluation associated.
*
* Example:
@code
aoi_event_config_t demoEventLogicStruct;
AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct);
@endcode
*
* @param base AOI peripheral address.
* @param event Index of the event which will be set of type aoi_event_t.
* @param config Selected input configuration .
*/
void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config);
/*!
* @brief Configures an AOI event.
*
* This function configures an AOI event according
* to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D)
* of all product terms (0, 1, 2, and 3) of a desired event.
*
* Example:
@code
aoi_event_config_t demoEventLogicStruct;
demoEventLogicStruct.PT0AC = kAOI_InvInputSignal;
demoEventLogicStruct.PT0BC = kAOI_InputSignal;
demoEventLogicStruct.PT0CC = kAOI_LogicOne;
demoEventLogicStruct.PT0DC = kAOI_LogicOne;
demoEventLogicStruct.PT1AC = kAOI_LogicZero;
demoEventLogicStruct.PT1BC = kAOI_LogicOne;
demoEventLogicStruct.PT1CC = kAOI_LogicOne;
demoEventLogicStruct.PT1DC = kAOI_LogicOne;
demoEventLogicStruct.PT2AC = kAOI_LogicZero;
demoEventLogicStruct.PT2BC = kAOI_LogicOne;
demoEventLogicStruct.PT2CC = kAOI_LogicOne;
demoEventLogicStruct.PT2DC = kAOI_LogicOne;
demoEventLogicStruct.PT3AC = kAOI_LogicZero;
demoEventLogicStruct.PT3BC = kAOI_LogicOne;
demoEventLogicStruct.PT3CC = kAOI_LogicOne;
demoEventLogicStruct.PT3DC = kAOI_LogicOne;
AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct);
@endcode
*
* @param base AOI peripheral address.
* @param event Event which will be configured of type aoi_event_t.
* @param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for
* filling out the members of this structure and passing the pointer to this function.
*/
void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*@}*/
/*!* @} */
#endif /* _FSL_AOI_H_*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,814 @@
/*
* Copyright 2023, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_
#include "fsl_common.h"
/*! @addtogroup clock */
/*! @{ */
/*! @file */
/*******************************************************************************
* Definitions
*****************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief CLOCK driver version 1.0.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(1, 0, 0))
/*@}*/
/*! @brief Configure whether driver controls clock
*
* When set to 0, peripheral drivers will enable clock in initialize function
* and disable clock in de-initialize function. When set to 1, peripheral
* driver will not control the clock, application could control the clock out of
* the driver.
*
* @note All drivers share this feature switcher. If it is set to 1, application
* should handle clock enable and disable for all drivers.
*/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0U
#endif
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (96000000U)
#endif
/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
/*------------------------------------------------------------------------------
clock_ip_name_t definition:
------------------------------------------------------------------------------*/
#define CLK_GATE_REG_OFFSET(value) (((uint32_t)(value)) >> 16U)
#define CLK_GATE_BIT_SHIFT(value) (((uint32_t)(value)) & 0x0000FFFFU)
#define REG_PWM0SUBCTL (250U)
/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
typedef enum _clock_ip_name
{
kCLOCK_GateINPUTMUX0 = (0x00000U | (0U)), /*!< Clock gate name: INPUTMUX0 */
kCLOCK_InputMux = (0x00000U | (0U)), /*!< Clock gate name: INPUTMUX0 */
kCLOCK_GateI3C0 = (0x00000U | (1U)), /*!< Clock gate name: I3C0 */
kCLOCK_GateCTIMER0 = (0x00000U | (2U)), /*!< Clock gate name: CTIMER0 */
kCLOCK_GateCTIMER1 = (0x00000U | (3U)), /*!< Clock gate name: CTIMER1 */
kCLOCK_GateCTIMER2 = (0x00000U | (4U)), /*!< Clock gate name: CTIMER2 */
kCLOCK_GateFREQME = (0x00000U | (5U)), /*!< Clock gate name: FREQME */
kCLOCK_GateUTICK0 = (0x00000U | (6U)), /*!< Clock gate name: UTICK0 */
kCLOCK_GateWWDT0 = (0x00000U | (7U)), /*!< Clock gate name: WWDT0 */
kCLOCK_GateDMA = (0x00000U | (8U)), /*!< Clock gate name: DMA */
kCLOCK_GateAOI0 = (0x00000U | (9U)), /*!< Clock gate name: AOI0 */
kCLOCK_GateCRC = (0x00000U | (10U)), /*!< Clock gate name: CRC */
kCLOCK_Crc0 = (0x00000U | (10U)), /*!< Clock gate name: CRC */
kCLOCK_GateEIM = (0x00000U | (11U)), /*!< Clock gate name: EIM */
kCLOCK_GateERM = (0x00000U | (12U)), /*!< Clock gate name: ERM */
kCLOCK_GateLPI2C0 = (0x00000U | (16U)), /*!< Clock gate name: LPI2C0 */
kCLOCK_GateLPSPI0 = (0x00000U | (17U)), /*!< Clock gate name: LPSPI0 */
kCLOCK_GateLPSPI1 = (0x00000U | (18U)), /*!< Clock gate name: LPSPI1 */
kCLOCK_GateLPUART0 = (0x00000U | (19U)), /*!< Clock gate name: LPUART0 */
kCLOCK_GateLPUART1 = (0x00000U | (20U)), /*!< Clock gate name: LPUART1 */
kCLOCK_GateLPUART2 = (0x00000U | (21U)), /*!< Clock gate name: LPUART2 */
kCLOCK_GateUSB0 = (0x00000U | (22U)), /*!< Clock gate name: USB0 */
kCLOCK_GateQDC0 = (0x00000U | (23U)), /*!< Clock gate name: QDC0 */
kCLOCK_GateFLEXPWM0 = (0x00000U | (24U)), /*!< Clock gate name: FLEXPWM0 */
kCLOCK_GateOSTIMER0 = (0x00000U | (25U)), /*!< Clock gate name: OSTIMER0 */
kCLOCK_GateADC0 = (0x00000U | (26U)), /*!< Clock gate name: ADC0 */
kCLOCK_GateCMP0 = (0x00000U | (27U)), /*!< Clock gate name: CMP0 */
kCLOCK_GateCMP1 = (0x00000U | (28U)), /*!< Clock gate name: CMP1 */
kCLOCK_GatePORT0 = (0x00000U | (29U)), /*!< Clock gate name: PORT0 */
kCLOCK_GatePORT1 = (0x00000U | (30U)), /*!< Clock gate name: PORT1 */
kCLOCK_GatePORT2 = (0x00000U | (31U)), /*!< Clock gate name: PORT2 */
kCLOCK_GatePORT3 = ((0x10U << 16U) | (0U)), /*!< Clock gate name: PORT3 */
kCLOCK_GateATX0 = ((0x10U << 16U) | (1U)), /*!< Clock gate name: ATX0 */
kCLOCK_GateMTR = ((0x10U << 16U) | (2U)), /*!< Clock gate name: MTR */
kCLOCK_GateTCU = ((0x10U << 16U) | (3U)), /*!< Clock gate name: TCU */
kCLOCK_GateEZRAMC_RAMA = ((0x10U << 16U) | (4U)), /*!< Clock gate name: EZRAMC_RAMA */
kCLOCK_GateGPIO0 = ((0x10U << 16U) | (5U)), /*!< Clock gate name: GPIO0 */
kCLOCK_GateGPIO1 = ((0x10U << 16U) | (6U)), /*!< Clock gate name: GPIO1 */
kCLOCK_GateGPIO2 = ((0x10U << 16U) | (7U)), /*!< Clock gate name: GPIO2 */
kCLOCK_GateGPIO3 = ((0x10U << 16U) | (8U)), /*!< Clock gate name: GPIO3 */
kCLOCK_GateROMCP = ((0x10U << 16U) | (9U)), /*!< Clock gate name: ROMCP */
kCLOCK_GatePWMSM0 = ((REG_PWM0SUBCTL << 16U) | (0U)), /*!< Clock gate name: FlexPWM SM0 */
kCLOCK_GatePWMSM1 = ((REG_PWM0SUBCTL << 16U) | (1U)), /*!< Clock gate name: FlexPWM SM1 */
kCLOCK_GatePWMSM2 = ((REG_PWM0SUBCTL << 16U) | (2U)), /*!< Clock gate name: FlexPWM SM2 */
kCLOCK_GateNotAvail = (0xFFFFFFFFU), /**< Clock gate name: None */
} clock_ip_name_t;
/*! @brief Clock ip name array for AOI. */
#define AOI_CLOCKS \
{ \
kCLOCK_GateAOI0 \
}
/*! @brief Clock ip name array for CRC. */
#define CRC_CLOCKS \
{ \
kCLOCK_GateCRC \
}
/*! @brief Clock ip name array for CTIMER. */
#define CTIMER_CLOCKS \
{ \
kCLOCK_GateCTIMER0, kCLOCK_GateCTIMER1, kCLOCK_GateCTIMER2 \
}
/*! @brief Clock ip name array for DMA. */
#define DMA_CLOCKS \
{ \
kCLOCK_GateDMA \
}
/*! @brief Clock gate name array for EDMA. */
#define EDMA_CLOCKS \
{ \
kCLOCK_GateDMA \
}
/*! @brief Clock ip name array for ERM. */
#define ERM_CLOCKS \
{ \
kCLOCK_GateERM \
}
/*! @brief Clock ip name array for EIM. */
#define EIM_CLOCKS \
{ \
kCLOCK_GateEIM \
}
/*! @brief Clock ip name array for FREQME. */
#define FREQME_CLOCKS \
{ \
kCLOCK_GateFREQME \
}
/*! @brief Clock ip name array for GPIO. */
#define GPIO_CLOCKS \
{ \
kCLOCK_GateGPIO0, kCLOCK_GateGPIO1, kCLOCK_GateGPIO2, kCLOCK_GateGPIO3 \
}
/*! @brief Clock ip name array for I3C */
#define I3C_CLOCKS \
{ \
kCLOCK_GateI3C0 \
}
/*! @brief Clock ip name array for INPUTMUX. */
#define INPUTMUX_CLOCKS \
{ \
kCLOCK_GateINPUTMUX0 \
}
/*! @brief Clock ip name array for GPIO. */
#define LPCMP_CLOCKS \
{ \
kCLOCK_GateCMP0, kCLOCK_GateCMP1 \
}
/*! @brief Clock ip name array for LPADC. */
#define LPADC_CLOCKS \
{ \
kCLOCK_GateADC0 \
}
/*! @brief Clock ip name array for LPUART. */
#define LPUART_CLOCKS \
{ \
kCLOCK_GateLPUART0, kCLOCK_GateLPUART1, kCLOCK_GateLPUART2 \
}
/*! @brief Clock ip name array for LPI2C. */
#define LPI2C_CLOCKS \
{ \
kCLOCK_GateLPI2C0 \
}
/*! @brief Clock ip name array for LSPI. */
#define LPSPI_CLOCKS \
{ \
kCLOCK_GateLPSPI0, kCLOCK_GateLPSPI1 \
}
/*! @brief Clock ip name array for MTR. */
#define MTR_CLOCKS \
{ \
kCLOCK_GateMTR \
}
/*! @brief Clock ip name array for OSTIMER. */
#define OSTIMER_CLOCKS \
{ \
kCLOCK_GateOSTIMER0 \
}
/*! @brief Clock ip name array for PWM. */
#define PWM_CLOCKS \
{ \
{ \
kCLOCK_GatePWMSM0, kCLOCK_GatePWMSM1, kCLOCK_GatePWMSM2 \
} \
}
/*! @brief Clock ip name array for QDC. */
#define QDC_CLOCKS \
{ \
kCLOCK_GateQDC0 \
}
/*! @brief Clock ip name array for UTICK. */
#define UTICK_CLOCKS \
{ \
kCLOCK_GateUTICK0 \
}
/*! @brief Clock ip name array for WWDT. */
#define WWDT_CLOCKS \
{ \
kCLOCK_GateWWDT0 \
}
/*! @brief Peripherals clock source definition. */
#define BUS_CLK kCLOCK_BusClk
/*! @brief Clock name used to get clock frequency. */
typedef enum _clock_name
{
kCLOCK_MainClk, /*!< MAIN_CLK */
kCLOCK_CoreSysClk, /*!< Core/system clock(CPU_CLK) */
kCLOCK_SYSTEM_CLK, /*!< AHB clock */
kCLOCK_BusClk, /*!< Bus clock (AHB clock) */
kCLOCK_ExtClk, /*!< External Clock */
kCLOCK_FroHf, /*!< FRO192 */
kCLOCK_FroHfDiv, /*!< Divided by FRO192 */
kCLOCK_Clk48M, /*!< CLK48M */
kCLOCK_Fro12M, /*!< FRO12M */
kCLOCK_Clk1M, /*!< CLK1M */
kCLOCK_Fro16K, /*!< FRO16K */
kCLOCK_Clk16K0, /*!< CLK16K[0] */
kCLOCK_Clk16K1, /*!< CLK16K[1] */
kCLOCK_SLOW_CLK, /*!< SYSTEM_CLK divided by 4 */
} clock_name_t;
/*! @brief Clock Mux Switches
* The encoding is as follows each connection identified is 32bits wide while 24bits are valuable
* starting from LSB upwards
*
* [4 bits for choice, 0 means invalid choice] [8 bits mux ID]*
*
*/
#define CLK_ATTACH_REG_OFFSET(value) (((uint32_t)(value)) >> 16U)
#define CLK_ATTACH_CLK_SEL(value) (((uint32_t)(value)) & 0x0000FFFFU)
#define CLK_ATTACH_MUX(reg, sel) ((((uint32_t)(reg)) << 16U) | (sel))
/*! @brief Clock name used to get clock frequency. */
typedef enum _clock_select_name
{
kCLOCK_SelI3C0_FCLK = (0x0A0U), /*!< I3C0_FCLK clock selection */
kCLOCK_SelCTIMER0 = (0x0A8U), /*!< CTIMER0 clock selection */
kCLOCK_SelCTIMER1 = (0x0B0U), /*!< CTIMER1 clock selection */
kCLOCK_SelCTIMER2 = (0x0B8U), /*!< CTIMER2 clock selection */
kCLOCK_SelLPI2C0 = (0x0C8U), /*!< LPI2C0 clock selection */
kCLOCK_SelLPSPI0 = (0x0D0U), /*!< LPSPI0 clock selection */
kCLOCK_SelLPSPI1 = (0x0D8U), /*!< LPSPI1 clock selection */
kCLOCK_SelLPUART0 = (0x0E0U), /*!< LPUART0 clock selection */
kCLOCK_SelLPUART1 = (0x0E8U), /*!< LPUART1 clock selection */
kCLOCK_SelLPUART2 = (0x0F0U), /*!< LPUART2 clock selection */
kCLOCK_SelUSB0 = (0x0F8U), /*!< USB0 clock selection */
kCLOCK_SelLPTMR0 = (0x100U), /*!< LPTMR0 clock selection */
kCLOCK_SelOSTIMER0 = (0x108U), /*!< OSTIMER0 clock selection */
kCLOCK_SelADC0 = (0x110U), /*!< ADC0 clock selection */
kCLOCK_SelCMP0_RR = (0x120U), /*!< CMP0_RR clock selection */
kCLOCK_SelCMP1_RR = (0x130U), /*!< CMP1_RR clock selection */
kCLOCK_SelTRACE = (0x138U), /*!< TRACE clock selection */
kCLOCK_SelCLKOUT = (0x140U), /*!< CLKOUT clock selection */
kCLOCK_SelSYSTICK = (0x148U), /*!< SYSTICK clock selection */
kCLOCK_SelSCGSCS = (0x200U), /*!< SCG SCS clock selection */
kCLOCK_SelMax = (0x200U), /*!< MAX clock selection */
} clock_select_name_t;
/*!
* @brief The enumerator of clock attach Id.
*/
typedef enum _clock_attach_id
{
kCLK_IN_to_MAIN_CLK = CLK_ATTACH_MUX(kCLOCK_SelSCGSCS, 1U), /*!< Attach clk_in to MAIN_CLK. */
kFRO12M_to_MAIN_CLK = CLK_ATTACH_MUX(kCLOCK_SelSCGSCS, 2U), /*!< Attach FRO_12M to MAIN_CLK. */
kFRO_HF_to_MAIN_CLK = CLK_ATTACH_MUX(kCLOCK_SelSCGSCS, 3U), /*!< Attach FRO_HF to MAIN_CLK. */
kCLK_16K_to_MAIN_CLK = CLK_ATTACH_MUX(kCLOCK_SelSCGSCS, 4U), /*!< Attach CLK_16K[1] to MAIN_CLK. */
kNONE_to_MAIN_CLK = CLK_ATTACH_MUX(kCLOCK_SelSCGSCS, 7U), /*!< Attach NONE to MAIN_CLK. */
kFRO12M_to_I3C0FCLK = CLK_ATTACH_MUX(kCLOCK_SelI3C0_FCLK, 0U), /*!< Attach FRO12M to I3C0FCLK. */
kFRO_HF_DIV_to_I3C0FCLK = CLK_ATTACH_MUX(kCLOCK_SelI3C0_FCLK, 2U), /*!< Attach FRO_HF_DIV to I3C0FCLK. */
kCLK_IN_to_I3C0FCLK = CLK_ATTACH_MUX(kCLOCK_SelI3C0_FCLK, 3U), /*!< Attach CLK_IN to I3C0FCLK. */
kCLK_1M_to_I3C0FCLK = CLK_ATTACH_MUX(kCLOCK_SelI3C0_FCLK, 5U), /*!< Attach CLK_1M to I3C0FCLK. */
kNONE_to_I3C0FCLK = CLK_ATTACH_MUX(kCLOCK_SelI3C0_FCLK, 7U), /*!< Attach NONE to I3C0FCLK. */
kFRO12M_to_CTIMER0 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER0, 0U), /*!< Attach FRO12M to CTIMER0. */
kFRO_HF_to_CTIMER0 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER0, 1U), /*!< Attach FRO_HF to CTIMER0. */
kCLK_IN_to_CTIMER0 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER0, 3U), /*!< Attach CLK_IN to CTIMER0. */
kCLK_16K_to_CTIMER0 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER0, 4U), /*!< Attach CLK_16K to CTIMER0. */
kCLK_1M_to_CTIMER0 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER0, 5U), /*!< Attach CLK_1M to CTIMER0. */
kNONE_to_CTIMER0 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER0, 7U), /*!< Attach NONE to CTIMER0. */
kFRO12M_to_CTIMER1 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER1, 0U), /*!< Attach FRO12M to CTIMER1. */
kFRO_HF_to_CTIMER1 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER1, 1U), /*!< Attach FRO_HF to CTIMER1. */
kCLK_IN_to_CTIMER1 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER1, 3U), /*!< Attach CLK_IN to CTIMER1. */
kCLK_16K_to_CTIMER1 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER1, 4U), /*!< Attach CLK_16K to CTIMER1. */
kCLK_1M_to_CTIMER1 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER1, 5U), /*!< Attach CLK_1M to CTIMER1. */
kNONE_to_CTIMER1 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER1, 7U), /*!< Attach NONE to CTIMER1. */
kFRO12M_to_CTIMER2 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER2, 0U), /*!< Attach FRO12M to CTIMER2. */
kFRO_HF_to_CTIMER2 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER2, 1U), /*!< Attach FRO_HF to CTIMER2. */
kCLK_IN_to_CTIMER2 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER2, 3U), /*!< Attach CLK_IN to CTIMER2. */
kCLK_16K_to_CTIMER2 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER2, 4U), /*!< Attach CLK_16K to CTIMER2. */
kCLK_1M_to_CTIMER2 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER2, 5U), /*!< Attach CLK_1M to CTIMER2. */
kNONE_to_CTIMER2 = CLK_ATTACH_MUX(kCLOCK_SelCTIMER2, 7U), /*!< Attach NONE to CTIMER2. */
kFRO12M_to_LPI2C0 = CLK_ATTACH_MUX(kCLOCK_SelLPI2C0, 0U), /*!< Attach FRO12M to LPI2C0. */
kFRO_HF_DIV_to_LPI2C0 = CLK_ATTACH_MUX(kCLOCK_SelLPI2C0, 2U), /*!< Attach FRO_HF_DIV to LPI2C0. */
kCLK_IN_to_LPI2C0 = CLK_ATTACH_MUX(kCLOCK_SelLPI2C0, 3U), /*!< Attach CLK_IN to LPI2C0. */
kCLK_1M_to_LPI2C0 = CLK_ATTACH_MUX(kCLOCK_SelLPI2C0, 5U), /*!< Attach CLK_1M to LPI2C0. */
kNONE_to_LPI2C0 = CLK_ATTACH_MUX(kCLOCK_SelLPI2C0, 7U), /*!< Attach NONE to LPI2C0. */
kFRO12M_to_LPSPI0 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI0, 0U), /*!< Attach FRO12M to LPSPI0. */
kFRO_HF_DIV_to_LPSPI0 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI0, 2U), /*!< Attach FRO_HF_DIV to LPSPI0. */
kCLK_IN_to_LPSPI0 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI0, 3U), /*!< Attach CLK_IN to LPSPI0. */
kCLK_1M_to_LPSPI0 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI0, 5U), /*!< Attach CLK_1M to LPSPI0. */
kNONE_to_LPSPI0 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI0, 7U), /*!< Attach NONE to LPSPI0. */
kFRO12M_to_LPSPI1 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI1, 0U), /*!< Attach FRO12M to LPSPI1. */
kFRO_HF_DIV_to_LPSPI1 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI1, 2U), /*!< Attach FRO_HF_DIV to LPSPI1. */
kCLK_IN_to_LPSPI1 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI1, 3U), /*!< Attach CLK_IN to LPSPI1. */
kCLK_1M_to_LPSPI1 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI1, 5U), /*!< Attach CLK_1M to LPSPI1. */
kNONE_to_LPSPI1 = CLK_ATTACH_MUX(kCLOCK_SelLPSPI1, 7U), /*!< Attach NONE to LPSPI1. */
kFRO12M_to_LPUART0 = CLK_ATTACH_MUX(kCLOCK_SelLPUART0, 0U), /*!< Attach FRO12M to LPUART0. */
kFRO_HF_DIV_to_LPUART0 = CLK_ATTACH_MUX(kCLOCK_SelLPUART0, 2U), /*!< Attach FRO_HF_DIV to LPUART0. */
kCLK_IN_to_LPUART0 = CLK_ATTACH_MUX(kCLOCK_SelLPUART0, 3U), /*!< Attach CLK_IN to LPUART0. */
kCLK_16K_to_LPUART0 = CLK_ATTACH_MUX(kCLOCK_SelLPUART0, 4U), /*!< Attach CLK_16K to LPUART0. */
kCLK_1M_to_LPUART0 = CLK_ATTACH_MUX(kCLOCK_SelLPUART0, 5U), /*!< Attach CLK_1M to LPUART0. */
kNONE_to_LPUART0 = CLK_ATTACH_MUX(kCLOCK_SelLPUART0, 7U), /*!< Attach NONE to LPUART0. */
kFRO12M_to_LPUART1 = CLK_ATTACH_MUX(kCLOCK_SelLPUART1, 0U), /*!< Attach FRO12M to LPUART1. */
kFRO_HF_DIV_to_LPUART1 = CLK_ATTACH_MUX(kCLOCK_SelLPUART1, 2U), /*!< Attach FRO_HF_DIV to LPUART1. */
kCLK_IN_to_LPUART1 = CLK_ATTACH_MUX(kCLOCK_SelLPUART1, 3U), /*!< Attach CLK_IN to LPUART1. */
kCLK_16K_to_LPUART1 = CLK_ATTACH_MUX(kCLOCK_SelLPUART1, 4U), /*!< Attach CLK_16K to LPUART1. */
kCLK_1M_to_LPUART1 = CLK_ATTACH_MUX(kCLOCK_SelLPUART1, 5U), /*!< Attach CLK_1M to LPUART1. */
kNONE_to_LPUART1 = CLK_ATTACH_MUX(kCLOCK_SelLPUART1, 7U), /*!< Attach NONE to LPUART1. */
kFRO12M_to_LPUART2 = CLK_ATTACH_MUX(kCLOCK_SelLPUART2, 0U), /*!< Attach FRO12M to LPUART2. */
kFRO_HF_DIV_to_LPUART2 = CLK_ATTACH_MUX(kCLOCK_SelLPUART2, 2U), /*!< Attach FRO_HF_DIV to LPUART2. */
kCLK_IN_to_LPUART2 = CLK_ATTACH_MUX(kCLOCK_SelLPUART2, 3U), /*!< Attach CLK_IN to LPUART2. */
kCLK_16K_to_LPUART2 = CLK_ATTACH_MUX(kCLOCK_SelLPUART2, 4U), /*!< Attach CLK_16K to LPUART2. */
kCLK_1M_to_LPUART2 = CLK_ATTACH_MUX(kCLOCK_SelLPUART2, 5U), /*!< Attach CLK_1M to LPUART2. */
kNONE_to_LPUART2 = CLK_ATTACH_MUX(kCLOCK_SelLPUART2, 7U), /*!< Attach NONE to LPUART2. */
kCLK_48M_to_USB0 = CLK_ATTACH_MUX(kCLOCK_SelUSB0, 1U), /*!< Attach FRO12M to USB0. */
kCLK_IN_to_USB0 = CLK_ATTACH_MUX(kCLOCK_SelUSB0, 2U), /*!< Attach CLK_IN to USB0. */
kNONE_to_USB0 = CLK_ATTACH_MUX(kCLOCK_SelUSB0, 3U), /*!< Attach NONE to USB0. */
kFRO12M_to_LPTMR0 = CLK_ATTACH_MUX(kCLOCK_SelLPTMR0, 0U), /*!< Attach FRO12M to LPTMR0. */
kFRO_HF_DIV_to_LPTMR0 = CLK_ATTACH_MUX(kCLOCK_SelLPTMR0, 2U), /*!< Attach FRO_HF_DIV to LPTMR0. */
kCLK_IN_to_LPTMR0 = CLK_ATTACH_MUX(kCLOCK_SelLPTMR0, 3U), /*!< Attach CLK_IN to LPTMR0. */
kCLK_1M_to_LPTMR0 = CLK_ATTACH_MUX(kCLOCK_SelLPTMR0, 5U), /*!< Attach CLK_1M to LPTMR0. */
kNONE_to_LPTMR0 = CLK_ATTACH_MUX(kCLOCK_SelLPTMR0, 7U), /*!< Attach NONE to LPTMR0. */
kCLK_16K_to_OSTIMER = CLK_ATTACH_MUX(kCLOCK_SelOSTIMER0, 0U), /*!< Attach FRO16K to OSTIMER0. */
kCLK_1M_to_OSTIMER = CLK_ATTACH_MUX(kCLOCK_SelOSTIMER0, 2U), /*!< Attach CLK_1M to OSTIMER0. */
kNONE_to_OSTIMER = CLK_ATTACH_MUX(kCLOCK_SelOSTIMER0, 3U), /*!< Attach NONE to OSTIMER0. */
kFRO12M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 0U), /*!< Attach FRO12M to ADC0. */
kFRO_HF_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 1U), /*!< Attach FRO_HF to ADC0. */
kCLK_IN_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 3U), /*!< Attach CLK_IN to ADC0. */
kCLK_1M_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 5U), /*!< Attach CLK_1M to ADC0. */
kNONE_to_ADC0 = CLK_ATTACH_MUX(kCLOCK_SelADC0, 7U), /*!< Attach NONE to ADC0. */
kFRO12M_to_CMP0 = CLK_ATTACH_MUX(kCLOCK_SelCMP0_RR, 0U), /*!< Attach FRO12M to CMP0. */
kFRO_HF_DIV_to_CMP0 = CLK_ATTACH_MUX(kCLOCK_SelCMP0_RR, 2U), /*!< Attach FRO_HF_DIV to CMP0. */
kCLK_IN_to_CMP0 = CLK_ATTACH_MUX(kCLOCK_SelCMP0_RR, 3U), /*!< Attach CLK_IN to CMP0. */
kCLK_1M_to_CMP0 = CLK_ATTACH_MUX(kCLOCK_SelCMP0_RR, 5U), /*!< Attach CLK_1M to CMP0. */
kNONE_to_CMP0 = CLK_ATTACH_MUX(kCLOCK_SelCMP0_RR, 7U), /*!< Attach NONE to CMP0. */
kFRO12M_to_CMP1 = CLK_ATTACH_MUX(kCLOCK_SelCMP1_RR, 0U), /*!< Attach FRO12M to CMP1. */
kFRO_HF_DIV_to_CMP1 = CLK_ATTACH_MUX(kCLOCK_SelCMP1_RR, 2U), /*!< Attach FRO_HF_DIV to CMP1. */
kCLK_IN_to_CMP1 = CLK_ATTACH_MUX(kCLOCK_SelCMP1_RR, 3U), /*!< Attach CLK_IN to CMP1. */
kCLK_1M_to_CMP1 = CLK_ATTACH_MUX(kCLOCK_SelCMP1_RR, 5U), /*!< Attach CLK_1M to CMP1. */
kNONE_to_CMP1 = CLK_ATTACH_MUX(kCLOCK_SelCMP1_RR, 7U), /*!< Attach NONE to CMP1. */
kCPU_CLK_to_TRACE = CLK_ATTACH_MUX(kCLOCK_SelTRACE, 0U), /*!< Attach CPU_CLK to TRACE. */
kCLK_1M_to_TRACE = CLK_ATTACH_MUX(kCLOCK_SelTRACE, 1U), /*!< Attach CLK_1M to TRACE. */
kCLK_16K_to_TRACE = CLK_ATTACH_MUX(kCLOCK_SelTRACE, 2U), /*!< Attach CLK_16K to TRACE. */
kNONE_to_TRACE = CLK_ATTACH_MUX(kCLOCK_SelTRACE, 3U), /*!< Attach NONE to TRACE. */
kFRO12M_to_CLKOUT = CLK_ATTACH_MUX(kCLOCK_SelCLKOUT, 0U), /*!< Attach FRO12M to CLKOUT. */
kFRO_HF_DIV_to_CLKOUT = CLK_ATTACH_MUX(kCLOCK_SelCLKOUT, 1U), /*!< Attach FRO_HF_DIV to CLKOUT. */
kCLK_IN_to_CLKOUT = CLK_ATTACH_MUX(kCLOCK_SelCLKOUT, 2U), /*!< Attach CLK_IN to CLKOUT. */
kCLK_16K_to_CLKOUT = CLK_ATTACH_MUX(kCLOCK_SelCLKOUT, 3U), /*!< Attach CLK_16K to CLKOUT. */
kSLOW_CLK_to_CLKOUT = CLK_ATTACH_MUX(kCLOCK_SelCLKOUT, 6U), /*!< Attach SLOW_CLK to CLKOUT. */
kNONE_to_CLKOUT = CLK_ATTACH_MUX(kCLOCK_SelCLKOUT, 7U), /*!< Attach NONE to CLKOUT. */
kCPU_CLK_to_SYSTICK = CLK_ATTACH_MUX(kCLOCK_SelSYSTICK, 0U), /*!< Attach CPU_CLK to SYSTICK. */
kCLK_1M_to_SYSTICK = CLK_ATTACH_MUX(kCLOCK_SelSYSTICK, 1U), /*!< Attach CLK_1M to SYSTICK. */
kCLK_16K_to_SYSTICK = CLK_ATTACH_MUX(kCLOCK_SelSYSTICK, 2U), /*!< Attach CLK_16K to SYSTICK. */
kNONE_to_SYSTICK = CLK_ATTACH_MUX(kCLOCK_SelSYSTICK, 3U), /*!< Attach NONE to SYSTICK. */
kNONE_to_NONE = (0xFFFFFFFFU), /*!< Attach NONE to NONE. */
} clock_attach_id_t;
/*! @brief Clock dividers */
typedef enum _clock_div_name
{
kCLOCK_DivI3C0_FCLK = (0x0A4U), /*!< I3C0_FCLK clock divider */
kCLOCK_DivCTIMER0 = (0x0ACU), /*!< CTIMER0 clock divider */
kCLOCK_DivCTIMER1 = (0x0B4U), /*!< CTIMER1 clock divider */
kCLOCK_DivCTIMER2 = (0x0BCU), /*!< CTIMER2 clock divider */
kCLOCK_DivWWDT0 = (0x0C4U), /*!< WWDT0 clock divider */
kCLOCK_DivLPI2C0 = (0x0CCU), /*!< LPI2C0 clock divider */
kCLOCK_DivLPSPI0 = (0x0D4U), /*!< LPSPI0 clock divider */
kCLOCK_DivLPSPI1 = (0x0DCU), /*!< LPSPI1 clock divider */
kCLOCK_DivLPUART0 = (0x0E4U), /*!< LPUART0 clock divider */
kCLOCK_DivLPUART1 = (0x0ECU), /*!< LPUART1 clock divider */
kCLOCK_DivLPUART2 = (0x0F4U), /*!< LPUART2 clock divider */
kCLOCK_DivLPTMR0 = (0x104U), /*!< LPTMR0 clock divider */
kCLOCK_DivADC0 = (0x114U), /*!< ADC0 clock divider */
kCLOCK_DivCMP0_FUNC = (0x11CU), /*!< CMP0_FUNC clock divider */
kCLOCK_DivCMP0_RR = (0x124U), /*!< CMP0_RR clock divider */
kCLOCK_DivCMP1_FUNC = (0x12CU), /*!< CMP1_FUNC clock divider */
kCLOCK_DivCMP1_RR = (0x134U), /*!< CMP1_RR clock divider */
kCLOCK_DivTRACE = (0x13CU), /*!< TRACE clock divider */
kCLOCK_DivCLKOUT = (0x144U), /*!< CLKOUT clock divider */
kCLOCK_DivSYSTICK = (0x14CU), /*!< SYSTICK clock divider */
kCLOCK_DivFRO_HF_DIV = (0x154U), /*!< FRO_HF_DIV clock divider */
kCLOCK_DivSLOWCLK = (0x378U), /*!< SLOWCLK clock divider */
kCLOCK_DivAHBCLK = (0x380U), /*!< System clock divider */
kCLOCK_DivMax = (0x380U), /*!< MAX clock divider */
} clock_div_name_t;
/*!
* @brief firc trim mode.
*/
typedef enum _firc_trim_mode
{
kSCG_FircTrimNonUpdate = SCG_FIRCCSR_FIRCTREN_MASK,
/*!< Trim enable but not enable trim value update. In this mode, the
trim value is fixed to the initialized value which is defined by
trimCoar and trimFine in configure structure \ref firc_trim_config_t.*/
kSCG_FircTrimUpdate = SCG_FIRCCSR_FIRCTREN_MASK | SCG_FIRCCSR_FIRCTRUP_MASK
/*!< Trim enable and trim value update enable. In this mode, the trim
value is auto update. */
} firc_trim_mode_t;
/*!
* @brief firc trim source.
*/
typedef enum _firc_trim_src
{
kSCG_FircTrimSrcUsb0 = 0U, /*!< USB0 start of frame (1kHz). */
kSCG_FircTrimSrcSysOsc = 2U, /*!< System OSC. */
} firc_trim_src_t;
/*!
* @brief firc trim configuration.
*/
typedef struct _firc_trim_config
{
firc_trim_mode_t trimMode; /*!< Trim mode. */
firc_trim_src_t trimSrc; /*!< Trim source. */
uint16_t trimDiv; /*!< Divider of SOSC. */
uint8_t trimCoar; /*!< Trim coarse value; Irrelevant if trimMode is kSCG_TrimUpdate. */
uint8_t trimFine; /*!< Trim fine value; Irrelevant if trimMode is kSCG_TrimUpdate. */
} firc_trim_config_t;
/*!
* @brief sirc trim mode.
*/
typedef enum _sirc_trim_mode
{
kSCG_SircTrimNonUpdate = SCG_SIRCCSR_SIRCTREN_MASK,
/*!< Trim enable but not enable trim value update. In this mode, the
trim value is fixed to the initialized value which is defined by
trimCoar and trimFine in configure structure \ref sirc_trim_config_t.*/
kSCG_SircTrimUpdate = SCG_SIRCCSR_SIRCTREN_MASK | SCG_SIRCCSR_SIRCTRUP_MASK
/*!< Trim enable and trim value update enable. In this mode, the trim
value is auto update. */
} sirc_trim_mode_t;
/*!
* @brief sirc trim source.
*/
typedef enum _sirc_trim_src
{
kNoTrimSrc = 0, /*!< No external tirm source. */
kSCG_SircTrimSrcSysOsc = 2U, /*!< System OSC. */
} sirc_trim_src_t;
/*!
* @brief sirc trim configuration.
*/
typedef struct _sirc_trim_config
{
sirc_trim_mode_t trimMode; /*!< Trim mode. */
sirc_trim_src_t trimSrc; /*!< Trim source. */
uint16_t trimDiv; /*!< Divider of SOSC. */
uint8_t cltrim; /*!< Trim coarse value; Irrelevant if trimMode is kSCG_TrimUpdate. */
uint8_t ccotrim; /*!< Trim fine value; Irrelevant if trimMode is kSCG_TrimUpdate. */
} sirc_trim_config_t;
/*!
* @brief SCG system OSC monitor mode.
*/
typedef enum _scg_sosc_monitor_mode
{
kSCG_SysOscMonitorDisable = 0U, /*!< Monitor disabled. */
kSCG_SysOscMonitorInt = SCG_SOSCCSR_SOSCCM_MASK, /*!< Interrupt when the SOSC error is detected. */
kSCG_SysOscMonitorReset =
SCG_SOSCCSR_SOSCCM_MASK | SCG_SOSCCSR_SOSCCMRE_MASK /*!< Reset when the SOSC error is detected. */
} scg_sosc_monitor_mode_t;
/*!
* @brief firc trim source.
*/
typedef enum _clke_16k
{
kCLKE_16K_SYSTEM = VBAT_FROCLKE_CLKE(1U), /*!< To VSYS domain. */
kCLKE_16K_COREMAIN = VBAT_FROCLKE_CLKE(2U) /*!< To VDD_CORE domain. */
} clke_16k_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/**
* @brief Enable the clock for specific IP.
* @param clk : Clock to be enabled.
* @return Nothing
*/
static inline void CLOCK_EnableClock(clock_ip_name_t clk)
{
uint32_t reg_offset = CLK_GATE_REG_OFFSET(clk);
uint32_t bit_shift = CLK_GATE_BIT_SHIFT(clk);
volatile uint32_t *pClkCtrl = (volatile uint32_t *)((uint32_t)(&(MRCC0->MRCC_GLB_CC0_SET)) + reg_offset);
if (clk == kCLOCK_GateNotAvail)
{
return;
}
/* Unlock clock configuration */
SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
if (reg_offset == REG_PWM0SUBCTL)
{
SYSCON->PWM0SUBCTL |= (1UL << bit_shift);
MRCC0->MRCC_GLB_CC0_SET = MRCC_MRCC_GLB_CC0_FLEXPWM0_MASK;
}
else
{
*pClkCtrl = (1UL << bit_shift);
}
/* Freeze clock configuration */
SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
}
/**
* @brief Disable the clock for specific IP.
* @param clk : Clock to be Disabled.
* @return Nothing
*/
static inline void CLOCK_DisableClock(clock_ip_name_t clk)
{
uint32_t reg_offset = CLK_GATE_REG_OFFSET(clk);
uint32_t bit_shift = CLK_GATE_BIT_SHIFT(clk);
volatile uint32_t *pClkCtrl = (volatile uint32_t *)((uint32_t)(&(MRCC0->MRCC_GLB_CC0_CLR)) + reg_offset);
if (clk == kCLOCK_GateNotAvail)
{
return;
}
/* Unlock clock configuration */
SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
if (reg_offset == REG_PWM0SUBCTL)
{
SYSCON->PWM0SUBCTL &= ~(1UL << bit_shift);
if (0U == (SYSCON->PWM0SUBCTL & 0xFU))
{
MRCC0->MRCC_GLB_CC0_CLR = MRCC_MRCC_GLB_CC0_FLEXPWM0_MASK;
}
}
else
{
*pClkCtrl = (1UL << bit_shift);
}
/* Freeze clock configuration */
SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
}
/**
* @brief Configure the clock selection muxes.
* @param connection : Clock to be configured.
* @return Nothing
*/
void CLOCK_AttachClk(clock_attach_id_t connection);
/**
* @brief Get the actual clock attach id.
* This fuction uses the offset in input attach id, then it reads the actual source value in
* the register and combine the offset to obtain an actual attach id.
* @param connection : Clock attach id to get.
* @return Clock source value.
*/
clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t connection);
/**
* @brief Set the clock select value.
* This fuction set the peripheral clock select value.
* @param sel_name : Clock select.
* @param value : value to be set.
*/
void CLOCK_SetClockSelect(clock_select_name_t sel_name, uint32_t value);
/**
* @brief Get the clock select value.
* This fuction get the peripheral clock select value.
* @param sel_name : Clock select.
* @return Clock source value.
*/
uint32_t CLOCK_GetClockSelect(clock_select_name_t sel_name);
/**
* @brief Setup peripheral clock dividers.
* @param div_name : Clock divider name
* @param value : Value to be divided
* @return Nothing
*/
void CLOCK_SetClockDiv(clock_div_name_t div_name, uint32_t value);
/**
* @brief Get peripheral clock dividers.
* @param div_name : Clock divider name
* @return peripheral clock dividers
*/
uint32_t CLOCK_GetClockDiv(clock_div_name_t div_name);
/**
* @brief Halt peripheral clock dividers.
* @param div_name : Clock divider name
* @return Nothing
*/
void CLOCK_HaltClockDiv(clock_div_name_t div_name);
/**
* @brief Initialize the FROHF to given frequency (48,64,96,192).
* This function turns on FIRC and select the given frequency as the source of fro_hf
* @param iFreq : Desired frequency.
* @return returns success or fail status.
*/
status_t CLOCK_SetupFROHFClocking(uint32_t iFreq);
/**
* @brief Initialize the FRO12M.
* This function turns on FRO12M.
* @return returns success or fail status.
*/
status_t CLOCK_SetupFRO12MClocking(void);
/**
* @brief Initialize the FRO16K.
* This function turns on FRO16K.
* @param clk_16k_enable_mask: 0-3
* 0b00: disable both clk_16k0 and clk_16k1
* 0b01: only enable clk_16k0
* 0b10: only enable clk_16k1
* 0b11: enable both clk_16k0 and clk_16k1
* @return returns success or fail status.
*/
status_t CLOCK_SetupFRO16KClocking(uint8_t clk_16k_enable_mask);
/**
* @brief Initialize the external osc clock to given frequency.
* @param iFreq : Desired frequency (must be equal to exact rate in Hz)
* @return returns success or fail status.
*/
status_t CLOCK_SetupExtClocking(uint32_t iFreq);
/*! @brief Return Frequency of selected clock
* @return Frequency of selected clock
*/
uint32_t CLOCK_GetFreq(clock_name_t clockName);
/*! @brief Return Frequency of core
* @return Frequency of the core
*/
uint32_t CLOCK_GetCoreSysClkFreq(void);
/*! @brief Return Frequency of I3C FCLK
* @return Frequency of I3C FCLK.
*/
uint32_t CLOCK_GetI3CFClkFreq(void);
/*! @brief Return Frequency of CTimer functional Clock
* @return Frequency of CTimer functional Clock
*/
uint32_t CLOCK_GetCTimerClkFreq(uint32_t id);
/*! @brief Return Frequency of LPI2C0 functional Clock
* @return Frequency of LPI2C0 functional Clock
*/
uint32_t CLOCK_GetLpi2cClkFreq(void);
/*! @brief Return Frequency of LPSPI functional Clock
* @return Frequency of LPSPI functional Clock
*/
uint32_t CLOCK_GetLpspiClkFreq(uint32_t id);
/*! @brief Return Frequency of LPUART functional Clock
* @return Frequency of LPUART functional Clock
*/
uint32_t CLOCK_GetLpuartClkFreq(uint32_t id);
/*! @brief Return Frequency of LPTMR functional Clock
* @return Frequency of LPTMR functional Clock
*/
uint32_t CLOCK_GetLptmrClkFreq(void);
/*! @brief Return Frequency of OSTIMER
* @return Frequency of OSTIMER Clock
*/
uint32_t CLOCK_GetOstimerClkFreq(void);
/*! @brief Return Frequency of Adc Clock
* @return Frequency of Adc.
*/
uint32_t CLOCK_GetAdcClkFreq(void);
/*! @brief Return Frequency of CMP Function Clock
* @return Frequency of CMP Function.
*/
uint32_t CLOCK_GetCmpFClkFreq(uint32_t id);
/*! @brief Return Frequency of CMP Round Robin Clock
* @return Frequency of CMP Round Robin.
*/
uint32_t CLOCK_GetCmpRRClkFreq(uint32_t id);
/*! @brief Return Frequency of Trace Clock
* @return Frequency of Trace.
*/
uint32_t CLOCK_GetTraceClkFreq(void);
/*! @brief Return Frequency of CLKOUT Clock
* @return Frequency of CLKOUT.
*/
uint32_t CLOCK_GetClkoutClkFreq(void);
/*! @brief Return Frequency of Systick Clock
* @return Frequency of Systick.
*/
uint32_t CLOCK_GetSystickClkFreq(void);
/*! brief Return Frequency of Systick Clock
* return Frequency of Systick.
*/
uint32_t CLOCK_GetWwdtClkFreq(void);
/**
* @brief Setup FROHF trim.
* @param config : FROHF trim value
* @return returns success or fail status.
*/
status_t CLOCK_FROHFTrimConfig(firc_trim_config_t config);
/**
* @brief Setup FRO 12M trim.
* @param config : FRO 12M trim value
* @return returns success or fail status.
*/
status_t CLOCK_FRO12MTrimConfig(sirc_trim_config_t config);
/*!
* @brief Sets the system OSC monitor mode.
*
* This function sets the system OSC monitor mode. The mode can be disabled,
* it can generate an interrupt when the error is disabled, or reset when the error is detected.
*
* @param mode Monitor mode to set.
*/
void CLOCK_SetSysOscMonitorMode(scg_sosc_monitor_mode_t mode);
/*! brief Enable USB FS clock.
* Enable USB Full Speed clock.
*/
bool CLOCK_EnableUsbfsClock(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @} */
#endif /* _FSL_CLOCK_H_ */

View File

@ -0,0 +1,293 @@
/*
* Copyright 2022 ~ 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_cmc.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.mcx_cmc"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
#if (defined(FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG) && FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG)
#define CMC_SRAMDIS_RESERVED_MASK \
(~(kCMC_RAMX0 | kCMC_RAMX1 | kCMC_RAMX2 | kCMC_RAMB | kCMC_RAMC0 | kCMC_RAMC1 | kCMC_RAMD0 | kCMC_RAMD1 | \
kCMC_RAME0 | kCMC_RAME1 | kCMC_RAMF0 | kCMC_RAMF1 | kCMC_RAMG0_RAMG1 | kCMC_RAMG2_RAMG3 | kCMC_RAMH0_RAMH1 | \
kCMC_LPCAC | kCMC_DMA0_DMA1_PKC | kCMC_USB0 | kCMC_PQ | kCMC_CAN0_CAN1_ENET_USB1 | kCMC_FlexSPI))
#define CMC_SRAMRET_RESERVED_MASK (CMC_SRAMDIS_RESERVED_MASK)
#endif /* FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG */
/*******************************************************************************
* Variables
******************************************************************************/
static uint32_t g_savedPrimask;
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Sets clock mode.
*
* This function configs the amount of clock gating when the core asserts
* Sleeping due to WFI, WFE or SLEEPONEXIT.
*
* param base CMC peripheral base address.
* param mode System clock mode.
*/
void CMC_SetClockMode(CMC_Type *base, cmc_clock_mode_t mode)
{
uint32_t reg;
reg = base->CKCTRL;
reg &= ~CMC_CKCTRL_CKMODE_MASK;
reg |= CMC_CKCTRL_CKMODE((mode));
base->CKCTRL = reg;
}
/*!
* brief Configures all power mode protection settings.
*
* This function configures the power mode protection settings for
* supported power modes. This should be done before setting the lowPower mode
* for each power doamin.
*
* The allowed lowpower modes are passed as bit map. For example, to allow
* Sleep and DeepSleep, use CMC_SetPowerModeProtection(CMC_base, kCMC_AllowSleepMode|kCMC_AllowDeepSleepMode).
* To allow all low power modes, use CMC_SetPowerModeProtection(CMC_base, kCMC_AllowAllLowPowerModes).
*
* param base CMC peripheral base address.
* param allowedModes Bitmaps of the allowed power modes.
*/
void CMC_SetPowerModeProtection(CMC_Type *base, uint32_t allowedModes)
{
uint32_t reg;
reg = base->PMPROT;
reg &= ~0xFUL;
reg |= allowedModes;
base->PMPROT = reg;
}
/*!
* brief Configure reset pin.
*
* This function configures reset pin. When enabled, the low power filter is enabled in both
* Active and Low power modes, the reset filter is only enabled in Active mode. When both filers
* are enabled, they operate in series.
*
* param base CMC peripheral base address.
* param config Pointer to the reset pin config structure.
*/
void CMC_ConfigResetPin(CMC_Type *base, const cmc_reset_pin_config_t *config)
{
assert(config != NULL);
uint32_t reg = base->RPC;
if (config->lowpowerFilterEnable)
{
reg |= CMC_RPC_LPFEN_MASK;
}
else
{
reg &= ~CMC_RPC_LPFEN_MASK;
}
if (config->resetFilterEnable)
{
reg |= (CMC_RPC_FILTEN_MASK | CMC_RPC_FILTCFG(config->resetFilterWidth));
}
else
{
reg &= ~(CMC_RPC_FILTEN_MASK | CMC_RPC_FILTCFG_MASK);
}
base->RPC = reg;
}
#if (defined(FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG) && FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG)
/*!
* brief Power off the selected system SRAM always.
*
* This function powers off the selected system SRAM always. The SRAM arrays should
* not be accessed while they are shut down. SRAM array contents are not retained
* if they are powered off.
*
* param base CMC peripheral base address.
* param mask Bitmap of the SRAM arrays to be powered off all modes.
*/
void CMC_PowerOffSRAMAllMode(CMC_Type *base, uint32_t mask)
{
uint32_t reg = base->SRAMDIS[0];
reg &= ~(CMC_SRAMDIS_DIS_MASK | CMC_SRAMDIS_RESERVED_MASK);
reg |= CMC_SRAMDIS_DIS(mask);
base->SRAMDIS[0] = reg;
}
/*!
* brief Power off the selected system SRAm during low power mode only.
*
* This function powers off the selected system SRAM only during low power mode.
* SRAM array contents are not retained if they are power off.
*
* param base CMC peripheral base address.
* param mask Bitmap of the SRAM arrays to be power off during low power mode only.
*/
void CMC_PowerOffSRAMLowPowerOnly(CMC_Type *base, uint32_t mask)
{
uint32_t reg = base->SRAMRET[0];
reg &= ~(CMC_SRAMRET_RET_MASK | CMC_SRAMRET_RESERVED_MASK);
reg |= CMC_SRAMRET_RET(mask);
base->SRAMRET[0] = reg;
}
#endif /* FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG */
/*!
* brief Configs the low power mode of the on-chip flash memory.
*
* This function config the low power mode of the on-chip flash memory.
*
* param base CMC peripheral base address.
* param wake
* true - Flash will exit low power state during the flash memory accesses.
* false - No effect.
* param doze
* true - Flash is disabled while core is sleeping
* false - No effect.
* param disable
* true - Flash memory is placed in low power state.
* false - No effect.
*/
void CMC_ConfigFlashMode(CMC_Type *base, bool wake, bool doze, bool disable)
{
uint32_t reg = 0UL;
reg |= (disable ? CMC_FLASHCR_FLASHDIS(1U) : CMC_FLASHCR_FLASHDIS(0U)) |
(doze ? CMC_FLASHCR_FLASHDOZE(1U) : CMC_FLASHCR_FLASHDOZE(0U)) |
(wake ? CMC_FLASHCR_FLASHWAKE(1U) : CMC_FLASHCR_FLASHWAKE(0U));
base->FLASHCR = reg;
}
/*!
* brief Prepares to enter stop modes.
*
* This function should be called before entering low power modes.
*
*/
void CMC_PreEnterLowPowerMode(void)
{
g_savedPrimask = DisableGlobalIRQ();
__ISB();
}
/*!
* brief Recovers after wake up from stop modes.
*
* This function should be called after waking up from low power modes.
* This function should be used with CMC_PreEnterLowPowerMode()
*
*/
void CMC_PostExitLowPowerMode(void)
{
EnableGlobalIRQ(g_savedPrimask);
__ISB();
}
/*!
* brief Configs the entry into the same low power mode for each power domains.
*
* This function provides the feature to entry into the same low power mode for each power
* domains. Before invoking this function, please ensure the selected power mode have been allowed.
*
* param base CMC peripheral base address.
* param lowPowerMode The low power mode to be entered. See @ref cmc_low_power_mode_t for the details.
*
*/
void CMC_GlobalEnterLowPowerMode(CMC_Type *base, cmc_low_power_mode_t lowPowerMode)
{
/* Note: unlock the CKCTRL register if this API will be reinvoked later. */
CMC_SetClockMode(base, kCMC_GateAllSystemClocksEnterLowPowerMode);
CMC_SetGlobalPowerMode(base, lowPowerMode);
/* Before executing WFI instruction read back the last register to
* ensure all registers writes have completed. */
(void)base->GPMCTRL;
/* Set the core into DeepSleep mode. */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI();
__ISB();
}
/*!
* brief Configs the entry into different low power modes for each of the power domains.
*
* This function provides the feature to entry into different low power modes for
* each power domains. Before invoking this function please ensure the selected
* modes are allowed.
*
* param base CMC peripheral base address.
* param base config Pointer to the cmc_power_domain_config_t structure.
*/
void CMC_EnterLowPowerMode(CMC_Type *base, const cmc_power_domain_config_t *config)
{
assert(config != NULL);
#if (CMC_PMCTRL_COUNT > 1U)
/* The WAKE domain must never be configured to a lower power mode compared with main power mode. */
assert(config->wake_domain <= config->main_domain);
#endif /* (CMC_PMCTRL_COUNT > 1U) */
if (config->clock_mode < kCMC_GateAllSystemClocksEnterLowPowerMode)
{
/* In This case the power domain doesn't need to be placed in low power state. */
/* Note: unlock the register if this API will be reinvoked later. */
CMC_SetClockMode(base, config->clock_mode);
CMC_SetMAINPowerMode(base, kCMC_ActiveOrSleepMode);
#if (CMC_PMCTRL_COUNT > 1U)
CMC_SetWAKEPowerMode(base, kCMC_ActiveOrSleepMode);
#endif /* (CMC_PMCTRL_COUNT > 1U) */
/* Before executing WFI instruction read back the last register to
* ensure all registers writes have completed. */
(void)base->CKCTRL;
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI();
__ISB();
}
else
{
/* Note: unlock the register if this API will be reinvoked later. */
CMC_SetClockMode(base, kCMC_GateAllSystemClocksEnterLowPowerMode);
CMC_SetMAINPowerMode(base, config->main_domain);
#if (CMC_PMCTRL_COUNT > 1U)
CMC_SetWAKEPowerMode(base, config->wake_domain);
#endif /* (CMC_PMCTRL_COUNT > 1U) */
/* Before execute WFI instruction read back the last register to
* ensure all registers writes have completed. */
#if (CMC_PMCTRL_COUNT > 1U)
if ((CMC_GetWAKEPowerMode(base) == config->wake_domain) && (CMC_GetMAINPowerMode(base) == config->main_domain))
{
#endif /* (CMC_PMCTRL_COUNT > 1U) */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI();
__ISB();
#if (CMC_PMCTRL_COUNT > 1U)
}
#endif /* (CMC_PMCTRL_COUNT > 1U) */
}
}

View File

@ -0,0 +1,896 @@
/*
* Copyright 2022 ~ 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CMC_H_
#define _FSL_CMC_H_
#include "fsl_common.h"
/*!
* @addtogroup mcx_cmc
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief CMC driver version 2.1.0. */
#define FSL_CMC_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/* @} */
/*!
* @brief CMC power mode Protection enumeration.
*/
enum _cmc_power_mode_protection
{
kCMC_AllowDeepSleepMode = 0x1UL, /*!< Allow Deep Sleep mode. */
kCMC_AllowPowerDownMode = 0x2UL, /*!< Allow Power Down mode. */
kCMC_AllowDeepPowerDownMode = 0x8UL, /*!< Allow Deep Power Down mode. */
kCMC_AllowAllLowPowerModes = 0xFUL, /*!< Allow Deep Sleep, Power Down, Deep Power Down modes. */
};
/*!
* @brief Wake up sources from the previous low power mode entry.
*
* @note #kCMC_WakeupFromUsbFs, #kCMC_WakeupFromITRC, #kCMC_WakeupFromCpu1 are not supported in MCXA family.
*/
enum _cmc_wakeup_sources
{
kCMC_WakeupFromResetInterruptOrPowerDown =
CMC_CKSTAT_WAKEUP(1U << 0U), /*!< Wakeup source is reset interrupt, or wake up from Deep Power Down. */
kCMC_WakeupFromDebugReuqest = CMC_CKSTAT_WAKEUP(1U << 1U), /*!< Wakeup source is debug request. */
kCMC_WakeupFromInterrupt = CMC_CKSTAT_WAKEUP(1U << 2U), /*!< Wakeup source is interrupt. */
kCMC_WakeupFromDMAWakeup = CMC_CKSTAT_WAKEUP(1U << 3U), /*!< Wakeup source is DMA Wakeup. */
kCMC_WakeupFromWUURequest = CMC_CKSTAT_WAKEUP(1U << 4U), /*!< Wakeup source is WUU request. */
kCMC_WakeupFromUsbFs = CMC_CKSTAT_WAKEUP(1U << 5U), /*!< Wakeup source is USBFS(USB0). */
kCMC_WakeupFromITRC = CMC_CKSTAT_WAKEUP(1U << 6U), /*!< Wakeup source is ITRC. */
kCMC_WakeupFromCpu1 = CMC_CKSTAT_WAKEUP(1U << 7U), /*!< Wakeup source is CPU1. */
};
/*!
* @brief System Reset Interrupt enable enumeration.
*/
enum _cmc_system_reset_interrupt_enable
{
kCMC_PinResetInterruptEnable = CMC_SRIE_PIN_MASK, /*!< Pin Reset interrupt enable. */
kCMC_DAPResetInterruptEnable = CMC_SRIE_DAP_MASK, /*!< DAP Reset interrupt enable. */
kCMC_LowPowerAcknowledgeTimeoutResetInterruptEnable = CMC_SRIE_LPACK_MASK, /*!< Low Power Acknowledge Timeout
Reset interrupt enable. */
kCMC_WindowedWatchdog0ResetInterruptEnable = CMC_SRIE_WWDT0_MASK, /*!< Windowed Watchdog 0 reset
interrupt enable. */
kCMC_SoftwareResetInterruptEnable = CMC_SRIE_SW_MASK, /*!< Software Reset interrupt enable. */
kCMC_LockupResetInterruptEnable = CMC_SRIE_LOCKUP_MASK, /*!< Lockup Reset interrupt enable. */
#if defined(CMC_SRIE_CPU1_MASK)
kCMC_Cpu1ResetInterruptEnable = CMC_SRIE_CPU1_MASK, /*!< CPU1 Reset interrupt enable. */
#endif /* CMC_SRIE_CPU1_MASK */
#if defined(CMC_SRIE_VBAT_MASK)
kCMC_VBATResetInterruptEnable = CMC_SRIE_VBAT_MASK, /*!< VBAT reset interrupt enable. */
#endif /* CMC_SRIE_VBAT_MASK */
#if defined(CMC_SRIE_WWDT1_MASK)
kCMC_WindowedWatchdog1ResetInterruptEnable = CMC_SRIE_WWDT1_MASK, /*!< Windowed Watchdog 1 reset
interrupt enable. */
#endif /* CMC_SRIE_WWDT1_MASK */
kCMC_CodeWatchDog0ResetInterruptEnable = CMC_SRIE_CDOG0_MASK, /*!< Code watchdog 0 reset interrupt enable. */
#if defined(CMC_SRIE_CDOG1_MASK)
kCMC_CodeWatchDog1ResetInterruptEnable = CMC_SRIE_CDOG1_MASK, /*!< Code watchdog 1 reset interrupt enable. */
#endif /* CMC_SRIE_CDOG1_MASK */
};
/*!
* @brief CMC System Reset Interrupt Status flag.
*/
enum _cmc_system_reset_interrupt_flag
{
kCMC_PinResetInterruptFlag = CMC_SRIF_PIN_MASK, /*!< Pin Reset interrupt flag. */
kCMC_DAPResetInterruptFlag = CMC_SRIF_DAP_MASK, /*!< DAP Reset interrupt flag. */
kCMC_LowPowerAcknowledgeTimeoutResetFlag = CMC_SRIF_LPACK_MASK, /*!< Low Power Acknowledge
Timeout Reset interrupt flag. */
kCMC_WindowedWatchdog0ResetInterruptFlag = CMC_SRIF_WWDT0_MASK, /*!< Windowned Watchdog 0 Reset interrupt flag. */
kCMC_SoftwareResetInterruptFlag = CMC_SRIF_SW_MASK, /*!< Software Reset interrupt flag. */
kCMC_LockupResetInterruptFlag = CMC_SRIF_LOCKUP_MASK, /*!< Lock up Reset interrupt flag. */
#if defined(CMC_SRIF_CPU1_MASK)
kCMC_Cpu1ResetInterruptFlag = CMC_SRIF_CPU1_MASK, /*!< CPU1 Reset interrupt flag. */
#endif /* CMC_SRIF_CPU1_MASK */
#if defined(CMC_SRIF_VBAT_MASK)
kCMC_VbatResetInterruptFlag = CMC_SRIF_VBAT_MASK, /*!< VBAT system reset interrupt flag. */
#endif /* CMC_SRIF_VBAT_MASK */
#if defined(CMC_SRIF_WWDT1_MASK)
kCMC_WindowedWatchdog1ResetInterruptFlag = CMC_SRIF_WWDT1_MASK, /*!< Windowned Watchdog 1 Reset interrupt flag. */
#endif /* CMC_SRIF_WWDT1_MASK */
kCMC_CodeWatchdog0ResetInterruptFlag = CMC_SRIF_CDOG0_MASK, /*!< Code watchdog0 reset interrupt flag. */
#if defined(CMC_SRIF_CDOG1_MASK)
kCMC_CodeWatchdog1ResetInterruptFlag = CMC_SRIF_CDOG1_MASK, /*!< Code watchdog1 reset interrupt flag. */
#endif /* CMC_SRIF_CDOG1_MASK */
};
#if (defined(FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG) && FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG)
/*!
* @brief CMC System SRAM arrays low power mode enable enumeration.
*/
enum _cmc_system_sram_arrays
{
kCMC_RAMX0 = 1UL << 0UL, /*!< Used to control RAMX0. */
kCMC_RAMX1 = 1UL << 1UL, /*!< Used to control RAMX1. */
kCMC_RAMX2 = 1UL << 2UL, /*!< Used to control RAMX2. */
kCMC_RAMB = 1UL << 3UL, /*!< Used to control RAMB. */
kCMC_RAMC0 = 1UL << 4UL, /*!< Used to control RAMC0. */
kCMC_RAMC1 = 1UL << 5UL, /*!< Used to control RAMC1. */
kCMC_RAMD0 = 1UL << 6UL, /*!< Used to control RAMD0. */
kCMC_RAMD1 = 1UL << 7UL, /*!< Used to control RAMD1. */
kCMC_RAME0 = 1UL << 8UL, /*!< Used to control RAME0. */
kCMC_RAME1 = 1UL << 9UL, /*!< Used to control RAME1. */
kCMC_RAMF0 = 1UL << 10UL, /*!< Used to control RAMF0. */
kCMC_RAMF1 = 1UL << 11UL, /*!< Used to control RAMF1. */
kCMC_RAMG0_RAMG1 = 1UL << 12UL, /*!< Used to control RAMG0 and RAMG1. */
kCMC_RAMG2_RAMG3 = 1UL << 13UL, /*!< Used to control RAMG2 and RAMG3. */
kCMC_RAMH0_RAMH1 = 1UL << 14UL, /*!< Used to control RAMH0 and RAMH1. */
kCMC_LPCAC = 1UL << 24UL, /*!< Used to control LPCAC. */
kCMC_DMA0_DMA1_PKC = 1UL << 25UL, /*!< Used to control DMA0, DMA1 and PKC. */
kCMC_USB0 = 1UL << 26UL, /*!< Used to control USB0. */
kCMC_PQ = 1UL << 27UL, /*!< Used to control PQ. */
kCMC_CAN0_CAN1_ENET_USB1 = 1UL << 28UL, /*!< Used to control CAN0, CAN1, ENET, USB1. */
kCMC_FlexSPI = 1UL << 29UL, /*!< Used to control FlexSPI. */
};
#endif /* FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG */
/*!
* @brief System reset sources enumeration.
*/
enum _cmc_system_reset_sources
{
kCMC_WakeUpReset = CMC_SRS_WAKEUP_MASK, /*!< The reset caused by a wakeup from Power Down or
Deep Power Down mode. */
kCMC_PORReset = CMC_SRS_POR_MASK, /*!< The reset caused by power on reset detection logic. */
kCMC_VDReset = CMC_SRS_VD_MASK, /*!< The reset caused by an LVD or HVD. */
kCMC_WarmReset = CMC_SRS_WARM_MASK, /*!< The last reset source is a warm reset source. */
kCMC_FatalReset = CMC_SRS_FATAL_MASK, /*!< The last reset source is a fatal reset source. */
kCMC_PinReset = CMC_SRS_PIN_MASK, /*!< The reset caused by the RESET_b pin. */
kCMC_DAPReset = CMC_SRS_DAP_MASK, /*!< The reset caused by a reset request from the Debug Access port. */
kCMC_ResetTimeout = CMC_SRS_RSTACK_MASK, /*!< The reset caused by a timeout or other error condition in the system
reset generation. */
kCMC_LowPowerAcknowledgeTimeoutReset = CMC_SRS_LPACK_MASK, /*!< The reset caused by a timeout in
low power mode entry logic. */
kCMC_SCGReset = CMC_SRS_SCG_MASK, /*!< The reset caused by a loss of clock or loss of lock event in the SCG. */
kCMC_WindowedWatchdog0Reset = CMC_SRS_WWDT0_MASK, /*!< The reset caused by the Windowed WatchDog 0 timeout. */
kCMC_SoftwareReset = CMC_SRS_SW_MASK, /*!< The reset caused by a software reset request. */
kCMC_LockUoReset = CMC_SRS_LOCKUP_MASK, /*!< The reset caused by the ARM core indication of a LOCKUP event. */
#if defined(CMC_SRS_CPU1_MASK)
kCMC_Cpu1Reset = CMC_SRS_CPU1_MASK, /*!< The reset caused by a CPU1 system reset. */
#endif /* CMC_SRS_CPU1_MASK */
#if defined(CMC_SRS_VBAT_MASK)
kCMC_VbatReset = CMC_SRS_VBAT_MASK, /*!< The reset caused by a VBAT POR. */
#endif /* CMC_SRS_VBAT_MASK */
#if defined(CMC_SRS_WWDT1_MASK)
kCMC_WindowedWatchdog1Reset = CMC_SRS_WWDT1_MASK, /*!< The reset caused by the Windowed WatchDog 1 timeout. */
#endif /* CMC_SRS_WWDT1_MASK */
kCMC_CodeWatchDog0Reset = CMC_SRS_CDOG0_MASK, /*!< The reset caused by the code watchdog0 fault. */
#if defined(CMC_SRS_CDOG1_MASK)
kCMC_CodeWatchDog1Reset = CMC_SRS_CDOG1_MASK, /*!< The reset caused by the code watchdog1 fault. */
#endif /* CMC_SRS_CDOG1_MASK */
kCMC_JTAGSystemReset = CMC_SRS_JTAG_MASK, /*!< The reset caused by a JTAG system reset request. */
#if defined(CMC_SRS_SECVIO_MASK)
kCMC_SecurityViolationReset = CMC_SRS_SECVIO_MASK, /*!< The reset caused by a Security Violation logic. */
#endif /* CMC_SRS_SECVIO_MASK */
#if defined(CMC_SRS_TAMPER_MASK)
kCMC_TapmerReset = CMC_SRS_TAMPER_MASK, /*!< The reset caused by the tamper detection logic. */
#endif /* CMC_SRS_TAMPER_MASK */
};
/*!
* @brief Indicate the core clock was gated.
*/
typedef enum _cmc_core_clock_gate_status
{
kCMC_CoreClockNotGated = 0U, /*!< Core clock not gated. */
kCMC_CoreClockGated = 1U /*!< Core clock was gated due to low power mode entry. */
} cmc_core_clock_gate_status_t;
/*!
* @brief CMC clock mode enumeration.
*/
typedef enum _cmc_clock_mode
{
kCMC_GateNoneClock = 0x00U, /*!< No clock gating. */
kCMC_GateCoreClock = 0x01U, /*!< Gate Core clock. */
kCMC_GateCorePlatformClock = 0x03U, /*!< Gate Core clock and platform clock. */
kCMC_GateAllSystemClocks = 0x07U, /*!< Gate all System clocks, without getting core entering into low power mode. */
kCMC_GateAllSystemClocksEnterLowPowerMode = 0x0FU /*!< Gate all System clocks, with core
entering into low power mode. */
} cmc_clock_mode_t;
/*!
* @brief CMC power mode enumeration.
*/
typedef enum _cmc_low_power_mode
{
kCMC_ActiveOrSleepMode = 0x0U, /*!< Select Active/Sleep mode. */
kCMC_DeepSleepMode = 0x1U, /*!< Select Deep Sleep mode when a core executes WFI or WFE instruction. */
kCMC_PowerDownMode = 0x3U, /*!< Select Power Down mode when a core executes WFI or WFE instruction. */
kCMC_DeepPowerDown = 0xFU, /*!< Select Deep Power Down mode when a core executes WFI or WFE instruction. */
} cmc_low_power_mode_t;
/*!
* @brief CMC reset pin configuration.
*/
typedef struct _cmc_reset_pin_config
{
bool lowpowerFilterEnable; /*!< Low Power Filter enable. */
bool resetFilterEnable; /*!< Reset Filter enable. */
uint8_t resetFilterWidth; /*!< Width of the Reset Filter. */
} cmc_reset_pin_config_t;
/*!
* @brief power mode configuration for each power domain.
*/
typedef struct _cmc_power_domain_config
{
cmc_clock_mode_t clock_mode; /*!< Clock mode for each power domain. */
cmc_low_power_mode_t main_domain; /*!< The low power mode of the MAIN power domain. */
#if (CMC_PMCTRL_COUNT > 1U)
cmc_low_power_mode_t wake_domain; /*!< The low power mode of the WAKE power domain. */
#endif /* (CMC_PMCTRL_COUNT > 1U) */
} cmc_power_domain_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name CLOCK mode configuration.
* @{
*/
/*!
* @brief Sets clock mode.
*
* This function configs the amount of clock gating when the core asserts
* Sleeping due to WFI, WFE or SLEEPONEXIT.
*
* @param base CMC peripheral base address.
* @param mode System clock mode.
*/
void CMC_SetClockMode(CMC_Type *base, cmc_clock_mode_t mode);
/*!
* @brief Locks the clock mode setting.
*
* After invoking this function, any clock mode setting will be blocked.
*
* @param base CMC peripheral base address.
*/
static inline void CMC_LockClockModeSetting(CMC_Type *base)
{
base->CKCTRL |= CMC_CKCTRL_LOCK_MASK;
}
/* @} */
/*!
* @name Gets/Clears the Clock Mode, the wake up source, the Reset source.
* @{
*/
/*!
* @brief Gets the core clock gated status.
*
* This function get the status to indicate whether the core clock is gated.
* The core clock gated status can be cleared by software.
*
* @param base CMC peripheral base address.
* @return The status to indicate whether the core clock is gated.
*/
static inline cmc_core_clock_gate_status_t CMC_GetCoreClockGatedStatus(CMC_Type *base)
{
return (cmc_core_clock_gate_status_t)(uint32_t)((base->CKSTAT & CMC_CKSTAT_VALID_MASK) >> CMC_CKSTAT_VALID_SHIFT);
}
/*!
* @brief Clears the core clock gated status.
*
* This function clear clock status flag by software.
*
* @param base CMC peripheral base address.
*/
static inline void CMC_ClearCoreClockGatedStatus(CMC_Type *base)
{
base->CKSTAT |= CMC_CKSTAT_VALID_MASK;
}
/*!
* @brief Gets the Wakeup Source.
*
* This function gets the Wakeup sources from the previous low power mode entry.
*
* @param base CMC peripheral base address.
* @return The Wakeup sources from the previous low power mode entry. See @ref _cmc_wakeup_sources for details.
*/
static inline uint8_t CMC_GetWakeupSource(CMC_Type *base)
{
return ((uint8_t)((base->CKSTAT & CMC_CKSTAT_WAKEUP_MASK) >> CMC_CKSTAT_WAKEUP_SHIFT));
}
/*!
* @brief Gets the Clock mode.
*
* This function gets the clock mode of the previous low power mode entry.
*
* @param base CMC peripheral base address.
* @return The Low Power status.
*/
static inline cmc_clock_mode_t CMC_GetClockMode(CMC_Type *base)
{
return (cmc_clock_mode_t)(uint32_t)((base->CKSTAT & CMC_CKSTAT_CKMODE_MASK) >> CMC_CKSTAT_CKMODE_SHIFT);
}
/*!
* @brief Gets the System reset status.
*
* This function returns the system reset status. Those status
* updates on every MAIN Warm Reset to indicate the type/source
* of the most recent reset.
*
* @param base CMC peripheral base address.
* @return The most recent system reset status. See @ref _cmc_system_reset_sources for details.
*/
static inline uint32_t CMC_GetSystemResetStatus(CMC_Type *base)
{
return base->SRS;
}
/*!
* @brief Gets the sticky system reset status since the last WAKE Cold Reset.
*
* This function gets all source of system reset that have generated a
* system reset since the last WAKE Cold Reset, and that have not been
* cleared by software.
*
* @param base CMC peripheral base address.
* @return System reset status that have not been cleared by software. See @ref _cmc_system_reset_sources for details.
*/
static inline uint32_t CMC_GetStickySystemResetStatus(CMC_Type *base)
{
return base->SSRS;
}
/*!
* @brief Clears the sticky system reset status flags.
*
* @param base CMC peripheral base address.
* @param mask Bitmap of the sticky system reset status to be cleared.
*/
static inline void CMC_ClearStickySystemResetStatus(CMC_Type *base, uint32_t mask)
{
base->SSRS = mask;
}
#if (defined(FSL_FEATURE_MCX_CMC_HAS_RSTCNT_REG) && FSL_FEATURE_MCX_CMC_HAS_RSTCNT_REG)
/*!
* @brief Gets the number of reset sequences completed since the last Cold Reset.
*
* @param base CMC peripheral base address.
* @return The number of reset sequences.
*/
static inline uint8_t CMC_GetResetCount(CMC_Type *base)
{
return (uint8_t)(base->RSTCNT & CMC_RSTCNT_COUNT_MASK);
}
#endif /* FSL_FEATURE_MCX_CMC_HAS_RSTCNT_REG */
/* @} */
/*!
* @name Power mode configuration.
* @{
*/
/*!
* @brief Configures all power mode protection settings.
*
* This function configures the power mode protection settings for
* supported power modes. This should be done before set the lowPower mode
* for each power doamin.
*
* The allowed lowpower modes are passed as bit map. For example, to allow
* Sleep and DeepSleep, use CMC_SetPowerModeProtection(CMC_base, kCMC_AllowSleepMode|kCMC_AllowDeepSleepMode).
* To allow all low power modes, use CMC_SetPowerModeProtection(CMC_base, kCMC_AllowAllLowPowerModes).
*
* @param base CMC peripheral base address.
* @param allowedModes Bitmaps of the allowed power modes. See @ref _cmc_power_mode_protection for details.
*/
void CMC_SetPowerModeProtection(CMC_Type *base, uint32_t allowedModes);
/*!
* @brief Locks the power mode protection.
*
* This function locks the power mode protection. After invoking this function,
* any power mode protection setting will be ignored.
*
* @param base CMC peripheral base address.
*/
static inline void CMC_LockPowerModeProtectionSetting(CMC_Type *base)
{
base->PMPROT |= CMC_PMPROT_LOCK_MASK;
}
/*!
* @brief Config the same lowPower mode for all power domain.
*
* This function configures the same low power mode for MAIN power domian and WAKE power domain.
*
* @param base CMC peripheral base address.
* @param lowPowerMode The desired lowPower mode. See @ref cmc_low_power_mode_t for details.
*/
static inline void CMC_SetGlobalPowerMode(CMC_Type *base, cmc_low_power_mode_t lowPowerMode)
{
base->GPMCTRL = CMC_GPMCTRL_LPMODE((uint8_t)lowPowerMode);
}
/*!
* @brief Configures entry into low power mode for the MAIN Power domain.
*
* This function configures the low power mode for the MAIN power domian,
* when the core executes WFI/WFE instruction. The available lowPower modes
* are defined in the @ref cmc_low_power_mode_t.
*
* @param base CMC peripheral base address.
* @param lowPowerMode The desired lowPower mode. See @ref cmc_low_power_mode_t for details.
*
*/
static inline void CMC_SetMAINPowerMode(CMC_Type *base, cmc_low_power_mode_t lowPowerMode)
{
base->PMCTRL[0] = CMC_PMCTRL_LPMODE((uint8_t)lowPowerMode);
}
/*!
* @brief Gets the power mode of the MAIN Power domain.
*
* @param base CMC peripheral base address.
* @return The power mode of MAIN Power domain. See @ref cmc_low_power_mode_t for details.
*/
static inline cmc_low_power_mode_t CMC_GetMAINPowerMode(CMC_Type *base)
{
return (cmc_low_power_mode_t)(uint32_t)(base->PMCTRL[0] & CMC_PMCTRL_LPMODE_MASK);
}
#if (CMC_PMCTRL_COUNT > 1U)
/*!
* @brief Configure entry into low power mode for the WAKE Power domain.
*
* This function configures the low power mode for the WAKE power domian,
* when the core executes WFI/WFE instruction. The available lowPower mode
* are defined in the @ref cmc_low_power_mode_t.
*
* @note The lowPower Mode for the WAKE domain must not be configured to a
* lower power mode than any other power domain.
*
* @param base CMC peripheral base address.
* @param lowPowerMode The desired lowPower mode. See @ref cmc_low_power_mode_t for details.
*
*/
static inline void CMC_SetWAKEPowerMode(CMC_Type *base, cmc_low_power_mode_t lowPowerMode)
{
base->PMCTRL[1] = CMC_PMCTRL_LPMODE((uint8_t)lowPowerMode);
}
/*!
* @brief Gets the power mode of the WAKE Power domain.
*
* @param base CMC peripheral base address.
* @return The power mode of WAKE Power domain. See @ref cmc_low_power_mode_t for details.
*/
static inline cmc_low_power_mode_t CMC_GetWAKEPowerMode(CMC_Type *base)
{
return (cmc_low_power_mode_t)(uint32_t)(base->PMCTRL[1] & CMC_PMCTRL_LPMODE_MASK);
}
#endif /* CMC_PMCTRL_COUNT > 1U */
/* @} */
/*!
* @name Reset Pin configuration.
* @{
*/
/*!
* @brief Configure reset pin.
*
* This function configures reset pin. When enabled, the low power filter is enabled in both
* Active and Low power modes, the reset filter is only enabled in Active mode. When both filers
* are enabled, they operate in series.
*
* @param base CMC peripheral base address.
* @param config Pointer to the reset pin config structure.
*/
void CMC_ConfigResetPin(CMC_Type *base, const cmc_reset_pin_config_t *config);
/* @} */
/*!
* @name System Reset Interrupts.
* @{
*/
/*!
* @brief Enable system reset interrupts.
*
* This function enables the system reset interrupts. The assertion of
* non-fatal warm reset can be delayed for 258 cycles of the 32K_CLK clock
* while an enabled interrupt is generated. Then Software can perform a graceful
* shutdown or abort the non-fatal warm reset provided the pending reset source is cleared
* by resetting the reset source and then clearing the pending flag.
*
* @param base CMC peripheral base address.
* @param mask System reset interrupts. See @ref _cmc_system_reset_interrupt_enable for details.
*
*/
static inline void CMC_EnableSystemResetInterrupt(CMC_Type *base, uint32_t mask)
{
base->SRIE |= mask;
}
/*!
* @brief Disable system reset interrupts.
*
* This function disables the system reset interrupts.
*
* @param base CMC peripheral base address.
* @param mask System reset interrupts. See @ref _cmc_system_reset_interrupt_enable for details.
*/
static inline void CMC_DisableSystemResetInterrupt(CMC_Type *base, uint32_t mask)
{
base->SRIE &= (uint32_t)(~mask);
}
/*!
* @brief Gets System Reset interrupt flags.
*
* This function returns the System reset interrupt flags.
*
* @param base CMC peripheral base address.
* @return System reset interrupt flags. See @ref _cmc_system_reset_interrupt_flag for details.
*/
static inline uint32_t CMC_GetSystemResetInterruptFlags(CMC_Type *base)
{
return base->SRIF;
}
/*!
* @brief Clears System Reset interrupt flags.
*
* This function clears system reset interrupt flags. The pending reset source
* can be cleared by resetting the source of the reset and then clearing the pending
* flags.
*
* @param base CMC peripheral base address.
* @param mask System Reset interrupt flags. See @ref _cmc_system_reset_interrupt_flag for details.
*
*/
static inline void CMC_ClearSystemResetInterruptFlags(CMC_Type *base, uint32_t mask)
{
base->SRIF = mask;
}
/* @} */
/*!
* @name Non Maskable Pin interrupt.
* @{
*/
/*!
* @brief Enable/Disable Non maskable Pin interrupt.
*
* @param base CMC peripheral base address.
* @param enable Enable or disable Non maskable pin interrupt.
* true - enable Non-maskable pin interrupt.
* false - disable Non-maskable pin interupt.
*/
static inline void CMC_EnableNonMaskablePinInterrupt(CMC_Type *base, bool enable)
{
if (enable)
{
base->CORECTL |= CMC_CORECTL_NPIE_MASK;
}
else
{
base->CORECTL &= ~CMC_CORECTL_NPIE_MASK;
}
}
/* @} */
/*!
* @name Boot Configuration.
* @{
*/
/*!
* @brief Gets the logic state of the ISPMODE_n pin.
*
* This function returns the logic state of the ISPMODE_n pin
* on the last negation of RESET_b pin.
*
* @param base CMC peripheral base address.
* @return The logic state of the ISPMODE_n pin on the last negation of RESET_b pin.
*/
static inline uint8_t CMC_GetISPMODEPinLogic(CMC_Type *base)
{
return (uint8_t)((base->MR[0] & CMC_MR_ISPMODE_n_MASK) >> CMC_MR_ISPMODE_n_SHIFT);
}
/*!
* @brief Clears ISPMODE_n pin state.
*
* @param base CMC peripheral base address.
*/
static inline void CMC_ClearISPMODEPinLogic(CMC_Type *base)
{
base->MR[0] = CMC_MR_ISPMODE_n_MASK;
}
/*!
* @brief Set the logic state of the BOOT_CONFIGn pin.
*
* This function force the logic state of the Boot_Confign pin to assert
* on next system reset.
*
* @param base CMC peripheral base address.
* @param assert Assert the corresponding pin or not.
* true - Assert corresponding pin on next system reset.
* false - No effect.
*/
static inline void CMC_ForceBootConfiguration(CMC_Type *base, bool assert)
{
if (assert)
{
base->FM[0] |= CMC_FM_FORCECFG_MASK;
}
else
{
base->FM[0] &= ~CMC_FM_FORCECFG_MASK;
}
}
/* @} */
/*!
* @name BootROM Status.
* @{
*/
#if (defined(FSL_FEATURE_MCX_CMC_HAS_BSR_REG) && FSL_FEATURE_MCX_CMC_HAS_BSR_REG)
/*!
* @brief Gets the status information written by the BootROM.
*
* @param base CMC peripheral base address.
* @return The status information written by the BootROM.
*/
static inline uint32_t CMC_GetBootRomStatus(CMC_Type *base)
{
return base->BSR;
}
/*!
* @brief Sets the bootROM status value.
*
* @note This function is useful when result of CMC_CheckBootRomRegisterWrittable() is true.
*
* @param base CMC peripheral base address.
* @param stat The state value to set.
*/
static inline void CMC_SetBootRomStatus(CMC_Type *base, uint32_t statValue)
{
base->BSR = CMC_BSR_STAT(statValue);
}
#endif /* FSL_FEATURE_MCX_CMC_HAS_BSR_REG */
#if (defined(FSL_FEATURE_MCX_CMC_HAS_BLR_REG) && FSL_FEATURE_MCX_CMC_HAS_BLR_REG)
/*!
* @brief Check if BootROM status and lock registers is writtable.
*
* @param base CMC peripheral base address.
* @return The result of whether BootROM status and lock register is writtable.
* - \b true BootROM status and lock registers are writtable;
* - \b false BootROM status and lock registers are not writtable.
*/
static inline bool CMC_CheckBootRomRegisterWrittable(CMC_Type *base)
{
return (base->BLR == 0x2UL);
}
/*!
* @brief After invoking this function, BootROM status and lock registers cannot be written.
*
* @param base CMC peripheral base address.
*/
static inline void CMC_LockBootRomStatusWritten(CMC_Type *base)
{
base->BLR = CMC_BLR_LOCK(0x5U);
}
/*!
* @brief After invoking this function, BootROM status and lock register can be written.s
*
* @param base
*/
static inline void CMC_UnlockBootRomStatusWritten(CMC_Type *base)
{
base->BLR = CMC_BLR_LOCK(0x2U);
}
#endif /* FSL_FEATURE_MCX_CMC_HAS_BLR_REG */
/* @} */
#if (defined(FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG) && FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG)
/*!
* @name System SRAM Configuration.
* @{
*/
/*!
* @brief Power off the selected system SRAM always.
*
* This function power off the selected system SRAM always. The SRAM arrays should
* not be accessed while they are shut down. SRAM array contents are not retained
* if they are powered off.
*
* @param base CMC peripheral base address.
* @param mask Bitmap of the SRAM arrays to be powered off all modes.
* See @ref _cmc_system_sram_arrays for details.
* Check Reference Manual for the SRAM region and mask bit relationship.
*/
void CMC_PowerOffSRAMAllMode(CMC_Type *base, uint32_t mask);
/*!
* @brief Power on SRAM during all mode.
*
* @param base CMC peripheral base address.
* @param mask Bitmap of the SRAM arrays to be powered on all modes.
* See @ref _cmc_system_sram_arrays for details.
* Check Reference Manual for the SRAM region and mask bit relationship.
*/
static inline void CMC_PowerOnSRAMAllMode(CMC_Type *base, uint32_t mask)
{
base->SRAMDIS[0] &= CMC_SRAMDIS_DIS((uint32_t)(~mask));
}
/*!
* @brief Power off the selected system SRAM during low power modes only.
*
* This function power off the selected system SRAM only during low power mode.
* SRAM array contents are not retained if they are power off.
*
* @param base CMC peripheral base address.
* @param mask Bitmap of the SRAM arrays to be power off during low power mode only.
* See @ref _cmc_system_sram_arrays for details.
* Check Reference Manual for the SRAM region and mask bit relationship.
*/
void CMC_PowerOffSRAMLowPowerOnly(CMC_Type *base, uint32_t mask);
/*!
* @brief Power on the selected system SRAM during low power modes only.
*
* This function power on the selected system SRAM. The SRAM arrray contents are
* retained in low power modes.
*
* @param base CMC peripheral base address.
* @param mask Bitmap of the SRAM arrays to be power on during low power mode only.
* See @ref _cmc_system_sram_arrays for details.
* Check Reference Manual for the SRAM region and mask bit relationship.
*/
static inline void CMC_PowerOnSRAMLowPowerOnly(CMC_Type *base, uint32_t mask)
{
base->SRAMRET[0] &= CMC_SRAMRET_RET((uint32_t)(~mask));
}
/* @} */
#endif /* FSL_FEATURE_MCX_CMC_HAS_SRAM_DIS_REG */
/*!
* @name Flash Low Power Mode configuration.
* @{
*/
/*!
* @brief Configs the low power mode of the on-chip flash memory.
*
* This function configs the low power mode of the on-chip flash memory.
*
* @param base CMC peripheral base address.
* @param wake true: Flash will exit low power state during the flash memory accesses.
* false: No effect.
* @param doze true: Flash is disabled while core is sleeping
* false: No effect.
* @param disable true: Flash memory is placed in low power state.
* false: No effect.
*/
void CMC_ConfigFlashMode(CMC_Type *base, bool wake, bool doze, bool disable);
/* @} */
/*!
* @name Debug Configuration.
*/
/*!
* @brief Enables/Disables debug Operation when the core sleep.
*
* This function configs what happens to debug when core sleeps.
*
* @param base CMC peripheral base address.
* @param enable Enable or disable Debug when Core is sleeping.
* true - Debug remains enabled when the core is sleeping.
* false - Debug is disabled when the core is sleeping.
*/
static inline void CMC_EnableDebugOperation(CMC_Type *base, bool enable)
{
if (enable)
{
base->DBGCTL &= ~CMC_DBGCTL_SOD_MASK;
}
else
{
base->DBGCTL |= CMC_DBGCTL_SOD_MASK;
}
}
/* @} */
/*!
* @name Low Power modes enter.
* @{
*/
/*!
* @brief Prepares to enter low power modes.
*
* This function should be called before entering low power modes.
*
*/
void CMC_PreEnterLowPowerMode(void);
/*!
* @brief Recovers after wake up from low power modes.
*
* This function should be called after wake up from low power modes.
* This function should be used with CMC_PreEnterLowPowerMode()
*
*/
void CMC_PostExitLowPowerMode(void);
/*!
* @brief Configs the entry into the same low power mode for each power domains.
*
* This function provides the feature to entry into the same low power mode for each power
* domains. Before invoking this function, please ensure the selected power mode have been allowed.
*
* @param base CMC peripheral base address.
* @param lowPowerMode The low power mode to be entered. See @ref cmc_low_power_mode_t for the details.
*
*/
void CMC_GlobalEnterLowPowerMode(CMC_Type *base, cmc_low_power_mode_t lowPowerMode);
/*!
* @brief Configs the entry into different low power modes for each power domains.
*
* This function provides the feature to entry into different low power modes for
* each power domains. Before invoking this function please ensure the selected
* modes are allowed.
*
* @param base CMC peripheral base address.
* @param config Pointer to the cmc_power_domain_config_t structure.
*/
void CMC_EnterLowPowerMode(CMC_Type *base, const cmc_power_domain_config_t *config);
/* @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/
#endif /* _FSL_CMC_H_ */

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#define SDK_MEM_MAGIC_NUMBER 12345U
typedef struct _mem_align_control_block
{
uint16_t identifier; /*!< Identifier for the memory control block. */
uint16_t offset; /*!< offset from aligned address to real address */
} mem_align_cb_t;
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.common"
#endif
#if !((defined(__DSC__) && defined(__CW__)))
void *SDK_Malloc(size_t size, size_t alignbytes)
{
mem_align_cb_t *p_cb = NULL;
uint32_t alignedsize;
/* Check overflow. */
alignedsize = (uint32_t)(unsigned int)SDK_SIZEALIGN(size, alignbytes);
if (alignedsize < size)
{
return NULL;
}
if (alignedsize > SIZE_MAX - alignbytes - sizeof(mem_align_cb_t))
{
return NULL;
}
alignedsize += alignbytes + (uint32_t)sizeof(mem_align_cb_t);
union
{
void *pointer_value;
uintptr_t unsigned_value;
} p_align_addr, p_addr;
p_addr.pointer_value = malloc((size_t)alignedsize);
if (p_addr.pointer_value == NULL)
{
return NULL;
}
p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);
p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
return p_align_addr.pointer_value;
}
void SDK_Free(void *ptr)
{
union
{
void *pointer_value;
uintptr_t unsigned_value;
} p_free;
p_free.pointer_value = ptr;
mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U);
if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
{
return;
}
p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;
free(p_free.pointer_value);
}
#endif

View File

@ -0,0 +1,322 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_COMMON_H_
#define _FSL_COMMON_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#if defined(__ICCARM__) || (defined(__CC_ARM) || defined(__ARMCC_VERSION)) || defined(__GNUC__)
#include <stddef.h>
#endif
#include "fsl_device_registers.h"
/*!
* @addtogroup ksdk_common
* @{
*/
/*******************************************************************************
* Configurations
******************************************************************************/
/*! @brief Macro to use the default weak IRQ handler in drivers. */
#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Construct a status code value from a group and code number. */
#define MAKE_STATUS(group, code) ((((group)*100L) + (code)))
/*! @brief Construct the version number for drivers.
*
* The driver version is a 32-bit number, for both 32-bit platforms(such as Cortex M)
* and 16-bit platforms(such as DSC).
*
* @verbatim
| Unused || Major Version || Minor Version || Bug Fix |
31 25 24 17 16 9 8 0
@endverbatim
*/
#define MAKE_VERSION(major, minor, bugfix) (((major)*65536L) + ((minor)*256L) + (bugfix))
/*! @name Driver version */
/*@{*/
/*! @brief common driver version. */
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 4, 0))
/*@}*/
/* Debug console type definition. */
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */
#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */
#define DEBUG_CONSOLE_DEVICE_TYPE_QSCI 10U /*!< Debug console based on QSCI. */
/*! @brief Status group numbers. */
enum _status_groups
{
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */
kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */
kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */
kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/
kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */
kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */
kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */
kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */
kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */
kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/
kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/
kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/
kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/
kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */
kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */
kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */
kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */
kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */
kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */
kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */
kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */
kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */
kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */
kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */
kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */
kStatusGroup_SFA = 103, /*!< Group number for SFA status codes*/
kStatusGroup_SPC = 104, /*!< Group number for SPC status codes. */
kStatusGroup_PUF = 105, /*!< Group number for PUF status codes. */
kStatusGroup_TOUCH_PANEL = 106, /*!< Group number for touch panel status codes */
kStatusGroup_VBAT = 107, /*!< Group number for VBAT status codes */
kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */
kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */
kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */
kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */
kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */
kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */
kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */
kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */
kStatusGroup_HAL_I2S = 129, /*!< Group number for HAL I2S status codes. */
kStatusGroup_HAL_ADC_SENSOR = 130, /*!< Group number for HAL ADC SENSOR status codes. */
kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */
kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */
kStatusGroup_LED = 137, /*!< Group number for LED status codes. */
kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */
kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */
kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */
kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */
kStatusGroup_LIST = 142, /*!< Group number for List status codes. */
kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */
kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */
kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */
kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */
kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/
kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */
kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */
kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */
kStatusGroup_SDIOSLV = 151, /*!< Group number for SDIOSLV status codes. */
kStatusGroup_MECC = 152, /*!< Group number for MECC status codes. */
kStatusGroup_ENET_QOS = 153, /*!< Group number for ENET_QOS status codes. */
kStatusGroup_LOG = 154, /*!< Group number for LOG status codes. */
kStatusGroup_I3CBUS = 155, /*!< Group number for I3CBUS status codes. */
kStatusGroup_QSCI = 156, /*!< Group number for QSCI status codes. */
kStatusGroup_SNT = 157, /*!< Group number for SNT status codes. */
kStatusGroup_QUEUEDSPI = 158, /*!< Group number for QSPI status codes. */
kStatusGroup_POWER_MANAGER = 159, /*!< Group number for POWER_MANAGER status codes. */
kStatusGroup_IPED = 160, /*!< Group number for IPED status codes. */
kStatusGroup_ELS_PKC = 161, /*!< Group number for ELS PKC status codes. */
kStatusGroup_CSS_PKC = 162, /*!< Group number for CSS PKC status codes. */
kStatusGroup_HOSTIF = 163, /*!< Group number for HOSTIF status codes. */
kStatusGroup_CLIF = 164, /*!< Group number for CLIF status codes. */
kStatusGroup_BMA = 165, /*!< Group number for BMA status codes. */
kStatusGroup_NETC = 166, /*!< Group number for NETC status codes. */
kStatusGroup_ELE = 167, /*!< Group number for ELE status codes. */
kStatusGroup_GLIKEY = 168, /*!< Group number for GLIKEY status codes. */
};
/*! \public
* @brief Generic status return codes.
*/
enum
{
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< Generic status for Success. */
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< Generic status for Fail. */
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< Generic status for read only failure. */
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< Generic status for out of range access. */
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Generic status for invalid argument check. */
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Generic status for timeout. */
kStatus_NoTransferInProgress =
MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Generic status for no transfer in progress. */
kStatus_Busy = MAKE_STATUS(kStatusGroup_Generic, 7), /*!< Generic status for module is busy. */
kStatus_NoData =
MAKE_STATUS(kStatusGroup_Generic, 8), /*!< Generic status for no data is found for the operation. */
};
/*! @brief Type used for all status and error return values. */
typedef int32_t status_t;
/*!
* @name Min/max macros
* @{
*/
#if !defined(MIN)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#if !defined(MAX)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/* @} */
/*! @brief Computes the number of elements in an array. */
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/*! @name UINT16_MAX/UINT32_MAX value */
/* @{ */
#if !defined(UINT16_MAX)
#define UINT16_MAX ((uint16_t)-1)
#endif
#if !defined(UINT32_MAX)
#define UINT32_MAX ((uint32_t)-1)
#endif
/* @} */
/*! @name Suppress fallthrough warning macro */
/* For switch case code block, if case section ends without "break;" statement, there wil be
fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
case section which misses "break;"statement.
*/
/* @{ */
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__((fallthrough))
#else
#define SUPPRESS_FALL_THROUGH_WARNING()
#endif
/* @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
#if !((defined(__DSC__) && defined(__CW__)))
/*!
* @brief Allocate memory with given alignment and aligned size.
*
* This is provided to support the dynamically allocated memory
* used in cache-able region.
* @param size The length required to malloc.
* @param alignbytes The alignment size.
* @retval The allocated memory.
*/
void *SDK_Malloc(size_t size, size_t alignbytes);
/*!
* @brief Free memory.
*
* @param ptr The memory to be release.
*/
void SDK_Free(void *ptr);
#endif
/*!
* @brief Delay at least for some time.
* Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
* if precise delay count was needed, please implement a new delay function with hardware timer.
*
* @param delayTime_us Delay time in unit of microsecond.
* @param coreClock_Hz Core clock frequency with Hz.
*/
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz);
#if defined(__cplusplus)
}
#endif
/*! @} */
#if (defined(__DSC__) && defined(__CW__))
#include "fsl_common_dsc.h"
#elif defined(__XTENSA__)
#include "fsl_common_dsp.h"
#else
#include "fsl_common_arm.h"
#endif
#endif /* _FSL_COMMON_H_ */

View File

@ -0,0 +1,249 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.common_arm"
#endif
#ifndef __GIC_PRIO_BITS
#if defined(ENABLE_RAM_VECTOR_TABLE)
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
{
#ifdef __VECTOR_TABLE
#undef __VECTOR_TABLE
#endif
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
extern uint32_t Image$$VECTOR_ROM$$Base[];
extern uint32_t Image$$VECTOR_RAM$$Base[];
extern uint32_t Image$$RW_m_data$$Base[];
#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
#elif defined(__ICCARM__)
extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
#elif defined(__GNUC__)
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */
uint32_t n;
uint32_t ret;
uint32_t irqMaskValue;
irqMaskValue = DisableGlobalIRQ();
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
{
/* Copy the vector table from ROM to RAM */
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
{
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
}
/* Point the VTOR to the position of vector table */
SCB->VTOR = (uint32_t)__VECTOR_RAM;
}
ret = __VECTOR_RAM[(int32_t)irq + 16];
/* make sure the __VECTOR_RAM is noncachable */
__VECTOR_RAM[(int32_t)irq + 16] = irqHandler;
EnableGlobalIRQ(irqMaskValue);
return ret;
}
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#endif /* __GIC_PRIO_BITS. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
* powerlib should be used instead of these functions.
*/
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
/*
* When the SYSCON STARTER registers are discontinuous, these functions are
* implemented in fsl_power.c.
*/
#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERSET[index] = 1UL << intNumber;
(void)EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
void DisableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t intNumber = (uint32_t)interrupt;
(void)DisableIRQ(interrupt); /* also disable interrupt at NVIC */
uint32_t index = 0;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERCLR[index] = 1UL << intNumber;
}
#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#if defined(DWT)
/* Use WDT. */
void MSDK_EnableCpuCycleCounter(void)
{
/* Make sure the DWT trace fucntion is enabled. */
if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR))
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
}
/* CYCCNT not supported on this device. */
assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
/* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL))
{
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
uint32_t MSDK_GetCpuCycleCount(void)
{
return DWT->CYCCNT;
}
#endif /* defined(DWT) */
#if !(defined(SDK_DELAY_USE_DWT) && defined(DWT))
/* Use software loop. */
#if defined(__CC_ARM) /* This macro is arm v5 specific */
/* clang-format off */
__ASM static void DelayLoop(uint32_t count)
{
loop
SUBS R0, R0, #1
CMP R0, #0
BNE loop
BX LR
}
#elif defined(__ARM_ARCH_8A__) /* This macro is ARMv8-A specific */
static void DelayLoop(uint32_t count)
{
__ASM volatile(" MOV X0, %0" : : "r"(count));
__ASM volatile(
"loop: \n"
" SUB X0, X0, #1 \n"
" CMP X0, #0 \n"
" BNE loop \n"
:
:
: "r0");
}
/* clang-format on */
#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)
/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,
* use SUB and CMP here for compatibility */
static void DelayLoop(uint32_t count)
{
__ASM volatile(" MOV R0, %0" : : "r"(count));
__ASM volatile(
"loop: \n"
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
" SUB R0, R0, #1 \n"
#else
" SUBS R0, R0, #1 \n"
#endif
" CMP R0, #0 \n"
" BNE loop \n"
:
:
: "r0");
}
#endif /* defined(__CC_ARM) */
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
/*!
* @brief Delay at least for some time.
* Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have
* effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delayTime_us and
* coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delayTime_us only supports
* up to 4294967 in current code. If long time delay is needed, please implement a new delay function.
*
* @param delayTime_us Delay time in unit of microsecond.
* @param coreClock_Hz Core clock frequency with Hz.
*/
void SDK_DelayAtLeastUs(uint32_t delayTime_us, uint32_t coreClock_Hz)
{
uint64_t count;
if (delayTime_us > 0U)
{
count = USEC_TO_COUNT(delayTime_us, coreClock_Hz);
assert(count <= UINT32_MAX);
#if defined(SDK_DELAY_USE_DWT) && defined(DWT) /* Use DWT for better accuracy */
MSDK_EnableCpuCycleCounter();
/* Calculate the count ticks. */
count += MSDK_GetCpuCycleCount();
if (count > UINT32_MAX)
{
count -= UINT32_MAX;
/* Wait for cyccnt overflow. */
while (count < MSDK_GetCpuCycleCount())
{
}
}
/* Wait for cyccnt reach count value. */
while (count > MSDK_GetCpuCycleCount())
{
}
#else
/* Divide value may be different in various environment to ensure delay is precise.
* Every loop count includes three instructions, due to Cortex-M7 sometimes executes
* two instructions in one period, through test here set divide 1.5. Other M cores use
* divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
* not matter because other instructions outside while loop is enough to fill the time.
*/
#if (__CORTEX_M == 7)
count = count / 3U * 2U;
#else
count = count / 4U;
#endif
DelayLoop((uint32_t)count);
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
}
}

View File

@ -0,0 +1,842 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_COMMON_ARM_H_
#define _FSL_COMMON_ARM_H_
/*
* For CMSIS pack RTE.
* CMSIS pack RTE generates "RTC_Components.h" which contains the statements
* of the related <RTE_Components_h> element for all selected software components.
*/
#ifdef _RTE_
#include "RTE_Components.h"
#endif
/*!
* @addtogroup ksdk_common
* @{
*/
/*! @name Atomic modification
*
* These macros are used for atomic access, such as read-modify-write
* to the peripheral registers.
*
* - SDK_ATOMIC_LOCAL_ADD
* - SDK_ATOMIC_LOCAL_SET
* - SDK_ATOMIC_LOCAL_CLEAR
* - SDK_ATOMIC_LOCAL_TOGGLE
* - SDK_ATOMIC_LOCAL_CLEAR_AND_SET
*
* Take SDK_ATOMIC_LOCAL_CLEAR_AND_SET as an example: the parameter @c addr
* means the address of the peripheral register or variable you want to modify
* atomically, the parameter @c clearBits is the bits to clear, the parameter
* @c setBits it the bits to set.
* For example, to set a 32-bit register bit1:bit0 to 0b10, use like this:
*
* @code
volatile uint32_t * reg = (volatile uint32_t *)REG_ADDR;
SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, 0x03, 0x02);
@endcode
*
* In this example, the register bit1:bit0 are cleared and bit1 is set, as a result,
* register bit1:bit0 = 0b10.
*
* @note For the platforms don't support exclusive load and store, these macros
* disable the global interrupt to pretect the modification.
*
* @note These macros only guarantee the local processor atomic operations. For
* the multi-processor devices, use hardware semaphore such as SEMA42 to
* guarantee exclusive access if necessary.
*
* @{
*/
/* clang-format off */
#if ((defined(__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined(__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
(defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1)))
/* clang-format on */
/* If the LDREX and STREX are supported, use them. */
#define _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXB(addr); \
(ops); \
} while (0UL != __STREXB((val), (addr)))
#define _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXH(addr); \
(ops); \
} while (0UL != __STREXH((val), (addr)))
#define _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, val, ops) \
do \
{ \
(val) = __LDREXW(addr); \
(ops); \
} while (0UL != __STREXW((val), (addr)))
static inline void _SDK_AtomicLocalAdd1Byte(volatile uint8_t *addr, uint8_t val)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalAdd2Byte(volatile uint16_t *addr, uint16_t val)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalAdd4Byte(volatile uint32_t *addr, uint32_t val)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val += val);
}
static inline void _SDK_AtomicLocalSub1Byte(volatile uint8_t *addr, uint8_t val)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSub2Byte(volatile uint16_t *addr, uint16_t val)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSub4Byte(volatile uint32_t *addr, uint32_t val)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val -= val);
}
static inline void _SDK_AtomicLocalSet1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalSet2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalSet4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val |= bits);
}
static inline void _SDK_AtomicLocalClear1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalClear2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalClear4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val &= ~bits);
}
static inline void _SDK_AtomicLocalToggle1Byte(volatile uint8_t *addr, uint8_t bits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalToggle2Byte(volatile uint16_t *addr, uint16_t bits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalToggle4Byte(volatile uint32_t *addr, uint32_t bits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val ^= bits);
}
static inline void _SDK_AtomicLocalClearAndSet1Byte(volatile uint8_t *addr, uint8_t clearBits, uint8_t setBits)
{
uint8_t s_val;
_SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
static inline void _SDK_AtomicLocalClearAndSet2Byte(volatile uint16_t *addr, uint16_t clearBits, uint16_t setBits)
{
uint16_t s_val;
_SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
static inline void _SDK_AtomicLocalClearAndSet4Byte(volatile uint32_t *addr, uint32_t clearBits, uint32_t setBits)
{
uint32_t s_val;
_SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
}
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
((1UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalAdd1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(val)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(val)) : \
_SDK_AtomicLocalAdd4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(val))))
#define SDK_ATOMIC_LOCAL_SUB(addr, val) \
((1UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalSub1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(val)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSub2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(val)) : \
_SDK_AtomicLocalSub4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(val))))
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
((1UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalSet1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
_SDK_AtomicLocalSet4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
((1UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalClear1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
((2UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalClear2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
_SDK_AtomicLocalClear4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
((1UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalToggle1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
((2UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalToggle2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
_SDK_AtomicLocalToggle4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
((1UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalClearAndSet1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(clearBits), (uint8_t)(setBits)) : \
((2UL == sizeof(*(addr))) ? \
_SDK_AtomicLocalClearAndSet2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(clearBits), (uint16_t)(setBits)) : \
_SDK_AtomicLocalClearAndSet4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(clearBits), (uint32_t)(setBits))))
#else
#define SDK_ATOMIC_LOCAL_ADD(addr, val) \
do \
{ \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) += (val); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_SUB(addr, val) \
do \
{ \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) -= (val); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_SET(addr, bits) \
do \
{ \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) |= (bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
do \
{ \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) &= ~(bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
do \
{ \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) ^= (bits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
do \
{ \
uint32_t s_atomicOldInt; \
s_atomicOldInt = DisableGlobalIRQ(); \
*(addr) = (*(addr) & ~(clearBits)) | (setBits); \
EnableGlobalIRQ(s_atomicOldInt); \
} while (0)
#endif
/* @} */
/*! @name Timer utilities */
/* @{ */
/*! Macro to convert a microsecond period to raw count value */
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
/*! Macro to convert a raw count value to microsecond */
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count)*1000000U / (clockFreqInHz))
/*! Macro to convert a millisecond period to raw count value */
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U)
/*! Macro to convert a raw count value to millisecond */
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count)*1000U / (clockFreqInHz))
/* @} */
/*! @name ISR exit barrier
* @{
*
* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
* exception return operation might vector to incorrect interrupt.
* For Cortex-M7, if core speed much faster than peripheral register write speed,
* the peripheral interrupt flags may be still set after exiting ISR, this results to
* the same error similar with errata 83869.
*/
#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
#define SDK_ISR_EXIT_BARRIER __DSB()
#else
#define SDK_ISR_EXIT_BARRIER
#endif
/* @} */
/*! @name Alignment variable definition macros */
/* @{ */
#if (defined(__ICCARM__))
/*
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
* http:/ /supp.iar.com/Support/?note=24725
*/
_Pragma("diag_suppress=Pm120")
#define SDK_PRAGMA(x) _Pragma(#x)
_Pragma("diag_error=Pm120")
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
#elif defined(__GNUC__)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
#else
#error Toolchain not supported
#endif
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#endif
/*! Macro to change a value to a given size aligned value */
#define SDK_SIZEALIGN(var, alignbytes) \
((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
/* @} */
/*! @name Non-cacheable region definition macros */
/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
* "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable
* variables, please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them,
* these zero-inited variables will be initialized to zero in system startup.
*/
/* @{ */
#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && \
defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
#if (defined(__ICCARM__))
#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
#if (defined(__CC_ARM))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
#else
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var
#endif
#elif (defined(__GNUC__))
/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
* in your projects to make sure the non-cacheable section variables will be initialized in system startup.
*/
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
#else
#error Toolchain not supported.
#endif
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_ALIGN(var, alignbytes)
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_ALIGN(var, alignbytes)
#endif
/* @} */
/*!
* @name Time sensitive region
* @{
*/
#if (defined(__ICCARM__))
#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
#define AT_QUICKACCESS_SECTION_DATA(var) var @"DataQuickAccess"
#define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
SDK_PRAGMA(data_alignment = alignbytes) var @"DataQuickAccess"
#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(var) __attribute__((section("DataQuickAccess"))) var
#define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
__attribute__((section("DataQuickAccess"))) __attribute__((aligned(alignbytes))) var
#elif (defined(__GNUC__))
#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
#define AT_QUICKACCESS_SECTION_DATA(var) __attribute__((section("DataQuickAccess"))) var
#define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
__attribute__((section("DataQuickAccess"))) var __attribute__((aligned(alignbytes)))
#else
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
/*! @name Ram Function */
#if (defined(__ICCARM__))
#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
#elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
#elif (defined(__GNUC__))
#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
#else
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
/* @} */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
void DefaultISR(void);
#endif
/*
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
* defined in previous of this file.
*/
#include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief Enable specific interrupt.
*
* Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt enabled successfully
* @retval kStatus_Fail Failed to enable the interrupt
*/
static inline status_t EnableIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_EnableIRQ(interrupt);
#else
NVIC_EnableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Disable specific interrupt.
*
* Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt disabled successfully
* @retval kStatus_Fail Failed to disable the interrupt
*/
static inline status_t DisableIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_DisableIRQ(interrupt);
#else
NVIC_DisableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Enable the IRQ, and also set the interrupt priority.
*
* Only handle LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only handles the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ to Enable.
* @param priNum Priority number set to interrupt controller register.
* @retval kStatus_Success Interrupt priority set successfully
* @retval kStatus_Fail Failed to set the interrupt priority.
*/
static inline status_t EnableIRQWithPriority(IRQn_Type interrupt, uint8_t priNum)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_SetPriority(interrupt, priNum);
GIC_EnableIRQ(interrupt);
#else
NVIC_SetPriority(interrupt, priNum);
NVIC_EnableIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Set the IRQ priority.
*
* Only handle LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only handles the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ to set.
* @param priNum Priority number set to interrupt controller register.
*
* @retval kStatus_Success Interrupt priority set successfully
* @retval kStatus_Fail Failed to set the interrupt priority.
*/
static inline status_t IRQ_SetPriority(IRQn_Type interrupt, uint8_t priNum)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_SetPriority(interrupt, priNum);
#else
NVIC_SetPriority(interrupt, priNum);
#endif
}
return status;
}
/*!
* @brief Clear the pending IRQ flag.
*
* Only handle LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only handles the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The flag which IRQ to clear.
*
* @retval kStatus_Success Interrupt priority set successfully
* @retval kStatus_Fail Failed to set the interrupt priority.
*/
static inline status_t IRQ_ClearPendingIRQ(IRQn_Type interrupt)
{
status_t status = kStatus_Success;
if (NotAvail_IRQn == interrupt)
{
status = kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
status = kStatus_Fail;
}
#endif
else
{
#if defined(__GIC_PRIO_BITS)
GIC_ClearPendingIRQ(interrupt);
#else
NVIC_ClearPendingIRQ(interrupt);
#endif
}
return status;
}
/*!
* @brief Disable the global IRQ
*
* Disable the global interrupt and return the current primask register. User is required to provided the primask
* register for the EnableGlobalIRQ().
*
* @return Current primask value.
*/
static inline uint32_t DisableGlobalIRQ(void)
{
uint32_t mask;
#if defined(CPSR_I_Msk)
mask = __get_CPSR() & CPSR_I_Msk;
#elif defined(DAIF_I_BIT)
mask = __get_DAIF() & DAIF_I_BIT;
#else
mask = __get_PRIMASK();
#endif
__disable_irq();
return mask;
}
/*!
* @brief Enable the global IRQ
*
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
* convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
*
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
* DisableGlobalIRQ().
*/
static inline void EnableGlobalIRQ(uint32_t primask)
{
#if defined(CPSR_I_Msk)
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
#elif defined(DAIF_I_BIT)
if (0UL == primask)
{
__enable_irq();
}
#else
__set_PRIMASK(primask);
#endif
}
#if defined(ENABLE_RAM_VECTOR_TABLE)
/*!
* @brief install IRQ handler
*
* @param irq IRQ number
* @param irqHandler IRQ handler address
* @return The old IRQ handler address
*/
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*
* When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
* powerlib should be used instead of these functions.
*/
#if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
/*!
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
*
* Enable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
*
* @param interrupt The IRQ number.
*/
void EnableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
*
* Disable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
*
* @param interrupt The IRQ number.
*/
void DisableDeepSleepIRQ(IRQn_Type interrupt);
#endif /* FSL_FEATURE_POWERLIB_EXTEND */
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#if defined(DWT)
/*!
* @brief Enable the counter to get CPU cycles.
*/
void MSDK_EnableCpuCycleCounter(void);
/*!
* @brief Get the current CPU cycle count.
*
* @return Current CPU cycle count.
*/
uint32_t MSDK_GetCpuCycleCount(void);
#endif
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*! @} */
#endif /* _FSL_COMMON_ARM_H_ */

View File

@ -0,0 +1,371 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017, 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_crc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.crc"
#endif
/*! @internal @brief Has data register with name CRC. */
#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG
#define DATA CRC
#define DATALL CRCLL
#endif
#if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT
/* @brief Default user configuration structure for CRC-16-CCITT */
#define CRC_DRIVER_DEFAULT_POLYNOMIAL 0x1021U
/*< CRC-16-CCIT polynomial x**16 + x**12 + x**5 + x**0 */
#define CRC_DRIVER_DEFAULT_SEED 0xFFFFU
/*< Default initial checksum */
#define CRC_DRIVER_DEFAULT_REFLECT_IN false
/*< Default is no transpose */
#define CRC_DRIVER_DEFAULT_REFLECT_OUT false
/*< Default is transpose bytes */
#define CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM false
/*< Default is without complement of CRC data register read data */
#define CRC_DRIVER_DEFAULT_CRC_BITS kCrcBits16
/*< Default is 16-bit CRC protocol */
#define CRC_DRIVER_DEFAULT_CRC_RESULT kCrcFinalChecksum
/*< Default is resutl type is final checksum */
#endif /* CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT */
#if defined(CRC_RSTS)
#define CRC_RESETS_ARRAY CRC_RSTS
#endif
/*! @brief CRC type of transpose of read write data */
typedef enum _crc_transpose_type
{
kCrcTransposeNone = 0U, /*! No transpose */
kCrcTransposeBits = 1U, /*! Tranpose bits in bytes */
kCrcTransposeBitsAndBytes = 2U, /*! Transpose bytes and bits in bytes */
kCrcTransposeBytes = 3U, /*! Transpose bytes */
} crc_transpose_type_t;
/*!
* @brief CRC module configuration.
*
* This structure holds the configuration for the CRC module.
*/
typedef struct _crc_module_config
{
uint32_t polynomial; /*!< CRC Polynomial, MSBit first.@n
Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */
uint32_t seed; /*!< Starting checksum value */
crc_transpose_type_t readTranspose; /*!< Type of transpose when reading CRC result. */
crc_transpose_type_t writeTranspose; /*!< Type of transpose when writing CRC input data. */
bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */
crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */
} crc_module_config_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
#if defined(CRC_RESETS_ARRAY)
/*!
* @brief Get instance number for CRC module.
*
* @param base CRC peripheral base address
*/
static uint32_t CRC_GetInstance(CRC_Type *base);
#endif
/*******************************************************************************
* Variables
******************************************************************************/
#if defined(CRC_RESETS_ARRAY)
static CRC_Type *const s_crcBases[] = CRC_BASE_PTRS;
/* Reset array */
static const reset_ip_name_t s_crcResets[] = CRC_RESETS_ARRAY;
#endif
/*******************************************************************************
* Code
******************************************************************************/
#if defined(CRC_RESETS_ARRAY)
static uint32_t CRC_GetInstance(CRC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_crcBases); instance++)
{
if (s_crcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_crcBases));
return instance;
}
#endif
/*!
* @brief Returns transpose type for CRC protocol reflect in parameter.
*
* This functions helps to set writeTranspose member of crc_config_t structure. Reflect in is CRC protocol parameter.
*
* @param enable True or false for the selected CRC protocol Reflect In (refin) parameter.
*/
static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectIn(bool enable)
{
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes);
}
/*!
* @brief Returns transpose type for CRC protocol reflect out parameter.
*
* This functions helps to set readTranspose member of crc_config_t structure. Reflect out is CRC protocol parameter.
*
* @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter.
*/
static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectOut(bool enable)
{
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone);
}
/*!
* @brief Starts checksum computation.
*
* Configures the CRC module for the specified CRC protocol. @n
* Starts the checksum computation by writing the seed value
*
* @param base CRC peripheral address.
* @param config Pointer to protocol configuration structure.
*/
static void CRC_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config)
{
uint32_t crcControl;
/* pre-compute value for CRC control registger based on user configuraton without WAS field */
crcControl = 0U | CRC_CTRL_TOT(config->writeTranspose) | CRC_CTRL_TOTR(config->readTranspose) |
CRC_CTRL_FXOR(config->complementChecksum) | CRC_CTRL_TCRC(config->crcBits);
/* make sure the control register is clear - WAS is deasserted, and protocol is set */
base->CTRL = crcControl;
/* write polynomial register */
base->GPOLY = config->polynomial;
/* write pre-computed control register value along with WAS to start checksum computation */
base->CTRL = crcControl | CRC_CTRL_WAS(true);
/* write seed (initial checksum) */
base->DATA = config->seed;
/* deassert WAS by writing pre-computed CRC control register value */
base->CTRL = crcControl;
}
/*!
* @brief Starts final checksum computation.
*
* Configures the CRC module for the specified CRC protocol. @n
* Starts final checksum computation by writing the seed value.
* @note CRC_Get16bitResult() or CRC_Get32bitResult() return final checksum
* (output reflection and xor functions are applied).
*
* @param base CRC peripheral address.
* @param protocolConfig Pointer to protocol configuration structure.
*/
static void CRC_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
{
crc_module_config_t moduleConfig;
/* convert protocol to CRC peripheral module configuration, prepare for final checksum */
moduleConfig.polynomial = protocolConfig->polynomial;
moduleConfig.seed = protocolConfig->seed;
moduleConfig.readTranspose = CRC_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut);
moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
moduleConfig.complementChecksum = protocolConfig->complementChecksum;
moduleConfig.crcBits = protocolConfig->crcBits;
CRC_ConfigureAndStart(base, &moduleConfig);
}
/*!
* @brief Starts intermediate checksum computation.
*
* Configures the CRC module for the specified CRC protocol. @n
* Starts intermediate checksum computation by writing the seed value.
* @note CRC_Get16bitResult() or CRC_Get32bitResult() return intermediate checksum (raw data register value).
*
* @param base CRC peripheral address.
* @param protocolConfig Pointer to protocol configuration structure.
*/
static void CRC_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
{
crc_module_config_t moduleConfig;
/* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */
moduleConfig.polynomial = protocolConfig->polynomial;
moduleConfig.seed = protocolConfig->seed;
moduleConfig.readTranspose =
kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */
moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */
moduleConfig.crcBits = protocolConfig->crcBits;
CRC_ConfigureAndStart(base, &moduleConfig);
}
/*!
* brief Enables and configures the CRC peripheral module.
*
* This function enables the clock gate in the SIM module for the CRC peripheral.
* It also configures the CRC module and starts a checksum computation by writing the seed.
*
* param base CRC peripheral address.
* param config CRC module configuration structure.
*/
void CRC_Init(CRC_Type *base, const crc_config_t *config)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* ungate clock */
CLOCK_EnableClock(kCLOCK_Crc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(CRC_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_crcResets[CRC_GetInstance(base)]);
#endif
/* configure CRC module and write the seed */
if (config->crcResult == kCrcFinalChecksum)
{
CRC_SetProtocolConfig(base, config);
}
else
{
CRC_SetRawProtocolConfig(base, config);
}
}
/*!
* brief Loads default values to the CRC protocol configuration structure.
*
* Loads default values to the CRC protocol configuration structure. The default values are as follows.
* code
* config->polynomial = 0x1021;
* config->seed = 0xFFFF;
* config->reflectIn = false;
* config->reflectOut = false;
* config->complementChecksum = false;
* config->crcBits = kCrcBits16;
* config->crcResult = kCrcFinalChecksum;
* endcode
*
* param config CRC protocol configuration structure.
*/
void CRC_GetDefaultConfig(crc_config_t *config)
{
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
static const crc_config_t crc16ccit = {
CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_SEED,
CRC_DRIVER_DEFAULT_REFLECT_IN, CRC_DRIVER_DEFAULT_REFLECT_OUT,
CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM, CRC_DRIVER_DEFAULT_CRC_BITS,
CRC_DRIVER_DEFAULT_CRC_RESULT,
};
*config = crc16ccit;
}
/*!
* brief Writes data to the CRC module.
*
* Writes input data buffer bytes to the CRC data register.
* The configured type of transpose is applied.
*
* param base CRC peripheral address.
* param data Input data stream, MSByte in data[0].
* param dataSize Size in bytes of the input data buffer.
*/
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize)
{
const uint32_t *data32;
/* 8-bit reads and writes till source address is aligned 4 bytes */
while ((0U != dataSize) && (0U != ((uint32_t)data & 3U)))
{
base->ACCESS8BIT.DATALL = *data;
data++;
dataSize--;
}
/* use 32-bit reads and writes as long as possible */
data32 = (const uint32_t *)(uint32_t)data;
while (dataSize >= sizeof(uint32_t))
{
base->DATA = *data32;
data32++;
dataSize -= sizeof(uint32_t);
}
data = (const uint8_t *)data32;
/* 8-bit reads and writes till end of data buffer */
while (dataSize != 0U)
{
base->ACCESS8BIT.DATALL = *data;
data++;
dataSize--;
}
}
/*!
* brief Reads the 32-bit checksum from the CRC module.
*
* Reads the CRC data register (either an intermediate or the final checksum).
* The configured type of transpose and complement is applied.
*
* param base CRC peripheral address.
* return An intermediate or the final 32-bit checksum, after configured transpose and complement operations.
*/
uint32_t CRC_Get32bitResult(CRC_Type *base)
{
return base->DATA;
}
/*!
* brief Reads a 16-bit checksum from the CRC module.
*
* Reads the CRC data register (either an intermediate or the final checksum).
* The configured type of transpose and complement is applied.
*
* param base CRC peripheral address.
* return An intermediate or the final 16-bit checksum, after configured transpose and complement operations.
*/
uint16_t CRC_Get16bitResult(CRC_Type *base)
{
uint32_t retval;
uint32_t totr; /* type of transpose read bitfield */
retval = base->DATA;
totr = (base->CTRL & CRC_CTRL_TOTR_MASK) >> CRC_CTRL_TOTR_SHIFT;
/* check transpose type to get 16-bit out of 32-bit register */
if (totr >= 2U)
{
/* transpose of bytes for read is set, the result CRC is in CRC_DATA[HU:HL] */
retval &= 0xFFFF0000U;
retval = retval >> 16U;
}
else
{
/* no transpose of bytes for read, the result CRC is in CRC_DATA[LU:LL] */
retval &= 0x0000FFFFU;
}
return (uint16_t)retval;
}

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017, 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CRC_H_
#define _FSL_CRC_H_
#include "fsl_common.h"
/*!
* @addtogroup crc
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief CRC driver version. Version 2.0.4.
*
* Current version: 2.0.4
*
* Change log:
*
* - Version 2.0.4
* - Release peripheral from reset if necessary in init function.
*
* - Version 2.0.3
* - Fix MISRA issues
*
* - Version 2.0.2
* - Fix MISRA issues
*
* - Version 2.0.1
* - move DATA and DATALL macro definition from header file to source file
*/
#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
/*@}*/
#ifndef CRC_DRIVER_CUSTOM_DEFAULTS
/*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */
#define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1
#endif
/*! @brief CRC bit width */
typedef enum _crc_bits
{
kCrcBits16 = 0U, /*!< Generate 16-bit CRC code */
kCrcBits32 = 1U /*!< Generate 32-bit CRC code */
} crc_bits_t;
/*! @brief CRC result type */
typedef enum _crc_result
{
kCrcFinalChecksum = 0U, /*!< CRC data register read value is the final checksum.
Reflect out and final xor protocol features are applied. */
kCrcIntermediateChecksum = 1U /*!< CRC data register read value is intermediate checksum (raw value).
Reflect out and final xor protocol feature are not applied.
Intermediate checksum can be used as a seed for CRC_Init()
to continue adding data to this checksum. */
} crc_result_t;
/*!
* @brief CRC protocol configuration.
*
* This structure holds the configuration for the CRC protocol.
*
*/
typedef struct _crc_config
{
uint32_t polynomial; /*!< CRC Polynomial, MSBit first.
Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */
uint32_t seed; /*!< Starting checksum value */
bool reflectIn; /*!< Reflect bits on input. */
bool reflectOut; /*!< Reflect bits on output. */
bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */
crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */
crc_result_t crcResult; /*!< Selects final or intermediate checksum return from CRC_Get16bitResult() or
CRC_Get32bitResult() */
} crc_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Enables and configures the CRC peripheral module.
*
* This function enables the clock gate in the SIM module for the CRC peripheral.
* It also configures the CRC module and starts a checksum computation by writing the seed.
*
* @param base CRC peripheral address.
* @param config CRC module configuration structure.
*/
void CRC_Init(CRC_Type *base, const crc_config_t *config);
/*!
* @brief Disables the CRC peripheral module.
*
* This function disables the clock gate in the SIM module for the CRC peripheral.
*
* @param base CRC peripheral address.
*/
static inline void CRC_Deinit(CRC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* gate clock */
CLOCK_DisableClock(kCLOCK_Crc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* @brief Loads default values to the CRC protocol configuration structure.
*
* Loads default values to the CRC protocol configuration structure. The default values are as follows.
* @code
* config->polynomial = 0x1021;
* config->seed = 0xFFFF;
* config->reflectIn = false;
* config->reflectOut = false;
* config->complementChecksum = false;
* config->crcBits = kCrcBits16;
* config->crcResult = kCrcFinalChecksum;
* @endcode
*
* @param config CRC protocol configuration structure.
*/
void CRC_GetDefaultConfig(crc_config_t *config);
/*!
* @brief Writes data to the CRC module.
*
* Writes input data buffer bytes to the CRC data register.
* The configured type of transpose is applied.
*
* @param base CRC peripheral address.
* @param data Input data stream, MSByte in data[0].
* @param dataSize Size in bytes of the input data buffer.
*/
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize);
/*!
* @brief Reads the 32-bit checksum from the CRC module.
*
* Reads the CRC data register (either an intermediate or the final checksum).
* The configured type of transpose and complement is applied.
*
* @param base CRC peripheral address.
* @return An intermediate or the final 32-bit checksum, after configured transpose and complement operations.
*/
uint32_t CRC_Get32bitResult(CRC_Type *base);
/*!
* @brief Reads a 16-bit checksum from the CRC module.
*
* Reads the CRC data register (either an intermediate or the final checksum).
* The configured type of transpose and complement is applied.
*
* @param base CRC peripheral address.
* @return An intermediate or the final 16-bit checksum, after configured transpose and complement operations.
*/
uint16_t CRC_Get16bitResult(CRC_Type *base);
#if defined(__cplusplus)
}
#endif
/*!
*@}
*/
#endif /* _FSL_CRC_H_ */

View File

@ -0,0 +1,577 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_ctimer.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.ctimer"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the instance from the base address
*
* @param base Ctimer peripheral base address
*
* @return The Timer instance
*/
static uint32_t CTIMER_GetInstance(CTIMER_Type *base);
/*!
* @brief CTIMER generic IRQ handle function.
*
* @param index FlexCAN peripheral instance index.
*/
static void CTIMER_GenericIRQHandler(uint32_t index);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to Timer bases for each instance. */
static CTIMER_Type *const s_ctimerBases[] = CTIMER_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to Timer clocks for each instance. */
static const clock_ip_name_t s_ctimerClocks[] = CTIMER_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET))
#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
#if defined(FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET) && FSL_FEATURE_CTIMER_WRITE_ZERO_ASSERT_RESET
/*! @brief Pointers to Timer resets for each instance, writing a zero asserts the reset */
static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS_N;
#else
/*! @brief Pointers to Timer resets for each instance, writing a one asserts the reset */
static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS;
#endif
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
/*! @brief Pointers real ISRs installed by drivers for each instance. */
static ctimer_callback_t *s_ctimerCallback[sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0])] = {0};
/*! @brief Callback type installed by drivers for each instance. */
static ctimer_callback_type_t ctimerCallbackType[sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0])] = {
kCTIMER_SingleCallback};
/*! @brief Array to map timer instance to IRQ number. */
static const IRQn_Type s_ctimerIRQ[] = CTIMER_IRQS;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t CTIMER_GetInstance(CTIMER_Type *base)
{
uint32_t instance;
uint32_t ctimerArrayCount = (sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0]));
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ctimerArrayCount; instance++)
{
if (s_ctimerBases[instance] == base)
{
break;
}
}
assert(instance < ctimerArrayCount);
return instance;
}
/*!
* brief Ungates the clock and configures the peripheral for basic operation.
*
* note This API should be called at the beginning of the application before using the driver.
*
* param base Ctimer peripheral base address
* param config Pointer to the user configuration structure.
*/
void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config)
{
assert(config != NULL);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the timer clock*/
CLOCK_EnableClock(s_ctimerClocks[CTIMER_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
/* Reset the module. */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_RESET) && (FSL_FEATURE_CTIMER_HAS_NO_RESET))
RESET_PeripheralReset(s_ctimerResets[CTIMER_GetInstance(base)]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
/* Setup the cimer mode and count select */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
base->CTCR = CTIMER_CTCR_CTMODE(config->mode) | CTIMER_CTCR_CINSEL(config->input);
#endif
/* Setup the timer prescale value */
base->PR = CTIMER_PR_PRVAL(config->prescale);
}
/*!
* brief Gates the timer clock.
*
* param base Ctimer peripheral base address
*/
void CTIMER_Deinit(CTIMER_Type *base)
{
uint32_t index = CTIMER_GetInstance(base);
/* Stop the timer */
base->TCR &= ~CTIMER_TCR_CEN_MASK;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the timer clock*/
CLOCK_DisableClock(s_ctimerClocks[index]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Disable IRQ at NVIC Level */
(void)DisableIRQ(s_ctimerIRQ[index]);
}
/*!
* brief Fills in the timers configuration structure with the default settings.
*
* The default values are:
* code
* config->mode = kCTIMER_TimerMode;
* config->input = kCTIMER_Capture_0;
* config->prescale = 0;
* endcode
* param config Pointer to the user configuration structure.
*/
void CTIMER_GetDefaultConfig(ctimer_config_t *config)
{
assert(config != NULL);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
/* Run as a timer */
config->mode = kCTIMER_TimerMode;
/* This field is ignored when mode is timer */
config->input = kCTIMER_Capture_0;
/* Timer counter is incremented on every APB bus clock */
config->prescale = 0;
}
/*!
* brief Configures the PWM signal parameters.
*
* Enables PWM mode on the match channel passed in and will then setup the match value
* and other match parameters to generate a PWM signal.
* This function can manually assign the specified channel to set the PWM cycle.
*
* note When setting PWM output from multiple output pins, all should use the same PWM
* frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution.
*
* param base Ctimer peripheral base address
* param pwmPeriodChannel Specify the channel to control the PWM period
* param matchChannel Match pin to be used to output the PWM signal
* param dutyCyclePercent PWM pulse width; the value should be between 0 to 100
* param pwmFreq_Hz PWM signal frequency in Hz
* param srcClock_Hz Timer counter clock in Hz
* param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse,
* if it is 0 then no interrupt will be generated.
*
* return kStatus_Success on success
* kStatus_Fail If matchChannel is equal to pwmPeriodChannel; this channel is reserved to set the PWM cycle
*/
status_t CTIMER_SetupPwm(CTIMER_Type *base,
const ctimer_match_t pwmPeriodChannel,
ctimer_match_t matchChannel,
uint8_t dutyCyclePercent,
uint32_t pwmFreq_Hz,
uint32_t srcClock_Hz,
bool enableInt)
{
assert(pwmFreq_Hz > 0U);
uint32_t reg;
uint32_t period, pulsePeriod = 0;
uint32_t timerClock = srcClock_Hz / (base->PR + 1U);
uint32_t index = CTIMER_GetInstance(base);
if (matchChannel == pwmPeriodChannel)
{
return kStatus_Fail;
}
/* Enable PWM mode on the match channel */
base->PWMC |= (1UL << (uint32_t)matchChannel);
/* Clear the stop, reset and interrupt bits for this channel */
reg = base->MCR;
reg &=
~(((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK | (uint32_t)CTIMER_MCR_MR0S_MASK | (uint32_t)CTIMER_MCR_MR0I_MASK))
<< ((uint32_t)matchChannel * 3U));
/* If call back function is valid then enable match interrupt for the channel */
if (enableInt)
{
reg |= (((uint32_t)CTIMER_MCR_MR0I_MASK) << (CTIMER_MCR_MR0I_SHIFT + ((uint32_t)matchChannel * 3U)));
}
/* Reset the counter when match on PWM period channel (pwmPeriodChannel) */
reg |= ((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK) << ((uint32_t)pwmPeriodChannel * 3U));
base->MCR = reg;
/* Calculate PWM period match value */
period = (timerClock / pwmFreq_Hz) - 1U;
/* Calculate pulse width match value */
if (dutyCyclePercent == 0U)
{
pulsePeriod = period + 1U;
}
else
{
pulsePeriod = (period * (100U - (uint32_t)dutyCyclePercent)) / 100U;
}
/* Specified channel pwmPeriodChannel will define the PWM period */
base->MR[pwmPeriodChannel] = period;
/* This will define the PWM pulse period */
base->MR[matchChannel] = pulsePeriod;
/* Clear status flags */
CTIMER_ClearStatusFlags(base, ((uint32_t)CTIMER_IR_MR0INT_MASK) << (uint32_t)matchChannel);
/* If call back function is valid then enable interrupt and update the call back function */
if (enableInt)
{
(void)EnableIRQ(s_ctimerIRQ[index]);
}
return kStatus_Success;
}
/*!
* brief Configures the PWM signal parameters.
*
* Enables PWM mode on the match channel passed in and will then setup the match value
* and other match parameters to generate a PWM signal.
* This function can manually assign the specified channel to set the PWM cycle.
*
* note When setting PWM output from multiple output pins, all should use the same PWM
* period
*
* param base Ctimer peripheral base address
* param pwmPeriodChannel Specify the channel to control the PWM period
* param matchChannel Match pin to be used to output the PWM signal
* param pwmPeriod PWM period match value
* param pulsePeriod Pulse width match value
* param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse,
* if it is 0 then no interrupt will be generated.
*
* return kStatus_Success on success
* kStatus_Fail If matchChannel is equal to pwmPeriodChannel; this channel is reserved to set the PWM period
*/
status_t CTIMER_SetupPwmPeriod(CTIMER_Type *base,
const ctimer_match_t pwmPeriodChannel,
ctimer_match_t matchChannel,
uint32_t pwmPeriod,
uint32_t pulsePeriod,
bool enableInt)
{
/* Some CTimers only have 16bits , so the value is limited*/
#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B
assert(!((FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32) && (pulsePeriod > 0xFFFFU)));
#endif
uint32_t reg;
uint32_t index = CTIMER_GetInstance(base);
if (matchChannel == pwmPeriodChannel)
{
return kStatus_Fail;
}
/* Enable PWM mode on PWM pulse channel */
base->PWMC |= (1UL << (uint32_t)matchChannel);
/* Clear the stop, reset and interrupt bits for PWM pulse channel */
reg = base->MCR;
reg &=
~((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK | (uint32_t)CTIMER_MCR_MR0S_MASK | (uint32_t)CTIMER_MCR_MR0I_MASK)
<< ((uint32_t)matchChannel * 3U));
/* If call back function is valid then enable match interrupt for PWM pulse channel */
if (enableInt)
{
reg |= (((uint32_t)CTIMER_MCR_MR0I_MASK) << (CTIMER_MCR_MR0I_SHIFT + ((uint32_t)matchChannel * 3U)));
}
/* Reset the counter when match on PWM period channel (pwmPeriodChannel) */
reg |= ((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK) << ((uint32_t)pwmPeriodChannel * 3U));
base->MCR = reg;
/* Specified channel pwmPeriodChannel will define the PWM period */
base->MR[pwmPeriodChannel] = pwmPeriod;
/* This will define the PWM pulse period */
base->MR[matchChannel] = pulsePeriod;
/* Clear status flags */
CTIMER_ClearStatusFlags(base, ((uint32_t)CTIMER_IR_MR0INT_MASK) << (uint32_t)matchChannel);
/* If call back function is valid then enable interrupt and update the call back function */
if (enableInt)
{
(void)EnableIRQ(s_ctimerIRQ[index]);
}
return kStatus_Success;
}
/*!
* brief Updates the duty cycle of an active PWM signal.
*
* note Please use CTIMER_SetupPwmPeriod to update the PWM with high resolution.
* This function can manually assign the specified channel to set the PWM cycle.
*
* param base Ctimer peripheral base address
* param pwmPeriodChannel Specify the channel to control the PWM period
* param matchChannel Match pin to be used to output the PWM signal
* param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
*/
void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base,
const ctimer_match_t pwmPeriodChannel,
ctimer_match_t matchChannel,
uint8_t dutyCyclePercent)
{
uint32_t pulsePeriod = 0, period;
/* Specified channel pwmPeriodChannel defines the PWM period */
period = base->MR[pwmPeriodChannel];
/* For 0% dutycyle, make pulse period greater than period so the event will never occur */
if (dutyCyclePercent == 0U)
{
pulsePeriod = period + 1U;
}
else
{
pulsePeriod = (period * (100U - (uint32_t)dutyCyclePercent)) / 100U;
}
/* Update dutycycle */
base->MR[matchChannel] = pulsePeriod;
}
/*!
* brief Setup the match register.
*
* User configuration is used to setup the match value and action to be taken when a match occurs.
*
* param base Ctimer peripheral base address
* param matchChannel Match register to configure
* param config Pointer to the match configuration structure
*/
void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config)
{
/* Some CTimers only have 16bits , so the value is limited*/
#if defined(FSL_FEATURE_SOC_CTIMER16B) && FSL_FEATURE_SOC_CTIMER16B
assert(!(FSL_FEATURE_CTIMER_BIT_SIZEn(base) < 32 && config->matchValue > 0xFFFFU));
#endif
uint32_t reg;
uint32_t index = CTIMER_GetInstance(base);
/* Set the counter operation when a match on this channel occurs */
reg = base->MCR;
reg &=
~((uint32_t)((uint32_t)CTIMER_MCR_MR0R_MASK | (uint32_t)CTIMER_MCR_MR0S_MASK | (uint32_t)CTIMER_MCR_MR0I_MASK)
<< ((uint32_t)matchChannel * 3U));
reg |= ((uint32_t)(config->enableCounterReset) << (CTIMER_MCR_MR0R_SHIFT + ((uint32_t)matchChannel * 3U)));
reg |= ((uint32_t)(config->enableCounterStop) << (CTIMER_MCR_MR0S_SHIFT + ((uint32_t)matchChannel * 3U)));
reg |= ((uint32_t)(config->enableInterrupt) << (CTIMER_MCR_MR0I_SHIFT + ((uint32_t)matchChannel * 3U)));
base->MCR = reg;
reg = base->EMR;
/* Set the match output operation when a match on this channel occurs */
reg &= ~(((uint32_t)CTIMER_EMR_EMC0_MASK) << ((uint32_t)matchChannel * 2U));
reg |= ((uint32_t)config->outControl) << (CTIMER_EMR_EMC0_SHIFT + ((uint32_t)matchChannel * 2U));
/* Set the initial state of the EM bit/output */
reg &= ~(((uint32_t)CTIMER_EMR_EM0_MASK) << (uint32_t)matchChannel);
reg |= ((uint32_t)config->outPinInitState) << (uint32_t)matchChannel;
base->EMR = reg;
/* Set the match value */
base->MR[matchChannel] = config->matchValue;
/* Clear status flags */
CTIMER_ClearStatusFlags(base, ((uint32_t)CTIMER_IR_MR0INT_MASK) << (uint32_t)matchChannel);
/* If interrupt is enabled then enable interrupt and update the call back function */
if (config->enableInterrupt)
{
(void)EnableIRQ(s_ctimerIRQ[index]);
}
}
/*!
* brief Get the status of output match.
*
* This function gets the status of output MAT, whether or not this output is connected to a pin.
* This status is driven to the MAT pins if the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
*
* param base Ctimer peripheral base address
* param matchChannel External match channel, user can obtain the status of multiple match channels
* at the same time by using the logic of "|"
* enumeration ::ctimer_external_match_t
* return The mask of external match channel status flags. Users need to use the
* _ctimer_external_match type to decode the return variables.
*/
uint32_t CTIMER_GetOutputMatchStatus(CTIMER_Type *base, uint32_t matchChannel)
{
return (base->EMR & matchChannel);
}
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
/*!
* brief Setup the capture.
*
* param base Ctimer peripheral base address
* param capture Capture channel to configure
* param edge Edge on the channel that will trigger a capture
* param enableInt Flag to enable channel interrupts, if enabled then the registered call back
* is called upon capture
*/
void CTIMER_SetupCapture(CTIMER_Type *base,
ctimer_capture_channel_t capture,
ctimer_capture_edge_t edge,
bool enableInt)
{
uint32_t reg = base->CCR;
uint32_t index = CTIMER_GetInstance(base);
/* Set the capture edge */
reg &= ~((uint32_t)((uint32_t)CTIMER_CCR_CAP0RE_MASK | (uint32_t)CTIMER_CCR_CAP0FE_MASK |
(uint32_t)CTIMER_CCR_CAP0I_MASK)
<< ((uint32_t)capture * 3U));
reg |= ((uint32_t)edge) << (CTIMER_CCR_CAP0RE_SHIFT + ((uint32_t)capture * 3U));
/* Clear status flags */
CTIMER_ClearStatusFlags(base, (((uint32_t)kCTIMER_Capture0Flag) << (uint32_t)capture));
/* If call back function is valid then enable capture interrupt for the channel and update the call back function */
if (enableInt)
{
reg |= ((uint32_t)CTIMER_CCR_CAP0I_MASK) << ((uint32_t)capture * 3U);
(void)EnableIRQ(s_ctimerIRQ[index]);
}
base->CCR = reg;
}
#endif
/*!
* brief Register callback.
*
* param base Ctimer peripheral base address
* param cb_func callback function
* param cb_type callback function type, singular or multiple
*/
void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type)
{
uint32_t index = CTIMER_GetInstance(base);
s_ctimerCallback[index] = cb_func;
ctimerCallbackType[index] = cb_type;
}
/*!
* brief CTIMER generic IRQ handle function.
*
* param index FlexCAN peripheral instance index.
*/
static void CTIMER_GenericIRQHandler(uint32_t index)
{
uint32_t int_stat, i, mask;
/* Get Interrupt status flags */
int_stat = CTIMER_GetStatusFlags(s_ctimerBases[index]);
/* Clear the status flags that were set */
CTIMER_ClearStatusFlags(s_ctimerBases[index], int_stat);
if (ctimerCallbackType[index] == kCTIMER_SingleCallback)
{
if (s_ctimerCallback[index][0] != NULL)
{
s_ctimerCallback[index][0](int_stat);
}
}
else
{
#if defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE
for (i = 0; i <= CTIMER_IR_MR3INT_SHIFT; i++)
#else
#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT
for (i = 0; i <= CTIMER_IR_CR3INT_SHIFT; i++)
#else
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT) && FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT)
for (i = 0; i <= CTIMER_IR_CR2INT_SHIFT; i++)
#else
for (i = 0; i <= CTIMER_IR_CR1INT_SHIFT; i++)
#endif /* FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT */
#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
#endif
{
mask = 0x01UL << i;
/* For each status flag bit that was set call the callback function if it is valid */
if (((int_stat & mask) != 0U) && (s_ctimerCallback[index][i] != NULL))
{
s_ctimerCallback[index][i](int_stat);
}
}
}
SDK_ISR_EXIT_BARRIER;
}
/* IRQ handler functions overloading weak symbols in the startup */
#if defined(CTIMER0)
void CTIMER0_DriverIRQHandler(void);
void CTIMER0_DriverIRQHandler(void)
{
CTIMER_GenericIRQHandler(0);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(CTIMER1)
void CTIMER1_DriverIRQHandler(void);
void CTIMER1_DriverIRQHandler(void)
{
CTIMER_GenericIRQHandler(1);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(CTIMER2)
void CTIMER2_DriverIRQHandler(void);
void CTIMER2_DriverIRQHandler(void)
{
CTIMER_GenericIRQHandler(2);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(CTIMER3)
void CTIMER3_DriverIRQHandler(void);
void CTIMER3_DriverIRQHandler(void)
{
CTIMER_GenericIRQHandler(3);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(CTIMER4)
void CTIMER4_DriverIRQHandler(void);
void CTIMER4_DriverIRQHandler(void)
{
CTIMER_GenericIRQHandler(4);
SDK_ISR_EXIT_BARRIER;
}
#endif

View File

@ -0,0 +1,682 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CTIMER_H_
#define _FSL_CTIMER_H_
#include "fsl_common.h"
/*!
* @addtogroup ctimer
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_CTIMER_DRIVER_VERSION (MAKE_VERSION(2, 3, 1)) /*!< Version 2.3.1 */
/*@}*/
/*! @brief List of Timer capture channels */
typedef enum _ctimer_capture_channel
{
kCTIMER_Capture_0 = 0U, /*!< Timer capture channel 0 */
kCTIMER_Capture_1, /*!< Timer capture channel 1 */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2)
kCTIMER_Capture_2, /*!< Timer capture channel 2 */
#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */
#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
kCTIMER_Capture_3 /*!< Timer capture channel 3 */
#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
} ctimer_capture_channel_t;
/*! @brief List of capture edge options */
typedef enum _ctimer_capture_edge
{
kCTIMER_Capture_RiseEdge = 1U, /*!< Capture on rising edge */
kCTIMER_Capture_FallEdge = 2U, /*!< Capture on falling edge */
kCTIMER_Capture_BothEdge = 3U, /*!< Capture on rising and falling edge */
} ctimer_capture_edge_t;
/*! @brief List of Timer match registers */
typedef enum _ctimer_match
{
kCTIMER_Match_0 = 0U, /*!< Timer match register 0 */
kCTIMER_Match_1, /*!< Timer match register 1 */
kCTIMER_Match_2, /*!< Timer match register 2 */
kCTIMER_Match_3 /*!< Timer match register 3 */
} ctimer_match_t;
/*! @brief List of external match */
typedef enum _ctimer_external_match
{
kCTIMER_External_Match_0 = (1UL << 0), /*!< External match 0 */
kCTIMER_External_Match_1 = (1UL << 1), /*!< External match 1 */
kCTIMER_External_Match_2 = (1UL << 2), /*!< External match 2 */
kCTIMER_External_Match_3 = (1UL << 3) /*!< External match 3 */
} ctimer_external_match_t;
/*! @brief List of output control options */
typedef enum _ctimer_match_output_control
{
kCTIMER_Output_NoAction = 0U, /*!< No action is taken */
kCTIMER_Output_Clear, /*!< Clear the EM bit/output to 0 */
kCTIMER_Output_Set, /*!< Set the EM bit/output to 1 */
kCTIMER_Output_Toggle /*!< Toggle the EM bit/output */
} ctimer_match_output_control_t;
/*! @brief List of Timer modes */
typedef enum _ctimer_timer_mode
{
kCTIMER_TimerMode = 0U, /* TC is incremented every rising APB bus clock edge */
kCTIMER_IncreaseOnRiseEdge, /* TC is incremented on rising edge of input signal */
kCTIMER_IncreaseOnFallEdge, /* TC is incremented on falling edge of input signal */
kCTIMER_IncreaseOnBothEdge /* TC is incremented on both edges of input signal */
} ctimer_timer_mode_t;
/*! @brief List of Timer interrupts */
typedef enum _ctimer_interrupt_enable
{
kCTIMER_Match0InterruptEnable = CTIMER_MCR_MR0I_MASK, /*!< Match 0 interrupt */
kCTIMER_Match1InterruptEnable = CTIMER_MCR_MR1I_MASK, /*!< Match 1 interrupt */
kCTIMER_Match2InterruptEnable = CTIMER_MCR_MR2I_MASK, /*!< Match 2 interrupt */
kCTIMER_Match3InterruptEnable = CTIMER_MCR_MR3I_MASK, /*!< Match 3 interrupt */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
kCTIMER_Capture0InterruptEnable = CTIMER_CCR_CAP0I_MASK, /*!< Capture 0 interrupt */
kCTIMER_Capture1InterruptEnable = CTIMER_CCR_CAP1I_MASK, /*!< Capture 1 interrupt */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2)
kCTIMER_Capture2InterruptEnable = CTIMER_CCR_CAP2I_MASK, /*!< Capture 2 interrupt */
#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */
#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
kCTIMER_Capture3InterruptEnable = CTIMER_CCR_CAP3I_MASK, /*!< Capture 3 interrupt */
#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
#endif
} ctimer_interrupt_enable_t;
/*! @brief List of Timer flags */
typedef enum _ctimer_status_flags
{
kCTIMER_Match0Flag = CTIMER_IR_MR0INT_MASK, /*!< Match 0 interrupt flag */
kCTIMER_Match1Flag = CTIMER_IR_MR1INT_MASK, /*!< Match 1 interrupt flag */
kCTIMER_Match2Flag = CTIMER_IR_MR2INT_MASK, /*!< Match 2 interrupt flag */
kCTIMER_Match3Flag = CTIMER_IR_MR3INT_MASK, /*!< Match 3 interrupt flag */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
kCTIMER_Capture0Flag = CTIMER_IR_CR0INT_MASK, /*!< Capture 0 interrupt flag */
kCTIMER_Capture1Flag = CTIMER_IR_CR1INT_MASK, /*!< Capture 1 interrupt flag */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT) && FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT)
kCTIMER_Capture2Flag = CTIMER_IR_CR2INT_MASK, /*!< Capture 2 interrupt flag */
#endif /* FSL_FEATURE_CTIMER_HAS_NO_IR_CR2INT */
#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT
kCTIMER_Capture3Flag = CTIMER_IR_CR3INT_MASK, /*!< Capture 3 interrupt flag */
#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */
#endif
} ctimer_status_flags_t;
typedef void (*ctimer_callback_t)(uint32_t flags);
/*! @brief Callback type when registering for a callback. When registering a callback
* an array of function pointers is passed the size could be 1 or 8, the callback
* type will tell that.
*/
typedef enum
{
kCTIMER_SingleCallback, /*!< Single Callback type where there is only one callback for the timer.
based on the status flags different channels needs to be handled differently */
kCTIMER_MultipleCallback /*!< Multiple Callback type where there can be 8 valid callbacks, one per channel.
for both match/capture */
} ctimer_callback_type_t;
/*!
* @brief Match configuration
*
* This structure holds the configuration settings for each match register.
*/
typedef struct _ctimer_match_config
{
uint32_t matchValue; /*!< This is stored in the match register */
bool enableCounterReset; /*!< true: Match will reset the counter
false: Match will not reser the counter */
bool enableCounterStop; /*!< true: Match will stop the counter
false: Match will not stop the counter */
ctimer_match_output_control_t outControl; /*!< Action to be taken on a match on the EM bit/output */
bool outPinInitState; /*!< Initial value of the EM bit/output */
bool enableInterrupt; /*!< true: Generate interrupt upon match
false: Do not generate interrupt on match */
} ctimer_match_config_t;
/*!
* @brief Timer configuration structure
*
* This structure holds the configuration settings for the Timer peripheral. To initialize this
* structure to reasonable defaults, call the CTIMER_GetDefaultConfig() function and pass a
* pointer to the configuration structure instance.
*
* The configuration structure can be made constant so as to reside in flash.
*/
typedef struct _ctimer_config
{
ctimer_timer_mode_t mode; /*!< Timer mode */
ctimer_capture_channel_t input; /*!< Input channel to increment the timer, used only in timer
modes that rely on this input signal to increment TC */
uint32_t prescale; /*!< Prescale value */
} ctimer_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the clock and configures the peripheral for basic operation.
*
* @note This API should be called at the beginning of the application before using the driver.
*
* @param base Ctimer peripheral base address
* @param config Pointer to the user configuration structure.
*/
void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config);
/*!
* @brief Gates the timer clock.
*
* @param base Ctimer peripheral base address
*/
void CTIMER_Deinit(CTIMER_Type *base);
/*!
* @brief Fills in the timers configuration structure with the default settings.
*
* The default values are:
* @code
* config->mode = kCTIMER_TimerMode;
* config->input = kCTIMER_Capture_0;
* config->prescale = 0;
* @endcode
* @param config Pointer to the user configuration structure.
*/
void CTIMER_GetDefaultConfig(ctimer_config_t *config);
/*! @}*/
/*!
* @name PWM setup operations
* @{
*/
/*!
* @brief Configures the PWM signal parameters.
*
* Enables PWM mode on the match channel passed in and will then setup the match value
* and other match parameters to generate a PWM signal.
* This function can manually assign the specified channel to set the PWM cycle.
*
* @note When setting PWM output from multiple output pins, all should use the same PWM
* period
*
* @param base Ctimer peripheral base address
* @param pwmPeriodChannel Specify the channel to control the PWM period
* @param matchChannel Match pin to be used to output the PWM signal
* @param pwmPeriod PWM period match value
* @param pulsePeriod Pulse width match value
* @param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse,
* if it is 0 then no interrupt will be generated.
*/
status_t CTIMER_SetupPwmPeriod(CTIMER_Type *base,
const ctimer_match_t pwmPeriodChannel,
ctimer_match_t matchChannel,
uint32_t pwmPeriod,
uint32_t pulsePeriod,
bool enableInt);
/*!
* @brief Configures the PWM signal parameters.
*
* Enables PWM mode on the match channel passed in and will then setup the match value
* and other match parameters to generate a PWM signal.
* This function can manually assign the specified channel to set the PWM cycle.
*
* @note When setting PWM output from multiple output pins, all should use the same PWM
* frequency. Please use CTIMER_SetupPwmPeriod to set up the PWM with high resolution.
*
* @param base Ctimer peripheral base address
* @param pwmPeriodChannel Specify the channel to control the PWM period
* @param matchChannel Match pin to be used to output the PWM signal
* @param dutyCyclePercent PWM pulse width; the value should be between 0 to 100
* @param pwmFreq_Hz PWM signal frequency in Hz
* @param srcClock_Hz Timer counter clock in Hz
* @param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse,
* if it is 0 then no interrupt will be generated.
*/
status_t CTIMER_SetupPwm(CTIMER_Type *base,
const ctimer_match_t pwmPeriodChannel,
ctimer_match_t matchChannel,
uint8_t dutyCyclePercent,
uint32_t pwmFreq_Hz,
uint32_t srcClock_Hz,
bool enableInt);
/*!
* @brief Updates the pulse period of an active PWM signal.
*
* @param base Ctimer peripheral base address
* @param matchChannel Match pin to be used to output the PWM signal
* @param pulsePeriod New PWM pulse width match value
*/
static inline void CTIMER_UpdatePwmPulsePeriod(CTIMER_Type *base, ctimer_match_t matchChannel, uint32_t pulsePeriod)
{
/* Update PWM pulse period match value */
base->MR[matchChannel] = pulsePeriod;
}
/*!
* @brief Updates the duty cycle of an active PWM signal.
*
* @note Please use CTIMER_SetupPwmPeriod to update the PWM with high resolution.
* This function can manually assign the specified channel to set the PWM cycle.
*
* @param base Ctimer peripheral base address
* @param pwmPeriodChannel Specify the channel to control the PWM period
* @param matchChannel Match pin to be used to output the PWM signal
* @param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100
*/
void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base,
const ctimer_match_t pwmPeriodChannel,
ctimer_match_t matchChannel,
uint8_t dutyCyclePercent);
/*! @}*/
/*!
* @brief Setup the match register.
*
* User configuration is used to setup the match value and action to be taken when a match occurs.
*
* @param base Ctimer peripheral base address
* @param matchChannel Match register to configure
* @param config Pointer to the match configuration structure
*/
void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config);
/*!
* @brief Get the status of output match.
*
* This function gets the status of output MAT, whether or not this output is connected to a pin.
* This status is driven to the MAT pins if the match function is selected via IOCON. 0 = LOW. 1 = HIGH.
*
* @param base Ctimer peripheral base address
* @param matchChannel External match channel, user can obtain the status of multiple match channels
* at the same time by using the logic of "|"
* enumeration ::ctimer_external_match_t
* @return The mask of external match channel status flags. Users need to use the
* _ctimer_external_match type to decode the return variables.
*/
uint32_t CTIMER_GetOutputMatchStatus(CTIMER_Type *base, uint32_t matchChannel);
/*!
* @brief Setup the capture.
*
* @param base Ctimer peripheral base address
* @param capture Capture channel to configure
* @param edge Edge on the channel that will trigger a capture
* @param enableInt Flag to enable channel interrupts, if enabled then the registered call back
* is called upon capture
*/
void CTIMER_SetupCapture(CTIMER_Type *base,
ctimer_capture_channel_t capture,
ctimer_capture_edge_t edge,
bool enableInt);
/*!
* @brief Get the timer count value from TC register.
*
* @param base Ctimer peripheral base address.
* @return return the timer count value.
*/
static inline uint32_t CTIMER_GetTimerCountValue(CTIMER_Type *base)
{
return (base->TC);
}
/*!
* @brief Register callback.
*
* @param base Ctimer peripheral base address
* @param cb_func callback function
* @param cb_type callback function type, singular or multiple
*/
void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type);
/*!
* @name Interrupt Interface
* @{
*/
/*!
* @brief Enables the selected Timer interrupts.
*
* @param base Ctimer peripheral base address
* @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::ctimer_interrupt_enable_t
*/
static inline void CTIMER_EnableInterrupts(CTIMER_Type *base, uint32_t mask)
{
/* Enable match interrupts */
base->MCR |= mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK);
/* Enable capture interrupts */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
base->CCR |= mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2)
| CTIMER_CCR_CAP2I_MASK
#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */
#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
| CTIMER_CCR_CAP3I_MASK
#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
);
#endif
}
/*!
* @brief Disables the selected Timer interrupts.
*
* @param base Ctimer peripheral base address
* @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::ctimer_interrupt_enable_t
*/
static inline void CTIMER_DisableInterrupts(CTIMER_Type *base, uint32_t mask)
{
/* Disable match interrupts */
base->MCR &= ~(mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK));
/* Disable capture interrupts */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
base->CCR &= ~(mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2)
| CTIMER_CCR_CAP2I_MASK
#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */
#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
| CTIMER_CCR_CAP3I_MASK
#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
));
#endif
}
/*!
* @brief Gets the enabled Timer interrupts.
*
* @param base Ctimer peripheral base address
*
* @return The enabled interrupts. This is the logical OR of members of the
* enumeration ::ctimer_interrupt_enable_t
*/
static inline uint32_t CTIMER_GetEnabledInterrupts(CTIMER_Type *base)
{
uint32_t enabledIntrs = 0;
/* Get all the match interrupts enabled */
enabledIntrs =
base->MCR & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK);
/* Get all the capture interrupts enabled */
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE) && (FSL_FEATURE_CTIMER_HAS_NO_INPUT_CAPTURE))
enabledIntrs |= base->CCR & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK
#if !(defined(FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2) && FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2)
| CTIMER_CCR_CAP2I_MASK
#endif /* FSL_FEATURE_CTIMER_HAS_NO_CCR_CAP2 */
#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3
| CTIMER_CCR_CAP3I_MASK
#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */
);
#endif
return enabledIntrs;
}
/*! @}*/
/*!
* @name Status Interface
* @{
*/
/*!
* @brief Gets the Timer status flags.
*
* @param base Ctimer peripheral base address
*
* @return The status flags. This is the logical OR of members of the
* enumeration ::ctimer_status_flags_t
*/
static inline uint32_t CTIMER_GetStatusFlags(CTIMER_Type *base)
{
return base->IR;
}
/*!
* @brief Clears the Timer status flags.
*
* @param base Ctimer peripheral base address
* @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::ctimer_status_flags_t
*/
static inline void CTIMER_ClearStatusFlags(CTIMER_Type *base, uint32_t mask)
{
base->IR = mask;
}
/*! @}*/
/*!
* @name Counter Start and Stop
* @{
*/
/*!
* @brief Starts the Timer counter.
*
* @param base Ctimer peripheral base address
*/
static inline void CTIMER_StartTimer(CTIMER_Type *base)
{
base->TCR |= CTIMER_TCR_CEN_MASK;
}
/*!
* @brief Stops the Timer counter.
*
* @param base Ctimer peripheral base address
*/
static inline void CTIMER_StopTimer(CTIMER_Type *base)
{
base->TCR &= ~CTIMER_TCR_CEN_MASK;
}
/*! @}*/
/*!
* @brief Reset the counter.
*
* The timer counter and prescale counter are reset on the next positive edge of the APB clock.
*
* @param base Ctimer peripheral base address
*/
static inline void CTIMER_Reset(CTIMER_Type *base)
{
base->TCR |= CTIMER_TCR_CRST_MASK;
base->TCR &= ~CTIMER_TCR_CRST_MASK;
}
/*!
* @brief Setup the timer prescale value.
*
* Specifies the maximum value for the Prescale Counter.
*
* @param base Ctimer peripheral base address
* @param prescale Prescale value
*/
static inline void CTIMER_SetPrescale(CTIMER_Type *base, uint32_t prescale)
{
base->PR = CTIMER_PR_PRVAL(prescale);
}
/*!
* @brief Get capture channel value.
*
* Get the counter/timer value on the corresponding capture channel.
*
* @param base Ctimer peripheral base address
* @param capture Select capture channel
*
* @return The timer count capture value.
*/
static inline uint32_t CTIMER_GetCaptureValue(CTIMER_Type *base, ctimer_capture_channel_t capture)
{
return base->CR[capture];
}
/*!
* @brief Enable reset match channel.
*
* Set the specified match channel reset operation.
*
* @param base Ctimer peripheral base address
* @param match match channel used
* @param enable Enable match channel reset operation.
*/
static inline void CTIMER_EnableResetMatchChannel(CTIMER_Type *base, ctimer_match_t match, bool enable)
{
if (enable)
{
base->MCR |= (1UL << (CTIMER_MCR_MR0R_SHIFT + ((uint32_t)match * 3U)));
}
else
{
base->MCR &= ~(1UL << (CTIMER_MCR_MR0R_SHIFT + ((uint32_t)match * 3U)));
}
}
/*!
* @brief Enable stop match channel.
*
* Set the specified match channel stop operation.
*
* @param base Ctimer peripheral base address.
* @param match match channel used.
* @param enable Enable match channel stop operation.
*/
static inline void CTIMER_EnableStopMatchChannel(CTIMER_Type *base, ctimer_match_t match, bool enable)
{
if (enable)
{
base->MCR |= (1UL << (CTIMER_MCR_MR0S_SHIFT + ((uint32_t)match * 3U)));
}
else
{
base->MCR &= ~(1UL << (CTIMER_MCR_MR0S_SHIFT + ((uint32_t)match * 3U)));
}
}
#if (defined(FSL_FEATURE_CTIMER_HAS_MSR) && (FSL_FEATURE_CTIMER_HAS_MSR))
/*!
* @brief Enable reload channel falling edge.
*
* Enable the specified match channel reload match shadow value.
*
* @param base Ctimer peripheral base address.
* @param match match channel used.
* @param enable Enable .
*/
static inline void CTIMER_EnableMatchChannelReload(CTIMER_Type *base, ctimer_match_t match, bool enable)
{
if (enable)
{
base->MCR |= (1UL << (CTIMER_MCR_MR0RL_SHIFT + (uint32_t)match));
}
else
{
base->MCR &= ~(1UL << (CTIMER_MCR_MR0RL_SHIFT + (uint32_t)match));
}
}
#endif /* FSL_FEATURE_CTIMER_HAS_MSR */
/*!
* @brief Enable capture channel rising edge.
*
* Sets the specified capture channel for rising edge capture.
*
* @param base Ctimer peripheral base address.
* @param capture capture channel used.
* @param enable Enable rising edge capture.
*/
static inline void CTIMER_EnableRisingEdgeCapture(CTIMER_Type *base, ctimer_capture_channel_t capture, bool enable)
{
if (enable)
{
base->CCR |= (1UL << (CTIMER_CCR_CAP0RE_SHIFT + ((uint32_t)capture * 3U)));
}
else
{
base->CCR &= ~(1UL << (CTIMER_CCR_CAP0RE_SHIFT + ((uint32_t)capture * 3U)));
}
}
/*!
* @brief Enable capture channel falling edge.
*
* Sets the specified capture channel for falling edge capture.
*
* @param base Ctimer peripheral base address.
* @param capture capture channel used.
* @param enable Enable falling edge capture.
*/
static inline void CTIMER_EnableFallingEdgeCapture(CTIMER_Type *base, ctimer_capture_channel_t capture, bool enable)
{
if (enable)
{
base->CCR |= (1UL << (CTIMER_CCR_CAP0FE_SHIFT + ((uint32_t)capture * 3U)));
}
else
{
base->CCR &= ~(1UL << (CTIMER_CCR_CAP0FE_SHIFT + ((uint32_t)capture * 3U)));
}
}
#if (defined(FSL_FEATURE_CTIMER_HAS_MSR) && (FSL_FEATURE_CTIMER_HAS_MSR))
/*!
* @brief Set the specified match shadow channel.
*
* @param base Ctimer peripheral base address.
* @param match match channel used.
* @param matchvalue Reload the value of the corresponding match register.
*/
static inline void CTIMER_SetShadowValue(CTIMER_Type *base, ctimer_match_t match, uint32_t matchvalue)
{
base->MSR[match] = matchvalue;
}
#endif /* FSL_FEATURE_CTIMER_HAS_MSR */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_CTIMER_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_EDMA_CORE_H_
#define _FSL_EDMA_CORE_H_
#include "fsl_edma_soc.h"
/*!
* @addtogroup edma_core
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#if defined(FSL_EDMA_SOC_IP_DMA3) && defined(FSL_EDMA_SOC_IP_DMA4) && FSL_EDMA_SOC_IP_DMA3 && FSL_EDMA_SOC_IP_DMA4
#define DMA_CSR_INTMAJOR_MASK DMA_TCD_CSR_INTMAJOR_MASK
#define DMA_CSR_INTHALF_MASK DMA_TCD_CSR_INTHALF_MASK
#define DMA_CSR_DREQ_MASK DMA_TCD_CSR_DREQ_MASK
#define DMA_CSR_ESG_MASK DMA_TCD_CSR_ESG_MASK
#define DMA_CSR_BWC_MASK DMA_TCD_CSR_BWC_MASK
#define DMA_CSR_BWC(x) DMA_TCD_CSR_BWC(x)
#define DMA_CSR_START_MASK DMA_TCD_CSR_START_MASK
#define DMA_CITER_ELINKNO_CITER_MASK DMA_TCD_CITER_ELINKNO_CITER_MASK
#define DMA_BITER_ELINKNO_BITER_MASK DMA_TCD_BITER_ELINKNO_BITER_MASK
#define DMA_CITER_ELINKNO_CITER_SHIFT DMA_TCD_CITER_ELINKNO_CITER_SHIFT
#define DMA_CITER_ELINKYES_CITER_MASK DMA_TCD_CITER_ELINKYES_CITER_MASK
#define DMA_CITER_ELINKYES_CITER_SHIFT DMA_TCD_CITER_ELINKYES_CITER_SHIFT
#define DMA_ATTR_SMOD_MASK DMA_TCD_ATTR_SMOD_MASK
#define DMA_ATTR_DMOD_MASK DMA_TCD_ATTR_DMOD_MASK
#define DMA_CITER_ELINKNO_ELINK_MASK DMA_TCD_CITER_ELINKNO_ELINK_MASK
#define DMA_CSR_MAJORELINK_MASK DMA_TCD_CSR_MAJORELINK_MASK
#define DMA_BITER_ELINKYES_ELINK_MASK DMA_TCD_BITER_ELINKYES_ELINK_MASK
#define DMA_CITER_ELINKYES_ELINK_MASK DMA_TCD_CITER_ELINKYES_ELINK_MASK
#define DMA_CSR_MAJORLINKCH_MASK DMA_TCD_CSR_MAJORLINKCH_MASK
#define DMA_BITER_ELINKYES_LINKCH_MASK DMA_TCD_BITER_ELINKYES_LINKCH_MASK
#define DMA_CITER_ELINKYES_LINKCH_MASK DMA_TCD_CITER_ELINKYES_LINKCH_MASK
#define DMA_NBYTES_MLOFFYES_MLOFF_MASK DMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK
#define DMA_NBYTES_MLOFFYES_DMLOE_MASK DMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK
#define DMA_NBYTES_MLOFFYES_SMLOE_MASK DMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK
#define DMA_NBYTES_MLOFFNO_NBYTES_MASK DMA_TCD_NBYTES_MLOFFNO_NBYTES_MASK
#define DMA_ATTR_DMOD(x) DMA_TCD_ATTR_DMOD(x)
#define DMA_ATTR_SMOD(X) DMA_TCD_ATTR_SMOD(X)
#define DMA_BITER_ELINKYES_LINKCH(x) DMA_TCD_BITER_ELINKYES_LINKCH(x)
#define DMA_CITER_ELINKYES_LINKCH(x) DMA_TCD_CITER_ELINKYES_LINKCH(x)
#define DMA_NBYTES_MLOFFYES_MLOFF(x) DMA_TCD_NBYTES_MLOFFYES_MLOFF(x)
#define DMA_NBYTES_MLOFFYES_DMLOE(x) DMA_TCD_NBYTES_MLOFFYES_DMLOE(x)
#define DMA_NBYTES_MLOFFYES_SMLOE(x) DMA_TCD_NBYTES_MLOFFYES_SMLOE(x)
#define DMA_NBYTES_MLOFFNO_NBYTES(x) DMA_TCD_NBYTES_MLOFFNO_NBYTES(x)
#define DMA_NBYTES_MLOFFYES_NBYTES(x) DMA_TCD_NBYTES_MLOFFYES_NBYTES(x)
#define DMA_ATTR_DSIZE(x) DMA_TCD_ATTR_DSIZE(x)
#define DMA_ATTR_SSIZE(x) DMA_TCD_ATTR_SSIZE(x)
#define DMA_CSR_DREQ(x) DMA_TCD_CSR_DREQ(x)
#define DMA_CSR_MAJORLINKCH(x) DMA_TCD_CSR_MAJORLINKCH(x)
#define DMA_CH_MATTR_WCACHE(x) DMA4_CH_MATTR_WCACHE(x)
#define DMA_CH_MATTR_RCACHE(x) DMA4_CH_MATTR_RCACHE(x)
#define DMA_CH_CSR_SIGNEXT_MASK DMA4_CH_CSR_SIGNEXT_MASK
#define DMA_CH_CSR_SIGNEXT_SHIFT DMA4_CH_CSR_SIGNEXT_SHIFT
#define DMA_CH_CSR_SWAP_MASK DMA4_CH_CSR_SWAP_MASK
#define DMA_CH_CSR_SWAP_SHIFT DMA4_CH_CSR_SWAP_SHIFT
#define DMA_CH_SBR_INSTR_MASK DMA4_CH_SBR_INSTR_MASK
#define DMA_CH_SBR_INSTR_SHIFT DMA4_CH_SBR_INSTR_SHIFT
#define DMA_CH_MUX_SOURCE(x) DMA4_CH_MUX_SRC(x)
#elif defined(FSL_EDMA_SOC_IP_DMA3) && FSL_EDMA_SOC_IP_DMA3 && \
(!defined(FSL_EDMA_SOC_IP_DMA4) || (defined(FSL_EDMA_SOC_IP_DMA4) && !FSL_EDMA_SOC_IP_DMA4))
#define DMA_CSR_INTMAJOR_MASK DMA_TCD_CSR_INTMAJOR_MASK
#define DMA_CSR_INTHALF_MASK DMA_TCD_CSR_INTHALF_MASK
#define DMA_CSR_DREQ_MASK DMA_TCD_CSR_DREQ_MASK
#define DMA_CSR_ESG_MASK DMA_TCD_CSR_ESG_MASK
#define DMA_CSR_BWC_MASK DMA_TCD_CSR_BWC_MASK
#define DMA_CSR_BWC(x) DMA_TCD_CSR_BWC(x)
#define DMA_CSR_START_MASK DMA_TCD_CSR_START_MASK
#define DMA_CITER_ELINKNO_CITER_MASK DMA_TCD_CITER_ELINKNO_CITER_MASK
#define DMA_BITER_ELINKNO_BITER_MASK DMA_TCD_BITER_ELINKNO_BITER_MASK
#define DMA_CITER_ELINKNO_CITER_SHIFT DMA_TCD_CITER_ELINKNO_CITER_SHIFT
#define DMA_CITER_ELINKYES_CITER_MASK DMA_TCD_CITER_ELINKYES_CITER_MASK
#define DMA_CITER_ELINKYES_CITER_SHIFT DMA_TCD_CITER_ELINKYES_CITER_SHIFT
#define DMA_ATTR_SMOD_MASK DMA_TCD_ATTR_SMOD_MASK
#define DMA_ATTR_DMOD_MASK DMA_TCD_ATTR_DMOD_MASK
#define DMA_CITER_ELINKNO_ELINK_MASK DMA_TCD_CITER_ELINKNO_ELINK_MASK
#define DMA_CSR_MAJORELINK_MASK DMA_TCD_CSR_MAJORELINK_MASK
#define DMA_BITER_ELINKYES_ELINK_MASK DMA_TCD_BITER_ELINKYES_ELINK_MASK
#define DMA_CITER_ELINKYES_ELINK_MASK DMA_TCD_CITER_ELINKYES_ELINK_MASK
#define DMA_CSR_MAJORLINKCH_MASK DMA_TCD_CSR_MAJORLINKCH_MASK
#define DMA_BITER_ELINKYES_LINKCH_MASK DMA_TCD_BITER_ELINKYES_LINKCH_MASK
#define DMA_CITER_ELINKYES_LINKCH_MASK DMA_TCD_CITER_ELINKYES_LINKCH_MASK
#define DMA_NBYTES_MLOFFYES_MLOFF_MASK DMA_TCD_NBYTES_MLOFFYES_MLOFF_MASK
#define DMA_NBYTES_MLOFFYES_DMLOE_MASK DMA_TCD_NBYTES_MLOFFYES_DMLOE_MASK
#define DMA_NBYTES_MLOFFYES_SMLOE_MASK DMA_TCD_NBYTES_MLOFFYES_SMLOE_MASK
#define DMA_ATTR_DMOD(x) DMA_TCD_ATTR_DMOD(x)
#define DMA_ATTR_SMOD(X) DMA_TCD_ATTR_SMOD(X)
#define DMA_BITER_ELINKYES_LINKCH(x) DMA_TCD_BITER_ELINKYES_LINKCH(x)
#define DMA_CITER_ELINKYES_LINKCH(x) DMA_TCD_CITER_ELINKYES_LINKCH(x)
#define DMA_NBYTES_MLOFFYES_MLOFF(x) DMA_TCD_NBYTES_MLOFFYES_MLOFF(x)
#define DMA_NBYTES_MLOFFYES_DMLOE(x) DMA_TCD_NBYTES_MLOFFYES_DMLOE(x)
#define DMA_NBYTES_MLOFFYES_SMLOE(x) DMA_TCD_NBYTES_MLOFFYES_SMLOE(x)
#define DMA_NBYTES_MLOFFNO_NBYTES(x) DMA_TCD_NBYTES_MLOFFNO_NBYTES(x)
#define DMA_NBYTES_MLOFFYES_NBYTES(x) DMA_TCD_NBYTES_MLOFFYES_NBYTES(x)
#define DMA_ATTR_DSIZE(x) DMA_TCD_ATTR_DSIZE(x)
#define DMA_ATTR_SSIZE(x) DMA_TCD_ATTR_SSIZE(x)
#define DMA_CSR_DREQ(x) DMA_TCD_CSR_DREQ(x)
#define DMA_CSR_MAJORLINKCH(x) DMA_TCD_CSR_MAJORLINKCH(x)
#define DMA_CH_MUX_SOURCE(x) DMA_CH_MUX_SRC(x)
#elif defined(FSL_EDMA_SOC_IP_DMA4) && FSL_EDMA_SOC_IP_DMA4 && \
(!defined(FSL_EDMA_SOC_IP_DMA3) || (defined(FSL_EDMA_SOC_IP_DMA3) && !FSL_EDMA_SOC_IP_DMA3))
#define DMA_CSR_INTMAJOR_MASK DMA4_CSR_INTMAJOR_MASK
#define DMA_CSR_INTHALF_MASK DMA4_CSR_INTHALF_MASK
#define DMA_CSR_DREQ_MASK DMA4_CSR_DREQ_MASK
#define DMA_CSR_ESG_MASK DMA4_CSR_ESG_MASK
#define DMA_CSR_BWC_MASK DMA4_CSR_BWC_MASK
#define DMA_CSR_BWC(x) DMA4_CSR_BWC(x)
#define DMA_CSR_START_MASK DMA4_CSR_START_MASK
#define DMA_CITER_ELINKNO_CITER_MASK DMA4_CITER_ELINKNO_CITER_MASK
#define DMA_BITER_ELINKNO_BITER_MASK DMA4_BITER_ELINKNO_BITER_MASK
#define DMA_CITER_ELINKNO_CITER_SHIFT DMA4_CITER_ELINKNO_CITER_SHIFT
#define DMA_CITER_ELINKYES_CITER_MASK DMA4_CITER_ELINKYES_CITER_MASK
#define DMA_CITER_ELINKYES_CITER_SHIFT DMA4_CITER_ELINKYES_CITER_SHIFT
#define DMA_ATTR_SMOD_MASK DMA4_ATTR_SMOD_MASK
#define DMA_ATTR_DMOD_MASK DMA4_ATTR_DMOD_MASK
#define DMA_CITER_ELINKNO_ELINK_MASK DMA4_CITER_ELINKNO_ELINK_MASK
#define DMA_CSR_MAJORELINK_MASK DMA4_CSR_MAJORELINK_MASK
#define DMA_BITER_ELINKYES_ELINK_MASK DMA4_BITER_ELINKYES_ELINK_MASK
#define DMA_CITER_ELINKYES_ELINK_MASK DMA4_CITER_ELINKYES_ELINK_MASK
#define DMA_CSR_MAJORLINKCH_MASK DMA4_CSR_MAJORLINKCH_MASK
#define DMA_BITER_ELINKYES_LINKCH_MASK DMA4_BITER_ELINKYES_LINKCH_MASK
#define DMA_CITER_ELINKYES_LINKCH_MASK DMA4_CITER_ELINKYES_LINKCH_MASK
#define DMA_NBYTES_MLOFFYES_MLOFF_MASK DMA4_NBYTES_MLOFFYES_MLOFF_MASK
#define DMA_NBYTES_MLOFFYES_DMLOE_MASK DMA4_NBYTES_MLOFFYES_DMLOE_MASK
#define DMA_NBYTES_MLOFFYES_SMLOE_MASK DMA4_NBYTES_MLOFFYES_SMLOE_MASK
#define DMA_ATTR_DMOD(x) DMA4_ATTR_DMOD(x)
#define DMA_ATTR_SMOD(X) DMA4_ATTR_SMOD(X)
#define DMA_BITER_ELINKYES_LINKCH(x) DMA4_BITER_ELINKYES_LINKCH(x)
#define DMA_CITER_ELINKYES_LINKCH(x) DMA4_CITER_ELINKYES_LINKCH(x)
#define DMA_NBYTES_MLOFFYES_MLOFF(x) DMA4_NBYTES_MLOFFYES_MLOFF(x)
#define DMA_NBYTES_MLOFFYES_DMLOE(x) DMA4_NBYTES_MLOFFYES_DMLOE(x)
#define DMA_NBYTES_MLOFFYES_SMLOE(x) DMA4_NBYTES_MLOFFYES_SMLOE(x)
#define DMA_NBYTES_MLOFFNO_NBYTES(x) DMA4_NBYTES_MLOFFNO_NBYTES(x)
#define DMA_NBYTES_MLOFFYES_NBYTES(x) DMA4_NBYTES_MLOFFYES_NBYTES(x)
#define DMA_ATTR_DSIZE(x) DMA4_ATTR_DSIZE(x)
#define DMA_ATTR_SSIZE(x) DMA4_ATTR_SSIZE(x)
#define DMA_CSR_DREQ(x) DMA4_CSR_DREQ(x)
#define DMA_CSR_MAJORLINKCH(x) DMA4_CSR_MAJORLINKCH(x)
#define DMA_CH_MATTR_WCACHE(x) DMA4_CH_MATTR_WCACHE(x)
#define DMA_CH_MATTR_RCACHE(x) DMA4_CH_MATTR_RCACHE(x)
#define DMA_CH_CSR_SIGNEXT_MASK DMA4_CH_CSR_SIGNEXT_MASK
#define DMA_CH_CSR_SIGNEXT_SHIFT DMA4_CH_CSR_SIGNEXT_SHIFT
#define DMA_CH_CSR_SWAP_MASK DMA4_CH_CSR_SWAP_MASK
#define DMA_CH_CSR_SWAP_SHIFT DMA4_CH_CSR_SWAP_SHIFT
#define DMA_CH_SBR_INSTR_MASK DMA4_CH_SBR_INSTR_MASK
#define DMA_CH_SBR_INSTR_SHIFT DMA4_CH_SBR_INSTR_SHIFT
#define DMA_CH_MUX_SOURCE(x) DMA4_CH_MUX_SRC(x)
#define DMA_CH_CSR_DONE_MASK DMA4_CH_CSR_DONE_MASK
#define DMA_CH_CSR_ERQ_MASK DMA4_CH_CSR_ERQ_MASK
#elif defined(FSL_EDMA_SOC_IP_EDMA) && FSL_EDMA_SOC_IP_EDMA
/*! intentional empty */
#endif
/*! @brief DMA error flag */
#if defined(FSL_EDMA_SOC_IP_EDMA) && FSL_EDMA_SOC_IP_EDMA
#define DMA_ERR_DBE_FLAG DMA_ES_DBE_MASK
#define DMA_ERR_SBE_FLAG DMA_ES_SBE_MASK
#define DMA_ERR_SGE_FLAG DMA_ES_SGE_MASK
#define DMA_ERR_NCE_FLAG DMA_ES_NCE_MASK
#define DMA_ERR_DOE_FLAG DMA_ES_DOE_MASK
#define DMA_ERR_DAE_FLAG DMA_ES_DAE_MASK
#define DMA_ERR_SOE_FLAG DMA_ES_SOE_MASK
#define DMA_ERR_SAE_FLAG DMA_ES_SAE_MASK
#define DMA_ERR_ERRCHAN_FLAG DMA_ES_ERRCHN_MASK
#define DMA_ERR_CPE_FLAG DMA_ES_CPE_MASK
#define DMA_ERR_ECX_FLAG DMA_ES_ECX_MASK
#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && (FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1)
#define DMA_ERR_GPE_FLAG DMA_ES_GPE_MASK
#endif
#define DMA_ERR_FLAG DMA_ES_VLD_MASK
/*! @brief get/clear DONE status*/
#define DMA_CLEAR_DONE_STATUS(base, channel) (EDMA_BASE(base)->CDNE = (uint8_t)channel)
#define DMA_GET_DONE_STATUS(base, channel) \
((EDMA_TCD_BASE(base, channel)->CSR & DMA_CSR_DONE_MASK) >> DMA_CSR_DONE_SHIFT)
/*! @brief enable/disable error interrupt*/
#define DMA_ENABLE_ERROR_INT(base, channel) (base->EEI |= ((uint32_t)0x1U << channel))
#define DMA_DISABLE_ERROR_INT(base, channel) (base->EEI &= (~((uint32_t)0x1U << channel)))
/*! @brief get/clear error status*/
#define DMA_GET_ERROR_STATUS(base, channel) (((uint32_t)EDMA_BASE(base)->ERR >> channel) & 0x1U)
#define DMA_CLEAR_ERROR_STATUS(base, channel) ((uint32_t)EDMA_BASE(base)->CERR = (uint8_t)channel)
/*! @brief get/clear int status*/
#define DMA_GET_INT_STATUS(base, channel) ((((uint32_t)EDMA_BASE(base)->INT >> channel) & 0x1U))
#define DMA_CLEAR_INT_STATUS(base, channel) ((uint32_t)EDMA_BASE(base)->CINT = (uint8_t)channel)
#else
#define DMA_ERR_DBE_FLAG DMA_MP_ES_DBE_MASK
#define DMA_ERR_SBE_FLAG DMA_MP_ES_SBE_MASK
#define DMA_ERR_SGE_FLAG DMA_MP_ES_SGE_MASK
#define DMA_ERR_NCE_FLAG DMA_MP_ES_NCE_MASK
#define DMA_ERR_DOE_FLAG DMA_MP_ES_DOE_MASK
#define DMA_ERR_DAE_FLAG DMA_MP_ES_DAE_MASK
#define DMA_ERR_SOE_FLAG DMA_MP_ES_SOE_MASK
#define DMA_ERR_SAE_FLAG DMA_MP_ES_SAE_MASK
#define DMA_ERR_ERRCHAN_FLAG DMA_MP_ES_ERRCHN_MASK
#define DMA_ERR_ECX_FLAG DMA_MP_ES_ECX_MASK
#define DMA_ERR_FLAG DMA_MP_ES_VLD_MASK
/*! @brief get/clear DONE bit*/
#define DMA_CLEAR_DONE_STATUS(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_CSR |= DMA_CH_CSR_DONE_MASK)
#define DMA_GET_DONE_STATUS(base, channel) \
((EDMA_CHANNEL_BASE(base, channel)->CH_CSR & DMA_CH_CSR_DONE_MASK) >> DMA_CH_CSR_DONE_SHIFT)
/*! @brief enable/disable error interupt*/
#define DMA_ENABLE_ERROR_INT(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_CSR |= DMA_CH_CSR_EEI_MASK)
#define DMA_DISABLE_ERROR_INT(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_CSR &= ~DMA_CH_CSR_EEI_MASK)
/*! @brief get/clear error status*/
#define DMA_CLEAR_ERROR_STATUS(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_ES |= DMA_CH_ES_ERR_MASK)
#define DMA_GET_ERROR_STATUS(base, channel) \
(((uint32_t)EDMA_CHANNEL_BASE(base, channel)->CH_ES >> DMA_CH_ES_ERR_SHIFT) & 0x1U)
/*! @brief get/clear INT status*/
#define DMA_CLEAR_INT_STATUS(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_INT = DMA_CH_INT_INT_MASK)
#define DMA_GET_INT_STATUS(base, channel) ((((uint32_t)EDMA_CHANNEL_BASE(base, channel)->CH_INT) & 0x1U))
#endif /*FSL_EDMA_SOC_IP_EDMA*/
/*! @brief enable/dsiable MAJOR/HALF INT*/
#define DMA_ENABLE_MAJOR_INT(base, channel) (EDMA_TCD_BASE(base, channel)->CSR |= DMA_CSR_INTMAJOR_MASK)
#define DMA_ENABLE_HALF_INT(base, channel) (EDMA_TCD_BASE(base, channel)->CSR |= DMA_CSR_INTHALF_MASK)
#define DMA_DISABLE_MAJOR_INT(base, channel) (EDMA_TCD_BASE(base, channel)->CSR &= ~(uint16_t)DMA_CSR_INTMAJOR_MASK)
#define DMA_DISABLE_HALF_INT(base, channel) (EDMA_TCD_BASE(base, channel)->CSR &= ~(uint16_t)DMA_CSR_INTHALF_MASK)
/*!@brief EDMA tcd align size */
#define EDMA_TCD_ALIGN_SIZE (32U)
/*!@brief edma core channel struture definition */
typedef struct _edma_core_mp
{
__IO uint32_t MP_CSR; /**< Channel Control and Status, array offset: 0x10000, array step: 0x10000 */
__IO uint32_t MP_ES; /**< Channel Error Status, array offset: 0x10004, array step: 0x10000 */
} edma_core_mp_t;
/*!@brief edma core channel struture definition */
typedef struct _edma_core_channel
{
__IO uint32_t CH_CSR; /**< Channel Control and Status, array offset: 0x10000, array step: 0x10000 */
__IO uint32_t CH_ES; /**< Channel Error Status, array offset: 0x10004, array step: 0x10000 */
__IO uint32_t CH_INT; /**< Channel Interrupt Status, array offset: 0x10008, array step: 0x10000 */
__IO uint32_t CH_SBR; /**< Channel System Bus, array offset: 0x1000C, array step: 0x10000 */
__IO uint32_t CH_PRI; /**< Channel Priority, array offset: 0x10010, array step: 0x10000 */
__IO uint32_t CH_MUX; /**< Channel Multiplexor Configuration, array offset: 0x10014, array step: 0x10000 */
__IO uint16_t CH_MATTR; /**< Memory Attributes Register, array offset: 0x10018, array step: 0x8000 */
} edma_core_channel_t;
/*!@brief edma core TCD struture definition */
typedef struct _edma_core_tcd
{
__IO uint32_t SADDR; /*!< SADDR register, used to save source address */
__IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
__IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
__IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
__IO uint32_t SLAST; /*!< SLAST register */
__IO uint32_t DADDR; /*!< DADDR register, used for destination address */
__IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
__IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
__IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next tcd address used in scatter-gather mode */
__IO uint16_t CSR; /*!< CSR register, for TCD control status */
__IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
} edma_core_tcd_t;
/*!@brief EDMA typedef */
typedef edma_core_channel_t EDMA_ChannelType;
typedef edma_core_tcd_t EDMA_TCDType;
typedef void EDMA_Type;
/*!@brief EDMA base address convert macro */
#define EDMA_BASE(base)
#define EDMA_CHANNEL_BASE(base, channel) \
((edma_core_channel_t *)((uint32_t)(uint32_t *)(base) + EDMA_CHANNEL_OFFSET + \
(channel)*EDMA_CHANNEL_ARRAY_STEP(base)))
#define EDMA_TCD_BASE(base, channel) \
((edma_core_tcd_t *)((uint32_t)(uint32_t *)(base) + EDMA_CHANNEL_OFFSET + \
(channel)*EDMA_CHANNEL_ARRAY_STEP(base) + 0x20U))
#define EDMA_MP_BASE(base) ((edma_core_mp_t *)((uint32_t)(uint32_t *)(base)))
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
/*!
* @}
*/
#endif /* _FSL_EDMA_CORE_H_ */

View File

@ -0,0 +1,69 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_edma_soc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.edma_soc"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
extern void DMA_CH0_DriverIRQHandler(void);
extern void DMA_CH1_DriverIRQHandler(void);
extern void DMA_CH2_DriverIRQHandler(void);
extern void DMA_CH3_DriverIRQHandler(void);
extern void EDMA_DriverIRQHandler(uint32_t instance, uint32_t channel);
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief DMA instance 0, channel 0 IRQ handler.
*
*/
void DMA_CH0_DriverIRQHandler(void)
{
/* Instance 0 channel 0 */
EDMA_DriverIRQHandler(0U, 0U);
}
/*!
* brief DMA instance 0, channel 1 IRQ handler.
*
*/
void DMA_CH1_DriverIRQHandler(void)
{
/* Instance 0 channel 1 */
EDMA_DriverIRQHandler(0U, 1U);
}
/*!
* brief DMA instance 0, channel 2 IRQ handler.
*
*/
void DMA_CH2_DriverIRQHandler(void)
{
/* Instance 0 channel 2 */
EDMA_DriverIRQHandler(0U, 2U);
}
/*!
* brief DMA instance 0, channel 3 IRQ handler.
*
*/
void DMA_CH3_DriverIRQHandler(void)
{
/* Instance 0 channel 3 */
EDMA_DriverIRQHandler(0U, 3U);
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_EDMA_SOC_H_
#define _FSL_EDMA_SOC_H_
#include "fsl_common.h"
/*!
* @addtogroup edma_soc
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Driver version 2.0.0. */
#define FSL_EDMA_SOC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*!@brief DMA IP version */
#define FSL_EDMA_SOC_IP_DMA3 (1)
#define FSL_EDMA_SOC_IP_DMA4 (0)
/*!@brief DMA base table */
#define EDMA_BASE_PTRS \
{ \
DMA0 \
}
#define EDMA_CHN_IRQS \
{ \
{ \
DMA_CH0_IRQn, DMA_CH1_IRQn, DMA_CH2_IRQn, DMA_CH3_IRQn \
} \
}
/*!@brief EDMA base address convert macro */
#define EDMA_CHANNEL_OFFSET 0x1000U
#define EDMA_CHANNEL_ARRAY_STEP(base) (0x1000U)
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
/*!
* @}
*/
#endif /* _FSL_EDMA_SOC_H_ */

View File

@ -0,0 +1,312 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_eim.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.eim"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to EIM bases for each instance. */
static EIM_Type *const s_eimBases[] = EIM_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to EIM clocks for each instance. */
static const clock_ip_name_t s_eimClocks[] = EIM_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t EIM_GetInstance(EIM_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_eimBases); instance++)
{
if (s_eimBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_eimBases));
return instance;
}
/*!
* brief EIM module initialization function.
*
* param base EIM base address.
*/
void EIM_Init(EIM_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EIM clock. */
CLOCK_EnableClock(s_eimClocks[EIM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
base->EIMCR = 0x00U;
base->EICHEN = 0x00U;
}
/*!
* brief Deinitializes the EIM.
*
*/
void EIM_Deinit(EIM_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EIM clock. */
CLOCK_DisableClock(s_eimClocks[EIM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void EIM_InjectCheckBitError(EIM_Type *base, eim_memory_channel_t channel, uint8_t mask)
{
switch ((uint8_t)channel)
{
case 0U:
base->EICHD0_WORD0 = EIM_EICHD0_WORD0_CHKBIT_MASK(mask);
break;
#ifdef EIM_EICHEN_EICH1EN_MASK
case 1U:
base->EICHD1_WORD0 = EIM_EICHD1_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH2EN_MASK
case 2U:
base->EICHD2_WORD0 = EIM_EICHD2_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH3EN_MASK
case 3U:
base->EICHD3_WORD0 = EIM_EICHD3_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH4EN_MASK
case 4U:
base->EICHD4_WORD0 = EIM_EICHD4_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH5EN_MASK
case 5U:
base->EICHD5_WORD0 = EIM_EICHD5_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH6EN_MASK
case 6U:
base->EICHD6_WORD0 = EIM_EICHD6_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH7EN_MASK
case 7U:
base->EICHD7_WORD0 = EIM_EICHD7_WORD0_CHKBIT_MASK(mask);
break;
#endif
#ifdef EIM_EICHEN_EICH8EN_MASK
case 8U:
base->EICHD8_WORD0 = EIM_EICHD8_WORD0_CHKBIT_MASK(mask);
break;
#endif
default:
assert(NULL);
break;
}
}
uint8_t EIM_GetCheckBitMask(EIM_Type *base, eim_memory_channel_t channel)
{
uint8_t mask = 0x00U;
switch ((uint8_t)channel)
{
case 0U:
mask = (uint8_t)((base->EICHD0_WORD0 & EIM_EICHD0_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD0_WORD0_CHKBIT_MASK_SHIFT);
break;
#ifdef EIM_EICHEN_EICH1EN_MASK
case 1U:
mask = (uint8_t)((base->EICHD1_WORD0 & EIM_EICHD1_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD1_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH2EN_MASK
case 2U:
mask = (uint8_t)((base->EICHD2_WORD0 & EIM_EICHD2_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD2_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH3EN_MASK
case 3U:
mask = (uint8_t)((base->EICHD3_WORD0 & EIM_EICHD3_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD3_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH4EN_MASK
case 4U:
mask = (uint8_t)((base->EICHD4_WORD0 & EIM_EICHD4_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD4_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH5EN_MASK
case 5U:
mask = (uint8_t)((base->EICHD5_WORD0 & EIM_EICHD5_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD5_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH6EN_MASK
case 6U:
mask = (uint8_t)((base->EICHD6_WORD0 & EIM_EICHD6_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD6_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH7EN_MASK
case 7U:
mask = (uint8_t)((base->EICHD7_WORD0 & EIM_EICHD7_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD7_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
#ifdef EIM_EICHEN_EICH8EN_MASK
case 8U:
mask = (uint8_t)((base->EICHD8_WORD0 & EIM_EICHD8_WORD0_CHKBIT_MASK_MASK) >>
EIM_EICHD8_WORD0_CHKBIT_MASK_SHIFT);
break;
#endif
default:
assert(NULL);
break;
}
return mask;
}
void EIM_InjectDataBitError(EIM_Type *base, eim_memory_channel_t channel, uint8_t mask)
{
switch ((uint8_t)channel)
{
case 0U:
base->EICHD0_WORD1 = mask;
break;
#ifdef EIM_EICHEN_EICH1EN_MASK
case 1U:
base->EICHD1_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH2EN_MASK
case 2U:
base->EICHD2_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH3EN_MASK
case kEIM_MemoryChannelRAMC:
base->EICHD3_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH4EN_MASK
case kEIM_MemoryChannelRAMD:
base->EICHD4_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH5EN_MASK
case kEIM_MemoryChannelRAME:
base->EICHD5_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH6EN_MASK
case kEIM_MemoryChannelRAMF:
base->EICHD6_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH7EN_MASK
case kEIM_MemoryChannelLPCACRAM:
base->EICHD7_WORD1 = mask;
break;
#endif
#ifdef EIM_EICHEN_EICH8EN_MASK
case kEIM_MemoryChannelPKCRAM:
base->EICHD8_WORD1 = mask;
break;
#endif
default:
assert(NULL);
break;
}
}
uint32_t EIM_GetDataBitMask(EIM_Type *base, eim_memory_channel_t channel)
{
uint32_t mask = 0x00U;
switch ((uint8_t)channel)
{
case 0U:
mask = (base->EICHD0_WORD0 & EIM_EICHD0_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD0_WORD1_B0_3DATA_MASK_SHIFT;
break;
#ifdef EIM_EICHEN_EICH1EN_MASK
case 1U:
mask = (base->EICHD1_WORD0 & EIM_EICHD1_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD1_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH2EN_MASK
case 2U:
mask = (base->EICHD2_WORD0 & EIM_EICHD2_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD2_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH3EN_MASK
case 3U:
mask = (base->EICHD3_WORD0 & EIM_EICHD3_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD3_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH4EN_MASK
case 4U:
mask = (base->EICHD4_WORD0 & EIM_EICHD4_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD4_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH5EN_MASK
case 5U:
mask = (base->EICHD5_WORD0 & EIM_EICHD5_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD5_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH6EN_MASK
case 6U:
mask = (base->EICHD6_WORD0 & EIM_EICHD6_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD6_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH7EN_MASK
case 7U:
mask = (base->EICHD7_WORD0 & EIM_EICHD7_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD7_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
#ifdef EIM_EICHEN_EICH8EN_MASK
case 8U:
mask = (base->EICHD8_WORD1 & EIM_EICHD8_WORD1_B0_3DATA_MASK_MASK) >> EIM_EICHD8_WORD1_B0_3DATA_MASK_SHIFT;
break;
#endif
default:
assert(NULL);
break;
}
return mask;
}

View File

@ -0,0 +1,144 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_EIM_H_
#define _FSL_EIM_H_
#include "fsl_common.h"
/*!
* @addtogroup eim
* @{
*/
/******************************************************************************
* Definitions.
*****************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Driver version. */
#define FSL_ERM_DRIVER_VERSION (MAKE_VERSION(2U, 0U, 1U))
/*@}*/
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief EIM module initialization function.
*
* @param base EIM base address.
*/
void EIM_Init(EIM_Type *base);
/*!
* @brief De-initializes the EIM.
*
*/
void EIM_Deinit(EIM_Type *base);
/* @} */
/*!
* @name functional
* @{
*/
/*!
* @brief EIM module enable global error injection.
*
* @param base EIM base address.
* @param mask The interrupts to enable.
*/
static inline void EIM_EnableGlobalErrorInjection(EIM_Type *base, bool enable)
{
if (enable)
{
base->EIMCR = EIM_EIMCR_GEIEN_MASK;
}
else
{
base->EIMCR = ~EIM_EIMCR_GEIEN_MASK;
}
}
/*!
* @brief EIM module enable error injection for memory channel n, this function enables the corresponding error
* injection channel. The Global Error Injection Enable function must also be called to enable error injection.
*
* @param base EIM base address.
* @param mask The interrupts to enable. Refer to "_eim_error_injection_channel_enable" enumeration.
*/
static inline void EIM_EnableErrorInjectionChannels(EIM_Type *base, uint32_t mask)
{
base->EICHEN |= mask;
}
/*!
* @brief EIM module disable error injection for memory channel n.
*
* @param base EIM base address.
* @param mask The interrupts to enable. Refer to "_eim_error_injection_channel_enable" enumeration.
*/
static inline void EIM_DisableErrorInjectionChannels(EIM_Type *base, uint32_t mask)
{
base->EICHEN &= ~mask;
}
/*!
* @brief EIM module inject checkbit error for memory channel n, an attempt to invert more than 2 bits in one operation
* might result in undefined behavior.
*
* @param base EIM base address.
* @param channel memory channel.
* @param mask The interrupts to enable.
*/
void EIM_InjectCheckBitError(EIM_Type *base, eim_memory_channel_t channel, uint8_t mask);
/*!
* @brief EIM module get checkbit mask for memory channel n.
*
* @param base EIM base address.
* @param channel memory channel.
* @retval return checkbit mask.
*/
uint8_t EIM_GetCheckBitMask(EIM_Type *base, eim_memory_channel_t channel);
/*!
* @brief EIM module inject databit error for memory channel n, an attempt to invert more than 2 bits in one operation
* might result in undefined behavior.
*
* @param base EIM base address.
* @param channel memory channel.
* @param mask The interrupts to enable.
*/
void EIM_InjectDataBitError(EIM_Type *base, eim_memory_channel_t channel, uint8_t mask);
/*!
* @brief EIM module get databit mask for memory channel n.
*
* @param base EIM base address.
* @param channel memory channel.
* @retval return checkbit mask.
*/
uint32_t EIM_GetDataBitMask(EIM_Type *base, eim_memory_channel_t channel);
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif

View File

@ -0,0 +1,298 @@
/*
* Copyright 2022, 2023 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_eqdc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.eqdc"
#endif
#if defined(EQDC_RSTS)
#define EQDC_RESETS_ARRAY EQDC_RSTS
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for EQDC module.
*
* @param base EQDC peripheral base address
*/
static uint32_t EQDC_GetInstance(EQDC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to EQDC bases for each instance. */
static EQDC_Type *const s_eqdcBases[] = EQDC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to EQDC clocks for each instance. */
#if defined(QDC_CLOCKS)
static const clock_ip_name_t s_eqdcClocks[] = QDC_CLOCKS;
#elif defined(ENC_CLOCKS)
static const clock_ip_name_t s_eqdcClocks[] = ENC_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(EQDC_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_eqdcResets[] = EQDC_RESETS_ARRAY;
#endif
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t EQDC_GetInstance(EQDC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_eqdcBases); instance++)
{
if (s_eqdcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_eqdcBases));
return instance;
}
/*
* Initializes the EQDC module.
*
* This function initializes the EQDC by enabling the IP bus clock (optional).
*
* param base EQDC peripheral base address.
* param psConfig Pointer to configuration structure.
*/
void EQDC_Init(EQDC_Type *base, const eqdc_config_t *psConfig)
{
assert(NULL != psConfig);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_eqdcClocks[EQDC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(EQDC_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_eqdcResets[EQDC_GetInstance(base)]);
#endif
/* Initialize Double-set registers */
EQDC_ClearBufferedRegisterLoadUpdateMode(base);
EQDC_ClearEqdcLdok(base);
/* Counter value. */
EQDC_SetPositionCounterValue(base, psConfig->positionCounterValue);
/* Initial value. */
EQDC_SetInitialPositionValue(base, psConfig->positionInitialValue);
/* Modulus value. */
EQDC_SetPositionModulusValue(base, psConfig->positionModulusValue);
/* Compare value. */
EQDC_SetPositionCompare0Value(base, psConfig->positionCompareValue[0]);
EQDC_SetPositionCompare1Value(base, psConfig->positionCompareValue[1]);
EQDC_SetPositionCompare2Value(base, psConfig->positionCompareValue[2]);
EQDC_SetPositionCompare3Value(base, psConfig->positionCompareValue[3]);
EQDC_SetEqdcLdok(base);
while (EQDC_GetEqdcLdok(base) != 0U)
{
}
/* Watchdog. */
EQDC_SetWatchdogTimeout(base, psConfig->watchdogTimeoutValue);
/* EQDC_IMR. */
base->IMR = EQDC_IMR_FPHA(psConfig->filterPhaseA) | EQDC_IMR_FPHB(psConfig->filterPhaseB) |
EQDC_IMR_FIND_PRE(psConfig->filterIndPre) | EQDC_IMR_FHOM_ENA(psConfig->filterHomEna);
/* EQDC_FILT. */
base->FILT = EQDC_FILT_PRSC(psConfig->prescaler) | /* Prescaler used by LASTEDGE and POSDPER. */
EQDC_FILT_FILT_CS(psConfig->filterClockSourceselection) |
EQDC_FILT_FILT_CNT(psConfig->filterSampleCount) | EQDC_FILT_FILT_PER(psConfig->filterSamplePeriod);
/* EQDC_CTRL. */
base->CTRL = EQDC_CTRL_W1C_FLAGS | /* W1C flags. */
(uint16_t)psConfig->homeEnableInitPosCounterMode | /* HOME Enable trigger. */
(uint16_t)psConfig->indexPresetInitPosCounterMode | /* INDEX Preset trigger. */
EQDC_CTRL_REV(psConfig->enableReverseDirection) | /* Reverse direction. */
EQDC_CTRL_WDE(psConfig->enableWatchdog) | /* Enable watchdog. */
EQDC_CTRL_DMAEN(psConfig->enableDma); /* Enable Dma. */
/* Set mode of count. */
EQDC_SetCountMode(base, psConfig->countMode); /* eqdcoder count mode. */
/* EQDC_CTRL2. */
base->CTRL2 =
EQDC_CTRL2_ONCE(psConfig->countOnce) |
EQDC_CTRL2_INITPOS(psConfig->enableTriggerInitPositionCounter) | /* TRIGGER initializes position counter. */
#if (defined(FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD) && FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD)
EQDC_CTRL2_EMIP(psConfig->enableIndexInitPositionCounter)| /* Index Event Edge Mark initializes position counter */
#endif /* FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD */
EQDC_CTRL2_PMEN(psConfig->enablePeriodMeasurement) | /* Enable period measurement. */
EQDC_CTRL2_OUTCTL(psConfig->outputPulseMode) | /* Output pulse. */
EQDC_CTRL2_REVMOD(psConfig->revolutionCountCondition) | /* Revolution count condition. */
EQDC_CTRL2_LDMOD(psConfig->bufferedRegisterLoadMode) | /* Buffered register load (Update) mode select. */
EQDC_CTRL2_UPDPOS(psConfig->enableTriggerClearPositionRegisters) | /* TRIGGER clears position register. */
EQDC_CTRL2_UPDHLD(psConfig->enableTriggerHoldPositionRegisters); /* TRIGGER loads position registers. */
/* Set mode of operation. */
EQDC_SetOperateMode(base, psConfig->operateMode); /* eqdcoder work mode. */
/* Enable interrupts. */
EQDC_EnableInterrupts(base, psConfig->enabledInterruptsMask);
}
/*
* De-initializes the EQDC module.
*
* This function deinitializes the EQDC by:
* 1. Disables the IP bus clock (optional).
*
* param base EQDC peripheral base address.
*/
void EQDC_Deinit(EQDC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_eqdcClocks[EQDC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* Gets an available pre-defined configuration.
*
* The default value are:
* psConfig->enableReverseDirection = false;
* psConfig->countOnce = false;
* psConfig->operateMode = kEQDC_QuadratureDecodeOperationMode;
* psConfig->countMode = kEQDC_QuadratureX4;
* psConfig->homeEnableInitPosCounterMode = kEQDC_HomeInitPosCounterDisabled;
* psConfig->indexPresetInitPosCounterMode = kEQDC_IndexInitPosCounterDisabled;
* psConfig->enableIndexInitPositionCounter = false;
* psConfig->enableDma = false;
* psConfig->bufferedRegisterLoadMode = false;
* psConfig->enableTriggerInitPositionCounter = false;
* psConfig->enableTriggerClearPositionRegisters = false;
* psConfig->enableTriggerHoldPositionRegisters = false;
* psConfig->enableWatchdog = false;
* psConfig->watchdogTimeoutValue = 0xFFFFU;
* psConfig->filterPhaseA = 0U;
* psConfig->filterPhaseB = 0U;
* psConfig->filterIndPre = 0U;
* psConfig->filterHomEna = 0U;
* psConfig->filterClockSourceselection = false;
* psConfig->filterSampleCount = kEQDC_Filter3Samples;
* psConfig->filterSamplePeriod = 0U;
* psConfig->outputPulseMode = kEQDC_OutputPulseOnCounterEqualCompare;
* psConfig->positionCompareValue[0] = 0xFFFFFFFFU;
* psConfig->positionCompareValue[1] = 0xFFFFFFFFU;
* psConfig->positionCompareValue[2] = 0xFFFFFFFFU;
* psConfig->positionCompareValue[3] = 0xFFFFFFFFU;
* psConfig->revolutionCountCondition = kEQDC_RevolutionCountOnIndexPulse;
* psConfig->positionModulusValue = 0U;
* psConfig->positionInitialValue = 0U;
* psConfig->positionCounterValue = 0U;
* psConfig->enablePeriodMeasurement = false;
* psConfig->prescaler = kEQDC_Prescaler1;
* psConfig->enabledInterruptsMask = 0U;
*
* param psConfig Pointer to configuration structure.
*/
void EQDC_GetDefaultConfig(eqdc_config_t *psConfig)
{
assert(NULL != psConfig);
psConfig->enableReverseDirection = false;
psConfig->countOnce = false;
psConfig->operateMode = kEQDC_QuadratureDecodeOperationMode; /*!< Decode Mode. */
psConfig->countMode = kEQDC_QuadratureX4;
psConfig->homeEnableInitPosCounterMode = kEQDC_HomeInitPosCounterDisabled;
psConfig->indexPresetInitPosCounterMode = kEQDC_IndexInitPosCounterDisabled;
#if (defined(FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD) && FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD)
psConfig->enableIndexInitPositionCounter = false;
#endif /* FSL_FEATURE_EQDC_CTRL2_HAS_EMIP_BIT_FIELD */
psConfig->enableDma = false;
psConfig->bufferedRegisterLoadMode = false;
psConfig->enableTriggerInitPositionCounter = false;
psConfig->enableTriggerClearPositionRegisters = false;
psConfig->enableTriggerHoldPositionRegisters = false;
psConfig->enableWatchdog = false;
psConfig->watchdogTimeoutValue = 0xFFFFU;
psConfig->filterPhaseA = 0U;
psConfig->filterPhaseB = 0U;
psConfig->filterIndPre = 0U;
psConfig->filterHomEna = 0U;
psConfig->filterClockSourceselection = false;
psConfig->filterSampleCount = kEQDC_Filter3Samples;
psConfig->filterSamplePeriod = 0U;
psConfig->outputPulseMode = kEQDC_OutputPulseOnCounterEqualCompare;
psConfig->positionCompareValue[0] = 0xFFFFFFFFU;
psConfig->positionCompareValue[1] = 0xFFFFFFFFU;
psConfig->positionCompareValue[2] = 0xFFFFFFFFU;
psConfig->positionCompareValue[3] = 0xFFFFFFFFU;
psConfig->revolutionCountCondition = kEQDC_RevolutionCountOnIndexPulse;
psConfig->positionModulusValue = 0U;
psConfig->positionInitialValue = 0U;
psConfig->positionCounterValue = 0U;
psConfig->enablePeriodMeasurement = false;
psConfig->prescaler = kEQDC_Prescaler1;
psConfig->enabledInterruptsMask = 0U;
}
/*
* Initializes the mode of operation.
*
* The Quadrature Decoder operates in following 4 operation modes:
* 1.Quadrature Decode(QDC) Operation Mode (CTRL[PH1] = 0,CTRL2[OPMODE] = 0)
* 2.Quadrature Count(QCT) Operation Mode (CTRL[PH1] = 0,CTRL2[OPMODE] = 1)
* 3.Single Phase Decode(PH1DC) Operation Mode (CTRL[PH1] = 1,CTRL2[OPMODE] = 0)
* 4.Single Phase Count(PH1CT) Operation Mode (CTRL[PH1] = 1,CTRL2[OPMODE] = 1)
*
* param base EQDC peripheral base address.
* param psConfig Pointer to configuration structure.
*/
void EQDC_SetOperateMode(EQDC_Type *base, eqdc_operate_mode_t operateMode)
{
switch (operateMode)
{
case kEQDC_QuadratureDecodeOperationMode:
base->CTRL &= ~EQDC_CTRL_PH1_MASK;
base->CTRL2 &= ~EQDC_CTRL2_OPMODE_MASK;
break;
case kEQDC_QuadratureCountOperationMode:
base->CTRL &= ~EQDC_CTRL_PH1_MASK;
base->CTRL2 |= EQDC_CTRL2_OPMODE_MASK;
break;
case kEQDC_SinglePhaseDecodeOperationMode:
base->CTRL |= EQDC_CTRL_PH1_MASK;
base->CTRL2 &= ~EQDC_CTRL2_OPMODE_MASK;
break;
case kEQDC_SinglePhaseCountOperationMode:
base->CTRL |= EQDC_CTRL_PH1_MASK;
base->CTRL2 |= EQDC_CTRL2_OPMODE_MASK;
break;
default:
assert(false);
break;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,317 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_erm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.erm"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to ERM bases for each instance. */
static ERM_Type *const s_ermBases[] = ERM_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to ERM clocks for each instance. */
static const clock_ip_name_t s_ermClocks[] = ERM_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t ERM_GetInstance(ERM_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_ermBases); instance++)
{
if (s_ermBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_ermBases));
return instance;
}
/*!
* brief ERM module initialization function.
*
* param base ERM base address.
*/
void ERM_Init(ERM_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate ERM clock. */
CLOCK_EnableClock(s_ermClocks[ERM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
base->CR0 = 0x00U;
#ifdef ERM_CR1_ENCIE8_MASK
base->CR1 = 0x00U;
#endif
base->SR0 = 0xFFFFFFFFU;
#ifdef ERM_SR1_SBC8_MASK
base->SR1 = 0xFFFFFFFFU;
#endif
}
/*!
* brief Deinitializes the ERM.
*
*/
void ERM_Deinit(ERM_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate ERM clock. */
CLOCK_DisableClock(s_ermClocks[ERM_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
uint32_t ERM_GetMemoryErrorAddr(ERM_Type *base, erm_memory_channel_t channel)
{
uint32_t absoluteErrorAddress = 0x00U;
switch ((uint8_t)channel)
{
case 0U:
absoluteErrorAddress = base->EAR0;
break;
#ifdef ERM_EAR1_EAR_MASK
case 1U:
absoluteErrorAddress = base->EAR1;
break;
#endif
#ifdef ERM_EAR2_EAR_MASK
case 2U:
absoluteErrorAddress = base->EAR2;
break;
#endif
#ifdef ERM_EAR3_EAR_MASK
case 3U:
absoluteErrorAddress = base->EAR3;
break;
#endif
#ifdef ERM_EAR4_EAR_MASK
case 4U:
absoluteErrorAddress = base->EAR4;
break;
#endif
#ifdef ERM_EAR5_EAR_MASK
case 5U:
absoluteErrorAddress = base->EAR5;
break;
#endif
#ifdef ERM_EAR6_EAR_MASK
case 6U:
absoluteErrorAddress = base->EAR6;
break;
#endif
default:
assert(NULL);
break;
}
return absoluteErrorAddress;
}
uint32_t ERM_GetSyndrome(ERM_Type *base, erm_memory_channel_t channel)
{
uint32_t syndrome = 0x00U;
switch ((uint8_t)channel)
{
case 0U:
syndrome = (base->SYN0 & ERM_SYN0_SYNDROME_MASK) >> ERM_SYN0_SYNDROME_SHIFT;
break;
#ifdef ERM_SYN1_SYNDROME_MASK
case 1U:
syndrome = (base->SYN1 & ERM_SYN1_SYNDROME_MASK) >> ERM_SYN1_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN2_SYNDROME_MASK
case 2U:
syndrome = (base->SYN2 & ERM_SYN2_SYNDROME_MASK) >> ERM_SYN2_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN3_SYNDROME_MASK
case 3U:
syndrome = (base->SYN3 & ERM_SYN3_SYNDROME_MASK) >> ERM_SYN3_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN4_SYNDROME_MASK
case 4U:
syndrome = (base->SYN4 & ERM_SYN4_SYNDROME_MASK) >> ERM_SYN4_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN5_SYNDROME_MASK
case 5U:
syndrome = (base->SYN5 & ERM_SYN5_SYNDROME_MASK) >> ERM_SYN5_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN6_SYNDROME_MASK
case 6U:
syndrome = (base->SYN6 & ERM_SYN6_SYNDROME_MASK) >> ERM_SYN6_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN7_SYNDROME_MASK
case 7U:
syndrome = (base->SYN7 & ERM_SYN6_SYNDROME_MASK) >> ERM_SYN7_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN8_SYNDROME_MASK
case 8U:
syndrome = (base->SYN8 & ERM_SYN8_SYNDROME_MASK) >> ERM_SYN8_SYNDROME_SHIFT;
break;
#endif
#ifdef ERM_SYN9_SYNDROME_MASK
case 8U:
syndrome = (base->SYN9 & ERM_SYN9_SYNDROME_MASK) >> ERM_SYN9_SYNDROME_SHIFT;
break;
#endif
default:
assert(NULL);
break;
}
return syndrome;
}
uint32_t ERM_GetErrorCount(ERM_Type *base, erm_memory_channel_t channel)
{
uint32_t count = 0x00U;
switch ((uint8_t)channel)
{
case 0U:
count = (base->CORR_ERR_CNT0 & ERM_CORR_ERR_CNT0_COUNT_MASK) >> ERM_CORR_ERR_CNT0_COUNT_SHIFT;
break;
#ifdef ERM_CORR_ERR_CNT1_COUNT_MASK
case 1U:
count = (base->CORR_ERR_CNT1 & ERM_CORR_ERR_CNT1_COUNT_MASK) >> ERM_CORR_ERR_CNT1_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT2_COUNT_MASK
case 2U:
count = (base->CORR_ERR_CNT2 & ERM_CORR_ERR_CNT2_COUNT_MASK) >> ERM_CORR_ERR_CNT2_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT3_COUNT_MASK
case 3U:
count = (base->CORR_ERR_CNT3 & ERM_CORR_ERR_CNT3_COUNT_MASK) >> ERM_CORR_ERR_CNT3_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT4_COUNT_MASK
case 4U:
count = (base->CORR_ERR_CNT4 & ERM_CORR_ERR_CNT4_COUNT_MASK) >> ERM_CORR_ERR_CNT4_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT5_COUNT_MASK
case 5U:
count = (base->CORR_ERR_CNT5 & ERM_CORR_ERR_CNT5_COUNT_MASK) >> ERM_CORR_ERR_CNT5_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT6_COUNT_MASK
case 6U:
count = (base->CORR_ERR_CNT6 & ERM_CORR_ERR_CNT6_COUNT_MASK) >> ERM_CORR_ERR_CNT6_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT7_COUNT_MASK
case 7U:
count = (base->CORR_ERR_CNT7 & ERM_CORR_ERR_CNT7_COUNT_MASK) >> ERM_CORR_ERR_CNT7_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT8_COUNT_MASK
case 8U:
count = (base->CORR_ERR_CNT8 & ERM_CORR_ERR_CNT8_COUNT_MASK) >> ERM_CORR_ERR_CNT8_COUNT_SHIFT;
break;
#endif
#ifdef ERM_CORR_ERR_CNT9_COUNT_MASK
case 9U:
count = (base->CORR_ERR_CNT9 & ERM_CORR_ERR_CNT9_COUNT_MASK) >> ERM_CORR_ERR_CNT9_COUNT_SHIFT;
break;
#endif
default:
assert(NULL);
break;
}
return count;
}
void ERM_ResetErrorCount(ERM_Type *base, erm_memory_channel_t channel)
{
switch ((uint8_t)channel)
{
case 0U:
base->CORR_ERR_CNT0 = 0x00U;
break;
#ifdef ERM_CORR_ERR_CNT1_COUNT_MASK
case 1U:
base->CORR_ERR_CNT1 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT2_COUNT_MASK
case 2U:
base->CORR_ERR_CNT2 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT3_COUNT_MASK
case 3U:
base->CORR_ERR_CNT3 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT4_COUNT_MASK
case 4U:
base->CORR_ERR_CNT4 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT5_COUNT_MASK
case 5U:
base->CORR_ERR_CNT5 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT6_COUNT_MASK
case 6U:
base->CORR_ERR_CNT6 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT6_COUNT_MASK
case 7U:
base->CORR_ERR_CNT7 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT8_COUNT_MASK
case 8U:
base->CORR_ERR_CNT8 = 0x00U;
break;
#endif
#ifdef ERM_CORR_ERR_CNT9_COUNT_MASK
case 9U:
base->CORR_ERR_CNT9 = 0x00U;
break;
#endif
default:
assert(NULL);
break;
}
}

View File

@ -0,0 +1,235 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_ERM_H_
#define _FSL_ERM_H_
#include "fsl_common.h"
/*!
* @addtogroup erm
* @{
*/
/******************************************************************************
* Definitions.
*****************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Driver version. */
#define FSL_ERM_DRIVER_VERSION (MAKE_VERSION(2U, 0U, 1U))
/*@}*/
/*!
* @brief ERM interrupt configuration structure, default settings all disabled, _erm_interrupt_enable.
*
* This structure contains the settings for all of the ERM interrupt configurations.
*/
enum
{
kERM_SingleCorrectionIntEnable = 0x08U, /*!< Single Correction Interrupt Notification enable.*/
kERM_NonCorrectableIntEnable = 0x04U, /*!< Non-Correction Interrupt Notification enable.*/
kERM_AllInterruptsEnable = 0xFFFFFFFFUL, /*!< All Interrupts enable */
};
/*!
* @brief ERM interrupt status, _erm_interrupt_flag.
*
* This provides constants for the ERM event status for use in the ERM functions.
*/
enum
{
kERM_SingleBitCorrectionIntFlag = 0x08U, /*!< Single-Bit Correction Event.*/
kERM_NonCorrectableErrorIntFlag = 0x04U, /*!< Non-Correctable Error Event.*/
kERM_AllIntsFlag = 0xFFFFFFFFUL, /*!< All Events. */
};
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and de-initialization
* @{
*/
/*!
* @brief ERM module initialization function.
*
* @param base ERM base address.
*/
void ERM_Init(ERM_Type *base);
/*!
* @brief De-initializes the ERM.
*
*/
void ERM_Deinit(ERM_Type *base);
/* @} */
/*!
* @name Interrupt
* @{
*/
/*!
* @brief ERM enable interrupts.
*
* @param base ERM peripheral base address.
* @param channel memory channel.
* @param mask single correction interrupt or non-correction interrupt enable to disable for one specific memory region.
* Refer to "_erm_interrupt_enable" enumeration.
*/
static inline void ERM_EnableInterrupts(ERM_Type *base, erm_memory_channel_t channel, uint32_t mask)
{
uint32_t temp = 0x00U;
if ((uint32_t)channel <= 0x07U)
{
temp = base->CR0;
base->CR0 =
(temp & ~(0x0CUL << ((0x07U - (uint32_t)channel) * 4U))) | (mask << ((0x07U - (uint32_t)channel) * 4U));
}
#ifdef ERM_CR1_ESCIE8_MASK
else
{
temp = base->CR1;
base->CR1 = (temp & ~(0x0CUL << ((0x07U + 0x08U - (uint32_t)channel) * 4U))) |
(mask << ((0x07U + 0x08U - (uint32_t)channel) * 4U));
}
#endif
}
/*!
* @brief ERM module disable interrupts.
*
* @param base ERM base address.
* @param channel memory channel.
* @param mask single correction interrupt or non-correction interrupt enable to disable for one specific memory region.
* Refer to "_erm_interrupt_enable" enumeration.
*/
static inline void ERM_DisableInterrupts(ERM_Type *base, erm_memory_channel_t channel, uint32_t mask)
{
if ((uint32_t)channel <= 0x07U)
{
base->CR0 &= ~(mask << ((0x07U - (uint32_t)channel) * 4U));
}
#ifdef ERM_CR1_ESCIE8_MASK
else
{
base->CR1 &= ~(mask << ((0x07U + 0x08U - (uint32_t)channel) * 4U));
}
#endif
}
/*!
* @brief Gets ERM interrupt flags.
*
* @param base ERM peripheral base address.
* @return ERM event flags.
*/
static inline uint32_t ERM_GetInterruptStatus(ERM_Type *base, erm_memory_channel_t channel)
{
if ((uint32_t)channel <= 0x07U)
{
return ((base->SR0 & (uint32_t)kERM_AllIntsFlag) >> (0x07U - (uint32_t)channel) * 4U);
}
#ifdef ERM_SR1_SBC8_MASK
else
{
return ((base->SR1 & (uint32_t)kERM_AllIntsFlag) >> ((0x07U + 0x08U - (uint32_t)channel) * 4U));
}
#else
{
return 0;
}
#endif
}
/*!
* @brief ERM module clear interrupt status flag.
*
* @param base ERM base address.
* @param mask event flag to clear. Refer to "_erm_interrupt_flag" enumeration.
*/
static inline void ERM_ClearInterruptStatus(ERM_Type *base, erm_memory_channel_t channel, uint32_t mask)
{
if ((uint32_t)channel <= 0x07U)
{
base->SR0 = mask << ((0x07U - (uint32_t)channel) * 4U);
}
#ifdef ERM_SR1_SBC8_MASK
else
{
base->SR1 = mask << ((0x07U + 0x08U - (uint32_t)channel) * 4U);
}
#endif
}
/* @} */
/*!
* @name functional
* @{
*/
/*!
* @brief ERM get memory error absolute address, which capturing the address of the last ECC event in Memory n.
*
* @param base ERM base address.
* @param channel memory channel.
* @retval memory error absolute address.
*/
uint32_t ERM_GetMemoryErrorAddr(ERM_Type *base, erm_memory_channel_t channel);
/*!
* @brief ERM get syndrome, which identifies the pertinent bit position on a correctable, single-bit data inversion or a
* non-correctable, single-bit address inversion. The syndrome value does not provide any additional diagnostic
* information on non-correctable, multi-bit inversions.
*
* @param base ERM base address.
* @param channel memory channel.
* @retval syndrome value.
*/
uint32_t ERM_GetSyndrome(ERM_Type *base, erm_memory_channel_t channel);
/*!
* @brief ERM get error count, which records the count value of the number of correctable ECC error events for Memory
* n. Non-correctable errors are considered a serious fault, so the ERM does not provide any mechanism to count
* non-correctable errors. Only correctable errors are counted.
*
* @param base ERM base address.
* @param channel memory channel.
* @retval error count.
*/
uint32_t ERM_GetErrorCount(ERM_Type *base, erm_memory_channel_t channel);
/*!
* @brief ERM reset error count.
*
* @param base ERM base address.
* @param channel memory channel.
*/
void ERM_ResetErrorCount(ERM_Type *base, erm_memory_channel_t channel);
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif

View File

@ -0,0 +1,155 @@
/*
* Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_freqme.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpc_freqme"
#endif
#if defined(FREQME_RSTS_N)
#define FREQME_RESETS_ARRAY FREQME_RSTS_N
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
static uint32_t FREQME_GetInstance(FREQME_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Array to map freqme instance number to base address. */
static FREQME_Type *const s_freqmeBases[] = FREQME_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to FREQME clocks for each instance. */
static const clock_ip_name_t s_freqmeClocks[] = FREQME_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FREQME_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_freqmeResets[] = FREQME_RESETS_ARRAY;
#endif
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t FREQME_GetInstance(FREQME_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0U; instance < ARRAY_SIZE(s_freqmeBases); instance++)
{
if (s_freqmeBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_freqmeBases));
return instance;
}
/*!
* brief Initialize freqme module, set operate mode, operate mode attribute and initialize measurement cycle.
*
* param base FREQME peripheral base address.
* param config The pointer to module basic configuration, please refer to freq_measure_config_t.
*/
void FREQME_Init(FREQME_Type *base, const freq_measure_config_t *config)
{
assert(config);
uint32_t tmp32 = 0UL;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable FREQME clock. */
CLOCK_EnableClock(s_freqmeClocks[FREQME_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FREQME_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_freqmeResets[FREQME_GetInstance(base)]);
#endif
if (config->startMeasurement)
{
tmp32 |= FREQME_CTRL_W_MEASURE_IN_PROGRESS_MASK;
}
tmp32 |= FREQME_CTRL_W_CONTINUOUS_MODE_EN(config->enableContinuousMode) |
FREQME_CTRL_W_PULSE_MODE(config->operateMode);
if (config->operateMode == kFREQME_FreqMeasurementMode)
{
tmp32 |= FREQME_CTRL_W_REF_SCALE(config->operateModeAttribute.refClkScaleFactor);
}
else
{
tmp32 |= FREQME_CTRL_W_PULSE_POL(config->operateModeAttribute.pulsePolarity);
}
base->CTRL_W = tmp32;
}
/*!
* brief Get default configuration.
*
* code
* config->operateMode = kFREQME_FreqMeasurementMode;
* config->operateModeAttribute.refClkScaleFactor = 0U;
* config->enableContinuousMode = false;
* config->startMeasurement = false;
* endcode
*
* param config The pointer to module basic configuration, please refer to freq_measure_config_t.
*/
void FREQME_GetDefaultConfig(freq_measure_config_t *config)
{
assert(config);
(void)memset(config, 0, sizeof(*config));
config->operateMode = kFREQME_FreqMeasurementMode;
config->operateModeAttribute.refClkScaleFactor = 0U;
config->enableContinuousMode = false;
config->startMeasurement = false;
}
/*!
* brief Calculate the frequency of selected target clock.
*
* note The formula: Ftarget = (RESULT - 2) * Freference / 2 ^ REF_SCALE.
*
* note This function only useful when the operate mode is selected as frequency measurement mode.
*
* param base FREQME peripheral base address.
* param refClkFrequency The frequency of reference clock.
* return The frequency of target clock, if the output result is 0, please check the module's operate mode.
*/
uint32_t FREQME_CalculateTargetClkFreq(FREQME_Type *base, uint32_t refClkFrequency)
{
uint32_t measureResult = 0UL;
uint32_t targetFreq = 0UL;
uint64_t tmp64 = 0ULL;
while ((base->CTRL_R & FREQME_CTRL_R_MEASURE_IN_PROGRESS_MASK) != 0UL)
{
}
if (!FREQME_CheckOperateMode(base))
{
measureResult = base->CTRL_R & FREQME_CTRL_R_RESULT_MASK;
tmp64 = ((uint64_t)measureResult - 2ULL) * (uint64_t)refClkFrequency;
targetFreq = (uint32_t)(tmp64 / (1ULL << (uint64_t)FREQME_GetReferenceClkScaleValue(base)));
}
return targetFreq;
}

View File

@ -0,0 +1,441 @@
/*
* Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_FREQME_
#define _FSL_FREQME_
#include "fsl_common.h"
/*!
* @addtogroup lpc_freqme
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FREQME driver version 2.1.2. */
#define FSL_FREQME_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
/*@}*/
/*!
* @brief The enumeration of interrupt status flags.
* @anchor _freqme_interrupt_status_flags
*/
enum _freqme_interrupt_status_flags
{
kFREQME_UnderflowInterruptStatusFlag = FREQME_CTRLSTAT_LT_MIN_STAT_MASK, /*!< Indicate the measurement is
just done and the result is less
than minimun value. */
kFREQME_OverflowInterruptStatusFlag = FREQME_CTRLSTAT_GT_MAX_STAT_MASK, /*!< Indicate the measurement is
just done and the result is greater
than maximum value. */
kFREQME_ReadyInterruptStatusFlag = FREQME_CTRLSTAT_RESULT_READY_STAT_MASK, /*!< Indicate the measurement is
just done and the result is ready to
read. */
kFREQME_AllInterruptStatusFlags = FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_STAT_MASK |
FREQME_CTRLSTAT_RESULT_READY_STAT_MASK, /*!< All interrupt
status flags. */
};
/*!
* @brief The enumeration of interrupts, including underflow interrupt, overflow interrupt,
* and result ready interrupt.
* @anchor _freqme_interrupt_enable
*/
enum _freqme_interrupt_enable
{
kFREQME_UnderflowInterruptEnable = FREQME_CTRL_W_LT_MIN_INT_EN_MASK, /*!< Enable interrupt when the result is
less than minimum value. */
kFREQME_OverflowInterruptEnable = FREQME_CTRL_W_GT_MAX_INT_EN_MASK, /*!< Enable interrupt when the result is
greater than maximum value. */
kFREQME_ReadyInterruptEnable = FREQME_CTRL_W_RESULT_READY_INT_EN_MASK, /*!< Enable interrupt when a
measurement completes and the result
is ready. */
};
/*!
* @brief FREQME module operate mode enumeration, including frequency measurement mode
* and pulse width measurement mode.
*/
typedef enum _freqme_operate_mode
{
kFREQME_FreqMeasurementMode = 0U, /*!< The module works in the frequency measurement mode. */
kFREOME_PulseWidthMeasurementMode, /*!< The module works in the pulse width measurement mode. */
} freqme_operate_mode_t;
/*!
* @brief The enumeration of pulse polarity.
*/
typedef enum _freqme_pulse_polarity
{
kFREQME_PulseHighPeriod = 0U, /*!< Select high period of the reference clock. */
kFREQME_PulseLowPeriod, /*!< Select low period of the reference clock. */
} freqme_pulse_polarity_t;
/*!
* @brief The union of operate mode attribute.
* @note If the operate mode is selected as frequency measurement mode the member \b refClkScaleFactor should be used,
* if the operate mode is selected as pulse width measurement mode the member \b pulsePolarity should be used.
*/
typedef union _freqme_mode_attribute
{
uint8_t refClkScaleFactor; /*!< Only useful in frequency measurement operate mode,
used to set the reference clock counter scaling factor. */
freqme_pulse_polarity_t pulsePolarity; /*!< Only Useful in pulse width measurement operate mode,
used to set period polarity. */
} freqme_mode_attribute_t;
/*!
* @brief The structure of freqme module basic configuration,
* including operate mode, operate mode attribute and so on.
*/
typedef struct _freq_measure_config
{
freqme_operate_mode_t operateMode; /*!< Select operate mode, please refer to @ref freqme_operate_mode_t. */
freqme_mode_attribute_t operateModeAttribute; /*!< Used to set the attribute of the selected operate mode, if
the operate mode is selected as @ref kFREQME_FreqMeasurementMode
set freqme_mode_attribute_t::refClkScaleFactor, if operate mode is
selected as @ref kFREOME_PulseWidthMeasurementMode, please set
freqme_mode_attribute_t::pulsePolarity. */
bool enableContinuousMode; /*!< Enable/disable continuous mode, if continuous mode is enable,
the measurement is performed continuously and the result for the
last completed measurement is available in the result register. */
bool startMeasurement;
} freq_measure_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Basic Control APIs
* @{
*/
/*!
* @brief Initialize freqme module, set operate mode, operate mode attribute and initialize measurement cycle.
*
* @param base FREQME peripheral base address.
* @param config The pointer to module basic configuration, please refer to @ref freq_measure_config_t.
*/
void FREQME_Init(FREQME_Type *base, const freq_measure_config_t *config);
/*!
* @brief Get default configuration.
*
* @code
* config->operateMode = kFREQME_FreqMeasurementMode;
* config->operateModeAttribute.refClkScaleFactor = 0U;
* config->enableContinuousMode = false;
* config->startMeasurement = false;
* @endcode
*
* @param config The pointer to module basic configuration, please refer to @ref freq_measure_config_t.
*/
void FREQME_GetDefaultConfig(freq_measure_config_t *config);
/*!
* @brief Start frequency or pulse width measurement process.
*
* @param base FREQME peripheral base address.
*/
static inline void FREQME_StartMeasurementCycle(FREQME_Type *base)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_MEASURE_IN_PROGRESS_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
tmp32 |= FREQME_CTRL_W_MEASURE_IN_PROGRESS_MASK;
base->CTRL_W = tmp32;
}
/*!
* @brief Force the termination of any measurement cycle currently in progress and resets RESULT or just reset
* RESULT if the module in idle state.
*
* @param base FREQME peripheral base address.
*/
static inline void FREQME_TerminateMeasurementCycle(FREQME_Type *base)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_MEASURE_IN_PROGRESS_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
base->CTRL_W = tmp32;
}
/*!
* @brief Enable/disable Continuous mode.
*
* @param base FREQME peripheral base address.
* @param enable Used to enable/disable continuous mode,
* - \b true Enable Continuous mode.
* - \b false Disable Continuous mode.
*/
static inline void FREQME_EnableContinuousMode(FREQME_Type *base, bool enable)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_CONTINUOUS_MODE_EN_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
if (enable)
{
tmp32 |= FREQME_CTRL_W_CONTINUOUS_MODE_EN_MASK;
}
base->CTRL_W = tmp32;
}
/*!
* @brief Check whether continuous mode is enabled.
*
* @param base FREQME peripheral base address.
* @retval True Continuous mode is enabled, the measurement is performed continuously.
* @retval False Continuous mode is disabled.
*/
static inline bool FREQME_CheckContinuousMode(FREQME_Type *base)
{
return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_CONTINUOUS_MODE_EN_MASK) != 0UL);
}
/*!
* @brief Set operate mode of freqme module.
*
* @param base FREQME peripheral base address.
* @param operateMode The operate mode to be set, please refer to @ref freqme_operate_mode_t.
*/
static inline void FREQME_SetOperateMode(FREQME_Type *base, freqme_operate_mode_t operateMode)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_PULSE_MODE_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
if (operateMode == kFREOME_PulseWidthMeasurementMode)
{
tmp32 |= FREQME_CTRL_W_PULSE_MODE_MASK;
}
base->CTRL_W = tmp32;
}
/*!
* @brief Check module's operate mode.
*
* @param base FREQME peripheral base address.
* @retval True Pulse width measurement mode.
* @retval False Frequency measurement mode.
*/
static inline bool FREQME_CheckOperateMode(FREQME_Type *base)
{
return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_PULSE_MODE_MASK) != 0UL);
}
/*!
* @brief Set the minimum expected value for the measurement result.
*
* @param base FREQME peripheral base address.
* @param minValue The minimum value to set, please note that this value is 31 bits width.
*/
static inline void FREQME_SetMinExpectedValue(FREQME_Type *base, uint32_t minValue)
{
base->MIN = minValue;
}
/*!
* @brief Set the maximum expected value for the measurement result.
*
* @param base FREQME peripheral base address.
* @param maxValue The maximum value to set, please note that this value is 31 bits width.
*/
static inline void FREQME_SetMaxExpectedValue(FREQME_Type *base, uint32_t maxValue)
{
base->MAX = maxValue;
}
/*! @} */
/*!
* @name Frequency Measurement Mode Control APIs
* @{
*/
/*!
* @brief Calculate the frequency of selected target clock
*
* @note The formula: Ftarget = (RESULT - 2) * Freference / 2 ^ REF_SCALE.
*
* @note This function only useful when the operate mode is selected as frequency measurement mode.
*
* @param base FREQME peripheral base address.
* @param refClkFrequency The frequency of reference clock.
* @return The frequency of target clock the unit is Hz, if the output result is 0, please check the module's
* operate mode.
*/
uint32_t FREQME_CalculateTargetClkFreq(FREQME_Type *base, uint32_t refClkFrequency);
/*!
* @brief Get reference clock scaling factor.
*
* @param base FREQME peripheral base address.
* @return Reference clock scaling factor, the reference count cycle is 2 ^ ref_scale.
*/
static inline uint8_t FREQME_GetReferenceClkScaleValue(FREQME_Type *base)
{
return (uint8_t)(base->CTRLSTAT & FREQME_CTRLSTAT_REF_SCALE_MASK);
}
/*! @} */
/*!
* @name Pulse Width Measurement Mode Control APIs
* @{
*/
/*!
* @brief Set pulse polarity when operate mode is selected as Pulse Width Measurement mode.
*
* @param base FREQME peripheral base address.
* @param pulsePolarity The pulse polarity to be set, please refer to @ref freqme_pulse_polarity_t.
*/
static inline void FREQME_SetPulsePolarity(FREQME_Type *base, freqme_pulse_polarity_t pulsePolarity)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_PULSE_POL_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
if (pulsePolarity != kFREQME_PulseHighPeriod)
{
tmp32 |= FREQME_CTRL_W_PULSE_POL_MASK;
}
base->CTRL_W = tmp32;
}
/*!
* @brief Check pulse polarity when the operate mode is selected as pulse width measurement mode.
*
* @param base FREQME peripheral base address.
* @retval True Low period.
* @retval False High period.
*/
static inline bool FREQME_CheckPulsePolarity(FREQME_Type *base)
{
return (bool)((base->CTRLSTAT & FREQME_CTRLSTAT_PULSE_POL_MASK) != 0UL);
}
/*!
* @brief Get measurement result, if operate mode is selected as pulse width measurement mode this function can
* be used to calculate pulse width.
*
* @note Pulse width = counter result / Frequency of target clock.
*
* @param base FREQME peripheral base address.
* @return Measurement result.
*/
static inline uint32_t FREQME_GetMeasurementResult(FREQME_Type *base)
{
return base->CTRL_R & FREQME_CTRL_R_RESULT_MASK;
}
/*! @} */
/*!
* @name Status Control APIs
* @{
*/
/*!
* @brief Get interrupt status flags, such as overflow interrupt status flag,
* underflow interrupt status flag, and so on.
*
* @param base FREQME peripheral base address.
* @return Current interrupt status flags, should be the OR'ed value of @ref _freqme_interrupt_status_flags.
*/
static inline uint32_t FREQME_GetInterruptStatusFlags(FREQME_Type *base)
{
return (base->CTRLSTAT & (uint32_t)kFREQME_AllInterruptStatusFlags);
}
/*!
* @brief Clear interrupt status flags.
*
* @param base FREQME peripheral base address.
* @param statusFlags The combination of interrupt status flags to clear,
* should be the OR'ed value of @ref _freqme_interrupt_status_flags.
*/
static inline void FREQME_ClearInterruptStatusFlags(FREQME_Type *base, uint32_t statusFlags)
{
base->CTRLSTAT |= statusFlags;
}
/*! @} */
/*!
* @name Interrupt Control APIs
* @{
*/
/*!
* @brief Enable interrupts, such as result ready interrupt, overflow interrupt and so on.
*
* @param base FREQME peripheral base address.
* @param masks The mask of interrupts to enable, should be the OR'ed value of @ref _freqme_interrupt_enable.
*/
static inline void FREQME_EnableInterrupts(FREQME_Type *base, uint32_t masks)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_LT_MIN_INT_EN_MASK |
FREQME_CTRLSTAT_GT_MAX_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_INT_EN_MASK |
FREQME_CTRLSTAT_RESULT_READY_INT_EN_MASK | FREQME_CTRLSTAT_RESULT_READY_STAT_MASK);
tmp32 |= masks;
base->CTRL_W = tmp32;
}
/*!
* @brief Disable interrupts, such as result ready interrupt, overflow interrupt and so on.
*
* @param base FREQME peripheral base address.
* @param masks The mask of interrupts to disable, should be the OR'ed value of @ref _freqme_interrupt_enable.
*/
static inline void FREQME_DisableInterrupts(FREQME_Type *base, uint32_t masks)
{
uint32_t tmp32;
tmp32 = base->CTRLSTAT;
tmp32 &= ~(FREQME_CTRLSTAT_LT_MIN_STAT_MASK | FREQME_CTRLSTAT_GT_MAX_STAT_MASK |
FREQME_CTRLSTAT_RESULT_READY_STAT_MASK | masks);
base->CTRL_W = tmp32;
}
/*! @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* __FSL_FREQME_H__ */

View File

@ -0,0 +1,397 @@
/*
* Copyright 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_glikey.h"
/*******************************************************************************
* Definitions
*******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.glikey"
#endif
#define GLIKEY_SFR_LOCK 0x05u
#define GLIKEY_SFR_UNLOCK 0x0Au
/* Define to select between write to CTRL0_WR_0 or CTRL1_WR_1 */
#define WR_EN0 (0x0Fu)
#define WR_EN1 (0xF0u)
#define WR_EN0_VALUE_SHIFT (0u)
#define WR_EN1_VALUE_SHIFT (16u)
#define CTRL_SEL_CODEWORD_SHIFT (24u)
#define WR_0_INIT (0x2u)
#define WR_1_INIT (0x0u)
/*******************************************************************************
* Prototypes
******************************************************************************/
static inline void Glikey_Internal_Set_WR_0(GLIKEY_Type *base, uint32_t value);
static inline void Glikey_Internal_Set_WR_1(GLIKEY_Type *base, uint32_t value);
/*******************************************************************************
* Code
******************************************************************************/
/*!
* Weak implementation of GLIKEY IRQ, should be re-defined by user when using GLIKEY IRQ
__WEAK void GLIKEY0_DriverIRQHandler(void)
{
// GLIKEY generates IRQ until corresponding bit in STATUS is cleared by calling
// GLIKEY_ClearStatusFlags();
//
}
*/
static inline void Glikey_Internal_Set_WR_0(GLIKEY_Type *base, uint32_t value)
{
uint32_t ctrl0 = ((GLIKEY_Type *)base)->CTRL_0;
/* Clear WR_0 */
ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WR_EN_0_MASK);
/* Assign value */
((GLIKEY_Type *)base)->CTRL_0 = ctrl0 | GLIKEY_CTRL_0_WR_EN_0(value);
}
static inline void Glikey_Internal_Set_WR_1(GLIKEY_Type *base, uint32_t value)
{
uint32_t ctrl1 = ((GLIKEY_Type *)base)->CTRL_1;
/* Clear WR_1 */
ctrl1 = ctrl1 & (~GLIKEY_CTRL_1_WR_EN_1_MASK);
/* Assign value */
((GLIKEY_Type *)base)->CTRL_1 = ctrl1 | GLIKEY_CTRL_1_WR_EN_1(value);
}
uint32_t GLIKEY_GetStatus(GLIKEY_Type *base)
{
return ((GLIKEY_Type *)base)->STATUS;
}
status_t GLIKEY_IsLocked(GLIKEY_Type *base)
{
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked == retCode)
{
return kStatus_GLIKEY_NotLocked;
}
else
{
return kStatus_GLIKEY_Locked;
}
}
status_t GLIKEY_CheckLock(GLIKEY_Type *base)
{
uint32_t sfrLock = (((GLIKEY_Type *)base)->CTRL_1 & GLIKEY_CTRL_1_SFR_LOCK_MASK) >> GLIKEY_CTRL_1_SFR_LOCK_SHIFT;
if (GLIKEY_SFR_UNLOCK != sfrLock) /* Locked */
{
return kStatus_GLIKEY_LockedError;
}
return kStatus_GLIKEY_NotLocked;
}
status_t GLIKEY_GetVersion(GLIKEY_Type *base, uint32_t *result)
{
*result = ((GLIKEY_Type *)base)->VERSION;
return kStatus_Success;
}
status_t GLIKEY_SyncReset(GLIKEY_Type *base)
{
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* Set CTRL_0.SFT_RST = 1 */
((GLIKEY_Type *)base)->CTRL_0 |= GLIKEY_CTRL_0_SFT_RST_MASK;
return kStatus_Success;
}
status_t GLIKEY_SetIntEnable(GLIKEY_Type *base, uint32_t value)
{
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
((GLIKEY_Type *)base)->INTR_CTRL = GLIKEY_INTR_CTRL_INT_EN(value);
return kStatus_Success;
}
status_t GLIKEY_GetIntEnable(GLIKEY_Type *base, uint32_t *value)
{
*value = ((GLIKEY_Type *)base)->INTR_CTRL & GLIKEY_INTR_CTRL_INT_EN_MASK;
return kStatus_Success;
}
status_t GLIKEY_ClearIntStatus(GLIKEY_Type *base)
{
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
((GLIKEY_Type *)base)->INTR_CTRL |= GLIKEY_INTR_CTRL_INT_CLR_MASK;
return kStatus_Success;
}
status_t GLIKEY_SetIntStatus(GLIKEY_Type *base)
{
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
((GLIKEY_Type *)base)->INTR_CTRL |= GLIKEY_INTR_CTRL_INT_SET_MASK;
return kStatus_Success;
}
status_t GLIKEY_Lock(GLIKEY_Type *base)
{
/* Check if SFR_LOCK is locked */
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode) /* Glikey is not locked -> lock */
{
uint32_t ctrl1 = ((GLIKEY_Type *)base)->CTRL_1;
/* Clear SFR_LOCK */
ctrl1 = ctrl1 & (~GLIKEY_CTRL_1_SFR_LOCK_MASK);
/* Lock Gliekey */
((GLIKEY_Type *)base)->CTRL_1 = ctrl1 | GLIKEY_CTRL_1_SFR_LOCK(GLIKEY_SFR_LOCK);
}
return kStatus_Success;
}
status_t GLIKEY_IsIndexLocked(GLIKEY_Type *base, uint32_t index)
{
/* Set CTRL_1.READ_INDEX = index */
uint32_t ctr1Val = ((GLIKEY_Type *)base)->CTRL_1;
/* Clear READ_INDEX */
ctr1Val = ctr1Val & (~GLIKEY_CTRL_1_READ_INDEX_MASK);
/* Set index value */
((GLIKEY_Type *)base)->CTRL_1 = ctr1Val | GLIKEY_CTRL_1_READ_INDEX(index);
/* Check ERROR_STATUS */
if (0u != (GLIKEY_GetStatus(base) & GLIKEY_STATUS_ERROR_STATUS_MASK))
{
return kStatus_Fail;
}
/* Check if STATUS.LOCK_STATUS is 0 */
if (0u == (GLIKEY_GetStatus(base) & GLIKEY_STATUS_LOCK_STATUS_MASK))
{
return kStatus_GLIKEY_NotLocked;
}
else
{
return kStatus_GLIKEY_Locked;
}
}
status_t GLIKEY_LockIndex(GLIKEY_Type *base)
{
/* Check if Glikey SFR locked */
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* Check if FSM is in WR_EN state */
uint32_t state = (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT;
if (GLIKEY_FSM_WR_EN == state)
{
/* Set WR_EN0 = b11 */
((GLIKEY_Type *)base)->CTRL_0 |= GLIKEY_CTRL_0_WR_EN_0(0x3u);
return kStatus_GLIKEY_Locked;
}
else
{
return kStatus_GLIKEY_DisabledError;
}
}
status_t GLIKEY_StartEnable(GLIKEY_Type *base, uint32_t index)
{
/* Check if Glikey SFR locked */
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* Check if index is locked */
retCode = GLIKEY_IsIndexLocked(base, index);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* CTRL0 */
uint32_t ctrl0 = ((GLIKEY_Type *)base)->CTRL_0;
/* Clear old index */
ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WRITE_INDEX_MASK);
/* Clear old CTRL0.WR_EN_0 */
ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WR_EN_0_MASK);
/* Set new index */
ctrl0 |= GLIKEY_CTRL_0_WRITE_INDEX(index);
/* Start the enable process by writting 0x01 to CTRL0.WR_EN_0 */
ctrl0 = ctrl0 | (0x01u << GLIKEY_CTRL_0_WR_EN_0_SHIFT);
/* Write to CTRL0 (new index and WR_EN_0 = 0x01) */
((GLIKEY_Type *)base)->CTRL_0 = ctrl0;
/* CTRL1 */
uint32_t ctrl1 = ((GLIKEY_Type *)base)->CTRL_1;
/* Clear CTRL1.WR_EN_1 */
ctrl1 &= ~GLIKEY_CTRL_1_WR_EN_1_MASK;
//((GLIKEY_Type*)base)->CTRL_1 = ctrl1;
return kStatus_Success;
}
status_t GLIKEY_ContinueEnable(GLIKEY_Type *base, uint32_t codeword)
{
/* Check if Glikey SFR locked */
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* Set correctly we_en0 and wr_en1 according to codeword */
/* Select between CTRL0/CTRL1 */
if (WR_EN1 == (codeword >> CTRL_SEL_CODEWORD_SHIFT))
{
Glikey_Internal_Set_WR_1(base, codeword >> WR_EN1_VALUE_SHIFT);
}
else if (WR_EN0 == (codeword >> CTRL_SEL_CODEWORD_SHIFT))
{
Glikey_Internal_Set_WR_0(base, codeword >> WR_EN0_VALUE_SHIFT);
}
else
{
return kStatus_Fail;
}
if (0u != (GLIKEY_GetStatus(base) & GLIKEY_STATUS_ERROR_STATUS_MASK))
{
return kStatus_GLIKEY_DisabledError;
}
/* Validate codeword - check if XXYZ^UUVW == 0xFFFF */
if (0xFFFFu != (((codeword) ^ (codeword >> 16u)) & 0xFFFFu))
{
return kStatus_Fail;
}
return kStatus_Success;
}
status_t GLIKEY_EndOperation(GLIKEY_Type *base)
{
/* Check if Glikey SFR locked */
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
// check state
uint32_t state = (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT;
switch (state)
{
case GLIKEY_FSM_LOCKED:
{
/* If locked -> try to go to init with wr_en0 = WR_0_INIT (0x02); wr_en1 = WR_1_INIT (0x00) */
Glikey_Internal_Set_WR_0(base, WR_0_INIT);
Glikey_Internal_Set_WR_1(base, WR_1_INIT);
/* if still locked return locked - need to change index */
if (GLIKEY_FSM_LOCKED ==
(GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT)
{
return kStatus_GLIKEY_Locked;
}
return kStatus_Success;
}
case GLIKEY_FSM_SSR_RESET:
case GLIKEY_FSM_WR_EN:
{
/* If FSM in RESET -> wr_en0 = WR_0_INIT; wr_en1 = WR_1_INIT */
/* If FSM in WR_EN -> wr_en0 = WR_0_INIT; wr_en1 = WR_1_INIT */
Glikey_Internal_Set_WR_0(base, WR_0_INIT);
Glikey_Internal_Set_WR_1(base, WR_1_INIT);
return kStatus_Success;
}
default:
/* Disabled error */
return kStatus_GLIKEY_DisabledError;
}
}
status_t GLIKEY_ResetIndex(GLIKEY_Type *base, uint32_t index)
{
/* Check if Glikey SFR locked */
uint32_t retCode = GLIKEY_CheckLock(base);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* Check if index is locked */
retCode = GLIKEY_IsIndexLocked(base, index);
if (kStatus_GLIKEY_NotLocked != retCode)
{
return retCode;
}
/* Check if FSM is in INIT state */
uint32_t state = (GLIKEY_GetStatus(base) & GLIKEY_STATUS_FSM_STATE_MASK) >> GLIKEY_STATUS_FSM_STATE_SHIFT;
if (GLIKEY_FSM_INIT == state)
{
/* CTRL0.WRITE_INDEX = index */
uint32_t ctrl0 = ((GLIKEY_Type *)base)->CTRL_0;
/* Clear index */
ctrl0 = ctrl0 & (~GLIKEY_CTRL_0_WRITE_INDEX_MASK);
/* Write new value */
((GLIKEY_Type *)base)->CTRL_0 = ctrl0 | GLIKEY_CTRL_0_WRITE_INDEX(index);
return kStatus_Success;
}
else
{
return kStatus_GLIKEY_DisabledError;
}
}

View File

@ -0,0 +1,312 @@
/*
* Copyright 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_GLIKEY_H_
#define _FSL_GLIKEY_H_
#include "fsl_common.h"
/*!
* @addtogroup GLIKEY
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Defines GLIKEY driver version 2.0.0.
*
* Change log:
* - Version 2.0.0
* - Initial version
*/
#define FSL_GLIKEY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
enum
{
kStatus_GLIKEY_LockedError =
MAKE_STATUS(kStatusGroup_GLIKEY, 0x1u), /*!< GLIKEY status for locked SFR registers (unexpected) . */
kStatus_GLIKEY_NotLocked = MAKE_STATUS(kStatusGroup_GLIKEY, 0x2u), /*!< GLIKEY status for unlocked SFR registers. */
kStatus_GLIKEY_Locked = MAKE_STATUS(kStatusGroup_GLIKEY, 0x3u), /*!< GLIKEY status for locked SFR registers. */
kStatus_GLIKEY_DisabledError = MAKE_STATUS(kStatusGroup_GLIKEY, 0x4u), /*!< GLIKEY status for disabled error. */
};
/* [Design]
Value: XX YZ UU VW
- XX: F0: write to WR_EN1, 0F: do not write to WR_EN1
- UU: F0: write to WR_EN0, 0F: do not write to WR_EN0
- Y: equal to <step> ^ W
- Z: value to write to WR_EN1 or equal to ~W
- V: equal to <step> ^ Z
- W: value to write to WR_EN0 or equal to ~Z
Invariant: XXYZ ^ UUVW == 0xFFFF
*/
#define GLIKEY_CODEWORD_STEP1 ((uint32_t)0xF0C10F3EU) /*< Codeword for transition from STEP1 --> STEP2 */
#define GLIKEY_CODEWORD_STEP2 ((uint32_t)0x0F1DF0E2U) /*< Codeword for transition from STEP2 --> STEP3 */
#define GLIKEY_CODEWORD_STEP3 ((uint32_t)0xF0B00F4FU) /*< Codeword for transition from STEP3 --> STEP4 */
#define GLIKEY_CODEWORD_STEP4 ((uint32_t)0x0F4EF0B1U) /*< Codeword for transition from STEP4 --> STEP5 */
#define GLIKEY_CODEWORD_STEP5 ((uint32_t)0xF0810F7EU) /*< Codeword for transition from STEP5 --> STEP6 */
#define GLIKEY_CODEWORD_STEP6 ((uint32_t)0x0F5DF0A2U) /*< Codeword for transition from STEP6 --> STEP7 */
#define GLIKEY_CODEWORD_STEP7 ((uint32_t)0xF0700F8FU) /*< Codeword for transition from STEP7 --> STEP8 */
#define GLIKEY_CODEWORD_STEP_EN ((uint32_t)0x0FFFF000U) /*< Codeword for transition from STEP 4/8 --> WR_EN */
#define GLIKEY_FSM_WR_DIS 0x0Bu
#define GLIKEY_FSM_INIT 0x16u
#define GLIKEY_FSM_STEP1 0x2Cu
#define GLIKEY_FSM_STEP2 0x58u
#define GLIKEY_FSM_STEP3 0xB0u
#define GLIKEY_FSM_STEP4 0x160u
#define GLIKEY_FSM_LOCKED 0xC01u
#define GLIKEY_FSM_WR_EN 0x1802u
#define GLIKEY_FSM_SSR_RESET 0x1005u
/*@}*/
/*******************************************************************************
* API
*******************************************************************************/
extern void GLIKEY0_IRQHandler(void);
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name GLIKEY Functional Operation
* @{
*/
/*!
* @brief Retreives the current status of Glikey.
*
* @param[in] base The base address of the Glikey instance
*
* @return Glikey status information
*/
uint32_t GLIKEY_GetStatus(GLIKEY_Type *base);
/*!
* @brief Get if Glikey is locked
*
* This operation returns the locking status of Glikey.
*
* @return Status
* @retval kStatus_GLIKEY_Locked if locked
* @retval kStatus_GLIKEY_NotLocked if unlocked
*/
status_t GLIKEY_IsLocked(GLIKEY_Type *base);
/*!
* @brief Check if Glikey is locked
*
* This operation returns the locking status of Glikey.
*
* @return Status kStatus_Success if success
* @retval kStatus_GLIKEY_LockedError if locked
* @retval kStatus_GLIKEY_NotLocked if unlocked
*/
status_t GLIKEY_CheckLock(GLIKEY_Type *base);
/*!
* @brief Retreives the version and configuration of Glikey.
*
*
* @param[in] base The base address of the Glikey instance
* @param[out] result Pointer which will be filled with the Glikey hardware version
*
* @return Status kStatus_Success if success
*/
status_t GLIKEY_GetVersion(GLIKEY_Type *base, uint32_t *result);
/*!
* @brief Perform a synchronous reset of Glikey.
*
* This function performs a synchrounous reset of the Glikey. This results in:
* - Glikey will return to the INIT state, unless it is in the LOCK state
*
* @param[in] base The base address of the Glikey instance
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError
*/
status_t GLIKEY_SyncReset(GLIKEY_Type *base);
/*!
* @brief Set interrupt enable flag of Glikey.
*
* @param[in] base The base address of the Glikey instance
* @param[in] value Value to set the interrupt enable flag to, see #[TODO: add reference to constants]
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError
*/
status_t GLIKEY_SetIntEnable(GLIKEY_Type *base, uint32_t value);
/*!
* @brief Get interrupt enable flag of Glikey.
*
* @param[in] base The base address of the Glikey instance
* @param[out] value Pointer which will be filled with the interrupt enable status, see #[TODO: add reference to
* constants]
*
* @return Status kStatus_Success if success
*/
status_t GLIKEY_GetIntEnable(GLIKEY_Type *base, uint32_t *value);
/*!
* @brief Clear the interrupt status flag of Glikey.
*
* @param[in] base The base address of the Glikey instance
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError
*/
status_t GLIKEY_ClearIntStatus(GLIKEY_Type *base);
/*!
* @brief Set the interrupt status flag of Glikey.
*
* @param[in] base The base address of the Glikey instance
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError
*/
status_t GLIKEY_SetIntStatus(GLIKEY_Type *base);
/*!
* @brief Lock Glikey SFR (Special Function Registers) interface
*
* This operation locks the Glikey SFR interface if it is not locked yet.
*
* @param[in] base The base address of the Glikey instance
*
* @return Status kStatus_Success if success
*/
status_t GLIKEY_Lock(GLIKEY_Type *base);
/*!
* @brief Lock Glikey index
*
* This operation is used to lock a Glikey index. It can only be executed from the WR_EN state,
* executing it from any other state will result in Glikey entering WR_DIS state. When this happens
* Glikey requires a reset (synchrous or asynchronous) to go back to INIT state.
* If the Glikey SFR lock is active this operation will return an error.
*
* @param[in] base The base address of the Glikey instance
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError, kStatus_GLIKEY_DisabledError
*/
status_t GLIKEY_LockIndex(GLIKEY_Type *base);
/*!
* @brief Check if Glikey index is locked
*
* This operation returns the locking status of Glikey index.
*
* @param[in] base The base address of the Glikey instance
* @param[in] index The index of the Glikey instance
*
* @return kStatus_GLIKEY_Locked if locked, kStatus_GLIKEY_NotLocked if unlocked
* Possible errors: kStatus_Fail
*/
status_t GLIKEY_IsIndexLocked(GLIKEY_Type *base, uint32_t index);
/**
* @brief Start Glikey enable
*
* This operation is used to set a new index and start a the sequence to enable it. It needs to be
* started from the INIT state. If the new index is already locked Glikey will go to LOCKED state,
* otherwise it will go to STEP1 state.
* If this operation is used when Glikey is in any state other than INIT Glikey will go to WR_DIS
* state. It can only recover from this state through a reset (synchrounous or asyncrhonous).
* If the Glikey SFR lock is active this operation will return an error.
*
* @param[in] base The base address of the Glikey instance
* @param[in] index The index of the Glikey instance
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError, kStatus_Fail
*/
status_t GLIKEY_StartEnable(GLIKEY_Type *base, uint32_t index);
/**
* @brief Continue Glikey enable
*
* This operation is used to progress through the different states of the state machine, starting
* from STEP1 until the state WR_EN is reached. Each next state of the state machine can only be
* reached by providing the right codeword to this function. If anything goes wrong the state machine
* will go to WR_DIS state and can only recover from it through a reset (synchrous or asynchronous).
* If the Glikey SFR lock is active this operation will return an error.
*
* @param[in] base The base address of the Glikey instance
* @param[in] codeword Encoded word for progressing to next FSM state (see GLIKEY_CODEWORD_STEPx/EN)
*
* @return Status kStatus_Success if success
* Possible errors: kStatus_GLIKEY_LockedError, kStatus_Fail, kStatus_GLIKEY_DisabledError
*/
/* [Design]
- Check if Glikey is locked
if ( GLIKEY_LOCKED == GLIKEY_GET_SFR_LOCK(base) ) return NXPCLGLIKEY_STATUS_LOCKED_ERROR
- Decode the codeword and write to Glikey CTRL[]
Write GLIKEY_CTRL(base, EnableSelect, EnableValue)
- Check if an error occured
- the only possible error here is FSM error which results in a transition to WR_DIS state
- alternatively this can be confirmed by checking FSM state value
- Only now we will check if the codeword itself is valid
- this is done in this order to assure that the state machine reaches WR_DIS state when needed
- check if XXYZ^UUVW == 0xFFFF and return kStatus_Fail when it fails
- Return kStatus_Success
*/
status_t GLIKEY_ContinueEnable(GLIKEY_Type *base, uint32_t codeword);
/**
* @brief End Glikey operation
*
* This operation is used to end a Glikey operation. It can only be executed from the WR_EN, LOCKED
* and RESET states. Executing it from any other state will result in Glikey entering WR_DIS state.
* When this happens Glikey requires a reset (synchrous or asynchronous) to go back to INIT state.
* After this operation Glikey will go to INIT state or stay in LOCKED state when the index was locked.
* If the Glikey SFR lock is active this operation will return an error.
*
* @return A code-flow protected error code (see @ref nxpCsslFlowProtection)
*
* @param[in] base The base address of the Glikey instance
*
* @return Status kStatus_Success if success, kStatus_GLIKEY_Locked if index is still locked
* Possible errors: kStatus_GLIKEY_LockedError, kStatus_GLIKEY_DisabledError
*/
status_t GLIKEY_EndOperation(GLIKEY_Type *base);
/**
* @brief Reset Glikey index
*
* This operation is used to reset a Glikey index. It can only be executed from the INIT state,
* executing it from any other state will result in Glikey entering WR_DIS state. When this happens
* Glikey requires a reset (synchrous or asynchronous) to go back to INIT state.
* If the Glikey SFR lock is active or the index is locked this operation will return an error.
*
* @return A code-flow protected error code (see @ref nxpCsslFlowProtection)
*
* @return Status kStatus_Success if success, kStatus_GLIKEY_Locked if index is still locked
* Possible errors: kStatus_GLIKEY_LockedError, kStatus_GLIKEY_DisabledError
*/
status_t GLIKEY_ResetIndex(GLIKEY_Type *base, uint32_t index);
/*! @}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/ /* end of group glikey */
#endif /* _FSL_GLIKEY_H_ */

View File

@ -0,0 +1,440 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2019, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_gpio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.gpio"
#endif
#if defined(GPIO_RSTS)
#define GPIO_RESETS_ARRAY GPIO_RSTS
#endif
/*******************************************************************************
* Variables
******************************************************************************/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
static PORT_Type *const s_portBases[] = PORT_BASE_PTRS;
static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
#endif
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
#if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map FGPIO instance number to clock name. */
static const clock_ip_name_t s_fgpioClockName[] = FGPIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
#if defined(GPIO_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_gpioResets[] = GPIO_RESETS_ARRAY;
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* @brief Gets the GPIO instance according to the GPIO base
*
* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
* @retval GPIO instance
*/
static uint32_t GPIO_GetInstance(GPIO_Type *base);
#endif
/*******************************************************************************
* Code
******************************************************************************/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT) || defined(GPIO_RESETS_ARRAY)
static uint32_t GPIO_GetInstance(GPIO_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++)
{
if (s_gpioBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_gpioBases));
return instance;
}
#endif
/*!
* brief Initializes a GPIO pin used by the board.
*
* To initialize the GPIO, define a pin configuration, as either input or output, in the user file.
* Then, call the GPIO_PinInit() function.
*
* This is an example to define an input pin or an output pin configuration.
* code
* Define a digital input pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalInput,
* 0,
* }
* Define a digital output pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalOutput,
* 0,
* }
* endcode
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* param pin GPIO port pin number
* param config GPIO pin configuration pointer
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
{
assert(NULL != config);
#if defined(GPIO_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_gpioResets[GPIO_GetInstance(base)]);
#endif
if (config->pinDirection == kGPIO_DigitalInput)
{
base->PDDR &= GPIO_FIT_REG(~(1UL << pin));
}
else
{
GPIO_PinWrite(base, pin, config->outputLogic);
base->PDDR |= GPIO_FIT_REG((1UL << pin));
}
}
#if defined(FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER
void GPIO_GetVersionInfo(GPIO_Type *base, gpio_version_info_t *info)
{
info->feature = (uint16_t)base->VERID;
info->minor = (uint8_t)(base->VERID >> GPIO_VERID_MINOR_SHIFT);
info->major = (uint8_t)(base->VERID >> GPIO_VERID_MAJOR_SHIFT);
}
#endif /* FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER */
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* brief Reads the GPIO port interrupt status flag.
*
* If a pin is configured to generate the DMA request, the corresponding flag
* is cleared automatically at the completion of the requested DMA transfer.
* Otherwise, the flag remains set until a logic one is written to that flag.
* If configured for a level sensitive interrupt that remains asserted, the flag
* is set again immediately.
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* retval The current GPIO port interrupt status flag, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt.
*/
uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base)
{
uint8_t instance;
PORT_Type *portBase;
instance = (uint8_t)GPIO_GetInstance(base);
portBase = s_portBases[instance];
return portBase->ISFR;
}
#else
/*!
* brief Read the GPIO interrupt status flags.
*
* param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
* return The current GPIO's interrupt status flag.
* '1' means the related pin's flag is set, '0' means the related pin's flag not set.
* For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
*/
uint32_t GPIO_GpioGetInterruptFlags(GPIO_Type *base)
{
return base->ISFR[0];
}
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
/*!
* brief Read the GPIO interrupt status flags based on selected interrupt channel(IRQS).
* param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
* param channel '0' means selete interrupt channel 0, '1' means selete interrupt channel 1.
*
* return The current GPIO's interrupt status flag based on the selected interrupt channel.
* '1' means the related pin's flag is set, '0' means the related pin's flag not set.
* For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
*/
uint32_t GPIO_GpioGetInterruptChannelFlags(GPIO_Type *base, uint32_t channel)
{
assert(channel < 2U);
return base->ISFR[channel];
}
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT */
/*!
* brief Read individual pin's interrupt status flag.
*
* param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on)
* param pin GPIO specific pin number.
* return The current selected pin's interrupt status flag.
*/
uint8_t GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin)
{
return (uint8_t)((base->ICR[pin] & GPIO_ICR_ISF_MASK) >> GPIO_ICR_ISF_SHIFT);
}
#endif /* FSL_FEATURE_PORT_HAS_NO_INTERRUPT */
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* brief Clears multiple GPIO pin interrupt status flags.
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* param mask GPIO pin number macro
*/
void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask)
{
uint8_t instance;
PORT_Type *portBase;
instance = (uint8_t)GPIO_GetInstance(base);
portBase = s_portBases[instance];
portBase->ISFR = mask;
}
#else
/*!
* brief Clears GPIO pin interrupt status flags.
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* param mask GPIO pin number macro
*/
void GPIO_GpioClearInterruptFlags(GPIO_Type *base, uint32_t mask)
{
base->ISFR[0] = GPIO_FIT_REG(mask);
}
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
/*!
* brief Clears GPIO pin interrupt status flags based on selected interrupt channel(IRQS).
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* param mask GPIO pin number macro
* param channel '0' means selete interrupt channel 0, '1' means selete interrupt channel 1.
*/
void GPIO_GpioClearInterruptChannelFlags(GPIO_Type *base, uint32_t mask, uint32_t channel)
{
assert(channel < 2U);
base->ISFR[channel] = GPIO_FIT_REG(mask);
}
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT */
/*!
* brief Clear GPIO individual pin's interrupt status flag.
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on).
* param pin GPIO specific pin number.
*/
void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t pin)
{
base->ICR[pin] |= GPIO_FIT_REG(GPIO_ICR_ISF(1U));
}
#endif /* FSL_FEATURE_PORT_HAS_NO_INTERRUPT */
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
/*!
* brief The GPIO module supports a device-specific number of data ports, organized as 32-bit
* words/8-bit Bytes. Each 32-bit/8-bit data port includes a GACR register, which defines the byte-level
* attributes required for a successful access to the GPIO programming model. If the GPIO module's GACR register
* organized as 32-bit words, the attribute controls for the 4 data bytes in the GACR follow a standard little
* endian data convention.
*
* param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* param attribute GPIO checker attribute
*/
void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute)
{
#if defined(FSL_FEATURE_GPIO_REGISTERS_WIDTH) && (FSL_FEATURE_GPIO_REGISTERS_WIDTH == 8U)
base->GACR = ((uint8_t)attribute << GPIO_GACR_ACB_SHIFT);
#else
base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) |
((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT);
#endif /* FSL_FEATURE_GPIO_REGISTERS_WIDTH */
}
#endif
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
/*******************************************************************************
* Variables
******************************************************************************/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS;
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* @brief Gets the FGPIO instance according to the GPIO base
*
* @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.)
* @retval FGPIO instance
*/
static uint32_t FGPIO_GetInstance(FGPIO_Type *base);
#endif
/*******************************************************************************
* Code
******************************************************************************/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
static uint32_t FGPIO_GetInstance(FGPIO_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_fgpioBases); instance++)
{
if (s_fgpioBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_fgpioBases));
return instance;
}
#endif
#if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
/*!
* brief Initializes the FGPIO peripheral.
*
* This function ungates the FGPIO clock.
*
* param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
*/
void FGPIO_PortInit(FGPIO_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate FGPIO periphral clock */
CLOCK_EnableClock(s_fgpioClockName[FGPIO_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
#endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
/*!
* brief Initializes a FGPIO pin used by the board.
*
* To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file.
* Then, call the FGPIO_PinInit() function.
*
* This is an example to define an input pin or an output pin configuration:
* code
* Define a digital input pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalInput,
* 0,
* }
* Define a digital output pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalOutput,
* 0,
* }
* endcode
*
* param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* param pin FGPIO port pin number
* param config FGPIO pin configuration pointer
*/
void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
{
assert(NULL != config);
if (config->pinDirection == kGPIO_DigitalInput)
{
base->PDDR &= ~(1UL << pin);
}
else
{
FGPIO_PinWrite(base, pin, config->outputLogic);
base->PDDR |= (1UL << pin);
}
}
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* brief Reads the FGPIO port interrupt status flag.
*
* If a pin is configured to generate the DMA request, the corresponding flag
* is cleared automatically at the completion of the requested DMA transfer.
* Otherwise, the flag remains set until a logic one is written to that flag.
* If configured for a level-sensitive interrupt that remains asserted, the flag
* is set again immediately.
*
* param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt.
*/
uint32_t FGPIO_PortGetInterruptFlags(FGPIO_Type *base)
{
uint8_t instance;
instance = (uint8_t)FGPIO_GetInstance(base);
PORT_Type *portBase;
portBase = s_portBases[instance];
return portBase->ISFR;
}
/*!
* brief Clears the multiple FGPIO pin interrupt status flag.
*
* param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* param mask FGPIO pin number macro
*/
void FGPIO_PortClearInterruptFlags(FGPIO_Type *base, uint32_t mask)
{
uint8_t instance;
instance = (uint8_t)FGPIO_GetInstance(base);
PORT_Type *portBase;
portBase = s_portBases[instance];
portBase->ISFR = mask;
}
#endif
#if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER
/*!
* brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit
* words. Each 32-bit data port includes a GACR register, which defines the byte-level
* attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
* bytes in the GACR follow a standard little endian
* data convention.
*
* param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* param attribute FGPIO checker attribute
*/
void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute)
{
base->GACR = ((uint32_t)attribute << FGPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << FGPIO_GACR_ACB1_SHIFT) |
((uint32_t)attribute << FGPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << FGPIO_GACR_ACB3_SHIFT);
}
#endif
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */

View File

@ -0,0 +1,799 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_GPIO_H_
#define _FSL_GPIO_H_
#include "fsl_common.h"
/*!
* @addtogroup gpio
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief GPIO driver version. */
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 7, 3))
/*@}*/
#if defined(FSL_FEATURE_GPIO_REGISTERS_WIDTH) && (FSL_FEATURE_GPIO_REGISTERS_WIDTH == 8U)
#define GPIO_FIT_REG(value) \
((uint8_t)(value)) /*!< For some platforms with 8-bit register width, cast the type to uint8_t */
#else
#define GPIO_FIT_REG(value) ((uint32_t)(value))
#endif /*FSL_FEATURE_GPIO_REGISTERS_WIDTH*/
/*! @brief GPIO direction definition */
typedef enum _gpio_pin_direction
{
kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/
kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
} gpio_pin_direction_t;
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
/*! @brief GPIO checker attribute */
typedef enum _gpio_checker_attribute
{
kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW =
0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */
kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW =
0x01U, /*!< User nonsecure:Read; User Secure:Read+Write; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW =
0x02U, /*!< User nonsecure:None; User Secure:Read+Write; Privileged Secure:Read+Write */
kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW =
0x03U, /*!< User nonsecure:Read; User Secure:Read; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW =
0x04U, /*!< User nonsecure:None; User Secure:Read; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW =
0x05U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read+Write */
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR =
0x06U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read */
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN =
0x07U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:None */
kGPIO_IgnoreAttributeCheck = 0x80U, /*!< Ignores the attribute check */
} gpio_checker_attribute_t;
#endif
/*!
* @brief The GPIO pin configuration structure.
*
* Each pin can only be configured as either an output pin or an input pin at a time.
* If configured as an input pin, leave the outputConfig unused.
* Note that in some use cases, the corresponding port property should be configured in advance
* with the PORT_SetPinConfig().
*/
typedef struct _gpio_pin_config
{
gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
/* Output configurations; ignore if configured as an input pin */
uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */
} gpio_pin_config_t;
#if (defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) || \
!(defined(FSL_FEATURE_SOC_PORT_COUNT))
/*! @brief Configures the interrupt generation condition. */
typedef enum _gpio_interrupt_config
{
kGPIO_InterruptStatusFlagDisabled = 0x0U, /*!< Interrupt status flag is disabled. */
kGPIO_DMARisingEdge = 0x1U, /*!< ISF flag and DMA request on rising edge. */
kGPIO_DMAFallingEdge = 0x2U, /*!< ISF flag and DMA request on falling edge. */
kGPIO_DMAEitherEdge = 0x3U, /*!< ISF flag and DMA request on either edge. */
kGPIO_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */
kGPIO_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */
kGPIO_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */
kGPIO_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */
kGPIO_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */
kGPIO_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */
kGPIO_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */
kGPIO_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */
kGPIO_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */
kGPIO_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */
} gpio_interrupt_config_t;
#endif
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
/*! @brief Configures the selection of interrupt/DMA request/trigger output. */
typedef enum _gpio_interrupt_selection
{
kGPIO_InterruptOutput0 = 0x0U, /*!< Interrupt/DMA request/trigger output 0. */
kGPIO_InterruptOutput1 = 0x1U, /*!< Interrupt/DMA request/trigger output 1. */
} gpio_interrupt_selection_t;
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT */
#if defined(FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER
/*! @brief GPIO version information. */
typedef struct _gpio_version_info
{
uint16_t feature; /*!< Feature Specification Number. */
uint8_t minor; /*!< Minor Version Number. */
uint8_t major; /*!< Major Version Number. */
} gpio_version_info_t;
#endif /* FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER */
#if defined(FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL) && FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL
/*! @brief GPIO pin and interrupt control. */
typedef enum
{
kGPIO_PinControlNonSecure = 0x01U, /*!< Pin Control Non-Secure. */
kGPIO_InterruptControlNonSecure = 0x02U, /*!< Interrupt Control Non-Secure. */
kGPIO_PinControlNonPrivilege = 0x04U, /*!< Pin Control Non-Privilege. */
kGPIO_InterruptControlNonPrivilege = 0x08U, /*!< Interrupt Control Non-Privilege. */
} gpio_pin_interrupt_control_t;
#endif /* FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL */
/*! @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @addtogroup gpio_driver
* @{
*/
/*! @name GPIO Configuration */
/*@{*/
/*!
* @brief Initializes a GPIO pin used by the board.
*
* To initialize the GPIO, define a pin configuration, as either input or output, in the user file.
* Then, call the GPIO_PinInit() function.
*
* This is an example to define an input pin or an output pin configuration.
* @code
* Define a digital input pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalInput,
* 0,
* }
* Define a digital output pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalOutput,
* 0,
* }
* @endcode
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO port pin number
* @param config GPIO pin configuration pointer
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
#if defined(FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER
/*!
* @brief Get GPIO version information.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param info GPIO version information
*/
void GPIO_GetVersionInfo(GPIO_Type *base, gpio_version_info_t *info);
#endif /* FSL_FEATURE_GPIO_HAS_VERSION_INFO_REGISTER */
#if defined(FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL) && FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL
/*!
* @brief lock or unlock secure privilege.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask pin or interrupt macro
*/
static inline void GPIO_SecurePrivilegeLock(GPIO_Type *base, gpio_pin_interrupt_control_t mask)
{
base->LOCK |= GPIO_FIT_REG(mask);
}
/*!
* @brief Enable Pin Control Non-Secure.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_EnablePinControlNonSecure(GPIO_Type *base, uint32_t mask)
{
base->PCNS |= GPIO_FIT_REG(mask);
}
/*!
* @brief Disable Pin Control Non-Secure.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_DisablePinControlNonSecure(GPIO_Type *base, uint32_t mask)
{
base->PCNS &= GPIO_FIT_REG(~mask);
}
/*!
* @brief Enable Pin Control Non-Privilege.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_EnablePinControlNonPrivilege(GPIO_Type *base, uint32_t mask)
{
base->PCNP |= GPIO_FIT_REG(mask);
}
/*!
* @brief Disable Pin Control Non-Privilege.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_DisablePinControlNonPrivilege(GPIO_Type *base, uint32_t mask)
{
base->PCNP &= GPIO_FIT_REG(~mask);
}
/*!
* @brief Enable Interrupt Control Non-Secure.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_EnableInterruptControlNonSecure(GPIO_Type *base, uint32_t mask)
{
base->ICNS |= GPIO_FIT_REG(mask);
}
/*!
* @brief Disable Interrupt Control Non-Secure.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_DisableInterruptControlNonSecure(GPIO_Type *base, uint32_t mask)
{
base->ICNS &= GPIO_FIT_REG(~mask);
}
/*!
* @brief Enable Interrupt Control Non-Privilege.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_EnableInterruptControlNonPrivilege(GPIO_Type *base, uint32_t mask)
{
base->ICNP |= GPIO_FIT_REG(mask);
}
/*!
* @brief Disable Interrupt Control Non-Privilege.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_DisableInterruptControlNonPrivilege(GPIO_Type *base, uint32_t mask)
{
base->ICNP &= GPIO_FIT_REG(~mask);
}
#endif /* FSL_FEATURE_GPIO_HAS_SECURE_PRIVILEGE_CONTROL */
#if defined(FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL
/*!
* @brief Enable port input.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortInputEnable(GPIO_Type *base, uint32_t mask)
{
base->PIDR &= GPIO_FIT_REG(~mask);
}
/*!
* @brief Disable port input.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortInputDisable(GPIO_Type *base, uint32_t mask)
{
base->PIDR |= GPIO_FIT_REG(mask);
}
#endif /* FSL_FEATURE_GPIO_HAS_PORT_INPUT_CONTROL */
/*@}*/
/*! @name GPIO Output Operations */
/*@{*/
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO pin number
* @param output GPIO pin output logic level.
* - 0: corresponding pin output low-logic level.
* - 1: corresponding pin output high-logic level.
*/
static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output)
{
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
if (output == 0U)
{
base->PCOR = GPIO_FIT_REG(1UL << pin);
}
else
{
base->PSOR = GPIO_FIT_REG(1UL << pin);
}
#else
if (output == 0U)
{
base->PDOR |= GPIO_FIT_REG(1UL << pin);
}
else
{
base->PDOR &= ~GPIO_FIT_REG(1UL << pin);
}
#endif
}
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortSet(GPIO_Type *base, uint32_t mask)
{
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
base->PSOR = GPIO_FIT_REG(mask);
#else
base->PDOR |= GPIO_FIT_REG(mask);
#endif
}
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortClear(GPIO_Type *base, uint32_t mask)
{
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
base->PCOR = GPIO_FIT_REG(mask);
#else
base->PDOR &= ~GPIO_FIT_REG(mask);
#endif
}
/*!
* @brief Reverses the current output logic of the multiple GPIO pins.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t mask)
{
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
base->PTOR = GPIO_FIT_REG(mask);
#else
base->PDOR ^= GPIO_FIT_REG(mask);
#endif
}
/*@}*/
/*! @name GPIO Input Operations */
/*@{*/
/*!
* @brief Reads the current input value of the GPIO port.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param pin GPIO pin number
* @retval GPIO port input value
* - 0: corresponding pin input low-logic level.
* - 1: corresponding pin input high-logic level.
*/
static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t pin)
{
return (((uint32_t)(base->PDIR) >> pin) & 0x01UL);
}
/*@}*/
/*! @name GPIO Interrupt */
/*@{*/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* @brief Reads the GPIO port interrupt status flag.
*
* If a pin is configured to generate the DMA request, the corresponding flag
* is cleared automatically at the completion of the requested DMA transfer.
* Otherwise, the flag remains set until a logic one is written to that flag.
* If configured for a level sensitive interrupt that remains asserted, the flag
* is set again immediately.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt.
*/
uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base);
/*!
* @brief Clears multiple GPIO pin interrupt status flags.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask);
#else
/*!
* @brief Configures the gpio pin interrupt/DMA request.
*
* @param base GPIO peripheral base pointer.
* @param pin GPIO pin number.
* @param config GPIO pin interrupt configuration.
* - #kGPIO_InterruptStatusFlagDisabled: Interrupt/DMA request disabled.
* - #kGPIO_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
* - #kGPIO_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
* - #kGPIO_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
* - #kGPIO_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
* - #kGPIO_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
* - #kGPIO_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
* - #kGPIO_InterruptLogicZero : Interrupt when logic zero.
* - #kGPIO_InterruptRisingEdge : Interrupt on rising edge.
* - #kGPIO_InterruptFallingEdge: Interrupt on falling edge.
* - #kGPIO_InterruptEitherEdge : Interrupt on either edge.
* - #kGPIO_InterruptLogicOne : Interrupt when logic one.
* - #kGPIO_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
* - #kGPIO_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit).
*/
static inline void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_config_t config)
{
assert(base);
base->ICR[pin] = GPIO_FIT_REG((base->ICR[pin] & ~GPIO_ICR_IRQC_MASK) | GPIO_ICR_IRQC(config));
}
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
/*!
* @brief Configures the gpio pin interrupt/DMA request/trigger output channel selection.
*
* @param base GPIO peripheral base pointer.
* @param pin GPIO pin number.
* @param selection GPIO pin interrupt output selection.
* - #kGPIO_InterruptOutput0: Interrupt/DMA request/trigger output 0.
* - #kGPIO_InterruptOutput1 : Interrupt/DMA request/trigger output 1.
*/
static inline void GPIO_SetPinInterruptChannel(GPIO_Type *base, uint32_t pin, gpio_interrupt_selection_t selection)
{
assert(base);
base->ICR[pin] = GPIO_FIT_REG((base->ICR[pin] & ~GPIO_ICR_IRQS_MASK) | GPIO_ICR_IRQS(selection));
}
#endif
/*!
* @brief Read the GPIO interrupt status flags.
*
* @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
* @return The current GPIO's interrupt status flag.
* '1' means the related pin's flag is set, '0' means the related pin's flag not set.
* For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
*/
uint32_t GPIO_GpioGetInterruptFlags(GPIO_Type *base);
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
/*!
* @brief Read the GPIO interrupt status flags based on selected interrupt channel(IRQS).
*
* @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
* @param channel '0' means selete interrupt channel 0, '1' means selete interrupt channel 1.
* @return The current GPIO's interrupt status flag based on the selected interrupt channel.
* '1' means the related pin's flag is set, '0' means the related pin's flag not set.
* For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
*/
uint32_t GPIO_GpioGetInterruptChannelFlags(GPIO_Type *base, uint32_t channel);
#endif
/*!
* @brief Read individual pin's interrupt status flag.
*
* @param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on)
* @param pin GPIO specific pin number.
* @return The current selected pin's interrupt status flag.
*/
uint8_t GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin);
/*!
* @brief Clears GPIO pin interrupt status flags.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
void GPIO_GpioClearInterruptFlags(GPIO_Type *base, uint32_t mask);
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT)
/*!
* @brief Clears GPIO pin interrupt status flags based on selected interrupt channel(IRQS).
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
* @param channel '0' means selete interrupt channel 0, '1' means selete interrupt channel 1.
*/
void GPIO_GpioClearInterruptChannelFlags(GPIO_Type *base, uint32_t mask, uint32_t channel);
#endif
/*!
* @brief Clear GPIO individual pin's interrupt status flag.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on).
* @param pin GPIO specific pin number.
*/
void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t pin);
/*!
* @brief Reads the GPIO DMA request flags.
* The corresponding flag will be cleared automatically at the completion of the requested
* DMA transfer
*/
static inline uint32_t GPIO_GetPinsDMARequestFlags(GPIO_Type *base)
{
assert(base);
return (base->ISFR[1]);
}
/*!
* @brief Sets the GPIO interrupt configuration in PCR register for multiple pins.
*
* @param base GPIO peripheral base pointer.
* @param mask GPIO pin number macro.
* @param config GPIO pin interrupt configuration.
* - #kGPIO_InterruptStatusFlagDisabled: Interrupt disabled.
* - #kGPIO_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
* - #kGPIO_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
* - #kGPIO_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
* - #kGPIO_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
* - #kGPIO_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
* - #kGPIO_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
* - #kGPIO_InterruptLogicZero : Interrupt when logic zero.
* - #kGPIO_InterruptRisingEdge : Interrupt on rising edge.
* - #kGPIO_InterruptFallingEdge: Interrupt on falling edge.
* - #kGPIO_InterruptEitherEdge : Interrupt on either edge.
* - #kGPIO_InterruptLogicOne : Interrupt when logic one.
* - #kGPIO_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
* - #kGPIO_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit)..
*/
static inline void GPIO_SetMultipleInterruptPinsConfig(GPIO_Type *base, uint32_t mask, gpio_interrupt_config_t config)
{
assert(base);
if (0UL != (mask & 0xffffUL))
{
base->GICLR = GPIO_FIT_REG((GPIO_ICR_IRQC(config)) | (mask & 0xffffU));
}
mask = mask >> 16U;
if (mask != 0UL)
{
base->GICHR = GPIO_FIT_REG((GPIO_ICR_IRQC(config)) | (mask & 0xffffU));
}
}
#endif
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
/*!
* brief The GPIO module supports a device-specific number of data ports, organized as 32-bit
* words/8-bit Bytes. Each 32-bit/8-bit data port includes a GACR register, which defines the byte-level
* attributes required for a successful access to the GPIO programming model. If the GPIO module's GACR register
* organized as 32-bit words, the attribute controls for the 4 data bytes in the GACR follow a standard little
* endian data convention.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param attribute GPIO checker attribute
*/
void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute);
#endif
/*@}*/
/*! @} */
/*!
* @addtogroup fgpio_driver
* @{
*/
/*
* Introduces the FGPIO feature.
*
* The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT
* interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and
* complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO.
*/
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
/*! @name FGPIO Configuration */
/*@{*/
#if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
/*!
* @brief Initializes the FGPIO peripheral.
*
* This function ungates the FGPIO clock.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
*/
void FGPIO_PortInit(FGPIO_Type *base);
#endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
/*!
* @brief Initializes a FGPIO pin used by the board.
*
* To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file.
* Then, call the FGPIO_PinInit() function.
*
* This is an example to define an input pin or an output pin configuration:
* @code
* Define a digital input pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalInput,
* 0,
* }
* Define a digital output pin configuration,
* gpio_pin_config_t config =
* {
* kGPIO_DigitalOutput,
* 0,
* }
* @endcode
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param pin FGPIO port pin number
* @param config FGPIO pin configuration pointer
*/
void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
/*@}*/
/*! @name FGPIO Output Operations */
/*@{*/
/*!
* @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param pin FGPIO pin number
* @param output FGPIOpin output logic level.
* - 0: corresponding pin output low-logic level.
* - 1: corresponding pin output high-logic level.
*/
static inline void FGPIO_PinWrite(FGPIO_Type *base, uint32_t pin, uint8_t output)
{
if (output == 0U)
{
base->PCOR = 1UL << pin;
}
else
{
base->PSOR = 1UL << pin;
}
}
/*!
* @brief Sets the output level of the multiple FGPIO pins to the logic 1.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pin number macro
*/
static inline void FGPIO_PortSet(FGPIO_Type *base, uint32_t mask)
{
base->PSOR = mask;
}
/*!
* @brief Sets the output level of the multiple FGPIO pins to the logic 0.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pin number macro
*/
static inline void FGPIO_PortClear(FGPIO_Type *base, uint32_t mask)
{
base->PCOR = mask;
}
/*!
* @brief Reverses the current output logic of the multiple FGPIO pins.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pin number macro
*/
static inline void FGPIO_PortToggle(FGPIO_Type *base, uint32_t mask)
{
base->PTOR = mask;
}
/*@}*/
/*! @name FGPIO Input Operations */
/*@{*/
/*!
* @brief Reads the current input value of the FGPIO port.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param pin FGPIO pin number
* @retval FGPIO port input value
* - 0: corresponding pin input low-logic level.
* - 1: corresponding pin input high-logic level.
*/
static inline uint32_t FGPIO_PinRead(FGPIO_Type *base, uint32_t pin)
{
return (((base->PDIR) >> pin) & 0x01U);
}
/*@}*/
/*! @name FGPIO Interrupt */
/*@{*/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && \
defined(FSL_FEATURE_SOC_PORT_COUNT)
/*!
* @brief Reads the FGPIO port interrupt status flag.
*
* If a pin is configured to generate the DMA request, the corresponding flag
* is cleared automatically at the completion of the requested DMA transfer.
* Otherwise, the flag remains set until a logic one is written to that flag.
* If configured for a level-sensitive interrupt that remains asserted, the flag
* is set again immediately.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the
* pin 0 and 17 have the interrupt.
*/
uint32_t FGPIO_PortGetInterruptFlags(FGPIO_Type *base);
/*!
* @brief Clears the multiple FGPIO pin interrupt status flag.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param mask FGPIO pin number macro
*/
void FGPIO_PortClearInterruptFlags(FGPIO_Type *base, uint32_t mask);
#endif
#if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER
/*!
* @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit
* words. Each 32-bit data port includes a GACR register, which defines the byte-level
* attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
* bytes in the GACR follow a standard little endian
* data convention.
*
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
* @param attribute FGPIO checker attribute
*/
void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute);
#endif /* FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER */
/*@}*/
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _FSL_GPIO_H_*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,973 @@
/*
* Copyright 2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_i3c_edma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.i3c_edma"
#endif
/*! @brief States for the state machine used by transactional APIs. */
enum _i3c_edma_transfer_states
{
kIdleState = 0,
kIBIWonState,
kSlaveStartState,
kSendCommandState,
kWaitRepeatedStartCompleteState,
kTransmitDataState,
kReceiveDataState,
kStopState,
kWaitForCompletionState,
kAddressMatchState,
};
/*! @brief Common sets of flags used by the driver. */
enum _i3c_edma_flag_constants
{
/*! All flags which are cleared by the driver upon starting a transfer. */
kMasterClearFlags = kI3C_MasterSlaveStartFlag | kI3C_MasterControlDoneFlag | kI3C_MasterCompleteFlag |
kI3C_MasterArbitrationWonFlag | kI3C_MasterSlave2MasterFlag | kI3C_MasterErrorFlag,
/*! IRQ sources enabled by the non-blocking transactional API. */
kMasterDMAIrqFlags = kI3C_MasterSlaveStartFlag | kI3C_MasterControlDoneFlag | kI3C_MasterCompleteFlag |
kI3C_MasterArbitrationWonFlag | kI3C_MasterErrorFlag | kI3C_MasterSlave2MasterFlag,
/*! Errors to check for. */
kMasterErrorFlags = kI3C_MasterErrorNackFlag | kI3C_MasterErrorWriteAbortFlag |
#if !defined(FSL_FEATURE_I3C_HAS_NO_MERRWARN_TERM) || (!FSL_FEATURE_I3C_HAS_NO_MERRWARN_TERM)
kI3C_MasterErrorTermFlag |
#endif
kI3C_MasterErrorParityFlag | kI3C_MasterErrorCrcFlag | kI3C_MasterErrorReadFlag |
kI3C_MasterErrorWriteFlag | kI3C_MasterErrorMsgFlag | kI3C_MasterErrorInvalidReqFlag |
kI3C_MasterErrorTimeoutFlag,
/*! All flags which are cleared by the driver upon starting a transfer. */
kSlaveClearFlags = kI3C_SlaveBusStartFlag | kI3C_SlaveMatchedFlag | kI3C_SlaveBusStopFlag,
/*! IRQ sources enabled by the non-blocking transactional API. */
kSlaveDMAIrqFlags = kI3C_SlaveBusStartFlag | kI3C_SlaveMatchedFlag |
kI3C_SlaveBusStopFlag | /*kI3C_SlaveRxReadyFlag |*/
kI3C_SlaveDynamicAddrChangedFlag | kI3C_SlaveReceivedCCCFlag | kI3C_SlaveErrorFlag |
kI3C_SlaveHDRCommandMatchFlag | kI3C_SlaveCCCHandledFlag | kI3C_SlaveEventSentFlag,
/*! Errors to check for. */
kSlaveErrorFlags = kI3C_SlaveErrorOverrunFlag | kI3C_SlaveErrorUnderrunFlag | kI3C_SlaveErrorUnderrunNakFlag |
kI3C_SlaveErrorTermFlag | kI3C_SlaveErrorInvalidStartFlag | kI3C_SlaveErrorSdrParityFlag |
kI3C_SlaveErrorHdrParityFlag | kI3C_SlaveErrorHdrCRCFlag | kI3C_SlaveErrorS0S1Flag |
kI3C_SlaveErrorOverreadFlag | kI3C_SlaveErrorOverwriteFlag,
};
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static void I3C_MasterRunEDMATransfer(
I3C_Type *base, i3c_master_edma_handle_t *handle, void *data, size_t dataSize, i3c_direction_t direction);
/*******************************************************************************
* Code
******************************************************************************/
static void I3C_MasterTransferEDMACallbackRx(edma_handle_t *dmaHandle, void *param, bool transferDone, uint32_t tcds)
{
i3c_master_edma_handle_t *i3cHandle = (i3c_master_edma_handle_t *)param;
if (transferDone)
{
/* Read last data byte */
i3cHandle->base->MCTRL |= I3C_MCTRL_RDTERM(1U);
size_t rxCount = 0U;
while (rxCount == 0U)
{
I3C_MasterGetFifoCounts(i3cHandle->base, &rxCount, NULL);
};
*(uint8_t *)((uint32_t)((uint32_t *)i3cHandle->transfer.data) + i3cHandle->transfer.dataSize - 1U) =
(uint8_t)i3cHandle->base->MRDATAB;
/* Disable I3C Rx DMA */
i3cHandle->base->MDATACTRL &= ~I3C_MDMACTRL_DMAFB_MASK;
i3cHandle->state = (uint8_t)kStopState;
I3C_MasterTransferEDMAHandleIRQ(i3cHandle->base, i3cHandle);
}
}
static void I3C_MasterTransferEDMACallbackTx(edma_handle_t *dmaHandle, void *param, bool transferDone, uint32_t tcds)
{
i3c_master_edma_handle_t *i3cHandle = (i3c_master_edma_handle_t *)param;
if (transferDone)
{
/* Disable I3C Tx DMA */
i3cHandle->base->MDATACTRL &= ~I3C_MDMACTRL_DMATB_MASK;
i3cHandle->state = (uint8_t)kStopState;
size_t txCount = 0U;
do
{
I3C_MasterGetFifoCounts(i3cHandle->base, NULL, &txCount);
} while (txCount != 0U);
I3C_MasterTransferEDMAHandleIRQ(i3cHandle->base, i3cHandle);
}
}
/*!
* brief Prepares the transfer state machine and fills in the command buffer.
* param handle Master nonblocking driver handle.
*/
static status_t I3C_MasterInitTransferStateMachineEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle)
{
i3c_master_transfer_t *xfer = &handle->transfer;
status_t result = kStatus_Success;
i3c_direction_t direction = xfer->direction;
/* Calculate command count and put into command buffer. */
handle->subaddressCount = 0U;
if (xfer->subaddressSize != 0U)
{
for (uint32_t i = xfer->subaddressSize; i > 0U; i--)
{
handle->subaddressBuffer[handle->subaddressCount++] = (uint8_t)((xfer->subaddress) >> (8U * (i - 1U)));
}
}
/* Start condition shall be ommited, switch directly to next phase */
if (xfer->dataSize == 0U)
{
handle->state = (uint8_t)kStopState;
}
/* Handle no start option. */
if (0U != (xfer->flags & (uint32_t)kI3C_TransferNoStartFlag))
{
/* No need to send start flag, directly go to send command or data */
if (xfer->subaddressSize > 0UL)
{
handle->state = (uint8_t)kSendCommandState;
}
else
{
if (direction == kI3C_Write)
{
/* Next state, send data. */
handle->state = (uint8_t)kTransmitDataState;
}
else
{
/* Only support write with no stop signal. */
return kStatus_InvalidArgument;
}
}
}
else
{
if (xfer->subaddressSize != 0U)
{
handle->state = (uint8_t)kSendCommandState;
}
else
{
if (handle->transfer.direction == kI3C_Write)
{
handle->state = (uint8_t)kTransmitDataState;
}
else if (handle->transfer.direction == kI3C_Read)
{
handle->state = (uint8_t)kReceiveDataState;
}
else
{
return kStatus_InvalidArgument;
}
}
if (handle->transfer.direction == kI3C_Read)
{
I3C_MasterRunEDMATransfer(base, handle, xfer->data, xfer->dataSize - 1U, kI3C_Read);
}
if (handle->state != (uint8_t)kStopState)
{
/* If repeated start is requested, send repeated start. */
if (0U != (xfer->flags & (uint32_t)kI3C_TransferRepeatedStartFlag))
{
result = I3C_MasterRepeatedStart(base, xfer->busType, xfer->slaveAddress, direction);
}
else /* For normal transfer, send start. */
{
result = I3C_MasterStart(base, xfer->busType, xfer->slaveAddress, direction);
}
}
}
I3C_MasterTransferEDMAHandleIRQ(base, handle);
return result;
}
static void I3C_MasterRunEDMATransfer(
I3C_Type *base, i3c_master_edma_handle_t *handle, void *data, size_t dataSize, i3c_direction_t direction)
{
edma_transfer_config_t xferConfig;
uint32_t address;
bool isEnableTxDMA = false;
bool isEnableRxDMA = false;
uint32_t width;
handle->transferCount = dataSize;
switch (direction)
{
case kI3C_Write:
address = (uint32_t)&base->MWDATAB1;
EDMA_PrepareTransfer(&xferConfig, data, sizeof(uint8_t), (uint32_t *)address, sizeof(uint8_t), 1, dataSize,
kEDMA_MemoryToPeripheral);
(void)EDMA_SubmitTransfer(handle->txDmaHandle, &xferConfig);
EDMA_StartTransfer(handle->txDmaHandle);
isEnableTxDMA = true;
width = 1U;
break;
case kI3C_Read:
address = (uint32_t)&base->MRDATAB;
EDMA_PrepareTransfer(&xferConfig, (uint32_t *)address, sizeof(uint8_t), data, sizeof(uint8_t), 1, dataSize,
kEDMA_PeripheralToMemory);
(void)EDMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig);
EDMA_StartTransfer(handle->rxDmaHandle);
isEnableRxDMA = true;
width = 1U;
break;
default:
/* This should never happen */
assert(0);
break;
}
I3C_MasterEnableDMA(base, isEnableTxDMA, isEnableRxDMA, width);
}
static status_t I3C_MasterRunTransferStateMachineEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, bool *isDone)
{
uint32_t status;
uint32_t errStatus;
status_t result = kStatus_Success;
i3c_master_transfer_t *xfer;
size_t rxCount = 0;
bool state_complete = false;
/* Set default isDone return value. */
*isDone = false;
/* Check for errors. */
status = (uint32_t)I3C_MasterGetPendingInterrupts(base);
I3C_MasterClearStatusFlags(base, status);
i3c_master_state_t masterState = I3C_MasterGetState(base);
errStatus = I3C_MasterGetErrorStatusFlags(base);
result = I3C_MasterCheckAndClearError(base, errStatus);
if (kStatus_Success != result)
{
return result;
}
if (0UL != (status & (uint32_t)kI3C_MasterSlave2MasterFlag))
{
if (handle->callback.slave2Master != NULL)
{
handle->callback.slave2Master(base, handle->userData);
}
}
if ((0UL != (status & (uint32_t)kI3C_MasterSlaveStartFlag)) && (handle->transfer.busType != kI3C_TypeI2C))
{
handle->state = (uint8_t)kSlaveStartState;
}
if ((masterState == kI3C_MasterStateIbiRcv) || (masterState == kI3C_MasterStateIbiAck))
{
handle->state = (uint8_t)kIBIWonState;
}
if (handle->state == (uint8_t)kIdleState)
{
return result;
}
if (handle->state == (uint8_t)kIBIWonState)
{
/* Get fifo counts and compute room in tx fifo. */
rxCount = (base->MDATACTRL & I3C_MDATACTRL_RXCOUNT_MASK) >> I3C_MDATACTRL_RXCOUNT_SHIFT;
}
/* Get pointer to private data. */
xfer = &handle->transfer;
while (!state_complete)
{
/* Execute the state. */
switch (handle->state)
{
case (uint8_t)kSlaveStartState:
/* Emit start + 0x7E */
I3C_MasterEmitRequest(base, kI3C_RequestAutoIbi);
handle->state = (uint8_t)kIBIWonState;
state_complete = true;
break;
case (uint8_t)kIBIWonState:
if (masterState == kI3C_MasterStateIbiAck)
{
handle->ibiType = I3C_GetIBIType(base);
if (handle->callback.ibiCallback != NULL)
{
handle->callback.ibiCallback(base, handle, handle->ibiType, kI3C_IbiAckNackPending);
}
else
{
I3C_MasterEmitIBIResponse(base, kI3C_IbiRespNack);
}
}
/* Make sure there is data in the rx fifo. */
if (0UL != rxCount)
{
if ((handle->ibiBuff == NULL) && (handle->callback.ibiCallback != NULL))
{
handle->callback.ibiCallback(base, handle, kI3C_IbiNormal, kI3C_IbiDataBuffNeed);
}
uint8_t tempData = (uint8_t)base->MRDATAB;
if (handle->ibiBuff != NULL)
{
handle->ibiBuff[handle->ibiPayloadSize++] = tempData;
}
rxCount--;
break;
}
else if (0UL != (status & (uint32_t)kI3C_MasterCompleteFlag))
{
handle->ibiType = I3C_GetIBIType(base);
handle->ibiAddress = I3C_GetIBIAddress(base);
state_complete = true;
result = kStatus_I3C_IBIWon;
}
else
{
state_complete = true;
}
break;
case (uint8_t)kSendCommandState:
/* Calculate command count and put into command buffer. */
if (xfer->dataSize == 0U)
{
*isDone = true;
}
I3C_MasterRunEDMATransfer(base, handle, handle->subaddressBuffer, handle->subaddressCount, kI3C_Write);
if ((xfer->direction == kI3C_Read) || (0UL == xfer->dataSize))
{
if (0UL == xfer->dataSize)
{
handle->state = (uint8_t)kWaitForCompletionState;
}
else
{
/* xfer->dataSize != 0U, xfer->direction = kI3C_Read */
handle->state = (uint8_t)kWaitRepeatedStartCompleteState;
}
}
else
{
/* Next state, transfer data. */
handle->state = (uint8_t)kTransmitDataState;
}
state_complete = true;
break;
case (uint8_t)kWaitRepeatedStartCompleteState:
/* We stay in this state until the maste complete. */
if (0UL != (status & (uint32_t)kI3C_MasterCompleteFlag))
{
handle->state = (uint8_t)kReceiveDataState;
/* Send repeated start and slave address. */
result = I3C_MasterRepeatedStart(base, xfer->busType, xfer->slaveAddress, kI3C_Read);
}
state_complete = true;
break;
case (uint8_t)kTransmitDataState:
I3C_MasterRunEDMATransfer(base, handle, xfer->data, xfer->dataSize, kI3C_Write);
handle->state = (uint8_t)kWaitForCompletionState;
state_complete = true;
break;
case (uint8_t)kReceiveDataState:
/* Do DMA read. */
handle->state = (uint8_t)kWaitForCompletionState;
state_complete = true;
break;
case (uint8_t)kWaitForCompletionState:
/* We stay in this state until the maste complete. */
if (0UL != (status & (uint32_t)kI3C_MasterCompleteFlag))
{
handle->state = (uint8_t)kStopState;
}
else
{
state_complete = true;
}
break;
case (uint8_t)kStopState:
/* Only issue a stop transition if the caller requested it. */
if (0UL == (xfer->flags & (uint32_t)kI3C_TransferNoStopFlag))
{
if (xfer->busType == kI3C_TypeI3CDdr)
{
I3C_MasterEmitRequest(base, kI3C_RequestForceExit);
}
else
{
I3C_MasterEmitRequest(base, kI3C_RequestEmitStop);
}
}
*isDone = true;
state_complete = true;
break;
default:
assert(false);
break;
}
}
return result;
}
void I3C_MasterTransferCreateHandleEDMA(I3C_Type *base,
i3c_master_edma_handle_t *handle,
const i3c_master_edma_callback_t *callback,
void *userData,
edma_handle_t *rxDmaHandle,
edma_handle_t *txDmaHandle)
{
uint32_t instance;
assert(NULL != handle);
/* Clear out the handle. */
(void)memset(handle, 0, sizeof(*handle));
/* Look up instance number */
instance = I3C_GetInstance(base);
handle->base = base;
handle->txDmaHandle = txDmaHandle;
handle->rxDmaHandle = rxDmaHandle;
handle->callback = *callback;
handle->userData = userData;
/* Save this handle for IRQ use. */
s_i3cMasterHandle[instance] = handle;
/* Set irq handler. */
s_i3cMasterIsr = I3C_MasterTransferEDMAHandleIRQ;
EDMA_SetCallback(handle->rxDmaHandle, I3C_MasterTransferEDMACallbackRx, handle);
EDMA_SetCallback(handle->txDmaHandle, I3C_MasterTransferEDMACallbackTx, handle);
/* Clear all flags. */
I3C_MasterClearErrorStatusFlags(base, (uint32_t)kMasterErrorFlags);
I3C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags);
/* Reset fifos. These flags clear automatically. */
base->MDATACTRL |= I3C_MDATACTRL_FLUSHTB_MASK | I3C_MDATACTRL_FLUSHFB_MASK;
/* Enable NVIC IRQ, this only enables the IRQ directly connected to the NVIC.
In some cases the I3C IRQ is configured through INTMUX, user needs to enable
INTMUX IRQ in application code. */
(void)EnableIRQ(kI3cIrqs[instance]);
/* Clear internal IRQ enables and enable NVIC IRQ. */
I3C_MasterEnableInterrupts(base, (uint32_t)kMasterDMAIrqFlags);
}
/*!
* brief Performs a non-blocking DMA transaction on the I2C/I3C bus.
*
* param base The I3C peripheral base address.
* param handle Pointer to the I3C master driver handle.
* param transfer The pointer to the transfer descriptor.
* retval #kStatus_Success The transaction was started successfully.
* retval #kStatus_I3C_Busy Either another master is currently utilizing the bus, or a non-blocking
* transaction is already in progress.
*/
status_t I3C_MasterTransferEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, i3c_master_transfer_t *transfer)
{
assert(NULL != handle);
assert(NULL != transfer);
assert(transfer->subaddressSize <= sizeof(transfer->subaddress));
i3c_master_state_t masterState = I3C_MasterGetState(base);
bool checkDdrState = false;
/* Return busy if another transaction is in progress. */
if (handle->state != (uint8_t)kIdleState)
{
return kStatus_I3C_Busy;
}
/* Return an error if the bus is already in use not by us. */
checkDdrState = (transfer->busType == kI3C_TypeI3CDdr) ? (masterState != kI3C_MasterStateDdr) : true;
if ((masterState != kI3C_MasterStateIdle) && (masterState != kI3C_MasterStateNormAct) && checkDdrState)
{
return kStatus_I3C_Busy;
}
/* Disable I3C IRQ sources while we configure stuff. */
I3C_MasterDisableInterrupts(
base, ((uint32_t)kMasterDMAIrqFlags | (uint32_t)kI3C_MasterRxReadyFlag | (uint32_t)kI3C_MasterTxReadyFlag));
/* Save transfer into handle. */
handle->transfer = *transfer;
/* Configure IBI response type. */
base->MCTRL &= ~I3C_MCTRL_IBIRESP_MASK;
base->MCTRL |= I3C_MCTRL_IBIRESP(transfer->ibiResponse);
/* Clear all flags. */
I3C_MasterClearErrorStatusFlags(base, (uint32_t)kMasterErrorFlags);
I3C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags);
/* Reset fifos. These flags clear automatically. */
base->MDATACTRL |= I3C_MDATACTRL_FLUSHTB_MASK | I3C_MDATACTRL_FLUSHFB_MASK;
/* Generate commands to send. */
(void)I3C_MasterInitTransferStateMachineEDMA(base, handle);
/* Enable I3C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
I3C_MasterEnableInterrupts(base, (uint32_t)(kMasterDMAIrqFlags));
if (transfer->busType == kI3C_TypeI2C)
{
I3C_MasterDisableInterrupts(base, (uint32_t)kI3C_MasterSlaveStartFlag);
}
return kStatus_Success;
}
void I3C_MasterTransferEDMAHandleIRQ(I3C_Type *base, void *i3cHandle)
{
i3c_master_edma_handle_t *handle = (i3c_master_edma_handle_t *)i3cHandle;
bool isDone;
status_t result;
/* Don't do anything if we don't have a valid handle. */
if (NULL == handle)
{
return;
}
result = I3C_MasterRunTransferStateMachineEDMA(base, handle, &isDone);
if (handle->state == (uint8_t)kIdleState)
{
return;
}
if (isDone || (result != kStatus_Success))
{
/* XXX need to handle data that may be in rx fifo below watermark level? */
/* XXX handle error, terminate xfer */
if ((result == kStatus_I3C_Nak) || (result == kStatus_I3C_IBIWon))
{
I3C_MasterEmitRequest(base, kI3C_RequestEmitStop);
}
/* Set handle to idle state. */
handle->state = (uint8_t)kIdleState;
/* Invoke IBI user callback. */
if ((result == kStatus_I3C_IBIWon) && (handle->callback.ibiCallback != NULL))
{
handle->callback.ibiCallback(base, handle, handle->ibiType, kI3C_IbiReady);
handle->ibiPayloadSize = 0;
}
/* Invoke callback. */
if (NULL != handle->callback.transferComplete)
{
handle->callback.transferComplete(base, handle, result, handle->userData);
}
}
}
/*!
* brief Get master transfer status during a dma non-blocking transfer
*
* param base I3C peripheral base address
* param handle pointer to i2c_master_edma_handle_t structure
* param count Number of bytes transferred so far by the non-blocking transaction.
*/
status_t I3C_MasterTransferGetCountEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, size_t *count)
{
assert(handle != NULL);
if (NULL == count)
{
return kStatus_InvalidArgument;
}
/* Catch when there is not an active transfer. */
if (handle->state == (uint8_t)kIdleState)
{
*count = 0;
return kStatus_NoTransferInProgress;
}
/* There is no necessity to disable interrupts as we read a single integer value */
i3c_direction_t dir = handle->transfer.direction;
if (dir == kI3C_Read)
{
*count = handle->transferCount -
1U * EDMA_GetRemainingMajorLoopCount(handle->rxDmaHandle->base, handle->rxDmaHandle->channel);
}
else
{
*count = handle->transferCount -
1U * EDMA_GetRemainingMajorLoopCount(handle->txDmaHandle->base, handle->txDmaHandle->channel);
}
return kStatus_Success;
}
/*!
* brief Abort a master edma non-blocking transfer in a early time
*
* param base I3C peripheral base address
* param handle pointer to i2c_master_edma_handle_t structure
*/
void I3C_MasterTransferAbortEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle)
{
if (handle->state != (uint8_t)kIdleState)
{
EDMA_AbortTransfer(handle->txDmaHandle);
EDMA_AbortTransfer(handle->rxDmaHandle);
I3C_MasterEnableDMA(base, false, false, 0);
/* Reset fifos. These flags clear automatically. */
base->MDATACTRL |= I3C_MDATACTRL_FLUSHTB_MASK | I3C_MDATACTRL_FLUSHFB_MASK;
/* Send a stop command to finalize the transfer. */
(void)I3C_MasterStop(base);
/* Reset handle. */
handle->state = (uint8_t)kIdleState;
}
}
static void I3C_SlaveTransferEDMACallback(edma_handle_t *dmaHandle, void *param, bool transferDone, uint32_t tcds)
{
i3c_slave_edma_handle_t *i3cHandle = (i3c_slave_edma_handle_t *)param;
if (transferDone)
{
/* Simply disable dma enablement */
if (i3cHandle->txDmaHandle == dmaHandle)
{
i3cHandle->base->SDMACTRL &= ~I3C_SDMACTRL_DMATB_MASK;
if (i3cHandle->transfer.txDataSize > 1U)
{
/* Send the last byte. */
i3cHandle->base->SWDATABE = *(uint8_t *)((uintptr_t)i3cHandle->transfer.txData + i3cHandle->transfer.txDataSize - 1U);
}
}
else
{
i3cHandle->base->SDMACTRL &= ~I3C_SDMACTRL_DMAFB_MASK;
}
}
}
/*!
* brief Create a new handle for the I3C slave DMA APIs.
*
* The creation of a handle is for use with the DMA APIs. Once a handle
* is created, there is not a corresponding destroy handle. If the user wants to
* terminate a transfer, the I3C_SlaveTransferAbortDMA() API shall be called.
*
* For devices where the I3C send and receive DMA requests are OR'd together, the @a txDmaHandle
* parameter is ignored and may be set to NULL.
*
* param base The I3C peripheral base address.
* param handle Pointer to the I3C slave driver handle.
* param callback User provided pointer to the asynchronous callback function.
* param userData User provided pointer to the application callback data.
* param rxDmaHandle Handle for the DMA receive channel. Created by the user prior to calling this function.
* param txDmaHandle Handle for the DMA transmit channel. Created by the user prior to calling this function.
*/
void I3C_SlaveTransferCreateHandleEDMA(I3C_Type *base,
i3c_slave_edma_handle_t *handle,
i3c_slave_edma_callback_t callback,
void *userData,
edma_handle_t *rxDmaHandle,
edma_handle_t *txDmaHandle)
{
uint32_t instance;
assert(NULL != handle);
/* Clear out the handle. */
(void)memset(handle, 0, sizeof(*handle));
/* Look up instance number */
instance = I3C_GetInstance(base);
handle->base = base;
handle->txDmaHandle = txDmaHandle;
handle->rxDmaHandle = rxDmaHandle;
handle->callback = callback;
handle->userData = userData;
/* Save this handle for IRQ use. */
s_i3cSlaveHandle[instance] = handle;
/* Set irq handler. */
s_i3cSlaveIsr = I3C_SlaveTransferEDMAHandleIRQ;
EDMA_SetCallback(handle->rxDmaHandle, I3C_SlaveTransferEDMACallback, handle);
EDMA_SetCallback(handle->txDmaHandle, I3C_SlaveTransferEDMACallback, handle);
/* Clear internal IRQ enables and enable NVIC IRQ. */
I3C_SlaveDisableInterrupts(base, (uint32_t)kSlaveDMAIrqFlags);
/* Enable NVIC IRQ, this only enables the IRQ directly connected to the NVIC.
In some cases the I3C IRQ is configured through INTMUX, user needs to enable
INTMUX IRQ in application code. */
(void)EnableIRQ(kI3cIrqs[instance]);
/* Enable IRQ. */
I3C_SlaveEnableInterrupts(base, (uint32_t)kSlaveDMAIrqFlags);
}
static void I3C_SlavePrepareTxEDMA(I3C_Type *base, i3c_slave_edma_handle_t *handle)
{
edma_transfer_config_t txConfig;
uint32_t *txFifoBase;
i3c_slave_edma_transfer_t *xfer = &handle->transfer;
if (xfer->txDataSize == 1U)
{
txFifoBase = (uint32_t *)(uintptr_t)&base->SWDATABE;
EDMA_PrepareTransfer(&txConfig, xfer->txData, 1, (void *)txFifoBase, 1, 1, xfer->txDataSize,
kEDMA_MemoryToPeripheral);
}
else
{
txFifoBase = (uint32_t *)(uintptr_t)&base->SWDATAB;
EDMA_PrepareTransfer(&txConfig, xfer->txData, 1, (void *)txFifoBase, 1, 1, xfer->txDataSize - 1U,
kEDMA_MemoryToPeripheral);
}
(void)EDMA_SubmitTransfer(handle->txDmaHandle, &txConfig);
EDMA_StartTransfer(handle->txDmaHandle);
}
static void I3C_SlavePrepareRxEDMA(I3C_Type *base, i3c_slave_edma_handle_t *handle)
{
edma_transfer_config_t rxConfig;
uint32_t *rxFifoBase = (uint32_t *)(uintptr_t)&base->SRDATAB;
i3c_slave_edma_transfer_t *xfer = &handle->transfer;
EDMA_PrepareTransfer(&rxConfig, (void *)rxFifoBase, 1, xfer->rxData, 1, 1, xfer->rxDataSize,
kEDMA_PeripheralToMemory);
(void)EDMA_SubmitTransfer(handle->rxDmaHandle, &rxConfig);
EDMA_StartTransfer(handle->rxDmaHandle);
}
/*!
* brief Prepares for a non-blocking DMA-based transaction on the I3C bus.
*
* The API will do DMA configuration according to the input transfer descriptor, and the data will be transferred when
* there's bus master requesting transfer from/to this slave. So the timing of call to this API need be aligned
* with master application to ensure the transfer is executed as expected.
* Callback specified when the @a handle was created is invoked when the transaction has completed.
*
* param base The I3C peripheral base address.
* param handle Pointer to the I3C slave driver handle.
* param transfer The pointer to the transfer descriptor.
* param eventMask Bit mask formed by OR'ing together #i3c_slave_transfer_event_t enumerators to specify
* which events to send to the callback. The transmit and receive events is not allowed to be enabled.
* retval kStatus_Success The transaction was started successfully.
* retval #kStatus_I3C_Busy Either another master is currently utilizing the bus, or another DMA
* transaction is already in progress.
* retval #kStatus_Fail The transaction can't be set.
*/
status_t I3C_SlaveTransferEDMA(I3C_Type *base,
i3c_slave_edma_handle_t *handle,
i3c_slave_edma_transfer_t *transfer,
uint32_t eventMask)
{
assert(NULL != handle);
assert(NULL != transfer);
bool txDmaEn = false, rxDmaEn = false;
uint32_t width;
if (handle->isBusy)
{
return kStatus_I3C_Busy;
}
/* Clear all flags. */
I3C_SlaveClearErrorStatusFlags(base, (uint32_t)kSlaveErrorFlags);
I3C_SlaveClearStatusFlags(base, (uint32_t)kSlaveClearFlags);
/* Reset fifos. These flags clear automatically. */
base->SDATACTRL |= I3C_SDATACTRL_FLUSHTB_MASK | I3C_SDATACTRL_FLUSHFB_MASK;
handle->transfer = *transfer;
/* Set up event mask. */
handle->eventMask = eventMask;
if ((transfer->txData != NULL) && (transfer->txDataSize != 0U))
{
I3C_SlavePrepareTxEDMA(base, handle);
txDmaEn = true;
width = 1U;
}
if ((transfer->rxData != NULL) && (transfer->rxDataSize != 0U))
{
I3C_SlavePrepareRxEDMA(base, handle);
rxDmaEn = true;
width = 1U;
}
if (txDmaEn || rxDmaEn)
{
I3C_SlaveEnableDMA(base, txDmaEn, rxDmaEn, width);
return kStatus_Success;
}
else
{
return kStatus_Fail;
}
}
void I3C_SlaveTransferEDMAHandleIRQ(I3C_Type *base, void *i3cHandle)
{
uint32_t flags;
uint32_t errFlags;
i3c_slave_edma_transfer_t *xfer;
i3c_slave_edma_handle_t *handle = (i3c_slave_edma_handle_t *)i3cHandle;
/* Check for a valid handle in case of a spurious interrupt. */
if (NULL == handle)
{
return;
}
xfer = &handle->transfer;
/* Get status flags. */
flags = I3C_SlaveGetStatusFlags(base);
errFlags = I3C_SlaveGetErrorStatusFlags(base);
/* Clear status flags. */
I3C_SlaveClearStatusFlags(base, flags);
if (0UL != (errFlags & (uint32_t)kSlaveErrorFlags))
{
xfer->event = (uint32_t)kI3C_SlaveCompletionEvent;
xfer->completionStatus = I3C_SlaveCheckAndClearError(base, errFlags);
if ((0UL != (handle->eventMask & (uint32_t)kI3C_SlaveCompletionEvent)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
return;
}
if (0UL != (flags & (uint32_t)kI3C_SlaveEventSentFlag))
{
xfer->event = (uint32_t)kI3C_SlaveRequestSentEvent;
if ((0UL != (handle->eventMask & xfer->event)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
if (0UL != (flags & (uint32_t)kI3C_SlaveReceivedCCCFlag))
{
handle->isBusy = true;
xfer->event = (uint32_t)kI3C_SlaveReceivedCCCEvent;
if ((0UL != (handle->eventMask & xfer->event)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
if (0UL != (flags & (uint32_t)kI3C_SlaveBusStopFlag))
{
if (handle->isBusy == true)
{
xfer->event = (uint32_t)kI3C_SlaveCompletionEvent;
xfer->completionStatus = kStatus_Success;
handle->isBusy = false;
if ((0UL != (handle->eventMask & xfer->event)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
I3C_SlaveTransferAbortEDMA(base, handle);
}
else
{
return;
}
}
if (0UL != (flags & (uint32_t)kI3C_SlaveMatchedFlag))
{
xfer->event = (uint32_t)kI3C_SlaveAddressMatchEvent;
handle->isBusy = true;
if ((0UL != (handle->eventMask & (uint32_t)kI3C_SlaveAddressMatchEvent)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
}
/*!
* brief Abort a slave dma non-blocking transfer in a early time
*
* param base I3C peripheral base address
* param handle pointer to i3c_slave_edma_handle_t structure
*/
void I3C_SlaveTransferAbortEDMA(I3C_Type *base, i3c_slave_edma_handle_t *handle)
{
if (handle->isBusy != false)
{
EDMA_AbortTransfer(handle->txDmaHandle);
EDMA_AbortTransfer(handle->rxDmaHandle);
I3C_SlaveEnableDMA(base, false, false, 0);
/* Reset fifos. These flags clear automatically. */
base->SDATACTRL |= I3C_SDATACTRL_FLUSHTB_MASK | I3C_SDATACTRL_FLUSHFB_MASK;
}
}

View File

@ -0,0 +1,279 @@
/*
* Copyright 2022-2023 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_I3C_EDMA_H_
#define _FSL_I3C_EDMA_H_
#include "fsl_i3c.h"
#include "fsl_edma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief I3C EDMA driver version. */
#define FSL_I3C_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
/*@}*/
/*!
* @addtogroup i3c_master_edma_driver
* @{
*/
/* Forward declaration of the transfer descriptor and handle typedefs. */
typedef struct _i3c_master_edma_handle i3c_master_edma_handle_t;
/*! @brief i3c master callback functions. */
typedef struct _i3c_master_edma_callback
{
void (*slave2Master)(I3C_Type *base, void *userData); /*!< Transfer complete callback */
void (*ibiCallback)(I3C_Type *base,
i3c_master_edma_handle_t *handle,
i3c_ibi_type_t ibiType,
i3c_ibi_state_t ibiState); /*!< IBI event callback */
void (*transferComplete)(I3C_Type *base,
i3c_master_edma_handle_t *handle,
status_t status,
void *userData); /*!< Transfer complete callback */
} i3c_master_edma_callback_t;
/*!
* @brief Driver handle for master EDMA APIs.
* @note The contents of this structure are private and subject to change.
*/
struct _i3c_master_edma_handle
{
I3C_Type *base; /*!< I3C base pointer. */
uint8_t state; /*!< Transfer state machine current state. */
uint32_t transferCount; /*!< Indicates progress of the transfer */
uint8_t subaddressBuffer[4]; /*!< Saving subaddress command. */
uint8_t subaddressCount; /*!< Saving command count. */
i3c_master_transfer_t transfer; /*!< Copy of the current transfer info. */
i3c_master_edma_callback_t callback; /*!< Callback function pointer. */
void *userData; /*!< Application data passed to callback. */
edma_handle_t *rxDmaHandle; /*!< Handle for receive DMA channel. */
edma_handle_t *txDmaHandle; /*!< Handle for transmit DMA channel. */
uint8_t ibiAddress; /*!< Slave address which request IBI. */
uint8_t *ibiBuff; /*!< Pointer to IBI buffer to keep ibi bytes. */
size_t ibiPayloadSize; /*!< IBI payload size. */
i3c_ibi_type_t ibiType; /*!< IBI type. */
};
/*! @} */
/*!
* @addtogroup i3c_slave_edma_driver
* @{
*/
/* Forward declaration of the transfer descriptor and handle typedefs. */
typedef struct _i3c_slave_edma_handle i3c_slave_edma_handle_t;
/*! @brief I3C slave transfer structure */
typedef struct _i3c_slave_edma_transfer
{
uint32_t event; /*!< Reason the callback is being invoked. */
uint8_t *txData; /*!< Transfer buffer */
size_t txDataSize; /*!< Transfer size */
uint8_t *rxData; /*!< Transfer buffer */
size_t rxDataSize; /*!< Transfer size */
status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for
#kI3C_SlaveCompletionEvent. */
} i3c_slave_edma_transfer_t;
/*!
* @brief Slave event callback function pointer type.
*
* This callback is used only for the slave DMA transfer API.
*
* @param base Base address for the I3C instance on which the event occurred.
* @param handle Pointer to slave DMA transfer handle.
* @param transfer Pointer to transfer descriptor containing values passed to and/or from the callback.
* @param userData Arbitrary pointer-sized value passed from the application.
*/
typedef void (*i3c_slave_edma_callback_t)(I3C_Type *base, i3c_slave_edma_transfer_t *transfer, void *userData);
/*!
* @brief I3C slave edma handle structure.
* @note The contents of this structure are private and subject to change.
*/
struct _i3c_slave_edma_handle
{
I3C_Type *base; /*!< I3C base pointer. */
i3c_slave_edma_transfer_t transfer; /*!< I3C slave transfer copy. */
bool isBusy; /*!< Whether transfer is busy. */
bool wasTransmit; /*!< Whether the last transfer was a transmit. */
uint32_t eventMask; /*!< Mask of enabled events. */
i3c_slave_edma_callback_t callback; /*!< Callback function called at transfer event. */
edma_handle_t *rxDmaHandle; /*!< Handle for receive DMA channel. */
edma_handle_t *txDmaHandle; /*!< Handle for transmit DMA channel. */
void *userData; /*!< Callback parameter passed to callback. */
};
/*! @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @addtogroup i3c_master_edma_driver
* @{
*/
/*! @name Master DMA */
/*@{*/
/*!
* @brief Create a new handle for the I3C master DMA APIs.
*
* The creation of a handle is for use with the DMA APIs. Once a handle
* is created, there is not a corresponding destroy handle. If the user wants to
* terminate a transfer, the I3C_MasterTransferAbortDMA() API shall be called.
*
* For devices where the I3C send and receive DMA requests are OR'd together, the @a txDmaHandle
* parameter is ignored and may be set to NULL.
*
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C master driver handle.
* @param callback User provided pointer to the asynchronous callback function.
* @param userData User provided pointer to the application callback data.
* @param rxDmaHandle Handle for the DMA receive channel. Created by the user prior to calling this function.
* @param txDmaHandle Handle for the DMA transmit channel. Created by the user prior to calling this function.
*/
void I3C_MasterTransferCreateHandleEDMA(I3C_Type *base,
i3c_master_edma_handle_t *handle,
const i3c_master_edma_callback_t *callback,
void *userData,
edma_handle_t *rxDmaHandle,
edma_handle_t *txDmaHandle);
/*!
* @brief Performs a non-blocking DMA-based transaction on the I3C bus.
*
* The callback specified when the @a handle was created is invoked when the transaction has
* completed.
*
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C master driver handle.
* @param transfer The pointer to the transfer descriptor.
* @retval kStatus_Success The transaction was started successfully.
* @retval #kStatus_I3C_Busy Either another master is currently utilizing the bus, or another DMA
* transaction is already in progress.
*/
status_t I3C_MasterTransferEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, i3c_master_transfer_t *transfer);
/*!
* @brief Returns number of bytes transferred so far.
*
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C master driver handle.
* @param[out] count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_Success
* @retval kStatus_NoTransferInProgress There is not a DMA transaction currently in progress.
*/
status_t I3C_MasterTransferGetCountEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, size_t *count);
/*!
* @brief Terminates a non-blocking I3C master transmission early.
*
* @note It is not safe to call this function from an IRQ handler that has a higher priority than the
* DMA peripheral's IRQ priority.
*
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C master driver handle.
*/
void I3C_MasterTransferAbortEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle);
/*!
* @brief Reusable routine to handle master interrupts.
* @note This function does not need to be called unless you are reimplementing the
* nonblocking API's interrupt handler routines to add special functionality.
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C master DMA driver handle.
*/
void I3C_MasterTransferEDMAHandleIRQ(I3C_Type *base, void *i3cHandle);
/*@}*/
/*! @} */
/*!
* @addtogroup i3c_slave_edma_driver
* @{
*/
/*! @name Slave DMA */
/*@{*/
/*!
* @brief Create a new handle for the I3C slave DMA APIs.
*
* The creation of a handle is for use with the DMA APIs. Once a handle
* is created, there is not a corresponding destroy handle. If the user wants to
* terminate a transfer, the I3C_SlaveTransferAbortDMA() API shall be called.
*
* For devices where the I3C send and receive DMA requests are OR'd together, the @a txDmaHandle
* parameter is ignored and may be set to NULL.
*
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C slave driver handle.
* @param callback User provided pointer to the asynchronous callback function.
* @param userData User provided pointer to the application callback data.
* @param rxDmaHandle Handle for the DMA receive channel. Created by the user prior to calling this function.
* @param txDmaHandle Handle for the DMA transmit channel. Created by the user prior to calling this function.
*/
void I3C_SlaveTransferCreateHandleEDMA(I3C_Type *base,
i3c_slave_edma_handle_t *handle,
i3c_slave_edma_callback_t callback,
void *userData,
edma_handle_t *rxDmaHandle,
edma_handle_t *txDmaHandle);
/*!
* @brief Prepares for a non-blocking DMA-based transaction on the I3C bus.
*
* The API will do DMA configuration according to the input transfer descriptor, and the data will be transferred when
* there's bus master requesting transfer from/to this slave. So the timing of call to this API need be aligned
* with master application to ensure the transfer is executed as expected.
* Callback specified when the @a handle was created is invoked when the transaction has completed.
*
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C slave driver handle.
* @param transfer The pointer to the transfer descriptor.
* @param eventMask Bit mask formed by OR'ing together #i3c_slave_transfer_event_t enumerators to specify
* which events to send to the callback. The transmit and receive events is not allowed to be enabled.
* @retval kStatus_Success The transaction was started successfully.
* @retval #kStatus_I3C_Busy Either another master is currently utilizing the bus, or another DMA
* transaction is already in progress.
* @retval #kStatus_Fail The transaction can't be set.
*/
status_t I3C_SlaveTransferEDMA(I3C_Type *base,
i3c_slave_edma_handle_t *handle,
i3c_slave_edma_transfer_t *transfer,
uint32_t eventMask);
/*!
* @brief Abort a slave edma non-blocking transfer in a early time
*
* @param base I3C peripheral base address
* @param handle pointer to i3c_slave_edma_handle_t structure
*/
void I3C_SlaveTransferAbortEDMA(I3C_Type *base, i3c_slave_edma_handle_t *handle);
/*!
* @brief Reusable routine to handle slave interrupts.
* @note This function does not need to be called unless you are reimplementing the
* nonblocking API's interrupt handler routines to add special functionality.
* @param base The I3C peripheral base address.
* @param handle Pointer to the I3C slave DMA driver handle.
*/
void I3C_SlaveTransferEDMAHandleIRQ(I3C_Type *base, void *i3cHandle);
/*@}*/
/*! @} */
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_I3C_EDMA_H_ */

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_inputmux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.inputmux"
#endif
#if defined(INPUTMUX_RSTS)
#define INPUTMUX_RESETS_ARRAY INPUTMUX_RSTS
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
#if defined(INPUTMUX_RESETS_ARRAY)
/*!
* @brief Get instance number for INPUTMUX module.
*
* @param base INPUTMUX peripheral base address
*/
static uint32_t INPUTMUX_GetInstance(INPUTMUX_Type *base);
#endif
/*******************************************************************************
* Variables
******************************************************************************/
#if defined(INPUTMUX_RESETS_ARRAY)
/*! @brief Pointers to INPUTMUX bases for each instance. */
static INPUTMUX_Type *const s_inputmuxBases[] = INPUTMUX_BASE_PTRS;
/* Reset array */
static const reset_ip_name_t s_inputmuxResets[] = INPUTMUX_RESETS_ARRAY;
#endif
/*******************************************************************************
* Code
******************************************************************************/
#if defined(INPUTMUX_RESETS_ARRAY)
static uint32_t INPUTMUX_GetInstance(INPUTMUX_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_inputmuxBases); instance++)
{
if (s_inputmuxBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_inputmuxBases));
return instance;
}
#endif
/*!
* brief Initialize INPUTMUX peripheral.
* This function enables the INPUTMUX clock.
*
* param base Base address of the INPUTMUX peripheral.
*
* retval None.
*/
void INPUTMUX_Init(INPUTMUX_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE) && FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE
#if (defined(FSL_FEATURE_SOC_SCT_COUNT) && (FSL_FEATURE_SOC_SCT_COUNT > 0))
CLOCK_EnableClock(kCLOCK_Sct);
#endif /* FSL_FEATURE_SOC_SCT_COUNT */
CLOCK_EnableClock(kCLOCK_Dma);
#else
CLOCK_EnableClock(kCLOCK_InputMux);
#endif /* FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE */
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(INPUTMUX_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_inputmuxResets[INPUTMUX_GetInstance(base)]);
#endif
}
/*!
* brief Attaches a signal
*
* This function attaches multiplexed signals from INPUTMUX to target signals.
* For example, to attach GPIO PORT0 Pin 5 to PINT peripheral, do the following:
* code
* INPUTMUX_AttachSignal(INPUTMUX, 2, kINPUTMUX_GpioPort0Pin5ToPintsel);
* endcode
* In this example, INTMUX has 8 registers for PINT, PINT_SEL0~PINT_SEL7.
* With parameter p index specified as 2, this function configures register PINT_SEL2.
*
* param base Base address of the INPUTMUX peripheral.
* param index The serial number of destination register in the group of INPUTMUX registers with same name.
* param connection Applies signal from source signals collection to target signal.
*
* retval None.
*/
void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection)
{
uint32_t pmux_id;
uint32_t output_id;
/* extract pmux to be used */
pmux_id = ((uint32_t)(connection)) >> PMUX_SHIFT;
/* extract function number */
output_id = ((uint32_t)(connection)) & ((1UL << PMUX_SHIFT) - 1U);
/* programm signal */
*(volatile uint32_t *)(((uint32_t)base) + pmux_id + (index * 4U)) = output_id;
}
#if defined(FSL_FEATURE_INPUTMUX_HAS_SIGNAL_ENA)
/*!
* brief Enable/disable a signal
*
* This function gates the INPUTPMUX clock.
*
* param base Base address of the INPUTMUX peripheral.
* param signal Enable signal register id and bit offset.
* param enable Selects enable or disable.
*
* retval None.
*/
void INPUTMUX_EnableSignal(INPUTMUX_Type *base, inputmux_signal_t signal, bool enable)
{
uint32_t ena_id;
uint32_t ena_id_mask = (1UL << (32U - ENA_SHIFT)) - 1U;
uint32_t bit_offset;
#if defined(FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX) && FSL_FEATURE_INPUTMUX_HAS_CHANNEL_MUX
uint32_t chmux_offset;
uint32_t chmux_value;
/* Only enable need to update channel mux */
if (enable && ((((uint32_t)signal) & (1UL << CHMUX_AVL_SHIFT)) != 0U))
{
chmux_offset = (((uint32_t)signal) >> CHMUX_OFF_SHIFT) & ((1UL << (CHMUX_AVL_SHIFT - CHMUX_OFF_SHIFT)) - 1UL);
chmux_value = (((uint32_t)signal) >> CHMUX_VAL_SHIFT) & ((1UL << (CHMUX_OFF_SHIFT - CHMUX_VAL_SHIFT)) - 1UL);
*(volatile uint32_t *)(((uint32_t)base) + chmux_offset) = chmux_value;
}
ena_id_mask = (1UL << (CHMUX_VAL_SHIFT - ENA_SHIFT)) - 1U;
#endif
/* extract enable register to be used */
ena_id = (((uint32_t)signal) >> ENA_SHIFT) & ena_id_mask;
/* extract enable bit offset */
bit_offset = ((uint32_t)signal) & ((1UL << ENA_SHIFT) - 1U);
/* set signal */
if (enable)
{
*(volatile uint32_t *)(((uint32_t)base) + ena_id) |= (1UL << bit_offset);
}
else
{
*(volatile uint32_t *)(((uint32_t)base) + ena_id) &= ~(1UL << bit_offset);
}
}
#endif
/*!
* brief Deinitialize INPUTMUX peripheral.
* This function disables the INPUTMUX clock.
*
* param base Base address of the INPUTMUX peripheral.
*
* retval None.
*/
void INPUTMUX_Deinit(INPUTMUX_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE) && FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE
#if (defined(FSL_FEATURE_SOC_SCT_COUNT) && (FSL_FEATURE_SOC_SCT_COUNT > 0))
CLOCK_DisableClock(kCLOCK_Sct);
#endif /* FSL_FEATURE_SOC_SCT_COUNT */
CLOCK_DisableClock(kCLOCK_Dma);
#else
CLOCK_DisableClock(kCLOCK_InputMux);
#endif /* FSL_FEATURE_INPUTMUX_HAS_NO_INPUTMUX_CLOCK_SOURCE */
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021, 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_INPUTMUX_H_
#define _FSL_INPUTMUX_H_
#include "fsl_inputmux_connections.h"
#include "fsl_common.h"
/*!
* @addtogroup inputmux_driver
* @{
*/
/*! @file */
/*! @file fsl_inputmux_connections.h */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Group interrupt driver version for SDK */
#define FSL_INPUTMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 7))
/*@}*/
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Initialize INPUTMUX peripheral.
* This function enables the INPUTMUX clock.
*
* @param base Base address of the INPUTMUX peripheral.
*
* @retval None.
*/
void INPUTMUX_Init(INPUTMUX_Type *base);
/*!
* @brief Attaches a signal
*
* This function attaches multiplexed signals from INPUTMUX to target signals.
* For example, to attach GPIO PORT0 Pin 5 to PINT peripheral, do the following:
* @code
* INPUTMUX_AttachSignal(INPUTMUX, 2, kINPUTMUX_GpioPort0Pin5ToPintsel);
* @endcode
* In this example, INTMUX has 8 registers for PINT, PINT_SEL0~PINT_SEL7.
* With parameter @p index specified as 2, this function configures register PINT_SEL2.
*
* @param base Base address of the INPUTMUX peripheral.
* @param index The serial number of destination register in the group of INPUTMUX registers with same name.
* @param connection Applies signal from source signals collection to target signal.
*
* @retval None.
*/
void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection);
#if defined(FSL_FEATURE_INPUTMUX_HAS_SIGNAL_ENA)
/*!
* @brief Enable/disable a signal
*
* This function gates the INPUTPMUX clock.
*
* @param base Base address of the INPUTMUX peripheral.
* @param signal Enable signal register id and bit offset.
* @param enable Selects enable or disable.
*
* @retval None.
*/
void INPUTMUX_EnableSignal(INPUTMUX_Type *base, inputmux_signal_t signal, bool enable);
#endif
/*!
* @brief Deinitialize INPUTMUX peripheral.
* This function disables the INPUTMUX clock.
*
* @param base Base address of the INPUTMUX peripheral.
*
* @retval None.
*/
void INPUTMUX_Deinit(INPUTMUX_Type *base);
#ifdef __cplusplus
}
#endif
/*@}*/
#endif /* _FSL_INPUTMUX_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,924 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_lpadc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpadc"
#endif
#ifndef ADC_VERID_DIFFEN_MASK
#define ADC_VERID_DIFFEN_MASK (0x2U)
#endif /* ADC_VERID_DIFFEN_MASK */
#ifndef ADC_VERID_NUM_SEC_MASK
#define ADC_VERID_NUM_SEC_MASK (0x800U)
#endif /* ADC_VERID_NUM_SEC_MASK */
#define ADC_CMDL_CHANNEL_MODE_MASK (0x60U)
#define ADC_CMDL_CHANNEL_MODE_SHIFT (5U)
#define ADC_CMDL_CHANNEL_MODE(x) \
(((uint32_t)(((uint32_t)(x)) << ADC_CMDL_CHANNEL_MODE_SHIFT)) & ADC_CMDL_CHANNEL_MODE_MASK)
#define GET_ADC_CFG_TPRICTRL_VALUE(val) (val & 0x3U)
#if defined(FSL_FEATURE_LPADC_HAS_CFG_TRES) && FSL_FEATURE_LPADC_HAS_CFG_TRES
#define GET_ADC_CFG_TRES_VALUE(val) ((val & 0x4U) >> 2U)
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_TRES) && FSL_FEATURE_LPADC_HAS_CFG_TRES */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_TCMDRES) && FSL_FEATURE_LPADC_HAS_CFG_TCMDRES
#define GET_ADC_CFG_TCMDRES_VALUE(val) ((val & 0x8U) >> 3U)
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_TCMDRES) && FSL_FEATURE_LPADC_HAS_CFG_TCMDRES */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI) && FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI
#define GET_ADC_CFG_HPT_EXDI_VALUE(val) ((val & 0x10U) >> 4U)
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI) && FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI */
#if defined(LPADC_RSTS)
#define LPADC_RESETS_ARRAY LPADC_RSTS
#elif defined(ADC_RSTS)
#define LPADC_RESETS_ARRAY ADC_RSTS
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for LPADC module.
*
* @param base LPADC peripheral base address
*/
static uint32_t LPADC_GetInstance(ADC_Type *base);
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
/*!
* @brief Get gain conversion result .
*
* @param gainAdjustment gain adjustment value.
*/
static uint32_t LPADC_GetGainConvResult(float gainAdjustment);
#endif /* defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to LPADC bases for each instance. */
static ADC_Type *const s_lpadcBases[] = ADC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to LPADC clocks for each instance. */
static const clock_ip_name_t s_lpadcClocks[] = LPADC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(LPADC_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_lpadcResets[] = LPADC_RESETS_ARRAY;
#endif
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t LPADC_GetInstance(ADC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
/*
* $Branch Coverage Justification$
* (instance >= ARRAY_SIZE(s_lpadcBases)) not covered. The peripheral base
* address is always valid and checked by assert.
*/
for (instance = 0; instance < ARRAY_SIZE(s_lpadcBases); instance++)
{
/*
* $Branch Coverage Justification$
* (s_lpadcBases[instance] != base) not covered. The peripheral base
* address is always valid and checked by assert.
*/
if (s_lpadcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_lpadcBases));
return instance;
}
#if (defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ)
/*!
* brief Get gain conversion Result .
*
* param gainAdjustment gain adjustment value.
*/
static uint32_t LPADC_GetGainConvResult(float gainAdjustment)
{
uint16_t i = 0U;
uint32_t tmp32 = 0U;
uint32_t GCRa[17] = {0};
uint32_t GCALR = 0U;
for (i = 0x11U; i > 0U; i--)
{
tmp32 = (uint32_t)((gainAdjustment) / ((float)(1.0 / (double)(1U << (0x10U - (i - 1U))))));
GCRa[i - 1U] = tmp32;
gainAdjustment = gainAdjustment - ((float)tmp32) * ((float)(1.0 / (double)(1U << (0x10U - (i - 1U)))));
}
/* Get GCALR value calculated */
for (i = 0x11U; i > 0U; i--)
{
GCALR += GCRa[i - 1U] * ((uint32_t)(1UL << (uint32_t)(i - 1UL)));
}
/* to return GCALR value calculated */
return GCALR;
}
#endif /* defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
/*!
* brief Initializes the LPADC module.
*
* param base LPADC peripheral base address.
* param config Pointer to configuration structure. See "lpadc_config_t".
*/
void LPADC_Init(ADC_Type *base, const lpadc_config_t *config)
{
/* Check if the pointer is available. */
assert(config != NULL);
uint32_t tmp32 = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock for LPADC instance. */
(void)CLOCK_EnableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(LPADC_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_lpadcResets[LPADC_GetInstance(base)]);
#endif
/* Reset the module. */
LPADC_DoResetConfig(base);
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
LPADC_DoResetFIFO0(base);
LPADC_DoResetFIFO1(base);
#else
LPADC_DoResetFIFO(base);
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
/* Disable the module before setting configuration. */
LPADC_Enable(base, false);
/* Configure the module generally. */
if (config->enableInDozeMode)
{
base->CTRL &= ~ADC_CTRL_DOZEN_MASK;
}
else
{
base->CTRL |= ADC_CTRL_DOZEN_MASK;
}
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
/* Set calibration average mode. */
base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode);
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
/* ADCx_CFG. */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
if (config->enableInternalClock)
{
tmp32 |= ADC_CFG_ADCKEN_MASK;
}
#endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
if (config->enableVref1LowVoltage)
{
tmp32 |= ADC_CFG_VREF1RNG_MASK;
}
#endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
if (config->enableAnalogPreliminary)
{
tmp32 |= ADC_CFG_PWREN_MASK;
}
tmp32 |= (ADC_CFG_PUDLY(config->powerUpDelay) /* Power up delay. */
| ADC_CFG_REFSEL(config->referenceVoltageSource) /* Reference voltage. */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 1U)
| ADC_CFG_PWRSEL(config->powerLevelMode) /* Power configuration. */
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 1U) */
);
tmp32 |= ADC_CFG_TPRICTRL(GET_ADC_CFG_TPRICTRL_VALUE(config->triggerPriorityPolicy));
#if (defined(FSL_FEATURE_LPADC_HAS_CFG_TRES) && FSL_FEATURE_LPADC_HAS_CFG_TRES)
tmp32 |= ADC_CFG_TRES(GET_ADC_CFG_TRES_VALUE((uint8_t)(config->triggerPriorityPolicy)));
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_TRES) && FSL_FEATURE_LPADC_HAS_CFG_TRES */
#if (defined(FSL_FEATURE_LPADC_HAS_CFG_TCMDRES) && FSL_FEATURE_LPADC_HAS_CFG_TCMDRES)
tmp32 |= ADC_CFG_TCMDRES(GET_ADC_CFG_TCMDRES_VALUE((uint8_t)(config->triggerPriorityPolicy)));
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_TCMDRES) && FSL_FEATURE_LPADC_HAS_CFG_TCMDRES */
#if (defined(FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI) && FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI)
tmp32 |= ADC_CFG_HPT_EXDI(GET_ADC_CFG_HPT_EXDI_VALUE((uint8_t)(config->triggerPriorityPolicy)));
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI) && FSL_FEATURE_LPADC_HAS_CFG_HPT_EXDI */
base->CFG = tmp32;
/* ADCx_PAUSE. */
if (config->enableConvPause)
{
base->PAUSE = ADC_PAUSE_PAUSEEN_MASK | ADC_PAUSE_PAUSEDLY(config->convPauseDelay);
}
else
{
base->PAUSE = 0U;
}
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
/* ADCx_FCTRL0. */
base->FCTRL[0] = ADC_FCTRL_FWMARK(config->FIFO0Watermark);
/* ADCx_FCTRL1. */
base->FCTRL[1] = ADC_FCTRL_FWMARK(config->FIFO1Watermark);
#else
/* ADCx_FCTRL. */
base->FCTRL = ADC_FCTRL_FWMARK(config->FIFOWatermark);
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
/* Enable the module after setting configuration. */
LPADC_Enable(base, true);
}
/*!
* brief Gets an available pre-defined settings for initial configuration.
*
* This function initializes the converter configuration structure with an available settings. The default values are:
* code
* config->enableInDozeMode = true;
* config->conversionAverageMode = kLPADC_ConversionAverage1;
* config->enableAnalogPreliminary = false;
* config->powerUpDelay = 0x80;
* config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
* config->powerLevelMode = kLPADC_PowerLevelAlt1;
* config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
* config->enableConvPause = false;
* config->convPauseDelay = 0U;
* config->FIFO0Watermark = 0U;
* config->FIFO1Watermark = 0U;
* config->FIFOWatermark = 0U;
* endcode
* param config Pointer to configuration structure.
*/
void LPADC_GetDefaultConfig(lpadc_config_t *config)
{
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
#if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
config->enableInternalClock = false;
#endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
config->enableVref1LowVoltage = false;
#endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
config->enableInDozeMode = true;
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
/* Set calibration average mode. */
config->conversionAverageMode = kLPADC_ConversionAverage1;
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
config->enableAnalogPreliminary = false;
config->powerUpDelay = 0x80;
config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
#if defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 1U)
config->powerLevelMode = kLPADC_PowerLevelAlt1;
#endif /* defined(FSL_FEATURE_LPADC_HAS_CFG_PWRSEL) && (FSL_FEATURE_LPADC_HAS_CFG_PWRSEL == 1U) */
config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
config->enableConvPause = false;
config->convPauseDelay = 0U;
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
config->FIFO0Watermark = 0U;
config->FIFO1Watermark = 0U;
#else
config->FIFOWatermark = 0U;
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
}
/*!
* brief De-initializes the LPADC module.
*
* param base LPADC peripheral base address.
*/
void LPADC_Deinit(ADC_Type *base)
{
/* Disable the module. */
LPADC_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the clock. */
(void)CLOCK_DisableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
/*!
* brief Get the result in conversion FIFOn.
*
* param base LPADC peripheral base address.
* param result Pointer to structure variable that keeps the conversion result in conversion FIFOn.
* param index Result FIFO index.
*
* return Status whether FIFOn entry is valid.
*/
bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result, uint8_t index)
{
assert(result != NULL); /* Check if the input pointer is available. */
uint32_t tmp32 = 0U;
while (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
{
/* while loop until FIFO is not empty */
tmp32 = base->RESFIFO[index];
}
result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
return true;
}
#else
/*!
* brief Get the result in conversion FIFO.
*
* param base LPADC peripheral base address.
* param result Pointer to structure variable that keeps the conversion result in conversion FIFO.
*
* return Status whether FIFO entry is valid.
*/
bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result)
{
assert(result != NULL); /* Check if the input pointer is available. */
uint32_t tmp32 = 0U;
while (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
{
/* while loop until FIFO is not empty */
tmp32 = base->RESFIFO;
}
result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
return true;
}
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
/*!
* brief Configure the conversion trigger source.
*
* Each programmable trigger can launch the conversion command in command buffer.
*
* param base LPADC peripheral base address.
* param triggerId ID for each trigger. Typically, the available value range is from 0 to 3.
* param config Pointer to configuration structure. See to #lpadc_conv_trigger_config_t.
*/
void LPADC_SetConvTriggerConfig(ADC_Type *base, uint32_t triggerId, const lpadc_conv_trigger_config_t *config)
{
assert(triggerId < ADC_TCTRL_COUNT); /* Check if the triggerId is available in this device. */
assert(config != NULL); /* Check if the input pointer is available. */
uint32_t tmp32;
tmp32 = ADC_TCTRL_TCMD(config->targetCommandId) /* Trigger command select. */
| ADC_TCTRL_TDLY(config->delayPower) /* Trigger delay select. */
| ADC_TCTRL_TPRI(config->priority) /* Trigger priority setting. */
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
| ADC_TCTRL_FIFO_SEL_A(config->channelAFIFOSelect)
#if !(defined(FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B) && FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B)
| ADC_TCTRL_FIFO_SEL_B(config->channelBFIFOSelect)
#endif /* FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B */
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
;
if (config->enableHardwareTrigger)
{
tmp32 |= ADC_TCTRL_HTEN_MASK;
}
base->TCTRL[triggerId] = tmp32;
}
/*!
* brief Gets an available pre-defined settings for trigger's configuration.
*
* This function initializes the trigger's configuration structure with an available settings. The default values are:
* code
* config->targetCommandId = 0U;
* config->delayPower = 0U;
* config->priority = 0U;
* config->channelAFIFOSelect = 0U;
* config->channelBFIFOSelect = 0U;
* config->enableHardwareTrigger = false;
* endcode
* param config Pointer to configuration structure.
*/
void LPADC_GetDefaultConvTriggerConfig(lpadc_conv_trigger_config_t *config)
{
assert(config != NULL); /* Check if the input pointer is available. */
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->targetCommandId = 0U;
config->delayPower = 0U;
config->priority = 0U;
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
config->channelAFIFOSelect = 0U;
config->channelBFIFOSelect = 0U;
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
config->enableHardwareTrigger = false;
}
/*!
* brief Configure conversion command.
*
* param base LPADC peripheral base address.
* param commandId ID for command in command buffer. Typically, the available value range is 1 - 15.
* param config Pointer to configuration structure. See to #lpadc_conv_command_config_t.
*/
void LPADC_SetConvCommandConfig(ADC_Type *base, uint32_t commandId, const lpadc_conv_command_config_t *config)
{
assert(commandId < (ADC_CMDL_COUNT + 1U)); /* Check if the commandId is available on this device. */
assert(config != NULL); /* Check if the input pointer is available. */
uint32_t tmp32 = 0;
commandId--; /* The available command number are 1-15, while the index of register group are 0-14. */
/* ADCx_CMDL. */
tmp32 = ADC_CMDL_ADCH(config->channelNumber); /* Channel number. */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH
tmp32 |= ADC_CMDL_ALTB_ADCH(config->channelBNumber); /* Alternate channel B number. */
#endif
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
tmp32 |= ADC_CMDL_CSCALE(config->sampleScaleMode); /* Full/Part scale input voltage. */
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE
tmp32 |= ADC_CMDL_ALTB_CSCALE(config->channelBScaleMode); /* Alternate channel B full/Part scale input voltage. */
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
#if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U))
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
assert(((config->sampleChannelMode >= kLPADC_SampleChannelDiffBothSideAB) &&
(((base->VERID) & ADC_VERID_DIFFEN_MASK) != 0U)) ||
(config->sampleChannelMode < kLPADC_SampleChannelDiffBothSideAB));
tmp32 |= ADC_CMDL_CHANNEL_MODE(config->sampleChannelMode);
#endif /* defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_CTYPE) && FSL_FEATURE_LPADC_HAS_CMDL_CTYPE
assert(((config->sampleChannelMode == kLPADC_SampleChannelDiffBothSide) &&
(((base->VERID) & ADC_VERID_DIFFEN_MASK) != 0U)) ||
((config->sampleChannelMode == kLPADC_SampleChannelDualSingleEndBothSide) &&
(((base->VERID) & ADC_VERID_NUM_SEC_MASK) != 0U)) ||
(config->sampleChannelMode < kLPADC_SampleChannelDiffBothSide));
tmp32 |= ADC_CMDL_CTYPE(config->sampleChannelMode);
#endif /* defined(FSL_FEATURE_LPADC_HAS_CMDL_CTYPE) && FSL_FEATURE_LPADC_HAS_CMDL_CTYPE */
#endif /* !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U)) */
tmp32 |= ADC_CMDL_CHANNEL_MODE(config->sampleChannelMode);
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
tmp32 |= ADC_CMDL_MODE(config->conversionResolutionMode);
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN) && FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN
/* Enable alternate channel B.*/
if (config->enableChannelB)
{
tmp32 |= ADC_CMDL_ALTBEN_MASK;
}
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN */
base->CMD[commandId].CMDL = tmp32;
/* ADCx_CMDH. */
tmp32 = ADC_CMDH_NEXT(config->chainedNextCommandNumber) /* Next Command Select. */
| ADC_CMDH_LOOP(config->loopCount) /* Loop Count Select. */
| ADC_CMDH_AVGS(config->hardwareAverageMode) /* Hardware Average Select. */
| ADC_CMDH_STS(config->sampleTimeMode) /* Sample Time Select. */
| ADC_CMDH_CMPEN(config->hardwareCompareMode); /* Hardware compare enable. */
#if (defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG)
if (config->enableWaitTrigger)
{
tmp32 |= ADC_CMDH_WAIT_TRIG_MASK; /* Wait trigger enable. */
}
#endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
if (config->enableAutoChannelIncrement)
{
tmp32 |= ADC_CMDH_LWI_MASK;
}
base->CMD[commandId].CMDH = tmp32;
/* Hardware compare settings.
* Not all Command Buffers have an associated Compare Value register. The compare function is only available on
* Command Buffers that have a corresponding Compare Value register.
*/
if (kLPADC_HardwareCompareDisabled != config->hardwareCompareMode)
{
/* Set CV register. */
base->CV[commandId] = ADC_CV_CVH(config->hardwareCompareValueHigh) /* Compare value high. */
| ADC_CV_CVL(config->hardwareCompareValueLow); /* Compare value low. */
}
}
/*!
* brief Gets an available pre-defined settings for conversion command's configuration.
*
* This function initializes the conversion command's configuration structure with an available settings. The default
* values are:
* code
* config->sampleScaleMode = kLPADC_SampleFullScale;
* config->channelBScaleMode = kLPADC_SampleFullScale;
* config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
* config->channelNumber = 0U;
* config->channelBNumber = 0U;
* config->chainedNextCommandNumber = 0U;
* config->enableAutoChannelIncrement = false;
* config->loopCount = 0U;
* config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
* config->sampleTimeMode = kLPADC_SampleTimeADCK3;
* config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
* config->hardwareCompareValueHigh = 0U;
* config->hardwareCompareValueLow = 0U;
* config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
* config->enableWaitTrigger = false;
* config->enableChannelB = false;
* endcode
* param config Pointer to configuration structure.
*/
void LPADC_GetDefaultConvCommandConfig(lpadc_conv_command_config_t *config)
{
assert(config != NULL); /* Check if the input pointer is available. */
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
config->sampleScaleMode = kLPADC_SampleFullScale;
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE
config->channelBScaleMode = kLPADC_SampleFullScale;
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
config->channelNumber = 0U;
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH) && FSL_FEATURE_LPADC_HAS_CMDL_ALTB_ADCH
config->channelBNumber = 0U;
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTB_CSCALE */
config->chainedNextCommandNumber = 0U; /* No next command defined. */
config->enableAutoChannelIncrement = false;
config->loopCount = 0U;
config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
config->sampleTimeMode = kLPADC_SampleTimeADCK3;
config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
config->hardwareCompareValueHigh = 0U; /* No used. */
config->hardwareCompareValueLow = 0U; /* No used. */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
#if defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG
config->enableWaitTrigger = false;
#endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN) && FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN
config->enableChannelB = false; /* Enable alternate channel B.*/
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_ALTBEN */
}
#if defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS
/*!
* brief Enable the calibration function.
*
* When CALOFS is set, the ADC is configured to perform a calibration function anytime the ADC executes
* a conversion. Any channel selected is ignored and the value returned in the RESFIFO is a signed value
* between -31 and 31. -32 is not a valid and is never a returned value. Software should copy the lower 6-
* bits of the conversion result stored in the RESFIFO after a completed calibration conversion to the
* OFSTRIM field. The OFSTRIM field is used in normal operation for offset correction.
*
* param base LPADC peripheral base address.
* param enable switcher to the calibration function.
*/
void LPADC_EnableCalibration(ADC_Type *base, bool enable)
{
LPADC_Enable(base, false);
if (enable)
{
base->CFG |= ADC_CFG_CALOFS_MASK;
}
else
{
base->CFG &= ~ADC_CFG_CALOFS_MASK;
}
LPADC_Enable(base, true);
}
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
/*!
* brief Do auto calibration.
*
* Calibration function should be executed before using converter in application. It used the software trigger and a
* dummy conversion, get the offset and write them into the OFSTRIM register. It called some of functional API
* including: -LPADC_EnableCalibration(...) -LPADC_LPADC_SetOffsetValue(...) -LPADC_SetConvCommandConfig(...)
* -LPADC_SetConvTriggerConfig(...)
*
* param base LPADC peripheral base address.
*/
void LPADC_DoAutoCalibration(ADC_Type *base)
{
assert(0u == LPADC_GetConvResultCount(base));
uint32_t mLpadcCMDL;
uint32_t mLpadcCMDH;
uint32_t mLpadcTrigger;
lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
lpadc_conv_command_config_t mLpadcCommandConfigStruct;
lpadc_conv_result_t mLpadcResultConfigStruct;
/* Enable the calibration function. */
LPADC_EnableCalibration(base, true);
/* Keep the CMD and TRG state here and restore it later if the calibration completes.*/
mLpadcCMDL = base->CMD[0].CMDL; /* CMD1L. */
mLpadcCMDH = base->CMD[0].CMDH; /* CMD1H. */
mLpadcTrigger = base->TCTRL[0]; /* Trigger0. */
/* Set trigger0 configuration - for software trigger. */
LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
mLpadcTriggerConfigStruct.targetCommandId = 1U; /* CMD1 is executed. */
LPADC_SetConvTriggerConfig(base, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
/* Set conversion CMD configuration. */
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.hardwareAverageMode = kLPADC_HardwareAverageCount128;
LPADC_SetConvCommandConfig(base, 1U, &mLpadcCommandConfigStruct); /* Set CMD1 configuration. */
/* Do calibration. */
LPADC_DoSoftwareTrigger(base, 1U); /* 1U is trigger0 mask. */
while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
{
}
/* The valid bits of data are bits 14:3 in the RESFIFO register. */
LPADC_SetOffsetValue(base, (uint32_t)(mLpadcResultConfigStruct.convValue) >> 3UL);
/* Disable the calibration function. */
LPADC_EnableCalibration(base, false);
/* restore CMD and TRG registers. */
base->CMD[0].CMDL = mLpadcCMDL; /* CMD1L. */
base->CMD[0].CMDH = mLpadcCMDH; /* CMD1H. */
base->TCTRL[0] = mLpadcTrigger; /* Trigger0. */
}
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
/*!
* brief Do offset calibration.
*
* param base LPADC peripheral base address.
*/
void LPADC_DoOffsetCalibration(ADC_Type *base)
{
LPADC_EnableOffsetCalibration(base, true);
while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
{
}
}
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
/*!
* brief Do auto calibration.
*
* param base LPADC peripheral base address.
*/
void LPADC_DoAutoCalibration(ADC_Type *base)
{
LPADC_PrepareAutoCalibration(base);
LPADC_FinishAutoCalibration(base);
}
/*!
* brief Prepare auto calibration, LPADC_FinishAutoCalibration has to be called before using the LPADC.
* LPADC_DoAutoCalibration has been split in two API to avoid to be stuck too long in the function.
*
* param base LPADC peripheral base address.
*/
void LPADC_PrepareAutoCalibration(ADC_Type *base)
{
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
assert((0U == LPADC_GetConvResultCount(base, 0)) && (0U == LPADC_GetConvResultCount(base, 1)));
#else /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 1)) */
assert(LPADC_GetConvResultCount(base) == 0U);
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2)) */
/* Request gain calibration. */
base->CTRL |= ADC_CTRL_CAL_REQ_MASK;
}
/*!
* brief Finish auto calibration start with LPADC_PrepareAutoCalibration.
*
* param base LPADC peripheral base address.
*/
void LPADC_FinishAutoCalibration(ADC_Type *base)
{
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
int32_t GCCa;
int32_t GCCb;
float GCRa;
float GCRb;
#else
uint32_t GCCa;
float GCRa;
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
uint32_t GCCb;
float GCRb;
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
while ((ADC_GCC_RDY_MASK != (base->GCC[0] & ADC_GCC_RDY_MASK))
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
|| (ADC_GCC_RDY_MASK != (base->GCC[1] & ADC_GCC_RDY_MASK))
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
)
{
}
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE
GCCa = (base->GCC[0] & ADC_GCC_GAIN_CAL_MASK);
GCCb = (base->GCC[1] & ADC_GCC_GAIN_CAL_MASK);
if (0U != ((base->GCC[0]) & 0x8000U))
{
GCCa = GCCa - 0x10000;
GCRa = (float)((131072.0) /
(131072.0 - (double)GCCa)); /* Gain_CalA = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[0]))*/
base->GCR[0] = LPADC_GetGainConvResult(GCRa); /* write A side GCALR. */
}
if (0U != ((base->GCC[1]) & 0x8000U))
{
GCCb = GCCb - 0x10000;
GCRb = (float)((131072.0) /
(131072.0 - (double)GCCb)); /* Gain_CalB = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[1]))*/
base->GCR[1] = LPADC_GetGainConvResult(GCRb); /* write B side GCALR. */
}
#else
/* Calculate gain offset. */
GCCa = (base->GCC[0] & ADC_GCC_GAIN_CAL_MASK);
GCRa = (float)((131072.0) /
(131072.0 - (double)GCCa)); /* Gain_CalA = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[0]))*/
base->GCR[0] = LPADC_GetGainConvResult(GCRa); /* write A side GCALR. */
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
GCCb = (base->GCC[1] & ADC_GCC_GAIN_CAL_MASK);
GCRb = (float)((131072.0) /
(131072.0 - (double)GCCb)); /* Gain_CalB = (131072.0 / (131072-(ADC_GCC_GAIN_CAL(ADC->GCC[1]))*/
base->GCR[1] = LPADC_GetGainConvResult(GCRb); /* write B side GCALR. */
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFSMODE */
/* Indicate the values are valid. */
base->GCR[0] |= ADC_GCR_RDY_MASK;
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
base->GCR[1] |= ADC_GCR_RDY_MASK;
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
{
}
}
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
/*!
* brief Get calibration value into the memory which is defined by invoker.
*
* note Please note the ADC will be disabled temporary.
* note This function should be used after finish calibration.
*
* param base LPADC peripheral base address.
* param ptrCalibrationValue Pointer to lpadc_calibration_value_t structure, this memory block should be always powered
* on even in low power modes.
*/
void LPADC_GetCalibrationValue(ADC_Type *base, lpadc_calibration_value_t *ptrCalibrationValue)
{
assert(ptrCalibrationValue != NULL);
bool adcEnabled = false;
/* Check if ADC is enabled. */
if ((base->CTRL & ADC_CTRL_ADCEN_MASK) != 0UL)
{
LPADC_Enable(base, false);
adcEnabled = true;
}
#if (defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ)
uint32_t i;
for (i = 0UL; i < 33UL; i++)
{
#if defined(ADC_CAL_GAR0_CAL_GAR_VAL_MASK)
ptrCalibrationValue->generalCalibrationValueA[i] =
(uint16_t)((*(((volatile uint32_t *)(&(base->CAL_GAR0))) + i)) & 0xFFFFU);
#if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U))
ptrCalibrationValue->generalCalibrationValueB[i] =
(uint16_t)((*(((volatile uint32_t *)(&(base->CAL_GBR0))) + i)) & 0xFFFFU);
#endif /* (defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U)) */
#else
ptrCalibrationValue->generalCalibrationValueA[i] =
(uint16_t)((*(((volatile uint32_t *)(&(base->CAL_GAR[0]))) + i)) & 0xFFFFU);
#if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U))
ptrCalibrationValue->generalCalibrationValueB[i] =
(uint16_t)((*(((volatile uint32_t *)(&(base->CAL_GBR[0]))) + i)) & 0xFFFFU);
#endif /* (defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U)) */
#endif /* defined(ADC_CAL_GAR0_CAL_GAR_VAL_MASK) */
}
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
ptrCalibrationValue->gainCalibrationResultA = (uint16_t)(base->GCR[0] & ADC_GCR_GCALR_MASK);
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
ptrCalibrationValue->gainCalibrationResultB = (uint16_t)(base->GCR[1] & ADC_GCR_GCALR_MASK);
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
if (adcEnabled)
{
LPADC_Enable(base, true);
}
}
/*!
* brief Set calibration value into ADC calibration registers.
*
* note Please note the ADC will be disabled temporary.
*
* param base LPADC peripheral base address.
* param ptrCalibrationValue Pointer to lpadc_calibration_value_t structure which contains ADC's calibration value.
*/
void LPADC_SetCalibrationValue(ADC_Type *base, const lpadc_calibration_value_t *ptrCalibrationValue)
{
assert(ptrCalibrationValue != NULL);
bool adcEnabled = false;
/* Check if ADC is enabled. */
if ((base->CTRL & ADC_CTRL_ADCEN_MASK) != 0UL)
{
LPADC_Enable(base, false);
adcEnabled = true;
}
#if (defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ)
for (uint32_t i = 0UL; i < 33UL; i++)
{
#if defined(ADC_CAL_GAR0_CAL_GAR_VAL_MASK)
*(((volatile uint32_t *)(&(base->CAL_GAR0))) + i) = ptrCalibrationValue->generalCalibrationValueA[i];
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
*(((volatile uint32_t *)(&(base->CAL_GBR0))) + i) = ptrCalibrationValue->generalCalibrationValueB[i];
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
#else
*(((volatile uint32_t *)(&(base->CAL_GAR[0]))) + i) = ptrCalibrationValue->generalCalibrationValueA[i];
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
*(((volatile uint32_t *)(&(base->CAL_GBR[0]))) + i) = ptrCalibrationValue->generalCalibrationValueB[i];
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
#endif /* defined(ADC_CAL_GAR0_CAL_GAR_VAL_MASK) */
}
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
base->GCR[0] = ADC_GCR_GCALR(ptrCalibrationValue->gainCalibrationResultA) | ADC_GCR_RDY_MASK;
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
base->GCR[1] = ADC_GCR_GCALR(ptrCalibrationValue->gainCalibrationResultB) | ADC_GCR_RDY_MASK;
#endif /* (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U)) */
/*
* $Branch Coverage Justification$
* while ((base->STAT & ADC_STAT_CAL_RDY_MASK) == ADC_STAT_CAL_RDY_MASK) not covered. Test unfeasible,
* the calibration ready state is too short not to catch.
*/
while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
{
}
if (adcEnabled)
{
LPADC_Enable(base, true);
}
}
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,363 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019, 2023 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_lpcmp.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpcmp"
#endif
#if defined(LPCMP_RSTS)
#define LPCMP_RESETS_ARRAY LPCMP_RSTS
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
#if defined(LPCMP_CLOCKS)
/*!
* @brief Get instance number for LPCMP module.
*
* @param base LPCMP peripheral base address
*/
static uint32_t LPCMP_GetInstance(LPCMP_Type *base);
#endif /* LPCMP_CLOCKS */
/*******************************************************************************
* Variables
******************************************************************************/
#if defined(LPCMP_CLOCKS)
/*! @brief Pointers to LPCMP bases for each instance. */
static LPCMP_Type *const s_lpcmpBases[] = LPCMP_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to LPCMP clocks for each instance. */
static const clock_ip_name_t s_lpcmpClocks[] = LPCMP_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPCMP_CLOCKS */
#if defined(LPCMP_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_lpcmpResets[] = LPCMP_RESETS_ARRAY;
#endif
/*******************************************************************************
* Codes
******************************************************************************/
#if defined(LPCMP_CLOCKS)
static uint32_t LPCMP_GetInstance(LPCMP_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
/*
* $Branch Coverage Justification$
* (instance >= ARRAY_SIZE(s_lpcmpBases)) not covered. The peripheral base
* address is always valid and checked by assert.
*/
for (instance = 0; instance < ARRAY_SIZE(s_lpcmpBases); instance++)
{
/*
* $Branch Coverage Justification$
* (s_lpcmpBases[instance] != base) not covered. The peripheral base
* address is always valid and checked by assert.
*/
if (s_lpcmpBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_lpcmpBases));
return instance;
}
#endif /* LPCMP_CLOCKS */
/*!
* brief Initialize the LPCMP
*
* This function initializes the LPCMP module. The operations included are:
* - Enabling the clock for LPCMP module.
* - Configuring the comparator.
* - Enabling the LPCMP module.
* Note: For some devices, multiple LPCMP instance share the same clock gate. In this case, to enable the clock for
* any instance enables all the LPCMPs. Check the chip reference manual for the clock assignment of the LPCMP.
*
* param base LPCMP peripheral base address.
* param config Pointer to "lpcmp_config_t" structure.
*/
void LPCMP_Init(LPCMP_Type *base, const lpcmp_config_t *config)
{
assert(config != NULL);
uint32_t tmp32;
#if defined(LPCMP_CLOCKS)
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_lpcmpClocks[LPCMP_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPCMP_CLOCKS */
#if defined(LPCMP_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_lpcmpResets[LPCMP_GetInstance(base)]);
#endif
/* Configure. */
LPCMP_Enable(base, false);
/* CCR0 register. */
if (config->enableStopMode)
{
base->CCR0 |= LPCMP_CCR0_CMP_STOP_EN_MASK;
}
else
{
base->CCR0 &= ~LPCMP_CCR0_CMP_STOP_EN_MASK;
}
/* CCR1 register. */
tmp32 = (base->CCR1 & (~(LPCMP_CCR1_COUT_PEN_MASK | LPCMP_CCR1_COUT_SEL_MASK | LPCMP_CCR1_COUT_INV_MASK
#if defined(FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL) && FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL
| LPCMP_CCR1_FUNC_CLK_SEL_MASK
#endif /* FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL */
)));
if (config->enableOutputPin)
{
tmp32 |= LPCMP_CCR1_COUT_PEN_MASK;
}
if (config->useUnfilteredOutput)
{
tmp32 |= LPCMP_CCR1_COUT_SEL_MASK;
}
if (config->enableInvertOutput)
{
tmp32 |= LPCMP_CCR1_COUT_INV_MASK;
}
#if defined(FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL) && FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL
tmp32 |= LPCMP_CCR1_FUNC_CLK_SEL(config->functionalSourceClock);
#endif /* FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL */
base->CCR1 = tmp32;
/* CCR2 register. */
tmp32 = base->CCR2 & ~(LPCMP_CCR2_HYSTCTR_MASK | LPCMP_CCR2_CMP_NPMD_MASK | LPCMP_CCR2_CMP_HPMD_MASK);
tmp32 |= LPCMP_CCR2_HYSTCTR(config->hysteresisMode);
tmp32 |= ((uint32_t)(config->powerMode) << LPCMP_CCR2_CMP_HPMD_SHIFT);
base->CCR2 = tmp32;
LPCMP_Enable(base, true); /* Enable the LPCMP module. */
}
/*!
* brief De-initializes the LPCMP module.
*
* This function de-initializes the LPCMP module. The operations included are:
* - Disabling the LPCMP module.
* - Disabling the clock for LPCMP module.
*
* This function disables the clock for the LPCMP.
* Note: For some devices, multiple LPCMP instance shares the same clock gate. In this case, before disabling the
* clock for the LPCMP, ensure that all the LPCMP instances are not used.
*
* param base LPCMP peripheral base address.
*/
void LPCMP_Deinit(LPCMP_Type *base)
{
/* Disable the LPCMP module. */
LPCMP_Enable(base, false);
#if defined(LPCMP_CLOCKS)
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_lpcmpClocks[LPCMP_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPCMP_CLOCKS */
}
/*!
* brief Gets an available pre-defined settings for the comparator's configuration.
*
* This function initializes the comparator configuration structure to these default values:
* code
* config->enableStopMode = false;
* config->enableOutputPin = false;
* config->useUnfilteredOutput = false;
* config->enableInvertOutput = false;
* config->hysteresisMode = kLPCMP_HysteresisLevel0;
* config->powerMode = kLPCMP_LowSpeedPowerMode;
* config->functionalSourceClock = kLPCMP_FunctionalClockSource0;
* endcode
* param config Pointer to "lpcmp_config_t" structure.
*/
void LPCMP_GetDefaultConfig(lpcmp_config_t *config)
{
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->enableStopMode = false;
config->enableOutputPin = false;
config->useUnfilteredOutput = false;
config->enableInvertOutput = false;
config->hysteresisMode = kLPCMP_HysteresisLevel0;
config->powerMode = kLPCMP_LowSpeedPowerMode;
#if defined(FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL) && FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL
config->functionalSourceClock = kLPCMP_FunctionalClockSource0;
#endif /* FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL */
}
/*!
* brief Select the input channels for LPCMP. This function determines which input
* is selected for the negative and positive mux.
*
* param base LPCMP peripheral base address.
* param positiveChannel Positive side input channel number.
* param negativeChannel Negative side input channel number.
*/
void LPCMP_SetInputChannels(LPCMP_Type *base, uint32_t positiveChannel, uint32_t negativeChannel)
{
uint32_t tmp32;
tmp32 = base->CCR2 & ~(LPCMP_CCR2_PSEL_MASK | LPCMP_CCR2_MSEL_MASK);
tmp32 |= LPCMP_CCR2_PSEL(positiveChannel) | LPCMP_CCR2_MSEL(negativeChannel);
base->CCR2 = tmp32;
}
/*!
* brief Configures the filter.
*
* param base LPCMP peripheral base address.
* param config Pointer to "lpcmp_filter_config_t" structure.
*/
void LPCMP_SetFilterConfig(LPCMP_Type *base, const lpcmp_filter_config_t *config)
{
assert(config != NULL);
uint32_t tmp32;
tmp32 = base->CCR1 & ~(LPCMP_CCR1_FILT_PER_MASK | LPCMP_CCR1_FILT_CNT_MASK | LPCMP_CCR1_SAMPLE_EN_MASK);
if (config->enableSample)
{
tmp32 |= LPCMP_CCR1_SAMPLE_EN_MASK;
}
tmp32 |= LPCMP_CCR1_FILT_PER(config->filterSamplePeriod) | LPCMP_CCR1_FILT_CNT(config->filterSampleCount);
base->CCR1 = tmp32;
}
/*!
* brief Configure the internal DAC module.
*
* param base LPCMP peripheral base address.
* param config Pointer to "lpcmp_dac_config_t" structure. If config is "NULL", disable internal DAC.
*/
void LPCMP_SetDACConfig(LPCMP_Type *base, const lpcmp_dac_config_t *config)
{
uint32_t tmp32;
if (config == NULL)
{
tmp32 = 0U; /* Disable internal DAC. */
}
else
{
tmp32 = LPCMP_DCR_VRSEL(config->referenceVoltageSource) | LPCMP_DCR_DAC_DATA(config->DACValue);
if (config->enableLowPowerMode)
{
tmp32 |= LPCMP_DCR_DAC_HPMD_MASK;
}
tmp32 |= LPCMP_DCR_DAC_EN_MASK;
}
base->DCR = tmp32;
}
#if defined(FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL) && FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL
/*!
* @brief Configure the window control, users can use this API to implement operations on the window,
* such as inverting the window signal, setting the window closing event(only valid in windowing mode),
* and setting the COUTA signal after the window is closed(only valid in windowing mode).
*
* @param base LPCMP peripheral base address.
* @param config Pointer "lpcmp_window_control_config_t" structure.
*/
void LPCMP_SetWindowControl(LPCMP_Type *base, const lpcmp_window_control_config_t *config)
{
assert(config != NULL);
uint32_t tmp32 = 0UL;
tmp32 = (base->CCR1 & (~(LPCMP_CCR1_COUTA_CFG_MASK | LPCMP_CCR1_EVT_SEL_CFG_MASK | LPCMP_CCR1_WINDOW_INV_MASK)));
if (config->enableInvertWindowSignal)
{
tmp32 |= LPCMP_CCR1_WINDOW_INV_MASK;
}
/* Set COUT event, which can close the active window in window mode. */
tmp32 |= LPCMP_CCR1_EVT_SEL_CFG(config->closeWindowEvent);
/* Set the COUTA signal value when the window is closed. */
tmp32 |= LPCMP_CCR1_COUTA_CFG(config->COUTASignal);
base->CCR1 = tmp32;
}
#endif /* FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL */
#if defined(FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE) && FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE
/*!
* @brief Configure the roundrobin mode.
*
* @param base LPCMP peripheral base address.
* @param config Pointer "lpcmp_roundrobin_config_t" structure.
*/
void LPCMP_SetRoundRobinConfig(LPCMP_Type *base, const lpcmp_roundrobin_config_t *config)
{
assert(config != NULL);
uint32_t tmp32 = 0UL;
/* LPCMPx_RRCR0 register, Configuration options for the round-robin operation. */
tmp32 = (base->RRCR0 &
(~(LPCMP_RRCR0_RR_TRG_SEL_MASK | LPCMP_RRCR0_RR_NSAM_MASK | LPCMP_RRCR0_RR_CLK_SEL_MASK |
LPCMP_RRCR0_RR_INITMOD_MASK | LPCMP_RRCR0_RR_SAMPLE_CNT_MASK | LPCMP_RRCR0_RR_SAMPLE_THRESHOLD_MASK)));
tmp32 |=
(LPCMP_RRCR0_RR_TRG_SEL(config->roundrobinTriggerSource) | LPCMP_RRCR0_RR_NSAM(config->sampleClockNumbers) |
LPCMP_RRCR0_RR_CLK_SEL(config->roundrobinClockSource) | LPCMP_RRCR0_RR_INITMOD(config->initDelayModules) |
LPCMP_RRCR0_RR_SAMPLE_CNT(config->channelSampleNumbers) |
LPCMP_RRCR0_RR_SAMPLE_THRESHOLD(config->sampleTimeThreshhold));
base->RRCR0 = tmp32;
/* LPCMPx_RRCR1 register, Configure the fix port, fix channel and checker channel. */
tmp32 =
(base->RRCR1 & (~(LPCMP_RRCR1_FIXP_MASK | LPCMP_RRCR1_FIXCH_MASK | (0xFFUL << LPCMP_RRCR1_RR_CH0EN_SHIFT))));
tmp32 |= (LPCMP_RRCR1_FIXP(config->fixedMuxPort) | LPCMP_RRCR1_FIXCH(config->fixedChannel) |
((uint32_t)(config->checkerChannelMask) << LPCMP_RRCR1_RR_CH0EN_SHIFT));
base->RRCR1 = tmp32;
}
/*!
* brief Configure the roundrobin internal timer reload value.
*
* param base LPCMP peripheral base address.
* param value RoundRobin internal timer reload value, allowed range:0x0UL-0xFFFFFFFUL.
*/
void LPCMP_SetRoundRobinInternalTimer(LPCMP_Type *base, uint32_t value)
{
uint32_t tmp32 = 0UL;
tmp32 = (base->RRCR2 & (~LPCMP_RRCR2_RR_TIMER_RELOAD_MASK));
tmp32 |= LPCMP_RRCR2_RR_TIMER_RELOAD(value);
base->RRCR2 = tmp32;
}
#endif /* FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE */

View File

@ -0,0 +1,579 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020, 2023 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_LPCMP_H_
#define _FSL_LPCMP_H_
#include "fsl_common.h"
/*!
* @addtogroup lpcmp
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*! @{ */
/*! @brief LPCMP driver version 2.1.1. */
#define FSL_LPCMP_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
/*! @} */
#define LPCMP_CCR1_COUTA_CFG_MASK (LPCMP_CCR1_COUTA_OWEN_MASK | LPCMP_CCR1_COUTA_OW_MASK)
#define LPCMP_CCR1_COUTA_CFG_SHIFT LPCMP_CCR1_COUTA_OWEN_SHIFT
#define LPCMP_CCR1_COUTA_CFG(x) \
(((uint32_t)(((uint32_t)(x)) << LPCMP_CCR1_COUTA_CFG_SHIFT)) & LPCMP_CCR1_COUTA_CFG_MASK)
#define LPCMP_CCR1_EVT_SEL_CFG_MASK (LPCMP_CCR1_EVT_SEL_MASK | LPCMP_CCR1_WINDOW_CLS_MASK)
#define LPCMP_CCR1_EVT_SEL_CFG_SHIFT LPCMP_CCR1_WINDOW_CLS_SHIFT
#define LPCMP_CCR1_EVT_SEL_CFG(x) \
(((uint32_t)(((uint32_t)(x)) << LPCMP_CCR1_EVT_SEL_CFG_SHIFT)) & LPCMP_CCR1_EVT_SEL_CFG_MASK)
/*!
* @brief LPCMP status falgs mask.
*/
enum _lpcmp_status_flags
{
kLPCMP_OutputRisingEventFlag = LPCMP_CSR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */
kLPCMP_OutputFallingEventFlag = LPCMP_CSR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */
#if defined(FSL_FEATURE_LPCMP_HAS_CSR_RRF) && FSL_FEATURE_LPCMP_HAS_CSR_RRF
kLPCMP_OutputRoundRobinEventFlag = LPCMP_CSR_RRF_MASK, /*!< Detects when any channel's last comparison result is
different from the pre-set value in trigger mode. */
#endif /* FSL_FEATURE_LPCMP_HAS_CSR_RRF */
kLPCMP_OutputAssertEventFlag = LPCMP_CSR_COUT_MASK, /*!< Return the current value of the analog comparator output.
The flag does not support W1C. */
};
/*!
* @brief LPCMP interrupt enable/disable mask.
*/
enum _lpcmp_interrupt_enable
{
kLPCMP_OutputRisingInterruptEnable = LPCMP_IER_CFR_IE_MASK, /*!< Comparator interrupt enable rising. */
kLPCMP_OutputFallingInterruptEnable = LPCMP_IER_CFF_IE_MASK, /*!< Comparator interrupt enable falling. */
#if defined(FSL_FEATURE_LPCMP_HAS_IER_RRF_IE) && FSL_FEATURE_LPCMP_HAS_IER_RRF_IE
kLPCMP_RoundRobinInterruptEnable = LPCMP_IER_RRF_IE_MASK, /*!< Comparator round robin mode interrupt
occurred when the comparison result changes for a given channel. */
#endif /* FSL_FEATURE_LPCMP_HAS_IER_RRF_IE */
};
/*!
* @brief LPCMP hysteresis mode. See chip data sheet to get the actual hystersis
* value with each level
*/
typedef enum _lpcmp_hysteresis_mode
{
kLPCMP_HysteresisLevel0 = 0U, /*!< The hard block output has level 0 hysteresis internally. */
kLPCMP_HysteresisLevel1 = 1U, /*!< The hard block output has level 1 hysteresis internally. */
kLPCMP_HysteresisLevel2 = 2U, /*!< The hard block output has level 2 hysteresis internally. */
kLPCMP_HysteresisLevel3 = 3U, /*!< The hard block output has level 3 hysteresis internally. */
} lpcmp_hysteresis_mode_t;
/*!
* @brief LPCMP nano mode.
*/
typedef enum _lpcmp_power_mode
{
kLPCMP_LowSpeedPowerMode = 0U, /*!< Low speed comparison mode is selected. */
kLPCMP_HighSpeedPowerMode = 1U, /*!< High speed comparison mode is selected. */
kLPCMP_NanoPowerMode = 2U, /*!< Nano power comparator is enabled. */
} lpcmp_power_mode_t;
/*!
* @brief Internal DAC reference voltage source.
*/
typedef enum _lpcmp_dac_reference_voltage_source
{
kLPCMP_VrefSourceVin1 = 0U, /*!< vrefh_int is selected as resistor ladder network supply reference Vin. */
kLPCMP_VrefSourceVin2 = 1U, /*!< vrefh_ext is selected as resistor ladder network supply reference Vin. */
} lpcmp_dac_reference_voltage_source_t;
#if defined(FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL) && FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL
/*!
* @brief LPCMP functional mode clock source selection.
*
* Note: In different devices, the functional mode clock source selection is different,
* please refer to specific device Reference Manual for details.
*/
typedef enum _lpcmp_functional_source_clock
{
kLPCMP_FunctionalClockSource0 = 0U, /*!< Select functional mode clock source0. */
kLPCMP_FunctionalClockSource1 = 1U, /*!< Select functional mode clock source1. */
kLPCMP_FunctionalClockSource2 = 2U, /*!< Select functional mode clock source2. */
kLPCMP_FunctionalClockSource3 = 3U, /*!< Select functional mode clock source3. */
} lpcmp_functional_source_clock_t;
#endif /* FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL */
#if defined(FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL) && FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL
/*!
* @brief Set the COUTA signal value when the window is closed.
*/
typedef enum _lpcmp_couta_signal
{
kLPCMP_COUTASignalNoSet = 0U, /*!< NO set the COUTA signal value when the window is closed. */
kLPCMP_COUTASignalLow = 1U, /*!< Set COUTA signal low(0) when the window is closed. */
kLPCMP_COUTASignalHigh = 3U, /*!< Set COUTA signal high(1) when the window is closed. */
} lpcmp_couta_signal_t;
/*!
* @brief Set COUT event, which can close the active window in window mode.
*/
typedef enum _lpcmp_close_window_event
{
kLPCMP_CLoseWindowEventNoSet = 0U, /*!< No Set COUT event, which can close the active window in window mode. */
kLPCMP_CloseWindowEventRisingEdge = 1U, /*!< Set rising edge COUT signal as COUT event. */
kLPCMP_CloseWindowEventFallingEdge = 3U, /*!< Set falling edge COUT signal as COUT event. */
kLPCMP_CLoseWindowEventBothEdge = 5U, /*!< Set both rising and falling edge COUT signal as COUT event. */
} lpcmp_close_window_event_t;
#endif /* FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL */
#if defined(FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE) && FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE
/*!
* @brief LPCMP round robin mode fixed mux port.
*/
typedef enum _lpcmp_roundrobin_fixedmuxport
{
kLPCMP_FixedPlusMuxPort = 0U, /*!< Fixed plus mux port. */
kLPCMP_FixedMinusMuxPort = 1U, /*!< Fixed minus mux port. */
} lpcmp_roundrobin_fixedmuxport_t;
/*!
* @brief LPCMP round robin mode clock source selection.
*
* Note: In different devices,the round robin mode clock source selection is different,
* please refer to the specific device Reference Manual for details.
*/
typedef enum _lpcmp_roundrobin_clock_source
{
kLPCMP_RoundRobinClockSource0 = 0U, /*!< Select roundrobin mode clock source0. */
kLPCMP_RoundRobinClockSource1 = 1U, /*!< Select roundrobin mode clock source1. */
kLPCMP_RoundRobinClockSource2 = 2U, /*!< Select roundrobin mode clock source2. */
kLPCMP_RoundRobinClockSource3 = 3U, /*!< Select roundrobin mode clock source3. */
} lpcmp_roundrobin_clock_source_t;
/*!
* @brief LPCMP round robin mode trigger source.
*/
typedef enum _lpcmp_roundrobin_trigger_source
{
kLPCMP_TriggerSourceExternally = 0U, /*!< Select external trigger source. */
kLPCMP_TriggerSourceInternally = 1U, /*!< Select internal trigger source. */
} lpcmp_roundrobin_trigger_source_t;
#endif /* FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE */
/*!
* @brief Configure the filter.
*/
typedef struct _lpcmp_filter_config
{
bool enableSample; /*!< Decide whether to use the external SAMPLE as a sampling clock input. */
uint8_t filterSampleCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter. */
uint8_t filterSamplePeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. The
sampling clock must be at least 4 times slower than the system clock to the comparator.
So if enableSample is "false", filterSamplePeriod should be set greater than 4.*/
} lpcmp_filter_config_t;
/*!
* @brief configure the internal DAC.
*/
typedef struct _lpcmp_dac_config
{
bool enableLowPowerMode; /*!< Decide whether to enable DAC low power mode. */
lpcmp_dac_reference_voltage_source_t referenceVoltageSource; /*!< Internal DAC supply voltage reference source. */
uint8_t DACValue; /*!< Value for the DAC Output Voltage. Different devices has different available range,
for specific values, please refer to the reference manual.*/
} lpcmp_dac_config_t;
/*!
* @brief Configures the comparator.
*/
typedef struct _lpcmp_config
{
bool enableStopMode; /*!< Decide whether to enable the comparator when in STOP modes. */
bool enableOutputPin; /*!< Decide whether to enable the comparator is available in selected pin. */
bool useUnfilteredOutput; /*!< Decide whether to use unfiltered output. */
bool enableInvertOutput; /*!< Decide whether to inverts the comparator output. */
lpcmp_hysteresis_mode_t hysteresisMode; /*!< LPCMP hysteresis mode. */
lpcmp_power_mode_t powerMode; /*!< LPCMP power mode. */
#if defined(FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL) && FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL
lpcmp_functional_source_clock_t functionalSourceClock; /*!< Select LPCMP functional mode clock source. */
#endif /* FSL_FEATURE_LPCMP_HAS_CCR1_FUNC_CLK_SEL */
} lpcmp_config_t;
#if defined(FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL) && FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL
/*!
* @brief Configure the window mode control.
*/
typedef struct _lpcmp_window_control_config
{
bool enableInvertWindowSignal; /*!< True: enable invert window signal, False: disable invert window signal. */
lpcmp_couta_signal_t COUTASignal; /*!< Decide whether to define the COUTA signal value when the window is closed. */
lpcmp_close_window_event_t closeWindowEvent; /*!< Decide whether to select COUT event signal edge defines
a COUT event to close window. */
} lpcmp_window_control_config_t;
#endif /* FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL */
#if defined(FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE) && FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE
/*!
* @brief Configure the round robin mode.
*/
typedef struct _lpcmp_roundrobin_config
{
uint8_t initDelayModules; /*!< Comparator and DAC initialization delay modulus, See Reference Manual and DataSheet
for specific value. */
uint8_t sampleClockNumbers; /*!< Specify the number of the round robin clock cycles(0~3) to wait after scanning the
active channel before sampling the channel's comparison result. */
uint8_t channelSampleNumbers; /*!< Specify the number of samples for one channel, note that channelSampleNumbers
must not smaller than sampleTimeThreshhold. */
uint8_t sampleTimeThreshhold; /*!< Specify that for one channel, when (sampleTimeThreshhold + 1) sample results are
"1",the final result is "1", otherwise the final result is "0", note that the
sampleTimeThreshhold must not be larger than channelSampleNumbers. */
lpcmp_roundrobin_clock_source_t roundrobinClockSource; /*!< Decide which clock source to choose in round robin mode. */
lpcmp_roundrobin_trigger_source_t roundrobinTriggerSource; /*!< Decide which trigger source to choose in round robin mode. */
lpcmp_roundrobin_fixedmuxport_t fixedMuxPort; /*!< Decide which mux port to choose as fixed channel in round robin mode. */
uint8_t fixedChannel; /*!< Indicate which channel of the fixed mux port is used in round robin mode. */
uint8_t checkerChannelMask; /*!< Indicate which channel of the non-fixed mux port to check its voltage value in
round robin mode, for example, if checkerChannelMask set to 0x11U means select
channel 0 and channel 4 as checker channel.*/
} lpcmp_roundrobin_config_t;
#endif /* FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and configuration
* @{
*/
/*!
* @brief Initialize the LPCMP
*
* This function initializes the LPCMP module. The operations included are:
* - Enabling the clock for LPCMP module.
* - Configuring the comparator.
* - Enabling the LPCMP module.
* Note: For some devices, multiple LPCMP instance share the same clock gate. In this case, to enable the clock for
* any instance enables all the LPCMPs. Check the chip reference manual for the clock assignment of the LPCMP.
*
* @param base LPCMP peripheral base address.
* @param config Pointer to "lpcmp_config_t" structure.
*/
void LPCMP_Init(LPCMP_Type *base, const lpcmp_config_t *config);
/*!
* @brief De-initializes the LPCMP module.
*
* This function de-initializes the LPCMP module. The operations included are:
* - Disabling the LPCMP module.
* - Disabling the clock for LPCMP module.
*
* This function disables the clock for the LPCMP.
* Note: For some devices, multiple LPCMP instance shares the same clock gate. In this case, before disabling the
* clock for the LPCMP, ensure that all the LPCMP instances are not used.
*
* @param base LPCMP peripheral base address.
*/
void LPCMP_Deinit(LPCMP_Type *base);
/*!
* @brief Gets an available pre-defined settings for the comparator's configuration.
*
* This function initializes the comparator configuration structure to these default values:
* @code
* config->enableStopMode = false;
* config->enableOutputPin = false;
* config->useUnfilteredOutput = false;
* config->enableInvertOutput = false;
* config->hysteresisMode = kLPCMP_HysteresisLevel0;
* config->powerMode = kLPCMP_LowSpeedPowerMode;
* config->functionalSourceClock = kLPCMP_FunctionalClockSource0;
* @endcode
* @param config Pointer to "lpcmp_config_t" structure.
*/
void LPCMP_GetDefaultConfig(lpcmp_config_t *config);
/*!
* @brief Enable/Disable LPCMP module.
*
* @param base LPCMP peripheral base address.
* @param enable "true" means enable the module, and "false" means disable the module.
*/
static inline void LPCMP_Enable(LPCMP_Type *base, bool enable)
{
if (enable)
{
base->CCR0 |= LPCMP_CCR0_CMP_EN_MASK;
}
else
{
base->CCR0 &= ~LPCMP_CCR0_CMP_EN_MASK;
}
}
/*!
* @brief Select the input channels for LPCMP. This function determines which input
* is selected for the negative and positive mux.
*
* @param base LPCMP peripheral base address.
* @param positiveChannel Positive side input channel number. Available range is 0-7.
* @param negativeChannel Negative side input channel number. Available range is 0-7.
*/
void LPCMP_SetInputChannels(LPCMP_Type *base, uint32_t positiveChannel, uint32_t negativeChannel);
/*!
* @brief Enables/disables the DMA request for rising/falling events.
* Normally, the LPCMP generates a CPU interrupt if there is a rising/falling event. When
* DMA support is enabled and the rising/falling interrupt is enabled , the rising/falling
* event forces a DMA transfer request rather than a CPU interrupt instead.
*
* @param base LPCMP peripheral base address.
* @param enable "true" means enable DMA support, and "false" means disable DMA support.
*/
static inline void LPCMP_EnableDMA(LPCMP_Type *base, bool enable)
{
if (enable)
{
base->CCR1 |= LPCMP_CCR1_DMA_EN_MASK;
}
else
{
base->CCR1 &= ~LPCMP_CCR1_DMA_EN_MASK;
}
}
/*!
* @brief Configures the filter.
*
* @param base LPCMP peripheral base address.
* @param config Pointer to "lpcmp_filter_config_t" structure.
*/
void LPCMP_SetFilterConfig(LPCMP_Type *base, const lpcmp_filter_config_t *config);
/*!
* @brief Configure the internal DAC module.
*
* @param base LPCMP peripheral base address.
* @param config Pointer to "lpcmp_dac_config_t" structure. If config is "NULL", disable internal DAC.
*/
void LPCMP_SetDACConfig(LPCMP_Type *base, const lpcmp_dac_config_t *config);
/*!
* @brief Enable the interrupts.
*
* @param base LPCMP peripheral base address.
* @param mask Mask value for interrupts. See "_lpcmp_interrupt_enable".
*/
static inline void LPCMP_EnableInterrupts(LPCMP_Type *base, uint32_t mask)
{
base->IER |= mask;
}
/*!
* @brief Disable the interrupts.
*
* @param base LPCMP peripheral base address.
* @param mask Mask value for interrupts. See "_lpcmp_interrupt_enable".
*/
static inline void LPCMP_DisableInterrupts(LPCMP_Type *base, uint32_t mask)
{
base->IER &= ~mask;
}
/*!
* @brief Get the LPCMP status flags.
*
* @param base LPCMP peripheral base address.
*
* @return Mask value for the asserted flags. See "_lpcmp_status_flags".
*/
static inline uint32_t LPCMP_GetStatusFlags(LPCMP_Type *base)
{
return base->CSR;
}
/*!
* @brief Clear the LPCMP status flags
*
* @param base LPCMP peripheral base address.
* @param mask Mask value for the flags. See "_lpcmp_status_flags".
*/
static inline void LPCMP_ClearStatusFlags(LPCMP_Type *base, uint32_t mask)
{
base->CSR = mask;
}
/*! @} */
/*!
* @name Window mode
* @{
*/
/*!
* @brief Enable/Disable window mode.When any windowed mode is active, COUTA is clocked by
* the bus clock whenever WINDOW = 1. The last latched value is held when WINDOW = 0.
* The optionally inverted comparator output COUT_RAW is sampled on every bus clock
* when WINDOW=1 to generate COUTA.
*
* @param base LPCMP peripheral base address.
* @param enable "true" means enable window mode, and "false" means disable window mode.
*/
static inline void LPCMP_EnableWindowMode(LPCMP_Type *base, bool enable)
{
if (enable)
{
base->CCR1 |= LPCMP_CCR1_WINDOW_EN_MASK;
}
else
{
base->CCR1 &= ~LPCMP_CCR1_WINDOW_EN_MASK;
}
}
#if defined(FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL) && FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL
/*!
* @brief Configure the window control, users can use this API to implement operations on the window,
* such as inverting the window signal, setting the window closing event(only valid in windowing mode),
* and setting the COUTA signal after the window is closed(only valid in windowing mode).
*
* @param base LPCMP peripheral base address.
* @param config Pointer "lpcmp_window_control_config_t" structure.
*/
void LPCMP_SetWindowControl(LPCMP_Type *base, const lpcmp_window_control_config_t *config);
#endif /* FSL_FEATURE_LPCMP_HAS_WINDOW_CONTROL */
/*! @} */
#if defined(FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE) && FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE
/*!
* @name RoundRobin mode
* @{
*/
/*!
* @brief Configure the roundrobin mode.
*
* @param base LPCMP peripheral base address.
* @param config Pointer "lpcmp_roundrobin_config_t" structure.
*/
void LPCMP_SetRoundRobinConfig(LPCMP_Type *base, const lpcmp_roundrobin_config_t *config);
/*!
* brief Configure the roundrobin internal timer reload value.
*
* param base LPCMP peripheral base address.
* param value RoundRobin internal timer reload value, allowed range:0x0UL-0xFFFFFFFUL.
*/
void LPCMP_SetRoundRobinInternalTimer(LPCMP_Type *base, uint32_t value);
/*!
* @brief Enable/Disable roundrobin mode.
*
* @param base LPCMP peripheral base address.
* @param enable "true" means enable roundrobin mode, and "false" means disable roundrobin mode.
*/
static inline void LPCMP_EnableRoundRobinMode(LPCMP_Type *base, bool enable)
{
if (enable)
{
base->RRCR0 |= LPCMP_RRCR0_RR_EN_MASK;
}
else
{
base->RRCR0 &= ~LPCMP_RRCR0_RR_EN_MASK;
}
}
/*!
* @brief Enable/Disable roundrobin internal timer, note that this function is only valid
* when using the internal trigger source.
*
* @param base LPCMP peripheral base address.
* @param enable "true" means enable roundrobin internal timer, and "false" means disable roundrobin internal timer.
*/
static inline void LPCMP_EnableRoundRobinInternalTimer(LPCMP_Type *base, bool enable)
{
if (enable)
{
base->RRCR2 |= LPCMP_RRCR2_RR_TIMER_EN_MASK;
}
else
{
base->RRCR2 &= ~LPCMP_RRCR2_RR_TIMER_EN_MASK;
}
}
/*!
* @brief Set preset value for all channels, users can set all channels' preset vaule through this API,
* for example, if the mask set to 0x03U means channel0 and channel2's preset value set to 1U and other
* channels' preset value set to 0U.
*
* @param base LPCMP peripheral base address.
* @param mask Mask of channel index.
*/
static inline void LPCMP_SetPreSetValue(LPCMP_Type *base, uint8_t mask)
{
base->RRCSR = (uint32_t)mask;
}
/*!
* @brief Get comparison results for all channels, users can get all channels' comparison
* results through this API.
*
* @param base LPCMP peripheral base address.
* @return return All channels' comparison result.
*/
static inline uint8_t LPCMP_GetComparisonResult(LPCMP_Type *base)
{
return (uint8_t)base->RRCSR;
}
/*!
* @brief Clear input changed flags for single channel or multiple channels, users can clear
* input changed flag of a single channel or multiple channels through this API, for example,
* if the mask set to 0x03U means clear channel0 and channel2's input changed flags.
*
* @param base LPCMP peripheral base address.
* @param mask Mask of channel index.
*/
static inline void LPCMP_ClearInputChangedFlags(LPCMP_Type *base, uint8_t mask)
{
base->RRSR = (uint32_t)mask;
}
/*!
* @brief Get input changed flags for all channels, Users can get all channels' input changed
* flags through this API.
*
* @param base LPCMP peripheral base address.
* @return return All channels' changed flag.
*/
static inline uint8_t LPCMP_GetInputChangedFlags(LPCMP_Type *base)
{
return (uint8_t)base->RRSR;
}
/*! @} */
#endif /* FSL_FEATURE_LPCMP_HAS_ROUNDROBIN_MODE */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_LPCMP_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,642 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_lpi2c_edma.h"
#include <stdlib.h>
#include <string.h>
/*
* $Coverage Justification Reference$
*
* $Justification fsl_lpi2c_edma_c_ref_1$
* Need multiple master and slave modules on bus to simulate the true branch
*
* $Justification fsl_lpi2c_edma_c_ref_2$
* FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(X) is a constant.
*
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpi2c_edma"
#endif
/* @brief Mask to align an address to 32 bytes. */
#define ALIGN_32_MASK (0x1fU)
/* ! @brief LPI2C master fifo commands. */
enum _lpi2c_master_fifo_cmd
{
kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */
kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */
kStopCmd = LPI2C_MTDR_CMD(0x2U), /*!< Generate STOP condition */
kStartCmd = LPI2C_MTDR_CMD(0x4U), /*!< Generate(repeated) START and transmit address in DATA[[7:0] */
};
/*! @brief States for the state machine used by transactional APIs. */
enum _lpi2c_transfer_states
{
kIdleState = 0,
kSendCommandState,
kIssueReadCommandState,
kTransferDataState,
kStopState,
kWaitForCompletionState,
};
/*! @brief Typedef for interrupt handler. */
typedef void (*lpi2c_isr_t)(LPI2C_Type *base, void *handle);
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Prepares the command buffer with the sequence of commands needed to send the requested transaction.
* @param handle Master DMA driver handle.
* @return Number of command words.
*/
static uint32_t LPI2C_GenerateCommands(lpi2c_master_edma_handle_t *handle);
/*!
* @brief DMA completion callback.
* @param dmaHandle DMA channel handle for the channel that completed.
* @param userData User data associated with the channel handle. For this callback, the user data is the
* LPI2C DMA driver handle.
* @param isTransferDone Whether the DMA transfer has completed.
* @param tcds Number of TCDs that completed.
*/
static void LPI2C_MasterEDMACallback(edma_handle_t *dmaHandle, void *userData, bool isTransferDone, uint32_t tcds);
/*!
* @brief LPI2C master edma transfer IRQ handle routine.
*
* This API handles the LPI2C bus error status and invoke callback if needed.
*
* @param base The LPI2C peripheral base address.
* @param lpi2cMasterEdmaHandle Pointer to the LPI2C master edma handle.
*/
static void LPI2C_MasterTransferEdmaHandleIRQ(LPI2C_Type *base, void *lpi2cMasterEdmaHandle);
/*******************************************************************************
* Variables
******************************************************************************/
static uint32_t lpi2c_edma_RecSetting = 0x02;
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Create a new handle for the LPI2C master DMA APIs.
*
* The creation of a handle is for use with the DMA APIs. Once a handle
* is created, there is not a corresponding destroy handle. If the user wants to
* terminate a transfer, the LPI2C_MasterTransferAbortEDMA() API shall be called.
*
* For devices where the LPI2C send and receive DMA requests are OR'd together, the a txDmaHandle
* parameter is ignored and may be set to NULL.
*
* param base The LPI2C peripheral base address.
* param[out] handle Pointer to the LPI2C master driver handle.
* param rxDmaHandle Handle for the eDMA receive channel. Created by the user prior to calling this function.
* param txDmaHandle Handle for the eDMA transmit channel. Created by the user prior to calling this function.
* param callback User provided pointer to the asynchronous callback function.
* param userData User provided pointer to the application callback data.
*/
void LPI2C_MasterCreateEDMAHandle(LPI2C_Type *base,
lpi2c_master_edma_handle_t *handle,
edma_handle_t *rxDmaHandle,
edma_handle_t *txDmaHandle,
lpi2c_master_edma_transfer_callback_t callback,
void *userData)
{
assert(handle != NULL);
assert(rxDmaHandle != NULL);
assert(txDmaHandle != NULL);
/* Look up instance number */
uint32_t instance = LPI2C_GetInstance(base);
/* Clear out the handle. */
(void)memset(handle, 0, sizeof(*handle));
/* Set up the handle. For combined rx/tx DMA requests, the tx channel handle is set to the rx handle */
/* in order to make the transfer API code simpler. */
handle->base = base;
handle->completionCallback = callback;
handle->userData = userData;
handle->rx = rxDmaHandle;
handle->tx = (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) > 0) ? txDmaHandle : rxDmaHandle;
/* Save the handle in global variables to support the double weak mechanism. */
s_lpi2cMasterHandle[instance] = handle;
/* Set LPI2C_MasterTransferEdmaHandleIRQ as LPI2C DMA IRQ handler */
s_lpi2cMasterIsr = LPI2C_MasterTransferEdmaHandleIRQ;
/* Enable interrupt in NVIC. */
(void)EnableIRQ(kLpi2cIrqs[instance]);
/* Set DMA channel completion callbacks. */
EDMA_SetCallback(handle->rx, LPI2C_MasterEDMACallback, handle);
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0)
{
EDMA_SetCallback(handle->tx, LPI2C_MasterEDMACallback, handle);
}
}
static uint32_t LPI2C_GenerateCommands(lpi2c_master_edma_handle_t *handle)
{
lpi2c_master_transfer_t *xfer = &handle->transfer;
uint16_t *cmd = (uint16_t *)&handle->commandBuffer;
uint32_t cmdCount = 0;
/* Handle no start option. */
if ((xfer->flags & (uint32_t)kLPI2C_TransferNoStartFlag) != 0U)
{
if (xfer->direction == kLPI2C_Read)
{
/* Need to issue read command first. */
cmd[cmdCount++] = (uint16_t)kRxDataCmd | (uint16_t)LPI2C_MTDR_DATA(xfer->dataSize - 1U);
}
}
else
{
/*
* Initial direction depends on whether a subaddress was provided, and of course the actual
* data transfer direction.
*/
lpi2c_direction_t direction = (xfer->subaddressSize != 0U) ? kLPI2C_Write : xfer->direction;
/* Start command. */
cmd[cmdCount++] =
(uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction);
/* Subaddress, MSB first. */
if (xfer->subaddressSize != 0U)
{
uint32_t subaddressRemaining = xfer->subaddressSize;
while (0U != subaddressRemaining--)
{
uint8_t subaddressByte = (uint8_t)(xfer->subaddress >> (8U * subaddressRemaining)) & 0xffU;
cmd[cmdCount++] = subaddressByte;
}
}
/* Reads need special handling because we have to issue a read command and maybe a repeated start. */
if ((xfer->dataSize != 0U) && (xfer->direction == kLPI2C_Read))
{
/* Need to send repeated start if switching directions to read. */
if (direction == kLPI2C_Write)
{
cmd[cmdCount++] = (uint16_t)kStartCmd |
(uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read);
}
/* Read command. A single write to MTDR can issue read operation of 0xFFU + 1 byte of data at most, so when
the dataSize is larger than 0x100U, push multiple read commands to MTDR until dataSize is reached. */
size_t tmpRxSize = xfer->dataSize;
while (tmpRxSize != 0U)
{
if (tmpRxSize > 256U)
{
cmd[cmdCount++] = (uint16_t)kRxDataCmd | (uint16_t)LPI2C_MTDR_DATA(0xFFU);
tmpRxSize -= 256U;
}
else
{
cmd[cmdCount++] = (uint16_t)kRxDataCmd | (uint16_t)LPI2C_MTDR_DATA(tmpRxSize - 1U);
tmpRxSize = 0U;
}
}
}
}
return cmdCount;
}
/*!
* brief Performs a non-blocking DMA-based transaction on the I2C bus.
*
* The callback specified when the a handle was created is invoked when the transaction has
* completed.
*
* param base The LPI2C peripheral base address.
* param handle Pointer to the LPI2C master driver handle.
* param transfer The pointer to the transfer descriptor.
* retval #kStatus_Success The transaction was started successfully.
* retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or another DMA
* transaction is already in progress.
*/
status_t LPI2C_MasterTransferEDMA(LPI2C_Type *base,
lpi2c_master_edma_handle_t *handle,
lpi2c_master_transfer_t *transfer)
{
status_t result;
assert(handle != NULL);
assert(transfer != NULL);
assert(transfer->subaddressSize <= sizeof(transfer->subaddress));
/* Check transfer data size in read operation. */
/* A single write to MTDR can issue read operation of 0xFFU + 1 byte of data at most, so when the dataSize is larger
than 0x100U, push multiple read commands to MTDR until dataSize is reached. LPI2C edma transfer uses linked
descriptor to transfer command and data, the command buffer is stored in handle. Allocate 4 command words to
carry read command which can cover nearly all use cases. */
if ((transfer->direction == kLPI2C_Read) && (transfer->dataSize > (256U * 4U)))
{
return kStatus_InvalidArgument;
}
/* Return busy if another transaction is in progress. */
if (handle->isBusy)
{
return kStatus_LPI2C_Busy;
}
/* Enable the master function and disable the slave function. */
LPI2C_MasterEnable(base, true);
LPI2C_SlaveEnable(base, false);
/* Return an error if the bus is already in use not by us. */
result = LPI2C_CheckForBusyBus(base);
/*
* $Branch Coverage Justification$
* $ref fsl_lpi2c_edma_c_ref_1$
*/
if (result != kStatus_Success)
{
return result;
}
/* We're now busy. */
handle->isBusy = true;
/* Disable LPI2C IRQ and DMA sources while we configure stuff. */
LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
LPI2C_MasterEnableDMA(base, false, false);
/* Clear all flags. */
LPI2C_MasterClearStatusFlags(base, (uint32_t)kLPI2C_MasterClearFlags);
/* Save transfer into handle. */
handle->transfer = *transfer;
/* Generate commands to send. */
uint32_t commandCount = LPI2C_GenerateCommands(handle);
/* If the user is transmitting no data with no start or stop, then just go ahead and invoke the callback. */
if ((0U == commandCount) && (transfer->dataSize == 0U))
{
if (handle->completionCallback != NULL)
{
handle->completionCallback(base, handle, kStatus_Success, handle->userData);
}
return kStatus_Success;
}
/* Reset DMA channels. */
EDMA_ResetChannel(handle->rx->base, handle->rx->channel);
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0)
{
EDMA_ResetChannel(handle->tx->base, handle->tx->channel);
}
/* Get a 32-byte aligned TCD pointer. */
edma_tcd_t *tcd = (edma_tcd_t *)((uint32_t)(&handle->tcds[1]) & (~ALIGN_32_MASK));
bool hasSendData = (transfer->direction == kLPI2C_Write) && (transfer->dataSize != 0U);
bool hasReceiveData = (transfer->direction == kLPI2C_Read) && (transfer->dataSize != 0U);
edma_transfer_config_t transferConfig = {0};
edma_tcd_t *linkTcd = NULL;
/* Set up data transmit. */
if (hasSendData)
{
uint32_t *srcAddr = (uint32_t *)transfer->data;
transferConfig.srcAddr = (uint32_t)srcAddr;
transferConfig.destAddr = (uint32_t)LPI2C_MasterGetTxFifoAddress(base);
transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
transferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
transferConfig.srcOffset = (int16_t)sizeof(uint8_t);
transferConfig.destOffset = 0;
transferConfig.minorLoopBytes = sizeof(uint8_t); /* TODO optimize to fill fifo */
transferConfig.majorLoopCounts = transfer->dataSize;
/* Store the initially configured eDMA minor byte transfer count into the LPI2C handle */
handle->nbytes = (uint8_t)transferConfig.minorLoopBytes;
if (commandCount != 0U)
{
/* Create a software TCD, which will be chained after the commands. */
EDMA_TcdReset(tcd);
EDMA_TcdSetTransferConfig(tcd, &transferConfig, NULL);
EDMA_TcdEnableInterrupts(tcd, (uint32_t)kEDMA_MajorInterruptEnable);
linkTcd = tcd;
}
else
{
/* User is only transmitting data with no required commands, so this transfer can stand alone. */
EDMA_SetTransferConfig(handle->tx->base, handle->tx->channel, &transferConfig, NULL);
EDMA_EnableChannelInterrupts(handle->tx->base, handle->tx->channel, (uint32_t)kEDMA_MajorInterruptEnable);
}
}
else if (hasReceiveData)
{
uint32_t *srcAddr = (uint32_t *)transfer->data;
/* Set up data receive. */
transferConfig.srcAddr = (uint32_t)LPI2C_MasterGetRxFifoAddress(base);
transferConfig.destAddr = (uint32_t)srcAddr;
transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
transferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
transferConfig.srcOffset = 0;
transferConfig.destOffset = (int16_t)sizeof(uint8_t);
transferConfig.minorLoopBytes = sizeof(uint8_t); /* TODO optimize to empty fifo */
transferConfig.majorLoopCounts = transfer->dataSize;
/* Store the initially configured eDMA minor byte transfer count into the LPI2C handle */
handle->nbytes = (uint8_t)transferConfig.minorLoopBytes;
if ((FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0) || (0U == commandCount))
{
/* We can put this receive transfer on its own DMA channel. */
EDMA_SetTransferConfig(handle->rx->base, handle->rx->channel, &transferConfig, NULL);
EDMA_EnableChannelInterrupts(handle->rx->base, handle->rx->channel, (uint32_t)kEDMA_MajorInterruptEnable);
}
else
{
/* For shared rx/tx DMA requests, when there are commands, create a software TCD of
enabling rx dma and disabling tx dma, which will be chained onto the commands transfer,
and create another software TCD of transfering data and chain it onto the last TCD.
Notice that in this situation assume tx/rx uses same channel */
EDMA_TcdReset(tcd);
EDMA_TcdSetTransferConfig(tcd, &transferConfig, NULL);
EDMA_TcdEnableInterrupts(tcd, (uint32_t)kEDMA_MajorInterruptEnable);
transferConfig.srcAddr = (uint32_t)&lpi2c_edma_RecSetting;
transferConfig.destAddr = (uint32_t) & (base->MDER);
transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
transferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
transferConfig.srcOffset = 0;
transferConfig.destOffset = (int16_t)sizeof(uint8_t);
transferConfig.minorLoopBytes = sizeof(uint8_t);
transferConfig.majorLoopCounts = 1;
edma_tcd_t *tcdSetRxClearTxDMA = (edma_tcd_t *)((uint32_t)(&handle->tcds[2]) & (~ALIGN_32_MASK));
EDMA_TcdReset(tcdSetRxClearTxDMA);
EDMA_TcdSetTransferConfig(tcdSetRxClearTxDMA, &transferConfig, tcd);
linkTcd = tcdSetRxClearTxDMA;
}
}
else
{
/* No data to send */
}
/* Set up commands transfer. */
if (commandCount != 0U)
{
transferConfig.srcAddr = (uint32_t)handle->commandBuffer;
transferConfig.destAddr = (uint32_t)LPI2C_MasterGetTxFifoAddress(base);
transferConfig.srcTransferSize = kEDMA_TransferSize2Bytes;
transferConfig.destTransferSize = kEDMA_TransferSize2Bytes;
transferConfig.srcOffset = (int16_t)sizeof(uint16_t);
transferConfig.destOffset = 0;
transferConfig.minorLoopBytes = sizeof(uint16_t); /* TODO optimize to fill fifo */
transferConfig.majorLoopCounts = commandCount;
EDMA_SetTransferConfig(handle->tx->base, handle->tx->channel, &transferConfig, linkTcd);
}
/* Start DMA transfer. */
/*
* $Branch Coverage Justification$
* $ref fsl_lpi2c_edma_c_ref_2$
*/
if (hasReceiveData || (0 == FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base)))
{
EDMA_StartTransfer(handle->rx);
}
/*
* $Branch Coverage Justification$
* $ref fsl_lpi2c_edma_c_ref_2$
*/
if ((hasSendData || (commandCount != 0U)) && (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0))
{
EDMA_StartTransfer(handle->tx);
}
/* Enable DMA in both directions. This actually kicks of the transfer. */
LPI2C_MasterEnableDMA(base, true, true);
/* Enable all LPI2C master interrupts */
LPI2C_MasterEnableInterrupts(base,
(uint32_t)kLPI2C_MasterArbitrationLostFlag | (uint32_t)kLPI2C_MasterNackDetectFlag |
(uint32_t)kLPI2C_MasterPinLowTimeoutFlag | (uint32_t)kLPI2C_MasterFifoErrFlag);
return result;
}
/*!
* brief Returns number of bytes transferred so far.
*
* param base The LPI2C peripheral base address.
* param handle Pointer to the LPI2C master driver handle.
* param[out] count Number of bytes transferred so far by the non-blocking transaction.
* retval #kStatus_Success
* retval #kStatus_NoTransferInProgress There is not a DMA transaction currently in progress.
*/
status_t LPI2C_MasterTransferGetCountEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle, size_t *count)
{
assert(handle != NULL);
if (NULL == count)
{
return kStatus_InvalidArgument;
}
/* Catch when there is not an active transfer. */
if (!handle->isBusy)
{
*count = 0;
return kStatus_NoTransferInProgress;
}
uint32_t remaining = handle->transfer.dataSize;
/* If the DMA is still on a commands transfer that chains to the actual data transfer, */
/* we do nothing and return the number of transferred bytes as zero. */
if (EDMA_GetNextTCDAddress(handle->tx) == 0U)
{
if (handle->transfer.direction == kLPI2C_Write)
{
remaining =
(uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->tx->base, handle->tx->channel);
}
else
{
remaining =
(uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->rx->base, handle->rx->channel);
}
}
*count = handle->transfer.dataSize - remaining;
return kStatus_Success;
}
/*!
* brief Terminates a non-blocking LPI2C master transmission early.
*
* note It is not safe to call this function from an IRQ handler that has a higher priority than the
* eDMA peripheral's IRQ priority.
*
* param base The LPI2C peripheral base address.
* param handle Pointer to the LPI2C master driver handle.
* retval #kStatus_Success A transaction was successfully aborted.
* retval #kStatus_LPI2C_Idle There is not a DMA transaction currently in progress.
*/
status_t LPI2C_MasterTransferAbortEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle)
{
/* Catch when there is not an active transfer. */
if (!handle->isBusy)
{
return kStatus_LPI2C_Idle;
}
/* Terminate DMA transfers. */
EDMA_AbortTransfer(handle->rx);
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0)
{
EDMA_AbortTransfer(handle->tx);
}
/* Reset fifos. */
base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
/* Disable LPI2C interrupts. */
LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
/* If master is still busy and has not send out stop signal yet. */
if ((LPI2C_MasterGetStatusFlags(base) &
((uint32_t)kLPI2C_MasterStopDetectFlag | (uint32_t)kLPI2C_MasterBusyFlag)) == (uint32_t)kLPI2C_MasterBusyFlag)
{
/* Send a stop command to finalize the transfer. */
base->MTDR = (uint32_t)kStopCmd;
}
/* Reset handle. */
handle->isBusy = false;
return kStatus_Success;
}
static void LPI2C_MasterEDMACallback(edma_handle_t *dmaHandle, void *userData, bool isTransferDone, uint32_t tcds)
{
lpi2c_master_edma_handle_t *handle = (lpi2c_master_edma_handle_t *)userData;
if (NULL == handle)
{
return;
}
/* Check for errors. */
status_t result = LPI2C_MasterCheckAndClearError(handle->base, LPI2C_MasterGetStatusFlags(handle->base));
/* Done with this transaction. */
handle->isBusy = false;
if (0U == (handle->transfer.flags & (uint32_t)kLPI2C_TransferNoStopFlag))
{
/* Send a stop command to finalize the transfer. */
handle->base->MTDR = (uint32_t)kStopCmd;
}
/* Invoke callback. */
if (handle->completionCallback != NULL)
{
handle->completionCallback(handle->base, handle, result, handle->userData);
}
}
static void LPI2C_MasterTransferEdmaHandleIRQ(LPI2C_Type *base, void *lpi2cMasterEdmaHandle)
{
assert(lpi2cMasterEdmaHandle != NULL);
lpi2c_master_edma_handle_t *handle = (lpi2c_master_edma_handle_t *)lpi2cMasterEdmaHandle;
uint32_t status = LPI2C_MasterGetStatusFlags(base);
status_t result = kStatus_Success;
/* Terminate DMA transfers. */
EDMA_AbortTransfer(handle->rx);
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0)
{
EDMA_AbortTransfer(handle->tx);
}
/* Done with this transaction. */
handle->isBusy = false;
/* Disable LPI2C interrupts. */
LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
/* Check error status */
if (0U != (status & (uint32_t)kLPI2C_MasterPinLowTimeoutFlag))
{
result = kStatus_LPI2C_PinLowTimeout;
}
/*
* $Branch Coverage Justification$
* $ref fsl_lpi2c_edma_c_ref_1$
*/
else if (0U != (status & (uint32_t)kLPI2C_MasterArbitrationLostFlag))
{
result = kStatus_LPI2C_ArbitrationLost;
}
else if (0U != (status & (uint32_t)kLPI2C_MasterNackDetectFlag))
{
result = kStatus_LPI2C_Nak;
}
else if (0U != (status & (uint32_t)kLPI2C_MasterFifoErrFlag))
{
result = kStatus_LPI2C_FifoError;
}
else
{
; /* Intentional empty */
}
/* Clear error status. */
(void)LPI2C_MasterCheckAndClearError(base, status);
/* Send stop flag if needed */
if (0U == (handle->transfer.flags & (uint32_t)kLPI2C_TransferNoStopFlag))
{
status = LPI2C_MasterGetStatusFlags(base);
/* If bus is still busy and the master has not generate stop flag */
if ((status & ((uint32_t)kLPI2C_MasterBusBusyFlag | (uint32_t)kLPI2C_MasterStopDetectFlag)) ==
(uint32_t)kLPI2C_MasterBusBusyFlag)
{
/* Send a stop command to finalize the transfer. */
handle->base->MTDR = (uint32_t)kStopCmd;
}
}
/* Invoke callback. */
if (handle->completionCallback != NULL)
{
handle->completionCallback(base, handle, result, handle->userData);
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_LPI2C_EDMA_H_
#define _FSL_LPI2C_EDMA_H_
#include "fsl_lpi2c.h"
#include "fsl_edma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPI2C EDMA driver version. */
#define FSL_LPI2C_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 4, 1))
/*@}*/
/*!
* @addtogroup lpi2c_master_edma_driver
* @{
*/
/* Forward declaration of the transfer descriptor and handle typedefs. */
typedef struct _lpi2c_master_edma_handle lpi2c_master_edma_handle_t;
/*!
* @brief Master DMA completion callback function pointer type.
*
* This callback is used only for the non-blocking master transfer API. Specify the callback you wish to use
* in the call to LPI2C_MasterCreateEDMAHandle().
*
* @param base The LPI2C peripheral base address.
* @param handle Handle associated with the completed transfer.
* @param completionStatus Either kStatus_Success or an error code describing how the transfer completed.
* @param userData Arbitrary pointer-sized value passed from the application.
*/
typedef void (*lpi2c_master_edma_transfer_callback_t)(LPI2C_Type *base,
lpi2c_master_edma_handle_t *handle,
status_t completionStatus,
void *userData);
/*!
* @brief Driver handle for master DMA APIs.
* @note The contents of this structure are private and subject to change.
*/
struct _lpi2c_master_edma_handle
{
LPI2C_Type *base; /*!< LPI2C base pointer. */
bool isBusy; /*!< Transfer state machine current state. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
uint16_t commandBuffer[10]; /*!< LPI2C command sequence. When all 10 command words are used:
Start&addr&write[1 word] + subaddr[4 words] + restart&addr&read[1 word] + receive&Size[4 words] */
lpi2c_master_transfer_t transfer; /*!< Copy of the current transfer info. */
lpi2c_master_edma_transfer_callback_t completionCallback; /*!< Callback function pointer. */
void *userData; /*!< Application data passed to callback. */
edma_handle_t *rx; /*!< Handle for receive DMA channel. */
edma_handle_t *tx; /*!< Handle for transmit DMA channel. */
edma_tcd_t tcds[3]; /*!< Software TCD. Three are allocated to provide enough room to align to 32-bytes. */
};
/*! @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @addtogroup lpi2c_master_edma_driver
* @{
*/
/*! @name Master DMA */
/*@{*/
/*!
* @brief Create a new handle for the LPI2C master DMA APIs.
*
* The creation of a handle is for use with the DMA APIs. Once a handle
* is created, there is not a corresponding destroy handle. If the user wants to
* terminate a transfer, the LPI2C_MasterTransferAbortEDMA() API shall be called.
*
* For devices where the LPI2C send and receive DMA requests are OR'd together, the @a txDmaHandle
* parameter is ignored and may be set to NULL.
*
* @param base The LPI2C peripheral base address.
* @param[out] handle Pointer to the LPI2C master driver handle.
* @param rxDmaHandle Handle for the eDMA receive channel. Created by the user prior to calling this function.
* @param txDmaHandle Handle for the eDMA transmit channel. Created by the user prior to calling this function.
* @param callback User provided pointer to the asynchronous callback function.
* @param userData User provided pointer to the application callback data.
*/
void LPI2C_MasterCreateEDMAHandle(LPI2C_Type *base,
lpi2c_master_edma_handle_t *handle,
edma_handle_t *rxDmaHandle,
edma_handle_t *txDmaHandle,
lpi2c_master_edma_transfer_callback_t callback,
void *userData);
/*!
* @brief Performs a non-blocking DMA-based transaction on the I2C bus.
*
* The callback specified when the @a handle was created is invoked when the transaction has
* completed.
*
* @param base The LPI2C peripheral base address.
* @param handle Pointer to the LPI2C master driver handle.
* @param transfer The pointer to the transfer descriptor.
* @retval kStatus_Success The transaction was started successfully.
* @retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or another DMA
* transaction is already in progress.
*/
status_t LPI2C_MasterTransferEDMA(LPI2C_Type *base,
lpi2c_master_edma_handle_t *handle,
lpi2c_master_transfer_t *transfer);
/*!
* @brief Returns number of bytes transferred so far.
*
* @param base The LPI2C peripheral base address.
* @param handle Pointer to the LPI2C master driver handle.
* @param[out] count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_Success
* @retval kStatus_NoTransferInProgress There is not a DMA transaction currently in progress.
*/
status_t LPI2C_MasterTransferGetCountEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle, size_t *count);
/*!
* @brief Terminates a non-blocking LPI2C master transmission early.
*
* @note It is not safe to call this function from an IRQ handler that has a higher priority than the
* eDMA peripheral's IRQ priority.
*
* @param base The LPI2C peripheral base address.
* @param handle Pointer to the LPI2C master driver handle.
* @retval kStatus_Success A transaction was successfully aborted.
* @retval #kStatus_LPI2C_Idle There is not a DMA transaction currently in progress.
*/
status_t LPI2C_MasterTransferAbortEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle);
/*@}*/
/*! @} */
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_LPI2C_EDMA_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,339 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_LPSPI_EDMA_H_
#define _FSL_LPSPI_EDMA_H_
#include "fsl_lpspi.h"
#include "fsl_edma.h"
/*!
* @addtogroup lpspi_edma_driver
* @{
*/
/***********************************************************************************************************************
* Definitions
**********************************************************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPSPI EDMA driver version. */
#define FSL_LPSPI_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 4, 1))
/*@}*/
/*!
* @brief Forward declaration of the _lpspi_master_edma_handle typedefs.
*/
typedef struct _lpspi_master_edma_handle lpspi_master_edma_handle_t;
/*!
* @brief Forward declaration of the _lpspi_slave_edma_handle typedefs.
*/
typedef struct _lpspi_slave_edma_handle lpspi_slave_edma_handle_t;
/*!
* @brief Completion callback function pointer type.
*
* @param base LPSPI peripheral base address.
* @param handle Pointer to the handle for the LPSPI master.
* @param status Success or error code describing whether the transfer completed.
* @param userData Arbitrary pointer-dataSized value passed from the application.
*/
typedef void (*lpspi_master_edma_transfer_callback_t)(LPSPI_Type *base,
lpspi_master_edma_handle_t *handle,
status_t status,
void *userData);
/*!
* @brief Completion callback function pointer type.
*
* @param base LPSPI peripheral base address.
* @param handle Pointer to the handle for the LPSPI slave.
* @param status Success or error code describing whether the transfer completed.
* @param userData Arbitrary pointer-dataSized value passed from the application.
*/
typedef void (*lpspi_slave_edma_transfer_callback_t)(LPSPI_Type *base,
lpspi_slave_edma_handle_t *handle,
status_t status,
void *userData);
/*! @brief LPSPI master eDMA transfer handle structure used for transactional API. */
struct _lpspi_master_edma_handle
{
volatile bool isPcsContinuous; /*!< Is PCS continuous in transfer. */
volatile bool isByteSwap; /*!< A flag that whether should byte swap. */
volatile uint8_t fifoSize; /*!< FIFO dataSize. */
volatile uint8_t rxWatermark; /*!< Rx watermark. */
volatile uint8_t bytesEachWrite; /*!< Bytes for each write TDR. */
volatile uint8_t bytesEachRead; /*!< Bytes for each read RDR. */
volatile uint8_t bytesLastRead; /*!< Bytes for last read RDR. */
volatile bool isThereExtraRxBytes; /*!< Is there extra RX byte. */
uint8_t *volatile txData; /*!< Send buffer. */
uint8_t *volatile rxData; /*!< Receive buffer. */
volatile size_t txRemainingByteCount; /*!< Number of bytes remaining to send.*/
volatile size_t rxRemainingByteCount; /*!< Number of bytes remaining to receive.*/
volatile uint32_t writeRegRemainingTimes; /*!< Write TDR register remaining times. */
volatile uint32_t readRegRemainingTimes; /*!< Read RDR register remaining times. */
uint32_t totalByteCount; /*!< Number of transfer bytes*/
uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
uint32_t transmitCommand; /*!< Used to write TCR for DMA purpose.*/
volatile uint8_t state; /*!< LPSPI transfer state , _lpspi_transfer_state.*/
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
lpspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */
void *userData; /*!< Callback user data. */
edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg buff*/
edma_tcd_t lpspiSoftwareTCD[3]; /*!<SoftwareTCD, internal used*/
};
/*! @brief LPSPI slave eDMA transfer handle structure used for transactional API.*/
struct _lpspi_slave_edma_handle
{
volatile bool isByteSwap; /*!< A flag that whether should byte swap. */
volatile uint8_t fifoSize; /*!< FIFO dataSize. */
volatile uint8_t rxWatermark; /*!< Rx watermark. */
volatile uint8_t bytesEachWrite; /*!< Bytes for each write TDR. */
volatile uint8_t bytesEachRead; /*!< Bytes for each read RDR. */
volatile uint8_t bytesLastRead; /*!< Bytes for last read RDR. */
volatile bool isThereExtraRxBytes; /*!< Is there extra RX byte. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
uint8_t *volatile txData; /*!< Send buffer. */
uint8_t *volatile rxData; /*!< Receive buffer. */
volatile size_t txRemainingByteCount; /*!< Number of bytes remaining to send.*/
volatile size_t rxRemainingByteCount; /*!< Number of bytes remaining to receive.*/
volatile uint32_t writeRegRemainingTimes; /*!< Write TDR register remaining times. */
volatile uint32_t readRegRemainingTimes; /*!< Read RDR register remaining times. */
uint32_t totalByteCount; /*!< Number of transfer bytes*/
uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
volatile uint8_t state; /*!< LPSPI transfer state.*/
uint32_t errorCount; /*!< Error count for slave transfer.*/
lpspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
void *userData; /*!< Callback user data. */
edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/
edma_tcd_t lpspiSoftwareTCD[2]; /*!<SoftwareTCD, internal used*/
};
/***********************************************************************************************************************
* API
**********************************************************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*Transactional APIs*/
/*!
* @brief Initializes the LPSPI master eDMA handle.
*
* This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs. Usually, for a
* specified LPSPI instance, call this API once to get the initialized handle.
*
* Note that the LPSPI eDMA has a separated (Rx and Tx as two sources) or shared (Rx and Tx are the same source) DMA
* request source.
* (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
* Tx DMAMUX source for edmaTxDataToTxRegHandle.
* (2) For a shared DMA request source, enable and set the Rx/Tx DMAMUX source for edmaRxRegToRxDataHandle.
*
* @param base LPSPI peripheral base address.
* @param handle LPSPI handle pointer to lpspi_master_edma_handle_t.
* @param callback LPSPI callback.
* @param userData callback function parameter.
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
* @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
*/
void LPSPI_MasterTransferCreateHandleEDMA(LPSPI_Type *base,
lpspi_master_edma_handle_t *handle,
lpspi_master_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *edmaRxRegToRxDataHandle,
edma_handle_t *edmaTxDataToTxRegHandle);
/*!
* @brief LPSPI master transfer data using eDMA.
*
* This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
* is transferred, the callback function is called.
*
* Note:
* The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
* For bytesPerFrame greater than 4:
* The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
* Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to lpspi_transfer_t structure.
* @return status of status_t.
*/
status_t LPSPI_MasterTransferEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer);
/*!
* @brief LPSPI master config transfer parameter while using eDMA.
*
* This function is preparing to transfer data using eDMA, work with LPSPI_MasterTransferEDMALite.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
* @param configFlags transfer configuration flags. @ref _lpspi_transfer_config_flag_for_master.
* @return Indicates whether LPSPI master transfer was successful or not.
* @retval kStatus_Success Execution successfully.
* @retval kStatus_LPSPI_Busy The LPSPI device is busy.
*/
status_t LPSPI_MasterTransferPrepareEDMALite(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, uint32_t configFlags);
/*!
* @brief LPSPI master transfer data using eDMA without configs.
*
* This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
* is transferred, the callback function is called.
*
* Note:
* This API is only for transfer through DMA without configuration.
* Before calling this API, you must call LPSPI_MasterTransferPrepareEDMALite to configure it once.
* The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
* For bytesPerFrame greater than 4:
* The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
* Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to lpspi_transfer_t structure, config field is not uesed.
* @return Indicates whether LPSPI master transfer was successful or not.
* @retval kStatus_Success Execution successfully.
* @retval kStatus_LPSPI_Busy The LPSPI device is busy.
* @retval kStatus_InvalidArgument The transfer structure is invalid.
*/
status_t LPSPI_MasterTransferEDMALite(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer);
/*!
* @brief LPSPI master aborts a transfer which is using eDMA.
*
* This function aborts a transfer which is using eDMA.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
*/
void LPSPI_MasterTransferAbortEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle);
/*!
* @brief Gets the master eDMA transfer remaining bytes.
*
* This function gets the master eDMA transfer remaining bytes.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the EDMA transaction.
* @return status of status_t.
*/
status_t LPSPI_MasterTransferGetCountEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, size_t *count);
/*!
* @brief Initializes the LPSPI slave eDMA handle.
*
* This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs. Usually, for a
* specified LPSPI instance, call this API once to get the initialized handle.
*
* Note that LPSPI eDMA has a separated (Rx and Tx as two sources) or shared (Rx and Tx as the same source) DMA request
* source.
*
* (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
* Tx DMAMUX source for edmaTxDataToTxRegHandle.
* (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle .
*
* @param base LPSPI peripheral base address.
* @param handle LPSPI handle pointer to lpspi_slave_edma_handle_t.
* @param callback LPSPI callback.
* @param userData callback function parameter.
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
* @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
*/
void LPSPI_SlaveTransferCreateHandleEDMA(LPSPI_Type *base,
lpspi_slave_edma_handle_t *handle,
lpspi_slave_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *edmaRxRegToRxDataHandle,
edma_handle_t *edmaTxDataToTxRegHandle);
/*!
* @brief LPSPI slave transfers data using eDMA.
*
* This function transfers data using eDMA. This is a non-blocking function, which return right away. When all data
* is transferred, the callback function is called.
*
* Note:
* The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
* For bytesPerFrame greater than 4:
* The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
* Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to lpspi_transfer_t structure.
* @return status of status_t.
*/
status_t LPSPI_SlaveTransferEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, lpspi_transfer_t *transfer);
/*!
* @brief LPSPI slave aborts a transfer which is using eDMA.
*
* This function aborts a transfer which is using eDMA.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
*/
void LPSPI_SlaveTransferAbortEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle);
/*!
* @brief Gets the slave eDMA transfer remaining bytes.
*
* This function gets the slave eDMA transfer remaining bytes.
*
* @param base LPSPI peripheral base address.
* @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the eDMA transaction.
* @return status of status_t.
*/
status_t LPSPI_SlaveTransferGetCountEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, size_t *count);
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /*_FSL_LPSPI_EDMA_H_*/

View File

@ -0,0 +1,173 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_lptmr.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lptmr"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
#if defined(LPTMR_CLOCKS)
/*!
* @brief Gets the instance from the base address to be used to gate or ungate the module clock
*
* @param base LPTMR peripheral base address
*
* @return The LPTMR instance
*/
static uint32_t LPTMR_GetInstance(LPTMR_Type *base);
#endif /* LPTMR_CLOCKS */
/*******************************************************************************
* Variables
******************************************************************************/
#if defined(LPTMR_CLOCKS)
/*! @brief Pointers to LPTMR bases for each instance. */
static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to LPTMR clocks for each instance. */
static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS;
#if defined(LPTMR_PERIPH_CLOCKS)
/* Array of LPTMR functional clock name. */
static const clock_ip_name_t s_lptmrPeriphClocks[] = LPTMR_PERIPH_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPTMR_CLOCKS */
/*******************************************************************************
* Code
******************************************************************************/
#if defined(LPTMR_CLOCKS)
static uint32_t LPTMR_GetInstance(LPTMR_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_lptmrBases); instance++)
{
if (s_lptmrBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_lptmrBases));
return instance;
}
#endif /* LPTMR_CLOCKS */
/*!
* brief Ungates the LPTMR clock and configures the peripheral for a basic operation.
*
* note This API should be called at the beginning of the application using the LPTMR driver.
*
* param base LPTMR peripheral base address
* param config A pointer to the LPTMR configuration structure.
*/
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config)
{
assert(NULL != config);
#if defined(LPTMR_CLOCKS)
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPTMR_GetInstance(base);
/* Ungate the LPTMR clock*/
CLOCK_EnableClock(s_lptmrClocks[instance]);
#if defined(LPTMR_PERIPH_CLOCKS)
CLOCK_EnableClock(s_lptmrPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPTMR_CLOCKS */
/* Configure the timers operation mode and input pin setup */
base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) |
LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect));
/* Configure the prescale value and clock source */
base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) |
LPTMR_PSR_PCS(config->prescalerClockSource));
}
/*!
* brief Gates the LPTMR clock.
*
* param base LPTMR peripheral base address
*/
void LPTMR_Deinit(LPTMR_Type *base)
{
/* Disable the LPTMR and reset the internal logic */
base->CSR &= ~LPTMR_CSR_TEN_MASK;
#if defined(LPTMR_CLOCKS)
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPTMR_GetInstance(base);
/* Gate the LPTMR clock*/
CLOCK_DisableClock(s_lptmrClocks[instance]);
#if defined(LPTMR_PERIPH_CLOCKS)
CLOCK_DisableClock(s_lptmrPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* LPTMR_CLOCKS */
}
/*!
* brief Fills in the LPTMR configuration structure with default settings.
*
* The default values are as follows.
* code
* config->timerMode = kLPTMR_TimerModeTimeCounter;
* config->pinSelect = kLPTMR_PinSelectInput_0;
* config->pinPolarity = kLPTMR_PinPolarityActiveHigh;
* config->enableFreeRunning = false;
* config->bypassPrescaler = true;
* config->prescalerClockSource = kLPTMR_PrescalerClock_1;
* config->value = kLPTMR_Prescale_Glitch_0;
* endcode
* param config A pointer to the LPTMR configuration structure.
*/
void LPTMR_GetDefaultConfig(lptmr_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
/* Use time counter mode */
config->timerMode = kLPTMR_TimerModeTimeCounter;
/* Use input 0 as source in pulse counter mode */
config->pinSelect = kLPTMR_PinSelectInput_0;
/* Pulse input pin polarity is active-high */
config->pinPolarity = kLPTMR_PinPolarityActiveHigh;
/* Counter resets whenever TCF flag is set */
config->enableFreeRunning = false;
/* Bypass the prescaler */
config->bypassPrescaler = true;
/* LPTMR clock source */
#if !(defined(FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT) && \
FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT)
config->prescalerClockSource = kLPTMR_PrescalerClock_1;
#else
config->prescalerClockSource = kLPTMR_PrescalerClock_0;
#endif /* FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT */
/* Divide the prescaler clock by 2 */
config->value = kLPTMR_Prescale_Glitch_0;
}

View File

@ -0,0 +1,374 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_LPTMR_H_
#define _FSL_LPTMR_H_
#include "fsl_common.h"
/*!
* @addtogroup lptmr
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1 */
/*@}*/
/*! @brief LPTMR pin selection used in pulse counter mode.*/
typedef enum _lptmr_pin_select
{
kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */
kLPTMR_PinSelectInput_1 = 0x1U, /*!< Pulse counter input 1 is selected */
kLPTMR_PinSelectInput_2 = 0x2U, /*!< Pulse counter input 2 is selected */
kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */
} lptmr_pin_select_t;
/*! @brief LPTMR pin polarity used in pulse counter mode.*/
typedef enum _lptmr_pin_polarity
{
kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */
kLPTMR_PinPolarityActiveLow = 0x1U /*!< Pulse Counter input source is active-low */
} lptmr_pin_polarity_t;
/*! @brief LPTMR timer mode selection.*/
typedef enum _lptmr_timer_mode
{
kLPTMR_TimerModeTimeCounter = 0x0U, /*!< Time Counter mode */
kLPTMR_TimerModePulseCounter = 0x1U /*!< Pulse Counter mode */
} lptmr_timer_mode_t;
/*! @brief LPTMR prescaler/glitch filter values*/
typedef enum _lptmr_prescaler_glitch_value
{
kLPTMR_Prescale_Glitch_0 = 0x0U, /*!< Prescaler divide 2, glitch filter does not support this setting */
kLPTMR_Prescale_Glitch_1 = 0x1U, /*!< Prescaler divide 4, glitch filter 2 */
kLPTMR_Prescale_Glitch_2 = 0x2U, /*!< Prescaler divide 8, glitch filter 4 */
kLPTMR_Prescale_Glitch_3 = 0x3U, /*!< Prescaler divide 16, glitch filter 8 */
kLPTMR_Prescale_Glitch_4 = 0x4U, /*!< Prescaler divide 32, glitch filter 16 */
kLPTMR_Prescale_Glitch_5 = 0x5U, /*!< Prescaler divide 64, glitch filter 32 */
kLPTMR_Prescale_Glitch_6 = 0x6U, /*!< Prescaler divide 128, glitch filter 64 */
kLPTMR_Prescale_Glitch_7 = 0x7U, /*!< Prescaler divide 256, glitch filter 128 */
kLPTMR_Prescale_Glitch_8 = 0x8U, /*!< Prescaler divide 512, glitch filter 256 */
kLPTMR_Prescale_Glitch_9 = 0x9U, /*!< Prescaler divide 1024, glitch filter 512*/
kLPTMR_Prescale_Glitch_10 = 0xAU, /*!< Prescaler divide 2048 glitch filter 1024 */
kLPTMR_Prescale_Glitch_11 = 0xBU, /*!< Prescaler divide 4096, glitch filter 2048 */
kLPTMR_Prescale_Glitch_12 = 0xCU, /*!< Prescaler divide 8192, glitch filter 4096 */
kLPTMR_Prescale_Glitch_13 = 0xDU, /*!< Prescaler divide 16384, glitch filter 8192 */
kLPTMR_Prescale_Glitch_14 = 0xEU, /*!< Prescaler divide 32768, glitch filter 16384 */
kLPTMR_Prescale_Glitch_15 = 0xFU /*!< Prescaler divide 65536, glitch filter 32768 */
} lptmr_prescaler_glitch_value_t;
/*!
* @brief LPTMR prescaler/glitch filter clock select.
* @note Clock connections are SoC-specific
*/
typedef enum _lptmr_prescaler_clock_select
{
kLPTMR_PrescalerClock_0 = 0x0U, /*!< Prescaler/glitch filter clock 0 selected. */
#if !(defined(FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT) && \
FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT)
kLPTMR_PrescalerClock_1 = 0x1U, /*!< Prescaler/glitch filter clock 1 selected. */
#endif /* FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_1_SUPPORT */
kLPTMR_PrescalerClock_2 = 0x2U, /*!< Prescaler/glitch filter clock 2 selected. */
#if !(defined(FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_3_SUPPORT) && \
FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_3_SUPPORT)
kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */
#endif /* FSL_FEATURE_LPTMR_HAS_NO_PRESCALER_CLOCK_SOURCE_3_SUPPORT */
} lptmr_prescaler_clock_select_t;
/*! @brief List of the LPTMR interrupts */
typedef enum _lptmr_interrupt_enable
{
kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */
} lptmr_interrupt_enable_t;
/*! @brief List of the LPTMR status flags */
typedef enum _lptmr_status_flags
{
kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */
} lptmr_status_flags_t;
/*!
* @brief LPTMR config structure
*
* This structure holds the configuration settings for the LPTMR peripheral. To initialize this
* structure to reasonable defaults, call the LPTMR_GetDefaultConfig() function and pass a
* pointer to your configuration structure instance.
*
* The configuration struct can be made constant so it resides in flash.
*/
typedef struct _lptmr_config
{
lptmr_timer_mode_t timerMode; /*!< Time counter mode or pulse counter mode */
lptmr_pin_select_t pinSelect; /*!< LPTMR pulse input pin select; used only in pulse counter mode */
lptmr_pin_polarity_t pinPolarity; /*!< LPTMR pulse input pin polarity; used only in pulse counter mode */
bool enableFreeRunning; /*!< True: enable free running, counter is reset on overflow
False: counter is reset when the compare flag is set */
bool bypassPrescaler; /*!< True: bypass prescaler; false: use clock from prescaler */
lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */
lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */
} lptmr_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the LPTMR clock and configures the peripheral for a basic operation.
*
* @note This API should be called at the beginning of the application using the LPTMR driver.
*
* @param base LPTMR peripheral base address
* @param config A pointer to the LPTMR configuration structure.
*/
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config);
/*!
* @brief Gates the LPTMR clock.
*
* @param base LPTMR peripheral base address
*/
void LPTMR_Deinit(LPTMR_Type *base);
/*!
* @brief Fills in the LPTMR configuration structure with default settings.
*
* The default values are as follows.
* @code
* config->timerMode = kLPTMR_TimerModeTimeCounter;
* config->pinSelect = kLPTMR_PinSelectInput_0;
* config->pinPolarity = kLPTMR_PinPolarityActiveHigh;
* config->enableFreeRunning = false;
* config->bypassPrescaler = true;
* config->prescalerClockSource = kLPTMR_PrescalerClock_1;
* config->value = kLPTMR_Prescale_Glitch_0;
* @endcode
* @param config A pointer to the LPTMR configuration structure.
*/
void LPTMR_GetDefaultConfig(lptmr_config_t *config);
/*! @}*/
/*!
* @name Interrupt Interface
* @{
*/
/*!
* @brief Enables the selected LPTMR interrupts.
*
* @param base LPTMR peripheral base address
* @param mask The interrupts to enable. This is a logical OR of members of the
* enumeration ::lptmr_interrupt_enable_t
*/
static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask)
{
uint32_t reg = base->CSR;
/* Clear the TCF bit so that we don't clear this w1c bit when writing back */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg |= mask;
base->CSR = reg;
}
/*!
* @brief Disables the selected LPTMR interrupts.
*
* @param base LPTMR peripheral base address
* @param mask The interrupts to disable. This is a logical OR of members of the
* enumeration ::lptmr_interrupt_enable_t.
*/
static inline void LPTMR_DisableInterrupts(LPTMR_Type *base, uint32_t mask)
{
uint32_t reg = base->CSR;
/* Clear the TCF bit so that we don't clear this w1c bit when writing back */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg &= ~mask;
base->CSR = reg;
}
/*!
* @brief Gets the enabled LPTMR interrupts.
*
* @param base LPTMR peripheral base address
*
* @return The enabled interrupts. This is the logical OR of members of the
* enumeration ::lptmr_interrupt_enable_t
*/
static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type *base)
{
return (base->CSR & LPTMR_CSR_TIE_MASK);
}
/*! @}*/
#if defined(FSL_FEATURE_LPTMR_HAS_CSR_TDRE) && (FSL_FEATURE_LPTMR_HAS_CSR_TDRE)
/*!
* @brief Enable or disable timer DMA request
*
* @param base base LPTMR peripheral base address
* @param enable Switcher of timer DMA feature. "true" means to enable, "false" means to disable.
*/
static inline void LPTMR_EnableTimerDMA(LPTMR_Type *base, bool enable)
{
if (enable)
{
base->CSR |= LPTMR_CSR_TDRE_MASK;
}
else
{
base->CSR &= ~(LPTMR_CSR_TDRE_MASK);
}
}
#endif /* FSL_FEATURE_LPTMR_HAS_CSR_TDRE */
/*!
* @name Status Interface
* @{
*/
/*!
* @brief Gets the LPTMR status flags.
*
* @param base LPTMR peripheral base address
*
* @return The status flags. This is the logical OR of members of the
* enumeration ::lptmr_status_flags_t
*/
static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type *base)
{
return (base->CSR & LPTMR_CSR_TCF_MASK);
}
/*!
* @brief Clears the LPTMR status flags.
*
* @param base LPTMR peripheral base address
* @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::lptmr_status_flags_t.
*/
static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask)
{
base->CSR |= mask;
}
/*! @}*/
/*!
* @name Read and write the timer period
* @{
*/
/*!
* @brief Sets the timer period in units of count.
*
* Timers counts from 0 until it equals the count value set here. The count value is written to
* the CMR register.
*
* @note
* 1. The TCF flag is set with the CNR equals the count provided here and then increments.
* 2. Call the utility macros provided in the fsl_common.h to convert to ticks.
*
* @param base LPTMR peripheral base address
* @param ticks A timer period in units of ticks, which should be equal or greater than 1.
*/
static inline void LPTMR_SetTimerPeriod(LPTMR_Type *base, uint32_t ticks)
{
assert(ticks > 0U);
base->CMR = LPTMR_CMR_COMPARE(ticks - 1U);
}
/*!
* @brief Reads the current timer counting value.
*
* This function returns the real-time timer counting value in a range from 0 to a
* timer period.
*
* @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec.
*
* @param base LPTMR peripheral base address
*
* @return The current counter value in ticks
*/
static inline uint32_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base)
{
/* Must first write any value to the CNR. This synchronizes and registers the current value
* of the CNR into a temporary register which can then be read
*/
base->CNR = 0U;
return (uint32_t)((base->CNR & LPTMR_CNR_COUNTER_MASK) >> LPTMR_CNR_COUNTER_SHIFT);
}
/*! @}*/
/*!
* @name Timer Start and Stop
* @{
*/
/*!
* @brief Starts the timer.
*
* After calling this function, the timer counts up to the CMR register value.
* Each time the timer reaches the CMR value and then increments, it generates a
* trigger pulse and sets the timeout interrupt flag. An interrupt is also
* triggered if the timer interrupt is enabled.
*
* @param base LPTMR peripheral base address
*/
static inline void LPTMR_StartTimer(LPTMR_Type *base)
{
uint32_t reg = base->CSR;
/* Clear the TCF bit to avoid clearing the w1c bit when writing back. */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg |= LPTMR_CSR_TEN_MASK;
base->CSR = reg;
}
/*!
* @brief Stops the timer.
*
* This function stops the timer and resets the timer's counter register.
*
* @param base LPTMR peripheral base address
*/
static inline void LPTMR_StopTimer(LPTMR_Type *base)
{
uint32_t reg = base->CSR;
/* Clear the TCF bit to avoid clearing the w1c bit when writing back. */
reg &= ~(LPTMR_CSR_TCF_MASK);
reg &= ~LPTMR_CSR_TEN_MASK;
base->CSR = reg;
}
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_LPTMR_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,522 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_lpuart_edma.h"
/*
* $Coverage Justification Reference$
*
* $Justification fsl_lpuart_edma_c_ref_1$
* The EDMA handle is only used by the LPUART EDMA driver, with the LPUART EDMA driver workflow,
* the callback is only called when EDMA transfer done.
*
* $Justification fsl_lpuart_edma_c_ref_2$
* This function only handles the kLPUART_TransmissionCompleteFlag event.
*
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpuart_edma"
#endif
/*<! Structure definition for lpuart_edma_private_handle_t. The structure is private. */
typedef struct _lpuart_edma_private_handle
{
LPUART_Type *base;
lpuart_edma_handle_t *handle;
} lpuart_edma_private_handle_t;
/* LPUART EDMA transfer handle. */
enum
{
kLPUART_TxIdle, /* TX idle. */
kLPUART_TxBusy, /* TX busy. */
kLPUART_RxIdle, /* RX idle. */
kLPUART_RxBusy /* RX busy. */
};
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of LPUART handle. */
#if (defined(LPUART12))
#define LPUART_HANDLE_ARRAY_SIZE 13
#else /* LPUART12 */
#if (defined(LPUART11))
#define LPUART_HANDLE_ARRAY_SIZE 12
#else /* LPUART11 */
#if (defined(LPUART10))
#define LPUART_HANDLE_ARRAY_SIZE 11
#else /* LPUART10 */
#if (defined(LPUART9))
#define LPUART_HANDLE_ARRAY_SIZE 10
#else /* LPUART9 */
#if (defined(LPUART8))
#define LPUART_HANDLE_ARRAY_SIZE 9
#else /* LPUART8 */
#if (defined(LPUART7))
#define LPUART_HANDLE_ARRAY_SIZE 8
#else /* LPUART7 */
#if (defined(LPUART6))
#define LPUART_HANDLE_ARRAY_SIZE 7
#else /* LPUART6 */
#if (defined(LPUART5))
#define LPUART_HANDLE_ARRAY_SIZE 6
#else /* LPUART5 */
#if (defined(LPUART4))
#define LPUART_HANDLE_ARRAY_SIZE 5
#else /* LPUART4 */
#if (defined(LPUART3))
#define LPUART_HANDLE_ARRAY_SIZE 4
#else /* LPUART3 */
#if (defined(LPUART2))
#define LPUART_HANDLE_ARRAY_SIZE 3
#else /* LPUART2 */
#if (defined(LPUART1))
#define LPUART_HANDLE_ARRAY_SIZE 2
#else /* LPUART1 */
#if (defined(LPUART0))
#define LPUART_HANDLE_ARRAY_SIZE 1
#else /* LPUART0 */
#define LPUART_HANDLE_ARRAY_SIZE FSL_FEATURE_SOC_LPUART_COUNT
#endif /* LPUART 0 */
#endif /* LPUART 1 */
#endif /* LPUART 2 */
#endif /* LPUART 3 */
#endif /* LPUART 4 */
#endif /* LPUART 5 */
#endif /* LPUART 6 */
#endif /* LPUART 7 */
#endif /* LPUART 8 */
#endif /* LPUART 9 */
#endif /* LPUART 10 */
#endif /* LPUART 11 */
#endif /* LPUART 12 */
/*<! Private handle only used for internally. */
static lpuart_edma_private_handle_t s_lpuartEdmaPrivateHandle[LPUART_HANDLE_ARRAY_SIZE];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief LPUART EDMA send finished callback function.
*
* This function is called when LPUART EDMA send finished. It disables the LPUART
* TX EDMA request and sends @ref kStatus_LPUART_TxIdle to LPUART callback.
*
* @param handle The EDMA handle.
* @param param Callback function parameter.
*/
static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
/*!
* @brief LPUART EDMA receive finished callback function.
*
* This function is called when LPUART EDMA receive finished. It disables the LPUART
* RX EDMA request and sends @ref kStatus_LPUART_RxIdle to LPUART callback.
*
* @param handle The EDMA handle.
* @param param Callback function parameter.
*/
static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
/*******************************************************************************
* Code
******************************************************************************/
static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
assert(NULL != param);
lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param;
/* Avoid the warning for unused variables. */
handle = handle;
tcds = tcds;
/*
* $Branch Coverage Justification$
* $ref fsl_lpuart_edma_c_ref_1$
*/
if (transferDone)
{
/* Disable LPUART TX EDMA. */
LPUART_EnableTxDMA(lpuartPrivateHandle->base, false);
/* Stop transfer. */
EDMA_AbortTransfer(handle);
/* Enable tx complete interrupt */
LPUART_EnableInterrupts(lpuartPrivateHandle->base, (uint32_t)kLPUART_TransmissionCompleteInterruptEnable);
}
}
static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
assert(NULL != param);
lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param;
/* Avoid warning for unused parameters. */
handle = handle;
tcds = tcds;
/*
* $Branch Coverage Justification$
* $ref fsl_lpuart_edma_c_ref_1$
*/
if (transferDone)
{
/* Disable transfer. */
LPUART_TransferAbortReceiveEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle);
if (NULL != lpuartPrivateHandle->handle->callback)
{
lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle,
kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData);
}
}
}
/*!
* brief Initializes the LPUART handle which is used in transactional functions.
*
* note This function disables all LPUART interrupts.
*
* param base LPUART peripheral base address.
* param handle Pointer to lpuart_edma_handle_t structure.
* param callback Callback function.
* param userData User data.
* param txEdmaHandle User requested DMA handle for TX DMA transfer.
* param rxEdmaHandle User requested DMA handle for RX DMA transfer.
*/
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle)
{
assert(NULL != handle);
uint32_t instance = LPUART_GetInstance(base);
s_lpuartEdmaPrivateHandle[instance].base = base;
s_lpuartEdmaPrivateHandle[instance].handle = handle;
(void)memset(handle, 0, sizeof(*handle));
handle->rxState = (uint8_t)kLPUART_RxIdle;
handle->txState = (uint8_t)kLPUART_TxIdle;
handle->rxEdmaHandle = rxEdmaHandle;
handle->txEdmaHandle = txEdmaHandle;
handle->callback = callback;
handle->userData = userData;
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
/* Note:
Take care of the RX FIFO, EDMA request only assert when received bytes
equal or more than RX water mark, there is potential issue if RX water
mark larger than 1.
For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
5 bytes are received. the last byte will be saved in FIFO but not trigger
EDMA transfer because the water mark is 2.
*/
if (NULL != rxEdmaHandle)
{
base->WATER &= (~LPUART_WATER_RXWATER_MASK);
}
#endif
/* Save the handle in global variables to support the double weak mechanism. */
s_lpuartHandle[instance] = handle;
/* Set LPUART_TransferEdmaHandleIRQ as DMA IRQ handler */
s_lpuartIsr[instance] = LPUART_TransferEdmaHandleIRQ;
/* Disable all LPUART internal interrupts */
LPUART_DisableInterrupts(base, (uint32_t)kLPUART_AllInterruptEnable);
/* Enable interrupt in NVIC. */
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
(void)EnableIRQ(s_lpuartTxIRQ[instance]);
#else
(void)EnableIRQ(s_lpuartIRQ[instance]);
#endif
/* Configure TX. */
if (NULL != txEdmaHandle)
{
EDMA_SetCallback(handle->txEdmaHandle, LPUART_SendEDMACallback, &s_lpuartEdmaPrivateHandle[instance]);
}
/* Configure RX. */
if (NULL != rxEdmaHandle)
{
EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_lpuartEdmaPrivateHandle[instance]);
}
}
/*!
* brief Sends data using eDMA.
*
* This function sends data using eDMA. This is a non-blocking function, which returns
* right away. When all data is sent, the send callback function is called.
*
* param base LPUART peripheral base address.
* param handle LPUART handle pointer.
* param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t.
* retval kStatus_Success if succeed, others failed.
* retval kStatus_LPUART_TxBusy Previous transfer on going.
* retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
{
assert(NULL != handle);
assert(NULL != handle->txEdmaHandle);
assert(NULL != xfer);
assert(NULL != xfer->data);
assert(0U != xfer->dataSize);
edma_transfer_config_t xferConfig;
status_t status;
/* If previous TX not finished. */
if ((uint8_t)kLPUART_TxBusy == handle->txState)
{
status = kStatus_LPUART_TxBusy;
}
else
{
handle->txState = (uint8_t)kLPUART_TxBusy;
handle->txDataSizeAll = xfer->dataSize;
/* Prepare transfer. */
EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t),
(void *)(uint32_t *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t),
xfer->dataSize, kEDMA_MemoryToPeripheral);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = (uint8_t)sizeof(uint8_t);
/* Submit transfer. */
if (kStatus_Success !=
EDMA_SubmitTransfer(handle->txEdmaHandle, (const edma_transfer_config_t *)(uint32_t)&xferConfig))
{
return kStatus_Fail;
}
EDMA_StartTransfer(handle->txEdmaHandle);
/* Enable LPUART TX EDMA. */
LPUART_EnableTxDMA(base, true);
status = kStatus_Success;
}
return status;
}
/*!
* brief Receives data using eDMA.
*
* This function receives data using eDMA. This is non-blocking function, which returns
* right away. When all data is received, the receive callback function is called.
*
* param base LPUART peripheral base address.
* param handle Pointer to lpuart_edma_handle_t structure.
* param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t.
* retval kStatus_Success if succeed, others fail.
* retval kStatus_LPUART_RxBusy Previous transfer ongoing.
* retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
{
assert(NULL != handle);
assert(NULL != handle->rxEdmaHandle);
assert(NULL != xfer);
assert(NULL != xfer->data);
assert(0U != xfer->dataSize);
edma_transfer_config_t xferConfig;
status_t status;
/* If previous RX not finished. */
if ((uint8_t)kLPUART_RxBusy == handle->rxState)
{
status = kStatus_LPUART_RxBusy;
}
else
{
handle->rxState = (uint8_t)kLPUART_RxBusy;
handle->rxDataSizeAll = xfer->dataSize;
/* Prepare transfer. */
EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t),
xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = (uint8_t)sizeof(uint8_t);
/* Submit transfer. */
if (kStatus_Success !=
EDMA_SubmitTransfer(handle->rxEdmaHandle, (const edma_transfer_config_t *)(uint32_t)&xferConfig))
{
return kStatus_Fail;
}
EDMA_StartTransfer(handle->rxEdmaHandle);
/* Enable LPUART RX EDMA. */
LPUART_EnableRxDMA(base, true);
status = kStatus_Success;
}
return status;
}
/*!
* brief Aborts the sent data using eDMA.
*
* This function aborts the sent data using eDMA.
*
* param base LPUART peripheral base address.
* param handle Pointer to lpuart_edma_handle_t structure.
*/
void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
{
assert(NULL != handle);
assert(NULL != handle->txEdmaHandle);
/* Disable LPUART TX EDMA. */
LPUART_EnableTxDMA(base, false);
/* Stop transfer. */
EDMA_AbortTransfer(handle->txEdmaHandle);
handle->txState = (uint8_t)kLPUART_TxIdle;
}
/*!
* brief Aborts the received data using eDMA.
*
* This function aborts the received data using eDMA.
*
* param base LPUART peripheral base address.
* param handle Pointer to lpuart_edma_handle_t structure.
*/
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
{
assert(NULL != handle);
assert(NULL != handle->rxEdmaHandle);
/* Disable LPUART RX EDMA. */
LPUART_EnableRxDMA(base, false);
/* Stop transfer. */
EDMA_AbortTransfer(handle->rxEdmaHandle);
handle->rxState = (uint8_t)kLPUART_RxIdle;
}
/*!
* brief Gets the number of received bytes.
*
* This function gets the number of received bytes.
*
* param base LPUART peripheral base address.
* param handle LPUART handle pointer.
* param count Receive bytes count.
* retval kStatus_NoTransferInProgress No receive in progress.
* retval kStatus_InvalidArgument Parameter is invalid.
* retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
{
assert(NULL != handle);
assert(NULL != handle->rxEdmaHandle);
assert(NULL != count);
if ((uint8_t)kLPUART_RxIdle == handle->rxState)
{
return kStatus_NoTransferInProgress;
}
*count = handle->rxDataSizeAll -
((uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel));
return kStatus_Success;
}
/*!
* brief Gets the number of bytes written to the LPUART TX register.
*
* This function gets the number of bytes written to the LPUART TX
* register by DMA.
*
* param base LPUART peripheral base address.
* param handle LPUART handle pointer.
* param count Send bytes count.
* retval kStatus_NoTransferInProgress No send in progress.
* retval kStatus_InvalidArgument Parameter is invalid.
* retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
{
assert(NULL != handle);
assert(NULL != handle->txEdmaHandle);
assert(NULL != count);
if ((uint8_t)kLPUART_TxIdle == handle->txState)
{
return kStatus_NoTransferInProgress;
}
*count = handle->txDataSizeAll -
((uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel));
return kStatus_Success;
}
/*!
* brief LPUART eDMA IRQ handle function.
*
* This function handles the LPUART tx complete IRQ request and invoke user callback.
* It is not set to static so that it can be used in user application.
* note This function is used as default IRQ handler by double weak mechanism.
* If user's specific IRQ handler is implemented, make sure this function is invoked in the handler.
*
* param base LPUART peripheral base address.
* param lpuartEdmaHandle LPUART handle pointer.
*/
void LPUART_TransferEdmaHandleIRQ(LPUART_Type *base, void *lpuartEdmaHandle)
{
assert(lpuartEdmaHandle != NULL);
/*
* $Branch Coverage Justification$
* $ref fsl_lpuart_edma_c_ref_2$
*/
if (((uint32_t)kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags(base)) != 0U)
{
lpuart_edma_handle_t *handle = (lpuart_edma_handle_t *)lpuartEdmaHandle;
/* Disable tx complete interrupt */
LPUART_DisableInterrupts(base, (uint32_t)kLPUART_TransmissionCompleteInterruptEnable);
handle->txState = (uint8_t)kLPUART_TxIdle;
if (handle->callback != NULL)
{
handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData);
}
}
}

View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_LPUART_EDMA_H_
#define _FSL_LPUART_EDMA_H_
#include "fsl_lpuart.h"
#include "fsl_edma.h"
/*!
* @addtogroup lpuart_edma_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPUART EDMA driver version. */
#define FSL_LPUART_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 6, 0))
/*@}*/
/* Forward declaration of the handle typedef. */
typedef struct _lpuart_edma_handle lpuart_edma_handle_t;
/*! @brief LPUART transfer callback function. */
typedef void (*lpuart_edma_transfer_callback_t)(LPUART_Type *base,
lpuart_edma_handle_t *handle,
status_t status,
void *userData);
/*!
* @brief LPUART eDMA handle
*/
struct _lpuart_edma_handle
{
lpuart_edma_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< LPUART callback function parameter.*/
size_t rxDataSizeAll; /*!< Size of the data to receive. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */
edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name eDMA transactional
* @{
*/
/*!
* @brief Initializes the LPUART handle which is used in transactional functions.
*
* @note This function disables all LPUART interrupts.
*
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_edma_handle_t structure.
* @param callback Callback function.
* @param userData User data.
* @param txEdmaHandle User requested DMA handle for TX DMA transfer.
* @param rxEdmaHandle User requested DMA handle for RX DMA transfer.
*/
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
/*!
* @brief Sends data using eDMA.
*
* This function sends data using eDMA. This is a non-blocking function, which returns
* right away. When all data is sent, the send callback function is called.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_LPUART_TxBusy Previous transfer on going.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer);
/*!
* @brief Receives data using eDMA.
*
* This function receives data using eDMA. This is non-blocking function, which returns
* right away. When all data is received, the receive callback function is called.
*
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_edma_handle_t structure.
* @param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t.
* @retval kStatus_Success if succeed, others fail.
* @retval kStatus_LPUART_RxBusy Previous transfer ongoing.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer);
/*!
* @brief Aborts the sent data using eDMA.
*
* This function aborts the sent data using eDMA.
*
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_edma_handle_t structure.
*/
void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle);
/*!
* @brief Aborts the received data using eDMA.
*
* This function aborts the received data using eDMA.
*
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_edma_handle_t structure.
*/
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle);
/*!
* @brief Gets the number of bytes written to the LPUART TX register.
*
* This function gets the number of bytes written to the LPUART TX
* register by DMA.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param count Send bytes count.
* @retval kStatus_NoTransferInProgress No send in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count);
/*!
* @brief Gets the number of received bytes.
*
* This function gets the number of received bytes.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param count Receive bytes count.
* @retval kStatus_NoTransferInProgress No receive in progress.
* @retval kStatus_InvalidArgument Parameter is invalid.
* @retval kStatus_Success Get successfully through the parameter \p count;
*/
status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count);
/*!
* @brief LPUART eDMA IRQ handle function.
*
* This function handles the LPUART tx complete IRQ request and invoke user callback.
* It is not set to static so that it can be used in user application.
* @note This function is used as default IRQ handler by double weak mechanism.
* If user's specific IRQ handler is implemented, make sure this function is invoked in the handler.
*
* @param base LPUART peripheral base address.
* @param lpuartEdmaHandle LPUART handle pointer.
*/
void LPUART_TransferEdmaHandleIRQ(LPUART_Type *base, void *lpuartEdmaHandle);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_LPUART_EDMA_H_ */

View File

@ -0,0 +1,394 @@
/*
* Copyright 2018-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_ostimer.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.ostimer"
#endif
#if defined(OSTIMER_RSTS)
#define OSTIMER_RESETS_ARRAY OSTIMER_RSTS
#endif
/* Typedef for interrupt handler. */
typedef void (*ostimer_isr_t)(OSTIMER_Type *base, ostimer_callback_t cb);
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the instance from the base address
*
* @param base OSTIMER peripheral base address
*
* @return The OSTIMER instance
*/
static uint32_t OSTIMER_GetInstance(OSTIMER_Type *base);
#if (defined(FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY) && FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY)
/* @brief Translate the value from gray-code to decimal by the Code Gray in SYSCTL.
*
* @param gray The gray value input.
*
* @return the decimal value.
*/
static uint64_t OSTIMER_GrayToDecimalbyCodeGray(uint64_t gray);
#endif /* FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY. */
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of OSTIMER handle. */
static ostimer_callback_t s_ostimerHandle[FSL_FEATURE_SOC_OSTIMER_COUNT];
/* Array of OSTIMER peripheral base address. */
static OSTIMER_Type *const s_ostimerBases[] = OSTIMER_BASE_PTRS;
/* Array of OSTIMER IRQ number. */
static const IRQn_Type s_ostimerIRQ[] = OSTIMER_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of OSTIMER clock name. */
static const clock_ip_name_t s_ostimerClock[] = OSTIMER_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* OSTIMER ISR for transactional APIs. */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
static ostimer_isr_t s_ostimerIsr = (ostimer_isr_t)DefaultISR;
#else
static ostimer_isr_t s_ostimerIsr;
#endif
#if defined(OSTIMER_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_ostimerResets[] = OSTIMER_RESETS_ARRAY;
#endif
/*******************************************************************************
* Code
******************************************************************************/
/* @brief Function for getting the instance number of OS timer. */
static uint32_t OSTIMER_GetInstance(OSTIMER_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_ostimerBases); instance++)
{
if (s_ostimerBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_ostimerBases));
return instance;
}
#if (defined(FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY) && FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY)
/* @brief Translate the value from gray-code to decimal by the Code Gray in SYSCTL.
*
* @param gray The gray value input.
*
* @return the decimal value.
*/
static uint64_t OSTIMER_GrayToDecimalbyCodeGray(uint64_t gray)
{
uint64_t decOut;
SYSCTL->CODE_GRAY_LSB = (uint32_t)(gray & 0xFFFFFFFFU);
SYSCTL->CODE_GRAY_MSB = (uint32_t)((gray >> 32U) & 0x3FFU); // limit to 42bits as OSevent timer
__NOP();
decOut = ((uint64_t)(SYSCTL->CODE_BIN_MSB) & 0x3FFU) << 32U;
decOut |= (uint64_t)(SYSCTL->CODE_BIN_LSB);
return decOut;
}
#endif /* FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY. */
/* @brief Translate the value from gray-code to decimal. */
/*
* @param gray The gray value input.
*
* @return the decimal value.
*/
uint64_t OSTIMER_GrayToDecimal(uint64_t gray)
{
#if (defined(FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY) && FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY)
return OSTIMER_GrayToDecimalbyCodeGray(gray);
#else
uint64_t temp = gray;
while (temp != 0U)
{
temp >>= 1U;
gray ^= temp;
}
return gray;
#endif /* FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY. */
}
/* @brief Enable the OSTIMER interrupt.
*
* After calling this function, the OSTIMER driver will enable/disable the IRQ and module interrupt enablement.
*
* @param base OSTIMER peripheral base address.
* @param enable enable/disable the IRQ and module interrupt enablement.
* - true: Disable the IRQ and module interrupt enablement.
* - false: Disable the IRQ and module interrupt enablement.
* @return none
*/
static void OSTIMER_EnableInterrupt(OSTIMER_Type *base, bool enable)
{
assert(NULL != base);
if (enable)
{
/* Enable the IRQ and module interrupt enablement. */
(void)EnableIRQ(s_ostimerIRQ[OSTIMER_GetInstance(base)]);
base->OSEVENT_CTRL |= OSTIMER_OSEVENT_CTRL_OSTIMER_INTENA_MASK;
}
else
{
/* Clear interrupt flag, disable the IRQ and module interrupt enablement. */
(void)DisableIRQ(s_ostimerIRQ[OSTIMER_GetInstance(base)]);
base->OSEVENT_CTRL &= ~OSTIMER_OSEVENT_CTRL_OSTIMER_INTENA_MASK; /* Clear interrupt flag by writing 1. */
}
}
/*!
* @brief Initializes an OSTIMER by turning it's clock on.
*
*/
void OSTIMER_Init(OSTIMER_Type *base)
{
assert(NULL != base);
uint32_t instance = OSTIMER_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if !(defined(FSL_FEATURE_PMC_HAS_NO_OSTIMER_REG) && FSL_FEATURE_PMC_HAS_NO_OSTIMER_REG)
/* Enable the OSTIMER 32k clock in PMC module. */
CLOCK_EnableOstimer32kClock();
#endif
/* Enable clock for OSTIMER. */
CLOCK_EnableClock(s_ostimerClock[instance]);
#if (defined(FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY) && FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY)
CLOCK_EnableClock(kCLOCK_Sysctl);
#endif /* FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY. */
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(OSTIMER_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_ostimerResets[OSTIMER_GetInstance(base)]);
#endif
}
/*!
* @brief Deinitializes a OSTIMER instance.
*
* This function shuts down OSTIMER clock
*
* @param base OSTIMER peripheral base address.
*/
void OSTIMER_Deinit(OSTIMER_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable clock for OSTIMER. */
CLOCK_DisableClock(s_ostimerClock[OSTIMER_GetInstance(base)]);
#if (defined(FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY) && FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY)
CLOCK_DisableClock(kCLOCK_Sysctl);
#endif /* FSL_FEATURE_SYSCTRL_HAS_CODE_GRAY. */
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* @brief Get OSTIMER status Flags.
*
* This returns the status flag.
* Currently, only match interrupt flag can be got.
*
* @param base OSTIMER peripheral base address.
* @return status register value
*/
uint32_t OSTIMER_GetStatusFlags(OSTIMER_Type *base)
{
return base->OSEVENT_CTRL & OSTIMER_OSEVENT_CTRL_OSTIMER_INTRFLAG_MASK;
}
/*!
* @brief Clear Status Interrupt Flags.
*
* This clears intr status flag.
* Currently, only match interrupt flag can be cleared.
*
* @param base OSTIMER peripheral base address.
* @param mask Clear bit mask.
* @return none
*/
void OSTIMER_ClearStatusFlags(OSTIMER_Type *base, uint32_t mask)
{
base->OSEVENT_CTRL |= mask;
}
/*!
* @brief Set the match raw value for OSTIMER.
*
* This function will set a match value for OSTIMER with an optional callback. And this callback
* will be called while the data in dedicated pair match register is equals to the value of central EVTIMER.
* Please note that, the data format is gray-code, if decimal data was desired, please using OSTIMER_SetMatchValue().
*
* @param base OSTIMER peripheral base address.
* @param count OSTIMER timer match value.(Value is gray-code format)
*
* @param cb OSTIMER callback (can be left as NULL if none, otherwise should be a void func(void)).
* @retval kStatus_Success - Set match raw value and enable interrupt Successfully.
* @retval kStatus_Fail - Set match raw value fail.
*/
status_t OSTIMER_SetMatchRawValue(OSTIMER_Type *base, uint64_t count, ostimer_callback_t cb)
{
#ifdef OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK
uint64_t decValueTimer;
#endif
status_t status;
uint64_t tmp = count;
uint32_t instance = OSTIMER_GetInstance(base);
/* Clear interrupt flag, disable the IRQ and module interrupt enablement. */
OSTIMER_EnableInterrupt(base, false);
s_ostimerIsr = OSTIMER_HandleIRQ;
s_ostimerHandle[instance] = cb;
/* Set the match value. */
base->MATCH_L = (uint32_t)tmp;
base->MATCH_H = (uint32_t)(tmp >> 32U);
#ifdef OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK
/* Workaround-2019-12-30:
* Since OSTimer's counter register is Gray-encoded, it would cost more time to write register. When EVTimer Match
* Write Ready bit is low, which means the previous match value has been updated successfully by that time, it is
* safe to reload (write) the Match Registers. Even if there is the RM comment that "In typical applications, it
* should not be necessary to test this bit", but we found the interruption would not be reported when the delta
* timer user added is smaller(IE: RT595 11us in 1MHz typical application) in release version." To prevent such
* issue from happening, we'd better wait for the match value to update successfully before enabling IRQ.
*/
while (0U != (base->OSEVENT_CTRL & OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK))
{
}
/* After the WR_RDY bit became low, we need to check whether current time goes ahead of the match value we set.
* (1) If current timer value has gone ahead of the match value, the interrupt will not be reported before 64-bit
* timer value over flow. We need to check whether the interrupt flag has been set or not: if yes, we will enable
* interrupt and return success; if not, we will return fail directly.
* (2) If current timer value has not gone ahead of match value, we will enable interrupt and return success.
*/
decValueTimer = OSTIMER_GetCurrentTimerValue(base);
if ((decValueTimer >= OSTIMER_GrayToDecimal(tmp)) &&
(0U == (base->OSEVENT_CTRL & (uint32_t)kOSTIMER_MatchInterruptFlag)))
{
status = kStatus_Fail;
}
else
#endif /* #ifdef OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK */
{
/* Enable the module interrupt enablement. */
OSTIMER_EnableInterrupt(base, true);
status = kStatus_Success;
}
return status;
}
/*!
* @brief Set the match value for OSTIMER.
*
* This function will set a match value for OSTIMER with an optional callback. And this callback
* will be called while the data in dedicated pair match register is equals to the value of central EVTIMER.
*
* @param base OSTIMER peripheral base address.
* @param count OSTIMER timer match value.(Value is decimal format, and this value will be translate to Gray code in
* API. )
* @param cb OSTIMER callback (can be left as NULL if none, otherwise should be a void func(void)).
* @retval kStatus_Success - Set match value and enable interrupt Successfully.
* @retval kStatus_Fail - Set match value fail.
*/
status_t OSTIMER_SetMatchValue(OSTIMER_Type *base, uint64_t count, ostimer_callback_t cb)
{
uint64_t tmp = OSTIMER_DecimalToGray(count);
return OSTIMER_SetMatchRawValue(base, tmp, cb);
}
/*!
* @brief Get current timer count value from OSTIMER.
*
* This function will get a decimal timer count value.
* The RAW value of timer count is gray code format, will be translated to decimal data internally.
*
* @param base OSTIMER peripheral base address.
* @return Value of OSTIMER which will formated to decimal value.
*/
uint64_t OSTIMER_GetCurrentTimerValue(OSTIMER_Type *base)
{
uint64_t tmp = 0U;
tmp = OSTIMER_GetCurrentTimerRawValue(base);
return OSTIMER_GrayToDecimal(tmp);
}
/*!
* @brief Get the capture value from OSTIMER.
*
* This function will get a capture decimal-value from OSTIMER.
* The RAW value of timer capture is gray code format, will be translated to decimal data internally.
*
* @param base OSTIMER peripheral base address.
* @return Value of capture register, data format is decimal.
*/
uint64_t OSTIMER_GetCaptureValue(OSTIMER_Type *base)
{
uint64_t tmp = 0U;
tmp = OSTIMER_GetCaptureRawValue(base);
return OSTIMER_GrayToDecimal(tmp);
}
void OSTIMER_HandleIRQ(OSTIMER_Type *base, ostimer_callback_t cb)
{
/* Clear interrupt flag, disable the IRQ and module interrupt enablement. */
OSTIMER_EnableInterrupt(base, false);
if (cb != NULL)
{
cb();
}
}
#if defined(OSTIMER0)
void OS_EVENT_DriverIRQHandler(void);
void OS_EVENT_DriverIRQHandler(void)
{
s_ostimerIsr(OSTIMER0, s_ostimerHandle[0]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(OSTIMER)
void OS_EVENT_DriverIRQHandler(void);
void OS_EVENT_DriverIRQHandler(void)
{
s_ostimerIsr(OSTIMER, s_ostimerHandle[0]);
SDK_ISR_EXIT_BARRIER;
}
#endif

View File

@ -0,0 +1,273 @@
/*
* Copyright 2018-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_OSTIMER_H_
#define _FSL_OSTIMER_H_
#include "fsl_common.h"
/*!
* @addtogroup ostimer
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief OSTIMER driver version. */
#define FSL_OSTIMER_DRIVER_VERSION (MAKE_VERSION(2, 2, 1))
/*@}*/
/*!
* @brief OSTIMER status flags.
*/
enum _ostimer_flags
{
kOSTIMER_MatchInterruptFlag = (OSTIMER_OSEVENT_CTRL_OSTIMER_INTRFLAG_MASK), /*!< Match interrupt flag bit, sets if
the match value was reached. */
};
/*! @brief ostimer callback function. */
typedef void (*ostimer_callback_t)(void);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an OSTIMER by turning its bus clock on
*
*/
void OSTIMER_Init(OSTIMER_Type *base);
/*!
* @brief Deinitializes a OSTIMER instance.
*
* This function shuts down OSTIMER bus clock
*
* @param base OSTIMER peripheral base address.
*/
void OSTIMER_Deinit(OSTIMER_Type *base);
/*!
* @brief Translate the value from gray-code to decimal.
*
* @param gray The gray value input.
* @return The decimal value.
*/
uint64_t OSTIMER_GrayToDecimal(uint64_t gray);
/*!
* @brief Translate the value from decimal to gray-code.
*
* @param dec The decimal value.
* @return The gray code of the input value.
*/
static inline uint64_t OSTIMER_DecimalToGray(uint64_t dec)
{
return (dec ^ (dec >> 1U));
}
/*!
* @brief Get OSTIMER status Flags.
*
* This returns the status flag.
* Currently, only match interrupt flag can be got.
*
* @param base OSTIMER peripheral base address.
* @return status register value
*/
uint32_t OSTIMER_GetStatusFlags(OSTIMER_Type *base);
/*!
* @brief Clear Status Interrupt Flags.
*
* This clears intrrupt status flag.
* Currently, only match interrupt flag can be cleared.
*
* @param base OSTIMER peripheral base address.
* @param mask Clear bit mask.
* @return none
*/
void OSTIMER_ClearStatusFlags(OSTIMER_Type *base, uint32_t mask);
/*!
* @brief Set the match raw value for OSTIMER.
*
* This function will set a match value for OSTIMER with an optional callback. And this callback
* will be called while the data in dedicated pair match register is equals to the value of central EVTIMER.
* Please note that, the data format is gray-code, if decimal data was desired, please using OSTIMER_SetMatchValue().
*
* @param base OSTIMER peripheral base address.
* @param count OSTIMER timer match value.(Value is gray-code format)
*
* @param cb OSTIMER callback (can be left as NULL if none, otherwise should be a void func(void)).
* @retval kStatus_Success - Set match raw value and enable interrupt Successfully.
* @retval kStatus_Fail - Set match raw value fail.
*/
status_t OSTIMER_SetMatchRawValue(OSTIMER_Type *base, uint64_t count, ostimer_callback_t cb);
/*!
* @brief Set the match value for OSTIMER.
*
* This function will set a match value for OSTIMER with an optional callback. And this callback
* will be called while the data in dedicated pair match register is equals to the value of central OS TIMER.
*
* @param base OSTIMER peripheral base address.
* @param count OSTIMER timer match value.(Value is decimal format, and this value will be translate to Gray code
* internally.)
*
* @param cb OSTIMER callback (can be left as NULL if none, otherwise should be a void func(void)).
* @retval kStatus_Success - Set match value and enable interrupt Successfully.
* @retval kStatus_Fail - Set match value fail.
*/
status_t OSTIMER_SetMatchValue(OSTIMER_Type *base, uint64_t count, ostimer_callback_t cb);
/*!
* @brief Set value to OSTIMER MATCH register directly.
*
* This function writes the input value to OSTIMER MATCH register directly,
* it does not touch any other registers. Note that, the data format is
* gray-code. The function @ref OSTIMER_DecimalToGray could convert decimal
* value to gray code.
*
* @param base OSTIMER peripheral base address.
* @param count OSTIMER timer match value (Value is gray-code format).
*/
static inline void OSTIMER_SetMatchRegister(OSTIMER_Type *base, uint64_t value)
{
#ifdef OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK
/* Wait for MATCH register ready for write. */
while (0U != (base->OSEVENT_CTRL & OSTIMER_OSEVENT_CTRL_MATCH_WR_RDY_MASK))
{
}
#endif
base->MATCH_L = (uint32_t)value;
base->MATCH_H = (uint32_t)(value >> 32U);
}
/*!
* @brief Enable the OSTIMER counter match interrupt.
*
* Enable the timer counter match interrupt. The interrupt happens when OSTIMER
* counter matches the value in MATCH registers.
*
* @param base OSTIMER peripheral base address.
*/
static inline void OSTIMER_EnableMatchInterrupt(OSTIMER_Type *base)
{
base->OSEVENT_CTRL |= OSTIMER_OSEVENT_CTRL_OSTIMER_INTENA_MASK;
}
/*!
* @brief Disable the OSTIMER counter match interrupt.
*
* Disable the timer counter match interrupt. The interrupt happens when OSTIMER
* counter matches the value in MATCH registers.
*
* @param base OSTIMER peripheral base address.
*/
static inline void OSTIMER_DisableMatchInterrupt(OSTIMER_Type *base)
{
base->OSEVENT_CTRL &= ~OSTIMER_OSEVENT_CTRL_OSTIMER_INTENA_MASK;
}
/*!
* @brief Get current timer raw count value from OSTIMER.
*
* This function will get a gray code type timer count value from OS timer register.
* The raw value of timer count is gray code format.
*
* @param base OSTIMER peripheral base address.
* @return Raw value of OSTIMER, gray code format.
*/
static inline uint64_t OSTIMER_GetCurrentTimerRawValue(OSTIMER_Type *base)
{
uint64_t tmp = 0U;
tmp = base->EVTIMERL;
tmp |= (uint64_t)(base->EVTIMERH) << 32U;
return tmp;
}
/*!
* @brief Get current timer count value from OSTIMER.
*
* This function will get a decimal timer count value.
* The RAW value of timer count is gray code format, will be translated to decimal data internally.
*
* @param base OSTIMER peripheral base address.
* @return Value of OSTIMER which will be formated to decimal value.
*/
uint64_t OSTIMER_GetCurrentTimerValue(OSTIMER_Type *base);
/*!
* @brief Get the capture value from OSTIMER.
*
* This function will get a captured gray-code value from OSTIMER.
* The Raw value of timer capture is gray code format.
*
* @param base OSTIMER peripheral base address.
* @return Raw value of capture register, data format is gray code.
*/
static inline uint64_t OSTIMER_GetCaptureRawValue(OSTIMER_Type *base)
{
uint64_t tmp = 0U;
tmp = base->CAPTURE_L;
tmp |= (uint64_t)(base->CAPTURE_H) << 32U;
return tmp;
}
/*!
* @brief Get the capture value from OSTIMER.
*
* This function will get a capture decimal-value from OSTIMER.
* The RAW value of timer capture is gray code format, will be translated to decimal data internally.
*
* @param base OSTIMER peripheral base address.
* @return Value of capture register, data format is decimal.
*/
uint64_t OSTIMER_GetCaptureValue(OSTIMER_Type *base);
/*!
* @brief OS timer interrupt Service Handler.
*
* This function handles the interrupt and refers to the callback array in the driver to callback user (as per request
* in OSTIMER_SetMatchValue()).
* if no user callback is scheduled, the interrupt will simply be cleared.
*
* @param base OS timer peripheral base address.
* @param cb callback scheduled for this instance of OS timer
* @return none
*/
void OSTIMER_HandleIRQ(OSTIMER_Type *base, ostimer_callback_t cb);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_OSTIMER_H_ */

View File

@ -0,0 +1,679 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_PORT_H_
#define _FSL_PORT_H_
#include "fsl_common.h"
/*!
* @addtogroup port
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.port"
#endif
/*! @name Driver version */
/*@{*/
/*! @brief PORT driver version. */
#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 4, 1))
/*@}*/
#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE
/*! @brief Internal resistor pull feature selection */
enum _port_pull
{
kPORT_PullDisable = 0U, /*!< Internal pull-up/down resistor is disabled. */
kPORT_PullDown = 2U, /*!< Internal pull-down resistor is enabled. */
kPORT_PullUp = 3U, /*!< Internal pull-up resistor is enabled. */
};
#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */
#if defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE
/*! @brief Internal resistor pull value selection */
enum _port_pull_value
{
kPORT_LowPullResistor = 0U, /*!< Low internal pull resistor value is selected. */
kPORT_HighPullResistor = 1U, /*!< High internal pull resistor value is selected. */
};
#endif /* FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE */
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
/*! @brief Slew rate selection */
enum _port_slew_rate
{
kPORT_FastSlewRate = 0U, /*!< Fast slew rate is configured. */
kPORT_SlowSlewRate = 1U, /*!< Slow slew rate is configured. */
};
#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
/*! @brief Open Drain feature enable/disable */
enum _port_open_drain_enable
{
kPORT_OpenDrainDisable = 0U, /*!< Open drain output is disabled. */
kPORT_OpenDrainEnable = 1U, /*!< Open drain output is enabled. */
};
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
/*! @brief Passive filter feature enable/disable */
enum _port_passive_filter_enable
{
kPORT_PassiveFilterDisable = 0U, /*!< Passive input filter is disabled. */
kPORT_PassiveFilterEnable = 1U, /*!< Passive input filter is enabled. */
};
#endif
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
/*! @brief Configures the drive strength. */
enum _port_drive_strength
{
kPORT_LowDriveStrength = 0U, /*!< Low-drive strength is configured. */
kPORT_HighDriveStrength = 1U, /*!< High-drive strength is configured. */
};
#endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1
/*! @brief Configures the drive strength1. */
enum _port_drive_strength1
{
kPORT_NormalDriveStrength = 0U, /*!< Normal drive strength */
kPORT_DoubleDriveStrength = 1U, /*!< Double drive strength */
};
#endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1 */
#if defined(FSL_FEATURE_PORT_HAS_INPUT_BUFFER) && FSL_FEATURE_PORT_HAS_INPUT_BUFFER
/*! @brief input buffer disable/enable. */
enum _port_input_buffer
{
kPORT_InputBufferDisable = 0U, /*!< Digital input is disabled */
kPORT_InputBufferEnable = 1U, /*!< Digital input is enabled */
};
#endif /* FSL_FEATURE_PORT_HAS_INPUT_BUFFER */
#if defined(FSL_FEATURE_PORT_HAS_INVERT_INPUT) && FSL_FEATURE_PORT_HAS_INVERT_INPUT
/*! @brief Digital input is not inverted or it is inverted. */
enum _port_invet_input
{
kPORT_InputNormal = 0U, /*!< Digital input is not inverted */
kPORT_InputInvert = 1U, /*!< Digital input is inverted */
};
#endif /* FSL_FEATURE_PORT_HAS_INVERT_INPUT */
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
/*! @brief Unlock/lock the pin control register field[15:0] */
enum _port_lock_register
{
kPORT_UnlockRegister = 0U, /*!< Pin Control Register fields [15:0] are not locked. */
kPORT_LockRegister = 1U, /*!< Pin Control Register fields [15:0] are locked. */
};
#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
/*! @brief Pin mux selection */
typedef enum _port_mux
{
kPORT_PinDisabledOrAnalog = 0U, /*!< Corresponding pin is disabled, but is used as an analog pin. */
kPORT_MuxAsGpio = 1U, /*!< Corresponding pin is configured as GPIO. */
kPORT_MuxAlt0 = 0U, /*!< Chip-specific */
kPORT_MuxAlt1 = 1U, /*!< Chip-specific */
kPORT_MuxAlt2 = 2U, /*!< Chip-specific */
kPORT_MuxAlt3 = 3U, /*!< Chip-specific */
kPORT_MuxAlt4 = 4U, /*!< Chip-specific */
kPORT_MuxAlt5 = 5U, /*!< Chip-specific */
kPORT_MuxAlt6 = 6U, /*!< Chip-specific */
kPORT_MuxAlt7 = 7U, /*!< Chip-specific */
kPORT_MuxAlt8 = 8U, /*!< Chip-specific */
kPORT_MuxAlt9 = 9U, /*!< Chip-specific */
kPORT_MuxAlt10 = 10U, /*!< Chip-specific */
kPORT_MuxAlt11 = 11U, /*!< Chip-specific */
kPORT_MuxAlt12 = 12U, /*!< Chip-specific */
kPORT_MuxAlt13 = 13U, /*!< Chip-specific */
kPORT_MuxAlt14 = 14U, /*!< Chip-specific */
kPORT_MuxAlt15 = 15U, /*!< Chip-specific */
} port_mux_t;
#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
/*! @brief Configures the interrupt generation condition. */
typedef enum _port_interrupt
{
kPORT_InterruptOrDMADisabled = 0x0U, /*!< Interrupt/DMA request is disabled. */
#if defined(FSL_FEATURE_PORT_HAS_DMA_REQUEST) && FSL_FEATURE_PORT_HAS_DMA_REQUEST || defined(DOXYGEN_OUTPUT)
kPORT_DMARisingEdge = 0x1U, /*!< DMA request on rising edge. */
kPORT_DMAFallingEdge = 0x2U, /*!< DMA request on falling edge. */
kPORT_DMAEitherEdge = 0x3U, /*!< DMA request on either edge. */
#endif
#if defined(FSL_FEATURE_PORT_HAS_IRQC_FLAG) && FSL_FEATURE_PORT_HAS_IRQC_FLAG || defined(DOXYGEN_OUTPUT)
kPORT_FlagRisingEdge = 0x05U, /*!< Flag sets on rising edge. */
kPORT_FlagFallingEdge = 0x06U, /*!< Flag sets on falling edge. */
kPORT_FlagEitherEdge = 0x07U, /*!< Flag sets on either edge. */
#endif
kPORT_InterruptLogicZero = 0x8U, /*!< Interrupt when logic zero. */
kPORT_InterruptRisingEdge = 0x9U, /*!< Interrupt on rising edge. */
kPORT_InterruptFallingEdge = 0xAU, /*!< Interrupt on falling edge. */
kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */
kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */
#if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER || defined(DOXYGEN_OUTPUT)
kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */
kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */
#endif
} port_interrupt_t;
#endif
#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
/*! @brief Digital filter clock source selection */
typedef enum _port_digital_filter_clock_source
{
kPORT_BusClock = 0U, /*!< Digital filters are clocked by the bus clock. */
kPORT_LpoClock = 1U, /*!< Digital filters are clocked by the 1 kHz LPO clock. */
} port_digital_filter_clock_source_t;
/*! @brief PORT digital filter feature configuration definition */
typedef struct _port_digital_filter_config
{
uint32_t digitalFilterWidth; /*!< Set digital filter width */
port_digital_filter_clock_source_t clockSource; /*!< Set digital filter clockSource */
} port_digital_filter_config_t;
#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
/*! @brief PORT pin configuration structure */
typedef struct _port_pin_config
{
#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE
uint16_t pullSelect : 2; /*!< No-pull/pull-down/pull-up select */
#else
uint16_t : 2;
#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */
#if defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE
uint16_t pullValueSelect : 1; /*!< Pull value select */
#endif /* FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE */
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
uint16_t slewRate : 1; /*!< Fast/slow slew rate Configure */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
#if !(defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE)
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE */
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
uint16_t passiveFilterEnable : 1; /*!< Passive filter enable/disable */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_PASSIVE_FILTER */
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
uint16_t openDrainEnable : 1; /*!< Open drain enable/disable */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
uint16_t driveStrength : 1; /*!< Fast/slow drive strength configure */
#else
uint16_t : 1;
#endif
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1
uint16_t driveStrength1 : 1; /*!< Normal/Double drive strength enable/disable */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1 */
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && (FSL_FEATURE_PORT_PCR_MUX_WIDTH == 3)
uint16_t mux : 3; /*!< Pin mux Configure */
uint16_t : 1;
#elif defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && (FSL_FEATURE_PORT_PCR_MUX_WIDTH == 4)
uint16_t mux : 4; /*!< Pin mux Configure */
#else
uint16_t : 4;
#endif
#if defined(FSL_FEATURE_PORT_HAS_INPUT_BUFFER) && FSL_FEATURE_PORT_HAS_INPUT_BUFFER
uint16_t inputBuffer : 1; /*!< Input Buffer Configure */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_INPUT_BUFFER */
#if defined(FSL_FEATURE_PORT_HAS_INVERT_INPUT) && FSL_FEATURE_PORT_HAS_INVERT_INPUT
uint16_t invertInput : 1; /*!< Invert Input Configure */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_INVERT_INPUT */
uint16_t : 1;
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
uint16_t lockRegister : 1; /*!< Lock/unlock the PCR field[15:0] */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */
} port_pin_config_t;
#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
#if defined(FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER
/*! @brief PORT version information. */
typedef struct _port_version_info
{
uint16_t feature; /*!< Feature Specification Number. */
uint8_t minor; /*!< Minor Version Number. */
uint8_t major; /*!< Major Version Number. */
} port_version_info_t;
#endif /* FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER */
#if defined(FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE) && FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE
/*! @brief PORT voltage range. */
typedef enum _port_voltage_range
{
kPORT_VoltageRange1Dot71V_3Dot6V = 0x0U, /*!< Port voltage range is 1.71 V - 3.6 V. */
kPORT_VoltageRange2Dot70V_3Dot6V = 0x1U, /*!< Port voltage range is 2.70 V - 3.6 V. */
} port_voltage_range_t;
#endif /* FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH
/*! @name Configuration */
/*@{*/
#if defined(FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER) && FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER
/*!
* @brief Get PORT version information.
*
* @param base PORT peripheral base pointer
* @param info PORT version information
*/
static inline void PORT_GetVersionInfo(PORT_Type *base, port_version_info_t *info)
{
uint32_t verid = base->VERID;
info->feature = (uint16_t)verid;
info->minor = (uint8_t)(verid >> PORT_VERID_MINOR_SHIFT);
info->major = (uint8_t)(verid >> PORT_VERID_MAJOR_SHIFT);
}
#endif /* FSL_FEATURE_PORT_HAS_VERSION_INFO_REGISTER */
#if defined(FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE) && FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE
/*!
* @brief Get PORT version information.
*
* @note : PORTA_CONFIG[RANGE] controls the voltage ranges of Port A, B, and C. Read or write PORTB_CONFIG[RANGE] and
* PORTC_CONFIG[RANGE] does not take effect.
*
* @param base PORT peripheral base pointer
* @param range port voltage range
*/
static inline void PORT_SecletPortVoltageRange(PORT_Type *base, port_voltage_range_t range)
{
base->CONFIG = (uint32_t)range;
}
#endif /* FSL_FEATURE_PORT_SUPPORT_DIFFERENT_VOLTAGE_RANGE */
/*!
* @brief Sets the port PCR register.
*
* This is an example to define an input pin or output pin PCR configuration.
* @code
* // Define a digital input pin PCR configuration
* port_pin_config_t config = {
* kPORT_PullUp,
* kPORT_FastSlewRate,
* kPORT_PassiveFilterDisable,
* kPORT_OpenDrainDisable,
* kPORT_LowDriveStrength,
* kPORT_MuxAsGpio,
* kPORT_UnLockRegister,
* };
* @endcode
*
* @param base PORT peripheral base pointer.
* @param pin PORT pin number.
* @param config PORT PCR register configuration structure.
*/
static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config)
{
assert(config);
uint32_t addr = (uint32_t)&base->PCR[pin];
*(volatile uint16_t *)(addr) = *((const uint16_t *)(const void *)config);
}
/*!
* @brief Sets the port PCR register for multiple pins.
*
* This is an example to define input pins or output pins PCR configuration.
* @code
* Define a digital input pin PCR configuration
* port_pin_config_t config = {
* kPORT_PullUp ,
* kPORT_PullEnable,
* kPORT_FastSlewRate,
* kPORT_PassiveFilterDisable,
* kPORT_OpenDrainDisable,
* kPORT_LowDriveStrength,
* kPORT_MuxAsGpio,
* kPORT_UnlockRegister,
* };
* @endcode
*
* @param base PORT peripheral base pointer.
* @param mask PORT pin number macro.
* @param config PORT PCR register configuration structure.
*/
static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config)
{
assert(config);
uint16_t pcrl = *((const uint16_t *)(const void *)config);
if (0U != (mask & 0xffffU))
{
base->GPCLR = ((mask & 0xffffU) << 16) | pcrl;
}
if (0U != (mask >> 16))
{
base->GPCHR = (mask & 0xffff0000U) | pcrl;
}
}
#if defined(FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG) && FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG
/*!
* @brief Sets the port interrupt configuration in PCR register for multiple pins.
*
* @param base PORT peripheral base pointer.
* @param mask PORT pin number macro.
* @param config PORT pin interrupt configuration.
* - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled.
* - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
* - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
* - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
* - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
* - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
* - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
* - #kPORT_InterruptLogicZero : Interrupt when logic zero.
* - #kPORT_InterruptRisingEdge : Interrupt on rising edge.
* - #kPORT_InterruptFallingEdge: Interrupt on falling edge.
* - #kPORT_InterruptEitherEdge : Interrupt on either edge.
* - #kPORT_InterruptLogicOne : Interrupt when logic one.
* - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
* - #kPORT_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit)..
*/
static inline void PORT_SetMultipleInterruptPinsConfig(PORT_Type *base, uint32_t mask, port_interrupt_t config)
{
assert(config);
if (0U != ((uint32_t)mask & 0xffffU))
{
base->GICLR = ((uint32_t)config << 16U) | ((uint32_t)mask & 0xffffU);
}
mask = mask >> 16;
if (0U != mask)
{
base->GICHR = ((uint32_t)config << 16U) | ((uint32_t)mask & 0xffffU);
}
}
#endif
/*!
* @brief Configures the pin muxing.
*
* @param base PORT peripheral base pointer.
* @param pin PORT pin number.
* @param mux pin muxing slot selection.
* - #kPORT_PinDisabledOrAnalog: Pin disabled or work in analog function.
* - #kPORT_MuxAsGpio : Set as GPIO.
* - #kPORT_MuxAlt2 : chip-specific.
* - #kPORT_MuxAlt3 : chip-specific.
* - #kPORT_MuxAlt4 : chip-specific.
* - #kPORT_MuxAlt5 : chip-specific.
* - #kPORT_MuxAlt6 : chip-specific.
* - #kPORT_MuxAlt7 : chip-specific.
* @note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because
* the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is
* reset to zero : kPORT_PinDisabledOrAnalog).
* This function is recommended to use to reset the pin mux
*
*/
static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux)
{
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux);
}
#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */
#if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER
/*!
* @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin.
*
* @param base PORT peripheral base pointer.
* @param mask PORT pin number macro.
* @param enable PORT digital filter configuration.
*/
static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable)
{
if (enable == true)
{
base->DFER |= mask;
}
else
{
base->DFER &= ~mask;
}
}
/*!
* @brief Sets the digital filter in one port, each bit of the 32-bit register represents one pin.
*
* @param base PORT peripheral base pointer.
* @param config PORT digital filter configuration structure.
*/
static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digital_filter_config_t *config)
{
assert(config);
base->DFCR = PORT_DFCR_CS(config->clockSource);
base->DFWR = PORT_DFWR_FILT(config->digitalFilterWidth);
}
#endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */
/*@}*/
/*! @name Interrupt */
/*@{*/
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
/*!
* @brief Configures the port pin interrupt/DMA request.
*
* @param base PORT peripheral base pointer.
* @param pin PORT pin number.
* @param config PORT pin interrupt configuration.
* - #kPORT_InterruptOrDMADisabled: Interrupt/DMA request disabled.
* - #kPORT_DMARisingEdge : DMA request on rising edge(if the DMA requests exit).
* - #kPORT_DMAFallingEdge: DMA request on falling edge(if the DMA requests exit).
* - #kPORT_DMAEitherEdge : DMA request on either edge(if the DMA requests exit).
* - #kPORT_FlagRisingEdge : Flag sets on rising edge(if the Flag states exit).
* - #kPORT_FlagFallingEdge : Flag sets on falling edge(if the Flag states exit).
* - #kPORT_FlagEitherEdge : Flag sets on either edge(if the Flag states exit).
* - #kPORT_InterruptLogicZero : Interrupt when logic zero.
* - #kPORT_InterruptRisingEdge : Interrupt on rising edge.
* - #kPORT_InterruptFallingEdge: Interrupt on falling edge.
* - #kPORT_InterruptEitherEdge : Interrupt on either edge.
* - #kPORT_InterruptLogicOne : Interrupt when logic one.
* - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit).
* - #kPORT_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit).
*/
static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config)
{
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | PORT_PCR_IRQC(config);
}
#endif
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
/*!
* @brief Configures the port pin drive strength.
*
* @param base PORT peripheral base pointer.
* @param pin PORT pin number.
* @param strength PORT pin drive strength
* - #kPORT_LowDriveStrength = 0U - Low-drive strength is configured.
* - #kPORT_HighDriveStrength = 1U - High-drive strength is configured.
*/
static inline void PORT_SetPinDriveStrength(PORT_Type *base, uint32_t pin, uint8_t strength)
{
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_DSE_MASK) | PORT_PCR_DSE(strength);
}
#endif
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1
/*!
* @brief Enables the port pin double drive strength.
*
* @param base PORT peripheral base pointer.
* @param pin PORT pin number.
* @param enable PORT pin drive strength configuration.
*/
static inline void PORT_EnablePinDoubleDriveStrength(PORT_Type *base, uint32_t pin, bool enable)
{
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_DSE1_MASK) | PORT_PCR_DSE1(enable);
}
#endif
#if defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE
/*!
* @brief Configures the port pin pull value.
*
* @param base PORT peripheral base pointer.
* @param pin PORT pin number.
* @param value PORT pin pull value
* - #kPORT_LowPullResistor = 0U - Low internal pull resistor value is selected.
* - #kPORT_HighPullResistor = 1U - High internal pull resistor value is selected.
*/
static inline void PORT_SetPinPullValue(PORT_Type *base, uint32_t pin, uint8_t value)
{
base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_PV_MASK) | PORT_PCR_PV(value);
}
#endif /* FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE */
#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
/*!
* @brief Reads the whole port status flag.
*
* If a pin is configured to generate the DMA request, the corresponding flag
* is cleared automatically at the completion of the requested DMA transfer.
* Otherwise, the flag remains set until a logic one is written to that flag.
* If configured for a level sensitive interrupt that remains asserted, the flag
* is set again immediately.
*
* @param base PORT peripheral base pointer.
* @return Current port interrupt status flags, for example, 0x00010001 means the
* pin 0 and 16 have the interrupt.
*/
static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base)
{
return base->ISFR;
}
/*!
* @brief Clears the multiple pin interrupt status flag.
*
* @param base PORT peripheral base pointer.
* @param mask PORT pin number macro.
*/
static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask)
{
base->ISFR = mask;
}
#endif
#if defined(FSL_FEATURE_PORT_SUPPORT_EFT) && FSL_FEATURE_PORT_SUPPORT_EFT
/*!
* @brief Get EFT detect flags.
*
* @param base PORT peripheral base pointer
* @return EFT detect flags
*/
static inline uint32_t PORT_GetEFTDetectFlags(PORT_Type *base)
{
return base->EDFR;
}
/*!
* @brief Enable EFT detect interrupts.
*
* @param base PORT peripheral base pointer
* @param interrupt EFT detect interrupt
*/
static inline void PORT_EnableEFTDetectInterrupts(PORT_Type *base, uint32_t interrupt)
{
base->EDIER |= interrupt;
}
/*!
* @brief Disable EFT detect interrupts.
*
* @param base PORT peripheral base pointer
* @param interrupt EFT detect interrupt
*/
static inline void PORT_DisableEFTDetectInterrupts(PORT_Type *base, uint32_t interrupt)
{
base->EDIER &= ~interrupt;
}
/*!
* @brief Clear all low EFT detector.
*
* @note : Port B and Port C pins share the same EFT detector clear control from PORTC_EDCR register. Any write to the
* PORTB_EDCR does not take effect.
* @param base PORT peripheral base pointer
* @param interrupt EFT detect interrupt
*/
static inline void PORT_ClearAllLowEFTDetectors(PORT_Type *base)
{
base->EDCR |= PORT_EDCR_EDLC_MASK;
base->EDCR &= ~PORT_EDCR_EDLC_MASK;
}
/*!
* @brief Clear all high EFT detector.
*
* @param base PORT peripheral base pointer
* @param interrupt EFT detect interrupt
*/
static inline void PORT_ClearAllHighEFTDetectors(PORT_Type *base)
{
base->EDCR |= PORT_EDCR_EDHC_MASK;
base->EDCR &= ~PORT_EDCR_EDHC_MASK;
}
#endif /* FSL_FEATURE_PORT_SUPPORT_EFT */
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_PORT_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,133 @@
/*
* Copyright 2023, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_reset.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.reset"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
#define GET_REG_INDEX(x) ((uint32_t)(((uint32_t)(x)&0xFF00U) >> 8))
#define GET_BIT_INDEX(x) ((uint32_t)((uint32_t)(x)&0x00FFU))
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Assert reset to peripheral.
*
* Asserts reset signal to specified peripheral module.
*
* param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
{
uint32_t regIndex = GET_REG_INDEX(peripheral);
uint32_t bitPos = GET_BIT_INDEX(peripheral);
uint32_t bitMask = 1UL << bitPos;
volatile uint32_t *pResetCtrl = &(MRCC0->MRCC_GLB_RST0);
if (peripheral == NotAvail_RSTn)
{
return;
}
assert(bitPos < 32u);
assert(regIndex < 2u);
/* Unlock clock configuration */
SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
/* reset register is in MRCC */
/* set bit */
if (regIndex == 0U)
{
MRCC0->MRCC_GLB_RST0_SET = bitMask;
pResetCtrl = &(MRCC0->MRCC_GLB_RST0);
}
else if (regIndex == 1U)
{
MRCC0->MRCC_GLB_RST1_SET = bitMask;
pResetCtrl = &(MRCC0->MRCC_GLB_RST1);
}
/* wait until it reads 0b1 */
while (0u == ((*pResetCtrl) & bitMask))
{
}
/* Freeze clock configuration */
SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
}
/*!
* brief Clear reset to peripheral.
*
* Clears reset signal to specified peripheral module, allows it to operate.
*
* param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
{
uint32_t regIndex = GET_REG_INDEX(peripheral);
uint32_t bitPos = GET_BIT_INDEX(peripheral);
uint32_t bitMask = 1UL << bitPos;
volatile uint32_t *pResetCtrl = &(MRCC0->MRCC_GLB_RST0);
assert(bitPos < 32u);
/* Unlock clock configuration */
SYSCON->CLKUNLOCK &= ~SYSCON_CLKUNLOCK_UNLOCK_MASK;
/* reset register is in MRCC */
/* clear bit */
if (regIndex == 0U)
{
MRCC0->MRCC_GLB_RST0_CLR = bitMask;
pResetCtrl = &(MRCC0->MRCC_GLB_RST0);
}
else if (regIndex == 1U)
{
MRCC0->MRCC_GLB_RST1_CLR = bitMask;
pResetCtrl = &(MRCC0->MRCC_GLB_RST1);
}
/* wait until it reads 0b0 */
while (bitMask == ((*pResetCtrl) & bitMask))
{
}
/* Freeze clock configuration */
SYSCON->CLKUNLOCK |= SYSCON_CLKUNLOCK_UNLOCK_MASK;
}
/*!
* brief Reset peripheral module.
*
* Reset peripheral module.
*
* param peripheral Peripheral to reset. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_PeripheralReset(reset_ip_name_t peripheral)
{
RESET_ClearPeripheralReset(peripheral);
RESET_SetPeripheralReset(peripheral);
}

View File

@ -0,0 +1,207 @@
/*
* Copyright 2023, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_RESET_H_
#define _FSL_RESET_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "fsl_device_registers.h"
/*!
* @addtogroup reset
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief reset driver version 2.4.0 */
#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 4, 0))
/*@}*/
/*!
* @brief Enumeration for peripheral reset control bits
*
* Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers
*/
typedef enum _SYSCON_RSTn
{
kINPUTMUX0_RST_SHIFT_RSTn = (0U | (0U)), /*!< INPUTMUX0 reset control */
kI3C0_RST_SHIFT_RSTn = (0U | (1U)), /*!< I3C0 reset control */
kCTIMER0_RST_SHIFT_RSTn = (0U | (2U)), /*!< CTIMER0 reset control */
kCTIMER1_RST_SHIFT_RSTn = (0U | (3U)), /*!< CTIMER1 reset control */
kCTIMER2_RST_SHIFT_RSTn = (0U | (4U)), /*!< CTIMER2 reset control */
kFREQME_RST_SHIFT_RSTn = (0U | (5U)), /*!< FREQME reset control */
kUTICK0_RST_SHIFT_RSTn = (0U | (6U)), /*!< UTICK0 reset control */
kDMA_RST_SHIFT_RSTn = (0U | (8U)), /*!< DMA reset control */
kAOI0_RST_SHIFT_RSTn = (0U | (9U)), /*!< AOI0 reset control */
kCRC_RST_SHIFT_RSTn = (0U | (10U)), /*!< CRC reset control */
kEIM_RST_SHIFT_RSTn = (0U | (11U)), /*!< EIM reset control */
kERM_RST_SHIFT_RSTn = (0U | (12U)), /*!< ERM reset control */
kLPI2C0_RST_SHIFT_RSTn = (0U | (16U)), /*!< LPI2C0 reset control */
kLPSPI0_RST_SHIFT_RSTn = (0U | (17U)), /*!< LPSPI0 reset control */
kLPSPI1_RST_SHIFT_RSTn = (0U | (18U)), /*!< LPSPI1 reset control */
kLPUART0_RST_SHIFT_RSTn = (0U | (19U)), /*!< LPUART0 reset control */
kLPUART1_RST_SHIFT_RSTn = (0U | (20U)), /*!< LPUART1 reset control */
kLPUART2_RST_SHIFT_RSTn = (0U | (21U)), /*!< LPUART2 reset control */
kUSB0_RST_SHIFT_RSTn = (0U | (22U)), /*!< USB0 reset control */
kQDC0_RST_SHIFT_RSTn = (0U | (23U)), /*!< QDC0 reset control */
kFLEXPWM0_RST_SHIFT_RSTn = (0U | (24U)), /*!< FLEXPWM0 reset control */
kOSTIMER0_RST_SHIFT_RSTn = (0U | (25U)), /*!< OSTIMER0 reset control */
kADC0_RST_SHIFT_RSTn = (0U | (26U)), /*!< ADC0 reset control */
kCMP1_RST_SHIFT_RSTn = (0U | (28U)), /*!< CMP1 reset control */
kPORT0_RST_SHIFT_RSTn = (0U | (29U)), /*!< PORT0 reset control */
kPORT1_RST_SHIFT_RSTn = (0U | (30U)), /*!< PORT1 reset control */
kPORT2_RST_SHIFT_RSTn = (0U | (31U)), /*!< PORT2 reset control */
kPORT3_RST_SHIFT_RSTn = ((1U << 8U) | (0U)), /*!< PORT3 reset control */
kATX0_RST_SHIFT_RSTn = ((1U << 8U) | (1U)), /*!< ATX0 reset control */
kGPIO0_RST_SHIFT_RSTn = ((1U << 8U) | (5U)), /*!< GPIO0 reset control */
kGPIO1_RST_SHIFT_RSTn = ((1U << 8U) | (6U)), /*!< GPIO1 reset control */
kGPIO2_RST_SHIFT_RSTn = ((1U << 8U) | (7U)), /*!< GPIO2 reset control */
kGPIO3_RST_SHIFT_RSTn = ((1U << 8U) | (8U)), /*!< GPIO3 reset control */
NotAvail_RSTn = (0xFFFFU), /*!< No reset control */
} SYSCON_RSTn_t;
/** Array initializers with peripheral reset bits **/
#define AOI_RSTS \
{ \
kAOI0_RST_SHIFT_RSTn \
} /* Reset bits for ADC peripheral */
#define ADC_RSTS \
{ \
kADC0_RST_SHIFT_RSTn \
} /* Reset bits for ADC peripheral */
#define CRC_RSTS \
{ \
kCRC_RST_SHIFT_RSTn \
} /* Reset bits for CRC peripheral */
#define CTIMER_RSTS \
{ \
kCTIMER0_RST_SHIFT_RSTn, kCTIMER1_RST_SHIFT_RSTn, kCTIMER2_RST_SHIFT_RSTn \
} /* Reset bits for CTIMER peripheral */
#define DMA_RSTS_N \
{ \
kDMA_RST_SHIFT_RSTn \
} /* Reset bits for DMA peripheral */
#define FLEXPWM_RSTS_N \
{ \
kFLEXPWM0_RST_SHIFT_RSTn \
} /* Reset bits for FLEXPWM peripheral */
#define FREQME_RSTS_N \
{ \
kFREQME_RST_SHIFT_RSTn \
} /* Reset bits for FREQME peripheral */
#define GPIO_RSTS_N \
{ \
kGPIO0_RST_SHIFT_RSTn, kGPIO1_RST_SHIFT_RSTn, kGPIO2_RST_SHIFT_RSTn, kGPIO3_RST_SHIFT_RSTn \
} /* Reset bits for GPIO peripheral */
#define I3C_RSTS \
{ \
kI3C0_RST_SHIFT_RSTn \
} /* Reset bits for I3C peripheral */
#define INPUTMUX_RSTS \
{ \
kINPUTMUX0_RST_SHIFT_RSTn \
} /* Reset bits for INPUTMUX peripheral */
#define LPUART_RSTS \
{ \
kLPUART0_RST_SHIFT_RSTn, kLPUART1_RST_SHIFT_RSTn, kLPUART2_RST_SHIFT_RSTn \
} /* Reset bits for LPUART peripheral */
#define LPSPI_RSTS \
{ \
kLPSPI0_RST_SHIFT_RSTn, kLPSPI0_RST_SHIFT_RSTn \
} /* Reset bits for LPSPI peripheral */
#define LPI2C_RSTS \
{ \
kLPI2C0_RST_SHIFT_RSTn \
} /* Reset bits for LPI2C peripheral */
#define LPCMP_RSTS \
{ \
NotAvail_RSTn, kCMP1_RST_SHIFT_RSTn \
} /* Reset bits for LPCMP peripheral */
#define OSTIMER_RSTS \
{ \
kOSTIMER0_RST_SHIFT_RSTn \
} /* Reset bits for OSTIMER peripheral */
#define PORT_RSTS_N \
{ \
kPORT0_RST_SHIFT_RSTn, kPORT1_RST_SHIFT_RSTn, kPORT2_RST_SHIFT_RSTn, kPORT3_RST_SHIFT_RSTn \
} /* Reset bits for PORT peripheral */
#define EQDC_RSTS \
{ \
kQDC0_RST_SHIFT_RSTn \
} /* Reset bits for EQDC peripheral */
#define UTICK_RSTS \
{ \
kUTICK0_RST_SHIFT_RSTn \
} /* Reset bits for UTICK peripheral */
typedef SYSCON_RSTn_t reset_ip_name_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Assert reset to peripheral.
*
* Asserts reset signal to specified peripheral module.
*
* @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
/*!
* @brief Clear reset to peripheral.
*
* Clears reset signal to specified peripheral module, allows it to operate.
*
* @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
/*!
* @brief Reset peripheral module.
*
* Reset peripheral module.
*
* @param peripheral Peripheral to reset. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
void RESET_PeripheralReset(reset_ip_name_t peripheral);
/*!
* @brief Release peripheral module.
*
* Release peripheral module.
*
* @param peripheral Peripheral to release. The enum argument contains encoding of reset register
* and reset bit position in the reset register.
*/
static inline void RESET_ReleasePeripheralReset(reset_ip_name_t peripheral)
{
RESET_SetPeripheralReset(peripheral);
}
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_RESET_H_ */

View File

@ -0,0 +1,172 @@
/*
* Copyright 2023, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_ROMAPI_H_
#define _FSL_ROMAPI_H_
#include "fsl_common.h"
/*!
* @addtogroup romapi
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.romapi"
#endif
/*! @name Driver version */
/*@{*/
/*! @brief romapi driver version 2.0.0. */
#define FSL_ROMAPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*!
* @brief Enumeration for various flash properties.
*/
typedef enum _flash_property_tag
{
kFLASH_PropertyPflashSectorSize = 0x00U, /*!< Pflash sector size property.*/
kFLASH_PropertyPflashTotalSize = 0x01U, /*!< Pflash total size property.*/
kFLASH_PropertyPflashBlockSize = 0x02U, /*!< Pflash block size property.*/
kFLASH_PropertyPflashBlockCount = 0x03U, /*!< Pflash block count property.*/
kFLASH_PropertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/
kFLASH_PropertyPflashPageSize = 0x30U, /*!< Pflash page size property.*/
kFLASH_PropertyPflashSystemFreq = 0x31U, /*!< System Frequency property.*/
kFLASH_PropertyFfrSectorSize = 0x40U, /*!< FFR sector size property.*/
kFLASH_PropertyFfrTotalSize = 0x41U, /*!< FFR total size property.*/
kFLASH_PropertyFfrBlockBaseAddr = 0x42U, /*!< FFR block base address property.*/
kFLASH_PropertyFfrPageSize = 0x43U, /*!< FFR page size property.*/
} flash_property_tag_t;
/*! @brief Flash controller paramter config. */
typedef struct _flash_ffr_config
{
uint32_t ffrBlockBase;
uint32_t ffrTotalSize;
uint32_t ffrPageSize;
uint32_t sectorSize;
uint32_t cfpaPageVersion;
uint32_t cfpaPageOffset;
} flash_ffr_config_t;
/*! @brief Flash driver state information.
*
* An instance of this structure is allocated by the user of the flash driver and
* passed into each of the driver APIs.
*/
typedef struct _flash_config
{
uint32_t PFlashBlockBase; /*!< A base address of the first PFlash block */
uint32_t PFlashTotalSize; /*!< The size of the combined PFlash block. */
uint32_t PFlashBlockCount; /*!< A number of PFlash blocks. */
uint32_t PFlashPageSize; /*!< The size in bytes of a page of PFlash. */
uint32_t PFlashSectorSize; /*!< The size in bytes of a sector of PFlash. */
flash_ffr_config_t ffrConfig;
} flash_config_t;
/*! @brief Interface for the flash driver. */
typedef struct _flash_driver_interface
{
/* Flash driver */
status_t (*flash_init)(flash_config_t *config);
status_t (*flash_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key);
status_t (*flash_program_phrase)(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes);
status_t (*flash_program_page)(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes);
status_t (*flash_verify_program)(flash_config_t *config,
uint32_t start,
uint32_t lengthInBytes,
const uint8_t *expectedData,
uint32_t *failedAddress,
uint32_t *failedData);
status_t (*flash_verify_erase_phrase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*flash_verify_erase_page)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*flash_verify_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*flash_get_property)(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value);
/* IFR driver */
status_t (*ifr_verify_erase_phrase)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*ifr_verify_erase_page)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*ifr_verify_erase_sector)(flash_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*flash_read)(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
/* version */
uint32_t version;
} flash_driver_interface_t;
/*! @brief Constructs the four character code for the Flash driver API key. */
#if !defined(FOUR_CHAR_CODE)
#define FOUR_CHAR_CODE(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a)))
#endif
/*!
* @brief Enumeration for Flash driver API keys.
*
* @note The resulting value is built with a byte order such that the string
* being readable in expected order when viewed in a hex editor, if the value
* is treated as a 32-bit little endian value.
*/
enum _flash_driver_api_keys
{
kFLASH_ApiEraseKey = FOUR_CHAR_CODE('l', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/
};
/* API prototype fields definition.
| 31 : 24 | 23 : 20 | 19 : 16 | 15 : 12 | 11 : 8 | 7 0 |
| Tag | Boot mode | bootloader periphal| Instance | Image Index| Reserved |
| | | | Used For Boot mode 0| | |
| | 0: Passive mode | 0 - Auto detection | | | |
| | 1: ISP mode | 1 - USB-HID | | | |
| | | 2 - UART | | | |
| | | 3 - SPI | | | |
| | | 4 - I2C | | | |
| | | 5 - CAN | | | |
*/
typedef struct
{
union
{
struct
{
uint32_t reserved : 8;
uint32_t boot_image_index : 4;
uint32_t instance : 4;
uint32_t boot_interface : 4;
uint32_t mode : 4;
uint32_t tag : 8;
} B;
uint32_t U;
} option;
} user_app_boot_invoke_option_t;
/*! @brief Root of the bootloader API tree.
*
* An instance of this struct resides in read-only memory in the bootloader. It
* provides a user application access to APIs exported by the bootloader.
*
*/
typedef struct _bootloader_tree
{
void (*run_bootloader)(void *arg); /*!< Function to start the bootloader executing. */
const flash_driver_interface_t *flash_driver; /*!< Internal Flash driver API. */
void (*jump)(void *arg);
} bootloader_tree_t;
/** ROM API base address */
#define ROM_API_BASE (0x03003fe0u)
/** ROM API base pointer */
#define ROM_API ((bootloader_tree_t *)ROM_API_BASE)
/** FLASH API base pointer */
#define FLASH_API (ROM_API->flash_driver)
/*! @} */
#endif /* _FSL_RESET_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,230 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019, 2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_utick.h"
#if !(defined(FSL_FEATURE_UTICK_HAS_NO_PDCFG) && FSL_FEATURE_UTICK_HAS_NO_PDCFG)
#include "fsl_power.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.utick"
#endif
/* Typedef for interrupt handler. */
typedef void (*utick_isr_t)(UTICK_Type *base, utick_callback_t cb);
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the instance from the base address
*
* @param base UTICK peripheral base address
*
* @return The UTICK instance
*/
static uint32_t UTICK_GetInstance(UTICK_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of UTICK handle. */
static utick_callback_t s_utickHandle[FSL_FEATURE_SOC_UTICK_COUNT];
/* Array of UTICK peripheral base address. */
static UTICK_Type *const s_utickBases[] = UTICK_BASE_PTRS;
/* Array of UTICK IRQ number. */
static const IRQn_Type s_utickIRQ[] = UTICK_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of UTICK clock name. */
static const clock_ip_name_t s_utickClock[] = UTICK_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_UTICK_HAS_NO_RESET) && FSL_FEATURE_UTICK_HAS_NO_RESET)
/*! @brief Pointers to UTICK resets for each instance. */
static const reset_ip_name_t s_utickResets[] = UTICK_RSTS;
#endif
/* UTICK ISR for transactional APIs. */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
static utick_isr_t s_utickIsr = (utick_isr_t)DefaultISR;
#else
static utick_isr_t s_utickIsr;
#endif
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t UTICK_GetInstance(UTICK_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_utickBases); instance++)
{
if (s_utickBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_utickBases));
return instance;
}
/*!
* brief Starts UTICK.
*
* This function starts a repeat/onetime countdown with an optional callback
*
* param base UTICK peripheral base address.
* param mode UTICK timer mode (ie kUTICK_onetime or kUTICK_repeat)
* param count UTICK timer mode (ie kUTICK_onetime or kUTICK_repeat)
* param cb UTICK callback (can be left as NULL if none, otherwise should be a void func(void))
* return none
*/
void UTICK_SetTick(UTICK_Type *base, utick_mode_t mode, uint32_t count, utick_callback_t cb)
{
uint32_t instance;
/* Get instance from peripheral base address. */
instance = UTICK_GetInstance(base);
/* Save the handle in global variables to support the double weak mechanism. */
s_utickHandle[instance] = cb;
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) && \
!(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS))
EnableDeepSleepIRQ(s_utickIRQ[instance]);
#else
(void)EnableIRQ(s_utickIRQ[instance]);
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT && !FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
base->CTRL = count | UTICK_CTRL_REPEAT(mode);
}
/*!
* brief Initializes an UTICK by turning its bus clock on
*
*/
void UTICK_Init(UTICK_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable utick clock */
CLOCK_EnableClock(s_utickClock[UTICK_GetInstance(base)]);
#endif
#if !(defined(FSL_FEATURE_UTICK_HAS_NO_RESET) && FSL_FEATURE_UTICK_HAS_NO_RESET)
RESET_PeripheralReset(s_utickResets[UTICK_GetInstance(base)]);
#endif
#if !(defined(FSL_FEATURE_UTICK_HAS_NO_PDCFG) && FSL_FEATURE_UTICK_HAS_NO_PDCFG)
/* Power up Watchdog oscillator*/
POWER_DisablePD(kPDRUNCFG_PD_WDT_OSC);
#endif
s_utickIsr = UTICK_HandleIRQ;
}
/*!
* brief Deinitializes a UTICK instance.
*
* This function shuts down Utick bus clock
*
* param base UTICK peripheral base address.
*/
void UTICK_Deinit(UTICK_Type *base)
{
/* Turn off utick */
base->CTRL = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable utick clock */
CLOCK_DisableClock(s_utickClock[UTICK_GetInstance(base)]);
#endif
}
/*!
* brief Get Status Flags.
*
* This returns the status flag
*
* param base UTICK peripheral base address.
* return status register value
*/
uint32_t UTICK_GetStatusFlags(UTICK_Type *base)
{
return (base->STAT);
}
/*!
* brief Clear Status Interrupt Flags.
*
* This clears intr status flag
*
* param base UTICK peripheral base address.
* return none
*/
void UTICK_ClearStatusFlags(UTICK_Type *base)
{
base->STAT = UTICK_STAT_INTR_MASK;
}
/*!
* brief UTICK Interrupt Service Handler.
*
* This function handles the interrupt and refers to the callback array in the driver to callback user (as per request
* in UTICK_SetTick()).
* if no user callback is scheduled, the interrupt will simply be cleared.
*
* param base UTICK peripheral base address.
* param cb callback scheduled for this instance of UTICK
* return none
*/
void UTICK_HandleIRQ(UTICK_Type *base, utick_callback_t cb)
{
UTICK_ClearStatusFlags(base);
if (cb != NULL)
{
cb();
}
}
#if defined(UTICK0)
void UTICK0_DriverIRQHandler(void);
void UTICK0_DriverIRQHandler(void)
{
s_utickIsr(UTICK0, s_utickHandle[0]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UTICK1)
void UTICK1_DriverIRQHandler(void);
void UTICK1_DriverIRQHandler(void)
{
s_utickIsr(UTICK1, s_utickHandle[1]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UTICK2)
void UTICK2_DriverIRQHandler(void);
void UTICK2_DriverIRQHandler(void)
{
s_utickIsr(UTICK2, s_utickHandle[2]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(UTICK)
void UTICK_DriverIRQHandler(void);
void UTICK_DriverIRQHandler(void)
{
s_utickIsr(UTICK, s_utickHandle[0]);
SDK_ISR_EXIT_BARRIER;
}
#endif

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019, 2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_UTICK_H_
#define _FSL_UTICK_H_
#include "fsl_common.h"
/*!
* @addtogroup utick
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief UTICK driver version 2.0.5. */
#define FSL_UTICK_DRIVER_VERSION (MAKE_VERSION(2, 0, 5))
/*@}*/
/*! @brief UTICK timer operational mode. */
typedef enum _utick_mode
{
kUTICK_Onetime = 0x0U, /*!< Trigger once*/
kUTICK_Repeat = 0x1U, /*!< Trigger repeatedly */
} utick_mode_t;
/*! @brief UTICK callback function. */
typedef void (*utick_callback_t)(void);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an UTICK by turning its bus clock on
*
*/
void UTICK_Init(UTICK_Type *base);
/*!
* @brief Deinitializes a UTICK instance.
*
* This function shuts down Utick bus clock
*
* @param base UTICK peripheral base address.
*/
void UTICK_Deinit(UTICK_Type *base);
/*!
* @brief Get Status Flags.
*
* This returns the status flag
*
* @param base UTICK peripheral base address.
* @return status register value
*/
uint32_t UTICK_GetStatusFlags(UTICK_Type *base);
/*!
* @brief Clear Status Interrupt Flags.
*
* This clears intr status flag
*
* @param base UTICK peripheral base address.
* @return none
*/
void UTICK_ClearStatusFlags(UTICK_Type *base);
/*!
* @brief Starts UTICK.
*
* This function starts a repeat/onetime countdown with an optional callback
*
* @param base UTICK peripheral base address.
* @param mode UTICK timer mode (ie kUTICK_onetime or kUTICK_repeat)
* @param count UTICK timer mode (ie kUTICK_onetime or kUTICK_repeat)
* @param cb UTICK callback (can be left as NULL if none, otherwise should be a void func(void))
* @return none
*/
void UTICK_SetTick(UTICK_Type *base, utick_mode_t mode, uint32_t count, utick_callback_t cb);
/*!
* @brief UTICK Interrupt Service Handler.
*
* This function handles the interrupt and refers to the callback array in the driver to callback user (as per request
* in UTICK_SetTick()).
* if no user callback is scheduled, the interrupt will simply be cleared.
*
* @param base UTICK peripheral base address.
* @param cb callback scheduled for this instance of UTICK
* @return none
*/
void UTICK_HandleIRQ(UTICK_Type *base, utick_callback_t cb);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_UTICK_H_ */

View File

@ -0,0 +1,498 @@
/*
* Copyright 2022-2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_vbat.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.mcx_vbat"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Configure internal 16kHz free running oscillator, including enabel FRO16k, gate FRO16k output.
*
* param base VBAT peripheral base address.
* param config Pointer to vbat_fro16k_config_t structure.
*/
void VBAT_ConfigFRO16k(VBAT_Type *base, const vbat_fro16k_config_t *config)
{
assert(config != NULL);
VBAT_EnableFRO16k(base, config->enableFRO16k);
VBAT_UngateFRO16k(base, config->enabledConnectionsMask);
}
#if (defined(FSL_FEATURE_MCX_VBAT_HAS_OSCCTL_REG) && FSL_FEATURE_MCX_VBAT_HAS_OSCCTL_REG)
/*!
* brief Set 32k crystal oscillator mode and load capacitance for the XTAL/EXTAL pin.
*
* param base VBAT peripheral base address.
* param operateMode Specify the crystal oscillator mode, please refer to vbat_osc32k_operate_mode_t.
* param xtalCap Specify the internal capacitance for the XTAL pin from the capacitor bank.
* param extalCap Specify the internal capacitance for the EXTAL pin from the capacitor bank.
*
* retval kStatus_VBAT_WrongCapacitanceValue The load capacitance value to set is not align with operate mode's
* requirements.
* retval kStatus_Success Success to set operate mode and load capacitance.
*/
status_t VBAT_SetCrystalOsc32kModeAndLoadCapacitance(VBAT_Type *base,
vbat_osc32k_operate_mode_t operateMode,
vbat_osc32k_load_capacitance_select_t xtalCap,
vbat_osc32k_load_capacitance_select_t extalCap)
{
if (operateMode == kVBAT_Osc32kEnabledToTransconductanceMode)
{
if (((uint8_t)extalCap & 0x1U) == 0U)
{
return kStatus_VBAT_WrongCapacitanceValue;
}
}
if (operateMode == kVBAT_Osc32kEnabledToLowPowerSwitchedMode)
{
if ((extalCap != kVBAT_Osc32kCrystalLoadCap0pF) && (xtalCap != kVBAT_Osc32kCrystalLoadCap0pF))
{
return kStatus_VBAT_WrongCapacitanceValue;
}
}
if (operateMode == kVBAT_Osc32kEnabledToLowPowerBackupMode)
{
if ((extalCap & 0x1U) != 0U)
{
return kStatus_VBAT_WrongCapacitanceValue;
}
}
if ((xtalCap != kVBAT_Osc32kCrystalLoadCapBankDisabled) && (extalCap != kVBAT_Osc32kCrystalLoadCapBankDisabled))
{
base->OSCCTLA |= VBAT_OSCCTLA_CAP_SEL_EN_MASK;
base->OSCCTLB &= ~VBAT_OSCCTLA_CAP_SEL_EN_MASK;
base->OSCCTLA = ((base->OSCCTLA & ~(VBAT_OSCCTLA_EXTAL_CAP_SEL_MASK | VBAT_OSCCTLA_XTAL_CAP_SEL_MASK)) |
(VBAT_OSCCTLA_XTAL_CAP_SEL(xtalCap) | VBAT_OSCCTLA_EXTAL_CAP_SEL(extalCap)));
base->OSCCTLB = ((base->OSCCTLB & ~(VBAT_OSCCTLA_EXTAL_CAP_SEL_MASK | VBAT_OSCCTLA_XTAL_CAP_SEL_MASK)) |
VBAT_OSCCTLA_XTAL_CAP_SEL(~xtalCap) | VBAT_OSCCTLA_EXTAL_CAP_SEL(~extalCap));
}
base->OSCCTLA = (((base->OSCCTLA & ~VBAT_OSCCTLA_MODE_EN_MASK)) | VBAT_OSCCTLA_MODE_EN(operateMode));
base->OSCCTLB = ((base->OSCCTLB & ~VBAT_OSCCTLA_MODE_EN_MASK) | VBAT_OSCCTLA_MODE_EN((uint8_t)~operateMode));
return kStatus_Success;
}
#endif /* FSL_FEATURE_MCX_VBAT_HAS_OSCCTL_REG */
#if (defined(FSL_FEATURE_MCX_VBAT_HAS_LDOCTL_REG) && FSL_FEATURE_MCX_VBAT_HAS_LDOCTL_REG)
/*!
* brief Enable/disable Bandgap.
*
* note The FRO16K must be enabled before enableing the bandgap.
* note This setting can be locked by VBAT_LockRamLdoSettings() function.
*
* param base VBAT peripheral base address.
* param enable Used to enable/disable bandgap.
* - \b true Enable the bandgap.
* - \b false Disable the bandgap.
*
* retval kStatus_Success Success to enable/disable the bandgap.
* retval kStatus_VBAT_Fro16kNotEnabled Fail to enable the bandgap due to FRO16k is not enabled previously.
*/
status_t VBAT_EnableBandgap(VBAT_Type *base, bool enable)
{
status_t status = kStatus_Success;
if (enable)
{
if (VBAT_CheckFRO16kEnabled(base))
{
base->LDOCTLA |= VBAT_LDOCTLA_BG_EN_MASK;
base->LDOCTLB &= ~VBAT_LDOCTLA_BG_EN_MASK;
}
else
{
/* FRO16K must be enabled before enabling the Bandgap. */
status = kStatus_VBAT_Fro16kNotEnabled;
}
}
else
{
base->LDOCTLA &= ~VBAT_LDOCTLA_BG_EN_MASK;
base->LDOCTLB |= VBAT_LDOCTLA_BG_EN_MASK;
}
return status;
}
/*!
* brief Enable/disable Backup RAM Regulator(RAM_LDO).
*
* note This setting can be locked by VBAT_LockRamLdoSettings() function.
*
* param base VBAT peripheral base address.
* param enable Used to enable/disable RAM_LDO.
* - \b true Enable backup SRAM regulator.
* - \b false Disable backup SRAM regulator.
*
* retval kStatusSuccess Success to enable/disable backup SRAM regulator.
* retval kStatus_VBAT_Fro16kNotEnabled Fail to enable backup SRAM regulator due to FRO16k is not enabled previously.
* retval kStatus_VBAT_BandgapNotEnabled Fail to enable backup SRAM regulator due to the bandgap is not enabled
* previously.
*/
status_t VBAT_EnableBackupSRAMRegulator(VBAT_Type *base, bool enable)
{
status_t status = kStatus_Success;
if (enable)
{
if (VBAT_CheckFRO16kEnabled(base))
{
if (VBAT_CheckBandgapEnabled(base))
{
base->LDOCTLA |= VBAT_LDOCTLA_LDO_EN_MASK;
base->LDOCTLB &= ~VBAT_LDOCTLA_LDO_EN_MASK;
/* Polling until LDO is enabled. */
while ((base->STATUSA & VBAT_STATUSA_LDO_RDY_MASK) == 0UL)
{
}
}
else
{
/* The bandgap must be enabled previously. */
status = kStatus_VBAT_BandgapNotEnabled;
}
}
else
{
/* FRO16k must be enabled previously. */
status = kStatus_VBAT_Fro16kNotEnabled;
}
}
else
{
base->LDOCTLA &= ~VBAT_LDOCTLA_LDO_EN_MASK;
base->LDOCTLB |= VBAT_LDOCTLA_LDO_EN_MASK;
}
return status;
}
/*!
* brief Switch the SRAM to be powered by VBAT.
*
* param base VBAT peripheral base address.
*
* retval kStatusSuccess Success to Switch SRAM powered by VBAT.
* retval kStatus_VBAT_Fro16kNotEnabled Fail to switch SRAM powered by VBAT due to FRO16K not enabled previously.
*/
status_t VBAT_SwitchSRAMPowerByLDOSRAM(VBAT_Type *base)
{
status_t status = kStatus_Success;
status = VBAT_EnableBandgap(base, true);
if (status == kStatus_Success)
{
VBAT_EnableBandgapRefreshMode(base, true);
(void)VBAT_EnableBackupSRAMRegulator(base, true);
/* Isolate the SRAM array */
base->LDORAMC |= VBAT_LDORAMC_ISO_MASK;
/* Switch the supply to VBAT LDO. */
base->LDORAMC |= VBAT_LDORAMC_SWI_MASK;
}
return status;
}
#endif /* FSL_FEATURE_MCX_VBAT_HAS_LDOCTL_REG */
#if (defined(FSL_FEATURE_MCX_VBAT_HAS_BANDGAP_TIMER) && FSL_FEATURE_MCX_VBAT_HAS_BANDGAP_TIMER)
/*!
* brief Enable/disable Bandgap timer.
*
* note The bandgap timer is available when the bandgap is enabled and are clocked by the FRO16k.
*
* param base VBAT peripheral base address.
* param enable Used to enable/disable bandgap timer.
* param timerIdMask The mask of bandgap timer Id, should be the OR'ed value of vbat_bandgap_timer_id_t.
*
* retval kStatus_Success Success to enable/disable selected bandgap timer.
* retval kStatus_VBAT_Fro16kNotEnabled Fail to enable/disable selected bandgap timer due to FRO16k not enabled
* previously. retval kStatus_VBAT_BandgapNotEnabled Fail to enable/disable selected bandgap timer due to bandgap not
* enabled previously.
*/
status_t VBAT_EnableBandgapTimer(VBAT_Type *base, bool enable, uint8_t timerIdMask)
{
status_t status = kStatus_Success;
if (enable)
{
if (VBAT_CheckFRO16kEnabled(base))
{
if (VBAT_CheckBandgapEnabled(base))
{
if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer0) != 0U)
{
base->LDOTIMER0 |= VBAT_LDOTIMER0_TIMEN_MASK;
}
if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer1) != 0U)
{
base->LDOTIMER1 |= VBAT_LDOTIMER1_TIMEN_MASK;
}
}
else
{
/* Bandgap must be enabled previously. */
status = kStatus_VBAT_BandgapNotEnabled;
}
}
else
{
/* FRO16K must be enabled previously. */
status = kStatus_VBAT_Fro16kNotEnabled;
}
}
else
{
if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer0) != 0U)
{
base->LDOTIMER0 &= ~VBAT_LDOTIMER0_TIMEN_MASK;
}
if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer1) != 0U)
{
base->LDOTIMER1 &= ~VBAT_LDOTIMER1_TIMEN_MASK;
}
}
return status;
}
/*!
* brief Set bandgap timer0 timeout value.
*
* param base VBAT peripheral base address.
* param timeoutPeriod Bandgap timer timeout value, please refer to vbat_bandgap_timer0_timeout_period_t.
*/
void VBAT_SetBandgapTimer0TimeoutValue(VBAT_Type *base, vbat_bandgap_timer0_timeout_period_t timeoutPeriod)
{
bool timerEnabled = false;
timerEnabled = ((base->LDOTIMER0 & VBAT_LDOTIMER0_TIMEN_MASK) != 0UL) ? true : false;
if (timerEnabled)
{
base->LDOTIMER0 &= ~VBAT_LDOTIMER0_TIMEN_MASK;
}
base->LDOTIMER0 = ((base->LDOTIMER0 & (~VBAT_LDOTIMER0_TIMCFG_MASK)) | VBAT_LDOTIMER0_TIMCFG(timeoutPeriod));
if (timerEnabled)
{
base->LDOTIMER0 |= VBAT_LDOTIMER0_TIMEN_MASK;
}
}
/*!
* brief Set bandgap timer1 timeout value.
*
* note The timeout value can only be changed when the timer is disabled.
*
* param base VBAT peripheral base address.
* param timeoutPeriod The bandgap timerout 1 period, in number of seconds, ranging from 0 to 65535s.
*/
void VBAT_SetBandgapTimer1TimeoutValue(VBAT_Type *base, uint32_t timeoutPeriod)
{
bool timerEnabled = false;
timerEnabled = ((base->LDOTIMER1 & VBAT_LDOTIMER1_TIMEN_MASK) != 0UL) ? true : false;
if (timerEnabled)
{
base->LDOTIMER1 &= ~VBAT_LDOTIMER1_TIMEN_MASK;
}
base->LDOTIMER1 = ((base->LDOTIMER1 & (~VBAT_LDOTIMER1_TIMCFG_MASK)) | VBAT_LDOTIMER1_TIMCFG(timeoutPeriod));
if (timerEnabled)
{
base->LDOTIMER1 |= VBAT_LDOTIMER1_TIMEN_MASK;
}
}
#endif /* FSL_FEATURE_MCX_VBAT_HAS_BANDGAP_TIMER */
#if (defined(FSL_FEATURE_MCX_VBAT_HAS_CLKMON_REG) && FSL_FEATURE_MCX_VBAT_HAS_CLKMON_REG)
/*!
* brief Initializes the VBAT clock monitor, enable clock monitor and set the clock monitor configuration.
*
* note Both FRO16K and OSC32K should be enabled and stable before invoking this function.
*
* param base VBAT peripheral base address.
* param config Pointer to vbat_clock_monitor_config_t structure.
*
* retval kStatus_Success Clock monitor is initialized successfully.
* retval kStatus_VBAT_Fro16kNotEnabled FRO16K is not enabled.
* retval kStatus_VBAT_Osc32kNotReady OSC32K is not ready.
* retval kStatus_VBAT_ClockMonitorLocked Clock monitor is locked.
*/
status_t VBAT_InitClockMonitor(VBAT_Type *base, const vbat_clock_monitor_config_t *config)
{
assert(config != NULL);
status_t status = kStatus_Success;
if (VBAT_CheckFRO16kEnabled(base))
{
if ((VBAT_GetStatusFlags(base) & kVBAT_StatusFlagOsc32kReady) != 0UL)
{
if (VBAT_CheckClockMonitorControlLocked(base))
{
status = kStatus_VBAT_ClockMonitorLocked;
}
else
{
/* Disable clock monitor before configuring clock monitor. */
VBAT_EnableClockMonitor(base, false);
/* Set clock monitor divide trim value. */
VBAT_SetClockMonitorDivideTrim(base, config->divideTrim);
/* Set clock monitor frequency trim value. */
VBAT_SetClockMonitorFrequencyTrim(base, config->freqTrim);
/* Enable clock monitor. */
VBAT_EnableClockMonitor(base, true);
if (config->lock)
{
VBAT_LockClockMonitorControl(base);
}
}
}
else
{
status = kStatus_VBAT_OSC32KNotReady;
}
}
else
{
status = kStatus_VBAT_Fro16kNotEnabled;
}
return status;
}
/*!
* brief Deinitialize the VBAT clock monitor.
*
* param base VBAT peripheral base address.
*
* retval kStatus_Success Clock monitor is de-initialized successfully.
* retval kStatus_VBAT_ClockMonitorLocked Control of Clock monitor is locked.
*/
status_t VBAT_DeinitMonitor(VBAT_Type *base)
{
if (VBAT_CheckClockMonitorControlLocked(base))
{
return kStatus_VBAT_ClockMonitorLocked;
}
VBAT_EnableClockMonitor(base, false);
return kStatus_Success;
}
#endif /* FSL_FEATURE_MCX_VBAT_HAS_CLKMON_REG */
#if (defined(FSL_FEATURE_MCX_VBAT_HAS_TAMPER_REG) && FSL_FEATURE_MCX_VBAT_HAS_TAMPER_REG)
/*!
* brief Initialize tamper control.
*
* note Both FRO16K and bandgap should be enabled before calling this function.
*
* param base VBAT peripheral base address.
* param config Pointer to vbat_tamper_config_t structure.
*
* retval kStatus_Success Tamper is initialized successfully.
* retval kStatus_VBAT_TamperLocked Tamper control is locked.
* retval kStatus_VBAT_BandgapNotEnabled Bandgap is not enabled.
* retval kStatus_VBAT_Fro16kNotEnabled FRO 16K is not enabled.
*/
status_t VBAT_InitTamper(VBAT_Type *base, const vbat_tamper_config_t *config)
{
assert(config != NULL);
status_t status = kStatus_Success;
if (VBAT_CheckFRO16kEnabled(base))
{
if (VBAT_CheckBandgapEnabled(base))
{
if (VBAT_CheckTamperControlLocked(base))
{
return kStatus_VBAT_TamperLocked;
}
else
{
base->TAMCTLA = ((base->TAMCTLA & (~VBAT_TAMCTLA_VOLT_EN_MASK | VBAT_TAMCTLA_TEMP_EN_MASK)) |
VBAT_TAMCTLA_VOLT_EN(config->enableVoltageDetect) |
VBAT_TAMCTLA_TEMP_EN(config->enableTemperatureDetect));
base->TAMCTLB = ((base->TAMCTLB & (~VBAT_TAMCTLA_VOLT_EN_MASK | VBAT_TAMCTLA_TEMP_EN_MASK)) |
VBAT_TAMCTLA_VOLT_EN((config->enableVoltageDetect) ? 0U : 1U) |
VBAT_TAMCTLA_TEMP_EN((config->enableTemperatureDetect) ? 0U : 1U));
if (config->lock)
{
VBAT_LockTamperControl(base);
}
}
}
else
{
status = kStatus_VBAT_BandgapNotEnabled;
}
}
else
{
status = kStatus_VBAT_Fro16kNotEnabled;
}
return status;
}
/*!
* brief De-initialize tamper control.
*
* param base VBAT peripheral base address.
*
* retval kStatus_Success Tamper is de-initialized successfully.
* retval kStatus_VBAT_TamperLocked Tamper control is locked.
*/
status_t VBAT_DeinitTamper(VBAT_Type *base)
{
if (VBAT_CheckTamperControlLocked(base))
{
return kStatus_VBAT_TamperLocked;
}
base->TAMCTLA &= ~(VBAT_TAMCTLA_VOLT_EN_MASK | VBAT_TAMCTLA_TEMP_EN_MASK);
base->TAMCTLB |= (VBAT_TAMCTLA_VOLT_EN_MASK | VBAT_TAMCTLA_TEMP_EN_MASK);
return kStatus_Success;
}
#endif /* FSL_FEATURE_MCX_VBAT_HAS_TAMPER_REG */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,253 @@
/*
* Copyright 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_waketimer.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.waketimer"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* brief Gets the instance from the base address
*
* param base WAKETIMER peripheral base address
*
* return The WAKETIMER instance
*/
static uint32_t WAKETIMER_GetInstance(WAKETIMER_Type *base);
/*!
* brief WAKETIMER generic IRQ handle function.
*
* param index WAKETIMER peripheral instance index.
*/
static void WAKETIMER_GenericIRQHandler(WAKETIMER_Type *base, waketimer_callback_t callback);
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of WAKETIMER peripheral base address. */
static WAKETIMER_Type *const s_waketimerBases[] = WAKETIMER_BASE_PTRS;
/* Array of WAKETIMER ISR. */
static waketimer_callback_t s_waketimerCallback[sizeof(s_waketimerBases) / sizeof(s_waketimerBases[0])];
/* Array of WAKETIMER IRQ number. */
static const IRQn_Type s_waketimerIRQ[] = WAKETIMER_IRQS;
/*******************************************************************************
* Code
******************************************************************************/
/* brief Function for getting the instance number of Waketimer. */
static uint32_t WAKETIMER_GetInstance(WAKETIMER_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_waketimerBases); instance++)
{
if (s_waketimerBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_waketimerBases));
return instance;
}
/*!
* brief Initializes an WAKETIMER.
* param base WAKETIMER peripheral base address.
*/
void WAKETIMER_Init(WAKETIMER_Type *base, const waketimer_config_t *config)
{
assert(NULL != base);
uint32_t index = WAKETIMER_GetInstance(base);
/* Halt timer */
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_CLR_WAKE_TIMER_MASK;
/* Set OSC divide */
if (config->enableOSCDivide)
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_OSC_DIV_ENA_MASK;
}
else
{
base->WAKE_TIMER_CTRL &= ~WAKETIMER_WAKE_TIMER_CTRL_OSC_DIV_ENA_MASK;
}
/* Set callback */
s_waketimerCallback[index] = config->callback;
/* Set interrupt */
if (config->enableInterrupt)
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
(void)EnableIRQ(s_waketimerIRQ[index]);
}
else
{
base->WAKE_TIMER_CTRL &= ~WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
(void)DisableIRQ(s_waketimerIRQ[index]);
}
}
/*!
* brief Deinitializes a WAKETIMER instance.
*
* This function deinitializes the WAKETIMER.
*
* param base WAKETIMER peripheral base address.
*/
void WAKETIMER_Deinit(WAKETIMER_Type *base)
{
assert(NULL != base);
uint32_t index = WAKETIMER_GetInstance(base);
/* Disable IRQ at NVIC Level */
(void)DisableIRQ(s_waketimerIRQ[index]);
}
/*!
* brief Fills in the WAKETIMER configuration structure with the default settings.
*
* The default values are:
* code
* config->enableInterrupt = true;
* config->enableOSCDivide = true;
* config->callback = NULL;
* endcode
* param config Pointer to the user configuration structure.
*/
void WAKETIMER_GetDefaultConfig(waketimer_config_t *config)
{
config->enableInterrupt = true;
config->enableOSCDivide = true;
config->callback = NULL;
}
/*!
* brief Enables the selected WAKETIMER interrupts.
*
* param base WAKETIMER peripheral base address
* param mask Mask value for interrupt events. See to #_waketimer_interrupt_enable
*/
void WAKETIMER_EnableInterrupts(WAKETIMER_Type *base, uint32_t mask)
{
assert(NULL != base);
if (0U != (mask & (uint32_t)kWAKETIMER_WakeInterruptEnable))
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
}
}
/*!
* brief Disable the selected WAKETIMER interrupts.
*
* param base WAKETIMER peripheral base address
* param mask Mask value for interrupt events. See to #_waketimer_interrupt_enable
*/
void WAKETIMER_DisableInterrupts(WAKETIMER_Type *base, uint32_t mask)
{
assert(NULL != base);
if (0U != (mask & (uint32_t)kWAKETIMER_WakeInterruptEnable))
{
base->WAKE_TIMER_CTRL &= ~WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK;
}
}
/*!
* brief Clear Status Interrupt Flag.
*
* This clears intrrupt status flag.
* Currently, only match interrupt flag can be cleared.
*
* param base WAKETIMER peripheral base address.
* param mask Mask value for flags to be cleared. See to #_waketimer_status_flags.
* return none
*/
void WAKETIMER_ClearStatusFlags(WAKETIMER_Type *base, uint32_t mask)
{
if (0U != (mask & (uint32_t)kWAKETIMER_WakeFlag))
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_WAKE_FLAG_MASK;
}
}
/*!
* brief Receive noticification when waketime countdown.
*
* If the interrupt for the waketime countdown is enabled, then a callback can be registered
* which will be invoked when the event is triggered
*
* param base WAKETIMER peripheral base address
* param callback Function to invoke when the event is triggered
*/
void WAKETIMER_SetCallback(WAKETIMER_Type *base, waketimer_callback_t callback)
{
assert(NULL != base);
uint32_t index = WAKETIMER_GetInstance(base);
s_waketimerCallback[index] = callback;
}
/*!
* brief Get current timer count value from WAKETIMER.
*
* This function will get a decimal timer count value.
* The RAW value of timer count is gray code format, will be translated to decimal data internally.
*
* param base WAKETIMER peripheral base address.
* return Value of WAKETIMER which will formated to decimal value.
*/
uint32_t WAKETIMER_GetCurrentTimerValue(WAKETIMER_Type *base)
{
uint32_t value1 = 0;
uint32_t value2 = 0;
do
{
value1 = base->WAKE_TIMER_CNT;
value2 = base->WAKE_TIMER_CNT;
} while (value1 != value2);
return value1;
}
static void WAKETIMER_GenericIRQHandler(WAKETIMER_Type *base, waketimer_callback_t callback)
{
/* Clear interrupt flag. */
WAKETIMER_ClearStatusFlags(base, (uint32_t)kWAKETIMER_WakeFlag);
if (callback != NULL)
{
callback();
}
}
#if defined(WAKETIMER0)
void WAKETIMER0_DriverIRQHandler(void);
void WAKETIMER0_DriverIRQHandler(void)
{
WAKETIMER_GenericIRQHandler(WAKETIMER0, s_waketimerCallback[0]);
SDK_ISR_EXIT_BARRIER;
}
#endif

View File

@ -0,0 +1,212 @@
/*
* Copyright 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_WAKETIMER_H_
#define _FSL_WAKETIMER_H_
#include "fsl_common.h"
/*!
* @addtogroup waketimer
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief WAKETIMER driver version. */
#define FSL_WAKETIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/
/*!
* @brief WAKETIMER status flags.
*/
enum _waketimer_status_flags
{
kWAKETIMER_WakeFlag =
(WAKETIMER_WAKE_TIMER_CTRL_WAKE_FLAG_MASK), /*!< Wake Timer Status Flag, sets wake timer has timed out. */
};
/*!
* @brief Define interrupt switchers of the module.
*/
enum _waketimer_interrupt_enable
{
kWAKETIMER_WakeInterruptEnable = WAKETIMER_WAKE_TIMER_CTRL_INTR_EN_MASK, /*!< Generate interrupt
requests when WAKE_FLAG is asserted. */
};
/*! @brief waketimer callback function. */
typedef void (*waketimer_callback_t)(void);
/*!
* @brief WAKETIMER configuration structure
*
* This structure holds the configuration settings for the WAKETIMER peripheral. To initialize this
* structure to reasonable defaults, call the WAKETIMER_GetDefaultConfig() function and pass a
* pointer to the configuration structure instance.
*
* The configuration structure can be made constant so as to reside in flash.
*/
typedef struct _waketimer_config
{
bool enableOSCDivide; /*!< true: Enable OSC Divide.
false: Disable OSC Divide. */
bool enableInterrupt; /*!< true: Enable interrupt.
false: Disable interrupt. */
waketimer_callback_t callback; /*!< timer countdown callback. */
} waketimer_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an WAKETIMER
*
* This function initializes the WAKETIMER.
*
* @param base WAKETIMER peripheral base address.
* @param config Pointer to the user configuration structure.
*/
void WAKETIMER_Init(WAKETIMER_Type *base, const waketimer_config_t *config);
/*!
* @brief Deinitializes a WAKETIMER instance.
*
* This function deinitialize the WAKETIMER.
*
* @param base WAKETIMER peripheral base address.
*/
void WAKETIMER_Deinit(WAKETIMER_Type *base);
/*!
* @brief Fills in the WAKETIMER configuration structure with the default settings.
*
* The default values are:
* @code
* config->enableInterrupt = true;
* config->enableOSCDivide = true;
* config->callback = NULL;
* @endcode
* @param config Pointer to the user configuration structure.
*/
void WAKETIMER_GetDefaultConfig(waketimer_config_t *config);
/*! @}*/
/*!
* @name Interrupt Interface
* @{
*/
/*!
* @brief Enables the selected WAKETIMER interrupts.
*
* @param base WAKETIMER peripheral base address
* @param mask Mask value for interrupt events. See to #_waketimer_interrupt_enable
*/
void WAKETIMER_EnableInterrupts(WAKETIMER_Type *base, uint32_t mask);
/*!
* @brief Enables the selected WAKETIMER interrupts.
*
* @param base WAKETIMER peripheral base address
* @param mask Mask value for interrupt events. See to #_waketimer_interrupt_enable
*/
void WAKETIMER_DisableInterrupts(WAKETIMER_Type *base, uint32_t mask);
/*!
* @brief Clear Status Interrupt Flag.
*
* This clears intrrupt status flag.
* Currently, only match interrupt flag can be cleared.
*
* @param base WAKETIMER peripheral base address.
* @param mask Mask value for flags to be cleared. See to #_waketimer_status_flags.
* @return none
*/
void WAKETIMER_ClearStatusFlags(WAKETIMER_Type *base, uint32_t mask);
/*!
* @brief Receive noticification when waketime countdown.
*
* If the interrupt for the waketime countdown is enabled, then a callback can be registered
* which will be invoked when the event is triggered
*
* @param base WAKETIMER peripheral base address
* @param callback Function to invoke when the event is triggered
*/
void WAKETIMER_SetCallback(WAKETIMER_Type *base, waketimer_callback_t callback);
/*! @}*/
/*!
* @name Timer Start and Stop
* @{
*/
/*!
* @brief Halt and clear timer counter.
*
* This halt and clear timer counter.
*
* @param base WAKETIMER peripheral base address.
* @return none
*/
static inline void WAKETIMER_HaltTimer(WAKETIMER_Type *base)
{
base->WAKE_TIMER_CTRL |= WAKETIMER_WAKE_TIMER_CTRL_CLR_WAKE_TIMER_MASK;
}
/*!
* @brief Set timer counter.
*
* This set the timer counter and start the timer countdown.
*
* @param base WAKETIMER peripheral base address.
* @param value countdown value.
* @return none
*/
static inline void WAKETIMER_StartTimer(WAKETIMER_Type *base, uint32_t value)
{
base->WAKE_TIMER_CNT = value;
}
/*!
* @brief Get current timer count value from WAKETIMER.
*
* This function will get a decimal timer count value.
* The RAW value of timer count is gray code format, will be translated to decimal data internally.
*
* @param base WAKETIMER peripheral base address.
* @return Value of WAKETIMER which will be formated to decimal value.
*/
uint32_t WAKETIMER_GetCurrentTimerValue(WAKETIMER_Type *base);
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_WAKETIMER_H_ */

View File

@ -0,0 +1,292 @@
/*
* Copyright 2019-2023 NXP.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_wuu.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.wuu"
#endif
#define WUU_PE_REG_BIT_FIELD_MASK 0x03UL
#define WUU_PDC_REG_BIT_FIELD_MASK 0x03UL
#define WUU_PMC_REG_BIT_FIELD_MASK 0x01UL
#define WUU_ME_REG_WUME_FIELD_MASK 0x01UL
#define WUU_DE_REG_WUME_FIELD_MASK 0x01UL
#define WUU_FILT_REG_FILTE_FIELD_MASK 0x60U
#define WUU_FILT_REG_FILTSET_FIELD_MASK 0x1FU
#define WUU_FDC_REG_FILTC_FIELD_MASK 0x3U
#define WUU_FMC_REG_FILTM_FIELD_MASK 0x1U
#define WUU_FILT_REG_FILTSET_FIELD(x) (((uint32_t)(x) << 5UL) & WUU_FILT_REG_FILTE_FIELD_MASK)
#define WUU_CLEAR_BIT_FIELD_IN_REG(mask, offset) (~((uint32_t)(mask) << (offset)))
#define WUU_SET_BIT_FIELD_IN_REG(val, offset) ((uint32_t)(val) << (offset))
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Enables and Configs External WakeUp Pins.
*
* This function enables/disables the external pin as wakeup input. What's more this
* function configs pins options, including edge detection wakeup event and operate mode.
*
* param base MUU peripheral base address.
* param pinIndex The index of the external input pin. See Reference Manual for the details.
* param config Pointer to wuu_external_wakeup_pin_config_t structure.
*/
void WUU_SetExternalWakeUpPinsConfig(WUU_Type *base, uint8_t pinIndex, const wuu_external_wakeup_pin_config_t *config)
{
assert(config != NULL);
volatile uint32_t *edgeRegBase = NULL;
volatile uint32_t *eventRegBase = NULL;
uint32_t edgeReg;
uint32_t eventReg;
uint32_t modeReg;
uint8_t offset;
/* Calculate offset. */
offset = 2U * (pinIndex & 0xFU);
if (config->edge != kWUU_ExternalPinDisable)
{
/* Based on pin index, get register base address. */
if ((pinIndex >> 4U) != 0U)
{
edgeRegBase = &base->PE2;
eventRegBase = &base->PDC2;
}
else
{
edgeRegBase = &base->PE1;
eventRegBase = &base->PDC1;
}
/* Enable and config the edge detection. */
edgeReg = *edgeRegBase;
edgeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PE_REG_BIT_FIELD_MASK, offset);
edgeReg |= WUU_SET_BIT_FIELD_IN_REG(config->edge, offset);
*edgeRegBase = edgeReg;
/* Config the wakeup event. */
eventReg = *eventRegBase;
eventReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PDC_REG_BIT_FIELD_MASK, offset);
eventReg |= WUU_SET_BIT_FIELD_IN_REG(config->event, offset);
*eventRegBase = eventReg;
/* Config operate mode. */
modeReg = base->PMC;
modeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PMC_REG_BIT_FIELD_MASK, pinIndex);
modeReg |= WUU_SET_BIT_FIELD_IN_REG(config->mode, pinIndex);
base->PMC = modeReg;
}
else
{
/* Based on pin index, get register base address. */
if ((pinIndex >> 4U) != 0U)
{
edgeRegBase = &base->PE2;
}
else
{
edgeRegBase = &base->PE1;
}
edgeReg = *edgeRegBase;
edgeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_PE_REG_BIT_FIELD_MASK, offset);
*edgeRegBase = edgeReg;
}
}
/*!
* brief Config Internal modules' event as the wake up soures.
*
* This function configs the internal modules event as the wake up sources.
*
* param base WUU peripheral base address.
* param moduleIndex The selected internal module. See the Reference Manual for the details.
* param event Select interrupt or DMA/Trigger of the internal module as the wake up source.
*/
void WUU_SetInternalWakeUpModulesConfig(WUU_Type *base, uint8_t moduleIndex, wuu_internal_wakeup_module_event_t event)
{
switch (event)
{
case kWUU_InternalModuleInterrupt:
base->ME |= WUU_SET_BIT_FIELD_IN_REG(WUU_ME_REG_WUME_FIELD_MASK, moduleIndex);
break;
case kWUU_InternalModuleDMATrigger:
base->DE |= WUU_SET_BIT_FIELD_IN_REG(WUU_DE_REG_WUME_FIELD_MASK, moduleIndex);
break;
default:
assert(false);
break;
}
}
/*!
* brief Disable an on-chip internal modules' event as the wakeup sources.
*
* param base WUU peripheral base address.
* param moduleIndex The selected internal module. See the Reference Manual for the details.
* param event The event(interrupt or DMA/trigger) of the internal module to disable.
*/
void WUU_ClearInternalWakeUpModulesConfig(WUU_Type *base, uint8_t moduleIndex, wuu_internal_wakeup_module_event_t event)
{
switch(event)
{
case kWUU_InternalModuleInterrupt:
base->ME &= ~WUU_SET_BIT_FIELD_IN_REG(WUU_ME_REG_WUME_FIELD_MASK, moduleIndex);
break;
case kWUU_InternalModuleDMATrigger:
base->DE &= ~WUU_SET_BIT_FIELD_IN_REG(WUU_DE_REG_WUME_FIELD_MASK, moduleIndex);
break;
default:
assert(false);
break;
}
}
/*!
* brief Configs and Enables Pin filters.
*
* This function configs Pin filter, including pin select, filer operate mode
* filer wakeup event and filter edge detection.
*
* param base WUU peripheral base address.
* param filterIndex The index of the pin filer.
* param config Pointer to wuu_pin_filter_config_t structure.
*/
void WUU_SetPinFilterConfig(WUU_Type *base, uint8_t filterIndex, const wuu_pin_filter_config_t *config)
{
assert(config != NULL);
uint8_t shift;
uint32_t filterReg;
uint32_t eventReg;
uint32_t modeReg;
shift = (filterIndex - 1U) * 8U;
filterReg = base->FILT;
filterReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FILT_REG_FILTE_FIELD_MASK, shift);
filterReg |= WUU_SET_BIT_FIELD_IN_REG(WUU_FILT_REG_FILTSET_FIELD(config->edge), shift);
if (config->edge != kWUU_FilterDisabled)
{
filterReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FILT_REG_FILTSET_FIELD_MASK, shift);
filterReg |= WUU_SET_BIT_FIELD_IN_REG(config->pinIndex, shift);
/* Config wake up event. */
shift = (filterIndex - 1U) * 2U;
eventReg = base->FDC;
eventReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FDC_REG_FILTC_FIELD_MASK, shift);
eventReg |= WUU_SET_BIT_FIELD_IN_REG(config->event, shift);
base->FDC = eventReg;
/* Config operate mode. */
shift = (filterIndex - 1U) * 1U;
modeReg = base->FMC;
modeReg &= WUU_CLEAR_BIT_FIELD_IN_REG(WUU_FMC_REG_FILTM_FIELD_MASK, shift);
modeReg |= WUU_SET_BIT_FIELD_IN_REG(config->mode, shift);
base->FMC = modeReg;
}
base->FILT = filterReg;
}
/*!
* brief Gets the pin filter configuration.
*
* This function gets the pin filter flag.
*
* param base WUU peripheral base address.
* param filterIndex A pin filter index, which starts from 1.
* return True if the flag is a source of the existing low-leakage power mode.
*/
bool WUU_GetPinFilterFlag(WUU_Type *base, uint8_t filterIndex)
{
bool ret = false;
switch (filterIndex)
{
case 1:
ret = ((base->FILT & WUU_FILT_FILTF1_MASK) != 0U);
break;
case 2:
ret = ((base->FILT & WUU_FILT_FILTF2_MASK) != 0U);
break;
default:
ret = false;
break;
}
return ret;
}
/*!
* brief Clears the pin filter configuration.
*
* This function clears the pin filter flag.
*
* param base WUU peripheral base address.
* param filterIndex A pin filter index to clear the flag, starting from 1.
*/
void WUU_ClearPinFilterFlag(WUU_Type *base, uint8_t filterIndex)
{
uint32_t reg;
reg = base->FILT;
/* Clean the W1C bits, in case the flags are cleared by mistake. */
reg &= ~(WUU_FILT_FILTF1_MASK | WUU_FILT_FILTF2_MASK);
reg |= WUU_SET_BIT_FIELD_IN_REG(WUU_FILT_FILTF1_MASK, ((filterIndex - 1U) * 8U));
base->FILT = reg;
}
/*!
* brief Gets the external wakeup source flag.
*
* This function checks the external pin flag to detect whether the MCU is
* woken up by the specific pin.
*
* param base WUU peripheral base address.
* param pinIndex A pin index, which starts from 0.
* return True if the specific pin is a wakeup source.
*/
bool WUU_GetExternalWakeupPinFlag(WUU_Type *base, uint32_t pinIndex)
{
return (0U != (base->PF & (1UL << pinIndex)));
}
/*!
* brief Clears the external wakeup source flag.
*
* This function clears the external wakeup source flag for a specific pin.
*
* param base WUU peripheral base address.
* param pinIndex A pin index, which starts from 0.
*/
void WUU_ClearExternalWakeupPinFlag(WUU_Type *base, uint32_t pinIndex)
{
base->PF = (1UL << pinIndex);
}

View File

@ -0,0 +1,286 @@
/*
* Copyright 2019-2023 NXP.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_WUU_H_
#define _FSL_WUU_H_
#include "fsl_common.h"
/*! @addtogroup wuu */
/*! @{ */
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Defines WUU driver version 2.3.0. */
#define FSL_WUU_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
/*@}*/
/*!
* @brief External WakeUp pin edge detection enumeration.
*/
typedef enum _wuu_external_pin_edge_detection
{
kWUU_ExternalPinDisable = 0x0U, /*!< External input Pin disabled as wake up input. */
kWUU_ExternalPinRisingEdge = 0x1U, /*!< External input Pin enabled with the rising edge detection. */
kWUU_ExternalPinFallingEdge = 0x2U, /*!< External input Pin enabled with the falling edge detection. */
kWUU_ExternalPinAnyEdge = 0x3U, /*!< External input Pin enabled with any change detection. */
} wuu_external_pin_edge_detection_t;
/*!
* @brief External input wake up pin event enumeration.
*/
typedef enum _wuu_external_wakeup_pin_event
{
kWUU_ExternalPinInterrupt = 0x0U, /*!< External input Pin configured as interrupt. */
kWUU_ExternalPinDMARequest = 0x1U, /*!< External input Pin configured as DMA request. */
kWUU_ExternalPinTriggerEvent = 0x2U, /*!< External input Pin configured as Trigger event. */
} wuu_external_wakeup_pin_event_t;
/*!
* @brief External input wake up pin mode enumeration.
*/
typedef enum _wuu_external_wakeup_pin_mode
{
kWUU_ExternalPinActiveDSPD = 0x0U, /*!< External input Pin is active only during Deep Sleep/Power Down Mode. */
kWUU_ExternalPinActiveAlways = 0x1U, /*!< External input Pin is active during all power modes. */
} wuu_external_wakeup_pin_mode_t;
/*!
* @brief Internal module wake up event enumeration.
*/
typedef enum _wuu_internal_wakeup_module_event
{
kWUU_InternalModuleInterrupt = 0x0U, /*!< Internal modules' interrupt as a wakeup source. */
kWUU_InternalModuleDMATrigger = 0x1U, /*!< Internal modules' DMA/Trigger as a wakeup source. */
} wuu_internal_wakeup_module_event_t;
/*!
* @brief Pin filter edge enumeration.
*/
typedef enum _wuu_filter_edge
{
kWUU_FilterDisabled = 0x0U, /*!< Filter disabled. */
kWUU_FilterPosedgeEnable = 0x1U, /*!< Filter posedge detect enabled. */
kWUU_FilterNegedgeEnable = 0x2U, /*!< Filter negedge detect enabled. */
kWUU_FilterAnyEdge = 0x3U, /*!< Filter any edge detect enabled. */
} wuu_filter_edge_t;
/*!
* @brief Pin Filter event enumeration.
*/
typedef enum _wuu_filter_event
{
kWUU_FilterInterrupt = 0x0U, /*!< Filter output configured as interrupt. */
kWUU_FilterDMARequest = 0x1U, /*!< Filter output configured as DMA request. */
kWUU_FilterTriggerEvent = 0x2U, /*!< Filter output configured as Trigger event. */
} wuu_filter_event_t;
/*!
* @brief Pin filter mode enumeration.
*/
typedef enum _wuu_filter_mode
{
kWUU_FilterActiveDSPD = 0x0U, /*!< External input pin filter is active only during Deep Sleep/Power Down Mode. */
kWUU_FilterActiveAlways = 0x1U, /*!< External input Pin filter is active during all power modes. */
} wuu_filter_mode_t;
/*!
* @brief External WakeUp pin configuration
*/
typedef struct _wuu_external_wakeup_pin_config
{
wuu_external_pin_edge_detection_t edge; /*!< External Input pin edge detection. */
wuu_external_wakeup_pin_event_t event; /*!< External Input wakeup Pin event */
wuu_external_wakeup_pin_mode_t mode; /*!< External Input wakeup Pin operate mode. */
} wuu_external_wakeup_pin_config_t;
/*!
* @brief Pin Filter configuration.
*/
typedef struct _wuu_pin_filter_config
{
uint32_t pinIndex; /*!< The index of wakeup pin to be muxxed into filter. */
wuu_filter_edge_t edge; /*!< The edge of the pin digital filter. */
wuu_filter_event_t event; /*!< The event of the filter output. */
wuu_filter_mode_t mode; /*!< The mode of the filter operate. */
} wuu_pin_filter_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name External Wake up Pins Control APIs.
* @{
*/
/*!
* @brief Enables and Configs External WakeUp Pins.
*
* This function enables/disables the external pin as wakeup input. What's more this
* function configs pins options, including edge detection wakeup event and operate mode.
*
* @param base MUU peripheral base address.
* @param pinIndex The index of the external input pin. See Reference Manual for the details.
* @param config Pointer to wuu_external_wakeup_pin_config_t structure.
*/
void WUU_SetExternalWakeUpPinsConfig(WUU_Type *base, uint8_t pinIndex, const wuu_external_wakeup_pin_config_t *config);
/*!
* @brief Gets External Wakeup pin flags.
*
* This function return the external wakeup pin flags.
*
* @param base WUU peripheral base address.
* @return Wakeup flags for all external wakeup pins.
*/
static inline uint32_t WUU_GetExternalWakeUpPinsFlag(WUU_Type *base)
{
return base->PF;
}
/*!
* @brief Clears External WakeUp Pin flags.
*
* This function clears external wakeup pins flags based on the mask.
*
* @param base WUU peripheral base address.
* @param mask The mask of Wakeup pin index to be cleared.
*/
static inline void WUU_ClearExternalWakeUpPinsFlag(WUU_Type *base, uint32_t mask)
{
base->PF = mask;
}
/* @} */
/*!
* @name Internal Wakeup Module control APIs.
* @{
*/
/*!
* @brief Config Internal modules' event as the wake up soures.
*
* This function configs the internal modules event as the wake up sources.
*
* @param base WUU peripheral base address.
* @param moduleIndex The selected internal module. See the Reference Manual for the details.
* @param event Select interrupt or DMA/Trigger of the internal module as the wake up source.
*/
void WUU_SetInternalWakeUpModulesConfig(WUU_Type *base, uint8_t moduleIndex, wuu_internal_wakeup_module_event_t event);
/*!
* @brief Disable an on-chip internal modules' event as the wakeup sources.
*
* @param base WUU peripheral base address.
* @param moduleIndex The selected internal module. See the Reference Manual for the details.
* @param event The event(interrupt or DMA/trigger) of the internal module to disable.
*/
void WUU_ClearInternalWakeUpModulesConfig(WUU_Type *base, uint8_t moduleIndex, wuu_internal_wakeup_module_event_t event);
#if (defined(FSL_FEATURE_WUU_HAS_MF) && FSL_FEATURE_WUU_HAS_MF)
/*!
* @brief Get wakeup flags for internal wakeup modules.
*
* @param base WUU peripheral base address.
* @return Wakeup flags for all internal wakeup modules.
*/
static inline uint32_t WUU_GetModuleInterruptFlag(WUU_Type *base)
{
return base->MF;
}
/*!
* @brief Gets the internal module wakeup source flag.
*
* This function checks the flag to detect whether the system is
* woken up by specific on-chip module interrupt.
*
* @param base WWU peripheral base address.
* @param moduleIndex A module index, which starts from 0.
* @return True if the specific pin is a wake up source.
*/
static inline bool WUU_GetInternalWakeupModuleFlag(WUU_Type *base, uint32_t moduleIndex)
{
return ((1UL << moduleIndex) == (WUU_GetModuleInterruptFlag(base) & (1UL << moduleIndex)));
}
#endif /* FSL_FEATURE_WUU_HAS_MF */
/* @} */
/*!
* @name Pin Filter Control APIs
* @{
*/
/*!
* @brief Configs and Enables Pin filters.
*
* This function configs Pin filter, including pin select, filer operate mode
* filer wakeup event and filter edge detection.
*
* @param base WUU peripheral base address.
* @param filterIndex The index of the pin filer.
* @param config Pointer to wuu_pin_filter_config_t structure.
*/
void WUU_SetPinFilterConfig(WUU_Type *base, uint8_t filterIndex, const wuu_pin_filter_config_t *config);
/*!
* @brief Gets the pin filter configuration.
*
* This function gets the pin filter flag.
*
* @param base WUU peripheral base address.
* @param filterIndex A pin filter index, which starts from 1.
* @return True if the flag is a source of the existing low-leakage power mode.
*/
bool WUU_GetPinFilterFlag(WUU_Type *base, uint8_t filterIndex);
/*!
* @brief Clears the pin filter configuration.
*
* This function clears the pin filter flag.
*
* @param base WUU peripheral base address.
* @param filterIndex A pin filter index to clear the flag, starting from 1.
*/
void WUU_ClearPinFilterFlag(WUU_Type *base, uint8_t filterIndex);
/*!
* brief Gets the external wakeup source flag.
*
* This function checks the external pin flag to detect whether the MCU is
* woken up by the specific pin.
*
* param base WUU peripheral base address.
* param pinIndex A pin index, which starts from 0.
* return True if the specific pin is a wakeup source.
*/
bool WUU_GetExternalWakeupPinFlag(WUU_Type *base, uint32_t pinIndex);
/*!
* brief Clears the external wakeup source flag.
*
* This function clears the external wakeup source flag for a specific pin.
*
* param base WUU peripheral base address.
* param pinIndex A pin index, which starts from 0.
*/
void WUU_ClearExternalWakeupPinFlag(WUU_Type *base, uint32_t pinIndex);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /*_FSL_WUU_H_*/

View File

@ -0,0 +1,275 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_wwdt.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.wwdt"
#endif
#define FREQUENCY_3MHZ (3000000U)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the instance from the base address
*
* @param base WWDT peripheral base address
*
* @return The WWDT instance
*/
static uint32_t WWDT_GetInstance(WWDT_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to WWDT bases for each instance. */
static WWDT_Type *const s_wwdtBases[] = WWDT_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to WWDT clocks for each instance. */
static const clock_ip_name_t s_wwdtClocks[] = WWDT_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
#if !(defined(FSL_FEATURE_WWDT_HAS_NO_RESET) && FSL_FEATURE_WWDT_HAS_NO_RESET)
/*! @brief Pointers to WWDT resets for each instance. */
static const reset_ip_name_t s_wwdtResets[] = WWDT_RSTS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t WWDT_GetInstance(WWDT_Type *base)
{
uint32_t instance;
uint32_t wwdtArrayCount = (sizeof(s_wwdtBases) / sizeof(s_wwdtBases[0]));
/* Find the instance index from base address mappings. */
for (instance = 0; instance < wwdtArrayCount; instance++)
{
if (s_wwdtBases[instance] == base)
{
break;
}
}
assert(instance < wwdtArrayCount);
return instance;
}
/*******************************************************************************
* Code
******************************************************************************/
/*!
* brief Initializes WWDT configure structure.
*
* This function initializes the WWDT configure structure to default value. The default
* value are:
* code
* config->enableWwdt = true;
* config->enableWatchdogReset = false;
* config->enableWatchdogProtect = false;
* config->enableLockOscillator = false;
* config->windowValue = 0xFFFFFFU;
* config->timeoutValue = 0xFFFFFFU;
* config->warningValue = 0;
* endcode
*
* param config Pointer to WWDT config structure.
* see wwdt_config_t
*/
void WWDT_GetDefaultConfig(wwdt_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
/* Enable the watch dog */
config->enableWwdt = true;
/* Disable the watchdog timeout reset */
config->enableWatchdogReset = false;
/* Disable the watchdog protection for updating the timeout value */
config->enableWatchdogProtect = false;
#if !(defined(FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK) && FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK)
/* Do not lock the watchdog oscillator */
config->enableLockOscillator = false;
#endif
/* Windowing is not in effect */
config->windowValue = 0xFFFFFFU;
/* Set the timeout value to the max */
config->timeoutValue = 0xFFFFFFU;
/* No warning is provided */
config->warningValue = 0;
/* Set clock frequency. */
config->clockFreq_Hz = 0U;
}
/*!
* brief Initializes the WWDT.
*
* This function initializes the WWDT. When called, the WWDT runs according to the configuration.
*
* Example:
* code
* wwdt_config_t config;
* WWDT_GetDefaultConfig(&config);
* config.timeoutValue = 0x7ffU;
* WWDT_Init(wwdt_base,&config);
* endcode
*
* param base WWDT peripheral base address
* param config The configuration of WWDT
*/
void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config)
{
assert(NULL != config);
uint32_t value = 0U;
uint32_t DelayUs = 0U;
uint32_t primaskValue = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the WWDT clock */
CLOCK_EnableClock(s_wwdtClocks[WWDT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL)
#if !(defined(FSL_FEATURE_WWDT_HAS_NO_RESET) && FSL_FEATURE_WWDT_HAS_NO_RESET)
/* Reset the module. */
RESET_PeripheralReset(s_wwdtResets[WWDT_GetInstance(base)]);
#endif
#if defined(FSL_FEATURE_WWDT_WDTRESET_FROM_PMC) && (FSL_FEATURE_WWDT_WDTRESET_FROM_PMC)
/* PMC RESETCAUSE: set bit to clear it by write 1. */
PMC->RESETCAUSE = PMC_RESETCAUSE_WDTRESET_MASK;
/* Enable the watchdog reset event to affect the system in the Power Management Controller */
PMC->CTRL |= PMC_CTRL_WDTRESETENABLE_MASK;
#endif /*FSL_FEATURE_WWDT_WDTRESET_FROM_PMC*/
#endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */
#if !(defined(FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK) && FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK)
value = WWDT_MOD_WDEN(config->enableWwdt) | WWDT_MOD_WDRESET(config->enableWatchdogReset) |
WWDT_MOD_LOCK(config->enableLockOscillator);
#else
value = WWDT_MOD_WDEN(config->enableWwdt) | WWDT_MOD_WDRESET(config->enableWatchdogReset);
#endif
/* Clear legacy flag in the MOD register by software writing a "1" to this bit field.. */
if (0U != (base->MOD & WWDT_MOD_WDINT_MASK))
{
value |= WWDT_MOD_WDINT_MASK;
}
/* Set configuration */
primaskValue = DisableGlobalIRQ();
base->TC = WWDT_TC_COUNT(config->timeoutValue);
base->MOD = value;
base->WINDOW = WWDT_WINDOW_WINDOW(config->windowValue);
base->WARNINT = WWDT_WARNINT_WARNINT(config->warningValue);
/* Refreshes the WWDT timer. */
base->FEED = WWDT_FIRST_WORD_OF_REFRESH;
base->FEED = WWDT_SECOND_WORD_OF_REFRESH;
EnableGlobalIRQ(primaskValue);
/* Read counter value to wait wwdt timer start*/
if (config->enableWwdt)
{
while (base->TV == 0xFFUL)
{
}
}
/* This WDPROTECT bit can be set once by software and is only cleared by a reset */
if (config->enableWatchdogProtect && (0U == (base->MOD & WWDT_MOD_WDPROTECT_MASK)))
{
/* The config->clockFreq_Hz must be set in order to config the delay time. */
assert(0U != config->clockFreq_Hz);
/* Set the WDPROTECT bit after the Feed Sequence (0xAA, 0x55) with 3 WDCLK delay */
DelayUs = FREQUENCY_3MHZ / config->clockFreq_Hz + 1U;
SDK_DelayAtLeastUs(DelayUs, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
base->MOD |= WWDT_MOD_WDPROTECT(1U);
}
}
/*!
* brief Shuts down the WWDT.
*
* This function shuts down the WWDT.
*
* param base WWDT peripheral base address
*/
void WWDT_Deinit(WWDT_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the WWDT clock */
CLOCK_DisableClock(s_wwdtClocks[WWDT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Refreshes the WWDT timer.
*
* This function feeds the WWDT.
* This function should be called before WWDT timer is in timeout. Otherwise, a reset is asserted.
*
* param base WWDT peripheral base address
*/
void WWDT_Refresh(WWDT_Type *base)
{
uint32_t primaskValue = 0U;
/* Disable the global interrupt to protect refresh sequence */
primaskValue = DisableGlobalIRQ();
base->FEED = WWDT_FIRST_WORD_OF_REFRESH;
base->FEED = WWDT_SECOND_WORD_OF_REFRESH;
EnableGlobalIRQ(primaskValue);
}
/*!
* brief Clear WWDT flag.
*
* This function clears WWDT status flag.
*
* Example for clearing warning flag:
* code
* WWDT_ClearStatusFlags(wwdt_base, kWWDT_WarningFlag);
* endcode
* param base WWDT peripheral base address
* param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::_wwdt_status_flags_t
*/
void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask)
{
/* Clear the WDINT bit so that we don't accidentally clear it */
uint32_t reg = (base->MOD & (~WWDT_MOD_WDINT_MASK));
/* Clear timeout by writing a zero */
if (0U != (mask & (uint32_t)kWWDT_TimeoutFlag))
{
reg &= ~WWDT_MOD_WDTOF_MASK;
#if defined(FSL_FEATURE_WWDT_WDTRESET_FROM_PMC) && (FSL_FEATURE_WWDT_WDTRESET_FROM_PMC)
/* PMC RESETCAUSE: set bit to clear it */
PMC->RESETCAUSE = PMC_RESETCAUSE_WDTRESET_MASK;
#endif /*FSL_FEATURE_WWDT_WDTRESET_FROM_PMC*/
}
/* Clear warning interrupt flag by writing a one */
if (0U != (mask & (uint32_t)kWWDT_WarningFlag))
{
reg |= WWDT_MOD_WDINT_MASK;
}
base->MOD = reg;
}

View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_WWDT_H_
#define _FSL_WWDT_H_
#include "fsl_common.h"
/*!
* @addtogroup wwdt
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Defines WWDT driver version. */
#define FSL_WWDT_DRIVER_VERSION (MAKE_VERSION(2, 1, 9))
/*@}*/
/*! @name Refresh sequence */
/*@{*/
#define WWDT_FIRST_WORD_OF_REFRESH (0xAAU) /*!< First word of refresh sequence */
#define WWDT_SECOND_WORD_OF_REFRESH (0x55U) /*!< Second word of refresh sequence */
/*@}*/
/*! @brief Describes WWDT configuration structure. */
typedef struct _wwdt_config
{
bool enableWwdt; /*!< Enables or disables WWDT */
bool enableWatchdogReset; /*!< true: Watchdog timeout will cause a chip reset
false: Watchdog timeout will not cause a chip reset */
bool enableWatchdogProtect; /*!< true: Enable watchdog protect i.e timeout value can only be
changed after counter is below warning & window values
false: Disable watchdog protect; timeout value can be changed
at any time */
#if !(defined(FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK) && FSL_FEATURE_WWDT_HAS_NO_OSCILLATOR_LOCK)
bool enableLockOscillator; /*!< true: Disabling or powering down the watchdog oscillator is prevented
Once set, this bit can only be cleared by a reset
false: Do not lock oscillator */
#endif
uint32_t windowValue; /*!< Window value, set this to 0xFFFFFF if windowing is not in effect */
uint32_t timeoutValue; /*!< Timeout value */
uint32_t warningValue; /*!< Watchdog time counter value that will generate a
warning interrupt. Set this to 0 for no warning */
uint32_t clockFreq_Hz; /*!< Watchdog clock source frequency. */
} wwdt_config_t;
/*!
* @brief WWDT status flags.
*
* This structure contains the WWDT status flags for use in the WWDT functions.
*/
enum _wwdt_status_flags_t
{
kWWDT_TimeoutFlag = WWDT_MOD_WDTOF_MASK, /*!< Time-out flag, set when the timer times out */
kWWDT_WarningFlag = WWDT_MOD_WDINT_MASK /*!< Warning interrupt flag, set when timer is below the value WDWARNINT */
};
/*******************************************************************************
* API
*******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name WWDT Initialization and De-initialization
* @{
*/
/*!
* @brief Initializes WWDT configure structure.
*
* This function initializes the WWDT configure structure to default value. The default
* value are:
* @code
* config->enableWwdt = true;
* config->enableWatchdogReset = false;
* config->enableWatchdogProtect = false;
* config->enableLockOscillator = false;
* config->windowValue = 0xFFFFFFU;
* config->timeoutValue = 0xFFFFFFU;
* config->warningValue = 0;
* @endcode
*
* @param config Pointer to WWDT config structure.
* @see wwdt_config_t
*/
void WWDT_GetDefaultConfig(wwdt_config_t *config);
/*!
* @brief Initializes the WWDT.
*
* This function initializes the WWDT. When called, the WWDT runs according to the configuration.
*
* Example:
* @code
* wwdt_config_t config;
* WWDT_GetDefaultConfig(&config);
* config.timeoutValue = 0x7ffU;
* WWDT_Init(wwdt_base,&config);
* @endcode
*
* @param base WWDT peripheral base address
* @param config The configuration of WWDT
*/
void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config);
/*!
* @brief Shuts down the WWDT.
*
* This function shuts down the WWDT.
*
* @param base WWDT peripheral base address
*/
void WWDT_Deinit(WWDT_Type *base);
/* @} */
/*!
* @name WWDT Functional Operation
* @{
*/
/*!
* @brief Enables the WWDT module.
*
* This function write value into WWDT_MOD register to enable the WWDT, it is a write-once bit;
* once this bit is set to one and a watchdog feed is performed, the watchdog timer will run
* permanently.
*
* @param base WWDT peripheral base address
*/
static inline void WWDT_Enable(WWDT_Type *base)
{
base->MOD |= WWDT_MOD_WDEN_MASK;
}
/*!
* @brief Disables the WWDT module.
* @deprecated Do not use this function. It will be deleted in next release version, for
* once the bit field of WDEN written with a 1, it can not be re-written with a 0.
*
* This function write value into WWDT_MOD register to disable the WWDT.
*
* @param base WWDT peripheral base address
*/
static inline void WWDT_Disable(WWDT_Type *base)
{
base->MOD &= ~WWDT_MOD_WDEN_MASK;
}
/*!
* @brief Gets all WWDT status flags.
*
* This function gets all status flags.
*
* Example for getting Timeout Flag:
* @code
* uint32_t status;
* status = WWDT_GetStatusFlags(wwdt_base) & kWWDT_TimeoutFlag;
* @endcode
* @param base WWDT peripheral base address
* @return The status flags. This is the logical OR of members of the
* enumeration ::_wwdt_status_flags_t
*/
static inline uint32_t WWDT_GetStatusFlags(WWDT_Type *base)
{
#if defined(FSL_FEATURE_WWDT_WDTRESET_FROM_PMC) && (FSL_FEATURE_WWDT_WDTRESET_FROM_PMC)
uint32_t status;
/* WDTOF is not set in case of WD reset - get info from PMC instead */
status = (base->MOD & (WWDT_MOD_WDTOF_MASK | WWDT_MOD_WDINT_MASK));
if (PMC->RESETCAUSE & PMC_RESETCAUSE_WDTRESET_MASK)
{
status |= kWWDT_TimeoutFlag;
}
return status;
#else
return (base->MOD & (WWDT_MOD_WDTOF_MASK | WWDT_MOD_WDINT_MASK));
#endif /*FSL_FEATURE_WWDT_WDTRESET_FROM_PMC*/
}
/*!
* @brief Clear WWDT flag.
*
* This function clears WWDT status flag.
*
* Example for clearing warning flag:
* @code
* WWDT_ClearStatusFlags(wwdt_base, kWWDT_WarningFlag);
* @endcode
* @param base WWDT peripheral base address
* @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::_wwdt_status_flags_t
*/
void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask);
/*!
* @brief Set the WWDT warning value.
*
* The WDWARNINT register determines the watchdog timer counter value that will generate a watchdog
* interrupt. When the watchdog timer counter is no longer greater than the value defined by
* WARNINT, an interrupt will be generated after the subsequent WDCLK.
*
* @param base WWDT peripheral base address
* @param warningValue WWDT warning value.
*/
static inline void WWDT_SetWarningValue(WWDT_Type *base, uint32_t warningValue)
{
base->WARNINT = WWDT_WARNINT_WARNINT(warningValue);
}
/*!
* @brief Set the WWDT timeout value.
*
* This function sets the timeout value. Every time a feed sequence occurs the value in the TC
* register is loaded into the Watchdog timer. Writing a value below 0xFF will cause 0xFF to be
* loaded into the TC register. Thus the minimum time-out interval is TWDCLK*256*4.
* If enableWatchdogProtect flag is true in wwdt_config_t config structure, any attempt to change
* the timeout value before the watchdog counter is below the warning and window values
* will cause a watchdog reset and set the WDTOF flag.
*
* @param base WWDT peripheral base address
* @param timeoutCount WWDT timeout value, count of WWDT clock tick.
*/
static inline void WWDT_SetTimeoutValue(WWDT_Type *base, uint32_t timeoutCount)
{
base->TC = WWDT_TC_COUNT(timeoutCount);
}
/*!
* @brief Sets the WWDT window value.
*
* The WINDOW register determines the highest TV value allowed when a watchdog feed is performed.
* If a feed sequence occurs when timer value is greater than the value in WINDOW, a watchdog
* event will occur. To disable windowing, set windowValue to 0xFFFFFF (maximum possible timer
* value) so windowing is not in effect.
*
* @param base WWDT peripheral base address
* @param windowValue WWDT window value.
*/
static inline void WWDT_SetWindowValue(WWDT_Type *base, uint32_t windowValue)
{
base->WINDOW = WWDT_WINDOW_WINDOW(windowValue);
}
/*!
* @brief Refreshes the WWDT timer.
*
* This function feeds the WWDT.
* This function should be called before WWDT timer is in timeout. Otherwise, a reset is asserted.
*
* @param base WWDT peripheral base address
*/
void WWDT_Refresh(WWDT_Type *base);
/*@}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/
#endif /* _FSL_WWDT_H_ */

View File

@ -0,0 +1,33 @@
/*
* Copyright 2014-2016 Freescale Semiconductor, Inc.
* Copyright 2016-2023 NXP
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef __FSL_DEVICE_REGISTERS_H__
#define __FSL_DEVICE_REGISTERS_H__
/*
* Include the cpu specific register header files.
*
* The CPU macro should be declared in the project or makefile.
*/
#if (defined(CPU_MCXA153VFM) || defined(CPU_MCXA153VFT) || defined(CPU_MCXA153VLH))
#define MCXA153_SERIES
/* CMSIS-style register definitions */
#include "MCXA153.h"
/* CPU specific feature definitions */
#include "MCXA153_features.h"
#else
#error "No valid CPU defined!"
#endif
#endif /* __FSL_DEVICE_REGISTERS_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@ -0,0 +1,201 @@
/*
** ###################################################################
** Processors: MCXA153VFM
** MCXA153VFT
** MCXA153VLH
**
** Compiler: GNU C Compiler
** Reference manual: MCXA1 User manual
** Version: rev. 1.0, 2022-03-29
** Build: b230411
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0800;
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000200
m_text (RX) : ORIGIN = 0x00000200, LENGTH = 0x0001FE00
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00006000
m_sramx0 (RW) : ORIGIN = 0x04000000, LENGTH = 0x00002000
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal flash */
.interrupts :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(.ramfunc*) /* for functions in ram */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
/* Uninitialized data section */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
. = ALIGN(4);
__START_BSS = .;
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__END_BSS = .;
} > m_data
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > m_data
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
} > m_data
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data) + LENGTH(m_data);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}

View File

@ -0,0 +1,200 @@
/*
** ###################################################################
** Processors: MCXA153VFM
** MCXA153VFT
** MCXA153VLH
**
** Compiler: GNU C Compiler
** Reference manual: MCXA1 User manual
** Version: rev. 1.0, 2022-03-29
** Build: b230411
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0800;
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x04000000, LENGTH = 0x00000200
m_text (RX) : ORIGIN = 0x04000200, LENGTH = 0x00001E00
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00006000
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal flash */
.interrupts :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(.ramfunc*) /* for functions in ram */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
/* Uninitialized data section */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
. = ALIGN(4);
__START_BSS = .;
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__END_BSS = .;
} > m_data
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > m_data
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
} > m_data
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data) + LENGTH(m_data);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
/*
** ###################################################################
** Processors: MCXA153VFM
** MCXA153VFT
** MCXA153VLH
**
** Compiler: IAR ANSI C/C++ Compiler for ARM
** Reference manual: MCXA1 User manual
** Version: rev. 1.0, 2022-03-29
** Build: b230411
**
** Abstract:
** Linker file for the IAR ANSI C/C++ Compiler for ARM
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Stack and Heap Sizes */
if (isdefinedsymbol(__stack_size__)) {
define symbol __size_cstack__ = __stack_size__;
} else {
define symbol __size_cstack__ = 0x0400;
}
if (isdefinedsymbol(__heap_size__)) {
define symbol __size_heap__ = __heap_size__;
} else {
define symbol __size_heap__ = 0x0400;
}
define symbol m_interrupts_start = 0x00000000;
define symbol m_interrupts_end = 0x000001FF;
define symbol m_text_start = 0x00000200;
define symbol m_text_end = 0x0001FFFF;
define symbol m_data_start = 0x20000000;
define symbol m_data_end = 0x20005FFF;
define symbol m_sramx0_start = 0x04000000;
define symbol m_sramx0_end = 0x04001FFF;
define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__]
| mem:[from m_sramx0_start to m_sramx0_end];
define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end];
if (isdefinedsymbol(__use_shmem__)) {
define region rpmsg_sh_mem_region = mem:[from rpmsg_sh_mem_start to rpmsg_sh_mem_end];
}
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block RW { readwrite };
define block ZI { zi };
initialize by copy { readwrite, section .textrw };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
/* Required in a multi-threaded application */
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem: m_interrupts_start { readonly section .intvec };
place in TEXT_region { readonly };
place in DATA_region { block RW };
place in DATA_region { block ZI };
place in DATA_region { last block HEAP };
place in CSTACK_region { block CSTACK };

View File

@ -0,0 +1,81 @@
/*
** ###################################################################
** Processors: MCXA153VFM
** MCXA153VFT
** MCXA153VLH
**
** Compiler: IAR ANSI C/C++ Compiler for ARM
** Reference manual: MCXA1 User manual
** Version: rev. 1.0, 2022-03-29
** Build: b230411
**
** Abstract:
** Linker file for the IAR ANSI C/C++ Compiler for ARM
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Stack and Heap Sizes */
if (isdefinedsymbol(__stack_size__)) {
define symbol __size_cstack__ = __stack_size__;
} else {
define symbol __size_cstack__ = 0x0400;
}
if (isdefinedsymbol(__heap_size__)) {
define symbol __size_heap__ = __heap_size__;
} else {
define symbol __size_heap__ = 0x0400;
}
define symbol m_interrupts_start = 0x04000000;
define symbol m_interrupts_end = 0x040001FF;
define symbol m_text_start = 0x04000200;
define symbol m_text_end = 0x04001FFF;
define symbol m_data_start = 0x20000000;
define symbol m_data_end = 0x20005FFF;
define memory mem with size = 4G;
define region TEXT_region = mem:[from m_interrupts_start to m_interrupts_end]
| mem:[from m_text_start to m_text_end];
define region DATA_region = mem:[from m_data_start to m_data_end-__size_cstack__];
define region CSTACK_region = mem:[from m_data_end-__size_cstack__+1 to m_data_end];
if (isdefinedsymbol(__use_shmem__)) {
define region rpmsg_sh_mem_region = mem:[from rpmsg_sh_mem_start to rpmsg_sh_mem_end];
}
define block CSTACK with alignment = 8, size = __size_cstack__ { };
define block HEAP with alignment = 8, size = __size_heap__ { };
define block RW { readwrite };
define block ZI { zi };
initialize by copy { readwrite, section .textrw };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
/* Required in a multi-threaded application */
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem: m_interrupts_start { readonly section .intvec };
place in TEXT_region { readonly };
place in DATA_region { block RW };
place in DATA_region { block ZI };
place in DATA_region { last block HEAP };
place in CSTACK_region { block CSTACK };

View File

@ -0,0 +1,872 @@
; -------------------------------------------------------------------------
; @file: startup_MCXA153.s
; @purpose: CMSIS Cortex-M33 Core Device Startup File
; MCXA153
; @version: 1.0
; @date: 2022-3-29
; @build: b230804
; -------------------------------------------------------------------------
;
; Copyright 1997-2016 Freescale Semiconductor, Inc.
; Copyright 2016-2023 NXP
; SPDX-License-Identifier: BSD-3-Clause
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
;
; Cortex-M version
;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
EXTERN SystemInit
PUBLIC __vector_table
PUBLIC __vector_table_0x1c
PUBLIC __Vectors
PUBLIC __Vectors_End
PUBLIC __Vectors_Size
DATA
__iar_init$$done: ; The vector table is not needed
; until after copy initialization is done
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler ;NMI Handler
DCD HardFault_Handler ;Hard Fault Handler
DCD MemManage_Handler ;MPU Fault Handler
DCD BusFault_Handler ;Bus Fault Handler
DCD UsageFault_Handler ;Usage Fault Handler
__vector_table_0x1c
DCD SecureFault_Handler ;Secure Fault Handler
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD 0 ;Reserved
DCD SVC_Handler ;SVCall Handler
DCD DebugMon_Handler ;Debug Monitor Handler
DCD 0 ;Reserved
DCD PendSV_Handler ;PendSV Handler
DCD SysTick_Handler ;SysTick Handler
;External Interrupts
DCD Reserved16_IRQHandler ;OR IRQ1 to IRQ53
DCD CMC_IRQHandler ;Core Mode Controller interrupt
DCD DMA_CH0_IRQHandler ;DMA3_0_CH0 error or transfer complete
DCD DMA_CH1_IRQHandler ;DMA3_0_CH1 error or transfer complete
DCD DMA_CH2_IRQHandler ;DMA3_0_CH2 error or transfer complete
DCD DMA_CH3_IRQHandler ;DMA3_0_CH3 error or transfer complete
DCD Reserved22_IRQHandler ;Reserved interrupt
DCD Reserved23_IRQHandler ;Reserved interrupt
DCD Reserved24_IRQHandler ;Reserved interrupt
DCD Reserved25_IRQHandler ;Reserved interrupt
DCD ERM0_SINGLE_BIT_IRQHandler ;ERM Single Bit error interrupt
DCD ERM0_MULTI_BIT_IRQHandler ;ERM Multi Bit error interrupt
DCD FMU0_IRQHandler ;Flash Management Unit interrupt
DCD GLIKEY0_IRQHandler ;GLIKEY Interrupt
DCD MBC0_IRQHandler ;MBC secure violation interrupt
DCD SCG0_IRQHandler ;System Clock Generator interrupt
DCD SPC0_IRQHandler ;System Power Controller interrupt
DCD Reserved33_IRQHandler ;Reserved interrupt
DCD WUU0_IRQHandler ;Wake Up Unit interrupt
DCD Reserved35_IRQHandler ;Reserved interrupt
DCD Reserved36_IRQHandler ;Reserved interrupt
DCD Reserved37_IRQHandler ;Reserved interrupt
DCD Reserved38_IRQHandler ;Reserved interrupt
DCD Reserved39_IRQHandler ;Reserved interrupt
DCD I3C0_IRQHandler ;Improved Inter Integrated Circuit interrupt 0
DCD Reserved41_IRQHandler ;Reserved interrupt
DCD LPI2C0_IRQHandler ;Low-Power Inter Integrated Circuit interrupt
DCD Reserved43_IRQHandler ;Reserved interrupt
DCD LPSPI0_IRQHandler ;Low-Power Serial Peripheral Interface interrupt
DCD LPSPI1_IRQHandler ;Low-Power Serial Peripheral Interface interrupt
DCD Reserved46_IRQHandler ;Reserved interrupt
DCD LPUART0_IRQHandler ;Low-Power Universal Asynchronous Receive/Transmit interrupt
DCD LPUART1_IRQHandler ;Low-Power Universal Asynchronous Receive/Transmit interrupt
DCD LPUART2_IRQHandler ;Low-Power Universal Asynchronous Receive/Transmit interrupt
DCD Reserved50_IRQHandler ;Reserved interrupt
DCD Reserved51_IRQHandler ;Reserved interrupt
DCD USB0_IRQHandler ;Universal Serial Bus - Full Speed interrupt
DCD Reserved53_IRQHandler ;Reserved interrupt
DCD CDOG0_IRQHandler ;Code Watchdog Timer 0 interrupt
DCD CTIMER0_IRQHandler ;Standard counter/timer 0 interrupt
DCD CTIMER1_IRQHandler ;Standard counter/timer 1 interrupt
DCD CTIMER2_IRQHandler ;Standard counter/timer 2 interrupt
DCD Reserved58_IRQHandler ;Reserved interrupt
DCD Reserved59_IRQHandler ;Reserved interrupt
DCD FLEXPWM0_RELOAD_ERROR_IRQHandler ;FlexPWM0_reload_error interrupt
DCD FLEXPWM0_FAULT_IRQHandler ;FlexPWM0_fault interrupt
DCD FLEXPWM0_SUBMODULE0_IRQHandler ;FlexPWM0 Submodule 0 capture/compare/reload interrupt
DCD FLEXPWM0_SUBMODULE1_IRQHandler ;FlexPWM0 Submodule 1 capture/compare/reload interrupt
DCD FLEXPWM0_SUBMODULE2_IRQHandler ;FlexPWM0 Submodule 2 capture/compare/reload interrupt
DCD Reserved65_IRQHandler ;Reserved interrupt
DCD QDC0_COMPARE_IRQHandler ;Compare
DCD QDC0_HOME_IRQHandler ;Home
DCD QDC0_WATCHDOG_IRQHandler ;Watchdog / Simultaneous A and B Change
DCD QDC0_INDEX_IRQHandler ;Index / Roll Over / Roll Under
DCD FREQME0_IRQHandler ;Frequency Measurement interrupt
DCD LPTMR0_IRQHandler ;Low Power Timer 0 interrupt
DCD Reserved72_IRQHandler ;Reserved interrupt
DCD OS_EVENT_IRQHandler ;OS event timer interrupt
DCD WAKETIMER0_IRQHandler ;Wake Timer Interrupt
DCD UTICK0_IRQHandler ;Micro-Tick Timer interrupt
DCD WWDT0_IRQHandler ;Windowed Watchdog Timer 0 interrupt
DCD Reserved77_IRQHandler ;Reserved interrupt
DCD ADC0_IRQHandler ;Analog-to-Digital Converter interrupt
DCD Reserved79_IRQHandler ;Reserved interrupt
DCD CMP0_IRQHandler ;Comparator interrupt
DCD CMP1_IRQHandler ;Comparator interrupt
DCD Reserved82_IRQHandler ;Reserved interrupt
DCD Reserved83_IRQHandler ;Reserved interrupt
DCD Reserved84_IRQHandler ;Reserved interrupt
DCD Reserved85_IRQHandler ;Reserved interrupt
DCD Reserved86_IRQHandler ;Reserved interrupt
DCD GPIO0_IRQHandler ;General Purpose Input/Output interrupt 0
DCD GPIO1_IRQHandler ;General Purpose Input/Output interrupt 1
DCD GPIO2_IRQHandler ;General Purpose Input/Output interrupt 2
DCD GPIO3_IRQHandler ;General Purpose Input/Output interrupt 3
DCD Reserved91_IRQHandler ;Reserved interrupt
DCD Reserved92_IRQHandler ;Reserved interrupt
DCD Reserved93_IRQHandler ;Reserved interrupt
DCD Reserved94_IRQHandler ;Reserved interrupt
DCD Reserved95_IRQHandler ;Reserved interrupt
__Vectors_End
__Vectors EQU __vector_table
__Vectors_Size EQU __Vectors_End - __Vectors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
CPSID I ; Mask interrupts
LDR R0, =0xE000ED08
LDR R1, =__vector_table
STR R1, [R0]
LDR R2, [R1]
MSR MSP, R2
LDR R0, =sfb(CSTACK)
MSR MSPLIM, R0
CPSIE I ; Unmask interrupts
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
PUBWEAK NMI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler
B .
PUBWEAK HardFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
HardFault_Handler
B .
PUBWEAK MemManage_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
MemManage_Handler
B .
PUBWEAK BusFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
BusFault_Handler
B .
PUBWEAK UsageFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
UsageFault_Handler
B .
PUBWEAK SecureFault_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SecureFault_Handler
B .
PUBWEAK SVC_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SVC_Handler
B .
PUBWEAK DebugMon_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
DebugMon_Handler
B .
PUBWEAK PendSV_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
PendSV_Handler
B .
PUBWEAK SysTick_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
SysTick_Handler
B .
PUBWEAK Reserved16_IRQHandler
PUBWEAK Reserved16_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved16_IRQHandler
LDR R0, =Reserved16_DriverIRQHandler
BX R0
PUBWEAK CMC_IRQHandler
PUBWEAK CMC_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CMC_IRQHandler
LDR R0, =CMC_DriverIRQHandler
BX R0
PUBWEAK DMA_CH0_IRQHandler
PUBWEAK DMA_CH0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA_CH0_IRQHandler
LDR R0, =DMA_CH0_DriverIRQHandler
BX R0
PUBWEAK DMA_CH1_IRQHandler
PUBWEAK DMA_CH1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA_CH1_IRQHandler
LDR R0, =DMA_CH1_DriverIRQHandler
BX R0
PUBWEAK DMA_CH2_IRQHandler
PUBWEAK DMA_CH2_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA_CH2_IRQHandler
LDR R0, =DMA_CH2_DriverIRQHandler
BX R0
PUBWEAK DMA_CH3_IRQHandler
PUBWEAK DMA_CH3_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
DMA_CH3_IRQHandler
LDR R0, =DMA_CH3_DriverIRQHandler
BX R0
PUBWEAK Reserved22_IRQHandler
PUBWEAK Reserved22_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved22_IRQHandler
LDR R0, =Reserved22_DriverIRQHandler
BX R0
PUBWEAK Reserved23_IRQHandler
PUBWEAK Reserved23_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved23_IRQHandler
LDR R0, =Reserved23_DriverIRQHandler
BX R0
PUBWEAK Reserved24_IRQHandler
PUBWEAK Reserved24_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved24_IRQHandler
LDR R0, =Reserved24_DriverIRQHandler
BX R0
PUBWEAK Reserved25_IRQHandler
PUBWEAK Reserved25_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved25_IRQHandler
LDR R0, =Reserved25_DriverIRQHandler
BX R0
PUBWEAK ERM0_SINGLE_BIT_IRQHandler
PUBWEAK ERM0_SINGLE_BIT_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
ERM0_SINGLE_BIT_IRQHandler
LDR R0, =ERM0_SINGLE_BIT_DriverIRQHandler
BX R0
PUBWEAK ERM0_MULTI_BIT_IRQHandler
PUBWEAK ERM0_MULTI_BIT_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
ERM0_MULTI_BIT_IRQHandler
LDR R0, =ERM0_MULTI_BIT_DriverIRQHandler
BX R0
PUBWEAK FMU0_IRQHandler
PUBWEAK FMU0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FMU0_IRQHandler
LDR R0, =FMU0_DriverIRQHandler
BX R0
PUBWEAK GLIKEY0_IRQHandler
PUBWEAK GLIKEY0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
GLIKEY0_IRQHandler
LDR R0, =GLIKEY0_DriverIRQHandler
BX R0
PUBWEAK MBC0_IRQHandler
PUBWEAK MBC0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
MBC0_IRQHandler
LDR R0, =MBC0_DriverIRQHandler
BX R0
PUBWEAK SCG0_IRQHandler
PUBWEAK SCG0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
SCG0_IRQHandler
LDR R0, =SCG0_DriverIRQHandler
BX R0
PUBWEAK SPC0_IRQHandler
PUBWEAK SPC0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
SPC0_IRQHandler
LDR R0, =SPC0_DriverIRQHandler
BX R0
PUBWEAK Reserved33_IRQHandler
PUBWEAK Reserved33_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved33_IRQHandler
LDR R0, =Reserved33_DriverIRQHandler
BX R0
PUBWEAK WUU0_IRQHandler
PUBWEAK WUU0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
WUU0_IRQHandler
LDR R0, =WUU0_DriverIRQHandler
BX R0
PUBWEAK Reserved35_IRQHandler
PUBWEAK Reserved35_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved35_IRQHandler
LDR R0, =Reserved35_DriverIRQHandler
BX R0
PUBWEAK Reserved36_IRQHandler
PUBWEAK Reserved36_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved36_IRQHandler
LDR R0, =Reserved36_DriverIRQHandler
BX R0
PUBWEAK Reserved37_IRQHandler
PUBWEAK Reserved37_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved37_IRQHandler
LDR R0, =Reserved37_DriverIRQHandler
BX R0
PUBWEAK Reserved38_IRQHandler
PUBWEAK Reserved38_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved38_IRQHandler
LDR R0, =Reserved38_DriverIRQHandler
BX R0
PUBWEAK Reserved39_IRQHandler
PUBWEAK Reserved39_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved39_IRQHandler
LDR R0, =Reserved39_DriverIRQHandler
BX R0
PUBWEAK I3C0_IRQHandler
PUBWEAK I3C0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
I3C0_IRQHandler
LDR R0, =I3C0_DriverIRQHandler
BX R0
PUBWEAK Reserved41_IRQHandler
PUBWEAK Reserved41_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved41_IRQHandler
LDR R0, =Reserved41_DriverIRQHandler
BX R0
PUBWEAK LPI2C0_IRQHandler
PUBWEAK LPI2C0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPI2C0_IRQHandler
LDR R0, =LPI2C0_DriverIRQHandler
BX R0
PUBWEAK Reserved43_IRQHandler
PUBWEAK Reserved43_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved43_IRQHandler
LDR R0, =Reserved43_DriverIRQHandler
BX R0
PUBWEAK LPSPI0_IRQHandler
PUBWEAK LPSPI0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPSPI0_IRQHandler
LDR R0, =LPSPI0_DriverIRQHandler
BX R0
PUBWEAK LPSPI1_IRQHandler
PUBWEAK LPSPI1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPSPI1_IRQHandler
LDR R0, =LPSPI1_DriverIRQHandler
BX R0
PUBWEAK Reserved46_IRQHandler
PUBWEAK Reserved46_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved46_IRQHandler
LDR R0, =Reserved46_DriverIRQHandler
BX R0
PUBWEAK LPUART0_IRQHandler
PUBWEAK LPUART0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPUART0_IRQHandler
LDR R0, =LPUART0_DriverIRQHandler
BX R0
PUBWEAK LPUART1_IRQHandler
PUBWEAK LPUART1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPUART1_IRQHandler
LDR R0, =LPUART1_DriverIRQHandler
BX R0
PUBWEAK LPUART2_IRQHandler
PUBWEAK LPUART2_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPUART2_IRQHandler
LDR R0, =LPUART2_DriverIRQHandler
BX R0
PUBWEAK Reserved50_IRQHandler
PUBWEAK Reserved50_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved50_IRQHandler
LDR R0, =Reserved50_DriverIRQHandler
BX R0
PUBWEAK Reserved51_IRQHandler
PUBWEAK Reserved51_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved51_IRQHandler
LDR R0, =Reserved51_DriverIRQHandler
BX R0
PUBWEAK USB0_IRQHandler
PUBWEAK USB0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
USB0_IRQHandler
LDR R0, =USB0_DriverIRQHandler
BX R0
PUBWEAK Reserved53_IRQHandler
PUBWEAK Reserved53_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved53_IRQHandler
LDR R0, =Reserved53_DriverIRQHandler
BX R0
PUBWEAK CDOG0_IRQHandler
PUBWEAK CDOG0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CDOG0_IRQHandler
LDR R0, =CDOG0_DriverIRQHandler
BX R0
PUBWEAK CTIMER0_IRQHandler
PUBWEAK CTIMER0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CTIMER0_IRQHandler
LDR R0, =CTIMER0_DriverIRQHandler
BX R0
PUBWEAK CTIMER1_IRQHandler
PUBWEAK CTIMER1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CTIMER1_IRQHandler
LDR R0, =CTIMER1_DriverIRQHandler
BX R0
PUBWEAK CTIMER2_IRQHandler
PUBWEAK CTIMER2_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CTIMER2_IRQHandler
LDR R0, =CTIMER2_DriverIRQHandler
BX R0
PUBWEAK Reserved58_IRQHandler
PUBWEAK Reserved58_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved58_IRQHandler
LDR R0, =Reserved58_DriverIRQHandler
BX R0
PUBWEAK Reserved59_IRQHandler
PUBWEAK Reserved59_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved59_IRQHandler
LDR R0, =Reserved59_DriverIRQHandler
BX R0
PUBWEAK FLEXPWM0_RELOAD_ERROR_IRQHandler
PUBWEAK FLEXPWM0_RELOAD_ERROR_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FLEXPWM0_RELOAD_ERROR_IRQHandler
LDR R0, =FLEXPWM0_RELOAD_ERROR_DriverIRQHandler
BX R0
PUBWEAK FLEXPWM0_FAULT_IRQHandler
PUBWEAK FLEXPWM0_FAULT_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FLEXPWM0_FAULT_IRQHandler
LDR R0, =FLEXPWM0_FAULT_DriverIRQHandler
BX R0
PUBWEAK FLEXPWM0_SUBMODULE0_IRQHandler
PUBWEAK FLEXPWM0_SUBMODULE0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FLEXPWM0_SUBMODULE0_IRQHandler
LDR R0, =FLEXPWM0_SUBMODULE0_DriverIRQHandler
BX R0
PUBWEAK FLEXPWM0_SUBMODULE1_IRQHandler
PUBWEAK FLEXPWM0_SUBMODULE1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FLEXPWM0_SUBMODULE1_IRQHandler
LDR R0, =FLEXPWM0_SUBMODULE1_DriverIRQHandler
BX R0
PUBWEAK FLEXPWM0_SUBMODULE2_IRQHandler
PUBWEAK FLEXPWM0_SUBMODULE2_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FLEXPWM0_SUBMODULE2_IRQHandler
LDR R0, =FLEXPWM0_SUBMODULE2_DriverIRQHandler
BX R0
PUBWEAK Reserved65_IRQHandler
PUBWEAK Reserved65_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved65_IRQHandler
LDR R0, =Reserved65_DriverIRQHandler
BX R0
PUBWEAK QDC0_COMPARE_IRQHandler
PUBWEAK QDC0_COMPARE_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
QDC0_COMPARE_IRQHandler
LDR R0, =QDC0_COMPARE_DriverIRQHandler
BX R0
PUBWEAK QDC0_HOME_IRQHandler
PUBWEAK QDC0_HOME_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
QDC0_HOME_IRQHandler
LDR R0, =QDC0_HOME_DriverIRQHandler
BX R0
PUBWEAK QDC0_WATCHDOG_IRQHandler
PUBWEAK QDC0_WATCHDOG_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
QDC0_WATCHDOG_IRQHandler
LDR R0, =QDC0_WATCHDOG_DriverIRQHandler
BX R0
PUBWEAK QDC0_INDEX_IRQHandler
PUBWEAK QDC0_INDEX_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
QDC0_INDEX_IRQHandler
LDR R0, =QDC0_INDEX_DriverIRQHandler
BX R0
PUBWEAK FREQME0_IRQHandler
PUBWEAK FREQME0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
FREQME0_IRQHandler
LDR R0, =FREQME0_DriverIRQHandler
BX R0
PUBWEAK LPTMR0_IRQHandler
PUBWEAK LPTMR0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
LPTMR0_IRQHandler
LDR R0, =LPTMR0_DriverIRQHandler
BX R0
PUBWEAK Reserved72_IRQHandler
PUBWEAK Reserved72_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved72_IRQHandler
LDR R0, =Reserved72_DriverIRQHandler
BX R0
PUBWEAK OS_EVENT_IRQHandler
PUBWEAK OS_EVENT_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
OS_EVENT_IRQHandler
LDR R0, =OS_EVENT_DriverIRQHandler
BX R0
PUBWEAK WAKETIMER0_IRQHandler
PUBWEAK WAKETIMER0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
WAKETIMER0_IRQHandler
LDR R0, =WAKETIMER0_DriverIRQHandler
BX R0
PUBWEAK UTICK0_IRQHandler
PUBWEAK UTICK0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
UTICK0_IRQHandler
LDR R0, =UTICK0_DriverIRQHandler
BX R0
PUBWEAK WWDT0_IRQHandler
PUBWEAK WWDT0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
WWDT0_IRQHandler
LDR R0, =WWDT0_DriverIRQHandler
BX R0
PUBWEAK Reserved77_IRQHandler
PUBWEAK Reserved77_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved77_IRQHandler
LDR R0, =Reserved77_DriverIRQHandler
BX R0
PUBWEAK ADC0_IRQHandler
PUBWEAK ADC0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
ADC0_IRQHandler
LDR R0, =ADC0_DriverIRQHandler
BX R0
PUBWEAK Reserved79_IRQHandler
PUBWEAK Reserved79_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved79_IRQHandler
LDR R0, =Reserved79_DriverIRQHandler
BX R0
PUBWEAK CMP0_IRQHandler
PUBWEAK CMP0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CMP0_IRQHandler
LDR R0, =CMP0_DriverIRQHandler
BX R0
PUBWEAK CMP1_IRQHandler
PUBWEAK CMP1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
CMP1_IRQHandler
LDR R0, =CMP1_DriverIRQHandler
BX R0
PUBWEAK Reserved82_IRQHandler
PUBWEAK Reserved82_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved82_IRQHandler
LDR R0, =Reserved82_DriverIRQHandler
BX R0
PUBWEAK Reserved83_IRQHandler
PUBWEAK Reserved83_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved83_IRQHandler
LDR R0, =Reserved83_DriverIRQHandler
BX R0
PUBWEAK Reserved84_IRQHandler
PUBWEAK Reserved84_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved84_IRQHandler
LDR R0, =Reserved84_DriverIRQHandler
BX R0
PUBWEAK Reserved85_IRQHandler
PUBWEAK Reserved85_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved85_IRQHandler
LDR R0, =Reserved85_DriverIRQHandler
BX R0
PUBWEAK Reserved86_IRQHandler
PUBWEAK Reserved86_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved86_IRQHandler
LDR R0, =Reserved86_DriverIRQHandler
BX R0
PUBWEAK GPIO0_IRQHandler
PUBWEAK GPIO0_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
GPIO0_IRQHandler
LDR R0, =GPIO0_DriverIRQHandler
BX R0
PUBWEAK GPIO1_IRQHandler
PUBWEAK GPIO1_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
GPIO1_IRQHandler
LDR R0, =GPIO1_DriverIRQHandler
BX R0
PUBWEAK GPIO2_IRQHandler
PUBWEAK GPIO2_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
GPIO2_IRQHandler
LDR R0, =GPIO2_DriverIRQHandler
BX R0
PUBWEAK GPIO3_IRQHandler
PUBWEAK GPIO3_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
GPIO3_IRQHandler
LDR R0, =GPIO3_DriverIRQHandler
BX R0
PUBWEAK Reserved91_IRQHandler
PUBWEAK Reserved91_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved91_IRQHandler
LDR R0, =Reserved91_DriverIRQHandler
BX R0
PUBWEAK Reserved92_IRQHandler
PUBWEAK Reserved92_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved92_IRQHandler
LDR R0, =Reserved92_DriverIRQHandler
BX R0
PUBWEAK Reserved93_IRQHandler
PUBWEAK Reserved93_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved93_IRQHandler
LDR R0, =Reserved93_DriverIRQHandler
BX R0
PUBWEAK Reserved94_IRQHandler
PUBWEAK Reserved94_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved94_IRQHandler
LDR R0, =Reserved94_DriverIRQHandler
BX R0
PUBWEAK Reserved95_IRQHandler
PUBWEAK Reserved95_DriverIRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
Reserved95_IRQHandler
LDR R0, =Reserved95_DriverIRQHandler
BX R0
Reserved16_DriverIRQHandler
CMC_DriverIRQHandler
DMA_CH0_DriverIRQHandler
DMA_CH1_DriverIRQHandler
DMA_CH2_DriverIRQHandler
DMA_CH3_DriverIRQHandler
Reserved22_DriverIRQHandler
Reserved23_DriverIRQHandler
Reserved24_DriverIRQHandler
Reserved25_DriverIRQHandler
ERM0_SINGLE_BIT_DriverIRQHandler
ERM0_MULTI_BIT_DriverIRQHandler
FMU0_DriverIRQHandler
GLIKEY0_DriverIRQHandler
MBC0_DriverIRQHandler
SCG0_DriverIRQHandler
SPC0_DriverIRQHandler
Reserved33_DriverIRQHandler
WUU0_DriverIRQHandler
Reserved35_DriverIRQHandler
Reserved36_DriverIRQHandler
Reserved37_DriverIRQHandler
Reserved38_DriverIRQHandler
Reserved39_DriverIRQHandler
I3C0_DriverIRQHandler
Reserved41_DriverIRQHandler
LPI2C0_DriverIRQHandler
Reserved43_DriverIRQHandler
LPSPI0_DriverIRQHandler
LPSPI1_DriverIRQHandler
Reserved46_DriverIRQHandler
LPUART0_DriverIRQHandler
LPUART1_DriverIRQHandler
LPUART2_DriverIRQHandler
Reserved50_DriverIRQHandler
Reserved51_DriverIRQHandler
USB0_DriverIRQHandler
Reserved53_DriverIRQHandler
CDOG0_DriverIRQHandler
CTIMER0_DriverIRQHandler
CTIMER1_DriverIRQHandler
CTIMER2_DriverIRQHandler
Reserved58_DriverIRQHandler
Reserved59_DriverIRQHandler
FLEXPWM0_RELOAD_ERROR_DriverIRQHandler
FLEXPWM0_FAULT_DriverIRQHandler
FLEXPWM0_SUBMODULE0_DriverIRQHandler
FLEXPWM0_SUBMODULE1_DriverIRQHandler
FLEXPWM0_SUBMODULE2_DriverIRQHandler
Reserved65_DriverIRQHandler
QDC0_COMPARE_DriverIRQHandler
QDC0_HOME_DriverIRQHandler
QDC0_WATCHDOG_DriverIRQHandler
QDC0_INDEX_DriverIRQHandler
FREQME0_DriverIRQHandler
LPTMR0_DriverIRQHandler
Reserved72_DriverIRQHandler
OS_EVENT_DriverIRQHandler
WAKETIMER0_DriverIRQHandler
UTICK0_DriverIRQHandler
WWDT0_DriverIRQHandler
Reserved77_DriverIRQHandler
ADC0_DriverIRQHandler
Reserved79_DriverIRQHandler
CMP0_DriverIRQHandler
CMP1_DriverIRQHandler
Reserved82_DriverIRQHandler
Reserved83_DriverIRQHandler
Reserved84_DriverIRQHandler
Reserved85_DriverIRQHandler
Reserved86_DriverIRQHandler
GPIO0_DriverIRQHandler
GPIO1_DriverIRQHandler
GPIO2_DriverIRQHandler
GPIO3_DriverIRQHandler
Reserved91_DriverIRQHandler
Reserved92_DriverIRQHandler
Reserved93_DriverIRQHandler
Reserved94_DriverIRQHandler
Reserved95_DriverIRQHandler
DefaultISR
B .
END

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