Bsp nxp support (#8530)
Co-authored-by: StackYuan <yuanjyjyj@outlook.com>
This commit is contained in:
parent
35eea4bc46
commit
41e08084f8
|
|
@ -0,0 +1,8 @@
|
|||
# NXP BSP 说明
|
||||
|
||||
存放RT-Thread NXP BSP目录,目前支持MCX系列,之前一些老的IC支持(如LPC/Kinetis/I.MXRT)会逐步放到此目录下
|
||||
|
||||
| BSP 文件夹名称 | 开发板名称 |
|
||||
|:------------------------- |:-------------------------- |
|
||||
| mcxn | frdm-mcxn947 |
|
||||
| mcxa | frdm-mcxa153 |
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/******************************************************************************
|
||||
* @file tz_context.h
|
||||
* @brief Context Management for Armv8-M TrustZone
|
||||
* @version V1.0.1
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef TZ_CONTEXT_H
|
||||
#define TZ_CONTEXT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef TZ_MODULEID_T
|
||||
#define TZ_MODULEID_T
|
||||
/// \details Data type that identifies secure software modules called by a process.
|
||||
typedef uint32_t TZ_ModuleId_t;
|
||||
#endif
|
||||
|
||||
/// \details TZ Memory ID identifies an allocated memory slot.
|
||||
typedef uint32_t TZ_MemoryId_t;
|
||||
|
||||
/// Initialize secure context memory system
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_InitContextSystem_S (void);
|
||||
|
||||
/// Allocate context memory for calling secure software modules in TrustZone
|
||||
/// \param[in] module identifies software modules called from non-secure mode
|
||||
/// \return value != 0 id TrustZone memory slot identifier
|
||||
/// \return value 0 no memory available or internal error
|
||||
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
|
||||
|
||||
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Load secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Store secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
|
||||
|
||||
#endif // TZ_CONTEXT_H
|
||||
|
|
@ -0,0 +1,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.
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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_ */
|
||||
|
|
@ -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) */
|
||||
}
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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) */
|
||||
}
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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_ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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_*/
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_*/
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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
|
||||
******************************************************************************/
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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 };
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 };
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
Loading…
Reference in New Issue