mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-21 10:36:04 +08:00
[BSP] Import RV32M1 SDK
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CORE_RISCV32_H__
|
||||
#define __CORE_RISCV32_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RISCV32
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
|
||||
#define __BKPT(x) __ASM("ebreak")
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("csrsi mstatus, 8");
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("csrci mstatus, 8");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
return __builtin_bswap32(value);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
return __builtin_bswap16(value);
|
||||
}
|
||||
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_RISCV32_H__ */
|
||||
@@ -0,0 +1,14 @@
|
||||
# for module compiling
|
||||
import os
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
objs = []
|
||||
list = os.listdir(cwd)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||
|
||||
Return('objs')
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Split('''
|
||||
system_RV32M1_ri5cy.c
|
||||
drivers/fsl_clock.c
|
||||
drivers/fsl_common.c
|
||||
drivers/fsl_lpuart.c
|
||||
drivers/fsl_gpio.c
|
||||
drivers/fsl_msmc.c
|
||||
drivers/fsl_usdhc.c
|
||||
drivers/fsl_intmux.c
|
||||
gcc/startup_RV32M1_ri5cy.S
|
||||
''')
|
||||
CPPPATH = [cwd, cwd + '/../../RISCV', cwd + '/drivers', cwd + '/utilities']
|
||||
CPPDEFINES = ['CPU_RV32M1_ri5cy', 'SDK_DEBUGCONSOLE=0']
|
||||
|
||||
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_debug_console.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if (defined(__CC_ARM)) || (defined(__ICCARM__))
|
||||
void __aeabi_assert(const char *failedExpr, const char *file, int line)
|
||||
{
|
||||
PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line);
|
||||
for (;;)
|
||||
{
|
||||
__BKPT(0);
|
||||
}
|
||||
}
|
||||
#elif(defined(__GNUC__))
|
||||
void __assert_func(const char *file, int line, const char *func, const char *failedExpr)
|
||||
{
|
||||
PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func);
|
||||
for (;;)
|
||||
{
|
||||
__BKPT(0);
|
||||
}
|
||||
}
|
||||
#endif /* (defined(__CC_ARM)) || (defined (__ICCARM__)) */
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#ifndef __GIC_PRIO_BITS
|
||||
#ifndef __riscv
|
||||
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
|
||||
{
|
||||
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
|
||||
#if defined(__CC_ARM)
|
||||
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) */
|
||||
uint32_t n;
|
||||
uint32_t ret;
|
||||
uint32_t irqMaskValue;
|
||||
|
||||
irqMaskValue = DisableGlobalIRQ();
|
||||
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
|
||||
{
|
||||
/* Copy the vector table from ROM to RAM */
|
||||
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
|
||||
{
|
||||
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
|
||||
}
|
||||
/* Point the VTOR to the position of vector table */
|
||||
SCB->VTOR = (uint32_t)__VECTOR_RAM;
|
||||
}
|
||||
|
||||
ret = __VECTOR_RAM[irq + 16];
|
||||
/* make sure the __VECTOR_RAM is noncachable */
|
||||
__VECTOR_RAM[irq + 16] = irqHandler;
|
||||
|
||||
EnableGlobalIRQ(irqMaskValue);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef QN908XC_SERIES
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
|
||||
void EnableDeepSleepIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
uint32_t intNumber = (uint32_t)interrupt;
|
||||
while (intNumber >= 32u)
|
||||
{
|
||||
index++;
|
||||
intNumber -= 32u;
|
||||
}
|
||||
|
||||
SYSCON->STARTERSET[index] = 1u << intNumber;
|
||||
EnableIRQ(interrupt); /* also enable interrupt at NVIC */
|
||||
}
|
||||
|
||||
void DisableDeepSleepIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
uint32_t intNumber = (uint32_t)interrupt;
|
||||
while (intNumber >= 32u)
|
||||
{
|
||||
index++;
|
||||
intNumber -= 32u;
|
||||
}
|
||||
|
||||
DisableIRQ(interrupt); /* also disable interrupt at NVIC */
|
||||
SYSCON->STARTERCLR[index] = 1u << intNumber;
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
|
||||
|
||||
#endif /* QN908XC_SERIES */
|
||||
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 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>
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup ksdk_common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Construct a status code value from a group and code number. */
|
||||
#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
|
||||
|
||||
/*! @brief Construct the version number for drivers. */
|
||||
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief common driver version 2.0.0. */
|
||||
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/* Debug console type definition. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console base on i.MX UART. */
|
||||
#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console base on LPC_USART. */
|
||||
|
||||
/*! @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_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_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_MICFIL = 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_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
|
||||
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
|
||||
kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */
|
||||
};
|
||||
|
||||
/*! @brief Generic status return codes. */
|
||||
enum _generic_status
|
||||
{
|
||||
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
|
||||
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
|
||||
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
|
||||
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
|
||||
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
|
||||
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
|
||||
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
|
||||
};
|
||||
|
||||
/*! @brief Type used for all status and error return values. */
|
||||
typedef int32_t status_t;
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*! @name Min/max macros */
|
||||
/* @{ */
|
||||
#if !defined(MIN)
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#if !defined(MAX)
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @brief Computes the number of elements in an array. */
|
||||
#if !defined(ARRAY_SIZE)
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/*! @name UINT16_MAX/UINT32_MAX value */
|
||||
/* @{ */
|
||||
#if !defined(UINT16_MAX)
|
||||
#define UINT16_MAX ((uint16_t)-1)
|
||||
#endif
|
||||
|
||||
#if !defined(UINT32_MAX)
|
||||
#define UINT32_MAX ((uint32_t)-1)
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*! @name Timer utilities */
|
||||
/* @{ */
|
||||
/*! Macro to convert a microsecond period to raw count value */
|
||||
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U)
|
||||
/*! Macro to convert a raw count value to microsecond */
|
||||
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
|
||||
|
||||
/*! Macro to convert a millisecond period to raw count value */
|
||||
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
|
||||
/*! Macro to convert a raw count value to millisecond */
|
||||
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
|
||||
/* @} */
|
||||
|
||||
/*! @name Alignment variable definition macros */
|
||||
/* @{ */
|
||||
#if (defined(__ICCARM__))
|
||||
/**
|
||||
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
|
||||
* http://supp.iar.com/Support/?note=24725
|
||||
*/
|
||||
_Pragma("diag_suppress=Pm120")
|
||||
#define SDK_PRAGMA(x) _Pragma(#x)
|
||||
_Pragma("diag_error=Pm120")
|
||||
/*! Macro to define a variable with alignbytes alignment */
|
||||
#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
|
||||
/*! Macro to define a variable with L1 d-cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
|
||||
#endif
|
||||
/*! Macro to define a variable with L2 cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
|
||||
#endif
|
||||
#elif defined(__CC_ARM)
|
||||
/*! Macro to define a variable with alignbytes alignment */
|
||||
#define SDK_ALIGN(var, alignbytes) __align(alignbytes) var
|
||||
/*! Macro to define a variable with L1 d-cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define SDK_L1DCACHE_ALIGN(var) __align(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
|
||||
#endif
|
||||
/*! Macro to define a variable with L2 cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define SDK_L2CACHE_ALIGN(var) __align(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
/*! Macro to define a variable with alignbytes alignment */
|
||||
#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
|
||||
/*! Macro to define a variable with L1 d-cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
|
||||
#endif
|
||||
/*! Macro to define a variable with L2 cache line size alignment */
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)))
|
||||
#endif
|
||||
#else
|
||||
#error Toolchain not supported
|
||||
#define SDK_ALIGN(var, alignbytes) var
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define SDK_L1DCACHE_ALIGN(var) var
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define SDK_L2CACHE_ALIGN(var) var
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*! Macro to change a value to a given size aligned value */
|
||||
#define SDK_SIZEALIGN(var, alignbytes) \
|
||||
((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1)))
|
||||
/* @} */
|
||||
|
||||
/*! @name Non-cacheable region definition macros */
|
||||
/* @{ */
|
||||
#if (defined(__ICCARM__))
|
||||
#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)
|
||||
#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
|
||||
#else
|
||||
#define AT_NONCACHEABLE_SECTION(var) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
|
||||
#endif
|
||||
#elif(defined(__CC_ARM))
|
||||
#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)
|
||||
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable"), zero_init)) __align(alignbytes) var
|
||||
#else
|
||||
#define AT_NONCACHEABLE_SECTION(var) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __align(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.
|
||||
*/
|
||||
#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)
|
||||
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
|
||||
__attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes)))
|
||||
#else
|
||||
#define AT_NONCACHEABLE_SECTION(var) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
|
||||
#endif
|
||||
#else
|
||||
#error Toolchain not supported.
|
||||
#define AT_NONCACHEABLE_SECTION(var) var
|
||||
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var
|
||||
#endif
|
||||
/* @} */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Enable specific interrupt.
|
||||
*
|
||||
* Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
|
||||
* levels. For example, there are NVIC and intmux. Here the interrupts connected
|
||||
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
|
||||
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
|
||||
* to NVIC first then routed to core.
|
||||
*
|
||||
* This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
|
||||
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
* @retval kStatus_Success Interrupt enabled successfully
|
||||
* @retval kStatus_Fail Failed to enable the interrupt
|
||||
*/
|
||||
static inline status_t EnableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
|
||||
if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_EVENT_COUNT) && (FSL_FEATURE_SOC_EVENT_COUNT > 0)
|
||||
EVENT_UNIT->INTPTEN |= (uint32_t)(1 << interrupt);
|
||||
/* Read back to make sure write finished. */
|
||||
(void)EVENT_UNIT->INTPTEN;
|
||||
#else
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_EnableIRQ(interrupt);
|
||||
#else
|
||||
NVIC_EnableIRQ(interrupt);
|
||||
#endif
|
||||
#endif
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable specific interrupt.
|
||||
*
|
||||
* Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
|
||||
* levels. For example, there are NVIC and intmux. Here the interrupts connected
|
||||
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
|
||||
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
|
||||
* to NVIC first then routed to core.
|
||||
*
|
||||
* This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
|
||||
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
* @retval kStatus_Success Interrupt disabled successfully
|
||||
* @retval kStatus_Fail Failed to disable the interrupt
|
||||
*/
|
||||
static inline status_t DisableIRQ(IRQn_Type interrupt)
|
||||
{
|
||||
if (NotAvail_IRQn == interrupt)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
|
||||
if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_EVENT_COUNT) && (FSL_FEATURE_SOC_EVENT_COUNT > 0)
|
||||
EVENT_UNIT->INTPTEN &= ~(uint32_t)(1 << interrupt);
|
||||
/* Read back to make sure write finished. */
|
||||
(void)EVENT_UNIT->INTPTEN;
|
||||
#else
|
||||
#if defined(__GIC_PRIO_BITS)
|
||||
GIC_DisableIRQ(interrupt);
|
||||
#else
|
||||
NVIC_DisableIRQ(interrupt);
|
||||
#endif
|
||||
#endif
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the global IRQ
|
||||
*
|
||||
* Disable the global interrupt and return the current primask register. User is required to provided the primask
|
||||
* register for the EnableGlobalIRQ().
|
||||
*
|
||||
* @return Current primask value.
|
||||
*/
|
||||
static inline uint32_t DisableGlobalIRQ(void)
|
||||
{
|
||||
#ifndef __riscv
|
||||
#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
|
||||
#else
|
||||
uint32_t mstatus;
|
||||
|
||||
__ASM volatile ("csrrci %0, mstatus, 8" : "=r"(mstatus));
|
||||
|
||||
return mstatus;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enaable the global IRQ
|
||||
*
|
||||
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
|
||||
* convinience 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)
|
||||
{
|
||||
#ifndef __riscv
|
||||
#if defined(CPSR_I_Msk)
|
||||
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
|
||||
#else
|
||||
__set_PRIMASK(primask);
|
||||
#endif
|
||||
#else
|
||||
__ASM volatile ("csrw mstatus, %0" : : "r"(primask));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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);
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
/*!
|
||||
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
|
||||
*
|
||||
* Enable the interrupt for wake-up from deep sleep mode.
|
||||
* Some interrupts are typically used in sleep mode only and will not occur during
|
||||
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
|
||||
* those clocks (significantly increasing power consumption in the reduced power mode),
|
||||
* making these wake-ups possible.
|
||||
*
|
||||
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally).
|
||||
*
|
||||
* @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 internally).
|
||||
*
|
||||
* @param interrupt The IRQ number.
|
||||
*/
|
||||
void DisableDeepSleepIRQ(IRQn_Type interrupt);
|
||||
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_COMMON_H_ */
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include "fsl_crc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @internal @brief Has data register with name CRC. */
|
||||
#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG
|
||||
#define DATA CRC
|
||||
#define DATALL CRCLL
|
||||
#endif
|
||||
|
||||
#if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT
|
||||
/* @brief Default user configuration structure for CRC-16-CCITT */
|
||||
#define CRC_DRIVER_DEFAULT_POLYNOMIAL 0x1021U
|
||||
/*< CRC-16-CCIT polynomial x**16 + x**12 + x**5 + x**0 */
|
||||
#define CRC_DRIVER_DEFAULT_SEED 0xFFFFU
|
||||
/*< Default initial checksum */
|
||||
#define CRC_DRIVER_DEFAULT_REFLECT_IN false
|
||||
/*< Default is no transpose */
|
||||
#define CRC_DRIVER_DEFAULT_REFLECT_OUT false
|
||||
/*< Default is transpose bytes */
|
||||
#define CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM false
|
||||
/*< Default is without complement of CRC data register read data */
|
||||
#define CRC_DRIVER_DEFAULT_CRC_BITS kCrcBits16
|
||||
/*< Default is 16-bit CRC protocol */
|
||||
#define CRC_DRIVER_DEFAULT_CRC_RESULT kCrcFinalChecksum
|
||||
/*< Default is resutl type is final checksum */
|
||||
#endif /* CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT */
|
||||
|
||||
/*! @brief CRC type of transpose of read write data */
|
||||
typedef enum _crc_transpose_type
|
||||
{
|
||||
kCrcTransposeNone = 0U, /*! No transpose */
|
||||
kCrcTransposeBits = 1U, /*! Tranpose bits in bytes */
|
||||
kCrcTransposeBitsAndBytes = 2U, /*! Transpose bytes and bits in bytes */
|
||||
kCrcTransposeBytes = 3U, /*! Transpose bytes */
|
||||
} crc_transpose_type_t;
|
||||
|
||||
/*!
|
||||
* @brief CRC module configuration.
|
||||
*
|
||||
* This structure holds the configuration for the CRC module.
|
||||
*/
|
||||
typedef struct _crc_module_config
|
||||
{
|
||||
uint32_t polynomial; /*!< CRC Polynomial, MSBit first.@n
|
||||
Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */
|
||||
uint32_t seed; /*!< Starting checksum value */
|
||||
crc_transpose_type_t readTranspose; /*!< Type of transpose when reading CRC result. */
|
||||
crc_transpose_type_t writeTranspose; /*!< Type of transpose when writing CRC input data. */
|
||||
bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */
|
||||
crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */
|
||||
} crc_module_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Returns transpose type for CRC protocol reflect in parameter.
|
||||
*
|
||||
* This functions helps to set writeTranspose member of crc_config_t structure. Reflect in is CRC protocol parameter.
|
||||
*
|
||||
* @param enable True or false for the selected CRC protocol Reflect In (refin) parameter.
|
||||
*/
|
||||
static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectIn(bool enable)
|
||||
{
|
||||
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Returns transpose type for CRC protocol reflect out parameter.
|
||||
*
|
||||
* This functions helps to set readTranspose member of crc_config_t structure. Reflect out is CRC protocol parameter.
|
||||
*
|
||||
* @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter.
|
||||
*/
|
||||
static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectOut(bool enable)
|
||||
{
|
||||
return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts checksum computation.
|
||||
*
|
||||
* Configures the CRC module for the specified CRC protocol. @n
|
||||
* Starts the checksum computation by writing the seed value
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param config Pointer to protocol configuration structure.
|
||||
*/
|
||||
static void CRC_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config)
|
||||
{
|
||||
uint32_t crcControl;
|
||||
|
||||
/* pre-compute value for CRC control registger based on user configuraton without WAS field */
|
||||
crcControl = 0 | CRC_CTRL_TOT(config->writeTranspose) | CRC_CTRL_TOTR(config->readTranspose) |
|
||||
CRC_CTRL_FXOR(config->complementChecksum) | CRC_CTRL_TCRC(config->crcBits);
|
||||
|
||||
/* make sure the control register is clear - WAS is deasserted, and protocol is set */
|
||||
base->CTRL = crcControl;
|
||||
|
||||
/* write polynomial register */
|
||||
base->GPOLY = config->polynomial;
|
||||
|
||||
/* write pre-computed control register value along with WAS to start checksum computation */
|
||||
base->CTRL = crcControl | CRC_CTRL_WAS(true);
|
||||
|
||||
/* write seed (initial checksum) */
|
||||
base->DATA = config->seed;
|
||||
|
||||
/* deassert WAS by writing pre-computed CRC control register value */
|
||||
base->CTRL = crcControl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts final checksum computation.
|
||||
*
|
||||
* Configures the CRC module for the specified CRC protocol. @n
|
||||
* Starts final checksum computation by writing the seed value.
|
||||
* @note CRC_Get16bitResult() or CRC_Get32bitResult() return final checksum
|
||||
* (output reflection and xor functions are applied).
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param protocolConfig Pointer to protocol configuration structure.
|
||||
*/
|
||||
static void CRC_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
|
||||
{
|
||||
crc_module_config_t moduleConfig;
|
||||
/* convert protocol to CRC peripheral module configuration, prepare for final checksum */
|
||||
moduleConfig.polynomial = protocolConfig->polynomial;
|
||||
moduleConfig.seed = protocolConfig->seed;
|
||||
moduleConfig.readTranspose = CRC_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut);
|
||||
moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
|
||||
moduleConfig.complementChecksum = protocolConfig->complementChecksum;
|
||||
moduleConfig.crcBits = protocolConfig->crcBits;
|
||||
|
||||
CRC_ConfigureAndStart(base, &moduleConfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Starts intermediate checksum computation.
|
||||
*
|
||||
* Configures the CRC module for the specified CRC protocol. @n
|
||||
* Starts intermediate checksum computation by writing the seed value.
|
||||
* @note CRC_Get16bitResult() or CRC_Get32bitResult() return intermediate checksum (raw data register value).
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param protocolConfig Pointer to protocol configuration structure.
|
||||
*/
|
||||
static void CRC_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig)
|
||||
{
|
||||
crc_module_config_t moduleConfig;
|
||||
/* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */
|
||||
moduleConfig.polynomial = protocolConfig->polynomial;
|
||||
moduleConfig.seed = protocolConfig->seed;
|
||||
moduleConfig.readTranspose =
|
||||
kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */
|
||||
moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn);
|
||||
moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */
|
||||
moduleConfig.crcBits = protocolConfig->crcBits;
|
||||
|
||||
CRC_ConfigureAndStart(base, &moduleConfig);
|
||||
}
|
||||
|
||||
void CRC_Init(CRC_Type *base, const crc_config_t *config)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* ungate clock */
|
||||
CLOCK_EnableClock(kCLOCK_Crc0);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
/* configure CRC module and write the seed */
|
||||
if (config->crcResult == kCrcFinalChecksum)
|
||||
{
|
||||
CRC_SetProtocolConfig(base, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
CRC_SetRawProtocolConfig(base, config);
|
||||
}
|
||||
}
|
||||
|
||||
void CRC_GetDefaultConfig(crc_config_t *config)
|
||||
{
|
||||
static const crc_config_t crc16ccit = {
|
||||
CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_SEED,
|
||||
CRC_DRIVER_DEFAULT_REFLECT_IN, CRC_DRIVER_DEFAULT_REFLECT_OUT,
|
||||
CRC_DRIVER_DEFAULT_COMPLEMENT_CHECKSUM, CRC_DRIVER_DEFAULT_CRC_BITS,
|
||||
CRC_DRIVER_DEFAULT_CRC_RESULT,
|
||||
};
|
||||
|
||||
*config = crc16ccit;
|
||||
}
|
||||
|
||||
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize)
|
||||
{
|
||||
const uint32_t *data32;
|
||||
|
||||
/* 8-bit reads and writes till source address is aligned 4 bytes */
|
||||
while ((dataSize) && ((uint32_t)data & 3U))
|
||||
{
|
||||
base->ACCESS8BIT.DATALL = *data;
|
||||
data++;
|
||||
dataSize--;
|
||||
}
|
||||
|
||||
/* use 32-bit reads and writes as long as possible */
|
||||
data32 = (const uint32_t *)data;
|
||||
while (dataSize >= sizeof(uint32_t))
|
||||
{
|
||||
base->DATA = *data32;
|
||||
data32++;
|
||||
dataSize -= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
data = (const uint8_t *)data32;
|
||||
|
||||
/* 8-bit reads and writes till end of data buffer */
|
||||
while (dataSize)
|
||||
{
|
||||
base->ACCESS8BIT.DATALL = *data;
|
||||
data++;
|
||||
dataSize--;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CRC_Get32bitResult(CRC_Type *base)
|
||||
{
|
||||
return base->DATA;
|
||||
}
|
||||
|
||||
uint16_t CRC_Get16bitResult(CRC_Type *base)
|
||||
{
|
||||
uint32_t retval;
|
||||
uint32_t totr; /* type of transpose read bitfield */
|
||||
|
||||
retval = base->DATA;
|
||||
totr = (base->CTRL & CRC_CTRL_TOTR_MASK) >> CRC_CTRL_TOTR_SHIFT;
|
||||
|
||||
/* check transpose type to get 16-bit out of 32-bit register */
|
||||
if (totr >= 2U)
|
||||
{
|
||||
/* transpose of bytes for read is set, the result CRC is in CRC_DATA[HU:HL] */
|
||||
retval &= 0xFFFF0000U;
|
||||
retval = retval >> 16U;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no transpose of bytes for read, the result CRC is in CRC_DATA[LU:LL] */
|
||||
retval &= 0x0000FFFFU;
|
||||
}
|
||||
return (uint16_t)retval;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CRC_H_
|
||||
#define _FSL_CRC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup crc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief CRC driver version. Version 2.0.1.
|
||||
*
|
||||
* Current version: 2.0.1
|
||||
*
|
||||
* Change log:
|
||||
* - Version 2.0.1
|
||||
* - move DATA and DATALL macro definition from header file to source file
|
||||
*/
|
||||
#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
#ifndef CRC_DRIVER_CUSTOM_DEFAULTS
|
||||
/*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */
|
||||
#define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
/*! @brief CRC bit width */
|
||||
typedef enum _crc_bits
|
||||
{
|
||||
kCrcBits16 = 0U, /*!< Generate 16-bit CRC code */
|
||||
kCrcBits32 = 1U /*!< Generate 32-bit CRC code */
|
||||
} crc_bits_t;
|
||||
|
||||
/*! @brief CRC result type */
|
||||
typedef enum _crc_result
|
||||
{
|
||||
kCrcFinalChecksum = 0U, /*!< CRC data register read value is the final checksum.
|
||||
Reflect out and final xor protocol features are applied. */
|
||||
kCrcIntermediateChecksum = 1U /*!< CRC data register read value is intermediate checksum (raw value).
|
||||
Reflect out and final xor protocol feature are not applied.
|
||||
Intermediate checksum can be used as a seed for CRC_Init()
|
||||
to continue adding data to this checksum. */
|
||||
} crc_result_t;
|
||||
|
||||
/*!
|
||||
* @brief CRC protocol configuration.
|
||||
*
|
||||
* This structure holds the configuration for the CRC protocol.
|
||||
*
|
||||
*/
|
||||
typedef struct _crc_config
|
||||
{
|
||||
uint32_t polynomial; /*!< CRC Polynomial, MSBit first.
|
||||
Example polynomial: 0x1021 = 1_0000_0010_0001 = x^12+x^5+1 */
|
||||
uint32_t seed; /*!< Starting checksum value */
|
||||
bool reflectIn; /*!< Reflect bits on input. */
|
||||
bool reflectOut; /*!< Reflect bits on output. */
|
||||
bool complementChecksum; /*!< True if the result shall be complement of the actual checksum. */
|
||||
crc_bits_t crcBits; /*!< Selects 16- or 32- bit CRC protocol. */
|
||||
crc_result_t crcResult; /*!< Selects final or intermediate checksum return from CRC_Get16bitResult() or
|
||||
CRC_Get32bitResult() */
|
||||
} crc_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Enables and configures the CRC peripheral module.
|
||||
*
|
||||
* This function enables the clock gate in the SIM module for the CRC peripheral.
|
||||
* It also configures the CRC module and starts a checksum computation by writing the seed.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param config CRC module configuration structure.
|
||||
*/
|
||||
void CRC_Init(CRC_Type *base, const crc_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Disables the CRC peripheral module.
|
||||
*
|
||||
* This function disables the clock gate in the SIM module for the CRC peripheral.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
*/
|
||||
static inline void CRC_Deinit(CRC_Type *base)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* gate clock */
|
||||
CLOCK_DisableClock(kCLOCK_Crc0);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Loads default values to the CRC protocol configuration structure.
|
||||
*
|
||||
* Loads default values to the CRC protocol configuration structure. The default values are as follows.
|
||||
* @code
|
||||
* config->polynomial = 0x1021;
|
||||
* config->seed = 0xFFFF;
|
||||
* config->reflectIn = false;
|
||||
* config->reflectOut = false;
|
||||
* config->complementChecksum = false;
|
||||
* config->crcBits = kCrcBits16;
|
||||
* config->crcResult = kCrcFinalChecksum;
|
||||
* @endcode
|
||||
*
|
||||
* @param config CRC protocol configuration structure.
|
||||
*/
|
||||
void CRC_GetDefaultConfig(crc_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Writes data to the CRC module.
|
||||
*
|
||||
* Writes input data buffer bytes to the CRC data register.
|
||||
* The configured type of transpose is applied.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @param data Input data stream, MSByte in data[0].
|
||||
* @param dataSize Size in bytes of the input data buffer.
|
||||
*/
|
||||
void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize);
|
||||
|
||||
/*!
|
||||
* @brief Reads the 32-bit checksum from the CRC module.
|
||||
*
|
||||
* Reads the CRC data register (either an intermediate or the final checksum).
|
||||
* The configured type of transpose and complement is applied.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @return An intermediate or the final 32-bit checksum, after configured transpose and complement operations.
|
||||
*/
|
||||
uint32_t CRC_Get32bitResult(CRC_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Reads a 16-bit checksum from the CRC module.
|
||||
*
|
||||
* Reads the CRC data register (either an intermediate or the final checksum).
|
||||
* The configured type of transpose and complement is applied.
|
||||
*
|
||||
* @param base CRC peripheral address.
|
||||
* @return An intermediate or the final 16-bit checksum, after configured transpose and complement operations.
|
||||
*/
|
||||
uint16_t CRC_Get16bitResult(CRC_Type *base);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
*@}
|
||||
*/
|
||||
|
||||
#endif /* _FSL_CRC_H_ */
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_dac.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get instance number for DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address
|
||||
*/
|
||||
static uint32_t DAC_GetInstance(LPDAC_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to DAC bases for each instance. */
|
||||
static LPDAC_Type *const s_dacBases[] = LPDAC_BASE_PTRS;
|
||||
|
||||
/*! @brief Pointers to DAC clocks for each instance. */
|
||||
static const clock_ip_name_t s_dacClocks[] = LPDAC_CLOCKS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t DAC_GetInstance(LPDAC_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_dacBases); instance++)
|
||||
{
|
||||
if (s_dacBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_dacBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DAC_Init(LPDAC_Type *base, const dac_config_t *config)
|
||||
{
|
||||
assert(NULL != config);
|
||||
|
||||
uint32_t tmp32 = 0U;
|
||||
|
||||
/* Enable the clock. */
|
||||
CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
|
||||
|
||||
/* Reset the logic. */
|
||||
DAC_SetReset(base, kDAC_ResetLogic);
|
||||
DAC_ClearReset(base, kDAC_ResetLogic);
|
||||
|
||||
/* Reset the FIFO. */
|
||||
DAC_SetReset(base, kDAC_ResetFIFO);
|
||||
DAC_ClearReset(base, kDAC_ResetFIFO);
|
||||
|
||||
/* Configuration. */
|
||||
if (kDAC_FIFOTriggerBySoftwareMode == config->fifoTriggerMode)
|
||||
{
|
||||
tmp32 |= LPDAC_GCR_TRGSEL_MASK; /* Software trigger. */
|
||||
}
|
||||
switch (config->fifoWorkMode)
|
||||
{
|
||||
case kDAC_FIFOWorkAsNormalMode: /* Normal FIFO. */
|
||||
tmp32 |= LPDAC_GCR_FIFOEN_MASK;
|
||||
break;
|
||||
case kDAC_FIFOWorkAsSwingMode:
|
||||
tmp32 |= LPDAC_GCR_FIFOEN_MASK | LPDAC_GCR_SWMD_MASK; /* Enable swing mode. */
|
||||
break;
|
||||
default: /* kDAC_FIFODisabled. */
|
||||
break;
|
||||
}
|
||||
if (config->enableLowPowerMode)
|
||||
{
|
||||
tmp32 |= LPDAC_GCR_LPEN_MASK; /* Enable low power. */
|
||||
}
|
||||
if (kDAC_ReferenceVoltageSourceAlt2 == config->referenceVoltageSource)
|
||||
{
|
||||
tmp32 |= LPDAC_GCR_DACRFS_MASK;
|
||||
}
|
||||
base->GCR = tmp32;
|
||||
base->FCR = LPDAC_FCR_WML(config->fifoWatermarkLevel);
|
||||
|
||||
/* Now, the DAC is disabled. It needs to be enabled in application. */
|
||||
}
|
||||
|
||||
void DAC_GetDefaultConfig(dac_config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
|
||||
config->fifoWatermarkLevel = 0U;
|
||||
config->fifoTriggerMode = kDAC_FIFOTriggerByHardwareMode;
|
||||
config->fifoWorkMode = kDAC_FIFODisabled;
|
||||
config->enableLowPowerMode = false;
|
||||
config->referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1;
|
||||
}
|
||||
|
||||
void DAC_Deinit(LPDAC_Type *base)
|
||||
{
|
||||
/* Disable the module. */
|
||||
DAC_Enable(base, false);
|
||||
|
||||
/* Disable the clock. */
|
||||
CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_DAC_H_
|
||||
#define _FSL_DAC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup dac
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @file */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief DAC driver version 2.0.0. */
|
||||
#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief DAC reset control.
|
||||
*/
|
||||
enum _dac_reset_control
|
||||
{
|
||||
kDAC_ResetFIFO = LPDAC_RCR_FIFORST_MASK, /*!< Resets the FIFO pointers and flags. */
|
||||
kDAC_ResetLogic = LPDAC_RCR_SWRST_MASK, /*!< Resets all DAC registers and internal logic. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief DAC interrupts.
|
||||
*/
|
||||
enum _dac_interrupt_enable
|
||||
{
|
||||
kDAC_FIFOFullInterruptEnable = LPDAC_IER_FULL_IE_MASK, /*!< FIFO full interrupt enable. */
|
||||
kDAC_FIFOEmptyInterruptEnable = LPDAC_IER_EMPTY_IE_MASK, /*!< FIFO empty interrupt enable. */
|
||||
kDAC_FIFOWatermarkInterruptEnable = LPDAC_IER_WM_IE_MASK, /*!< FIFO watermark interrupt enable. */
|
||||
kDAC_SwingBackInterruptEnable = LPDAC_IER_SWBK_IE_MASK, /*!< Swing back one cycle complete interrupt enable. */
|
||||
kDAC_FIFOOverflowInterruptEnable = LPDAC_IER_OF_IE_MASK, /*!< FIFO overflow interrupt enable. */
|
||||
kDAC_FIFOUnderflowInterruptEnable = LPDAC_IER_UF_IE_MASK, /*!< FIFO underflow interrupt enable. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief DAC DMA switchers.
|
||||
*/
|
||||
enum _dac_dma_enable
|
||||
{
|
||||
kDAC_FIFOEmptyDMAEnable = LPDAC_DER_EMPTY_DMAEN_MASK, /*!< FIFO empty DMA enable. */
|
||||
kDAC_FIFOWatermarkDMAEnable = LPDAC_DER_WM_DMAEN_MASK, /*!< FIFO watermark DMA enable. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief DAC status flags.
|
||||
*/
|
||||
enum _dac_status_flags
|
||||
{
|
||||
kDAC_FIFOUnderflowFlag = LPDAC_FSR_UF_MASK, /*!< This flag means that there is a new trigger after the buffer is
|
||||
empty. The FIFO read pointer will not
|
||||
increase in this case and the data sent to DAC analog conversion will not changed. This flag is cleared by writing a 1
|
||||
to it. */
|
||||
|
||||
kDAC_FIFOOverflowFlag = LPDAC_FSR_OF_MASK, /*!< This flag indicates that data is intended to write into FIFO after the
|
||||
buffer is full. The writer pointer will
|
||||
not increase in this case. The extra data will not be written into the FIFO. This flag is cleared by writing a 1 to it.
|
||||
*/
|
||||
|
||||
kDAC_FIFOSwingBackFlag = LPDAC_FSR_SWBK_MASK, /*!< This flag indicates that the DAC has completed one period of
|
||||
conversion in swing back mode. It means
|
||||
that the read pointer has increased to the top (write pointer) once and then decreased to zero once. For
|
||||
example, after three data is written to FIFO, the writer pointer is now 3. Then, if continually triggered, the
|
||||
read pointer will swing like: 0-1-2-1-0-1-2-, and so on. After the fourth trigger, the flag is set. This flag is
|
||||
cleared by writing a 1 to it. */
|
||||
|
||||
kDAC_FIFOWatermarkFlag = LPDAC_FSR_WM_MASK, /*!< This field is set if the remaining data in FIFO is less than or equal
|
||||
to the setting value of wartermark. By writing data into
|
||||
FIFO by DMA or CPU, this flag is cleared automatically when the data in FIFO is more than the setting value of
|
||||
watermark. */
|
||||
|
||||
kDAC_FIFOEmptyFlag = LPDAC_FSR_EMPTY_MASK, /*!< FIFO empty flag. */
|
||||
kDAC_FIFOFullFlag = LPDAC_FSR_FULL_MASK, /*!< FIFO full flag. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief DAC FIFO trigger mode.
|
||||
*/
|
||||
typedef enum _dac_fifo_trigger_mode
|
||||
{
|
||||
kDAC_FIFOTriggerByHardwareMode = 0U, /*!< Buffer would be triggered by hardware. */
|
||||
kDAC_FIFOTriggerBySoftwareMode = 1U, /*!< Buffer would be triggered by software. */
|
||||
} dac_fifo_trigger_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief DAC FIFO work mode.
|
||||
*/
|
||||
typedef enum _dac_fifo_work_mode
|
||||
{
|
||||
kDAC_FIFODisabled = 0U, /*!< FIFO mode is disabled and buffer mode is enabled. Any data written to DATA[DATA] goes
|
||||
to buffer then goes to conversion. */
|
||||
kDAC_FIFOWorkAsNormalMode = 1U, /*!< FIFO mode is enabled. Data will be first read from FIFO to buffer then goes to
|
||||
conversion. */
|
||||
kDAC_FIFOWorkAsSwingMode = 2U, /*!< In swing mode, the read pointer swings between the writer pointer and zero. That
|
||||
is, the trigger increases the read pointer till reach the writer pointer and
|
||||
decreases the read pointer till zero, and so on. The FIFO empty/full/watermark
|
||||
flag will not update during swing back mode. */
|
||||
} dac_fifo_work_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief DAC reference voltage source.
|
||||
*/
|
||||
typedef enum _dac_reference_voltage_source
|
||||
{
|
||||
kDAC_ReferenceVoltageSourceAlt1 = 0U, /*!< The DAC selects VREFH_INT as the reference voltage. */
|
||||
kDAC_ReferenceVoltageSourceAlt2 = 1U, /*!< The DAC selects VREFH_EXT as the reference voltage. */
|
||||
} dac_reference_voltage_source_t;
|
||||
|
||||
/*!
|
||||
* @brief DAC configuration structure.
|
||||
*/
|
||||
typedef struct _dac_config
|
||||
{
|
||||
uint32_t fifoWatermarkLevel; /*!< FIFO's watermark, the max value can be the hardware FIFO size. */
|
||||
dac_fifo_trigger_mode_t fifoTriggerMode; /*!< Select the trigger mode for FIFO. */
|
||||
dac_fifo_work_mode_t fifoWorkMode; /*!< Select the work mode for FIFO. */
|
||||
bool enableLowPowerMode; /*!< Enable the low power mode. */
|
||||
dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */
|
||||
} dac_config_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Initialization and de-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initialize the DAC module with common configuartion.
|
||||
*
|
||||
* The clock will be enabled in this function.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param config Pointer to configuration structure.
|
||||
*/
|
||||
void DAC_Init(LPDAC_Type *base, const dac_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Get the default settings for initialization's configuration.
|
||||
*
|
||||
* This function initializes the user configuration structure to a default value. The default values are:
|
||||
* @code
|
||||
* config->fifoWatermarkLevel = 0U;
|
||||
* config->fifoTriggerMode = kDAC_FIFOTriggerByHardwareMode;
|
||||
* config->fifoWorkMode = kDAC_FIFODisabled;
|
||||
* config->enableLowPowerMode = false;
|
||||
* config->referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1;
|
||||
* @endcode
|
||||
*
|
||||
* @param config Pointer to configuration structure.
|
||||
* @param
|
||||
*/
|
||||
void DAC_GetDefaultConfig(dac_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initialize the DAC module.
|
||||
*
|
||||
* The clock will be disabled in this function.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param
|
||||
*/
|
||||
void DAC_Deinit(LPDAC_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Assert the reset control to part hardware.
|
||||
*
|
||||
* This fucntion is to assert the reset control to part hardware. Responding part hardware would remain reset untill
|
||||
* cleared by software.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask The reset control mask, see to #_dac_reset_control_t.
|
||||
*/
|
||||
static inline void DAC_SetReset(LPDAC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->RCR |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clear the reset control to part hardware.
|
||||
*
|
||||
* This fucntion is to clear the reset control to part hardware. Responding part hardware would work after the reset
|
||||
* control is cleared by software.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask The reset control mask, see to #_dac_reset_control_t.
|
||||
*/
|
||||
static inline void DAC_ClearReset(LPDAC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->RCR &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enable the DAC hardware system or not.
|
||||
*
|
||||
* This function is to start the Programmable Reference Generator operation or not.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param enable Assertion of indicated event.
|
||||
*/
|
||||
static inline void DAC_Enable(LPDAC_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->GCR |= LPDAC_GCR_DACEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->GCR &= ~LPDAC_GCR_DACEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enable the interrupts.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask Mask value of indicated interrupt events. See to #_dac_interrupt_enable.
|
||||
*/
|
||||
static inline void DAC_EnableInterrupts(LPDAC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IER |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the interrupts.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask Mask value of indicated interrupt events. See to #_dac_interrupt_enable.
|
||||
*/
|
||||
static inline void DAC_DisableInterrupts(LPDAC_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IER &= ~mask;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name DMA control
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enable the DMA switchers or not.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param mask Mask value of indicated DMA requeset. See to #_dac_dma_enable.
|
||||
* @param enable Enable the DMA or not.
|
||||
*/
|
||||
static inline void DAC_EnableDMA(LPDAC_Type *base, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->DER |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->DER &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Status flags
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Get status flags of DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @return Mask value of status flags. See to #_dac_status_flags.
|
||||
*/
|
||||
static inline uint32_t DAC_GetStatusFlags(LPDAC_Type *base)
|
||||
{
|
||||
return base->FSR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clear status flags of DAC module.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param flags Mask value of status flags to be cleared. See to #_dac_status_flags.
|
||||
*/
|
||||
static inline void DAC_ClearStatusFlags(LPDAC_Type *base, uint32_t flags)
|
||||
{
|
||||
base->FSR = flags;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Functional feature
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Set data into the entry of FIFO buffer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @param value Setting value into FIFO buffer.
|
||||
*/
|
||||
static inline void DAC_SetData(LPDAC_Type *base, uint32_t value)
|
||||
{
|
||||
base->DATA = LPDAC_DATA_DATA(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the value of the FIFO write pointer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @return Current value of the FIFO write pointer.
|
||||
*/
|
||||
|
||||
static inline uint32_t DAC_GetFIFOWritePointer(LPDAC_Type *base)
|
||||
{
|
||||
return (LPDAC_FPR_FIFO_WPT_MASK & base->FPR) >> LPDAC_FPR_FIFO_WPT_SHIFT;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the value of the FIFO read pointer.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
* @return Current value of the FIFO read pointer.
|
||||
*/
|
||||
|
||||
static inline uint32_t DAC_GetFIFOReadPointer(LPDAC_Type *base)
|
||||
{
|
||||
return (LPDAC_FPR_FIFO_RPT_MASK & base->FPR) >> LPDAC_FPR_FIFO_RPT_SHIFT;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Do software trigger to FIFO when in software mode.
|
||||
*
|
||||
* @param base DAC peripheral base address.
|
||||
*/
|
||||
|
||||
static inline void DAC_DoSoftwareTriggerFIFO(LPDAC_Type *base)
|
||||
{
|
||||
base->TCR = LPDAC_TCR_SWTRG_MASK;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif /* _FSL_DAC12_H_ */
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_dmamux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get instance number for DMAMUX.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
*/
|
||||
static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Array to map DMAMUX instance number to base pointer. */
|
||||
static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Array to map DMAMUX instance number to clock name. */
|
||||
static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++)
|
||||
{
|
||||
if (s_dmamuxBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_dmamuxBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DMAMUX_Init(DMAMUX_Type *base)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
|
||||
void DMAMUX_Deinit(DMAMUX_Type *base)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_DMAMUX_H_
|
||||
#define _FSL_DMAMUX_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup dmamux
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief DMAMUX driver version 2.0.2. */
|
||||
#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
|
||||
/*@}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name DMAMUX Initialization and de-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the DMAMUX peripheral.
|
||||
*
|
||||
* This function ungates the DMAMUX clock.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
*
|
||||
*/
|
||||
void DMAMUX_Init(DMAMUX_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the DMAMUX peripheral.
|
||||
*
|
||||
* This function gates the DMAMUX clock.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
*/
|
||||
void DMAMUX_Deinit(DMAMUX_Type *base);
|
||||
|
||||
/* @} */
|
||||
/*!
|
||||
* @name DMAMUX Channel Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the DMAMUX channel.
|
||||
*
|
||||
* This function enables the DMAMUX channel.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the DMAMUX channel.
|
||||
*
|
||||
* This function disables the DMAMUX channel.
|
||||
*
|
||||
* @note The user must disable the DMAMUX channel before configuring it.
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configures the DMAMUX channel source.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
* @param source Channel source, which is used to trigger the DMA transfer.
|
||||
*/
|
||||
static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] = ((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source));
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U
|
||||
/*!
|
||||
* @brief Enables the DMAMUX period trigger.
|
||||
*
|
||||
* This function enables the DMAMUX period trigger feature.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the DMAMUX period trigger.
|
||||
*
|
||||
* This function disables the DMAMUX period trigger.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
*/
|
||||
static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
base->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */
|
||||
|
||||
#if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON)
|
||||
/*!
|
||||
* @brief Enables the DMA channel to be always ON.
|
||||
*
|
||||
* This function enables the DMAMUX channel always ON feature.
|
||||
*
|
||||
* @param base DMAMUX peripheral base address.
|
||||
* @param channel DMAMUX channel number.
|
||||
* @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled.
|
||||
*/
|
||||
static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* @} */
|
||||
|
||||
#endif /* _FSL_DMAMUX_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_ewm.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void EWM_Init(EWM_Type *base, const ewm_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint32_t value = 0U;
|
||||
|
||||
#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \
|
||||
(defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE))
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
CLOCK_EnableClock(kCLOCK_Ewm0);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
#endif
|
||||
value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) |
|
||||
EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt);
|
||||
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
|
||||
base->CLKPRESCALER = config->prescaler;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
|
||||
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
base->CLKCTRL = config->clockSource;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
|
||||
|
||||
base->CMPL = config->compareLowValue;
|
||||
base->CMPH = config->compareHighValue;
|
||||
base->CTRL = value;
|
||||
}
|
||||
|
||||
void EWM_Deinit(EWM_Type *base)
|
||||
{
|
||||
EWM_DisableInterrupts(base, kEWM_InterruptEnable);
|
||||
#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \
|
||||
(defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE))
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
CLOCK_DisableClock(kCLOCK_Ewm0);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
#endif /* FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE */
|
||||
}
|
||||
|
||||
void EWM_GetDefaultConfig(ewm_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
config->enableEwm = true;
|
||||
config->enableEwmInput = false;
|
||||
config->setInputAssertLogic = false;
|
||||
config->enableInterrupt = false;
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
config->clockSource = kEWM_LpoClockSource0;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
|
||||
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
|
||||
config->prescaler = 0U;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
|
||||
config->compareLowValue = 0U;
|
||||
config->compareHighValue = 0xFEU;
|
||||
}
|
||||
|
||||
void EWM_Refresh(EWM_Type *base)
|
||||
{
|
||||
uint32_t primaskValue = 0U;
|
||||
|
||||
/* Disable the global interrupt to protect refresh sequence */
|
||||
primaskValue = DisableGlobalIRQ();
|
||||
base->SERV = (uint8_t)0xB4U;
|
||||
base->SERV = (uint8_t)0x2CU;
|
||||
EnableGlobalIRQ(primaskValue);
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_EWM_H_
|
||||
#define _FSL_EWM_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup ewm
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief EWM driver version 2.0.1. */
|
||||
#define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief Describes EWM clock source. */
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
typedef enum _ewm_lpo_clock_source
|
||||
{
|
||||
kEWM_LpoClockSource0 = 0U, /*!< EWM clock sourced from lpo_clk[0]*/
|
||||
kEWM_LpoClockSource1 = 1U, /*!< EWM clock sourced from lpo_clk[1]*/
|
||||
kEWM_LpoClockSource2 = 2U, /*!< EWM clock sourced from lpo_clk[2]*/
|
||||
kEWM_LpoClockSource3 = 3U, /*!< EWM clock sourced from lpo_clk[3]*/
|
||||
} ewm_lpo_clock_source_t;
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
|
||||
|
||||
/*!
|
||||
* @brief Data structure for EWM configuration.
|
||||
*
|
||||
* This structure is used to configure the EWM.
|
||||
*/
|
||||
typedef struct _ewm_config
|
||||
{
|
||||
bool enableEwm; /*!< Enable EWM module */
|
||||
bool enableEwmInput; /*!< Enable EWM_in input */
|
||||
bool setInputAssertLogic; /*!< EWM_in signal assertion state */
|
||||
bool enableInterrupt; /*!< Enable EWM interrupt */
|
||||
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
|
||||
ewm_lpo_clock_source_t clockSource; /*!< Clock source select */
|
||||
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
|
||||
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
|
||||
uint8_t prescaler; /*!< Clock prescaler value */
|
||||
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
|
||||
uint8_t compareLowValue; /*!< Compare low-register value */
|
||||
uint8_t compareHighValue; /*!< Compare high-register value */
|
||||
} ewm_config_t;
|
||||
|
||||
/*!
|
||||
* @brief EWM interrupt configuration structure with default settings all disabled.
|
||||
*
|
||||
* This structure contains the settings for all of EWM interrupt configurations.
|
||||
*/
|
||||
enum _ewm_interrupt_enable_t
|
||||
{
|
||||
kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable the EWM to generate an interrupt*/
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief EWM status flags.
|
||||
*
|
||||
* This structure contains the constants for the EWM status flags for use in the EWM functions.
|
||||
*/
|
||||
enum _ewm_status_flags_t
|
||||
{
|
||||
kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when EWM is enabled*/
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
*******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*!
|
||||
* @name EWM initialization and de-initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the EWM peripheral.
|
||||
*
|
||||
* This function is used to initialize the EWM. After calling, the EWM
|
||||
* runs immediately according to the configuration.
|
||||
* Note that, except for the interrupt enable control bit, other control bits and registers are write once after a
|
||||
* CPU reset. Modifying them more than once generates a bus transfer error.
|
||||
*
|
||||
* This is an example.
|
||||
* @code
|
||||
* ewm_config_t config;
|
||||
* EWM_GetDefaultConfig(&config);
|
||||
* config.compareHighValue = 0xAAU;
|
||||
* EWM_Init(ewm_base,&config);
|
||||
* @endcode
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
* @param config The configuration of the EWM
|
||||
*/
|
||||
void EWM_Init(EWM_Type *base, const ewm_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the EWM peripheral.
|
||||
*
|
||||
* This function is used to shut down the EWM.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
*/
|
||||
void EWM_Deinit(EWM_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the EWM configuration structure.
|
||||
*
|
||||
* This function initializes the EWM configuration structure to default values. The default
|
||||
* values are as follows.
|
||||
* @code
|
||||
* ewmConfig->enableEwm = true;
|
||||
* ewmConfig->enableEwmInput = false;
|
||||
* ewmConfig->setInputAssertLogic = false;
|
||||
* ewmConfig->enableInterrupt = false;
|
||||
* ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0;
|
||||
* ewmConfig->prescaler = 0;
|
||||
* ewmConfig->compareLowValue = 0;
|
||||
* ewmConfig->compareHighValue = 0xFEU;
|
||||
* @endcode
|
||||
*
|
||||
* @param config Pointer to the EWM configuration structure.
|
||||
* @see ewm_config_t
|
||||
*/
|
||||
void EWM_GetDefaultConfig(ewm_config_t *config);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name EWM functional Operation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the EWM interrupt.
|
||||
*
|
||||
* This function enables the EWM interrupt.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
* @param mask The interrupts to enable
|
||||
* The parameter can be combination of the following source if defined
|
||||
* @arg kEWM_InterruptEnable
|
||||
*/
|
||||
static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables the EWM interrupt.
|
||||
*
|
||||
* This function enables the EWM interrupt.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
* @param mask The interrupts to disable
|
||||
* The parameter can be combination of the following source if defined
|
||||
* @arg kEWM_InterruptEnable
|
||||
*/
|
||||
static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CTRL &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets all status flags.
|
||||
*
|
||||
* This function gets all status flags.
|
||||
*
|
||||
* This is an example for getting the running flag.
|
||||
* @code
|
||||
* uint32_t status;
|
||||
* status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag;
|
||||
* @endcode
|
||||
* @param base EWM peripheral base address
|
||||
* @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t
|
||||
* - True: a related status flag has been set.
|
||||
* - False: a related status flag is not set.
|
||||
*/
|
||||
static inline uint32_t EWM_GetStatusFlags(EWM_Type *base)
|
||||
{
|
||||
return (base->CTRL & EWM_CTRL_EWMEN_MASK);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Services the EWM.
|
||||
*
|
||||
* This function resets the EWM counter to zero.
|
||||
*
|
||||
* @param base EWM peripheral base address
|
||||
*/
|
||||
void EWM_Refresh(EWM_Type *base);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_EWM_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_flexio.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*< @brief user configurable flexio handle count. */
|
||||
#define FLEXIO_HANDLE_COUNT 2
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*< @brief pointer to array of FLEXIO handle. */
|
||||
static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
|
||||
|
||||
/*< @brief pointer to array of FLEXIO IP types. */
|
||||
static void *s_flexioType[FLEXIO_HANDLE_COUNT];
|
||||
|
||||
/*< @brief pointer to array of FLEXIO Isr. */
|
||||
static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Pointers to flexio clocks for each instance. */
|
||||
const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*! @brief Pointers to flexio bases for each instance. */
|
||||
FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t FLEXIO_GetInstance(FLEXIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++)
|
||||
{
|
||||
if (s_flexioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_flexioBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
|
||||
{
|
||||
uint32_t ctrlReg = 0;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
FLEXIO_Reset(base);
|
||||
|
||||
ctrlReg = base->CTRL;
|
||||
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
|
||||
ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
|
||||
FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
|
||||
if (!userConfig->enableInDoze)
|
||||
{
|
||||
ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
|
||||
}
|
||||
|
||||
base->CTRL = ctrlReg;
|
||||
}
|
||||
|
||||
void FLEXIO_Deinit(FLEXIO_Type *base)
|
||||
{
|
||||
FLEXIO_Enable(base, false);
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
|
||||
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
|
||||
{
|
||||
assert(userConfig);
|
||||
|
||||
userConfig->enableFlexio = true;
|
||||
userConfig->enableInDoze = false;
|
||||
userConfig->enableInDebug = true;
|
||||
userConfig->enableFastAccess = false;
|
||||
}
|
||||
|
||||
void FLEXIO_Reset(FLEXIO_Type *base)
|
||||
{
|
||||
/*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
|
||||
base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
|
||||
base->CTRL = 0;
|
||||
}
|
||||
|
||||
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
|
||||
{
|
||||
assert(index < FLEXIO_SHIFTBUF_COUNT);
|
||||
|
||||
uint32_t address = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kFLEXIO_ShifterBuffer:
|
||||
address = (uint32_t) & (base->SHIFTBUF[index]);
|
||||
break;
|
||||
|
||||
case kFLEXIO_ShifterBufferBitSwapped:
|
||||
address = (uint32_t) & (base->SHIFTBUFBIS[index]);
|
||||
break;
|
||||
|
||||
case kFLEXIO_ShifterBufferByteSwapped:
|
||||
address = (uint32_t) & (base->SHIFTBUFBYS[index]);
|
||||
break;
|
||||
|
||||
case kFLEXIO_ShifterBufferBitByteSwapped:
|
||||
address = (uint32_t) & (base->SHIFTBUFBBS[index]);
|
||||
break;
|
||||
|
||||
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
|
||||
case kFLEXIO_ShifterBufferNibbleByteSwapped:
|
||||
address = (uint32_t) & (base->SHIFTBUFNBS[index]);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
|
||||
case kFLEXIO_ShifterBufferHalfWordSwapped:
|
||||
address = (uint32_t) & (base->SHIFTBUFHWS[index]);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
|
||||
case kFLEXIO_ShifterBufferNibbleSwapped:
|
||||
address = (uint32_t) & (base->SHIFTBUFNIS[index]);
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
|
||||
{
|
||||
base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
|
||||
#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
|
||||
| FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
|
||||
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
|
||||
| FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
|
||||
FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
|
||||
|
||||
base->SHIFTCTL[index] =
|
||||
FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
|
||||
FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
|
||||
FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
|
||||
}
|
||||
|
||||
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
|
||||
{
|
||||
base->TIMCFG[index] =
|
||||
FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
|
||||
FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
|
||||
FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
|
||||
FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
|
||||
|
||||
base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
|
||||
|
||||
base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
|
||||
FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
|
||||
FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
|
||||
FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
|
||||
FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
|
||||
}
|
||||
|
||||
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
|
||||
{
|
||||
assert(base);
|
||||
assert(handle);
|
||||
assert(isr);
|
||||
|
||||
uint8_t index = 0;
|
||||
|
||||
/* Find the an empty handle pointer to store the handle. */
|
||||
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
|
||||
{
|
||||
if (s_flexioHandle[index] == NULL)
|
||||
{
|
||||
/* Register FLEXIO simulated driver base, handle and isr. */
|
||||
s_flexioType[index] = base;
|
||||
s_flexioHandle[index] = handle;
|
||||
s_flexioIsr[index] = isr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == FLEXIO_HANDLE_COUNT)
|
||||
{
|
||||
return kStatus_OutOfRange;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kStatus_Success;
|
||||
}
|
||||
}
|
||||
|
||||
status_t FLEXIO_UnregisterHandleIRQ(void *base)
|
||||
{
|
||||
assert(base);
|
||||
|
||||
uint8_t index = 0;
|
||||
|
||||
/* Find the index from base address mappings. */
|
||||
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
|
||||
{
|
||||
if (s_flexioType[index] == base)
|
||||
{
|
||||
/* Unregister FLEXIO simulated driver handle and isr. */
|
||||
s_flexioType[index] = NULL;
|
||||
s_flexioHandle[index] = NULL;
|
||||
s_flexioIsr[index] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == FLEXIO_HANDLE_COUNT)
|
||||
{
|
||||
return kStatus_OutOfRange;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kStatus_Success;
|
||||
}
|
||||
}
|
||||
|
||||
void FLEXIO_CommonIRQHandler(void)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
|
||||
{
|
||||
if (s_flexioHandle[index])
|
||||
{
|
||||
s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLEXIO_DriverIRQHandler(void)
|
||||
{
|
||||
FLEXIO_CommonIRQHandler();
|
||||
}
|
||||
|
||||
void FLEXIO0_DriverIRQHandler(void)
|
||||
{
|
||||
FLEXIO_CommonIRQHandler();
|
||||
}
|
||||
|
||||
void FLEXIO1_DriverIRQHandler(void)
|
||||
{
|
||||
FLEXIO_CommonIRQHandler();
|
||||
}
|
||||
|
||||
void UART2_FLEXIO_DriverIRQHandler(void)
|
||||
{
|
||||
FLEXIO_CommonIRQHandler();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_FLEXIO_I2C_MASTER_H_
|
||||
#define _FSL_FLEXIO_I2C_MASTER_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_flexio.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup flexio_i2c_master
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief FlexIO I2C master driver version 2.1.2. */
|
||||
#define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief FlexIO I2C transfer status*/
|
||||
enum _flexio_i2c_status
|
||||
{
|
||||
kStatus_FLEXIO_I2C_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */
|
||||
kStatus_FLEXIO_I2C_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */
|
||||
kStatus_FLEXIO_I2C_Nak = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */
|
||||
};
|
||||
|
||||
/*! @brief Define FlexIO I2C master interrupt mask. */
|
||||
enum _flexio_i2c_master_interrupt
|
||||
{
|
||||
kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */
|
||||
kFLEXIO_I2C_RxFullInterruptEnable = 0x2U, /*!< Rx buffer full interrupt enable. */
|
||||
};
|
||||
|
||||
/*! @brief Define FlexIO I2C master status mask. */
|
||||
enum _flexio_i2c_master_status_flags
|
||||
{
|
||||
kFLEXIO_I2C_TxEmptyFlag = 0x1U, /*!< Tx shifter empty flag. */
|
||||
kFLEXIO_I2C_RxFullFlag = 0x2U, /*!< Rx shifter full/Transfer complete flag. */
|
||||
kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */
|
||||
};
|
||||
|
||||
/*! @brief Direction of master transfer.*/
|
||||
typedef enum _flexio_i2c_direction
|
||||
{
|
||||
kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */
|
||||
kFLEXIO_I2C_Read = 0x1U, /*!< Master receive from slave. */
|
||||
} flexio_i2c_direction_t;
|
||||
|
||||
/*! @brief Define FlexIO I2C master access structure typedef. */
|
||||
typedef struct _flexio_i2c_type
|
||||
{
|
||||
FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
|
||||
uint8_t SDAPinIndex; /*!< Pin select for I2C SDA. */
|
||||
uint8_t SCLPinIndex; /*!< Pin select for I2C SCL. */
|
||||
uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */
|
||||
uint8_t timerIndex[2]; /*!< Timer index used in FlexIO I2C. */
|
||||
} FLEXIO_I2C_Type;
|
||||
|
||||
/*! @brief Define FlexIO I2C master user configuration structure. */
|
||||
typedef struct _flexio_i2c_master_config
|
||||
{
|
||||
bool enableMaster; /*!< Enables the FlexIO I2C peripheral at initialization time. */
|
||||
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */
|
||||
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */
|
||||
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
|
||||
the FlexIO clock to be at least twice the frequency of the bus clock. */
|
||||
uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
|
||||
} flexio_i2c_master_config_t;
|
||||
|
||||
/*! @brief Define FlexIO I2C master transfer structure. */
|
||||
typedef struct _flexio_i2c_master_transfer
|
||||
{
|
||||
uint32_t flags; /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */
|
||||
uint8_t slaveAddress; /*!< 7-bit slave address. */
|
||||
flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */
|
||||
uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
|
||||
uint8_t subaddressSize; /*!< Size of command buffer. */
|
||||
uint8_t volatile *data; /*!< Transfer buffer. */
|
||||
volatile size_t dataSize; /*!< Transfer size. */
|
||||
} flexio_i2c_master_transfer_t;
|
||||
|
||||
/*! @brief FlexIO I2C master handle typedef. */
|
||||
typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t;
|
||||
|
||||
/*! @brief FlexIO I2C master transfer callback typedef. */
|
||||
typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base,
|
||||
flexio_i2c_master_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief Define FlexIO I2C master handle structure. */
|
||||
struct _flexio_i2c_master_handle
|
||||
{
|
||||
flexio_i2c_master_transfer_t transfer; /*!< FlexIO I2C master transfer copy. */
|
||||
size_t transferSize; /*!< Total bytes to be transferred. */
|
||||
uint8_t state; /*!< Transfer state maintained during transfer. */
|
||||
flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */
|
||||
/*!< Callback function called at transfer event. */
|
||||
void *userData; /*!< Callback parameter passed to callback function. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /*_cplusplus*/
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
|
||||
* hardware configuration.
|
||||
*
|
||||
* Example
|
||||
@code
|
||||
FLEXIO_I2C_Type base = {
|
||||
.flexioBase = FLEXIO,
|
||||
.SDAPinIndex = 0,
|
||||
.SCLPinIndex = 1,
|
||||
.shifterIndex = {0,1},
|
||||
.timerIndex = {0,1}
|
||||
};
|
||||
flexio_i2c_master_config_t config = {
|
||||
.enableInDoze = false,
|
||||
.enableInDebug = true,
|
||||
.enableFastAccess = false,
|
||||
.baudRate_Bps = 100000
|
||||
};
|
||||
FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
|
||||
@endcode
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param masterConfig Pointer to flexio_i2c_master_config_t structure.
|
||||
* @param srcClock_Hz FlexIO source clock in Hz.
|
||||
* @retval kStatus_Success Initialization successful
|
||||
* @retval kStatus_InvalidArgument The source clock exceed upper range limitation
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the FlexIO I2C master peripheral. Calling this API gates the FlexIO clock
|
||||
* and the FlexIO I2C master module can't work unless the FLEXIO_I2C_MasterInit is called.
|
||||
*
|
||||
* @param base pointer to FLEXIO_I2C_Type structure.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets the default configuration to configure the FlexIO module. The configuration
|
||||
* can be used directly for calling the FLEXIO_I2C_MasterInit().
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
flexio_i2c_master_config_t config;
|
||||
FLEXIO_I2C_MasterGetDefaultConfig(&config);
|
||||
@endcode
|
||||
* @param masterConfig Pointer to flexio_i2c_master_config_t structure.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables the FlexIO module operation.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param enable Pass true to enable module, false to disable module.
|
||||
*/
|
||||
static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Status
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Gets the FlexIO I2C master status flags.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure
|
||||
* @return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
|
||||
*/
|
||||
|
||||
uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the FlexIO I2C master status flags.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param mask Status flag.
|
||||
* The parameter can be any combination of the following values:
|
||||
* @arg kFLEXIO_I2C_RxFullFlag
|
||||
* @arg kFLEXIO_I2C_ReceiveNakFlag
|
||||
*/
|
||||
|
||||
void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables the FlexIO i2c master interrupt requests.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param mask Interrupt source.
|
||||
* Currently only one interrupt request source:
|
||||
* @arg kFLEXIO_I2C_TransferCompleteInterruptEnable
|
||||
*/
|
||||
void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
|
||||
|
||||
/*!
|
||||
* @brief Disables the FlexIO I2C master interrupt requests.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param mask Interrupt source.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Bus Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the FlexIO I2C master transfer baudrate.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure
|
||||
* @param baudRate_Bps the baud rate value in HZ
|
||||
* @param srcClock_Hz source clock in HZ
|
||||
*/
|
||||
void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief Sends START + 7-bit address to the bus.
|
||||
*
|
||||
* @note This API should be called when the transfer configuration is ready to send a START signal
|
||||
* and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
|
||||
* is put into the data register but the address transfer is not finished on the bus. Ensure that
|
||||
* the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param address 7-bit address.
|
||||
* @param direction transfer direction.
|
||||
* This parameter is one of the values in flexio_i2c_direction_t:
|
||||
* @arg kFLEXIO_I2C_Write: Transmit
|
||||
* @arg kFLEXIO_I2C_Read: Receive
|
||||
*/
|
||||
|
||||
void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction);
|
||||
|
||||
/*!
|
||||
* @brief Sends the stop signal on the bus.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Sends the repeated start signal on the bus.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Sends the stop signal when transfer is still on-going.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Configures the sent ACK/NAK for the following byte.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param enable True to configure send ACK, false configure to send NAK.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief Sets the number of bytes to be transferred from a start signal to a stop signal.
|
||||
*
|
||||
* @note Call this API before a transfer begins because the timer generates a number of clocks according
|
||||
* to the number of bytes that need to be transferred.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
|
||||
* @retval kStatus_Success Successfully configured the count.
|
||||
* @retval kStatus_InvalidArgument Input argument is invalid.
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count);
|
||||
|
||||
/*!
|
||||
* @brief Writes one byte of data to the I2C bus.
|
||||
*
|
||||
* @note This is a non-blocking API, which returns directly after the data is put into the
|
||||
* data register but the data transfer is not finished on the bus. Ensure that
|
||||
* the TxEmptyFlag is asserted before calling this API.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param data a byte of data.
|
||||
*/
|
||||
static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data)
|
||||
{
|
||||
base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reads one byte of data from the I2C bus.
|
||||
*
|
||||
* @note This is a non-blocking API, which returns directly after the data is read from the
|
||||
* data register. Ensure that the data is ready in the register.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @return data byte read.
|
||||
*/
|
||||
static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base)
|
||||
{
|
||||
return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sends a buffer of data in bytes.
|
||||
*
|
||||
* @note This function blocks via polling until all bytes have been sent.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param txBuff The data bytes to send.
|
||||
* @param txSize The number of data bytes to send.
|
||||
* @retval kStatus_Success Successfully write data.
|
||||
* @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize);
|
||||
|
||||
/*!
|
||||
* @brief Receives a buffer of bytes.
|
||||
*
|
||||
* @note This function blocks via polling until all bytes have been received.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param rxBuff The buffer to store the received bytes.
|
||||
* @param rxSize The number of data bytes to be received.
|
||||
*/
|
||||
void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize);
|
||||
|
||||
/*!
|
||||
* @brief Performs a master polling transfer on the I2C bus.
|
||||
*
|
||||
* @note The API does not return until the transfer succeeds or fails due
|
||||
* to receiving NAK.
|
||||
*
|
||||
* @param base pointer to FLEXIO_I2C_Type structure.
|
||||
* @param xfer pointer to flexio_i2c_master_transfer_t structure.
|
||||
* @return status of status_t.
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer);
|
||||
/*@}*/
|
||||
|
||||
/*Transactional APIs*/
|
||||
|
||||
/*!
|
||||
* @name Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the I2C handle which is used in transactional functions.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
|
||||
* @param callback Pointer to user callback function.
|
||||
* @param userData User param passed to the callback function.
|
||||
* @retval kStatus_Success Successfully create the handle.
|
||||
* @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
|
||||
flexio_i2c_master_handle_t *handle,
|
||||
flexio_i2c_master_transfer_callback_t callback,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Performs a master interrupt non-blocking transfer on the I2C bus.
|
||||
*
|
||||
* @note The API returns immediately after the transfer initiates.
|
||||
* Call FLEXIO_I2C_MasterGetTransferCount to poll the transfer status to check whether
|
||||
* the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
|
||||
* is finished.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure
|
||||
* @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
|
||||
* @param xfer pointer to flexio_i2c_master_transfer_t structure
|
||||
* @retval kStatus_Success Successfully start a transfer.
|
||||
* @retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
|
||||
flexio_i2c_master_handle_t *handle,
|
||||
flexio_i2c_master_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure.
|
||||
* @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
* @retval kStatus_InvalidArgument count is Invalid.
|
||||
* @retval kStatus_Success Successfully return the count.
|
||||
*/
|
||||
status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Aborts an interrupt non-blocking transfer early.
|
||||
*
|
||||
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
|
||||
* to abort the transfer early.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_I2C_Type structure
|
||||
* @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
|
||||
*/
|
||||
void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Master interrupt handler.
|
||||
*
|
||||
* @param i2cType Pointer to FLEXIO_I2C_Type structure
|
||||
* @param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
|
||||
*/
|
||||
void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus*/
|
||||
/*@}*/
|
||||
|
||||
#endif /*_FSL_FLEXIO_I2C_MASTER_H_*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_flexio_spi_edma.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitons
|
||||
******************************************************************************/
|
||||
/*<! Structure definition for spi_edma_private_handle_t. The structure is private. */
|
||||
typedef struct _flexio_spi_master_edma_private_handle
|
||||
{
|
||||
FLEXIO_SPI_Type *base;
|
||||
flexio_spi_master_edma_handle_t *handle;
|
||||
} flexio_spi_master_edma_private_handle_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief EDMA callback function for FLEXIO SPI send transfer.
|
||||
*
|
||||
* @param handle EDMA handle pointer.
|
||||
* @param param Callback function parameter.
|
||||
*/
|
||||
static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
|
||||
|
||||
/*!
|
||||
* @brief EDMA callback function for FLEXIO SPI receive transfer.
|
||||
*
|
||||
* @param handle EDMA handle pointer.
|
||||
* @param param Callback function parameter.
|
||||
*/
|
||||
static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
|
||||
|
||||
/*!
|
||||
* @brief EDMA config for FLEXIO SPI transfer.
|
||||
*
|
||||
* @param base pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle pointer to flexio_spi_master_edma_handle_t structure to store the transfer state.
|
||||
* @param xfer Pointer to flexio spi transfer structure.
|
||||
*/
|
||||
static void FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
flexio_spi_transfer_t *xfer);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/* Dummy data used to send */
|
||||
static const uint16_t s_dummyData = FLEXIO_SPI_DUMMYDATA;
|
||||
|
||||
/*< @brief user configurable flexio spi handle count. */
|
||||
#define FLEXIO_SPI_HANDLE_COUNT 2
|
||||
|
||||
/*<! Private handle only used for internally. */
|
||||
static flexio_spi_master_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_SPI_HANDLE_COUNT];
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
|
||||
{
|
||||
tcds = tcds;
|
||||
flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param;
|
||||
|
||||
/* Disable Tx DMA */
|
||||
if (transferDone)
|
||||
{
|
||||
FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_TxDmaEnable, false);
|
||||
|
||||
/* change the state */
|
||||
spiPrivateHandle->handle->txInProgress = false;
|
||||
|
||||
/* All finished, call the callback */
|
||||
if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
|
||||
{
|
||||
if (spiPrivateHandle->handle->callback)
|
||||
{
|
||||
(spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
|
||||
spiPrivateHandle->handle->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
|
||||
{
|
||||
tcds = tcds;
|
||||
flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param;
|
||||
|
||||
if (transferDone)
|
||||
{
|
||||
/* Disable Rx dma */
|
||||
FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_RxDmaEnable, false);
|
||||
|
||||
/* change the state */
|
||||
spiPrivateHandle->handle->rxInProgress = false;
|
||||
|
||||
/* All finished, call the callback */
|
||||
if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
|
||||
{
|
||||
if (spiPrivateHandle->handle->callback)
|
||||
{
|
||||
(spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
|
||||
spiPrivateHandle->handle->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
flexio_spi_transfer_t *xfer)
|
||||
{
|
||||
edma_transfer_config_t xferConfig;
|
||||
flexio_spi_shift_direction_t direction;
|
||||
uint8_t bytesPerFrame;
|
||||
|
||||
/* Configure the values in handle. */
|
||||
switch (xfer->flags)
|
||||
{
|
||||
case kFLEXIO_SPI_8bitMsb:
|
||||
bytesPerFrame = 1;
|
||||
direction = kFLEXIO_SPI_MsbFirst;
|
||||
break;
|
||||
case kFLEXIO_SPI_8bitLsb:
|
||||
bytesPerFrame = 1;
|
||||
direction = kFLEXIO_SPI_LsbFirst;
|
||||
break;
|
||||
case kFLEXIO_SPI_16bitMsb:
|
||||
bytesPerFrame = 2;
|
||||
direction = kFLEXIO_SPI_MsbFirst;
|
||||
break;
|
||||
case kFLEXIO_SPI_16bitLsb:
|
||||
bytesPerFrame = 2;
|
||||
direction = kFLEXIO_SPI_LsbFirst;
|
||||
break;
|
||||
default:
|
||||
bytesPerFrame = 1U;
|
||||
direction = kFLEXIO_SPI_MsbFirst;
|
||||
assert(true);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Save total transfer size. */
|
||||
handle->transferSize = xfer->dataSize;
|
||||
|
||||
/* Configure tx transfer EDMA. */
|
||||
xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction);
|
||||
xferConfig.destOffset = 0;
|
||||
if (bytesPerFrame == 1U)
|
||||
{
|
||||
xferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
|
||||
xferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
|
||||
xferConfig.minorLoopBytes = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (direction == kFLEXIO_SPI_MsbFirst)
|
||||
{
|
||||
xferConfig.destAddr -= 1U;
|
||||
}
|
||||
xferConfig.srcTransferSize = kEDMA_TransferSize2Bytes;
|
||||
xferConfig.destTransferSize = kEDMA_TransferSize2Bytes;
|
||||
xferConfig.minorLoopBytes = 2;
|
||||
}
|
||||
|
||||
/* Configure DMA channel. */
|
||||
if (xfer->txData)
|
||||
{
|
||||
xferConfig.srcOffset = bytesPerFrame;
|
||||
xferConfig.srcAddr = (uint32_t)(xfer->txData);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the source increasement and source set to dummyData. */
|
||||
xferConfig.srcOffset = 0;
|
||||
xferConfig.srcAddr = (uint32_t)(&s_dummyData);
|
||||
}
|
||||
|
||||
xferConfig.majorLoopCounts = (xfer->dataSize / xferConfig.minorLoopBytes);
|
||||
|
||||
/* Store the initially configured eDMA minor byte transfer count into the FLEXIO SPI handle */
|
||||
handle->nbytes = xferConfig.minorLoopBytes;
|
||||
|
||||
if (handle->txHandle)
|
||||
{
|
||||
EDMA_SubmitTransfer(handle->txHandle, &xferConfig);
|
||||
}
|
||||
|
||||
/* Configure tx transfer EDMA. */
|
||||
if (xfer->rxData)
|
||||
{
|
||||
xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction);
|
||||
if (bytesPerFrame == 2U)
|
||||
{
|
||||
if (direction == kFLEXIO_SPI_LsbFirst)
|
||||
{
|
||||
xferConfig.srcAddr -= 1U;
|
||||
}
|
||||
}
|
||||
xferConfig.srcOffset = 0;
|
||||
xferConfig.destAddr = (uint32_t)(xfer->rxData);
|
||||
xferConfig.destOffset = bytesPerFrame;
|
||||
EDMA_SubmitTransfer(handle->rxHandle, &xferConfig);
|
||||
handle->rxInProgress = true;
|
||||
FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_RxDmaEnable, true);
|
||||
EDMA_StartTransfer(handle->rxHandle);
|
||||
}
|
||||
|
||||
/* Always start Tx transfer. */
|
||||
if (handle->txHandle)
|
||||
{
|
||||
handle->txInProgress = true;
|
||||
FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_TxDmaEnable, true);
|
||||
EDMA_StartTransfer(handle->txHandle);
|
||||
}
|
||||
}
|
||||
|
||||
status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
flexio_spi_master_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *txHandle,
|
||||
edma_handle_t *rxHandle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
uint8_t index = 0;
|
||||
|
||||
/* Find the an empty handle pointer to store the handle. */
|
||||
for (index = 0; index < FLEXIO_SPI_HANDLE_COUNT; index++)
|
||||
{
|
||||
if (s_edmaPrivateHandle[index].base == NULL)
|
||||
{
|
||||
s_edmaPrivateHandle[index].base = base;
|
||||
s_edmaPrivateHandle[index].handle = handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == FLEXIO_SPI_HANDLE_COUNT)
|
||||
{
|
||||
return kStatus_OutOfRange;
|
||||
}
|
||||
|
||||
/* Set spi base to handle. */
|
||||
handle->txHandle = txHandle;
|
||||
handle->rxHandle = rxHandle;
|
||||
|
||||
/* Register callback and userData. */
|
||||
handle->callback = callback;
|
||||
handle->userData = userData;
|
||||
|
||||
/* Set SPI state to idle. */
|
||||
handle->txInProgress = false;
|
||||
handle->rxInProgress = false;
|
||||
|
||||
/* Install callback for Tx/Rx dma channel. */
|
||||
if (handle->txHandle)
|
||||
{
|
||||
EDMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxEDMACallback, &s_edmaPrivateHandle[index]);
|
||||
}
|
||||
if (handle->rxHandle)
|
||||
{
|
||||
EDMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxEDMACallback, &s_edmaPrivateHandle[index]);
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
flexio_spi_transfer_t *xfer)
|
||||
{
|
||||
assert(handle);
|
||||
assert(xfer);
|
||||
|
||||
uint32_t dataMode = 0;
|
||||
uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]];
|
||||
|
||||
timerCmp &= 0x00FFU;
|
||||
|
||||
/* Check if the device is busy. */
|
||||
if ((handle->txInProgress) || (handle->rxInProgress))
|
||||
{
|
||||
return kStatus_FLEXIO_SPI_Busy;
|
||||
}
|
||||
|
||||
/* Check if input parameter invalid. */
|
||||
if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
/* configure data mode. */
|
||||
if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb))
|
||||
{
|
||||
dataMode = (8 * 2 - 1U) << 8U;
|
||||
}
|
||||
else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb))
|
||||
{
|
||||
dataMode = (16 * 2 - 1U) << 8U;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataMode = 8 * 2 - 1U;
|
||||
}
|
||||
|
||||
dataMode |= timerCmp;
|
||||
|
||||
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
|
||||
|
||||
FLEXIO_SPI_EDMAConfig(base, handle, xfer);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
size_t *count)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
if (!count)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
if (handle->rxInProgress)
|
||||
{
|
||||
*count = (handle->transferSize -
|
||||
(uint32_t)handle->nbytes *
|
||||
EDMA_GetRemainingMajorLoopCount(handle->rxHandle->base, handle->rxHandle->channel));
|
||||
}
|
||||
else
|
||||
{
|
||||
*count = (handle->transferSize -
|
||||
(uint32_t)handle->nbytes *
|
||||
EDMA_GetRemainingMajorLoopCount(handle->txHandle->base, handle->txHandle->channel));
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
/* Disable dma. */
|
||||
EDMA_StopTransfer(handle->txHandle);
|
||||
EDMA_StopTransfer(handle->rxHandle);
|
||||
|
||||
/* Disable DMA enable bit. */
|
||||
FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_DmaAllEnable, false);
|
||||
|
||||
/* Set the handle state. */
|
||||
handle->txInProgress = false;
|
||||
handle->rxInProgress = false;
|
||||
}
|
||||
|
||||
status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_slave_edma_handle_t *handle,
|
||||
flexio_spi_transfer_t *xfer)
|
||||
{
|
||||
assert(handle);
|
||||
assert(xfer);
|
||||
|
||||
uint32_t dataMode = 0;
|
||||
|
||||
/* Check if the device is busy. */
|
||||
if ((handle->txInProgress) || (handle->rxInProgress))
|
||||
{
|
||||
return kStatus_FLEXIO_SPI_Busy;
|
||||
}
|
||||
|
||||
/* Check if input parameter invalid. */
|
||||
if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
/* configure data mode. */
|
||||
if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb))
|
||||
{
|
||||
dataMode = 8 * 2 - 1U;
|
||||
}
|
||||
else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb))
|
||||
{
|
||||
dataMode = 16 * 2 - 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataMode = 8 * 2 - 1U;
|
||||
}
|
||||
|
||||
base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
|
||||
|
||||
FLEXIO_SPI_EDMAConfig(base, handle, xfer);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_FLEXIO_SPI_EDMA_H_
|
||||
#define _FSL_FLEXIO_SPI_EDMA_H_
|
||||
|
||||
#include "fsl_flexio_spi.h"
|
||||
#include "fsl_edma.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup flexio_edma_spi
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief typedef for flexio_spi_master_edma_handle_t in advance. */
|
||||
typedef struct _flexio_spi_master_edma_handle flexio_spi_master_edma_handle_t;
|
||||
|
||||
/*! @brief Slave handle is the same with master handle. */
|
||||
typedef flexio_spi_master_edma_handle_t flexio_spi_slave_edma_handle_t;
|
||||
|
||||
/*! @brief FlexIO SPI master callback for finished transmit */
|
||||
typedef void (*flexio_spi_master_edma_transfer_callback_t)(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief FlexIO SPI slave callback for finished transmit */
|
||||
typedef void (*flexio_spi_slave_edma_transfer_callback_t)(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_slave_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief FlexIO SPI eDMA transfer handle, users should not touch the content of the handle.*/
|
||||
struct _flexio_spi_master_edma_handle
|
||||
{
|
||||
size_t transferSize; /*!< Total bytes to be transferred. */
|
||||
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
|
||||
bool txInProgress; /*!< Send transfer in progress */
|
||||
bool rxInProgress; /*!< Receive transfer in progress */
|
||||
edma_handle_t *txHandle; /*!< DMA handler for SPI send */
|
||||
edma_handle_t *rxHandle; /*!< DMA handler for SPI receive */
|
||||
flexio_spi_master_edma_transfer_callback_t callback; /*!< Callback for SPI DMA transfer */
|
||||
void *userData; /*!< User Data for SPI DMA callback */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* APIs
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name eDMA Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the FlexIO SPI master eDMA handle.
|
||||
*
|
||||
* This function initializes the FlexIO SPI master eDMA handle which can be used for other FlexIO SPI master transactional
|
||||
* APIs.
|
||||
* For a specified FlexIO SPI instance, call this API once to get the initialized handle.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state.
|
||||
* @param callback SPI callback, NULL means no callback.
|
||||
* @param userData callback function parameter.
|
||||
* @param txHandle User requested eDMA handle for FlexIO SPI RX eDMA transfer.
|
||||
* @param rxHandle User requested eDMA handle for FlexIO SPI TX eDMA transfer.
|
||||
* @retval kStatus_Success Successfully create the handle.
|
||||
* @retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range.
|
||||
*/
|
||||
status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
flexio_spi_master_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *txHandle,
|
||||
edma_handle_t *rxHandle);
|
||||
|
||||
/*!
|
||||
* @brief Performs a non-blocking FlexIO SPI transfer using eDMA.
|
||||
*
|
||||
* @note This interface returns immediately after transfer initiates. Call
|
||||
* FLEXIO_SPI_MasterGetTransferCountEDMA to poll the transfer status and check
|
||||
* whether the FlexIO SPI transfer is finished.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state.
|
||||
* @param xfer Pointer to FlexIO SPI transfer structure.
|
||||
* @retval kStatus_Success Successfully start a transfer.
|
||||
* @retval kStatus_InvalidArgument Input argument is invalid.
|
||||
* @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer.
|
||||
*/
|
||||
status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
flexio_spi_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Aborts a FlexIO SPI transfer using eDMA.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle FlexIO SPI eDMA handle pointer.
|
||||
*/
|
||||
void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets the remaining bytes for FlexIO SPI eDMA transfer.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle FlexIO SPI eDMA handle pointer.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
*/
|
||||
status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_master_edma_handle_t *handle,
|
||||
size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Initializes the FlexIO SPI slave eDMA handle.
|
||||
*
|
||||
* This function initializes the FlexIO SPI slave eDMA handle.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state.
|
||||
* @param callback SPI callback, NULL means no callback.
|
||||
* @param userData callback function parameter.
|
||||
* @param txHandle User requested eDMA handle for FlexIO SPI TX eDMA transfer.
|
||||
* @param rxHandle User requested eDMA handle for FlexIO SPI RX eDMA transfer.
|
||||
*/
|
||||
static inline void FLEXIO_SPI_SlaveTransferCreateHandleEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_slave_edma_handle_t *handle,
|
||||
flexio_spi_slave_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *txHandle,
|
||||
edma_handle_t *rxHandle)
|
||||
{
|
||||
FLEXIO_SPI_MasterTransferCreateHandleEDMA(base, handle, callback, userData, txHandle, rxHandle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Performs a non-blocking FlexIO SPI transfer using eDMA.
|
||||
*
|
||||
* @note This interface returns immediately after transfer initiates. Call
|
||||
* FLEXIO_SPI_SlaveGetTransferCountEDMA to poll the transfer status and
|
||||
* check whether the FlexIO SPI transfer is finished.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state.
|
||||
* @param xfer Pointer to FlexIO SPI transfer structure.
|
||||
* @retval kStatus_Success Successfully start a transfer.
|
||||
* @retval kStatus_InvalidArgument Input argument is invalid.
|
||||
* @retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer.
|
||||
*/
|
||||
status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_slave_edma_handle_t *handle,
|
||||
flexio_spi_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Aborts a FlexIO SPI transfer using eDMA.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state.
|
||||
*/
|
||||
static inline void FLEXIO_SPI_SlaveTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_slave_edma_handle_t *handle)
|
||||
{
|
||||
FLEXIO_SPI_MasterTransferAbortEDMA(base, handle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the remaining bytes to be transferred for FlexIO SPI eDMA.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_SPI_Type structure.
|
||||
* @param handle FlexIO SPI eDMA handle pointer.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
*/
|
||||
static inline status_t FLEXIO_SPI_SlaveTransferGetCountEDMA(FLEXIO_SPI_Type *base,
|
||||
flexio_spi_slave_edma_handle_t *handle,
|
||||
size_t *count)
|
||||
{
|
||||
return FLEXIO_SPI_MasterTransferGetCountEDMA(base, handle, count);
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_flexio_uart_edma.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*<! Structure definition for uart_edma_private_handle_t. The structure is private. */
|
||||
typedef struct _flexio_uart_edma_private_handle
|
||||
{
|
||||
FLEXIO_UART_Type *base;
|
||||
flexio_uart_edma_handle_t *handle;
|
||||
} flexio_uart_edma_private_handle_t;
|
||||
|
||||
/* UART EDMA transfer handle. */
|
||||
enum _flexio_uart_edma_tansfer_states
|
||||
{
|
||||
kFLEXIO_UART_TxIdle, /* TX idle. */
|
||||
kFLEXIO_UART_TxBusy, /* TX busy. */
|
||||
kFLEXIO_UART_RxIdle, /* RX idle. */
|
||||
kFLEXIO_UART_RxBusy /* RX busy. */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*< @brief user configurable flexio uart handle count. */
|
||||
#define FLEXIO_UART_HANDLE_COUNT 2
|
||||
|
||||
/*<! Private handle only used for internally. */
|
||||
static flexio_uart_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_UART_HANDLE_COUNT];
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief FLEXIO UART EDMA send finished callback function.
|
||||
*
|
||||
* This function is called when FLEXIO UART EDMA send finished. It disables the UART
|
||||
* TX EDMA request and sends @ref kStatus_FLEXIO_UART_TxIdle to FLEXIO UART callback.
|
||||
*
|
||||
* @param handle The EDMA handle.
|
||||
* @param param Callback function parameter.
|
||||
*/
|
||||
static void FLEXIO_UART_TransferSendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
|
||||
|
||||
/*!
|
||||
* @brief FLEXIO UART EDMA receive finished callback function.
|
||||
*
|
||||
* This function is called when FLEXIO UART EDMA receive finished. It disables the UART
|
||||
* RX EDMA request and sends @ref kStatus_FLEXIO_UART_RxIdle to UART callback.
|
||||
*
|
||||
* @param handle The EDMA handle.
|
||||
* @param param Callback function parameter.
|
||||
*/
|
||||
static void FLEXIO_UART_TransferReceiveEDMACallback(edma_handle_t *handle,
|
||||
void *param,
|
||||
bool transferDone,
|
||||
uint32_t tcds);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static void FLEXIO_UART_TransferSendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
|
||||
{
|
||||
flexio_uart_edma_private_handle_t *uartPrivateHandle = (flexio_uart_edma_private_handle_t *)param;
|
||||
|
||||
assert(uartPrivateHandle->handle);
|
||||
|
||||
/* Avoid the warning for unused variables. */
|
||||
handle = handle;
|
||||
tcds = tcds;
|
||||
|
||||
if (transferDone)
|
||||
{
|
||||
FLEXIO_UART_TransferAbortSendEDMA(uartPrivateHandle->base, uartPrivateHandle->handle);
|
||||
|
||||
if (uartPrivateHandle->handle->callback)
|
||||
{
|
||||
uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle,
|
||||
kStatus_FLEXIO_UART_TxIdle, uartPrivateHandle->handle->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FLEXIO_UART_TransferReceiveEDMACallback(edma_handle_t *handle,
|
||||
void *param,
|
||||
bool transferDone,
|
||||
uint32_t tcds)
|
||||
{
|
||||
flexio_uart_edma_private_handle_t *uartPrivateHandle = (flexio_uart_edma_private_handle_t *)param;
|
||||
|
||||
assert(uartPrivateHandle->handle);
|
||||
|
||||
/* Avoid the warning for unused variables. */
|
||||
handle = handle;
|
||||
tcds = tcds;
|
||||
|
||||
if (transferDone)
|
||||
{
|
||||
/* Disable transfer. */
|
||||
FLEXIO_UART_TransferAbortReceiveEDMA(uartPrivateHandle->base, uartPrivateHandle->handle);
|
||||
|
||||
if (uartPrivateHandle->handle->callback)
|
||||
{
|
||||
uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle,
|
||||
kStatus_FLEXIO_UART_RxIdle, uartPrivateHandle->handle->userData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status_t FLEXIO_UART_TransferCreateHandleEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
flexio_uart_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *txEdmaHandle,
|
||||
edma_handle_t *rxEdmaHandle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
uint8_t index = 0;
|
||||
|
||||
/* Find the an empty handle pointer to store the handle. */
|
||||
for (index = 0; index < FLEXIO_UART_HANDLE_COUNT; index++)
|
||||
{
|
||||
if (s_edmaPrivateHandle[index].base == NULL)
|
||||
{
|
||||
s_edmaPrivateHandle[index].base = base;
|
||||
s_edmaPrivateHandle[index].handle = handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == FLEXIO_UART_HANDLE_COUNT)
|
||||
{
|
||||
return kStatus_OutOfRange;
|
||||
}
|
||||
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
handle->rxState = kFLEXIO_UART_RxIdle;
|
||||
handle->txState = kFLEXIO_UART_TxIdle;
|
||||
|
||||
handle->rxEdmaHandle = rxEdmaHandle;
|
||||
handle->txEdmaHandle = txEdmaHandle;
|
||||
|
||||
handle->callback = callback;
|
||||
handle->userData = userData;
|
||||
|
||||
/* Configure TX. */
|
||||
if (txEdmaHandle)
|
||||
{
|
||||
EDMA_SetCallback(handle->txEdmaHandle, FLEXIO_UART_TransferSendEDMACallback, &s_edmaPrivateHandle);
|
||||
}
|
||||
|
||||
/* Configure RX. */
|
||||
if (rxEdmaHandle)
|
||||
{
|
||||
EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_UART_TransferReceiveEDMACallback, &s_edmaPrivateHandle);
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t FLEXIO_UART_TransferSendEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
flexio_uart_transfer_t *xfer)
|
||||
{
|
||||
assert(handle->txEdmaHandle);
|
||||
|
||||
edma_transfer_config_t xferConfig;
|
||||
status_t status;
|
||||
|
||||
/* Return error if xfer invalid. */
|
||||
if ((0U == xfer->dataSize) || (NULL == xfer->data))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
/* If previous TX not finished. */
|
||||
if (kFLEXIO_UART_TxBusy == handle->txState)
|
||||
{
|
||||
status = kStatus_FLEXIO_UART_TxBusy;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->txState = kFLEXIO_UART_TxBusy;
|
||||
handle->txDataSizeAll = xfer->dataSize;
|
||||
|
||||
/* Prepare transfer. */
|
||||
EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t),
|
||||
(void *)FLEXIO_UART_GetTxDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t),
|
||||
xfer->dataSize, kEDMA_MemoryToPeripheral);
|
||||
|
||||
/* Store the initially configured eDMA minor byte transfer count into the FLEXIO UART handle */
|
||||
handle->nbytes = sizeof(uint8_t);
|
||||
|
||||
/* Submit transfer. */
|
||||
EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
|
||||
EDMA_StartTransfer(handle->txEdmaHandle);
|
||||
|
||||
/* Enable UART TX EDMA. */
|
||||
FLEXIO_UART_EnableTxDMA(base, true);
|
||||
|
||||
status = kStatus_Success;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t FLEXIO_UART_TransferReceiveEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
flexio_uart_transfer_t *xfer)
|
||||
{
|
||||
assert(handle->rxEdmaHandle);
|
||||
|
||||
edma_transfer_config_t xferConfig;
|
||||
status_t status;
|
||||
|
||||
/* Return error if xfer invalid. */
|
||||
if ((0U == xfer->dataSize) || (NULL == xfer->data))
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
/* If previous RX not finished. */
|
||||
if (kFLEXIO_UART_RxBusy == handle->rxState)
|
||||
{
|
||||
status = kStatus_FLEXIO_UART_RxBusy;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->rxState = kFLEXIO_UART_RxBusy;
|
||||
handle->rxDataSizeAll = xfer->dataSize;
|
||||
|
||||
/* Prepare transfer. */
|
||||
EDMA_PrepareTransfer(&xferConfig, (void *)FLEXIO_UART_GetRxDataRegisterAddress(base), sizeof(uint8_t),
|
||||
xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
|
||||
|
||||
/* Store the initially configured eDMA minor byte transfer count into the FLEXIO UART handle */
|
||||
handle->nbytes = sizeof(uint8_t);
|
||||
|
||||
/* Submit transfer. */
|
||||
EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
|
||||
EDMA_StartTransfer(handle->rxEdmaHandle);
|
||||
|
||||
/* Enable UART RX EDMA. */
|
||||
FLEXIO_UART_EnableRxDMA(base, true);
|
||||
|
||||
status = kStatus_Success;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void FLEXIO_UART_TransferAbortSendEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle)
|
||||
{
|
||||
assert(handle->txEdmaHandle);
|
||||
|
||||
/* Disable UART TX EDMA. */
|
||||
FLEXIO_UART_EnableTxDMA(base, false);
|
||||
|
||||
/* Stop transfer. */
|
||||
EDMA_StopTransfer(handle->txEdmaHandle);
|
||||
|
||||
handle->txState = kFLEXIO_UART_TxIdle;
|
||||
}
|
||||
|
||||
void FLEXIO_UART_TransferAbortReceiveEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle)
|
||||
{
|
||||
assert(handle->rxEdmaHandle);
|
||||
|
||||
/* Disable UART RX EDMA. */
|
||||
FLEXIO_UART_EnableRxDMA(base, false);
|
||||
|
||||
/* Stop transfer. */
|
||||
EDMA_StopTransfer(handle->rxEdmaHandle);
|
||||
|
||||
handle->rxState = kFLEXIO_UART_RxIdle;
|
||||
}
|
||||
|
||||
status_t FLEXIO_UART_TransferGetReceiveCountEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
size_t *count)
|
||||
{
|
||||
assert(handle);
|
||||
assert(handle->rxEdmaHandle);
|
||||
assert(count);
|
||||
|
||||
if (kFLEXIO_UART_RxIdle == handle->rxState)
|
||||
{
|
||||
return kStatus_NoTransferInProgress;
|
||||
}
|
||||
|
||||
*count = handle->rxDataSizeAll -
|
||||
(uint32_t)handle->nbytes *
|
||||
EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t FLEXIO_UART_TransferGetSendCountEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle, size_t *count)
|
||||
{
|
||||
assert(handle);
|
||||
assert(handle->txEdmaHandle);
|
||||
assert(count);
|
||||
|
||||
if (kFLEXIO_UART_TxIdle == handle->txState)
|
||||
{
|
||||
return kStatus_NoTransferInProgress;
|
||||
}
|
||||
|
||||
*count = handle->txDataSizeAll -
|
||||
(uint32_t)handle->nbytes *
|
||||
EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_FLEXIO_UART_EDMA_H_
|
||||
#define _FSL_FLEXIO_UART_EDMA_H_
|
||||
|
||||
#include "fsl_flexio_uart.h"
|
||||
#include "fsl_edma.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup flexio_edma_uart
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Forward declaration of the handle typedef. */
|
||||
typedef struct _flexio_uart_edma_handle flexio_uart_edma_handle_t;
|
||||
|
||||
/*! @brief UART transfer callback function. */
|
||||
typedef void (*flexio_uart_edma_transfer_callback_t)(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief UART eDMA handle
|
||||
*/
|
||||
struct _flexio_uart_edma_handle
|
||||
{
|
||||
flexio_uart_edma_transfer_callback_t callback; /*!< Callback function. */
|
||||
void *userData; /*!< UART callback function parameter.*/
|
||||
|
||||
size_t txDataSizeAll; /*!< Total bytes to be sent. */
|
||||
size_t rxDataSizeAll; /*!< Total bytes to be received. */
|
||||
|
||||
edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */
|
||||
edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */
|
||||
|
||||
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
|
||||
|
||||
volatile uint8_t txState; /*!< TX transfer state. */
|
||||
volatile uint8_t rxState; /*!< RX transfer state */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name eDMA transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the UART handle which is used in transactional functions.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type.
|
||||
* @param handle Pointer to flexio_uart_edma_handle_t structure.
|
||||
* @param callback The callback function.
|
||||
* @param userData The parameter of the callback function.
|
||||
* @param rxEdmaHandle User requested DMA handle for RX DMA transfer.
|
||||
* @param txEdmaHandle User requested DMA handle for TX DMA transfer.
|
||||
* @retval kStatus_Success Successfully create the handle.
|
||||
* @retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range.
|
||||
*/
|
||||
status_t FLEXIO_UART_TransferCreateHandleEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
flexio_uart_edma_transfer_callback_t callback,
|
||||
void *userData,
|
||||
edma_handle_t *txEdmaHandle,
|
||||
edma_handle_t *rxEdmaHandle);
|
||||
|
||||
/*!
|
||||
* @brief Sends data using eDMA.
|
||||
*
|
||||
* This function sends data using eDMA. This is a non-blocking function, which returns
|
||||
* right away. When all data is sent out, the send callback function is called.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type
|
||||
* @param handle UART handle pointer.
|
||||
* @param xfer UART eDMA transfer structure, see #flexio_uart_transfer_t.
|
||||
* @retval kStatus_Success if succeed, others failed.
|
||||
* @retval kStatus_FLEXIO_UART_TxBusy Previous transfer on going.
|
||||
*/
|
||||
status_t FLEXIO_UART_TransferSendEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
flexio_uart_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Receives data using eDMA.
|
||||
*
|
||||
* This function receives data using eDMA. This is a non-blocking function, which returns
|
||||
* right away. When all data is received, the receive callback function is called.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type
|
||||
* @param handle Pointer to flexio_uart_edma_handle_t structure
|
||||
* @param xfer UART eDMA transfer structure, see #flexio_uart_transfer_t.
|
||||
* @retval kStatus_Success if succeed, others failed.
|
||||
* @retval kStatus_UART_RxBusy Previous transfer on going.
|
||||
*/
|
||||
status_t FLEXIO_UART_TransferReceiveEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
flexio_uart_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the sent data which using eDMA.
|
||||
*
|
||||
* This function aborts sent data which using eDMA.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type
|
||||
* @param handle Pointer to flexio_uart_edma_handle_t structure
|
||||
*/
|
||||
void FLEXIO_UART_TransferAbortSendEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Aborts the receive data which using eDMA.
|
||||
*
|
||||
* This function aborts the receive data which using eDMA.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type
|
||||
* @param handle Pointer to flexio_uart_edma_handle_t structure
|
||||
*/
|
||||
void FLEXIO_UART_TransferAbortReceiveEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Gets the number of bytes sent out.
|
||||
*
|
||||
* This function gets the number of bytes sent out.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type
|
||||
* @param handle Pointer to flexio_uart_edma_handle_t structure
|
||||
* @param count Number of bytes sent so far by the non-blocking transaction.
|
||||
* @retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress.
|
||||
* @retval kStatus_Success Successfully return the count.
|
||||
*/
|
||||
status_t FLEXIO_UART_TransferGetSendCountEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Gets the number of bytes received.
|
||||
*
|
||||
* This function gets the number of bytes received.
|
||||
*
|
||||
* @param base Pointer to FLEXIO_UART_Type
|
||||
* @param handle Pointer to flexio_uart_edma_handle_t structure
|
||||
* @param count Number of bytes received so far by the non-blocking transaction.
|
||||
* @retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress.
|
||||
* @retval kStatus_Success Successfully return the count.
|
||||
*/
|
||||
status_t FLEXIO_UART_TransferGetReceiveCountEDMA(FLEXIO_UART_Type *base,
|
||||
flexio_uart_edma_handle_t *handle,
|
||||
size_t *count);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_UART_EDMA_H_ */
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static PORT_Type *const s_portBases[] = PORT_BASE_PTRS;
|
||||
static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
|
||||
|
||||
#if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Array to map FGPIO instance number to clock name. */
|
||||
static const clock_ip_name_t s_fgpioClockName[] = FGPIO_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
#endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Gets the GPIO instance according to the GPIO base
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
|
||||
* @retval GPIO instance
|
||||
*/
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++)
|
||||
{
|
||||
if (s_gpioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_gpioBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
if (config->pinDirection == kGPIO_DigitalInput)
|
||||
{
|
||||
base->PDDR &= ~(1U << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_WritePinOutput(base, pin, config->outputLogic);
|
||||
base->PDDR |= (1U << pin);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base)
|
||||
{
|
||||
uint8_t instance;
|
||||
PORT_Type *portBase;
|
||||
instance = GPIO_GetInstance(base);
|
||||
portBase = s_portBases[instance];
|
||||
return portBase->ISFR;
|
||||
}
|
||||
|
||||
void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t instance;
|
||||
PORT_Type *portBase;
|
||||
instance = GPIO_GetInstance(base);
|
||||
portBase = s_portBases[instance];
|
||||
portBase->ISFR = mask;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
|
||||
void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute)
|
||||
{
|
||||
base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) |
|
||||
((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS;
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Gets the FGPIO instance according to the GPIO base
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.)
|
||||
* @retval FGPIO instance
|
||||
*/
|
||||
static uint32_t FGPIO_GetInstance(FGPIO_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t FGPIO_GetInstance(FGPIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_fgpioBases); instance++)
|
||||
{
|
||||
if (s_fgpioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_fgpioBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
|
||||
void FGPIO_Init(FGPIO_Type *base)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Ungate FGPIO periphral clock */
|
||||
CLOCK_EnableClock(s_fgpioClockName[FGPIO_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
#endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
|
||||
|
||||
void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
if (config->pinDirection == kGPIO_DigitalInput)
|
||||
{
|
||||
base->PDDR &= ~(1U << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
FGPIO_WritePinOutput(base, pin, config->outputLogic);
|
||||
base->PDDR |= (1U << pin);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base)
|
||||
{
|
||||
uint8_t instance;
|
||||
instance = FGPIO_GetInstance(base);
|
||||
PORT_Type *portBase;
|
||||
portBase = s_portBases[instance];
|
||||
return portBase->ISFR;
|
||||
}
|
||||
|
||||
void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
uint8_t instance;
|
||||
instance = FGPIO_GetInstance(base);
|
||||
PORT_Type *portBase;
|
||||
portBase = s_portBases[instance];
|
||||
portBase->ISFR = mask;
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER
|
||||
void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute)
|
||||
{
|
||||
base->GACR = (attribute << FGPIO_GACR_ACB0_SHIFT) | (attribute << FGPIO_GACR_ACB1_SHIFT) |
|
||||
(attribute << FGPIO_GACR_ACB2_SHIFT) | (attribute << FGPIO_GACR_ACB3_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
|
||||
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_GPIO_H_
|
||||
#define _FSL_GPIO_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup gpio
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief GPIO driver version 2.2.0. */
|
||||
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief GPIO direction definition */
|
||||
typedef enum _gpio_pin_direction
|
||||
{
|
||||
kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/
|
||||
kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
|
||||
} gpio_pin_direction_t;
|
||||
|
||||
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
|
||||
/*! @brief GPIO checker attribute */
|
||||
typedef enum _gpio_checker_attribute
|
||||
{
|
||||
kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW =
|
||||
0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */
|
||||
kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW =
|
||||
0x01U, /*!< User nonsecure:Read; User Secure:Read+Write; Privileged Secure:Read+Write */
|
||||
kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW =
|
||||
0x02U, /*!< User nonsecure:None; User Secure:Read+Write; Privileged Secure:Read+Write */
|
||||
kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW =
|
||||
0x03U, /*!< User nonsecure:Read; User Secure:Read; Privileged Secure:Read+Write */
|
||||
kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW =
|
||||
0x04U, /*!< User nonsecure:None; User Secure:Read; Privileged Secure:Read+Write */
|
||||
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW =
|
||||
0x05U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read+Write */
|
||||
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR =
|
||||
0x06U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read */
|
||||
kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN =
|
||||
0x07U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:None */
|
||||
kGPIO_IgnoreAttributeCheck = 0x80U, /*!< Ignores the attribute check */
|
||||
} gpio_checker_attribute_t;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief The GPIO pin configuration structure.
|
||||
*
|
||||
* Each pin can only be configured as either an output pin or an input pin at a time.
|
||||
* If configured as an input pin, leave the outputConfig unused.
|
||||
* Note that in some use cases, the corresponding port property should be configured in advance
|
||||
* with the PORT_SetPinConfig().
|
||||
*/
|
||||
typedef struct _gpio_pin_config
|
||||
{
|
||||
gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */
|
||||
/* Output configurations; ignore if configured as an input pin */
|
||||
uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */
|
||||
} gpio_pin_config_t;
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @addtogroup gpio_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @name GPIO Configuration */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes a GPIO pin used by the board.
|
||||
*
|
||||
* To initialize the GPIO, define a pin configuration, as either input or output, in the user file.
|
||||
* Then, call the GPIO_PinInit() function.
|
||||
*
|
||||
* This is an example to define an input pin or an output pin configuration.
|
||||
* @code
|
||||
* // Define a digital input pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalInput,
|
||||
* 0,
|
||||
* }
|
||||
* //Define a digital output pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalOutput,
|
||||
* 0,
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin GPIO port pin number
|
||||
* @param config GPIO pin configuration pointer
|
||||
*/
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*! @name GPIO Output Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin GPIO pin number
|
||||
* @param output GPIO pin output logic level.
|
||||
* - 0: corresponding pin output low-logic level.
|
||||
* - 1: corresponding pin output high-logic level.
|
||||
*/
|
||||
static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
if (output == 0U)
|
||||
{
|
||||
base->PCOR = 1U << pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->PSOR = 1U << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PSOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple GPIO pins to the logic 0.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PCOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reverses the current output logic of the multiple GPIO pins.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PTOR = mask;
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name GPIO Input Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the current input value of the GPIO port.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param pin GPIO pin number
|
||||
* @retval GPIO port input value
|
||||
* - 0: corresponding pin input low-logic level.
|
||||
* - 1: corresponding pin input high-logic level.
|
||||
*/
|
||||
static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
return (((base->PDIR) >> pin) & 0x01U);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name GPIO Interrupt */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the GPIO port interrupt status flag.
|
||||
*
|
||||
* If a pin is configured to generate the DMA request, the corresponding flag
|
||||
* is cleared automatically at the completion of the requested DMA transfer.
|
||||
* Otherwise, the flag remains set until a logic one is written to that flag.
|
||||
* If configured for a level sensitive interrupt that remains asserted, the flag
|
||||
* is set again immediately.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the
|
||||
* pin 0 and 17 have the interrupt.
|
||||
*/
|
||||
uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears multiple GPIO pin interrupt status flags.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask);
|
||||
|
||||
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
|
||||
/*!
|
||||
* @brief The GPIO module supports a device-specific number of data ports, organized as 32-bit
|
||||
* words. Each 32-bit data port includes a GACR register, which defines the byte-level
|
||||
* attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
|
||||
* bytes in the GACR follow a standard little endian
|
||||
* data convention.
|
||||
*
|
||||
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
|
||||
* @param mask GPIO pin number macro
|
||||
*/
|
||||
void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute);
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @addtogroup fgpio_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* Introduces the FGPIO feature.
|
||||
*
|
||||
* The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT
|
||||
* interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and
|
||||
* complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO.
|
||||
*/
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
|
||||
|
||||
/*! @name FGPIO Configuration */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the FGPIO peripheral.
|
||||
*
|
||||
* This function ungates the FGPIO clock.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
*/
|
||||
void FGPIO_Init(FGPIO_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Initializes a FGPIO pin used by the board.
|
||||
*
|
||||
* To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file.
|
||||
* Then, call the FGPIO_PinInit() function.
|
||||
*
|
||||
* This is an example to define an input pin or an output pin configuration:
|
||||
* @code
|
||||
* // Define a digital input pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalInput,
|
||||
* 0,
|
||||
* }
|
||||
* //Define a digital output pin configuration,
|
||||
* gpio_pin_config_t config =
|
||||
* {
|
||||
* kGPIO_DigitalOutput,
|
||||
* 0,
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param pin FGPIO port pin number
|
||||
* @param config FGPIO pin configuration pointer
|
||||
*/
|
||||
void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*! @name FGPIO Output Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param pin FGPIO pin number
|
||||
* @param output FGPIOpin output logic level.
|
||||
* - 0: corresponding pin output low-logic level.
|
||||
* - 1: corresponding pin output high-logic level.
|
||||
*/
|
||||
static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
if (output == 0U)
|
||||
{
|
||||
base->PCOR = 1 << pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->PSOR = 1 << pin;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple FGPIO pins to the logic 1.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param mask FGPIO pin number macro
|
||||
*/
|
||||
static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PSOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the output level of the multiple FGPIO pins to the logic 0.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param mask FGPIO pin number macro
|
||||
*/
|
||||
static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PCOR = mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reverses the current output logic of the multiple FGPIO pins.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param mask FGPIO pin number macro
|
||||
*/
|
||||
static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask)
|
||||
{
|
||||
base->PTOR = mask;
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name FGPIO Input Operations */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the current input value of the FGPIO port.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param pin FGPIO pin number
|
||||
* @retval FGPIO port input value
|
||||
* - 0: corresponding pin input low-logic level.
|
||||
* - 1: corresponding pin input high-logic level.
|
||||
*/
|
||||
static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin)
|
||||
{
|
||||
return (((base->PDIR) >> pin) & 0x01U);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*! @name FGPIO Interrupt */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Reads the FGPIO port interrupt status flag.
|
||||
*
|
||||
* If a pin is configured to generate the DMA request, the corresponding flag
|
||||
* is cleared automatically at the completion of the requested DMA transfer.
|
||||
* Otherwise, the flag remains set until a logic one is written to that flag.
|
||||
* If configured for a level-sensitive interrupt that remains asserted, the flag
|
||||
* is set again immediately.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the
|
||||
* pin 0 and 17 have the interrupt.
|
||||
*/
|
||||
uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Clears the multiple FGPIO pin interrupt status flag.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param mask FGPIO pin number macro
|
||||
*/
|
||||
void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask);
|
||||
|
||||
#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
|
||||
/*!
|
||||
* @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit
|
||||
* words. Each 32-bit data port includes a GACR register, which defines the byte-level
|
||||
* attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
|
||||
* bytes in the GACR follow a standard little endian
|
||||
* data convention.
|
||||
*
|
||||
* @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
|
||||
* @param mask FGPIO pin number macro
|
||||
*/
|
||||
void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute);
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _FSL_GPIO_H_*/
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_intmux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get instance number for INTMUX.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
*/
|
||||
static uint32_t INTMUX_GetInstance(INTMUX_Type *base);
|
||||
|
||||
#if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
|
||||
/*!
|
||||
* @brief Handle INTMUX all channels IRQ.
|
||||
*
|
||||
* The handler reads the INTMUX channel's active vector register. This returns the offset
|
||||
* from the start of the vector table to the vector for the INTMUX channel's highest priority
|
||||
* pending source interrupt. After a check for spurious interrupts (an offset of 0), the
|
||||
* function address at the vector offset is read and jumped to.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
* @param channel INTMUX channel number.
|
||||
*/
|
||||
static void INTMUX_CommonIRQHandler(INTMUX_Type *intmuxBase, uint32_t channel);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Array to map INTMUX instance number to base pointer. */
|
||||
static INTMUX_Type *const s_intmuxBases[] = INTMUX_BASE_PTRS;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Array to map INTMUX instance number to clock name. */
|
||||
static const clock_ip_name_t s_intmuxClockName[] = INTMUX_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
#if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
|
||||
/*! @brief Array to map INTMUX instance number to IRQ number. */
|
||||
static const IRQn_Type s_intmuxIRQNumber[][FSL_FEATURE_INTMUX_CHANNEL_COUNT] = INTMUX_IRQS;
|
||||
#endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t INTMUX_GetInstance(INTMUX_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_intmuxBases); instance++)
|
||||
{
|
||||
if (s_intmuxBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_intmuxBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
#if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
|
||||
static void INTMUX_CommonIRQHandler(INTMUX_Type *intmuxBase, uint32_t channel)
|
||||
{
|
||||
uint32_t pendingIrqOffset;
|
||||
|
||||
pendingIrqOffset = intmuxBase->CHANNEL[channel].CHn_VEC;
|
||||
|
||||
if (pendingIrqOffset)
|
||||
{
|
||||
#if defined(__riscv)
|
||||
extern uint32_t __user_vector[];
|
||||
uint32_t isr = __user_vector[pendingIrqOffset / 4 - 48 + 32];
|
||||
#else
|
||||
uint32_t isr = *(uint32_t *)(SCB->VTOR + pendingIrqOffset);
|
||||
#endif
|
||||
((void (*)(void))isr)();
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
|
||||
|
||||
void INTMUX_Init(INTMUX_Type *base)
|
||||
{
|
||||
uint32_t channel;
|
||||
uint32_t instance = INTMUX_GetInstance(base);
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Enable clock gate. */
|
||||
CLOCK_EnableClock(s_intmuxClockName[instance]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
/* Reset all channels and enable NVIC vectors for all INTMUX channels. */
|
||||
for (channel = 0; channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
INTMUX_ResetChannel(base, channel);
|
||||
#if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
|
||||
EnableIRQ(s_intmuxIRQNumber[instance][channel]);
|
||||
#endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
|
||||
}
|
||||
}
|
||||
|
||||
void INTMUX_Deinit(INTMUX_Type *base)
|
||||
{
|
||||
uint32_t channel;
|
||||
uint32_t instance = INTMUX_GetInstance(base);
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Disable clock gate. */
|
||||
CLOCK_DisableClock(s_intmuxClockName[instance]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
/* Disable NVIC vectors for all of the INTMUX channels. */
|
||||
for (channel = 0; channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
#if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
|
||||
DisableIRQ(s_intmuxIRQNumber[instance][channel]);
|
||||
#endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
|
||||
}
|
||||
}
|
||||
|
||||
#if !(defined(FSL_FEATURE_INTMUX_DIRECTION_OUT) && FSL_FEATURE_INTMUX_DIRECTION_OUT)
|
||||
#if defined(INTMUX0)
|
||||
void INTMUX0_0_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 0);
|
||||
}
|
||||
|
||||
void INTMUX0_1_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 1);
|
||||
}
|
||||
|
||||
void INTMUX0_2_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 2);
|
||||
}
|
||||
|
||||
void INTMUX0_3_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 3);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_INTMUX_CHANNEL_COUNT) && (FSL_FEATURE_INTMUX_CHANNEL_COUNT > 4U)
|
||||
void INTMUX0_4_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 4);
|
||||
}
|
||||
|
||||
void INTMUX0_5_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 5);
|
||||
}
|
||||
|
||||
void INTMUX0_6_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 6);
|
||||
}
|
||||
|
||||
void INTMUX0_7_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX0, 7);
|
||||
}
|
||||
#endif /* FSL_FEATURE_INTMUX_CHANNEL_COUNT */
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(INTMUX1)
|
||||
void INTMUX1_0_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 0);
|
||||
}
|
||||
|
||||
void INTMUX1_1_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 1);
|
||||
}
|
||||
|
||||
void INTMUX1_2_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 2);
|
||||
}
|
||||
|
||||
void INTMUX1_3_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 3);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_INTMUX_CHANNEL_COUNT) && (FSL_FEATURE_INTMUX_CHANNEL_COUNT > 4U)
|
||||
void INTMUX1_4_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 4);
|
||||
}
|
||||
|
||||
void INTMUX1_5_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 5);
|
||||
}
|
||||
|
||||
void INTMUX1_6_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 6);
|
||||
}
|
||||
|
||||
void INTMUX1_7_DriverIRQHandler(void)
|
||||
{
|
||||
INTMUX_CommonIRQHandler(INTMUX1, 7);
|
||||
}
|
||||
#endif /* FSL_FEATURE_INTMUX_CHANNEL_COUNT */
|
||||
#endif /* INTMUX1 */
|
||||
#endif /* FSL_FEATURE_INTMUX_DIRECTION_OUT */
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_INTMUX_H_
|
||||
#define _FSL_INTMUX_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup intmux
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*!< Version 2.0.1. */
|
||||
#define FSL_INTMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*! @brief INTMUX channel logic mode. */
|
||||
typedef enum _intmux_channel_logic_mode
|
||||
{
|
||||
kINTMUX_ChannelLogicOR = 0x0U, /*!< Logic OR all enabled interrupt inputs */
|
||||
kINTMUX_ChannelLogicAND, /*!< Logic AND all enabled interrupt inputs */
|
||||
} intmux_channel_logic_mode_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! @name Initialization and deinitialization */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the INTMUX module.
|
||||
*
|
||||
* This function enables the clock gate for the specified INTMUX. It then resets all channels, so that no
|
||||
* interrupt sources are routed and the logic mode is set to default of #kINTMUX_ChannelLogicOR.
|
||||
* Finally, the NVIC vectors for all the INTMUX output channels are enabled.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
*/
|
||||
void INTMUX_Init(INTMUX_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes an INTMUX instance for operation.
|
||||
*
|
||||
* The clock gate for the specified INTMUX is disabled and the NVIC vectors for all channels are disabled.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
*/
|
||||
void INTMUX_Deinit(INTMUX_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Resets an INTMUX channel.
|
||||
*
|
||||
* Sets all register values in the specified channel to their reset value. This function disables all interrupt
|
||||
* sources for the channel.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
* @param channel The INTMUX channel number.
|
||||
*/
|
||||
static inline void INTMUX_ResetChannel(INTMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT);
|
||||
|
||||
base->CHANNEL[channel].CHn_CSR |= INTMUX_CHn_CSR_RST_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets the logic mode for an INTMUX channel.
|
||||
*
|
||||
* INTMUX channels can be configured to use one of the two logic modes that control how pending interrupt sources
|
||||
* on the channel trigger the output interrupt.
|
||||
* - #kINTMUX_ChannelLogicOR means any source pending triggers the output interrupt.
|
||||
* - #kINTMUX_ChannelLogicAND means all selected sources on the channel must be pending before the channel
|
||||
* output interrupt triggers.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
* @param channel The INTMUX channel number.
|
||||
* @param logic The INTMUX channel logic mode.
|
||||
*/
|
||||
static inline void INTMUX_SetChannelMode(INTMUX_Type *base, uint32_t channel, intmux_channel_logic_mode_t logic)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT);
|
||||
|
||||
base->CHANNEL[channel].CHn_CSR = INTMUX_CHn_CSR_AND(logic);
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
/*! @name Sources */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Enables an interrupt source on an INTMUX channel.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
* @param channel Index of the INTMUX channel on which the specified interrupt is enabled.
|
||||
* @param irq Interrupt to route to the specified INTMUX channel. The interrupt must be an INTMUX source.
|
||||
*/
|
||||
static inline void INTMUX_EnableInterrupt(INTMUX_Type *base, uint32_t channel, IRQn_Type irq)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT);
|
||||
assert(irq >= FSL_FEATURE_INTMUX_IRQ_START_INDEX);
|
||||
|
||||
base->CHANNEL[channel].CHn_IER_31_0 |= (1U << ((uint32_t)irq - FSL_FEATURE_INTMUX_IRQ_START_INDEX));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables an interrupt source on an INTMUX channel.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
* @param channel Index of the INTMUX channel on which the specified interrupt is disabled.
|
||||
* @param irq Interrupt number. The interrupt must be an INTMUX source.
|
||||
*/
|
||||
static inline void INTMUX_DisableInterrupt(INTMUX_Type *base, uint32_t channel, IRQn_Type irq)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT);
|
||||
assert(irq >= FSL_FEATURE_INTMUX_IRQ_START_INDEX);
|
||||
|
||||
base->CHANNEL[channel].CHn_IER_31_0 &= ~(1U << ((uint32_t)irq - FSL_FEATURE_INTMUX_IRQ_START_INDEX));
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
/*! @name Status */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Gets INTMUX pending interrupt sources for a specific channel.
|
||||
*
|
||||
* @param base INTMUX peripheral base address.
|
||||
* @param channel The INTMUX channel number.
|
||||
* @return The mask of pending interrupt bits. Bit[n] set means INTMUX source n is pending.
|
||||
*/
|
||||
static inline uint32_t INTMUX_GetChannelPendingSources(INTMUX_Type *base, uint32_t channel)
|
||||
{
|
||||
assert(channel < FSL_FEATURE_INTMUX_CHANNEL_COUNT);
|
||||
|
||||
return base->CHANNEL[channel].CHn_IPR_31_0;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_INTMUX_H_ */
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_llwu.h"
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN)
|
||||
void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
volatile uint32_t *regBase;
|
||||
uint32_t regOffset;
|
||||
uint32_t reg;
|
||||
|
||||
switch (pinIndex >> 4U)
|
||||
{
|
||||
case 0U:
|
||||
regBase = &base->PE1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 1U:
|
||||
regBase = &base->PE2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
uint8_t regOffset;
|
||||
uint8_t reg;
|
||||
switch (pinIndex >> 2U)
|
||||
{
|
||||
case 0U:
|
||||
regBase = &base->PE1;
|
||||
break;
|
||||
case 1U:
|
||||
regBase = &base->PE2;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 2U:
|
||||
regBase = &base->PE3;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 12))
|
||||
case 3U:
|
||||
regBase = &base->PE4;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 4U:
|
||||
regBase = &base->PE5;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 20))
|
||||
case 5U:
|
||||
regBase = &base->PE6;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 6U:
|
||||
regBase = &base->PE7;
|
||||
break;
|
||||
#endif
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 28))
|
||||
case 7U:
|
||||
regBase = &base->PE8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH == 32 */
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
reg = *regBase;
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
regOffset = ((pinIndex & 0x0FU) << 1U);
|
||||
#else
|
||||
regOffset = ((pinIndex & 0x03U) << 1U);
|
||||
#endif
|
||||
reg &= ~(0x3U << regOffset);
|
||||
reg |= ((uint32_t)pinMode << regOffset);
|
||||
*regBase = reg;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
return (bool)(base->PF & (1U << pinIndex));
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
|
||||
switch (pinIndex >> 3U)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
case 0U:
|
||||
regBase = &base->PF1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->PF2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->PF3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->PF4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#else
|
||||
case 0U:
|
||||
regBase = &base->F1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->F2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->F3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->F4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PF */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
return (bool)(*regBase & (1U << pinIndex % 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
|
||||
void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
base->PF = (1U << pinIndex);
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
switch (pinIndex >> 3U)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
case 0U:
|
||||
regBase = &base->PF1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->PF2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->PF3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->PF4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#else
|
||||
case 0U:
|
||||
regBase = &base->F1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 8))
|
||||
case 1U:
|
||||
regBase = &base->F2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16))
|
||||
case 2U:
|
||||
regBase = &base->F3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 24))
|
||||
case 3U:
|
||||
regBase = &base->F4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PF */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
if (regBase)
|
||||
{
|
||||
*regBase = (1U << pinIndex % 8U);
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
|
||||
void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
base->FILT = ((base->FILT) & ~((LLWU_FILT_FILTSEL1_MASK | LLWU_FILT_FILTE1_MASK) << ((filterIndex - 1U) * 8U))) |
|
||||
((LLWU_FILT_FILTSEL1(filterMode.pinIndex) | LLWU_FILT_FILTE1(filterMode.filterMode))
|
||||
<< ((filterIndex - 1U) * 8U)) |
|
||||
LLWU_FILT_FILTF1_MASK /* W1C to clear the FILTF flag bit. */
|
||||
;
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1U:
|
||||
regBase = &base->FILT1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2U:
|
||||
regBase = &base->FILT2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3U:
|
||||
regBase = &base->FILT3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4U:
|
||||
regBase = &base->FILT4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL != regBase)
|
||||
{
|
||||
*regBase = (*regBase & ~(LLWU_FILT1_FILTSEL_MASK | LLWU_FILT1_FILTE_MASK)) |
|
||||
LLWU_FILT1_FILTSEL(filterMode.pinIndex) | LLWU_FILT1_FILTE(filterMode.filterMode) |
|
||||
LLWU_FILT1_FILTF_MASK /* W1C to clear the FILTF flag bit. */
|
||||
;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
|
||||
bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
return (bool)(base->FILT & (1U << (filterIndex * 8U - 1)));
|
||||
#else
|
||||
bool status = false;
|
||||
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
status = (base->FILT1 & LLWU_FILT1_FILTF_MASK);
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2:
|
||||
status = (base->FILT2 & LLWU_FILT2_FILTF_MASK);
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3:
|
||||
status = (base->FILT3 & LLWU_FILT3_FILTF_MASK);
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4:
|
||||
status = (base->FILT4 & LLWU_FILT4_FILTF_MASK);
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
|
||||
void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex)
|
||||
{
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32))
|
||||
uint32_t reg;
|
||||
|
||||
reg = base->FILT;
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
reg |= LLWU_FILT_FILTF1_MASK;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2:
|
||||
reg |= LLWU_FILT_FILTF2_MASK;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1 */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3:
|
||||
reg |= LLWU_FILT_FILTF3_MASK;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2 */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4:
|
||||
reg |= LLWU_FILT_FILTF4_MASK;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3 */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
base->FILT = reg;
|
||||
#else
|
||||
volatile uint8_t *regBase;
|
||||
uint8_t reg;
|
||||
|
||||
switch (filterIndex)
|
||||
{
|
||||
case 1:
|
||||
regBase = &base->FILT1;
|
||||
break;
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 1))
|
||||
case 2:
|
||||
regBase = &base->FILT2;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 2))
|
||||
case 3:
|
||||
regBase = &base->FILT3;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && (FSL_FEATURE_LLWU_HAS_PIN_FILTER > 3))
|
||||
case 4:
|
||||
regBase = &base->FILT4;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
default:
|
||||
regBase = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regBase)
|
||||
{
|
||||
reg = *regBase;
|
||||
reg |= LLWU_FILT1_FILTF_MASK;
|
||||
*regBase = reg;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE)
|
||||
void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
reg = base->RST;
|
||||
reg &= ~(LLWU_RST_LLRSTE_MASK | LLWU_RST_RSTFILT_MASK);
|
||||
reg |=
|
||||
(((uint32_t)pinEnable << LLWU_RST_LLRSTE_SHIFT) | ((uint32_t)enableInLowLeakageMode << LLWU_RST_RSTFILT_SHIFT));
|
||||
base->RST = reg;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_LLWU_H_
|
||||
#define _FSL_LLWU_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*! @addtogroup llwu */
|
||||
/*! @{ */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief LLWU driver version 2.0.1. */
|
||||
#define FSL_LLWU_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief External input pin control modes
|
||||
*/
|
||||
typedef enum _llwu_external_pin_mode
|
||||
{
|
||||
kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as a wakeup input. */
|
||||
kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with the rising edge detection. */
|
||||
kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with the falling edge detection.*/
|
||||
kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */
|
||||
} llwu_external_pin_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief Digital filter control modes
|
||||
*/
|
||||
typedef enum _llwu_pin_filter_mode
|
||||
{
|
||||
kLLWU_PinFilterDisable = 0U, /*!< Filter disabled. */
|
||||
kLLWU_PinFilterRisingEdge = 1U, /*!< Filter positive edge detection.*/
|
||||
kLLWU_PinFilterFallingEdge = 2U, /*!< Filter negative edge detection.*/
|
||||
kLLWU_PinFilterAnyEdge = 3U /*!< Filter any edge detection. */
|
||||
} llwu_pin_filter_mode_t;
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID)
|
||||
/*!
|
||||
* @brief IP version ID definition.
|
||||
*/
|
||||
typedef struct _llwu_version_id
|
||||
{
|
||||
uint16_t feature; /*!< A feature specification number. */
|
||||
uint8_t minor; /*!< The minor version number. */
|
||||
uint8_t major; /*!< The major version number. */
|
||||
} llwu_version_id_t;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_VERID */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM)
|
||||
/*!
|
||||
* @brief IP parameter definition.
|
||||
*/
|
||||
typedef struct _llwu_param
|
||||
{
|
||||
uint8_t filters; /*!< A number of the pin filter. */
|
||||
uint8_t dmas; /*!< A number of the wakeup DMA. */
|
||||
uint8_t modules; /*!< A number of the wakeup module. */
|
||||
uint8_t pins; /*!< A number of the wake up pin. */
|
||||
} llwu_param_t;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PARAM */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
|
||||
/*!
|
||||
* @brief An external input pin filter control structure
|
||||
*/
|
||||
typedef struct _llwu_external_pin_filter_mode
|
||||
{
|
||||
uint32_t pinIndex; /*!< A pin number */
|
||||
llwu_pin_filter_mode_t filterMode; /*!< Filter mode */
|
||||
} llwu_external_pin_filter_mode_t;
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Low-Leakage Wakeup Unit Control APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_VERID) && FSL_FEATURE_LLWU_HAS_VERID)
|
||||
/*!
|
||||
* @brief Gets the LLWU version ID.
|
||||
*
|
||||
* This function gets the LLWU version ID, including the major version number,
|
||||
* the minor version number, and the feature specification number.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param versionId A pointer to the version ID structure.
|
||||
*/
|
||||
static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId)
|
||||
{
|
||||
*((uint32_t *)versionId) = base->VERID;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_VERID */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PARAM) && FSL_FEATURE_LLWU_HAS_PARAM)
|
||||
/*!
|
||||
* @brief Gets the LLWU parameter.
|
||||
*
|
||||
* This function gets the LLWU parameter, including a wakeup pin number, a module
|
||||
* number, a DMA number, and a pin filter number.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param param A pointer to the LLWU parameter structure.
|
||||
*/
|
||||
static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param)
|
||||
{
|
||||
*((uint32_t *)param) = base->PARAM;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PARAM */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN)
|
||||
/*!
|
||||
* @brief Sets the external input pin source mode.
|
||||
*
|
||||
* This function sets the external input pin source mode that is used
|
||||
* as a wake up source.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param pinIndex A pin index to be enabled as an external wakeup source starting from 1.
|
||||
* @param pinMode A pin configuration mode defined in the llwu_external_pin_modes_t.
|
||||
*/
|
||||
void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode);
|
||||
|
||||
/*!
|
||||
* @brief Gets the external wakeup source flag.
|
||||
*
|
||||
* This function checks the external pin flag to detect whether the MCU is
|
||||
* woken up by the specific pin.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param pinIndex A pin index, which starts from 1.
|
||||
* @return True if the specific pin is a wakeup source.
|
||||
*/
|
||||
bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
|
||||
|
||||
/*!
|
||||
* @brief Clears the external wakeup source flag.
|
||||
*
|
||||
* This function clears the external wakeup source flag for a specific pin.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param pinIndex A pin index, which starts from 1.
|
||||
*/
|
||||
void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex);
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE) && FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE)
|
||||
/*!
|
||||
* @brief Enables/disables the internal module source.
|
||||
*
|
||||
* This function enables/disables the internal module source mode that is used
|
||||
* as a wake up source.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param moduleIndex A module index to be enabled as an internal wakeup source starting from 1.
|
||||
* @param enable An enable or a disable setting
|
||||
*/
|
||||
static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->ME |= 1U << moduleIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->ME &= ~(1U << moduleIndex);
|
||||
}
|
||||
}
|
||||
|
||||
#if (!(defined(FSL_FEATURE_LLWU_HAS_NO_INTERNAL_MODULE_WAKEUP_FLAG_REG) && \
|
||||
FSL_FEATURE_LLWU_HAS_NO_INTERNAL_MODULE_WAKEUP_FLAG_REG))
|
||||
/* Re-define the register which includes the internal wakeup module flag. */
|
||||
#if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) /* 32-bit LLWU. */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_MF) && FSL_FEATURE_LLWU_HAS_MF)
|
||||
#define INTERNAL_WAKEUP_MODULE_FLAG_REG MF
|
||||
#else
|
||||
#error "Unsupported internal module flag register."
|
||||
#endif
|
||||
#else /* 8-bit LLUW. */
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_MF) && FSL_FEATURE_LLWU_HAS_MF)
|
||||
#define INTERNAL_WAKEUP_MODULE_FLAG_REG MF5
|
||||
#elif(defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF)
|
||||
#define INTERNAL_WAKEUP_MODULE_FLAG_REG PF3
|
||||
#elif(!(defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)))
|
||||
#define INTERNAL_WAKEUP_MODULE_FLAG_REG F3
|
||||
#else
|
||||
#error "Unsupported internal module flag register."
|
||||
#endif
|
||||
#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */
|
||||
|
||||
/*!
|
||||
* @brief Gets the external wakeup source flag.
|
||||
*
|
||||
* This function checks the external pin flag to detect whether the system is
|
||||
* woken up by the specific pin.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param moduleIndex A module index, which starts from 1.
|
||||
* @return True if the specific pin is a wake up source.
|
||||
*/
|
||||
static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex)
|
||||
{
|
||||
return ((1U << moduleIndex) == (base->INTERNAL_WAKEUP_MODULE_FLAG_REG & (1U << moduleIndex)));
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_NO_INTERNAL_MODULE_WAKEUP_FLAG_REG */
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG) && FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG)
|
||||
/*!
|
||||
* @brief Enables/disables the internal module DMA wakeup source.
|
||||
*
|
||||
* This function enables/disables the internal DMA that is used as a wake up source.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param moduleIndex An internal module index which is used as a DMA request source, starting from 1.
|
||||
* @param enable Enable or disable the DMA request source
|
||||
*/
|
||||
static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->DE |= 1U << moduleIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->DE &= ~(1U << moduleIndex);
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER)
|
||||
/*!
|
||||
* @brief Sets the pin filter configuration.
|
||||
*
|
||||
* This function sets the pin filter configuration.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param filterIndex A pin filter index used to enable/disable the digital filter, starting from 1.
|
||||
* @param filterMode A filter mode configuration
|
||||
*/
|
||||
void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode);
|
||||
|
||||
/*!
|
||||
* @brief Gets the pin filter configuration.
|
||||
*
|
||||
* This function gets the pin filter flag.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param filterIndex A pin filter index, which starts from 1.
|
||||
* @return True if the flag is a source of the existing low-leakage power mode.
|
||||
*/
|
||||
bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
|
||||
|
||||
/*!
|
||||
* @brief Clears the pin filter configuration.
|
||||
*
|
||||
* This function clears the pin filter flag.
|
||||
*
|
||||
* @param base LLWU peripheral base address.
|
||||
* @param filterIndex A pin filter index to clear the flag, starting from 1.
|
||||
*/
|
||||
void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex);
|
||||
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */
|
||||
|
||||
#if (defined(FSL_FEATURE_LLWU_HAS_RESET_ENABLE) && FSL_FEATURE_LLWU_HAS_RESET_ENABLE)
|
||||
/*!
|
||||
* @brief Sets the reset pin mode.
|
||||
*
|
||||
* This function determines how the reset pin is used as a low leakage mode exit source.
|
||||
*
|
||||
* @param pinEnable Enable reset the pin filter
|
||||
* @param pinFilterEnable Specify whether the pin filter is enabled in Low-Leakage power mode.
|
||||
*/
|
||||
void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode);
|
||||
#endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
#endif /* _FSL_LLWU_H_*/
|
||||
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_lpadc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Get instance number for LPADC module.
|
||||
*
|
||||
* @param base LPADC peripheral base address
|
||||
*/
|
||||
static uint32_t LPADC_GetInstance(ADC_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
/*! @brief Pointers to LPADC bases for each instance. */
|
||||
static ADC_Type *const s_lpadcBases[] = ADC_BASE_PTRS;
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Pointers to LPADC clocks for each instance. */
|
||||
static const clock_ip_name_t s_lpadcClocks[] = LPADC_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint32_t LPADC_GetInstance(ADC_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_lpadcBases); instance++)
|
||||
{
|
||||
if (s_lpadcBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_lpadcBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void LPADC_Init(ADC_Type *base, const lpadc_config_t *config)
|
||||
{
|
||||
/* Check if the pointer is available. */
|
||||
assert(config != NULL);
|
||||
|
||||
uint32_t tmp32 = 0U;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Enable the clock for LPADC instance. */
|
||||
CLOCK_EnableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/* Reset the module. */
|
||||
LPADC_DoResetConfig(base);
|
||||
LPADC_DoResetFIFO(base);
|
||||
|
||||
/* Disable the module before setting configuration. */
|
||||
LPADC_Enable(base, false);
|
||||
|
||||
/* Configure the module generally. */
|
||||
if (config->enableInDozeMode)
|
||||
{
|
||||
base->CTRL &= ~ADC_CTRL_DOZEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CTRL |= ADC_CTRL_DOZEN_MASK;
|
||||
}
|
||||
|
||||
/* ADCx_CFG. */
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
|
||||
if (config->enableInternalClock)
|
||||
{
|
||||
tmp32 |= ADC_CFG_ADCKEN_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
|
||||
if (config->enableVref1LowVoltage)
|
||||
{
|
||||
tmp32 |= ADC_CFG_VREF1RNG_MASK;
|
||||
}
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
|
||||
if (config->enableAnalogPreliminary)
|
||||
{
|
||||
tmp32 |= ADC_CFG_PWREN_MASK;
|
||||
}
|
||||
tmp32 |= ADC_CFG_PUDLY(config->powerUpDelay) /* Power up delay. */
|
||||
| ADC_CFG_REFSEL(config->referenceVoltageSource) /* Reference voltage. */
|
||||
| ADC_CFG_TPRICTRL(config->triggerPrioirtyPolicy); /* Trigger priority policy. */
|
||||
base->CFG = tmp32;
|
||||
|
||||
/* ADCx_PAUSE. */
|
||||
if (config->enableConvPause)
|
||||
{
|
||||
base->PAUSE = ADC_PAUSE_PAUSEEN_MASK | ADC_PAUSE_PAUSEDLY(config->convPauseDelay);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->PAUSE = 0U;
|
||||
}
|
||||
|
||||
/* ADCx_FCTRL. */
|
||||
base->FCTRL = ADC_FCTRL_FWMARK(config->FIFOWatermark);
|
||||
|
||||
/* Enable the module after setting configuration. */
|
||||
LPADC_Enable(base, true);
|
||||
}
|
||||
|
||||
void LPADC_GetDefaultConfig(lpadc_config_t *config)
|
||||
{
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
|
||||
config->enableInternalClock = false;
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
|
||||
config->enableVref1LowVoltage = false;
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
|
||||
config->enableInDozeMode = true;
|
||||
config->enableAnalogPreliminary = false;
|
||||
config->powerUpDelay = 0x80;
|
||||
config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
|
||||
config->powerLevelMode = kLPADC_PowerLevelAlt1;
|
||||
config->triggerPrioirtyPolicy = kLPADC_TriggerPriorityPreemptImmediately;
|
||||
config->enableConvPause = false;
|
||||
config->convPauseDelay = 0U;
|
||||
config->FIFOWatermark = 0U;
|
||||
}
|
||||
|
||||
void LPADC_Deinit(ADC_Type *base)
|
||||
{
|
||||
/* Disable the module. */
|
||||
LPADC_Enable(base, false);
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Gate the clock. */
|
||||
CLOCK_DisableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
}
|
||||
|
||||
bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result)
|
||||
{
|
||||
assert(result != NULL); /* Check if the input pointer is available. */
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
tmp32 = base->RESFIFO;
|
||||
|
||||
if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
|
||||
{
|
||||
return false; /* FIFO is empty. Discard any read from RESFIFO. */
|
||||
}
|
||||
|
||||
result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
|
||||
result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
|
||||
result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
|
||||
result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LPADC_SetConvTriggerConfig(ADC_Type *base, uint32_t triggerId, const lpadc_conv_trigger_config_t *config)
|
||||
{
|
||||
assert(triggerId < ADC_TCTRL_COUNT); /* Check if the triggerId is available in this device. */
|
||||
assert(config != NULL); /* Check if the input pointer is available. */
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
tmp32 = ADC_TCTRL_TCMD(config->targetCommandId) /* Trigger command select. */
|
||||
| ADC_TCTRL_TDLY(config->delayPower) /* Trigger delay select. */
|
||||
| ADC_TCTRL_TPRI(config->priority); /* Trigger priority setting. */
|
||||
if (config->enableHardwareTrigger)
|
||||
{
|
||||
tmp32 |= ADC_TCTRL_HTEN_MASK;
|
||||
}
|
||||
|
||||
base->TCTRL[triggerId] = tmp32;
|
||||
}
|
||||
|
||||
void LPADC_GetDefaultConvTriggerConfig(lpadc_conv_trigger_config_t *config)
|
||||
{
|
||||
assert(config != NULL); /* Check if the input pointer is available. */
|
||||
|
||||
config->targetCommandId = 0U;
|
||||
config->delayPower = 0U;
|
||||
config->priority = 0U;
|
||||
config->enableHardwareTrigger = false;
|
||||
}
|
||||
|
||||
void LPADC_SetConvCommandConfig(ADC_Type *base, uint32_t commandId, const lpadc_conv_command_config_t *config)
|
||||
{
|
||||
assert(commandId < (ADC_CMDL_COUNT + 1U)); /* Check if the commandId is available on this device. */
|
||||
assert(config != NULL); /* Check if the input pointer is available. */
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
commandId--; /* The available command number are 1-15, while the index of register group are 0-14. */
|
||||
|
||||
/* ADCx_CMDL. */
|
||||
tmp32 = ADC_CMDL_ADCH(config->channelNumber); /* Channel number. */
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
|
||||
tmp32 |= ADC_CMDL_CSCALE(config->sampleScaleMode); /* Full/Part scale input voltage. */
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
|
||||
switch (config->sampleChannelMode) /* Sample input. */
|
||||
{
|
||||
case kLPADC_SampleChannelSingleEndSideB:
|
||||
tmp32 |= ADC_CMDL_ABSEL_MASK;
|
||||
break;
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
|
||||
case kLPADC_SampleChannelDiffBothSideAB:
|
||||
tmp32 |= ADC_CMDL_DIFF_MASK;
|
||||
break;
|
||||
case kLPADC_SampleChannelDiffBothSideBA:
|
||||
tmp32 |= ADC_CMDL_ABSEL_MASK | ADC_CMDL_DIFF_MASK;
|
||||
break;
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_DIFF */
|
||||
default: /* kLPADC_SampleChannelSingleEndSideA. */
|
||||
break;
|
||||
}
|
||||
base->CMD[commandId].CMDL = tmp32;
|
||||
|
||||
/* ADCx_CMDH. */
|
||||
tmp32 = ADC_CMDH_NEXT(config->chainedNextCommandNumber) /* Next Command Select. */
|
||||
| ADC_CMDH_LOOP(config->loopCount) /* Loop Count Select. */
|
||||
| ADC_CMDH_AVGS(config->hardwareAverageMode) /* Hardware Average Select. */
|
||||
| ADC_CMDH_STS(config->sampleTimeMode) /* Sample Time Select. */
|
||||
| ADC_CMDH_CMPEN(config->hardwareCompareMode); /* Hardware compare enable. */
|
||||
if (config->enableAutoChannelIncrement)
|
||||
{
|
||||
tmp32 |= ADC_CMDH_LWI_MASK;
|
||||
}
|
||||
base->CMD[commandId].CMDH = tmp32;
|
||||
|
||||
/* Hardware compare settings.
|
||||
* Not all Command Buffers have an associated Compare Value register. The compare function is only available on
|
||||
* Command Buffers that have a corresponding Compare Value register.
|
||||
*/
|
||||
if (kLPADC_HardwareCompareDisabled != config->hardwareCompareMode)
|
||||
{
|
||||
/* Check if the hardware compare feature is available for indicated command buffer. */
|
||||
assert(commandId < ADC_CV_COUNT);
|
||||
|
||||
/* Set CV register. */
|
||||
base->CV[commandId] = ADC_CV_CVH(config->hardwareCompareValueHigh) /* Compare value high. */
|
||||
| ADC_CV_CVL(config->hardwareCompareValueLow); /* Compare value low. */
|
||||
}
|
||||
}
|
||||
|
||||
void LPADC_GetDefaultConvCommandConfig(lpadc_conv_command_config_t *config)
|
||||
{
|
||||
assert(config != NULL); /* Check if the input pointer is available. */
|
||||
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
|
||||
config->sampleScaleMode = kLPADC_SampleFullScale;
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
|
||||
config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
|
||||
config->channelNumber = 0U;
|
||||
config->chainedNextCommandNumber = 0U; /* No next command defined. */
|
||||
config->enableAutoChannelIncrement = false;
|
||||
config->loopCount = 0U;
|
||||
config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
|
||||
config->sampleTimeMode = kLPADC_SampleTimeADCK3;
|
||||
config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
|
||||
config->hardwareCompareValueHigh = 0U; /* No used. */
|
||||
config->hardwareCompareValueLow = 0U; /* No used. */
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS
|
||||
void LPADC_EnableCalibration(ADC_Type *base, bool enable)
|
||||
{
|
||||
LPADC_Enable(base, false);
|
||||
if (enable)
|
||||
{
|
||||
base->CFG |= ADC_CFG_CALOFS_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CFG &= ~ADC_CFG_CALOFS_MASK;
|
||||
}
|
||||
LPADC_Enable(base, true);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
|
||||
void LPADC_DoAutoCalibration(ADC_Type *base)
|
||||
{
|
||||
assert(0u == LPADC_GetConvResultCount(base));
|
||||
|
||||
uint32_t mLpadcCMDL;
|
||||
uint32_t mLpadcCMDH;
|
||||
uint32_t mLpadcTrigger;
|
||||
lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
|
||||
lpadc_conv_command_config_t mLpadcCommandConfigStruct;
|
||||
lpadc_conv_result_t mLpadcResultConfigStruct;
|
||||
|
||||
/* Enable the calibration function. */
|
||||
LPADC_EnableCalibration(base, true);
|
||||
|
||||
/* Keep the CMD and TRG state here and restore it later if the calibration completes.*/
|
||||
mLpadcCMDL = base->CMD[0].CMDL; /* CMD1L. */
|
||||
mLpadcCMDH = base->CMD[0].CMDH; /* CMD1H. */
|
||||
mLpadcTrigger = base->TCTRL[0]; /* Trigger0. */
|
||||
|
||||
/* Set trigger0 configuration - for software trigger. */
|
||||
LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
|
||||
mLpadcTriggerConfigStruct.targetCommandId = 1U; /* CMD1 is executed. */
|
||||
LPADC_SetConvTriggerConfig(base, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
|
||||
|
||||
/* Set conversion CMD configuration. */
|
||||
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
|
||||
mLpadcCommandConfigStruct.hardwareAverageMode = kLPADC_HardwareAverageCount128;
|
||||
LPADC_SetConvCommandConfig(base, 1U, &mLpadcCommandConfigStruct); /* Set CMD1 configuration. */
|
||||
|
||||
/* Do calibration. */
|
||||
LPADC_DoSoftwareTrigger(base, 1U); /* 1U is trigger0 mask. */
|
||||
while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
|
||||
{
|
||||
}
|
||||
/* The valid bits of data are bits 14:3 in the RESFIFO register. */
|
||||
LPADC_SetOffsetValue(base, (mLpadcResultConfigStruct.convValue) >> 3U);
|
||||
/* Disable the calibration function. */
|
||||
LPADC_EnableCalibration(base, false);
|
||||
|
||||
/* restore CMD and TRG registers. */
|
||||
base->CMD[0].CMDL = mLpadcCMDL; /* CMD1L. */
|
||||
base->CMD[0].CMDH = mLpadcCMDH; /* CMD1H. */
|
||||
base->TCTRL[0] = mLpadcTrigger; /* Trigger0. */
|
||||
}
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
|
||||
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_lpcmp.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
#if defined(LPCMP_CLOCKS)
|
||||
/*!
|
||||
* @brief Get instance number for LPCMP module.
|
||||
*
|
||||
* @param base LPCMP peripheral base address
|
||||
*/
|
||||
static uint32_t LPCMP_GetInstance(LPCMP_Type *base);
|
||||
#endif /* LPCMP_CLOCKS */
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
#if defined(LPCMP_CLOCKS)
|
||||
/*! @brief Pointers to LPCMP bases for each instance. */
|
||||
static LPCMP_Type *const s_lpcmpBases[] = LPCMP_BASE_PTRS;
|
||||
/*! @brief Pointers to LPCMP clocks for each instance. */
|
||||
static const clock_ip_name_t s_lpcmpClocks[] = LPCMP_CLOCKS;
|
||||
#endif /* LPCMP_CLOCKS */
|
||||
|
||||
/*******************************************************************************
|
||||
* Codes
|
||||
******************************************************************************/
|
||||
#if defined(LPCMP_CLOCKS)
|
||||
static uint32_t LPCMP_GetInstance(LPCMP_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_lpcmpBases); instance++)
|
||||
{
|
||||
if (s_lpcmpBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_lpcmpBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
#endif /* LPCMP_CLOCKS */
|
||||
|
||||
void LPCMP_Init(LPCMP_Type *base, const lpcmp_config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
#if defined(LPCMP_CLOCKS)
|
||||
/* Enable LPCMP clock. */
|
||||
CLOCK_EnableClock(s_lpcmpClocks[LPCMP_GetInstance(base)]);
|
||||
#endif /* LPCMP_CLOCKS */
|
||||
|
||||
/* Configure. */
|
||||
LPCMP_Enable(base, false);
|
||||
/* CCR0 register. */
|
||||
if (config->enableStopMode)
|
||||
{
|
||||
base->CCR0 |= LPCMP_CCR0_CMP_STOP_EN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CCR0 &= ~LPCMP_CCR0_CMP_STOP_EN_MASK;
|
||||
}
|
||||
/* CCR1 register. */
|
||||
tmp32 = base->CCR1 & ~(LPCMP_CCR1_COUT_PEN_MASK | LPCMP_CCR1_COUT_SEL_MASK | LPCMP_CCR1_COUT_INV_MASK);
|
||||
if (config->enableOutputPin)
|
||||
{
|
||||
tmp32 |= LPCMP_CCR1_COUT_PEN_MASK;
|
||||
}
|
||||
if (config->useUnfilteredOutput)
|
||||
{
|
||||
tmp32 |= LPCMP_CCR1_COUT_SEL_MASK;
|
||||
}
|
||||
if (config->enableInvertOutput)
|
||||
{
|
||||
tmp32 |= LPCMP_CCR1_COUT_INV_MASK;
|
||||
}
|
||||
base->CCR1 = tmp32;
|
||||
/* CCR2 register. */
|
||||
tmp32 = base->CCR2 & ~(LPCMP_CCR2_HYSTCTR_MASK | LPCMP_CCR2_CMP_NPMD_MASK | LPCMP_CCR2_CMP_HPMD_MASK);
|
||||
tmp32 |= LPCMP_CCR2_HYSTCTR(config->hysteresisMode);
|
||||
tmp32 |= ((uint32_t)(config->powerMode) << LPCMP_CCR2_CMP_HPMD_SHIFT);
|
||||
base->CCR2 = tmp32;
|
||||
|
||||
LPCMP_Enable(base, true); /* Enable the LPCMP module. */
|
||||
}
|
||||
|
||||
void LPCMP_Deinit(LPCMP_Type *base)
|
||||
{
|
||||
/* Disable the LPCMP module. */
|
||||
LPCMP_Enable(base, false);
|
||||
#if defined(LPCMP_CLOCKS)
|
||||
/* Disable the clock for LPCMP. */
|
||||
CLOCK_DisableClock(s_lpcmpClocks[LPCMP_GetInstance(base)]);
|
||||
#endif /* LPCMP_CLOCKS */
|
||||
}
|
||||
|
||||
void LPCMP_GetDefaultConfig(lpcmp_config_t *config)
|
||||
{
|
||||
config->enableStopMode = false;
|
||||
config->enableOutputPin = false;
|
||||
config->useUnfilteredOutput = false;
|
||||
config->enableInvertOutput = false;
|
||||
config->hysteresisMode = kLPCMP_HysteresisLevel0;
|
||||
config->powerMode = kLPCMP_LowSpeedPowerMode;
|
||||
}
|
||||
|
||||
void LPCMP_SetInputChannels(LPCMP_Type *base, uint32_t positiveChannel, uint32_t negativeChannel)
|
||||
{
|
||||
uint32_t tmp32;
|
||||
|
||||
tmp32 = base->CCR2 & ~(LPCMP_CCR2_PSEL_MASK | LPCMP_CCR2_MSEL_MASK);
|
||||
tmp32 |= LPCMP_CCR2_PSEL(positiveChannel) | LPCMP_CCR2_MSEL(negativeChannel);
|
||||
base->CCR2 = tmp32;
|
||||
}
|
||||
|
||||
void LPCMP_SetFilterConfig(LPCMP_Type *base, const lpcmp_filter_config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
|
||||
uint32_t tmp32;
|
||||
|
||||
tmp32 = base->CCR1 & ~(LPCMP_CCR1_FILT_PER_MASK | LPCMP_CCR1_FILT_CNT_MASK | LPCMP_CCR1_SAMPLE_EN_MASK);
|
||||
if (config->enableSample)
|
||||
{
|
||||
tmp32 |= LPCMP_CCR1_SAMPLE_EN_MASK;
|
||||
}
|
||||
tmp32 |= LPCMP_CCR1_FILT_PER(config->filterSamplePeriod) | LPCMP_CCR1_FILT_CNT(config->filterSampleCount);
|
||||
base->CCR1 = tmp32;
|
||||
}
|
||||
|
||||
void LPCMP_SetDACConfig(LPCMP_Type *base, const lpcmp_dac_config_t *config)
|
||||
{
|
||||
uint32_t tmp32;
|
||||
if (config == NULL)
|
||||
{
|
||||
tmp32 = 0U; /* Disable internal DAC. */
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp32 = LPCMP_DCR_VRSEL(config->referenceVoltageSource) | LPCMP_DCR_DAC_DATA(config->DACValue);
|
||||
if (config->enableLowPowerMode)
|
||||
{
|
||||
tmp32 |= LPCMP_DCR_DAC_HPMD_MASK;
|
||||
}
|
||||
tmp32 |= LPCMP_DCR_DAC_EN_MASK;
|
||||
}
|
||||
base->DCR = tmp32;
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_LPCMP_H_
|
||||
#define _FSL_LPCMP_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup lpcmp
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief LPCMP driver version 2.0.0. */
|
||||
#define FSL_LPCMP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @brief LPCMP status falgs mask.
|
||||
*/
|
||||
enum _lpcmp_status_flags
|
||||
{
|
||||
kLPCMP_OutputRisingEventFlag = LPCMP_CSR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */
|
||||
kLPCMP_OutputFallingEventFlag = LPCMP_CSR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */
|
||||
kLPCMP_OutputAssertEventFlag = LPCMP_CSR_COUT_MASK, /*!< Return the current value of the analog comparator output.
|
||||
The flag does not support W1C. */
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief LPCMP interrupt enable/disable mask.
|
||||
*/
|
||||
enum _lpcmp_interrupt_enable
|
||||
{
|
||||
kLPCMP_OutputRisingInterruptEnable = LPCMP_IER_CFR_IE_MASK, /*!< Comparator interrupt enable rising. */
|
||||
kLPCMP_OutputFallingInterruptEnable = LPCMP_IER_CFF_IE_MASK, /*!< Comparator interrupt enable falling. */
|
||||
};
|
||||
/*!
|
||||
* @brief LPCMP hysteresis mode. See chip data sheet to get the actual hystersis
|
||||
* value with each level
|
||||
*/
|
||||
typedef enum _lpcmp_hysteresis_mode
|
||||
{
|
||||
kLPCMP_HysteresisLevel0 = 0U, /*!< The hard block output has level 0 hysteresis internally. */
|
||||
kLPCMP_HysteresisLevel1 = 1U, /*!< The hard block output has level 1 hysteresis internally. */
|
||||
kLPCMP_HysteresisLevel2 = 2U, /*!< The hard block output has level 2 hysteresis internally. */
|
||||
kLPCMP_HysteresisLevel3 = 3U, /*!< The hard block output has level 3 hysteresis internally. */
|
||||
} lpcmp_hysteresis_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief LPCMP nano mode.
|
||||
*/
|
||||
typedef enum _lpcmp_power_mode
|
||||
{
|
||||
kLPCMP_LowSpeedPowerMode = 0U, /*!< Low speed comparison mode is selected. */
|
||||
kLPCMP_HighSpeedPowerMode = 1U, /*!< High speed comparison mode is selected. */
|
||||
kLPCMP_NanoPowerMode = 2U, /*!< Nano power comparator is enabled. */
|
||||
} lpcmp_power_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief Internal DAC reference voltage source.
|
||||
*/
|
||||
typedef enum _lpcmp_dac_reference_voltage_source
|
||||
{
|
||||
kLPCMP_VrefSourceVin1 = 0U, /*!< vrefh_int is selected as resistor ladder network supply reference Vin. */
|
||||
kLPCMP_VrefSourceVin2 = 1U, /*!< vrefh_ext is selected as resistor ladder network supply reference Vin. */
|
||||
} lpcmp_dac_reference_voltage_source_t;
|
||||
|
||||
/*!
|
||||
* @brief Configure the filter.
|
||||
*/
|
||||
typedef struct _lpcmp_filter_config
|
||||
{
|
||||
bool enableSample; /*!< Decide whether to use the external SAMPLE as a sampling clock input. */
|
||||
uint8_t filterSampleCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter. */
|
||||
uint8_t filterSamplePeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. The
|
||||
sampling clock must be at least 4 times slower than the system clock to the comparator.
|
||||
So if enableSample is "false", filterSamplePeriod should be set greater than 4.*/
|
||||
} lpcmp_filter_config_t;
|
||||
|
||||
/*!
|
||||
* @brief configure the internal DAC.
|
||||
*/
|
||||
typedef struct _lpcmp_dac_config
|
||||
{
|
||||
bool enableLowPowerMode; /*!< Decide whether to enable DAC low power mode. */
|
||||
lpcmp_dac_reference_voltage_source_t referenceVoltageSource; /*!< Internal DAC supply voltage reference source. */
|
||||
uint8_t DACValue; /*!< Value for the DAC Output Voltage. Available range is 0-63.*/
|
||||
} lpcmp_dac_config_t;
|
||||
|
||||
/*!
|
||||
* @brief Configures the comparator.
|
||||
*/
|
||||
typedef struct _lpcmp_config
|
||||
{
|
||||
bool enableStopMode; /*!< Decide whether to enable the comparator when in STOP modes. */
|
||||
bool enableOutputPin; /*!< Decide whether to enable the comparator is available in selected pin. */
|
||||
bool useUnfilteredOutput; /*!< Decide whether to use unfiltered output. */
|
||||
bool enableInvertOutput; /*!< Decide whether to inverts the comparator output. */
|
||||
lpcmp_hysteresis_mode_t hysteresisMode; /*!< LPCMP hysteresis mode. */
|
||||
lpcmp_power_mode_t powerMode; /*!< LPCMP power mode. */
|
||||
} lpcmp_config_t;
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @name Initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initialize the LPCMP
|
||||
*
|
||||
* This function initializes the LPCMP module. The operations included are:
|
||||
* - Enabling the clock for LPCMP module.
|
||||
* - Configuring the comparator.
|
||||
* - Enabling the LPCMP module.
|
||||
* Note: For some devices, multiple LPCMP instance share the same clock gate. In this case, to enable the clock for
|
||||
* any instance enables all the LPCMPs. Check the chip reference manual for the clock assignment of the LPCMP.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param config Pointer to "lpcmp_config_t" structure.
|
||||
*/
|
||||
void LPCMP_Init(LPCMP_Type *base, const lpcmp_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the LPCMP module.
|
||||
*
|
||||
* This function de-initializes the LPCMP module. The operations included are:
|
||||
* - Disabling the LPCMP module.
|
||||
* - Disabling the clock for LPCMP module.
|
||||
*
|
||||
* This function disables the clock for the LPCMP.
|
||||
* Note: For some devices, multiple LPCMP instance shares the same clock gate. In this case, before disabling the
|
||||
* clock for the LPCMP, ensure that all the LPCMP instances are not used.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
*/
|
||||
void LPCMP_Deinit(LPCMP_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Gets an available pre-defined settings for the comparator's configuration.
|
||||
*
|
||||
* This function initializes the comparator configuration structure to these default values:
|
||||
* @code
|
||||
* config->enableStopMode = false;
|
||||
* config->enableOutputPin = false;
|
||||
* config->useUnfilteredOutput = false;
|
||||
* config->enableInvertOutput = false;
|
||||
* config->hysteresisMode = kLPCMP_HysteresisLevel0;
|
||||
* config->powerMode = kLPCMP_LowSpeedPowerMode;
|
||||
* @endcode
|
||||
* @param config Pointer to "lpcmp_config_t" structure.
|
||||
*/
|
||||
void LPCMP_GetDefaultConfig(lpcmp_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enable/Disable LPCMP module.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param enable "true" means enable the module, and "false" means disable the module.
|
||||
*/
|
||||
static inline void LPCMP_Enable(LPCMP_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CCR0 |= LPCMP_CCR0_CMP_EN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CCR0 &= ~LPCMP_CCR0_CMP_EN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Select the input channels for LPCMP. This function determines which input
|
||||
* is selected for the negative and positive mux.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param positiveChannel Positive side input channel number. Available range is 0-7.
|
||||
* @param negativeChannel Negative side input channel number. Available range is 0-7.
|
||||
*/
|
||||
void LPCMP_SetInputChannels(LPCMP_Type *base, uint32_t positiveChannel, uint32_t negativeChannel);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables the DMA request for rising/falling events.
|
||||
* Normally, the LPCMP generates a CPU interrupt if there is a rising/falling event. When
|
||||
* DMA support is enabled and the rising/falling interrupt is enabled , the rising/falling
|
||||
* event forces a DMA transfer request rather than a CPU interrupt instead.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param enable "true" means enable DMA support, and "false" means disable DMA support.
|
||||
*/
|
||||
static inline void LPCMP_EnableDMA(LPCMP_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CCR1 |= LPCMP_CCR1_DMA_EN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CCR1 &= ~LPCMP_CCR1_DMA_EN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enable/Disable window mode.When any windowed mode is active, COUTA is clocked by
|
||||
* the bus clock whenever WINDOW = 1. The last latched value is held when WINDOW = 0.
|
||||
* The optionally inverted comparator output COUT_RAW is sampled on every bus clock
|
||||
* when WINDOW=1 to generate COUTA.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param enable "true" means enable window mode, and "false" means disable window mode.
|
||||
*/
|
||||
static inline void LPCMP_EnableWindowMode(LPCMP_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->CCR1 |= LPCMP_CCR1_WINDOW_EN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->CCR1 &= ~LPCMP_CCR1_WINDOW_EN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configures the filter.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param config Pointer to "lpcmp_filter_config_t" structure.
|
||||
*/
|
||||
void LPCMP_SetFilterConfig(LPCMP_Type *base, const lpcmp_filter_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Configure the internal DAC module.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param config Pointer to "lpcmp_dac_config_t" structure. If config is "NULL", disable internal DAC.
|
||||
*/
|
||||
void LPCMP_SetDACConfig(LPCMP_Type *base, const lpcmp_dac_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enable the interrupts.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_lpcmp_interrupt_enable".
|
||||
*/
|
||||
static inline void LPCMP_EnableInterrupts(LPCMP_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IER |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the interrupts.
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param mask Mask value for interrupts. See "_lpcmp_interrupt_enable".
|
||||
*/
|
||||
static inline void LPCMP_DisableInterrupts(LPCMP_Type *base, uint32_t mask)
|
||||
{
|
||||
base->IER &= ~mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the LPCMP status flags.
|
||||
*
|
||||
* @param LPCMP peripheral base address.
|
||||
*
|
||||
* @return Mask value for the asserted flags. See "_lpcmp_status_flags".
|
||||
*/
|
||||
static inline uint32_t LPCMP_GetStatusFlags(LPCMP_Type *base)
|
||||
{
|
||||
return base->CSR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Clear the LPCMP status flags
|
||||
*
|
||||
* @param base LPCMP peripheral base address.
|
||||
* @param mask Mask value for the flags. See "_lpcmp_status_flags".
|
||||
*/
|
||||
static inline void LPCMP_ClearStatusFlags(LPCMP_Type *base, uint32_t mask)
|
||||
{
|
||||
base->CSR = mask;
|
||||
}
|
||||
|
||||
#endif /* _FSL_LPCMP_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_lpi2c_edma.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* @brief Mask to align an address to 32 bytes. */
|
||||
#define ALIGN_32_MASK (0x1fU)
|
||||
|
||||
/*! @brief Common sets of flags used by the driver. */
|
||||
enum _lpi2c_flag_constants
|
||||
{
|
||||
/*! All flags which are cleared by the driver upon starting a transfer. */
|
||||
kMasterClearFlags = kLPI2C_MasterEndOfPacketFlag | kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag |
|
||||
kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | kLPI2C_MasterPinLowTimeoutFlag |
|
||||
kLPI2C_MasterDataMatchFlag,
|
||||
|
||||
/*! IRQ sources enabled by the non-blocking transactional API. */
|
||||
kMasterIrqFlags = kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterTxReadyFlag | kLPI2C_MasterRxReadyFlag |
|
||||
kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | kLPI2C_MasterPinLowTimeoutFlag |
|
||||
kLPI2C_MasterFifoErrFlag,
|
||||
|
||||
/*! Errors to check for. */
|
||||
kMasterErrorFlags = kLPI2C_MasterNackDetectFlag | kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag |
|
||||
kLPI2C_MasterPinLowTimeoutFlag,
|
||||
|
||||
/*! All flags which are cleared by the driver upon starting a transfer. */
|
||||
kSlaveClearFlags = kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveBitErrFlag |
|
||||
kLPI2C_SlaveFifoErrFlag,
|
||||
|
||||
/*! IRQ sources enabled by the non-blocking transactional API. */
|
||||
kSlaveIrqFlags = kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag |
|
||||
kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag |
|
||||
kLPI2C_SlaveTransmitAckFlag | kLPI2C_SlaveAddressValidFlag,
|
||||
|
||||
/*! Errors to check for. */
|
||||
kSlaveErrorFlags = kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag,
|
||||
};
|
||||
|
||||
/* ! @brief LPI2C master fifo commands. */
|
||||
enum _lpi2c_master_fifo_cmd
|
||||
{
|
||||
kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */
|
||||
kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */
|
||||
kStopCmd = LPI2C_MTDR_CMD(0x2U), /*!< Generate STOP condition */
|
||||
kStartCmd = LPI2C_MTDR_CMD(0x4U), /*!< Generate(repeated) START and transmit address in DATA[[7:0] */
|
||||
};
|
||||
|
||||
/*! @brief States for the state machine used by transactional APIs. */
|
||||
enum _lpi2c_transfer_states
|
||||
{
|
||||
kIdleState = 0,
|
||||
kSendCommandState,
|
||||
kIssueReadCommandState,
|
||||
kTransferDataState,
|
||||
kStopState,
|
||||
kWaitForCompletionState,
|
||||
};
|
||||
|
||||
/*! @brief Typedef for interrupt handler. */
|
||||
typedef void (*lpi2c_isr_t)(LPI2C_Type *base, void *handle);
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/* Defined in fsl_lpi2c.c. */
|
||||
extern status_t LPI2C_CheckForBusyBus(LPI2C_Type *base);
|
||||
|
||||
/* Defined in fsl_lpi2c.c. */
|
||||
extern status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status);
|
||||
|
||||
static uint32_t LPI2C_GenerateCommands(lpi2c_master_edma_handle_t *handle);
|
||||
|
||||
static void LPI2C_MasterEDMACallback(edma_handle_t *dmaHandle, void *userData, bool isTransferDone, uint32_t tcds);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void LPI2C_MasterCreateEDMAHandle(LPI2C_Type *base,
|
||||
lpi2c_master_edma_handle_t *handle,
|
||||
edma_handle_t *rxDmaHandle,
|
||||
edma_handle_t *txDmaHandle,
|
||||
lpi2c_master_edma_transfer_callback_t callback,
|
||||
void *userData)
|
||||
{
|
||||
assert(handle);
|
||||
assert(rxDmaHandle);
|
||||
assert(txDmaHandle);
|
||||
|
||||
/* Clear out the handle. */
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
/* Set up the handle. For combined rx/tx DMA requests, the tx channel handle is set to the rx handle */
|
||||
/* in order to make the transfer API code simpler. */
|
||||
handle->base = base;
|
||||
handle->completionCallback = callback;
|
||||
handle->userData = userData;
|
||||
handle->rx = rxDmaHandle;
|
||||
handle->tx = FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) ? txDmaHandle : rxDmaHandle;
|
||||
|
||||
/* Set DMA channel completion callbacks. */
|
||||
EDMA_SetCallback(handle->rx, LPI2C_MasterEDMACallback, handle);
|
||||
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
{
|
||||
EDMA_SetCallback(handle->tx, LPI2C_MasterEDMACallback, handle);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Prepares the command buffer with the sequence of commands needed to send the requested transaction.
|
||||
* @param handle Master DMA driver handle.
|
||||
* @return Number of command words.
|
||||
*/
|
||||
static uint32_t LPI2C_GenerateCommands(lpi2c_master_edma_handle_t *handle)
|
||||
{
|
||||
lpi2c_master_transfer_t *xfer = &handle->transfer;
|
||||
uint16_t *cmd = (uint16_t *)&handle->commandBuffer;
|
||||
uint32_t cmdCount = 0;
|
||||
|
||||
/* Handle no start option. */
|
||||
if (xfer->flags & kLPI2C_TransferNoStartFlag)
|
||||
{
|
||||
if (xfer->direction == kLPI2C_Read)
|
||||
{
|
||||
/* Need to issue read command first. */
|
||||
cmd[cmdCount++] = kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Initial direction depends on whether a subaddress was provided, and of course the actual
|
||||
* data transfer direction.
|
||||
*/
|
||||
lpi2c_direction_t direction = xfer->subaddressSize ? kLPI2C_Write : xfer->direction;
|
||||
|
||||
/* Start command. */
|
||||
cmd[cmdCount++] =
|
||||
(uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction);
|
||||
|
||||
/* Subaddress, MSB first. */
|
||||
if (xfer->subaddressSize)
|
||||
{
|
||||
uint32_t subaddressRemaining = xfer->subaddressSize;
|
||||
while (subaddressRemaining--)
|
||||
{
|
||||
uint8_t subaddressByte = (xfer->subaddress >> (8 * subaddressRemaining)) & 0xff;
|
||||
cmd[cmdCount++] = subaddressByte;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reads need special handling because we have to issue a read command and maybe a repeated start. */
|
||||
if ((xfer->dataSize) && (xfer->direction == kLPI2C_Read))
|
||||
{
|
||||
/* Need to send repeated start if switching directions to read. */
|
||||
if (direction == kLPI2C_Write)
|
||||
{
|
||||
cmd[cmdCount++] = (uint16_t)kStartCmd |
|
||||
(uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read);
|
||||
}
|
||||
|
||||
/* Read command. */
|
||||
cmd[cmdCount++] = kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return cmdCount;
|
||||
}
|
||||
|
||||
status_t LPI2C_MasterTransferEDMA(LPI2C_Type *base,
|
||||
lpi2c_master_edma_handle_t *handle,
|
||||
lpi2c_master_transfer_t *transfer)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
assert(handle);
|
||||
assert(transfer);
|
||||
assert(transfer->subaddressSize <= sizeof(transfer->subaddress));
|
||||
|
||||
/* Return busy if another transaction is in progress. */
|
||||
if (handle->isBusy)
|
||||
{
|
||||
return kStatus_LPI2C_Busy;
|
||||
}
|
||||
|
||||
/* Return an error if the bus is already in use not by us. */
|
||||
result = LPI2C_CheckForBusyBus(base);
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
/* We're now busy. */
|
||||
handle->isBusy = true;
|
||||
|
||||
/* Disable LPI2C IRQ and DMA sources while we configure stuff. */
|
||||
LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags);
|
||||
LPI2C_MasterEnableDMA(base, false, false);
|
||||
|
||||
/* Clear all flags. */
|
||||
LPI2C_MasterClearStatusFlags(base, kMasterClearFlags);
|
||||
|
||||
/* Save transfer into handle. */
|
||||
handle->transfer = *transfer;
|
||||
|
||||
/* Generate commands to send. */
|
||||
uint32_t commandCount = LPI2C_GenerateCommands(handle);
|
||||
|
||||
/* If the user is transmitting no data with no start or stop, then just go ahead and invoke the callback. */
|
||||
if ((!commandCount) && (transfer->dataSize == 0))
|
||||
{
|
||||
if (handle->completionCallback)
|
||||
{
|
||||
handle->completionCallback(base, handle, kStatus_Success, handle->userData);
|
||||
}
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/* Reset DMA channels. */
|
||||
EDMA_ResetChannel(handle->rx->base, handle->rx->channel);
|
||||
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
{
|
||||
EDMA_ResetChannel(handle->tx->base, handle->tx->channel);
|
||||
}
|
||||
|
||||
/* Get a 32-byte aligned TCD pointer. */
|
||||
edma_tcd_t *tcd = (edma_tcd_t *)((uint32_t)(&handle->tcds[1]) & (~ALIGN_32_MASK));
|
||||
|
||||
bool hasSendData = (transfer->direction == kLPI2C_Write) && (transfer->dataSize);
|
||||
bool hasReceiveData = (transfer->direction == kLPI2C_Read) && (transfer->dataSize);
|
||||
|
||||
edma_transfer_config_t transferConfig;
|
||||
edma_tcd_t *linkTcd = NULL;
|
||||
|
||||
/* Set up data transmit. */
|
||||
if (hasSendData)
|
||||
{
|
||||
transferConfig.srcAddr = (uint32_t)transfer->data;
|
||||
transferConfig.destAddr = (uint32_t)LPI2C_MasterGetTxFifoAddress(base);
|
||||
transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transferConfig.srcOffset = sizeof(uint8_t);
|
||||
transferConfig.destOffset = 0;
|
||||
transferConfig.minorLoopBytes = sizeof(uint8_t); /* TODO optimize to fill fifo */
|
||||
transferConfig.majorLoopCounts = transfer->dataSize;
|
||||
|
||||
/* Store the initially configured eDMA minor byte transfer count into the LPI2C handle */
|
||||
handle->nbytes = transferConfig.minorLoopBytes;
|
||||
|
||||
if (commandCount)
|
||||
{
|
||||
/* Create a software TCD, which will be chained after the commands. */
|
||||
EDMA_TcdReset(tcd);
|
||||
EDMA_TcdSetTransferConfig(tcd, &transferConfig, NULL);
|
||||
EDMA_TcdEnableInterrupts(tcd, kEDMA_MajorInterruptEnable);
|
||||
linkTcd = tcd;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* User is only transmitting data with no required commands, so this transfer can stand alone. */
|
||||
EDMA_SetTransferConfig(handle->tx->base, handle->tx->channel, &transferConfig, NULL);
|
||||
EDMA_EnableChannelInterrupts(handle->tx->base, handle->tx->channel, kEDMA_MajorInterruptEnable);
|
||||
}
|
||||
}
|
||||
else if (hasReceiveData)
|
||||
{
|
||||
/* Set up data receive. */
|
||||
transferConfig.srcAddr = (uint32_t)LPI2C_MasterGetRxFifoAddress(base);
|
||||
transferConfig.destAddr = (uint32_t)transfer->data;
|
||||
transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
|
||||
transferConfig.srcOffset = 0;
|
||||
transferConfig.destOffset = sizeof(uint8_t);
|
||||
transferConfig.minorLoopBytes = sizeof(uint8_t); /* TODO optimize to empty fifo */
|
||||
transferConfig.majorLoopCounts = transfer->dataSize;
|
||||
|
||||
/* Store the initially configured eDMA minor byte transfer count into the LPI2C handle */
|
||||
handle->nbytes = transferConfig.minorLoopBytes;
|
||||
|
||||
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) || (!commandCount))
|
||||
{
|
||||
/* We can put this receive transfer on its own DMA channel. */
|
||||
EDMA_SetTransferConfig(handle->rx->base, handle->rx->channel, &transferConfig, NULL);
|
||||
EDMA_EnableChannelInterrupts(handle->rx->base, handle->rx->channel, kEDMA_MajorInterruptEnable);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For shared rx/tx DMA requests when there are commands, create a software TCD which will be */
|
||||
/* chained onto the commands transfer. */
|
||||
EDMA_TcdReset(tcd);
|
||||
EDMA_TcdSetTransferConfig(tcd, &transferConfig, NULL);
|
||||
EDMA_TcdEnableInterrupts(tcd, kEDMA_MajorInterruptEnable);
|
||||
linkTcd = tcd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No data to send */
|
||||
}
|
||||
|
||||
/* Set up commands transfer. */
|
||||
if (commandCount)
|
||||
{
|
||||
transferConfig.srcAddr = (uint32_t)handle->commandBuffer;
|
||||
transferConfig.destAddr = (uint32_t)LPI2C_MasterGetTxFifoAddress(base);
|
||||
transferConfig.srcTransferSize = kEDMA_TransferSize2Bytes;
|
||||
transferConfig.destTransferSize = kEDMA_TransferSize2Bytes;
|
||||
transferConfig.srcOffset = sizeof(uint16_t);
|
||||
transferConfig.destOffset = 0;
|
||||
transferConfig.minorLoopBytes = sizeof(uint16_t); /* TODO optimize to fill fifo */
|
||||
transferConfig.majorLoopCounts = commandCount;
|
||||
|
||||
EDMA_SetTransferConfig(handle->tx->base, handle->tx->channel, &transferConfig, linkTcd);
|
||||
}
|
||||
|
||||
/* Start DMA transfer. */
|
||||
if (hasReceiveData || !FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
{
|
||||
EDMA_StartTransfer(handle->rx);
|
||||
}
|
||||
if ((hasSendData || commandCount) && FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
{
|
||||
EDMA_StartTransfer(handle->tx);
|
||||
}
|
||||
|
||||
/* Enable DMA in both directions. This actually kicks of the transfer. */
|
||||
LPI2C_MasterEnableDMA(base, true, true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t LPI2C_MasterTransferGetCountEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle, size_t *count)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
if (!count)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
/* Catch when there is not an active transfer. */
|
||||
if (!handle->isBusy)
|
||||
{
|
||||
*count = 0;
|
||||
return kStatus_NoTransferInProgress;
|
||||
}
|
||||
|
||||
uint32_t remaining = handle->transfer.dataSize;
|
||||
|
||||
/* If the DMA is still on a commands transfer that chains to the actual data transfer, */
|
||||
/* we do nothing and return the number of transferred bytes as zero. */
|
||||
if (handle->tx->base->TCD[handle->tx->channel].DLAST_SGA == 0)
|
||||
{
|
||||
if (handle->transfer.direction == kLPI2C_Write)
|
||||
{
|
||||
remaining =
|
||||
(uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->tx->base, handle->tx->channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining =
|
||||
(uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->rx->base, handle->rx->channel);
|
||||
}
|
||||
}
|
||||
|
||||
*count = handle->transfer.dataSize - remaining;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t LPI2C_MasterTransferAbortEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle)
|
||||
{
|
||||
/* Catch when there is not an active transfer. */
|
||||
if (!handle->isBusy)
|
||||
{
|
||||
return kStatus_LPI2C_Idle;
|
||||
}
|
||||
|
||||
/* Terminate DMA transfers. */
|
||||
EDMA_AbortTransfer(handle->rx);
|
||||
if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base))
|
||||
{
|
||||
EDMA_AbortTransfer(handle->tx);
|
||||
}
|
||||
|
||||
/* Reset fifos. */
|
||||
base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
|
||||
|
||||
/* Send a stop command to finalize the transfer. */
|
||||
base->MTDR = kStopCmd;
|
||||
|
||||
/* Reset handle. */
|
||||
handle->isBusy = false;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief DMA completion callback.
|
||||
* @param dmaHandle DMA channel handle for the channel that completed.
|
||||
* @param userData User data associated with the channel handle. For this callback, the user data is the
|
||||
* LPI2C DMA driver handle.
|
||||
* @param isTransferDone Whether the DMA transfer has completed.
|
||||
* @param tcds Number of TCDs that completed.
|
||||
*/
|
||||
static void LPI2C_MasterEDMACallback(edma_handle_t *dmaHandle, void *userData, bool isTransferDone, uint32_t tcds)
|
||||
{
|
||||
lpi2c_master_edma_handle_t *handle = (lpi2c_master_edma_handle_t *)userData;
|
||||
if (!handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for errors. */
|
||||
status_t result = LPI2C_MasterCheckAndClearError(handle->base, LPI2C_MasterGetStatusFlags(handle->base));
|
||||
|
||||
/* Done with this transaction. */
|
||||
handle->isBusy = false;
|
||||
|
||||
if (!(handle->transfer.flags & kLPI2C_TransferNoStopFlag))
|
||||
{
|
||||
/* Send a stop command to finalize the transfer. */
|
||||
handle->base->MTDR = kStopCmd;
|
||||
}
|
||||
|
||||
/* Invoke callback. */
|
||||
if (handle->completionCallback)
|
||||
{
|
||||
handle->completionCallback(handle->base, handle, result, handle->userData);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user