uploading the available driver librarires

This commit is contained in:
yul 2022-08-30 13:57:34 +02:00
parent c4b6a2973b
commit d3f98ecc30
19 changed files with 14565 additions and 0 deletions

2176
drivers/fsl_clock.c Normal file

File diff suppressed because it is too large Load Diff

1525
drivers/fsl_clock.h Normal file

File diff suppressed because it is too large Load Diff

91
drivers/fsl_common.c Normal file
View File

@ -0,0 +1,91 @@
/*
* 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
void *SDK_Malloc(size_t size, size_t alignbytes)
{
mem_align_cb_t *p_cb = NULL;
uint32_t alignedsize;
/* Check overflow. */
alignedsize = SDK_SIZEALIGN(size, alignbytes);
if (alignedsize < size)
{
return NULL;
}
if (alignedsize > SIZE_MAX - alignbytes - sizeof(mem_align_cb_t))
{
return NULL;
}
alignedsize += alignbytes + sizeof(mem_align_cb_t);
union
{
void *pointer_value;
#if (defined(__DSC__) && defined(__CW__))
uint32_t unsigned_value;
#else
uintptr_t unsigned_value;
#endif
} p_align_addr, p_addr;
p_addr.pointer_value = malloc(alignedsize);
if (p_addr.pointer_value == NULL)
{
return NULL;
}
p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);
p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
return p_align_addr.pointer_value;
}
void SDK_Free(void *ptr)
{
union
{
void *pointer_value;
#if (defined(__DSC__) && defined(__CW__))
uint32_t unsigned_value;
#else
uintptr_t unsigned_value;
#endif
} 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);
}

309
drivers/fsl_common.h Normal file
View File

@ -0,0 +1,309 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 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, 3, 1))
/*@}*/
/* 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_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_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. */
};
/*! \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
/*!
* @brief Allocate memory with given alignment and aligned size.
*
* This is provided to support the dynamically allocated memory
* used in cache-able region.
* @param size The length required to malloc.
* @param alignbytes The alignment size.
* @retval The allocated memory.
*/
void *SDK_Malloc(size_t size, size_t alignbytes);
/*!
* @brief Free memory.
*
* @param ptr The memory to be release.
*/
void SDK_Free(void *ptr);
/*!
* @brief Delay at least for some time.
* Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
* if precise delay count was needed, please implement a new delay function with hardware timer.
*
* @param 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(__XCC__)
#include "fsl_common_dsp.h"
#else
#include "fsl_common_arm.h"
#endif
#endif /* _FSL_COMMON_H_ */

233
drivers/fsl_common_arm.c Normal file
View File

@ -0,0 +1,233 @@
/*
* 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(SDK_DELAY_USE_DWT) && defined(DWT)
/* Use WDT. */
static void enableCpuCycleCounter(void)
{
/* Make sure the DWT trace fucntion is enabled. */
if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR))
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
}
/* CYCCNT not supported on this device. */
assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
/* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL))
{
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
static uint32_t getCpuCycleCount(void)
{
return DWT->CYCCNT;
}
#else /* 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
}
/* 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 */
enableCpuCycleCounter();
/* Calculate the count ticks. */
count += getCpuCycleCount();
if (count > UINT32_MAX)
{
count -= UINT32_MAX;
/* Wait for cyccnt overflow. */
while (count < getCpuCycleCount())
{
}
}
/* Wait for cyccnt reach count value. */
while (count > getCpuCycleCount())
{
}
#else
/* Divide value may be different in various environment to ensure delay is precise.
* Every loop count includes three instructions, due to Cortex-M7 sometimes executes
* two instructions in one period, through test here set divide 1.5. Other M cores use
* divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
* not matter because other instructions outside while loop is enough to fill the time.
*/
#if (__CORTEX_M == 7)
count = count / 3U * 2U;
#else
count = count / 4U;
#endif
DelayLoop((uint32_t)count);
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
}
}

671
drivers/fsl_common_arm.h Normal file
View File

@ -0,0 +1,671 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 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_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_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 Disable the global IRQ
*
* Disable the global interrupt and return the current primask register. User is required to provided the primask
* register for the EnableGlobalIRQ().
*
* @return Current primask value.
*/
static inline uint32_t DisableGlobalIRQ(void)
{
#if defined(CPSR_I_Msk)
uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
__disable_irq();
return cpsr;
#else
uint32_t regPrimask = __get_PRIMASK();
__disable_irq();
return regPrimask;
#endif
}
/*!
* @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);
#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(__cplusplus)
}
#endif /* __cplusplus*/
/*! @} */
#endif /* _FSL_COMMON_ARM_H_ */

412
drivers/fsl_flexcomm.c Normal file
View File

@ -0,0 +1,412 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_flexcomm.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.flexcomm"
#endif
/*!
* @brief Used for conversion between `void*` and `uint32_t`.
*/
typedef union pvoid_to_u32
{
void *pvoid;
uint32_t u32;
} pvoid_to_u32_t;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*! @brief Set the FLEXCOMM mode . */
static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
/*! @brief check whether flexcomm supports peripheral type */
static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Array to map FLEXCOMM instance number to base address. */
static const uint32_t s_flexcommBaseAddrs[] = FLEXCOMM_BASE_ADDRS;
/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
static flexcomm_irq_handler_t s_flexcommIrqHandler[ARRAY_SIZE(s_flexcommBaseAddrs)];
/*! @brief Pointers to handles for each instance to provide context to interrupt routines */
static void *s_flexcommHandle[ARRAY_SIZE(s_flexcommBaseAddrs)];
/*! @brief Array to map FLEXCOMM instance number to IRQ number. */
IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief IDs of clock for each FLEXCOMM module */
static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
/*! @brief Pointers to FLEXCOMM resets for each instance. */
static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
#endif
/*******************************************************************************
* Code
******************************************************************************/
/* check whether flexcomm supports peripheral type */
static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
{
if (periph == FLEXCOMM_PERIPH_NONE)
{
return true;
}
else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
{
return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false;
}
else if (periph == FLEXCOMM_PERIPH_I2S_RX)
{
return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false;
}
else
{
return false;
}
}
/* Get the index corresponding to the FLEXCOMM */
/*! brief Returns instance number for FLEXCOMM module with given base address. */
uint32_t FLEXCOMM_GetInstance(void *base)
{
uint32_t i;
pvoid_to_u32_t BaseAddr;
BaseAddr.pvoid = base;
for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
{
if (BaseAddr.u32 == s_flexcommBaseAddrs[i])
{
break;
}
}
assert(i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT);
return i;
}
/* Changes FLEXCOMM mode */
static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
{
/* Check whether peripheral type is present */
if (!FLEXCOMM_PeripheralIsPresent(base, periph))
{
return kStatus_OutOfRange;
}
/* Flexcomm is locked to different peripheral type than expected */
if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) &&
((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph))
{
return kStatus_Fail;
}
/* Check if we are asked to lock */
if (lock != 0)
{
base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
}
else
{
base->PSELID = (uint32_t)periph;
}
return kStatus_Success;
}
/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
{
uint32_t idx = FLEXCOMM_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the peripheral clock */
CLOCK_EnableClock(s_flexcommClocks[idx]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
/* Reset the FLEXCOMM module */
RESET_PeripheralReset(s_flexcommResets[idx]);
#endif
/* Set the FLEXCOMM to given peripheral */
return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
}
/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
* mode */
void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(base);
/* Clear handler first to avoid execution of the handler with wrong handle */
s_flexcommIrqHandler[instance] = NULL;
s_flexcommHandle[instance] = flexcommHandle;
s_flexcommIrqHandler[instance] = handler;
SDK_ISR_EXIT_BARRIER;
}
/* IRQ handler functions overloading weak symbols in the startup */
#if defined(FLEXCOMM0)
void FLEXCOMM0_DriverIRQHandler(void);
void FLEXCOMM0_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM0);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM1)
void FLEXCOMM1_DriverIRQHandler(void);
void FLEXCOMM1_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM1);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM2)
void FLEXCOMM2_DriverIRQHandler(void);
void FLEXCOMM2_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM2);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM3)
void FLEXCOMM3_DriverIRQHandler(void);
void FLEXCOMM3_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM3);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM4)
void FLEXCOMM4_DriverIRQHandler(void);
void FLEXCOMM4_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM4);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM5)
void FLEXCOMM5_DriverIRQHandler(void);
void FLEXCOMM5_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM5);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM6)
void FLEXCOMM6_DriverIRQHandler(void);
void FLEXCOMM6_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM6);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM7)
void FLEXCOMM7_DriverIRQHandler(void);
void FLEXCOMM7_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM7);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM8)
void FLEXCOMM8_DriverIRQHandler(void);
void FLEXCOMM8_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM8);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM9)
void FLEXCOMM9_DriverIRQHandler(void);
void FLEXCOMM9_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM9);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM10)
void FLEXCOMM10_DriverIRQHandler(void);
void FLEXCOMM10_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM10);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM11)
void FLEXCOMM11_DriverIRQHandler(void);
void FLEXCOMM11_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM11);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM12)
void FLEXCOMM12_DriverIRQHandler(void);
void FLEXCOMM12_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM12);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM13)
void FLEXCOMM13_DriverIRQHandler(void);
void FLEXCOMM13_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM13);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM14)
void FLEXCOMM14_DriverIRQHandler(void);
void FLEXCOMM14_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM14);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM15)
void FLEXCOMM15_DriverIRQHandler(void);
void FLEXCOMM15_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM15);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif
#if defined(FLEXCOMM16)
void FLEXCOMM16_DriverIRQHandler(void);
void FLEXCOMM16_DriverIRQHandler(void)
{
uint32_t instance;
/* Look up instance number */
instance = FLEXCOMM_GetInstance(FLEXCOMM16);
assert(s_flexcommIrqHandler[instance] != NULL);
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
SDK_ISR_EXIT_BARRIER;
}
#endif

64
drivers/fsl_flexcomm.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_FLEXCOMM_H_
#define _FSL_FLEXCOMM_H_
#include "fsl_common.h"
/*!
* @addtogroup flexcomm_driver
* @{
*/
/*! @name Driver version */
/*@{*/
/*! @brief FlexCOMM driver version 2.0.2. */
#define FSL_FLEXCOMM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/
/*! @brief FLEXCOMM peripheral modes. */
typedef enum
{
FLEXCOMM_PERIPH_NONE, /*!< No peripheral */
FLEXCOMM_PERIPH_USART, /*!< USART peripheral */
FLEXCOMM_PERIPH_SPI, /*!< SPI Peripheral */
FLEXCOMM_PERIPH_I2C, /*!< I2C Peripheral */
FLEXCOMM_PERIPH_I2S_TX, /*!< I2S TX Peripheral */
FLEXCOMM_PERIPH_I2S_RX, /*!< I2S RX Peripheral */
} FLEXCOMM_PERIPH_T;
/*! @brief Typedef for interrupt handler. */
typedef void (*flexcomm_irq_handler_t)(void *base, void *handle);
/*! @brief Array with IRQ number for each FLEXCOMM module. */
extern IRQn_Type const kFlexcommIrqs[];
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*! @brief Returns instance number for FLEXCOMM module with given base address. */
uint32_t FLEXCOMM_GetInstance(void *base);
/*! @brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph);
/*! @brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
* mode */
void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle);
#if defined(__cplusplus)
}
#endif
/*@}*/
#endif /* _FSL_FLEXCOMM_H_*/

317
drivers/fsl_gpio.c Normal file
View File

@ -0,0 +1,317 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_gpio.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpc_gpio"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
#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_gpioClockName[] = GPIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
/*! @brief Pointers to GPIO resets for each instance. */
static const reset_ip_name_t s_gpioResets[] = GPIO_RSTS_N;
#endif
/*******************************************************************************
* Prototypes
************ ******************************************************************/
/*!
* @brief Enable GPIO port clock.
*
* @param base GPIO peripheral base pointer.
* @param port GPIO port number.
*/
static void GPIO_EnablePortClock(GPIO_Type *base, uint32_t port);
/*******************************************************************************
* Code
******************************************************************************/
static void GPIO_EnablePortClock(GPIO_Type *base, uint32_t port)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
assert(port < ARRAY_SIZE(s_gpioClockName));
/* Upgate the GPIO clock */
CLOCK_EnableClock(s_gpioClockName[port]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Initializes the GPIO peripheral.
*
* This function ungates the GPIO clock.
*
* param base GPIO peripheral base pointer.
* param port GPIO port number.
*/
void GPIO_PortInit(GPIO_Type *base, uint32_t port)
{
GPIO_EnablePortClock(base, port);
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
/* Reset the GPIO module */
RESET_PeripheralReset(s_gpioResets[port]);
#endif
}
/*!
* brief Initializes a GPIO pin used by the board.
*
* To initialize the GPIO, define a pin configuration, either input or output, in the user file.
* Then, call the GPIO_PinInit() function.
*
* This is an example to define an input pin or 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(Typically GPIO)
* param port GPIO port number
* param pin GPIO pin number
* param config GPIO pin configuration pointer
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config)
{
GPIO_EnablePortClock(base, port);
if (config->pinDirection == kGPIO_DigitalInput)
{
#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
base->DIRCLR[port] = 1UL << pin;
#else
base->DIR[port] &= ~(1UL << pin);
#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
}
else
{
/* Set default output value */
if (config->outputLogic == 0U)
{
base->CLR[port] = (1UL << pin);
}
else
{
base->SET[port] = (1UL << pin);
}
/* Set pin direction */
#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
base->DIRSET[port] = 1UL << pin;
#else
base->DIR[port] |= 1UL << pin;
#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
}
}
#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
/*!
* @brief Set the configuration of pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param pin GPIO pin number.
* @param config GPIO pin interrupt configuration..
*/
void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config)
{
base->INTEDG[port] = (base->INTEDG[port] & ~(1UL << pin)) | ((uint32_t)config->mode << pin);
base->INTPOL[port] = (base->INTPOL[port] & ~(1UL << pin)) | ((uint32_t)config->polarity << pin);
}
/*!
* @brief Enables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] | mask;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] | mask;
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Disables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] & ~mask;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] & ~mask;
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Clears multiple pins interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTSTATA[port] = mask;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTSTATB[port] = mask;
}
else
{
/*Should not enter here*/
}
}
/*!
* @ Read port interrupt status.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param index GPIO interrupt number.
* @retval masked GPIO status value
*/
uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index)
{
uint32_t status = 0U;
if ((uint32_t)kGPIO_InterruptA == index)
{
status = base->INTSTATA[port];
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
status = base->INTSTATB[port];
}
else
{
/*Should not enter here*/
}
return status;
}
/*!
* @brief Enables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] | (1UL << pin);
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] | (1UL << pin);
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Disables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTENA[port] = base->INTENA[port] & ~(1UL << pin);
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTENB[port] = base->INTENB[port] & ~(1UL << pin);
}
else
{
/*Should not enter here*/
}
}
/*!
* @brief Clears the specific pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
{
if ((uint32_t)kGPIO_InterruptA == index)
{
base->INTSTATA[port] = 1UL << pin;
}
else if ((uint32_t)kGPIO_InterruptB == index)
{
base->INTSTATB[port] = 1UL << pin;
}
else
{
/*Should not enter here*/
}
}
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */

364
drivers/fsl_gpio.h Normal file
View File

@ -0,0 +1,364 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _LPC_GPIO_H_
#define _LPC_GPIO_H_
#include "fsl_common.h"
/*!
* @addtogroup lpc_gpio
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPC GPIO driver version. */
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 7))
/*@}*/
/*! @brief LPC 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;
/*!
* @brief The GPIO pin configuration structure.
*
* Every pin can only be configured as either output pin or input pin at a time.
* If configured as a input pin, then leave the outputConfig unused.
*/
typedef struct _gpio_pin_config
{
gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
/* Output configurations, please ignore if configured as a input one */
uint8_t outputLogic; /*!< Set default output logic, no use in input */
} gpio_pin_config_t;
#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT)
#define GPIO_PIN_INT_LEVEL 0x00U
#define GPIO_PIN_INT_EDGE 0x01U
#define PINT_PIN_INT_HIGH_OR_RISE_TRIGGER 0x00U
#define PINT_PIN_INT_LOW_OR_FALL_TRIGGER 0x01U
/*! @brief GPIO Pin Interrupt enable mode */
typedef enum _gpio_pin_enable_mode
{
kGPIO_PinIntEnableLevel = GPIO_PIN_INT_LEVEL, /*!< Generate Pin Interrupt on level mode */
kGPIO_PinIntEnableEdge = GPIO_PIN_INT_EDGE /*!< Generate Pin Interrupt on edge mode */
} gpio_pin_enable_mode_t;
/*! @brief GPIO Pin Interrupt enable polarity */
typedef enum _gpio_pin_enable_polarity
{
kGPIO_PinIntEnableHighOrRise =
PINT_PIN_INT_HIGH_OR_RISE_TRIGGER, /*!< Generate Pin Interrupt on high level or rising edge */
kGPIO_PinIntEnableLowOrFall =
PINT_PIN_INT_LOW_OR_FALL_TRIGGER /*!< Generate Pin Interrupt on low level or falling edge */
} gpio_pin_enable_polarity_t;
/*! @brief LPC GPIO interrupt index definition */
typedef enum _gpio_interrupt_index
{
kGPIO_InterruptA = 0U, /*!< Set current pin as interrupt A*/
kGPIO_InterruptB = 1U, /*!< Set current pin as interrupt B*/
} gpio_interrupt_index_t;
/*! @brief Configures the interrupt generation condition. */
typedef struct _gpio_interrupt_config
{
uint8_t mode; /* The trigger mode of GPIO interrupts */
uint8_t polarity; /* The polarity of GPIO interrupts */
} gpio_interrupt_config_t;
#endif
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*! @name GPIO Configuration */
/*@{*/
/*!
* @brief Initializes the GPIO peripheral.
*
* This function ungates the GPIO clock.
*
* @param base GPIO peripheral base pointer.
* @param port GPIO port number.
*/
void GPIO_PortInit(GPIO_Type *base, uint32_t port);
/*!
* @brief Initializes a GPIO pin used by the board.
*
* To initialize the GPIO, define a pin configuration, either input or output, in the user file.
* Then, call the GPIO_PinInit() function.
*
* This is an example to define an input pin or 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(Typically GPIO)
* @param port GPIO port number
* @param pin GPIO pin number
* @param config GPIO pin configuration pointer
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config);
/*@}*/
/*! @name GPIO Output Operations */
/*@{*/
/*!
* @brief Sets the output level of the one GPIO pin to the logic 1 or 0.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @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 port, uint32_t pin, uint8_t output)
{
base->B[port][pin] = output;
}
/*@}*/
/*! @name GPIO Input Operations */
/*@{*/
/*!
* @brief Reads the current input value of the GPIO PIN.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @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 port, uint32_t pin)
{
return (uint32_t)base->B[port][pin];
}
/*@}*/
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->SET[port] = mask;
}
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->CLR[port] = mask;
}
/*!
* @brief Reverses current output logic of the multiple GPIO pins.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->NOT[port] = mask;
}
/*@}*/
/*!
* @brief Reads the current input value of the whole GPIO port.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
*/
static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port)
{
return (uint32_t)base->PIN[port];
}
/*@}*/
/*! @name GPIO Mask Operations */
/*@{*/
/*!
* @brief Sets port mask, 0 - enable pin, 1 - disable pin.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask)
{
base->MASK[port] = mask;
}
/*!
* @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @param output GPIO port output value.
*/
static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output)
{
base->MPIN[port] = output;
}
/*!
* @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be
* affected.
*
* @param base GPIO peripheral base pointer(Typically GPIO)
* @param port GPIO port number
* @retval masked GPIO port value
*/
static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port)
{
return (uint32_t)base->MPIN[port];
}
#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
/*!
* @brief Set the configuration of pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param pin GPIO pin number.
* @param config GPIO pin interrupt configuration..
*/
void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config);
/*!
* @brief Enables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
/*!
* @brief Disables multiple pins interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
/*!
* @brief Clears pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param index GPIO interrupt number.
* @param mask GPIO pin number macro.
*/
void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
/*!
* @ Read port interrupt status.
*
* @param base GPIO base pointer.
* @param port GPIO port number
* @param index GPIO interrupt number.
* @retval masked GPIO status value
*/
uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index);
/*!
* @brief Enables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
/*!
* @brief Disables the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
/*!
* @brief Clears the specific pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param port GPIO port number.
* @param pin GPIO pin number.
* @param index GPIO interrupt number.
*/
void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
/*@}*/
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _LPC_GPIO_H_*/

2085
drivers/fsl_i2c.c Normal file

File diff suppressed because it is too large Load Diff

1148
drivers/fsl_i2c.h Normal file

File diff suppressed because it is too large Load Diff

215
drivers/fsl_iocon.h Normal file
View File

@ -0,0 +1,215 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_IOCON_H_
#define _FSL_IOCON_H_
#include "fsl_common.h"
/*!
* @addtogroup lpc_iocon
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpc_iocon"
#endif
/*! @name Driver version */
/*@{*/
/*! @brief IOCON driver version. */
#define FSL_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/
/**
* @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format
*/
typedef struct _iocon_group
{
uint8_t port; /* Pin port */
uint8_t pin; /* Pin number */
uint8_t ionumber; /* IO number */
uint16_t modefunc; /* Function and mode */
} iocon_group_t;
/**
* @brief IOCON function and mode selection definitions
* @note See the User Manual for specific modes and functions supported by the various pins.
*/
#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */
#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */
#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */
#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */
#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */
#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */
#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */
#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */
#if defined(FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH) && (FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH == 4)
#define IOCON_FUNC8 0x8 /*!< Selects pin function 8 */
#define IOCON_FUNC9 0x9 /*!< Selects pin function 9 */
#define IOCON_FUNC10 0xA /*!< Selects pin function 10 */
#define IOCON_FUNC11 0xB /*!< Selects pin function 11 */
#define IOCON_FUNC12 0xC /*!< Selects pin function 12 */
#define IOCON_FUNC13 0xD /*!< Selects pin function 13 */
#define IOCON_FUNC14 0xE /*!< Selects pin function 14 */
#define IOCON_FUNC15 0xF /*!< Selects pin function 15 */
#endif /* FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH */
#if defined(IOCON_PIO_MODE_SHIFT)
#define IOCON_MODE_INACT (0x0 << IOCON_PIO_MODE_SHIFT) /*!< No addition pin function */
#define IOCON_MODE_PULLDOWN (0x1 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-down function */
#define IOCON_MODE_PULLUP (0x2 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-up function */
#define IOCON_MODE_REPEATER (0x3 << IOCON_PIO_MODE_SHIFT) /*!< Selects pin repeater function */
#endif
#if defined(IOCON_PIO_I2CSLEW_SHIFT)
#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_I2CSLEW_SHIFT) /*!< GPIO Mode */
#define IOCON_I2C_MODE (0x0 << IOCON_PIO_I2CSLEW_SHIFT) /*!< I2C Slew Rate Control */
#define IOCON_I2C_SLEW IOCON_I2C_MODE /*!< Deprecated name for #IOCON_I2C_MODE */
#endif
#if defined(IOCON_PIO_EGP_SHIFT)
#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_EGP_SHIFT) /*!< GPIO Mode */
#define IOCON_I2C_MODE (0x0 << IOCON_PIO_EGP_SHIFT) /*!< I2C Slew Rate Control */
#define IOCON_I2C_SLEW IOCON_I2C_MODE /*!< Deprecated name for #IOCON_I2C_MODE */
#endif
#if defined(IOCON_PIO_SLEW_SHIFT)
#define IOCON_SLEW_STANDARD (0x0 << IOCON_PIO_SLEW_SHIFT) /*!< Driver Slew Rate Control */
#define IOCON_SLEW_FAST (0x1 << IOCON_PIO_SLEW_SHIFT) /*!< Driver Slew Rate Control */
#endif
#if defined(IOCON_PIO_INVERT_SHIFT)
#define IOCON_INV_EN (0x1 << IOCON_PIO_INVERT_SHIFT) /*!< Enables invert function on input */
#endif
#if defined(IOCON_PIO_DIGIMODE_SHIFT)
#define IOCON_ANALOG_EN (0x0 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables analog function by setting 0 to bit 7 */
#define IOCON_DIGITAL_EN \
(0x1 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables digital function by setting 1 to bit 7(default) */
#endif
#if defined(IOCON_PIO_FILTEROFF_SHIFT)
#define IOCON_INPFILT_OFF (0x1 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter Off for GPIO pins */
#define IOCON_INPFILT_ON (0x0 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter On for GPIO pins */
#endif
#if defined(IOCON_PIO_I2CDRIVE_SHIFT)
#define IOCON_I2C_LOWDRIVER (0x0 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< Low drive, Output drive sink is 4 mA */
#define IOCON_I2C_HIGHDRIVER (0x1 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< High drive, Output drive sink is 20 mA */
#endif
#if defined(IOCON_PIO_OD_SHIFT)
#define IOCON_OPENDRAIN_EN (0x1 << IOCON_PIO_OD_SHIFT) /*!< Enables open-drain function */
#endif
#if defined(IOCON_PIO_I2CFILTER_SHIFT)
#define IOCON_I2CFILTER_OFF (0x1 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter enabled */
#define IOCON_I2CFILTER_ON (0x0 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter not enabled, */
#endif
#if defined(IOCON_PIO_ASW_SHIFT)
#define IOCON_AWS_EN (0x1 << IOCON_PIO_ASW_SHIFT) /*!< Enables analog switch function */
#endif
#if defined(IOCON_PIO_SSEL_SHIFT)
#define IOCON_SSEL_3V3 (0x0 << IOCON_PIO_SSEL_SHIFT) /*!< 3V3 signaling in I2C mode */
#define IOCON_SSEL_1V8 (0x1 << IOCON_PIO_SSEL_SHIFT) /*!< 1V8 signaling in I2C mode */
#endif
#if defined(IOCON_PIO_ECS_SHIFT)
#define IOCON_ECS_OFF (0x0 << IOCON_PIO_ECS_SHIFT) /*!< IO is an open drain cell */
#define IOCON_ECS_ON (0x1 << IOCON_PIO_ECS_SHIFT) /*!< Pull-up resistor is connected */
#endif
#if defined(IOCON_PIO_S_MODE_SHIFT)
#define IOCON_S_MODE_0CLK (0x0 << IOCON_PIO_S_MODE_SHIFT) /*!< Bypass input filter */
#define IOCON_S_MODE_1CLK \
(0x1 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 1 filter clock are rejected \ \ \ \ \
*/
#define IOCON_S_MODE_2CLK \
(0x2 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 2 filter clock2 are rejected \ \ \ \ \
*/
#define IOCON_S_MODE_3CLK \
(0x3 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 3 filter clock2 are rejected \ \ \ \ \
*/
#define IOCON_S_MODE(clks) ((clks) << IOCON_PIO_S_MODE_SHIFT) /*!< Select clocks for digital input filter mode */
#endif
#if defined(IOCON_PIO_CLK_DIV_SHIFT)
#define IOCON_CLKDIV(div) \
((div) \
<< IOCON_PIO_CLK_DIV_SHIFT) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if (defined(FSL_FEATURE_IOCON_ONE_DIMENSION) && (FSL_FEATURE_IOCON_ONE_DIMENSION == 1))
/**
* @brief Sets I/O Control pin mux
* @param base : The base of IOCON peripheral on the chip
* @param ionumber : GPIO number to mux
* @param modefunc : OR'ed values of type IOCON_*
* @return Nothing
*/
__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t ionumber, uint32_t modefunc)
{
base->PIO[ionumber] = modefunc;
}
#else
/**
* @brief Sets I/O Control pin mux
* @param base : The base of IOCON peripheral on the chip
* @param port : GPIO port to mux
* @param pin : GPIO pin to mux
* @param modefunc : OR'ed values of type IOCON_*
* @return Nothing
*/
__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc)
{
base->PIO[port][pin] = modefunc;
}
#endif
/**
* @brief Set all I/O Control pin muxing
* @param base : The base of IOCON peripheral on the chip
* @param pinArray : Pointer to array of pin mux selections
* @param arrayLength : Number of entries in pinArray
* @return Nothing
*/
__STATIC_INLINE void IOCON_SetPinMuxing(IOCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength)
{
uint32_t i;
for (i = 0; i < arrayLength; i++)
{
#if (defined(FSL_FEATURE_IOCON_ONE_DIMENSION) && (FSL_FEATURE_IOCON_ONE_DIMENSION == 1))
IOCON_PinMuxSet(base, pinArray[i].ionumber, pinArray[i].modefunc);
#else
IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc);
#endif /* FSL_FEATURE_IOCON_ONE_DIMENSION */
}
}
/* @} */
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_IOCON_H_ */

1985
drivers/fsl_power.c Normal file

File diff suppressed because it is too large Load Diff

598
drivers/fsl_power.h Normal file
View File

@ -0,0 +1,598 @@
/*
* Copyright 2017, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_POWER_H_
#define _FSL_POWER_H_
#include "fsl_common.h"
#include "fsl_device_registers.h"
#include <stdint.h>
/*!
* @addtogroup power
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief power driver version 1.0.0. */
#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(1, 0, 0))
/*@}*/
/* Power mode configuration API parameter */
typedef enum _power_mode_config
{
kPmu_Sleep = 0U,
kPmu_Deep_Sleep = 1U,
kPmu_PowerDown = 2U,
kPmu_Deep_PowerDown = 3U,
} power_mode_cfg_t;
/**
* @brief Analog components power modes control during low power modes
*/
typedef enum pd_bits
{
kPDRUNCFG_PD_DCDC = (1UL << 0),
kPDRUNCFG_PD_BIAS = (1UL << 1),
kPDRUNCFG_PD_BODCORE = (1UL << 2),
kPDRUNCFG_PD_BODVBAT = (1UL << 3),
kPDRUNCFG_PD_FRO1M = (1UL << 4),
kPDRUNCFG_PD_FRO192M = (1UL << 5),
kPDRUNCFG_PD_FRO32K = (1UL << 6),
kPDRUNCFG_PD_XTAL32K = (1UL << 7),
kPDRUNCFG_PD_XTAL32M = (1UL << 8),
kPDRUNCFG_PD_PLL0 = (1UL << 9),
kPDRUNCFG_PD_PLL1 = (1UL << 10),
kPDRUNCFG_PD_USB0_PHY = (1UL << 11),
kPDRUNCFG_PD_USB1_PHY = (1UL << 12),
kPDRUNCFG_PD_COMP = (1UL << 13),
kPDRUNCFG_PD_TEMPSENS = (1UL << 14),
kPDRUNCFG_PD_GPADC = (1UL << 15),
kPDRUNCFG_PD_LDOMEM = (1UL << 16),
kPDRUNCFG_PD_LDODEEPSLEEP = (1UL << 17),
kPDRUNCFG_PD_LDOUSBHS = (1UL << 18),
kPDRUNCFG_PD_LDOGPADC = (1UL << 19),
kPDRUNCFG_PD_LDOXO32M = (1UL << 20),
kPDRUNCFG_PD_LDOFLASHNV = (1UL << 21),
kPDRUNCFG_PD_RNG = (1UL << 22),
kPDRUNCFG_PD_PLL0_SSCG = (1UL << 23),
kPDRUNCFG_PD_ROM = (1UL << 24),
/*
This enum member has no practical meaning,it is used to avoid MISRA issue,
user should not trying to use it.
*/
kPDRUNCFG_ForceUnsigned = 0x80000000U,
} pd_bit_t;
/**
* @brief BOD VBAT level
*/
typedef enum _power_bod_vbat_level
{
kPOWER_BodVbatLevel1000mv = 0, /*!< Brown out detector VBAT level 1V */
kPOWER_BodVbatLevel1100mv = 1, /*!< Brown out detector VBAT level 1.1V */
kPOWER_BodVbatLevel1200mv = 2, /*!< Brown out detector VBAT level 1.2V */
kPOWER_BodVbatLevel1300mv = 3, /*!< Brown out detector VBAT level 1.3V */
kPOWER_BodVbatLevel1400mv = 4, /*!< Brown out detector VBAT level 1.4V */
kPOWER_BodVbatLevel1500mv = 5, /*!< Brown out detector VBAT level 1.5V */
kPOWER_BodVbatLevel1600mv = 6, /*!< Brown out detector VBAT level 1.6V */
kPOWER_BodVbatLevel1650mv = 7, /*!< Brown out detector VBAT level 1.65V */
kPOWER_BodVbatLevel1700mv = 8, /*!< Brown out detector VBAT level 1.7V */
kPOWER_BodVbatLevel1750mv = 9, /*!< Brown out detector VBAT level 1.75V */
kPOWER_BodVbatLevel1800mv = 10, /*!< Brown out detector VBAT level 1.8V */
kPOWER_BodVbatLevel1900mv = 11, /*!< Brown out detector VBAT level 1.9V */
kPOWER_BodVbatLevel2000mv = 12, /*!< Brown out detector VBAT level 2V */
kPOWER_BodVbatLevel2100mv = 13, /*!< Brown out detector VBAT level 2.1V */
kPOWER_BodVbatLevel2200mv = 14, /*!< Brown out detector VBAT level 2.2V */
kPOWER_BodVbatLevel2300mv = 15, /*!< Brown out detector VBAT level 2.3V */
kPOWER_BodVbatLevel2400mv = 16, /*!< Brown out detector VBAT level 2.4V */
kPOWER_BodVbatLevel2500mv = 17, /*!< Brown out detector VBAT level 2.5V */
kPOWER_BodVbatLevel2600mv = 18, /*!< Brown out detector VBAT level 2.6V */
kPOWER_BodVbatLevel2700mv = 19, /*!< Brown out detector VBAT level 2.7V */
kPOWER_BodVbatLevel2806mv = 20, /*!< Brown out detector VBAT level 2.806V */
kPOWER_BodVbatLevel2900mv = 21, /*!< Brown out detector VBAT level 2.9V */
kPOWER_BodVbatLevel3000mv = 22, /*!< Brown out detector VBAT level 3.0V */
kPOWER_BodVbatLevel3100mv = 23, /*!< Brown out detector VBAT level 3.1V */
kPOWER_BodVbatLevel3200mv = 24, /*!< Brown out detector VBAT level 3.2V */
kPOWER_BodVbatLevel3300mv = 25, /*!< Brown out detector VBAT level 3.3V */
} power_bod_vbat_level_t;
/**
* @brief BOD Hysteresis control
*/
typedef enum _power_bod_hyst
{
kPOWER_BodHystLevel25mv = 0U, /*!< BOD Hysteresis control level 25mv */
kPOWER_BodHystLevel50mv = 1U, /*!< BOD Hysteresis control level 50mv */
kPOWER_BodHystLevel75mv = 2U, /*!< BOD Hysteresis control level 75mv */
kPOWER_BodHystLevel100mv = 3U, /*!< BOD Hysteresis control level 100mv */
} power_bod_hyst_t;
/**
* @brief BOD core level
*/
typedef enum _power_bod_core_level
{
kPOWER_BodCoreLevel600mv = 0, /*!< Brown out detector core level 600mV */
kPOWER_BodCoreLevel650mv = 1, /*!< Brown out detector core level 650mV */
kPOWER_BodCoreLevel700mv = 2, /*!< Brown out detector core level 700mV */
kPOWER_BodCoreLevel750mv = 3, /*!< Brown out detector core level 750mV */
kPOWER_BodCoreLevel800mv = 4, /*!< Brown out detector core level 800mV */
kPOWER_BodCoreLevel850mv = 5, /*!< Brown out detector core level 850mV */
kPOWER_BodCoreLevel900mv = 6, /*!< Brown out detector core level 900mV */
kPOWER_BodCoreLevel950mv = 7, /*!< Brown out detector core level 950mV */
} power_bod_core_level_t;
/**
* @brief Device Reset Causes
*/
typedef enum _power_device_reset_cause
{
kRESET_CAUSE_POR = 0UL, /*!< Power On Reset */
kRESET_CAUSE_PADRESET = 1UL, /*!< Hardware Pin Reset */
kRESET_CAUSE_BODRESET = 2UL, /*!< Brown-out Detector reset (either BODVBAT or BODCORE) */
kRESET_CAUSE_ARMSYSTEMRESET = 3UL, /*!< ARM System Reset */
kRESET_CAUSE_WDTRESET = 4UL, /*!< Watchdog Timer Reset */
kRESET_CAUSE_SWRRESET = 5UL, /*!< Software Reset */
kRESET_CAUSE_CDOGRESET = 6UL, /*!< Code Watchdog Reset */
/* Reset causes in DEEP-POWER-DOWN low power mode */
kRESET_CAUSE_DPDRESET_WAKEUPIO = 7UL, /*!< Any of the 4 wake-up pins */
kRESET_CAUSE_DPDRESET_RTC = 8UL, /*!< Real Time Counter (RTC) */
kRESET_CAUSE_DPDRESET_OSTIMER = 9UL, /*!< OS Event Timer (OSTIMER) */
kRESET_CAUSE_DPDRESET_WAKEUPIO_RTC = 10UL, /*!< Any of the 4 wake-up pins and RTC (it is not possible to distinguish
which of these 2 events occured first) */
kRESET_CAUSE_DPDRESET_WAKEUPIO_OSTIMER = 11UL, /*!< Any of the 4 wake-up pins and OSTIMER (it is not possible to
distinguish which of these 2 events occured first) */
kRESET_CAUSE_DPDRESET_RTC_OSTIMER = 12UL, /*!< Real Time Counter or OS Event Timer (it is not possible to
distinguish which of these 2 events occured first) */
kRESET_CAUSE_DPDRESET_WAKEUPIO_RTC_OSTIMER = 13UL, /*!< Any of the 4 wake-up pins (it is not possible to distinguish
which of these 3 events occured first) */
/* Miscallenous */
kRESET_CAUSE_NOT_RELEVANT =
14UL, /*!< No reset cause (for example, this code is used when waking up from DEEP-SLEEP low power mode) */
kRESET_CAUSE_NOT_DETERMINISTIC = 15UL, /*!< Unknown Reset Cause. Should be treated like "Hardware Pin Reset" from an
application point of view. */
} power_device_reset_cause_t;
/**
* @brief Device Boot Modes
*/
typedef enum _power_device_boot_mode
{
kBOOT_MODE_POWER_UP =
0UL, /*!< All non Low Power Mode wake up (Power On Reset, Pin Reset, BoD Reset, ARM System Reset ... ) */
kBOOT_MODE_LP_DEEP_SLEEP = 1UL, /*!< Wake up from DEEP-SLEEP Low Power mode */
kBOOT_MODE_LP_POWER_DOWN = 2UL, /*!< Wake up from POWER-DOWN Low Power mode */
kBOOT_MODE_LP_DEEP_POWER_DOWN = 4UL, /*!< Wake up from DEEP-POWER-DOWN Low Power mode */
} power_device_boot_mode_t;
/**
* @brief SRAM instances retention control during low power modes
*/
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX0 \
(1UL << 0) /*!< Enable SRAMX_0 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX1 \
(1UL << 1) /*!< Enable SRAMX_1 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX2 \
(1UL << 2) /*!< Enable SRAMX_2 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX3 \
(1UL << 3) /*!< Enable SRAMX_3 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM00 \
(1UL << 4) /*!< Enable SRAM0_0 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM10 \
(1UL << 6) /*!< Enable SRAM1_0 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM20 \
(1UL << 7) /*!< Enable SRAM2_0 retention when entering in Low power modes */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM_USB_HS \
(1UL << 14) /*!< Enable SRAM USB HS retention when entering in Low power modes */
/**
* @brief Low Power Modes Wake up sources
*/
#define WAKEUP_SYS (1ULL << 0) /*!< [SLEEP, DEEP SLEEP ] */ /* WWDT0_IRQ and BOD_IRQ*/
#define WAKEUP_SDMA0 (1ULL << 1) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_GLOBALINT0 (1ULL << 2) /*!< [SLEEP, DEEP SLEEP, POWER DOWN ] */
#define WAKEUP_GPIO_GLOBALINT1 (1ULL << 3) /*!< [SLEEP, DEEP SLEEP, POWER DOWN ] */
#define WAKEUP_GPIO_INT0_0 (1ULL << 4) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_INT0_1 (1ULL << 5) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_INT0_2 (1ULL << 6) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_INT0_3 (1ULL << 7) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_UTICK (1ULL << 8) /*!< [SLEEP, ] */
#define WAKEUP_MRT (1ULL << 9) /*!< [SLEEP, ] */
#define WAKEUP_CTIMER0 (1ULL << 10) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_CTIMER1 (1ULL << 11) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_SCT (1ULL << 12) /*!< [SLEEP, ] */
#define WAKEUP_CTIMER3 (1ULL << 13) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM0 (1ULL << 14) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM1 (1ULL << 15) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM2 (1ULL << 16) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM3 (1ULL << 17) /*!< [SLEEP, DEEP SLEEP, POWER DOWN ] */
#define WAKEUP_FLEXCOMM4 (1ULL << 18) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM5 (1ULL << 19) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM6 (1ULL << 20) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_FLEXCOMM7 (1ULL << 21) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_ADC (1ULL << 22) /*!< [SLEEP, ] */
// reserved (1ULL << 23)
#define WAKEUP_ACMP (1ULL << 24) /*!< [SLEEP, DEEP SLEEP, POWER DOWN ] */
// reserved (1ULL << 25)
// reserved (1ULL << 26)
#define WAKEUP_USB0_NEEDCLK (1ULL << 27) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_USB0 (1ULL << 28) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_RTC_LITE_ALARM_WAKEUP (1ULL << 29) /*!< [SLEEP, DEEP SLEEP, POWER DOWN, DEEP POWER DOWN] */
// reserved (1ULL << 30)
// reserved (1ULL << 31)
#define WAKEUP_GPIO_INT0_4 (1ULL << 32) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_INT0_5 (1ULL << 33) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_INT0_6 (1ULL << 34) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_GPIO_INT0_7 (1ULL << 35) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_CTIMER2 (1ULL << 36) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_CTIMER4 (1ULL << 37) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_OS_EVENT_TIMER (1ULL << 38) /*!< [SLEEP, DEEP SLEEP, POWER DOWN, DEEP POWER DOWN] */
// reserved (1ULL << 39)
// reserved (1ULL << 40)
// reserved (1ULL << 41)
// reserved (1ULL << 42)
#define CAN0_INT0 (1ULL << 43) /*!< [SLEEP, ] */
#define CAN1_INT0 (1ULL << 44) /*!< [SLEEP, ] */
// reserved (1ULL << 45)
// reserved (1ULL << 46)
#define WAKEUP_USB1 (1ULL << 47) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_USB1_NEEDCLK (1ULL << 48) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_SEC_HYPERVISOR_CALL (1ULL << 49) /*!< [SLEEP, ] */
#define WAKEUP_SEC_GPIO_INT0_0 (1ULL << 50) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_SEC_GPIO_INT0_1 (1ULL << 51) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_PLU (1ULL << 52) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_SEC_VIO (1ULL << 53)
#define WAKEUP_SHA (1ULL << 54) /*!< [SLEEP, ] */
#define WAKEUP_CASPER (1ULL << 55) /*!< [SLEEP, ] */
#define WAKEUP_PUF (1ULL << 56) /*!< [SLEEP, ] */
// reserved (1ULL << 57)
#define WAKEUP_SDMA1 (1ULL << 58) /*!< [SLEEP, DEEP SLEEP ] */
#define WAKEUP_LSPI_HS (1ULL << 59) /*!< [SLEEP, DEEP SLEEP ] */
//#define CDOG (1ULL << 60) !< [SLEEP, ]
// reserved (1ULL << 61)
// reserved (1ULL << 62)
#define WAKEUP_ALLWAKEUPIOS (1ULL << 63) /*!< [ , DEEP POWER DOWN] */
/**
* @brief Sleep Postpone
*/
#define LOWPOWER_HWWAKE_FORCED (1UL << 0) /*!< Force peripheral clocking to stay on during deep-sleep mode. */
#define LOWPOWER_HWWAKE_PERIPHERALS \
(1UL << 1) /*!< Wake for Flexcomms. Any Flexcomm FIFO reaching the level specified by its own TXLVL will cause \
peripheral clocking to wake up temporarily while the related status is asserted */
#define LOWPOWER_HWWAKE_SDMA0 \
(1UL << 3) /*!< Wake for DMA0. DMA0 being busy will cause peripheral clocking to remain running until DMA \
completes. Used in conjonction with LOWPOWER_HWWAKE_PERIPHERALS */
#define LOWPOWER_HWWAKE_SDMA1 \
(1UL << 5) /*!< Wake for DMA1. DMA0 being busy will cause peripheral clocking to remain running until DMA \
completes. Used in conjonction with LOWPOWER_HWWAKE_PERIPHERALS */
#define LOWPOWER_HWWAKE_ENABLE_FRO192M \
(1UL << 31) /*!< Need to be set if FRO192M is disable - via PDCTRL0 - in Deep Sleep mode and any of \
LOWPOWER_HWWAKE_PERIPHERALS, LOWPOWER_HWWAKE_SDMA0 or LOWPOWER_HWWAKE_SDMA1 is set */
#define LOWPOWER_CPURETCTRL_ENA_DISABLE 0 /*!< In POWER DOWN mode, CPU Retention is disabled */
#define LOWPOWER_CPURETCTRL_ENA_ENABLE 1 /*!< In POWER DOWN mode, CPU Retention is enabled */
/**
* @brief Wake up I/O sources
*/
#define LOWPOWER_WAKEUPIOSRC_PIO0_INDEX 0 /*!< Pin P1( 1) */
#define LOWPOWER_WAKEUPIOSRC_PIO1_INDEX 2 /*!< Pin P0(28) */
#define LOWPOWER_WAKEUPIOSRC_PIO2_INDEX 4 /*!< Pin P1(18) */
#define LOWPOWER_WAKEUPIOSRC_PIO3_INDEX 6 /*!< Pin P1(30) */
#define LOWPOWER_WAKEUPIOSRC_DISABLE 0 /*!< Wake up is disable */
#define LOWPOWER_WAKEUPIOSRC_RISING 1 /*!< Wake up on rising edge */
#define LOWPOWER_WAKEUPIOSRC_FALLING 2 /*!< Wake up on falling edge */
#define LOWPOWER_WAKEUPIOSRC_RISING_FALLING 3 /*!< Wake up on both rising or falling edges */
#define LOWPOWER_WAKEUPIOSRC_PIO0MODE_INDEX 12 /*!< Pin P1( 1) */
#define LOWPOWER_WAKEUPIOSRC_PIO1MODE_INDEX 14 /*!< Pin P0(28) */
#define LOWPOWER_WAKEUPIOSRC_PIO2MODE_INDEX 16 /*!< Pin P1(18) */
#define LOWPOWER_WAKEUPIOSRC_PIO3MODE_INDEX 18 /*!< Pin P1(30) */
#define LOWPOWER_WAKEUPIOSRC_IO_MODE_PLAIN 0 /*!< Wake up Pad is plain input */
#define LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN 1 /*!< Wake up Pad is pull-down */
#define LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP 2 /*!< Wake up Pad is pull-up */
#define LOWPOWER_WAKEUPIOSRC_IO_MODE_REPEATER 3 /*!< Wake up Pad is in repeater */
#define LOWPOWER_WAKEUPIO_PIO0_PULLUPDOWN_INDEX 8 /*!< Wake-up I/O 0 pull-up/down configuration index */
#define LOWPOWER_WAKEUPIO_PIO1_PULLUPDOWN_INDEX 9 /*!< Wake-up I/O 1 pull-up/down configuration index */
#define LOWPOWER_WAKEUPIO_PIO2_PULLUPDOWN_INDEX 10 /*!< Wake-up I/O 2 pull-up/down configuration index */
#define LOWPOWER_WAKEUPIO_PIO3_PULLUPDOWN_INDEX 11 /*!< Wake-up I/O 3 pull-up/down configuration index */
#define LOWPOWER_WAKEUPIO_PIO0_PULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO0_PULLUPDOWN_INDEX) /*!< Wake-up I/O 0 pull-up/down mask */
#define LOWPOWER_WAKEUPIO_PIO1_PULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO1_PULLUPDOWN_INDEX) /*!< Wake-up I/O 1 pull-up/down mask */
#define LOWPOWER_WAKEUPIO_PIO2_PULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO2_PULLUPDOWN_INDEX) /*!< Wake-up I/O 2 pull-up/down mask */
#define LOWPOWER_WAKEUPIO_PIO3_PULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO3_PULLUPDOWN_INDEX) /*!< Wake-up I/O 3 pull-up/down mask */
#define LOWPOWER_WAKEUPIO_PULLDOWN 0 /*!< Select pull-down */
#define LOWPOWER_WAKEUPIO_PULLUP 1 /*!< Select pull-up */
#define LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_INDEX \
12 /*!< Wake-up I/O 0 pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_INDEX \
13 /*!< Wake-up I/O 1 pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_INDEX \
14 /*!< Wake-up I/O 2 pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_INDEX \
15 /*!< Wake-up I/O 3 pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_INDEX) /*!< Wake-up I/O 0 pull-up/down disable/enable mask */
#define LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_INDEX) /*!< Wake-up I/O 1 pull-up/down disable/enable mask */
#define LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_INDEX) /*!< Wake-up I/O 2 pull-up/down disable/enable mask */
#define LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_INDEX) /*!< Wake-up I/O 3 pull-up/down disable/enable mask */
#define LOWPOWER_WAKEUPIO_PIO0_USEEXTERNALPULLUPDOWN_INDEX \
(16) /*!< Wake-up I/O 0 use external pull-up/down disable/enable control index*/
#define LOWPOWER_WAKEUPIO_PIO1_USEEXTERNALPULLUPDOWN_INDEX \
(17) /*!< Wake-up I/O 1 use external pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO2_USEEXTERNALPULLUPDOWN_INDEX \
(18) /*!< Wake-up I/O 2 use external pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO3_USEEXTERNALPULLUPDOWN_INDEX \
(19) /*!< Wake-up I/O 3 use external pull-up/down disable/enable control index */
#define LOWPOWER_WAKEUPIO_PIO0_USEEXTERNALPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO0_USEEXTERNALPULLUPDOWN_INDEX) /*!< Wake-up I/O 0 use external pull-up/down \
disable/enable mask, 0: disable, 1: enable */
#define LOWPOWER_WAKEUPIO_PIO1_USEEXTERNALPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO1_USEEXTERNALPULLUPDOWN_INDEX) /*!< Wake-up I/O 1 use external pull-up/down \
disable/enable mask, 0: disable, 1: enable */
#define LOWPOWER_WAKEUPIO_PIO2_USEEXTERNALPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO2_USEEXTERNALPULLUPDOWN_INDEX) /*!< Wake-up I/O 2 use external pull-up/down \
disable/enable mask, 0: disable, 1: enable */
#define LOWPOWER_WAKEUPIO_PIO3_USEEXTERNALPULLUPDOWN_MASK \
(1UL << LOWPOWER_WAKEUPIO_PIO3_USEEXTERNALPULLUPDOWN_INDEX) /*!< Wake-up I/O 3 use external pull-up/down \
disable/enable mask, 0: disable, 1: enable */
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
*
* @param en peripheral for which to enable the PDRUNCFG bit
* @return none
*/
static inline void POWER_EnablePD(pd_bit_t en)
{
/* PDRUNCFGSET */
PMC->PDRUNCFGSET0 = (uint32_t)en;
}
/*!
* @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
*
* @param en peripheral for which to disable the PDRUNCFG bit
* @return none
*/
static inline void POWER_DisablePD(pd_bit_t en)
{
/* PDRUNCFGCLR */
PMC->PDRUNCFGCLR0 = (uint32_t)en;
}
/*!
* @brief set BOD VBAT level.
*
* @param level BOD detect level
* @param hyst BoD Hysteresis control
* @param enBodVbatReset VBAT brown out detect reset
*/
void POWER_SetBodVbatLevel(power_bod_vbat_level_t level, power_bod_hyst_t hyst, bool enBodVbatReset);
#if defined(PMC_BODCORE_TRIGLVL_MASK)
/*!
* @brief set BOD core level.
*
* @param level BOD detect level
* @param hyst BoD Hysteresis control
* @param enBodCoreReset core brown out detect reset
*/
void POWER_SetBodCoreLevel(power_bod_core_level_t level, power_bod_hyst_t hyst, bool enBodCoreReset);
#endif
/*!
* @brief API to enable deep sleep bit in the ARM Core.
*
* @return none
*/
static inline void POWER_EnableDeepSleep(void)
{
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}
/*!
* @brief API to disable deep sleep bit in the ARM Core.
*
* @return none
*/
static inline void POWER_DisableDeepSleep(void)
{
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
}
/**
* @brief Shut off the Flash and execute the _WFI(), then power up the Flash after wake-up event
* This MUST BE EXECUTED outside the Flash:
* either from ROM or from SRAM. The rest could stay in Flash. But, for consistency, it is
* preferable to have all functions defined in this file implemented in ROM.
*
* @return Nothing
*/
void POWER_CycleCpuAndFlash(void);
/**
* @brief Configures and enters in DEEP-SLEEP low power mode
* @param exclude_from_pd:
* @param sram_retention_ctrl:
* @param wakeup_interrupts:
* @param hardware_wake_ctrl:
* @return Nothing
*
* !!! IMPORTANT NOTES :
0 - CPU0 & System CLock frequency is switched to FRO12MHz and is NOT restored back by the API.
* 1 - CPU0 Interrupt Enable registers (NVIC->ISER) are modified by this function. They are restored back in
case of CPU retention or if POWERDOWN is not taken (for instance because an interrupt is pending).
* 2 - The Non Maskable Interrupt (NMI) is disabled and its configuration before calling this function will be
restored back if POWERDOWN is not taken (for instance because an RTC or OSTIMER interrupt is pending).
* 3 - The HARD FAULT handler should execute from SRAM. (The Hard fault handler should initiate a full chip
reset) reset)
*/
void POWER_EnterDeepSleep(uint32_t exclude_from_pd,
uint32_t sram_retention_ctrl,
uint64_t wakeup_interrupts,
uint32_t hardware_wake_ctrl);
/**
* @brief Configures and enters in POWERDOWN low power mode
* @param exclude_from_pd:
* @param sram_retention_ctrl:
* @param wakeup_interrupts:
* @param cpu_retention_ctrl: 0 = CPU retention is disable / 1 = CPU retention is enabled, all other values are
RESERVED.
* @return Nothing
*
* !!! IMPORTANT NOTES :
0 - CPU0 & System CLock frequency is switched to FRO12MHz and is NOT restored back by the API.
* 1 - CPU0 Interrupt Enable registers (NVIC->ISER) are modified by this function. They are restored back in
case of CPU retention or if POWERDOWN is not taken (for instance because an interrupt is pending).
* 2 - The Non Maskable Interrupt (NMI) is disabled and its configuration before calling this function will be
restored back if POWERDOWN is not taken (for instance because an RTC or OSTIMER interrupt is pending).
* 3 - In case of CPU retention, it is the responsability of the user to make sure that SRAM instance
containing the stack used to call this function WILL BE preserved during low power (via parameter
"sram_retention_ctrl")
* 4 - The HARD FAULT handler should execute from SRAM. (The Hard fault handler should initiate a full chip
reset) reset)
*/
void POWER_EnterPowerDown(uint32_t exclude_from_pd,
uint32_t sram_retention_ctrl,
uint64_t wakeup_interrupts,
uint32_t cpu_retention_ctrl);
/**
* @brief Configures and enters in DEEPPOWERDOWN low power mode
* @param exclude_from_pd:
* @param sram_retention_ctrl:
* @param wakeup_interrupts:
* @param wakeup_io_ctrl:
* @return Nothing
*
* !!! IMPORTANT NOTES :
0 - CPU0 & System CLock frequency is switched to FRO12MHz and is NOT restored back by the API.
* 1 - CPU0 Interrupt Enable registers (NVIC->ISER) are modified by this function. They are restored back if
DEEPPOWERDOWN is not taken (for instance because an RTC or OSTIMER interrupt is pending).
* 2 - The Non Maskable Interrupt (NMI) is disabled and its configuration before calling this function will be
restored back if DEEPPOWERDOWN is not taken (for instance because an RTC or OSTIMER interrupt is pending).
* 3 - The HARD FAULT handler should execute from SRAM. (The Hard fault handler should initiate a full chip
reset)
*/
void POWER_EnterDeepPowerDown(uint32_t exclude_from_pd,
uint32_t sram_retention_ctrl,
uint64_t wakeup_interrupts,
uint32_t wakeup_io_ctrl);
/**
* @brief Configures and enters in SLEEP low power mode
*
* @return Nothing
*/
void POWER_EnterSleep(void);
/*!
* @brief Power Library API to choose normal regulation and set the voltage for the desired operating frequency.
*
* @param system_freq_hz - The desired frequency (in Hertz) at which the part would like to operate,
* note that the voltage and flash wait states should be set before changing frequency
* @return none
*/
void POWER_SetVoltageForFreq(uint32_t system_freq_hz);
/**
* @brief Sets board-specific trim values for 16MHz XTAL
* @param pi32_16MfXtalIecLoadpF_x100 Load capacitance, pF x 100. For example, 6pF becomes 600, 1.2pF becomes 120
* @param pi32_16MfXtalPPcbParCappF_x100 PCB +ve parasitic capacitance, pF x 100. For example, 6pF becomes 600, 1.2pF
* becomes 120
* @param pi32_16MfXtalNPcbParCappF_x100 PCB -ve parasitic capacitance, pF x 100. For example, 6pF becomes 600, 1.2pF
* becomes 120
* @return none
* @note Following default Values can be used:
* pi32_32MfXtalIecLoadpF_x100 Load capacitance, pF x 100 : 600
* pi32_32MfXtalPPcbParCappF_x100 PCB +ve parasitic capacitance, pF x 100 : 20
* pi32_32MfXtalNPcbParCappF_x100 PCB -ve parasitic capacitance, pF x 100 : 40
*/
extern void POWER_Xtal16mhzCapabankTrim(int32_t pi32_16MfXtalIecLoadpF_x100,
int32_t pi32_16MfXtalPPcbParCappF_x100,
int32_t pi32_16MfXtalNPcbParCappF_x100);
/**
* @brief Sets board-specific trim values for 32kHz XTAL
* @param pi32_32kfXtalIecLoadpF_x100 Load capacitance, pF x 100. For example, 6pF becomes 600, 1.2pF becomes 120
* @param pi32_32kfXtalPPcbParCappF_x100 PCB +ve parasitic capacitance, pF x 100. For example, 6pF becomes 600, 1.2pF
becomes 120
* @param pi32_32kfXtalNPcbParCappF_x100 PCB -ve parasitic capacitance, pF x 100. For example, 6pF becomes 600, 1.2pF
becomes 120
* @return none
* @note Following default Values can be used:
* pi32_32kfXtalIecLoadpF_x100 Load capacitance, pF x 100 : 600
* pi32_32kfXtalPPcbParCappF_x100 PCB +ve parasitic capacitance, pF x 100 : 40
* pi32_32kfXtalNPcbParCappF_x100 PCB -ve parasitic capacitance, pF x 100 : 40
*/
extern void POWER_Xtal32khzCapabankTrim(int32_t pi32_32kfXtalIecLoadpF_x100,
int32_t pi32_32kfXtalPPcbParCappF_x100,
int32_t pi32_32kfXtalNPcbParCappF_x100);
/**
* @brief Enables and sets LDO for 16MHz XTAL
* @return none
*/
extern void POWER_SetXtal16mhzLdo(void);
/**
* @brief Return some key information related to the device reset causes / wake-up sources, for all power modes.
* @param p_reset_cause : the device reset cause, according to the definition of power_device_reset_cause_t type.
* @param p_boot_mode : the device boot mode, according to the definition of power_device_boot_mode_t type.
* @param p_wakeupio_cause: the wake-up pin sources, according to the definition of register PMC->WAKEIOCAUSE[3:0].
* @return Nothing
*
* !!! IMPORTANT ERRATA - IMPORTANT ERRATA - IMPORTANT ERRATA !!!
* !!! valid ONLY for LPC55S69 (not for LPC55S16 and LPC55S06) !!!
* !!! when FALLING EDGE DETECTION is enabled on wake-up pins: !!!
* - 1. p_wakeupio_cause is NOT ACCURATE
* - 2. Spurious kRESET_CAUSE_DPDRESET_WAKEUPIO* event is reported when
* several wake-up sources are enabled during DEEP-POWER-DOWN
* (like enabling wake-up on RTC and Falling edge wake-up pins)
*
*/
void POWER_GetWakeUpCause(power_device_reset_cause_t *p_reset_cause,
power_device_boot_mode_t *p_boot_mode,
uint32_t *p_wakeupio_cause);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* _FSL_POWER_H_ */

99
drivers/fsl_reset.c Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 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
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*!
* 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)
{
const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
const uint32_t bitMask = 1UL << bitPos;
assert(bitPos < 32u);
/* reset register is in SYSCON */
/* set bit */
SYSCON->PRESETCTRLSET[regIndex] = bitMask;
/* wait until it reads 0b1 */
while (0u == (SYSCON->PRESETCTRLX[regIndex] & bitMask))
{
}
}
/*!
* 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)
{
const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
const uint32_t bitMask = 1UL << bitPos;
assert(bitPos < 32u);
/* reset register is in SYSCON */
/* clear bit */
SYSCON->PRESETCTRLCLR[regIndex] = bitMask;
/* wait until it reads 0b0 */
while (bitMask == (SYSCON->PRESETCTRLX[regIndex] & bitMask))
{
}
}
/*!
* 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_SetPeripheralReset(peripheral);
RESET_ClearPeripheralReset(peripheral);
}
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */

255
drivers/fsl_reset.h Normal file
View File

@ -0,0 +1,255 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016, 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.0.0. */
#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*!
* @brief Enumeration for peripheral reset control bits
*
* Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers
*/
typedef enum _SYSCON_RSTn
{
kROM_RST_SHIFT_RSTn = 0 | 1U, /**< ROM reset control */
kSRAM1_RST_SHIFT_RSTn = 0 | 3U, /**< SRAM1 reset control */
kSRAM2_RST_SHIFT_RSTn = 0 | 4U, /**< SRAM2 reset control */
kFLASH_RST_SHIFT_RSTn = 0 | 7U, /**< Flash controller reset control */
kFMC_RST_SHIFT_RSTn = 0 | 8U, /**< Flash accelerator reset control */
kMUX0_RST_SHIFT_RSTn = 0 | 11U, /**< Input mux0 reset control */
kIOCON_RST_SHIFT_RSTn = 0 | 13U, /**< IOCON reset control */
kGPIO0_RST_SHIFT_RSTn = 0 | 14U, /**< GPIO0 reset control */
kGPIO1_RST_SHIFT_RSTn = 0 | 15U, /**< GPIO1 reset control */
kPINT_RST_SHIFT_RSTn = 0 | 18U, /**< Pin interrupt (PINT) reset control */
kGINT_RST_SHIFT_RSTn = 0 | 19U, /**< Grouped interrupt (PINT) reset control. */
kDMA0_RST_SHIFT_RSTn = 0 | 20U, /**< DMA reset control */
kCRC_RST_SHIFT_RSTn = 0 | 21U, /**< CRC reset control */
kWWDT_RST_SHIFT_RSTn = 0 | 22U, /**< Watchdog timer reset control */
kRTC_RST_SHIFT_RSTn = 0 | 23U, /**< RTC reset control */
kMAILBOX_RST_SHIFT_RSTn = 0 | 26U, /**< Mailbox reset control */
kADC0_RST_SHIFT_RSTn = 0 | 27U, /**< ADC0 reset control */
kMRT_RST_SHIFT_RSTn = 65536 | 0U, /**< Multi-rate timer (MRT) reset control */
kOSTIMER0_RST_SHIFT_RSTn = 65536 | 1U, /**< OSTimer0 reset control */
kSCT0_RST_SHIFT_RSTn = 65536 | 2U, /**< SCTimer/PWM 0 (SCT0) reset control */
kMCAN_RST_SHIFT_RSTn = 65536 | 7U, /**< MCAN reset control */
kUTICK_RST_SHIFT_RSTn = 65536 | 10U, /**< Micro-tick timer reset control */
kFC0_RST_SHIFT_RSTn = 65536 | 11U, /**< Flexcomm Interface 0 reset control */
kFC1_RST_SHIFT_RSTn = 65536 | 12U, /**< Flexcomm Interface 1 reset control */
kFC2_RST_SHIFT_RSTn = 65536 | 13U, /**< Flexcomm Interface 2 reset control */
kFC3_RST_SHIFT_RSTn = 65536 | 14U, /**< Flexcomm Interface 3 reset control */
kFC4_RST_SHIFT_RSTn = 65536 | 15U, /**< Flexcomm Interface 4 reset control */
kFC5_RST_SHIFT_RSTn = 65536 | 16U, /**< Flexcomm Interface 5 reset control */
kFC6_RST_SHIFT_RSTn = 65536 | 17U, /**< Flexcomm Interface 6 reset control */
kFC7_RST_SHIFT_RSTn = 65536 | 18U, /**< Flexcomm Interface 7 reset control */
kCTIMER2_RST_SHIFT_RSTn = 65536 | 22U, /**< CTimer 2 reset control */
kUSB0D_RST_SHIFT_RSTn = 65536 | 25U, /**< USB0 Device reset control */
kCTIMER0_RST_SHIFT_RSTn = 65536 | 26U, /**< CTimer 0 reset control */
kCTIMER1_RST_SHIFT_RSTn = 65536 | 27U, /**< CTimer 1 reset control */
kEZHA_RST_SHIFT_RSTn = 65536 | 30U, /**< EZHA reset control */
kEZHB_RST_SHIFT_RSTn = 65536 | 31U, /**< EZHB reset control */
kDMA1_RST_SHIFT_RSTn = 131072 | 1U, /**< DMA1 reset control */
kCMP_RST_SHIFT_RSTn = 131072 | 2U, /**< CMP reset control */
kUSB1H_RST_SHIFT_RSTn = 131072 | 4U, /**< USBHS Host reset control */
kUSB1D_RST_SHIFT_RSTn = 131072 | 5U, /**< USBHS Device reset control */
kUSB1RAM_RST_SHIFT_RSTn = 131072 | 6U, /**< USB RAM reset control */
kUSB1_RST_SHIFT_RSTn = 131072 | 7U, /**< USBHS reset control */
kFREQME_RST_SHIFT_RSTn = 131072 | 8U, /**< FREQME reset control */
kCDOG_RST_SHIFT_RSTn = 131072 | 11U, /**< Code Watchdog reset control */
kRNG_RST_SHIFT_RSTn = 131072 | 13U, /**< RNG reset control */
kSYSCTL_RST_SHIFT_RSTn = 131072 | 15U, /**< SYSCTL reset control */
kUSB0HMR_RST_SHIFT_RSTn = 131072 | 16U, /**< USB0HMR reset control */
kUSB0HSL_RST_SHIFT_RSTn = 131072 | 17U, /**< USB0HSL reset control */
kHASHCRYPT_RST_SHIFT_RSTn = 131072 | 18U, /**< HASHCRYPT reset control */
kPLULUT_RST_SHIFT_RSTn = 131072 | 20U, /**< PLU LUT reset control */
kCTIMER3_RST_SHIFT_RSTn = 131072 | 21U, /**< CTimer 3 reset control */
kCTIMER4_RST_SHIFT_RSTn = 131072 | 22U, /**< CTimer 4 reset control */
kPUF_RST_SHIFT_RSTn = 131072 | 23U, /**< PUF reset control */
kCASPER_RST_SHIFT_RSTn = 131072 | 24U, /**< CASPER reset control */
kANALOGCTL_RST_SHIFT_RSTn = 131072 | 27U, /**< ANALOG_CTL reset control */
kHSLSPI_RST_SHIFT_RSTn = 131072 | 28U, /**< HS LSPI reset control */
kGPIOSEC_RST_SHIFT_RSTn = 131072 | 29U, /**< GPIO Secure reset control */
kGPIOSECINT_RST_SHIFT_RSTn = 131072 | 30U, /**< GPIO Secure int reset control */
} SYSCON_RSTn_t;
/** Array initializers with peripheral reset bits **/
#define ADC_RSTS \
{ \
kADC0_RST_SHIFT_RSTn \
} /* Reset bits for ADC peripheral */
#define MCAN_RSTS \
{ \
kMCAN_RST_SHIFT_RSTn \
} /* Reset bits for CAN 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, kCTIMER3_RST_SHIFT_RSTn, \
kCTIMER4_RST_SHIFT_RSTn \
} /* Reset bits for CTIMER peripheral */
#define DMA_RSTS_N \
{ \
kDMA0_RST_SHIFT_RSTn, kDMA1_RST_SHIFT_RSTn \
} /* Reset bits for DMA peripheral */
#define FLEXCOMM_RSTS \
{ \
kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \
kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn, kFC7_RST_SHIFT_RSTn, kHSLSPI_RST_SHIFT_RSTn \
} /* Reset bits for FLEXCOMM peripheral */
#define GINT_RSTS \
{ \
kGINT_RST_SHIFT_RSTn, kGINT_RST_SHIFT_RSTn \
} /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */
#define GPIO_RSTS_N \
{ \
kGPIO0_RST_SHIFT_RSTn, kGPIO1_RST_SHIFT_RSTn \
} /* Reset bits for GPIO peripheral */
#define INPUTMUX_RSTS \
{ \
kMUX0_RST_SHIFT_RSTn \
} /* Reset bits for INPUTMUX peripheral */
#define IOCON_RSTS \
{ \
kIOCON_RST_SHIFT_RSTn \
} /* Reset bits for IOCON peripheral */
#define FLASH_RSTS \
{ \
kFLASH_RST_SHIFT_RSTn, kFMC_RST_SHIFT_RSTn \
} /* Reset bits for Flash peripheral */
#define MRT_RSTS \
{ \
kMRT_RST_SHIFT_RSTn \
} /* Reset bits for MRT peripheral */
#define PINT_RSTS \
{ \
kPINT_RST_SHIFT_RSTn \
} /* Reset bits for PINT peripheral */
#define CDOG_RSTS \
{ \
kCDOG_RST_SHIFT_RSTn \
} /* Reset bits for CDOG peripheral */
#define RNG_RSTS \
{ \
kRNG_RST_SHIFT_RSTn \
} /* Reset bits for RNG peripheral */
#define SCT_RSTS \
{ \
kSCT0_RST_SHIFT_RSTn \
} /* Reset bits for SCT peripheral */
#define USB0D_RST \
{ \
kUSB0D_RST_SHIFT_RSTn \
} /* Reset bits for USB0D peripheral */
#define USB0HMR_RST \
{ \
kUSB0HMR_RST_SHIFT_RSTn \
} /* Reset bits for USB0HMR peripheral */
#define USB0HSL_RST \
{ \
kUSB0HSL_RST_SHIFT_RSTn \
} /* Reset bits for USB0HSL peripheral */
#define USB1H_RST \
{ \
kUSB1H_RST_SHIFT_RSTn \
} /* Reset bits for USB1H peripheral */
#define USB1D_RST \
{ \
kUSB1D_RST_SHIFT_RSTn \
} /* Reset bits for USB1D peripheral */
#define USB1RAM_RST \
{ \
kUSB1RAM_RST_SHIFT_RSTn \
} /* Reset bits for USB1RAM peripheral */
#define UTICK_RSTS \
{ \
kUTICK_RST_SHIFT_RSTn \
} /* Reset bits for UTICK peripheral */
#define WWDT_RSTS \
{ \
kWWDT_RST_SHIFT_RSTn \
} /* Reset bits for WWDT peripheral */
#define PLU_RSTS_N \
{ \
kPLULUT_RST_SHIFT_RSTn \
} /* Reset bits for PLU peripheral */
#define OSTIMER_RSTS \
{ \
kOSTIMER0_RST_SHIFT_RSTn \
} /* Reset bits for OSTIMER 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);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_RESET_H_ */

1156
drivers/fsl_usart.c Normal file

File diff suppressed because it is too large Load Diff

862
drivers/fsl_usart.h Normal file
View File

@ -0,0 +1,862 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_USART_H_
#define _FSL_USART_H_
#include "fsl_common.h"
/*!
* @addtogroup usart_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief USART driver version. */
#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 6, 0))
/*@}*/
#define USART_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_TXLVL_MASK) >> USART_FIFOTRIG_TXLVL_SHIFT)
#define USART_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_RXLVL_MASK) >> USART_FIFOTRIG_RXLVL_SHIFT)
/*! @brief Retry times for waiting flag. */
#ifndef UART_RETRY_TIMES
#define UART_RETRY_TIMES 0U /* Defining to zero means to keep waiting for the flag until it is assert/deassert. */
#endif
/*! @brief Error codes for the USART driver. */
enum
{
kStatus_USART_TxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 0), /*!< Transmitter is busy. */
kStatus_USART_RxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 1), /*!< Receiver is busy. */
kStatus_USART_TxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 2), /*!< USART transmitter is idle. */
kStatus_USART_RxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 3), /*!< USART receiver is idle. */
kStatus_USART_TxError = MAKE_STATUS(kStatusGroup_LPC_USART, 7), /*!< Error happens on txFIFO. */
kStatus_USART_RxError = MAKE_STATUS(kStatusGroup_LPC_USART, 9), /*!< Error happens on rxFIFO. */
kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8), /*!< Error happens on rx ring buffer */
kStatus_USART_NoiseError = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */
kStatus_USART_FramingError = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */
kStatus_USART_ParityError = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */
kStatus_USART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< Baudrate is not support in current clock source */
kStatus_USART_Timeout = MAKE_STATUS(kStatusGroup_LPC_USART, 14), /*!< USART time out. */
};
/*! @brief USART synchronous mode. */
typedef enum _usart_sync_mode
{
kUSART_SyncModeDisabled = 0x0U, /*!< Asynchronous mode. */
kUSART_SyncModeSlave = 0x2U, /*!< Synchronous slave mode. */
kUSART_SyncModeMaster = 0x3U, /*!< Synchronous master mode. */
} usart_sync_mode_t;
/*! @brief USART parity mode. */
typedef enum _usart_parity_mode
{
kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */
kUSART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
kUSART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
} usart_parity_mode_t;
/*! @brief USART stop bit count. */
typedef enum _usart_stop_bit_count
{
kUSART_OneStopBit = 0U, /*!< One stop bit */
kUSART_TwoStopBit = 1U, /*!< Two stop bits */
} usart_stop_bit_count_t;
/*! @brief USART data size. */
typedef enum _usart_data_len
{
kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */
kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */
} usart_data_len_t;
/*! @brief USART clock polarity configuration, used in sync mode.*/
typedef enum _usart_clock_polarity
{
kUSART_RxSampleOnFallingEdge = 0x0U, /*!< Un_RXD is sampled on the falling edge of SCLK. */
kUSART_RxSampleOnRisingEdge = 0x1U, /*!< Un_RXD is sampled on the rising edge of SCLK. */
} usart_clock_polarity_t;
/*! @brief txFIFO watermark values */
typedef enum _usart_txfifo_watermark
{
kUSART_TxFifo0 = 0, /*!< USART tx watermark is empty */
kUSART_TxFifo1 = 1, /*!< USART tx watermark at 1 item */
kUSART_TxFifo2 = 2, /*!< USART tx watermark at 2 items */
kUSART_TxFifo3 = 3, /*!< USART tx watermark at 3 items */
kUSART_TxFifo4 = 4, /*!< USART tx watermark at 4 items */
kUSART_TxFifo5 = 5, /*!< USART tx watermark at 5 items */
kUSART_TxFifo6 = 6, /*!< USART tx watermark at 6 items */
kUSART_TxFifo7 = 7, /*!< USART tx watermark at 7 items */
} usart_txfifo_watermark_t;
/*! @brief rxFIFO watermark values */
typedef enum _usart_rxfifo_watermark
{
kUSART_RxFifo1 = 0, /*!< USART rx watermark at 1 item */
kUSART_RxFifo2 = 1, /*!< USART rx watermark at 2 items */
kUSART_RxFifo3 = 2, /*!< USART rx watermark at 3 items */
kUSART_RxFifo4 = 3, /*!< USART rx watermark at 4 items */
kUSART_RxFifo5 = 4, /*!< USART rx watermark at 5 items */
kUSART_RxFifo6 = 5, /*!< USART rx watermark at 6 items */
kUSART_RxFifo7 = 6, /*!< USART rx watermark at 7 items */
kUSART_RxFifo8 = 7, /*!< USART rx watermark at 8 items */
} usart_rxfifo_watermark_t;
/*!
* @brief USART interrupt configuration structure, default settings all disabled.
*/
enum _usart_interrupt_enable
{
kUSART_TxErrorInterruptEnable = (USART_FIFOINTENSET_TXERR_MASK),
kUSART_RxErrorInterruptEnable = (USART_FIFOINTENSET_RXERR_MASK),
kUSART_TxLevelInterruptEnable = (USART_FIFOINTENSET_TXLVL_MASK),
kUSART_RxLevelInterruptEnable = (USART_FIFOINTENSET_RXLVL_MASK),
};
/*!
* @brief USART status flags.
*
* This provides constants for the USART status flags for use in the USART functions.
*/
enum _usart_flags
{
kUSART_TxError = (USART_FIFOSTAT_TXERR_MASK), /*!< TEERR bit, sets if TX buffer is error */
kUSART_RxError = (USART_FIFOSTAT_RXERR_MASK), /*!< RXERR bit, sets if RX buffer is error */
kUSART_TxFifoEmptyFlag = (USART_FIFOSTAT_TXEMPTY_MASK), /*!< TXEMPTY bit, sets if TX buffer is empty */
kUSART_TxFifoNotFullFlag = (USART_FIFOSTAT_TXNOTFULL_MASK), /*!< TXNOTFULL bit, sets if TX buffer is not full */
kUSART_RxFifoNotEmptyFlag = (USART_FIFOSTAT_RXNOTEMPTY_MASK), /*!< RXNOEMPTY bit, sets if RX buffer is not empty */
kUSART_RxFifoFullFlag = (USART_FIFOSTAT_RXFULL_MASK), /*!< RXFULL bit, sets if RX buffer is full */
};
/*! @brief USART configuration structure. */
typedef struct _usart_config
{
uint32_t baudRate_Bps; /*!< USART baud rate */
usart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
usart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
usart_data_len_t bitCountPerChar; /*!< Data length - 7 bit, 8 bit */
bool loopback; /*!< Enable peripheral loopback */
bool enableRx; /*!< Enable RX */
bool enableTx; /*!< Enable TX */
bool enableContinuousSCLK; /*!< USART continuous Clock generation enable in synchronous master mode. */
bool enableMode32k; /*!< USART uses 32 kHz clock from the RTC oscillator as the clock source. */
bool enableHardwareFlowControl; /*!< Enable hardware control RTS/CTS */
usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
usart_sync_mode_t syncMode; /*!< Transfer mode select - asynchronous, synchronous master, synchronous slave. */
usart_clock_polarity_t clockPolarity; /*!< Selects the clock polarity and sampling edge in synchronous mode. */
} usart_config_t;
/*! @brief USART transfer structure. */
typedef struct _usart_transfer
{
/*
* Use separate TX and RX data pointer, because TX data is const data.
* The member data is kept for backward compatibility.
*/
union
{
uint8_t *data; /*!< The buffer of data to be transfer.*/
uint8_t *rxData; /*!< The buffer to receive data. */
const uint8_t *txData; /*!< The buffer of data to be sent. */
};
size_t dataSize; /*!< The byte count to be transfer. */
} usart_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _usart_handle usart_handle_t;
/*! @brief USART transfer callback function. */
typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData);
/*! @brief USART handle structure. */
struct _usart_handle
{
const uint8_t *volatile txData; /*!< Address of remaining data to send. */
volatile size_t txDataSize; /*!< Size of the remaining data to send. */
size_t txDataSizeAll; /*!< Size of the data to send out. */
uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
size_t rxDataSizeAll; /*!< Size of the data to receive. */
uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
size_t rxRingBufferSize; /*!< Size of the ring buffer. */
volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
usart_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< USART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
uint8_t txWatermark; /*!< txFIFO watermark */
uint8_t rxWatermark; /*!< rxFIFO watermark */
};
/*! @brief Typedef for usart interrupt handler. */
typedef void (*flexcomm_usart_irq_handler_t)(USART_Type *base, usart_handle_t *handle);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*! @brief Returns instance number for USART peripheral base address. */
uint32_t USART_GetInstance(USART_Type *base);
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes a USART instance with user configuration structure and peripheral clock.
*
* This function configures the USART module with the user-defined settings. The user can configure the configuration
* structure and also get the default configuration by using the USART_GetDefaultConfig() function.
* Example below shows how to use this API to configure USART.
* @code
* usart_config_t usartConfig;
* usartConfig.baudRate_Bps = 115200U;
* usartConfig.parityMode = kUSART_ParityDisabled;
* usartConfig.stopBitCount = kUSART_OneStopBit;
* USART_Init(USART1, &usartConfig, 20000000U);
* @endcode
*
* @param base USART peripheral base address.
* @param config Pointer to user-defined configuration structure.
* @param srcClock_Hz USART clock source frequency in HZ.
* @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_InvalidArgument USART base address is not valid
* @retval kStatus_Success Status USART initialize succeed
*/
status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Deinitializes a USART instance.
*
* This function waits for TX complete, disables TX and RX, and disables the USART clock.
*
* @param base USART peripheral base address.
*/
void USART_Deinit(USART_Type *base);
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the USART configuration structure to a default value. The default
* values are:
* usartConfig->baudRate_Bps = 115200U;
* usartConfig->parityMode = kUSART_ParityDisabled;
* usartConfig->stopBitCount = kUSART_OneStopBit;
* usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
* usartConfig->loopback = false;
* usartConfig->enableTx = false;
* usartConfig->enableRx = false;
*
* @param config Pointer to configuration structure.
*/
void USART_GetDefaultConfig(usart_config_t *config);
/*!
* @brief Sets the USART instance baud rate.
*
* This function configures the USART module baud rate. This function is used to update
* the USART module baud rate after the USART module is initialized by the USART_Init.
* @code
* USART_SetBaudRate(USART1, 115200U, 20000000U);
* @endcode
*
* @param base USART peripheral base address.
* @param baudrate_Bps USART baudrate to be set.
* @param srcClock_Hz USART clock source frequency in HZ.
* @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success Set baudrate succeed.
* @retval kStatus_InvalidArgument One or more arguments are invalid.
*/
status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz);
/*!
* @brief Enable 32 kHz mode which USART uses clock from the RTC oscillator as the clock source
*
* Please note that in order to use a 32 kHz clock to operate USART properly, the RTC oscillator
* and its 32 kHz output must be manully enabled by user, by calling RTC_Init and setting
* SYSCON_RTCOSCCTRL_EN bit to 1.
* And in 32kHz clocking mode the USART can only work at 9600 baudrate or at the baudrate that
* 9600 can evenly divide, eg: 4800, 3200.
*
* @param base USART peripheral base address.
* @param baudRate_Bps USART baudrate to be set..
* @param enableMode32k true is 32k mode, false is normal mode.
* @param srcClock_Hz USART clock source frequency in HZ.
* @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success Set baudrate succeed.
* @retval kStatus_InvalidArgument One or more arguments are invalid.
*/
status_t USART_Enable32kMode(USART_Type *base, uint32_t baudRate_Bps, bool enableMode32k, uint32_t srcClock_Hz);
/*!
* @brief Enable 9-bit data mode for USART.
*
* This function set the 9-bit mode for USART module. The 9th bit is not used for parity thus can be modified by user.
*
* @param base USART peripheral base address.
* @param enable true to enable, false to disable.
*/
void USART_Enable9bitMode(USART_Type *base, bool enable);
/*!
* @brief Set the USART slave address.
*
* This function configures the address for USART module that works as slave in 9-bit data mode. When the address
* detection is enabled, the frame it receices with MSB being 1 is considered as an address frame, otherwise it is
* considered as data frame. Once the address frame matches slave's own addresses, this slave is addressed. This
* address frame and its following data frames are stored in the receive buffer, otherwise the frames will be discarded.
* To un-address a slave, just send an address frame with unmatched address.
*
* @note Any USART instance joined in the multi-slave system can work as slave. The position of the address mark is the
* same as the parity bit when parity is enabled for 8 bit and 9 bit data formats.
*
* @param base USART peripheral base address.
* @param address USART slave address.
*/
static inline void USART_SetMatchAddress(USART_Type *base, uint8_t address)
{
/* Configure match address. */
base->ADDR = (uint32_t)address;
}
/*!
* @brief Enable the USART match address feature.
*
* @param base USART peripheral base address.
* @param match true to enable match address, false to disable.
*/
static inline void USART_EnableMatchAddress(USART_Type *base, bool match)
{
/* Configure match address enable bit. */
if (match)
{
base->CFG |= (uint32_t)USART_CFG_AUTOADDR_MASK;
base->CTL |= (uint32_t)USART_CTL_ADDRDET_MASK;
}
else
{
base->CFG &= ~(uint32_t)USART_CFG_AUTOADDR_MASK;
base->CTL &= ~(uint32_t)USART_CTL_ADDRDET_MASK;
}
}
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Get USART status flags.
*
* This function get all USART status flags, the flags are returned as the logical
* OR value of the enumerators @ref _usart_flags. To check a specific status,
* compare the return value with enumerators in @ref _usart_flags.
* For example, to check whether the TX is empty:
* @code
* if (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(USART1))
* {
* ...
* }
* @endcode
*
* @param base USART peripheral base address.
* @return USART status flags which are ORed by the enumerators in the _usart_flags.
*/
static inline uint32_t USART_GetStatusFlags(USART_Type *base)
{
return base->FIFOSTAT;
}
/*!
* @brief Clear USART status flags.
*
* This function clear supported USART status flags
* Flags that can be cleared or set are:
* kUSART_TxError
* kUSART_RxError
* For example:
* @code
* USART_ClearStatusFlags(USART1, kUSART_TxError | kUSART_RxError)
* @endcode
*
* @param base USART peripheral base address.
* @param mask status flags to be cleared.
*/
static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask)
{
/* Only TXERR, RXERR fields support write. Remaining fields should be set to zero */
base->FIFOSTAT = mask & (USART_FIFOSTAT_TXERR_MASK | USART_FIFOSTAT_RXERR_MASK);
}
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables USART interrupts according to the provided mask.
*
* This function enables the USART interrupts according to the provided mask. The mask
* is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
* For example, to enable TX empty interrupt and RX full interrupt:
* @code
* USART_EnableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
* @endcode
*
* @param base USART peripheral base address.
* @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable.
*/
static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask)
{
base->FIFOINTENSET = mask & 0xFUL;
}
/*!
* @brief Disables USART interrupts according to a provided mask.
*
* This function disables the USART interrupts according to a provided mask. The mask
* is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
* This example shows how to disable the TX empty interrupt and RX full interrupt:
* @code
* USART_DisableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
* @endcode
*
* @param base USART peripheral base address.
* @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable.
*/
static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask)
{
base->FIFOINTENCLR = mask & 0xFUL;
}
/*!
* @brief Returns enabled USART interrupts.
*
* This function returns the enabled USART interrupts.
*
* @param base USART peripheral base address.
*/
static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base)
{
return base->FIFOINTENSET;
}
/*!
* @brief Enable DMA for Tx
*/
static inline void USART_EnableTxDMA(USART_Type *base, bool enable)
{
if (enable)
{
base->FIFOCFG |= USART_FIFOCFG_DMATX_MASK;
}
else
{
base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK);
}
}
/*!
* @brief Enable DMA for Rx
*/
static inline void USART_EnableRxDMA(USART_Type *base, bool enable)
{
if (enable)
{
base->FIFOCFG |= USART_FIFOCFG_DMARX_MASK;
}
else
{
base->FIFOCFG &= ~(USART_FIFOCFG_DMARX_MASK);
}
}
/*!
* @brief Enable CTS.
* This function will determine whether CTS is used for flow control.
*
* @param base USART peripheral base address.
* @param enable Enable CTS or not, true for enable and false for disable.
*/
static inline void USART_EnableCTS(USART_Type *base, bool enable)
{
if (enable)
{
base->CFG |= USART_CFG_CTSEN_MASK;
}
else
{
base->CFG &= ~USART_CFG_CTSEN_MASK;
}
}
/*!
* @brief Continuous Clock generation.
* By default, SCLK is only output while data is being transmitted in synchronous mode.
* Enable this funciton, SCLK will run continuously in synchronous mode, allowing
* characters to be received on Un_RxD independently from transmission on Un_TXD).
*
* @param base USART peripheral base address.
* @param enable Enable Continuous Clock generation mode or not, true for enable and false for disable.
*/
static inline void USART_EnableContinuousSCLK(USART_Type *base, bool enable)
{
if (enable)
{
base->CTL |= USART_CTL_CC_MASK;
}
else
{
base->CTL &= ~USART_CTL_CC_MASK;
}
}
/*!
* @brief Enable Continuous Clock generation bit auto clear.
* While enable this cuntion, the Continuous Clock bit is automatically cleared when a complete
* character has been received. This bit is cleared at the same time.
*
* @param base USART peripheral base address.
* @param enable Enable auto clear or not, true for enable and false for disable.
*/
static inline void USART_EnableAutoClearSCLK(USART_Type *base, bool enable)
{
if (enable)
{
base->CTL |= USART_CTL_CLRCCONRX_MASK;
}
else
{
base->CTL &= ~USART_CTL_CLRCCONRX_MASK;
}
}
/*!
* @brief Sets the rx FIFO watermark.
*
* @param base USART peripheral base address.
* @param water Rx FIFO watermark.
*/
static inline void USART_SetRxFifoWatermark(USART_Type *base, uint8_t water)
{
assert(water <= (USART_FIFOTRIG_RXLVL_MASK >> USART_FIFOTRIG_RXLVL_SHIFT));
base->FIFOTRIG = (base->FIFOTRIG & ~USART_FIFOTRIG_RXLVL_MASK) | USART_FIFOTRIG_RXLVL(water);
}
/*!
* @brief Sets the tx FIFO watermark.
*
* @param base USART peripheral base address.
* @param water Tx FIFO watermark.
*/
static inline void USART_SetTxFifoWatermark(USART_Type *base, uint8_t water)
{
assert(water <= (USART_FIFOTRIG_TXLVL_MASK >> USART_FIFOTRIG_TXLVL_SHIFT));
base->FIFOTRIG = (base->FIFOTRIG & ~USART_FIFOTRIG_TXLVL_MASK) | USART_FIFOTRIG_TXLVL(water);
}
/* @} */
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Writes to the FIFOWR register.
*
* This function writes data to the txFIFO directly. The upper layer must ensure
* that txFIFO has space for data to write before calling this function.
*
* @param base USART peripheral base address.
* @param data The byte to write.
*/
static inline void USART_WriteByte(USART_Type *base, uint8_t data)
{
base->FIFOWR = data;
}
/*!
* @brief Reads the FIFORD register directly.
*
* This function reads data from the rxFIFO directly. The upper layer must
* ensure that the rxFIFO is not empty before calling this function.
*
* @param base USART peripheral base address.
* @return The byte read from USART data register.
*/
static inline uint8_t USART_ReadByte(USART_Type *base)
{
return (uint8_t)base->FIFORD;
}
/*!
* @brief Gets the rx FIFO data count.
*
* @param base USART peripheral base address.
* @return rx FIFO data count.
*/
static inline uint8_t USART_GetRxFifoCount(USART_Type *base)
{
return (uint8_t)((base->FIFOSTAT & USART_FIFOSTAT_RXLVL_MASK) >> USART_FIFOSTAT_RXLVL_SHIFT);
}
/*!
* @brief Gets the tx FIFO data count.
*
* @param base USART peripheral base address.
* @return tx FIFO data count.
*/
static inline uint8_t USART_GetTxFifoCount(USART_Type *base)
{
return (uint8_t)((base->FIFOSTAT & USART_FIFOSTAT_TXLVL_MASK) >> USART_FIFOSTAT_TXLVL_SHIFT);
}
/*!
* @brief Transmit an address frame in 9-bit data mode.
*
* @param base USART peripheral base address.
* @param address USART slave address.
*/
void USART_SendAddress(USART_Type *base, uint8_t address);
/*!
* @brief Writes to the TX register using a blocking method.
*
* This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
* to have room and writes data to the TX buffer.
*
* @param base USART peripheral base address.
* @param data Start address of the data to write.
* @param length Size of the data to write.
* @retval kStatus_USART_Timeout Transmission timed out and was aborted.
* @retval kStatus_InvalidArgument Invalid argument.
* @retval kStatus_Success Successfully wrote all data.
*/
status_t USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Read RX data register using a blocking method.
*
* This function polls the RX register, waits for the RX register to be full or for RX FIFO to
* have data and read data from the TX register.
*
* @param base USART peripheral base address.
* @param data Start address of the buffer to store the received data.
* @param length Size of the buffer.
* @retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
* @retval kStatus_USART_ParityError Noise error happened while receiving data.
* @retval kStatus_USART_NoiseError Framing error happened while receiving data.
* @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
* @retval kStatus_USART_Timeout Transmission timed out and was aborted.
* @retval kStatus_Success Successfully received all data.
*/
status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length);
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the USART handle.
*
* This function initializes the USART handle which can be used for other USART
* transactional APIs. Usually, for a specified USART instance,
* call this API once to get the initialized handle.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param callback The callback function.
* @param userData The parameter of the callback function.
*/
status_t USART_TransferCreateHandle(USART_Type *base,
usart_handle_t *handle,
usart_transfer_callback_t callback,
void *userData);
/*!
* @brief Transmits a buffer of data using the interrupt method.
*
* This function sends data using an interrupt method. This is a non-blocking function, which
* returns directly without waiting for all data to be written to the TX register. When
* all data is written to the TX register in the IRQ handler, the USART driver calls the callback
* function and passes the @ref kStatus_USART_TxIdle as status parameter.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param xfer USART transfer structure. See #usart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer);
/*!
* @brief Sets up the RX ring buffer.
*
* This function sets up the RX ring buffer to a specific USART handle.
*
* When the RX ring buffer is used, data received are stored into the ring buffer even when the
* user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
* in the ring buffer, the user can get the received data from the ring buffer directly.
*
* @note When using the RX ring buffer, one byte is reserved for internal use. In other
* words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
* @param ringBufferSize size of the ring buffer.
*/
void USART_TransferStartRingBuffer(USART_Type *base,
usart_handle_t *handle,
uint8_t *ringBuffer,
size_t ringBufferSize);
/*!
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle);
/*!
* @brief Get the length of received data in RX ring buffer.
*
* @param handle USART handle pointer.
* @return Length of received data in RX ring buffer.
*/
size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle);
/*!
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
* how many bytes are still not sent out.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been sent out to bus.
*
* This function gets the number of bytes that have been sent out to bus by interrupt method.
*
* @param base USART peripheral base address.
* @param handle USART 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 USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
/*!
* @brief Receives a buffer of data using an interrupt method.
*
* This function receives data using an interrupt method. This is a non-blocking function, which
* returns without waiting for all data to be received.
* If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
* the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
* After copying, if the data in the ring buffer is not enough to read, the receive
* request is saved by the USART driver. When the new data arrives, the receive request
* is serviced first. When all data is received, the USART driver notifies the upper layer
* through a callback function and passes the status parameter @ref kStatus_USART_RxIdle.
* For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
* The 5 bytes are copied to the xfer->data and this function returns with the
* parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
* saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
* If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
* to receive data to the xfer->data. When all data is received, the upper layer is notified.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
* @param xfer USART transfer structure, see #usart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into transmit queue.
* @retval kStatus_USART_RxBusy Previous receive request is not finished.
* @retval kStatus_InvalidArgument Invalid argument.
*/
status_t USART_TransferReceiveNonBlocking(USART_Type *base,
usart_handle_t *handle,
usart_transfer_t *xfer,
size_t *receivedBytes);
/*!
* @brief Aborts the interrupt-driven data receiving.
*
* This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
* how many bytes not received yet.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*
* @param base USART peripheral base address.
* @param handle USART 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 USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
/*!
* @brief USART IRQ handle function.
*
* This function handles the USART transmit and receive IRQ request.
*
* @param base USART peripheral base address.
* @param handle USART handle pointer.
*/
void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_USART_H_ */