[bsp][nxp]support FRDM-MCXA156 (#9971)

support FRDM-MCXA156

Co-authored-by: shannon <xxlong1999@163.com>
This commit is contained in:
Rbb666
2025-02-07 09:45:56 +08:00
committed by GitHub
parent 8629c9572a
commit a63b97e316
146 changed files with 135645 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
#!armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -x c
/*
** ###################################################################
** Processors: MCXA156VLL
** MCXA156VMP
** MCXA156VPJ
**
** Compiler: Keil ARM C/C++ Compiler
** Reference manual: MCXA18 User manual
** Version: rev. 1.0, 2022-03-29
** Build: b240104
**
** Abstract:
** Linker file for the Keil ARM C/C++ Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2024 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Sizes */
#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#define Stack_Size 0x0400
#endif
#if (defined(__heap_size__))
#define Heap_Size __heap_size__
#else
#define Heap_Size 0x0400
#endif
#define m_interrupts_start 0x00000000
#define m_interrupts_size 0x00000200
#define m_text_start 0x00000200
#define m_text_size 0x000FFE00
#define m_data_start 0x20000000
#define m_data_size 0x0001E000
#define m_sramx0_start 0x04000000;
#define m_sramx0_size 0x00002000;
LR_m_text m_interrupts_start m_interrupts_size+m_text_size { ; load region size_region
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
* (.isr_vector,+FIRST)
}
ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
* (InRoot$$Sections)
.ANY (+RO)
}
RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
.ANY (+RW +ZI)
}
ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up
}
ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
}
}

View File

@@ -0,0 +1,68 @@
#!armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -x c
/*
** ###################################################################
** Processors: MCXA156VLL
** MCXA156VMP
** MCXA156VPJ
**
** Compiler: Keil ARM C/C++ Compiler
** Reference manual: MCXA18 User manual
** Version: rev. 1.0, 2022-03-29
** Build: b240104
**
** Abstract:
** Linker file for the Keil ARM C/C++ Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2024 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Sizes */
#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#define Stack_Size 0x0400
#endif
#if (defined(__heap_size__))
#define Heap_Size __heap_size__
#else
#define Heap_Size 0x0400
#endif
#define m_interrupts_start 0x20000000
#define m_interrupts_size 0x00000200
#define m_text_start 0x20000200
#define m_text_size 0x00005E00
#define m_data_start 0x20006000
#define m_data_size 0x00018000
LR_m_text m_interrupts_start m_interrupts_size+m_text_size { ; load region size_region
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
* (.isr_vector,+FIRST)
}
ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
* (InRoot$$Sections)
.ANY (+RO)
}
RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
.ANY (+RW +ZI)
}
ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up
}
ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
}
}

View File

@@ -0,0 +1,18 @@
// <<< Use Configuration Wizard in Context Menu >>>
// <o0> SWO pin
// <i> The SWO (Serial Wire Output) pin optionally provides data from the ITM
// <i> for an external debug tool to evaluate.
// <0=> PIO0_10
// <1=> PIO0_8
SWO_Pin = 0;
//
// <h>Debug Configuration
// <o.0> StopAfterBootloader <i> Stop after Bootloader
// </h>
Dbg_CR = 0x00000001;
//
// <<< end of configuration section >>>

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -0,0 +1,378 @@
/*
* Copyright 2020-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_cdog.h"
/*******************************************************************************
* Definitions
*******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.cdog"
#endif
/* Reset CONTROL mask */
#define RESERVED_CTRL_MASK 0x800u
#if defined(CDOG_IRQS)
/* Array of IRQs */
static const IRQn_Type s_CdogIrqs[] = CDOG_IRQS;
#endif /* CDOG_IRQS */
#ifdef CDOG_CLOCKS
static const clock_ip_name_t s_CdogClocks[] = CDOG_CLOCKS;
#endif /* CDOG_CLOCKS */
#ifdef CDOG_BASE_PTRS
static const CDOG_Type* s_cdogBases[] = CDOG_BASE_PTRS;
#endif /* CDOG_BASE_PTRS */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t CDOG_GetInstance(CDOG_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_cdogBases); instance++)
{
if (s_cdogBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_cdogBases));
return instance;
}
/*!
* brief Sets the default configuration of CDOG
*
* This function initialize CDOG config structure to default values.
*
* param conf CDOG configuration structure
*/
void CDOG_GetDefaultConfig(cdog_config_t *conf)
{
/* Default configuration after reset */
conf->lock = (uint8_t)kCDOG_LockCtrl_Unlock; /* Lock control */
conf->timeout = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Timeout control */
conf->miscompare = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Miscompare control */
conf->sequence = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Sequence control */
conf->state = (uint8_t)kCDOG_FaultCtrl_NoAction; /* State control */
conf->address = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Address control */
conf->irq_pause = (uint8_t)kCDOG_IrqPauseCtrl_Run; /* IRQ pause control */
conf->debug_halt = (uint8_t)kCDOG_DebugHaltCtrl_Run; /* Debug halt control */
return;
}
/*!
* brief Sets secure counter and instruction timer values
*
* This function sets value in RELOAD and START registers for instruction timer.
*
* param base CDOG peripheral base address
* param reload reload value
* param start start value
*/
void CDOG_Start(CDOG_Type *base, uint32_t reload, uint32_t start)
{
base->RELOAD = reload;
base->START = start;
}
/*!
* brief Stops secure counter and instruction timer
*
* This function stops instruction timer and secure counter.
* This also change state of CDOG to IDLE.
*
* param base CDOG peripheral base address
* param stop expected value which will be compared with value of secure counter
*/
void CDOG_Stop(CDOG_Type *base, uint32_t stop)
{
base->STOP = stop;
}
/*!
* brief Sets secure counter and instruction timer values
*
* This function sets value in STOP, RELOAD and START registers
* for instruction timer and secure counter.
*
* param base CDOG peripheral base address
* param stop expected value which will be compared with value of secure counter
* param reload reload value for instruction timer
* param start start value for secure timer
*/
void CDOG_Set(CDOG_Type *base, uint32_t stop, uint32_t reload, uint32_t start)
{
base->STOP = stop;
base->RELOAD = reload;
base->START = start;
}
/*!
* brief Add value to secure counter
*
* This function add specified value to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add(CDOG_Type *base, uint32_t add)
{
base->ADD = (secure_counter_t)add;
}
/*!
* brief Add 1 to secure counter
*
* This function add 1 to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add1(CDOG_Type *base)
{
base->ADD1 = (secure_counter_t)0x1U;
}
/*!
* brief Add 16 to secure counter
*
* This function add 16 to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add16(CDOG_Type *base)
{
base->ADD16 = (secure_counter_t)0x1U;
}
/*!
* brief Add 256 to secure counter
*
* This function add 256 to secure counter.
*
* param base CDOG peripheral base address.
* param add Value to be added.
*/
void CDOG_Add256(CDOG_Type *base)
{
base->ADD256 = (secure_counter_t)0x1U;
}
/*!
* brief Substract value to secure counter
*
* This function substract specified value to secure counter.
*
* param base CDOG peripheral base address.
* param sub Value to be substracted.
*/
void CDOG_Sub(CDOG_Type *base, uint32_t sub)
{
base->SUB = (secure_counter_t)sub;
}
/*!
* brief Substract 1 from secure counter
*
* This function substract specified 1 from secure counter.
*
* param base CDOG peripheral base address.
*/
void CDOG_Sub1(CDOG_Type *base)
{
base->SUB1 = (secure_counter_t)0x1U;
}
/*!
* brief Substract 16 from secure counter
*
* This function substract specified 16 from secure counter.
*
* param base CDOG peripheral base address.
*/
void CDOG_Sub16(CDOG_Type *base)
{
base->SUB16 = (secure_counter_t)0x1U;
}
/*!
* brief Substract 256 from secure counter
*
* This function substract specified 256 from secure counter.
*
* param base CDOG peripheral base address.
*/
void CDOG_Sub256(CDOG_Type *base)
{
base->SUB256 = (secure_counter_t)0x1U;
}
/*!
* brief Checks secure counter.
*
* This function compares stop value with secure counter value
* by writting to RELOAD refister.
*
* param base CDOG peripheral base address
* param check expected (stop) value.
*/
void CDOG_Check(CDOG_Type *base, uint32_t check)
{
#if defined(FLS_FEATURE_CDOG_USE_RESTART)
base->RESTART = check;
#else
base->STOP = check;
base->RELOAD = base->RELOAD;
base->START= check;
#endif
}
/*!
* brief Set the CDOG persistent word.
*
* param base CDOG peripheral base address.
* param value The value to be written.
*/
void CDOG_WritePersistent(CDOG_Type *base, uint32_t value)
{
base->PERSISTENT = value;
}
/*!
* brief Get the CDOG persistent word.
*
* param base CDOG peripheral base address.
* return The persistent word.
*/
uint32_t CDOG_ReadPersistent(CDOG_Type *base)
{
return base->PERSISTENT;
}
/*!
* brief Initialize CDOG
*
* This function initializes CDOG setting and enable all interrupts.
*
* param base CDOG peripheral base address
* param conf CDOG configuration structure
* return Status of the init operation
*/
status_t CDOG_Init(CDOG_Type *base, cdog_config_t *conf)
{
/* Ungate clock to CDOG engine and reset it */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#ifdef CDOG_CLOCKS
CLOCK_EnableClock(s_CdogClocks[CDOG_GetInstance(base)]);
#endif /* CDOG_CLOCKS */
#endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_CDOG_HAS_NO_RESET) && FSL_FEATURE_CDOG_HAS_NO_RESET)
RESET_PeripheralReset(kCDOG_RST_SHIFT_RSTn);
#endif /* !FSL_FEATURE_CDOG_HAS_NO_RESET */
if (base->CONTROL == 0x0U)
{
/* CDOG is not in IDLE mode, which may be cause after SW reset. */
/* Writing to CONTROL register will trigger fault. */
return kStatus_Fail;
}
/* Clear pending errors, otherwise the device will reset */
/* itself immediately after enable Code Watchdog */
if ((uint32_t)kCDOG_LockCtrl_Lock ==
((base->CONTROL & CDOG_CONTROL_LOCK_CTRL_MASK) >> CDOG_CONTROL_LOCK_CTRL_SHIFT))
{
base->FLAGS = CDOG_FLAGS_TO_FLAG(1U) | CDOG_FLAGS_MISCOM_FLAG(1U) | CDOG_FLAGS_SEQ_FLAG(1U) |
CDOG_FLAGS_CNT_FLAG(1U) | CDOG_FLAGS_STATE_FLAG(1U) | CDOG_FLAGS_ADDR_FLAG(1U) |
CDOG_FLAGS_POR_FLAG(1U);
}
else
{
/* load default values for CDOG->CONTROL before flags clear */
#if defined(FSL_FEATURE_CDOG_NEED_LOAD_DEFAULT_CONF) && (FSL_FEATURE_CDOG_NEED_LOAD_DEFAULT_CONF > 0)
cdog_config_t default_conf;
/* Initialize CDOG */
CDOG_GetDefaultConfig(&default_conf);
/* Write default value to CDOG->CONTROL*/
base->CONTROL =
CDOG_CONTROL_TIMEOUT_CTRL(default_conf.timeout) | /* Action if the timeout event is triggered */
CDOG_CONTROL_MISCOMPARE_CTRL(default_conf.miscompare) | /* Action if the miscompare error event is triggered */
CDOG_CONTROL_SEQUENCE_CTRL(default_conf.sequence) | /* Action if the sequence error event is triggered */
CDOG_CONTROL_STATE_CTRL(default_conf.state) | /* Action if the state error event is triggered */
CDOG_CONTROL_ADDRESS_CTRL(default_conf.address) | /* Action if the address error event is triggered */
CDOG_CONTROL_IRQ_PAUSE(default_conf.irq_pause) | /* Pause running during interrupts setup */
CDOG_CONTROL_DEBUG_HALT_CTRL(default_conf.debug_halt) | /* Halt CDOG timer during debug */
CDOG_CONTROL_LOCK_CTRL(default_conf.lock) | RESERVED_CTRL_MASK; /* Lock control register, RESERVED */
#endif /* FSL_FEATURE_CDOG_NEED_LOAD_DEFAULT_CONF */
base->FLAGS = CDOG_FLAGS_TO_FLAG(0U) | CDOG_FLAGS_MISCOM_FLAG(0U) | CDOG_FLAGS_SEQ_FLAG(0U) |
CDOG_FLAGS_CNT_FLAG(0U) | CDOG_FLAGS_STATE_FLAG(0U) | CDOG_FLAGS_ADDR_FLAG(0U) |
CDOG_FLAGS_POR_FLAG(0U);
}
base->CONTROL =
CDOG_CONTROL_TIMEOUT_CTRL(conf->timeout) | /* Action if the timeout event is triggered */
CDOG_CONTROL_MISCOMPARE_CTRL(conf->miscompare) | /* Action if the miscompare error event is triggered */
CDOG_CONTROL_SEQUENCE_CTRL(conf->sequence) | /* Action if the sequence error event is triggered */
CDOG_CONTROL_STATE_CTRL(conf->state) | /* Action if the state error event is triggered */
CDOG_CONTROL_ADDRESS_CTRL(conf->address) | /* Action if the address error event is triggered */
CDOG_CONTROL_IRQ_PAUSE(conf->irq_pause) | /* Pause running during interrupts setup */
CDOG_CONTROL_DEBUG_HALT_CTRL(conf->debug_halt) | /* Halt CDOG timer during debug */
CDOG_CONTROL_LOCK_CTRL(conf->lock) | RESERVED_CTRL_MASK; /* Lock control register, RESERVED */
#if defined(CDOG_IRQS)
/* Enable peripheral IRQ */
NVIC_EnableIRQ(s_CdogIrqs[CDOG_GetInstance(base)]);
#endif /* CDOG_IRQS */
return kStatus_Success;
}
/*!
* brief Deinitialize CDOG
*
* This function stops CDOG secure counter.
*
* param base CDOG peripheral base address
*/
void CDOG_Deinit(CDOG_Type *base)
{
#if defined(CDOG_IRQS)
/* Disable peripheral IRQ */
NVIC_DisableIRQ(s_CdogIrqs[CDOG_GetInstance(base)]);
#endif /* CDOG_IRQS */
#if !(defined(FSL_FEATURE_CDOG_HAS_NO_RESET) && FSL_FEATURE_CDOG_HAS_NO_RESET)
RESET_SetPeripheralReset(kCDOG_RST_SHIFT_RSTn);
#endif /* !FSL_FEATURE_CDOG_HAS_NO_RESET */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#ifdef CDOG_CLOCKS
CLOCK_DisableClock(s_CdogClocks[CDOG_GetInstance(base)]);
#endif /* CDOG_CLOCKS */
#endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

View File

@@ -0,0 +1,329 @@
/*
* Copyright 2020-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FSL_CDOG_H_
#define FSL_CDOG_H_
#include "fsl_common.h"
/*!
* @addtogroup CDOG
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*! @{ */
/*! @brief Defines CDOG driver version 2.1.3.
*
* Change log:
* - Version 2.1.3
* - Re-design multiple instance IRQs and Clocks
* - Add fix for RESTART command errata
* - Version 2.1.2
* - Support multiple IRQs
* - Fix default CONTROL values
* - Version 2.1.1
* - Remove bit CONTROL[CONTROL_CTRL]
* - Version 2.1.0
* - Rename CWT to CDOG
* - Version 2.0.2
* - Fix MISRA-2012 issues
* - Version 2.0.1
* - Fix doxygen issues
* - Version 2.0.0
* - initial version
*/
#define FSL_CDOG_DRIVER_VERSION (MAKE_VERSION(2, 1, 3))
/*! @} */
typedef struct
{
uint8_t lock : 2;
uint8_t timeout : 3;
uint8_t miscompare : 3;
uint8_t sequence : 3;
uint8_t state : 3;
uint8_t address : 3;
uint8_t reserved : 8;
uint8_t irq_pause : 2;
uint8_t debug_halt : 2;
} cdog_config_t;
enum __cdog_debug_Action_ctrl_enum
{
kCDOG_DebugHaltCtrl_Run = 0x1,
kCDOG_DebugHaltCtrl_Pause = 0x2,
};
enum __cdog_irq_pause_ctrl_enum
{
kCDOG_IrqPauseCtrl_Run = 0x1,
kCDOG_IrqPauseCtrl_Pause = 0x2,
};
enum __cdog_fault_ctrl_enum
{
kCDOG_FaultCtrl_EnableReset = 0x1U,
kCDOG_FaultCtrl_EnableInterrupt = 0x2U,
kCDOG_FaultCtrl_NoAction = 0x4U,
};
enum __code_lock_ctrl_enum
{
kCDOG_LockCtrl_Lock = 0x1,
kCDOG_LockCtrl_Unlock = 0x2,
};
typedef uint32_t secure_counter_t;
#define SC_ADD(add) \
do \
{ \
CDOG->ADD = (secure_counter_t)(add); \
} while (0)
#define SC_ADD1 \
do \
{ \
CDOG->ADD1 = (secure_counter_t)0x1U; \
} while (0)
#define SC_ADD16 \
do \
{ \
CDOG->ADD16 = (secure_counter_t)0x1U; \
} while (0)
#define SC_ADD256 \
do \
{ \
CDOG->ADD256 = (secure_counter_t)0x1U; \
} while (0)
#define SC_SUB(sub) \
do \
{ \
CDOG->SUB = (secure_counter_t)(sub); \
} while (0)
#define SC_SUB1 \
do \
{ \
CDOG->SUB1 = (secure_counter_t)0x1U; \
} while (0)
#define SC_SUB16 \
do \
{ \
CDOG->SUB16 = (secure_counter_t)0x1U; \
} while (0)
#define SC_SUB256 \
do \
{ \
CDOG->SUB256 = (secure_counter_t)0x1U; \
} while (0)
#define SC_CHECK(val) \
do \
{ \
CDOG->RESTART = (secure_counter_t)val; \
} while (0)
/*******************************************************************************
* API
*******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name CDOG Functional Operation
* @{
*/
/*!
* @brief Initialize CDOG
*
* This function initializes CDOG block and setting.
*
* @param base CDOG peripheral base address
* @param conf CDOG configuration structure
* @return Status of the init operation
*/
status_t CDOG_Init(CDOG_Type *base, cdog_config_t *conf);
/*!
* @brief Deinitialize CDOG
*
* This function deinitializes CDOG secure counter.
*
* @param base CDOG peripheral base address
*/
void CDOG_Deinit(CDOG_Type *base);
/*!
* @brief Sets the default configuration of CDOG
*
* This function initialize CDOG config structure to default values.
*
* @param conf CDOG configuration structure
*/
void CDOG_GetDefaultConfig(cdog_config_t *conf);
/*!
* @brief Stops secure counter and instruction timer
*
* This function stops instruction timer and secure counter.
* This also change state od CDOG to IDLE.
*
* @param base CDOG peripheral base address
* @param stop expected value which will be compared with value of secure counter
*/
void CDOG_Stop(CDOG_Type *base, uint32_t stop);
/*!
* @brief Sets secure counter and instruction timer values
*
* This function sets value in RELOAD and START registers
* for instruction timer and secure counter
*
* @param base CDOG peripheral base address
* @param reload reload value
* @param start start value
*/
void CDOG_Start(CDOG_Type *base, uint32_t reload, uint32_t start);
/*!
* @brief Checks secure counter.
*
* This function compares stop value in handler with secure counter value
* by writting to RELOAD refister.
*
* @param base CDOG peripheral base address
* @param check expected (stop) value
*/
void CDOG_Check(CDOG_Type *base, uint32_t check);
/*!
* @brief Sets secure counter and instruction timer values
*
* This function sets value in STOP, RELOAD and START registers
* for instruction timer and secure counter.
*
* @param base CDOG peripheral base address
* @param stop expected value which will be compared with value of secure counter
* @param reload reload value for instruction timer
* @param start start value for secure timer
*/
void CDOG_Set(CDOG_Type *base, uint32_t stop, uint32_t reload, uint32_t start);
/*!
* @brief Add value to secure counter
*
* This function add specified value to secure counter.
*
* @param base CDOG peripheral base address.
* @param add Value to be added.
*/
void CDOG_Add(CDOG_Type *base, uint32_t add);
/*!
* @brief Add 1 to secure counter
*
* This function add 1 to secure counter.
*
* @param base CDOG peripheral base address.
*/
void CDOG_Add1(CDOG_Type *base);
/*!
* @brief Add 16 to secure counter
*
* This function add 16 to secure counter.
*
* @param base CDOG peripheral base address.
*/
void CDOG_Add16(CDOG_Type *base);
/*!
* @brief Add 256 to secure counter
*
* This function add 256 to secure counter.
*
* @param base CDOG peripheral base address.
*/
void CDOG_Add256(CDOG_Type *base);
/*!
* brief Substract value to secure counter
*
* This function substract specified value to secure counter.
*
* param base CDOG peripheral base address.
* param sub Value to be substracted.
*/
void CDOG_Sub(CDOG_Type *base, uint32_t sub);
/*!
* @brief Substract 1 from secure counter
*
* This function substract specified 1 from secure counter.
*
* @param base CDOG peripheral base address.
*/
void CDOG_Sub1(CDOG_Type *base);
/*!
* @brief Substract 16 from secure counter
*
* This function substract specified 16 from secure counter.
*
* @param base CDOG peripheral base address.
*/
void CDOG_Sub16(CDOG_Type *base);
/*!
* @brief Substract 256 from secure counter
*
* This function substract specified 256 from secure counter.
*
* @param base CDOG peripheral base address.
*/
void CDOG_Sub256(CDOG_Type *base);
/*!
* @brief Set the CDOG persistent word.
*
* @param base CDOG peripheral base address.
* @param value The value to be written.
*/
void CDOG_WritePersistent(CDOG_Type *base, uint32_t value);
/*!
* @brief Get the CDOG persistent word.
*
* @param base CDOG peripheral base address.
* @return The persistent word.
*/
uint32_t CDOG_ReadPersistent(CDOG_Type *base);
/*! @}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/ /* end of group cdog */
#endif /* FSL_CDOG_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,236 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019, 2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_dac.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.dac_1"
#endif
#if defined(DAC_RSTS)
#define DAC_RESETS_ARRAY DAC_RSTS
#elif defined(DAC_RSTS_N)
#define DAC_RESETS_ARRAY DAC_RSTS_N
#endif
/*******************************************************************************
* 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;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to DAC clocks for each instance. */
static const clock_ip_name_t s_dacClocks[] = LPDAC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(DAC_RESETS_ARRAY)
/* Reset array */
static const reset_ip_name_t s_dacResets[] = DAC_RESETS_ARRAY;
#endif
/*******************************************************************************
* 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;
}
/*!
* 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)
{
assert(NULL != config);
uint32_t tmp32 = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(DAC_RESETS_ARRAY)
RESET_ReleasePeripheralReset(s_dacResets[DAC_GetInstance(base)]);
#endif
/* 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;
#if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
case kDAC_FIFOWorkAsPeriodTriggerMode:
tmp32 |= LPDAC_GCR_FIFOEN_MASK | LPDAC_GCR_PTGEN_MASK; /* Enable period trigger mode. */
/* Set trigger number and width. */
base->PCR =
LPDAC_PCR_PTG_NUM(config->periodicTriggerNumber) | LPDAC_PCR_PTG_PERIOD(config->periodicTriggerWidth);
break;
case kDAC_FIFOWorkAsPeriodTriggerAndSwingMode:
tmp32 |= LPDAC_GCR_FIFOEN_MASK | LPDAC_GCR_PTGEN_MASK | LPDAC_GCR_SWMD_MASK;
/* Set trigger number and width. */
base->PCR =
LPDAC_PCR_PTG_NUM(config->periodicTriggerNumber) | LPDAC_PCR_PTG_PERIOD(config->periodicTriggerWidth);
break;
#endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
default: /* kDAC_FIFODisabled. */
break;
}
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG) && FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG
if (config->enableExternalTriggerSource)
{
tmp32 |= LPDAC_GCR_RCV_TRG_MASK; /* Use trigger source from another DAC. */
}
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL
if (false == config->enableLowerLowPowerMode)
{
tmp32 |= LPDAC_GCR_BUF_SPD_CTRL_MASK; /* Enable low power. */
}
#else
if (config->enableLowPowerMode)
{
tmp32 |= LPDAC_GCR_LPEN_MASK; /* Enable low power. */
}
#endif /* LPDAC_GCR_BUF_SPD_CTRL_MASK */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN
tmp32 |= LPDAC_GCR_BUF_EN_MASK; /* Opamp is used as buffer. */
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC) && FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC
/* Configure DAC sync cycles. */
tmp32 |= LPDAC_GCR_LATCH_CYC(config->syncTime);
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC */
#if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
tmp32 |= (uint32_t)config->referenceCurrentSource;
#endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
/* Set reference voltage source. */
tmp32 |= LPDAC_GCR_DACRFS(config->referenceVoltageSource);
base->GCR = tmp32;
base->FCR = LPDAC_FCR_WML(config->fifoWatermarkLevel);
/* Now, the DAC is disabled. It needs to be enabled in application. */
}
/*!
* 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)
{
assert(config != NULL);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->fifoWatermarkLevel = 0U;
config->fifoTriggerMode = kDAC_FIFOTriggerByHardwareMode;
config->fifoWorkMode = kDAC_FIFODisabled;
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG) && FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG
config->enableExternalTriggerSource = false;
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL
config->enableLowerLowPowerMode = true;
#else
config->enableLowPowerMode = false;
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL */
#if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
config->periodicTriggerNumber = 0UL;
config->periodicTriggerWidth = 0UL;
#endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC) && FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC
/* Configure DAC sync cycles. */
config->syncTime = 1U;
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC */
#if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
config->referenceCurrentSource = kDAC_ReferenceCurrentSourcePtat;
#endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
config->referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1;
}
/*!
* 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)
{
/* Disable the module. */
DAC_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

View File

@@ -0,0 +1,442 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020, 2022 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.1.2. */
#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
/*! @} */
/*!
* @brief DAC reset control.
*/
enum
{
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
{
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. */
#if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
kDAC_PeriodTriggerCompleteInterruptEnable =
LPDAC_IER_PTGCOCO_IE_MASK, /*!< Period trigger mode conversion complete interrupt enable */
#endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
};
/*!
* @brief DAC DMA switchers.
*/
enum
{
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
{
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. */
#if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
kDAC_PeriodTriggerCompleteFlag = LPDAC_FSR_PTGCOCO_MASK, /*!< Period trigger mode conversion complete flag. */
#endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
};
/*!
* @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. */
#if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
kDAC_FIFOWorkAsPeriodTriggerMode =
3U, /*!< In periodic trigger mode, user only needs to send the first trigger. Then after every [PTG_PERIOD+1]
RCLK cycles, DAC will be automatically triggered by internal trigger. There will be [PTG_NUM] internal
triggers, thus in total [PTG_NUM+1] conversions including the first trigger sent by user. User can
terminate the current conversion queue by clearing the GCR[PTGEN] bit. Then, after the current conversion
is completed, the conversion is terminated and the PTGCOCO flag is set. If PCR[PTG_NUM] is set to zero,
there will be infinite triggers following the first hardware/software trigger, until the GCR[PTGEN] is
cleared by software. In any case, the conversion can be terminated by FIFORST/SWRST. */
kDAC_FIFOWorkAsPeriodTriggerAndSwingMode = 4U, /*!< Periodically trigger DAC and swing back. */
#endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
} dac_fifo_work_mode_t;
/*!
* @brief DAC reference voltage source.
*/
typedef enum _dac_reference_voltage_source
{
#if defined(FSL_FEATURE_ANALOG_NUM_OF_VREF_SRC) && (FSL_FEATURE_ANALOG_NUM_OF_VREF_SRC == 3)
kDAC_ReferenceVoltageSourceAlt1 = 0U, /*!< The DAC selects VDD_ANA as the reference voltage. */
kDAC_ReferenceVoltageSourceAlt2 = 1U, /*!< The DAC selects VREF_OUT as the reference voltage. */
kDAC_ReferenceVoltageSourceAlt3 = 2U, /*!< THe DAC selects VREFH as the reference voltage. */
#else
kDAC_ReferenceVoltageSourceAlt1 = 0U, /*!< The DAC selects VREFH_INT as the reference voltage. */
kDAC_ReferenceVoltageSourceAlt2 = 1U, /*!< The DAC selects VREFH_EXT as the reference voltage. */
#endif /* FSL_FEATURE_ANALOG_NUM_OF_VREF_SRC */
} dac_reference_voltage_source_t;
#if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
/*
* @brief DAC internal reference current source
*/
typedef enum _dac_reference_current_source
{
kDAC_ReferenceCurrentSourcePtat = LPDAC_GCR_IREF_PTAT_EXT_SEL_MASK, /* Internal PTAT Current Reference selected */
kDAC_ReferenceCurrentSourceZtc = LPDAC_GCR_IREF_ZTC_EXT_SEL_MASK, /* Internal ZTC Current Reference selected */
} dac_reference_current_source_t;
#endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
/*!
* @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. */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN
bool enableOpampBuffer; /*!< Opamp is used as buffer. */
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG) && FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG
bool enableExternalTriggerSource; /* DAC uses another DAC's hardware/software trigger as its trigger source. */
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL
bool enableLowerLowPowerMode; /*!< Enable the lower low power mode. */
#else
bool enableLowPowerMode; /*!< Enable the low power mode. */
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL */
#if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
uint32_t periodicTriggerNumber; /*!< There will be 'periodicTriggerNumber' internal triggers following the first
hardware/software trigger. So there will be 'periodicTriggerNumber + 1'
conversions in total. If set to zero, there will be infinite triggers following
the first hw/sw trigger, until the GCR[PTGEN] is cleared. */
uint32_t periodicTriggerWidth; /*!< Control the periodic trigger frequency. There will be 'periodicTriggerWidth + 1'
RCLK cycles between each periodic trigger. The periodic trigger frequency should
be configured to not larger than the analog conversion speed. */
#endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
#if defined(FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC) && FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC
uint32_t syncTime; /*!< RCLK cycles before data latch. accessible range is 0-15. It is used to configure the DAC
sync cycles which is helpful to reduce glitch on the output. The sync time is (LATCH_CYC+1)
RCLK cycles. User should configure this register according to the RCLK frequency. The
recommended sync time is at least 40ns.*/
#endif /* FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC */
#if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
dac_reference_current_source_t referenceCurrentSource; /*!< Select the internal reference current source. */
#endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
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.
*/
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.
*/
void DAC_Deinit(LPDAC_Type *base);
/*!
* @brief Assert the reset control to part hardware.
*
* This function 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 function 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_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,357 @@
/*
* Copyright 2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FSL_EDMA_CORE_H_
#define FSL_EDMA_CORE_H_
#include "fsl_edma_soc.h"
/*!
* @addtogroup edma_core
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define DMA_CSR_INTMAJOR_MASK (0x2U)
#define DMA_CSR_INTHALF_MASK (0x4U)
#define DMA_CSR_DREQ_MASK (0x8U)
#define DMA_CSR_ESG_MASK (0x10U)
#define DMA_CSR_BWC_MASK (0xC000U)
#define DMA_CSR_BWC(x) (((uint16_t)(((uint16_t)(x)) << (14U))) & (0xC000U))
#define DMA_CSR_START_MASK (0x1U)
#define DMA_CITER_ELINKNO_CITER_MASK (0x7FFFU)
#define DMA_BITER_ELINKNO_BITER_MASK (0x7FFFU)
#define DMA_CITER_ELINKNO_CITER_SHIFT (0U)
#define DMA_CITER_ELINKYES_CITER_MASK (0x1FFU)
#define DMA_CITER_ELINKYES_CITER_SHIFT (0U)
#define DMA_ATTR_SMOD_MASK (0xF800U)
#define DMA_ATTR_DMOD_MASK (0xF8U)
#define DMA_CITER_ELINKNO_ELINK_MASK (0x8000U)
#define DMA_CSR_MAJORELINK_MASK (0x20U)
#define DMA_BITER_ELINKYES_ELINK_MASK (0x8000U)
#define DMA_CITER_ELINKYES_ELINK_MASK (0x8000U)
#define DMA_CSR_MAJORLINKCH_MASK (0x1F00U)
#define DMA_BITER_ELINKYES_LINKCH_MASK (0x3E00U)
#define DMA_CITER_ELINKYES_LINKCH_MASK (0x3E00U)
#define DMA_NBYTES_MLOFFYES_MLOFF_MASK (0x3FFFFC00U)
#define DMA_NBYTES_MLOFFYES_DMLOE_MASK (0x40000000U)
#define DMA_NBYTES_MLOFFYES_SMLOE_MASK (0x80000000U)
#define DMA_NBYTES_MLOFFNO_NBYTES_MASK (0x3FFFFFFFU)
#define DMA_ATTR_DMOD(x) (((uint16_t)(((uint16_t)(x)) << (3U))) & (0xF8U))
#define DMA_ATTR_SMOD(x) (((uint16_t)(((uint16_t)(x)) << (11U))) & (0xF800U))
#define DMA_BITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << (9U))) & (0x3E00U))
#define DMA_CITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << (9U))) & (0x3E00U))
#define DMA_NBYTES_MLOFFYES_MLOFF(x) (((uint32_t)(((uint32_t)(x)) << (10U))) & (0x3FFFFC00U))
#define DMA_NBYTES_MLOFFYES_DMLOE(x) (((uint32_t)(((uint32_t)(x)) << (30U))) & (0x40000000U))
#define DMA_NBYTES_MLOFFYES_SMLOE(x) (((uint32_t)(((uint32_t)(x)) << (31U))) & (0x80000000U))
#define DMA_NBYTES_MLOFFNO_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << (0U))) & (0x3FFFFFFFU))
#define DMA_NBYTES_MLOFFYES_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << (0U))) & (0x3FFU))
#define DMA_ATTR_DSIZE(x) (((uint16_t)(((uint16_t)(x)) << (0U))) & (0x7U))
#define DMA_ATTR_SSIZE(x) (((uint16_t)(((uint16_t)(x)) << (8U))) & (0x700U))
#define DMA_CSR_DREQ(x) (((uint16_t)(((uint16_t)(x)) << (3U))) & (0x8U))
#define DMA_CSR_MAJORLINKCH(x) (((uint16_t)(((uint16_t)(x)) << (8U))) & (0x1F00U))
#define DMA_CH_MATTR_WCACHE(x) (((uint16_t)(((uint16_t)(x)) << (4U))) & (0xF0U))
#define DMA_CH_MATTR_RCACHE(x) (((uint16_t)(((uint16_t)(x)) << (0U))) & (0xFU))
#define DMA_CH_CSR_SIGNEXT_MASK (0x3F0000U)
#define DMA_CH_CSR_SIGNEXT_SHIFT (16U)
#define DMA_CH_CSR_SWAP_MASK (0xF000U)
#define DMA_CH_CSR_SWAP_SHIFT (12U)
#define DMA_CH_SBR_INSTR_MASK (0x2000U)
#define DMA_CH_SBR_INSTR_SHIFT (13U)
#define DMA_CH_MUX_SOURCE(x) (((uint32_t)(((uint32_t)(x)) << (0U))) & (0xFFU))
/*! @brief DMA error flag */
#if defined(FSL_EDMA_SOC_IP_EDMA) && FSL_EDMA_SOC_IP_EDMA
#define DMA_ERR_DBE_FLAG DMA_ES_DBE_MASK
#define DMA_ERR_SBE_FLAG DMA_ES_SBE_MASK
#define DMA_ERR_SGE_FLAG DMA_ES_SGE_MASK
#define DMA_ERR_NCE_FLAG DMA_ES_NCE_MASK
#define DMA_ERR_DOE_FLAG DMA_ES_DOE_MASK
#define DMA_ERR_DAE_FLAG DMA_ES_DAE_MASK
#define DMA_ERR_SOE_FLAG DMA_ES_SOE_MASK
#define DMA_ERR_SAE_FLAG DMA_ES_SAE_MASK
#define DMA_ERR_ERRCHAN_FLAG DMA_ES_ERRCHN_MASK
#define DMA_ERR_CPE_FLAG DMA_ES_CPE_MASK
#define DMA_ERR_ECX_FLAG DMA_ES_ECX_MASK
#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && (FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1)
#define DMA_ERR_GPE_FLAG DMA_ES_GPE_MASK
#endif
#define DMA_ERR_FLAG DMA_ES_VLD_MASK
/*! @brief get/clear DONE status*/
#define DMA_CLEAR_DONE_STATUS(base, channel) (EDMA_BASE(base)->CDNE = (uint8_t)channel)
#define DMA_GET_DONE_STATUS(base, channel) \
((EDMA_TCD_BASE(base, channel)->CSR & DMA_CSR_DONE_MASK) >> DMA_CSR_DONE_SHIFT)
/*! @brief enable/disable error interrupt*/
#define DMA_ENABLE_ERROR_INT(base, channel) (base->EEI |= ((uint32_t)0x1U << channel))
#define DMA_DISABLE_ERROR_INT(base, channel) (base->EEI &= (~((uint32_t)0x1U << channel)))
/*! @brief get/clear error status*/
#define DMA_GET_ERROR_STATUS(base, channel) (((uint32_t)EDMA_BASE(base)->ERR >> channel) & 0x1U)
#define DMA_CLEAR_ERROR_STATUS(base, channel) ((uint32_t)EDMA_BASE(base)->CERR = (uint8_t)channel)
/*! @brief get/clear int status*/
#define DMA_GET_INT_STATUS(base, channel) ((((uint32_t)EDMA_BASE(base)->INT >> channel) & 0x1U))
#define DMA_CLEAR_INT_STATUS(base, channel) ((uint32_t)EDMA_BASE(base)->CINT = (uint8_t)channel)
#else
#define DMA_ERR_DBE_FLAG DMA_MP_ES_DBE_MASK
#define DMA_ERR_SBE_FLAG DMA_MP_ES_SBE_MASK
#define DMA_ERR_SGE_FLAG DMA_MP_ES_SGE_MASK
#define DMA_ERR_NCE_FLAG DMA_MP_ES_NCE_MASK
#define DMA_ERR_DOE_FLAG DMA_MP_ES_DOE_MASK
#define DMA_ERR_DAE_FLAG DMA_MP_ES_DAE_MASK
#define DMA_ERR_SOE_FLAG DMA_MP_ES_SOE_MASK
#define DMA_ERR_SAE_FLAG DMA_MP_ES_SAE_MASK
#define DMA_ERR_ERRCHAN_FLAG DMA_MP_ES_ERRCHN_MASK
#define DMA_ERR_ECX_FLAG DMA_MP_ES_ECX_MASK
#define DMA_ERR_FLAG DMA_MP_ES_VLD_MASK
/*! @brief get/clear DONE bit*/
#define DMA_CLEAR_DONE_STATUS(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_CSR |= DMA_CH_CSR_DONE_MASK)
#define DMA_GET_DONE_STATUS(base, channel) \
((EDMA_CHANNEL_BASE(base, channel)->CH_CSR & DMA_CH_CSR_DONE_MASK) >> DMA_CH_CSR_DONE_SHIFT)
/*! @brief enable/disable error interupt*/
#define DMA_ENABLE_ERROR_INT(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_CSR |= DMA_CH_CSR_EEI_MASK)
#define DMA_DISABLE_ERROR_INT(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_CSR &= ~DMA_CH_CSR_EEI_MASK)
/*! @brief get/clear error status*/
#define DMA_CLEAR_ERROR_STATUS(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_ES |= DMA_CH_ES_ERR_MASK)
#define DMA_GET_ERROR_STATUS(base, channel) \
(((uint32_t)EDMA_CHANNEL_BASE(base, channel)->CH_ES >> DMA_CH_ES_ERR_SHIFT) & 0x1U)
/*! @brief get/clear INT status*/
#define DMA_CLEAR_INT_STATUS(base, channel) (EDMA_CHANNEL_BASE(base, channel)->CH_INT = DMA_CH_INT_INT_MASK)
#define DMA_GET_INT_STATUS(base, channel) ((((uint32_t)EDMA_CHANNEL_BASE(base, channel)->CH_INT) & 0x1U))
#endif /*FSL_EDMA_SOC_IP_EDMA*/
/*! @brief enable/dsiable MAJOR/HALF INT*/
#define DMA_ENABLE_MAJOR_INT(base, channel) \
(EDMA_TCD_CSR(EDMA_TCD_BASE(base, channel), EDMA_TCD_TYPE(base)) |= DMA_CSR_INTMAJOR_MASK)
#define DMA_ENABLE_HALF_INT(base, channel) \
(EDMA_TCD_CSR(EDMA_TCD_BASE(base, channel), EDMA_TCD_TYPE(base)) |= DMA_CSR_INTHALF_MASK)
#define DMA_DISABLE_MAJOR_INT(base, channel) \
(EDMA_TCD_CSR(EDMA_TCD_BASE(base, channel), EDMA_TCD_TYPE(base)) &= ~(uint16_t)DMA_CSR_INTMAJOR_MASK)
#define DMA_DISABLE_HALF_INT(base, channel) \
(EDMA_TCD_CSR(EDMA_TCD_BASE(base, channel), EDMA_TCD_TYPE(base)) &= ~(uint16_t)DMA_CSR_INTHALF_MASK)
/*!@brief EDMA tcd align size */
#define EDMA_TCD_ALIGN_SIZE (32U)
/*!@brief edma core channel struture definition */
typedef struct _edma_core_mp
{
__IO uint32_t MP_CSR; /**< Channel Control and Status, array offset: 0x10000, array step: 0x10000 */
__IO uint32_t MP_ES; /**< Channel Error Status, array offset: 0x10004, array step: 0x10000 */
union
{
struct
{
__IO uint32_t MP_INT_LOW; /**< Channel Control and Status, array offset: 0x10008, array step: 0x10000 */
__I uint32_t MP_INT_HIGH; /**< Channel Control and Status, array offset: 0x1000C, array step: 0x10000 */
__I uint32_t MP_HRS_LOW; /**< Channel Control and Status, array offset: 0x10010, array step: 0x10000 */
__I uint32_t MP_HRS_HIGH; /**< Channel Control and Status, array offset: 0x10014, array step: 0x10000 */
uint8_t RESERVED_0[8];
__IO uint32_t MP_STOPCH; /**< Channel Control and Status, array offset: 0x10020, array step: 0x10000 */
uint8_t RESERVED_1[12];
__I uint32_t MP_SSR_LOW; /**< Channel Control and Status, array offset: 0x10030, array step: 0x10000 */
__I uint32_t MP_SSR_HIGH; /**< Channel Control and Status, array offset: 0x10034, array step: 0x10000 */
uint8_t RESERVED_2[200];
__IO uint32_t CH_GRPRI[64]; /**< Channel Control and Status, array offset: 0x10100, array step: 0x10000 */
__IO uint32_t CH_MUX[64]; /**< Channel Control and Status, array offset: 0x10200, array step: 0x10000 */
uint8_t RESERVED_3[256];
__IO uint32_t CH_PROT[64]; /**< Channel Control and Status, array offset: 0x10400, array step: 0x10000 */
} EDMA5_REG;
} MP_REGS;
} edma_core_mp_t;
/*!@brief edma core channel struture definition */
typedef struct _edma_core_channel
{
__IO uint32_t CH_CSR; /**< Channel Control and Status, array offset: 0x10000, array step: 0x10000 */
__IO uint32_t CH_ES; /**< Channel Error Status, array offset: 0x10004, array step: 0x10000 */
__IO uint32_t CH_INT; /**< Channel Interrupt Status, array offset: 0x10008, array step: 0x10000 */
__IO uint32_t CH_SBR; /**< Channel System Bus, array offset: 0x1000C, array step: 0x10000 */
__IO uint32_t CH_PRI; /**< Channel Priority, array offset: 0x10010, array step: 0x10000 */
union
{
struct
{
__IO uint8_t RESERVED_1[4];
__IO uint32_t CH_MATTR; /**< Memory Attributes Register, array offset: 0x10018, array step: 0x8000 */
} EDMA5_REG;
struct
{
__IO uint32_t CH_MUX; /**< Channel Multiplexor Configuration, array offset: 0x10014, array step: 0x10000 */
__IO uint16_t CH_MATTR; /**< Memory Attributes Register, array offset: 0x10018, array step: 0x8000 */
} EDMA4_REG;
} CH_REGS;
} edma_core_channel_t;
/*! @brief eDMA tcd flag type */
typedef enum _edma_tcd_type
{
kEDMA_EDMA4Flag = 0x0U, /*!< Data access for eDMA4 transfers. */
kEDMA_EDMA5Flag = 0x1U, /*!< Instruction access for eDMA4 transfers. */
} edma_tcd_type_t;
/*!@brief edma5 core TCD struture definition */
typedef struct _edma5_core_tcd
{
__IO uint32_t SADDR; /*!< SADDR register, used to save source address */
__IO uint32_t SADDR_HIGH; /*!< SADDR HIGH register, used to save source address */
__IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
__IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
__IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
__IO uint32_t SLAST; /*!< SLAST register */
__IO uint32_t SLAST_SDA_HIGH; /*!< SLAST SDA HIGH register */
__IO uint32_t DADDR; /*!< DADDR register, used for destination address */
__IO uint32_t DADDR_HIGH; /*!< DADDR HIGH register, used for destination address */
__IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next tcd address used in scatter-gather mode */
__IO uint32_t DLAST_SGA_HIGH; /*!< DLASTSGA HIGH register, next tcd address used in scatter-gather mode */
__IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
__IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
__IO uint16_t CSR; /*!< CSR register, for TCD control status */
__IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
uint8_t RESERVED[16]; /*!< Aligned 64 bytes */
} edma5_core_tcd_t;
/*!@brief edma4 core TCD struture definition */
typedef struct _edma4_core_tcd
{
__IO uint32_t SADDR; /*!< SADDR register, used to save source address */
__IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
__IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
__IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
__IO uint32_t SLAST; /*!< SLAST register */
__IO uint32_t DADDR; /*!< DADDR register, used for destination address */
__IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
__IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
__IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next tcd address used in scatter-gather mode */
__IO uint16_t CSR; /*!< CSR register, for TCD control status */
__IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
} edma4_core_tcd_t;
/*!@brief edma core TCD struture definition */
typedef struct _edma_core_tcd
{
union
{
edma4_core_tcd_t edma4_tcd;
#if defined FSL_EDMA_SOC_IP_DMA5 && FSL_EDMA_SOC_IP_DMA5
edma5_core_tcd_t edma5_tcd;
#endif /* FSL_EDMA_SOC_IP_DMA5 */
} TCD_REGS;
} edma_core_tcd_t;
/*!@brief EDMA typedef */
typedef edma_core_channel_t EDMA_ChannelType;
typedef edma_core_tcd_t EDMA_TCDType;
typedef void EDMA_Type;
/*!@brief EDMA base address convert macro */
#define EDMA_BASE(base)
#define EDMA_CHANNEL_BASE(base, channel) \
((edma_core_channel_t *)((uint32_t)(uint32_t *)(base) + EDMA_CHANNEL_OFFSET + \
(channel)*EDMA_CHANNEL_ARRAY_STEP(base)))
#define EDMA_TCD_BASE(base, channel) \
((edma_core_tcd_t *)((uint32_t)(uint32_t *)(base) + EDMA_CHANNEL_OFFSET + \
(channel)*EDMA_CHANNEL_ARRAY_STEP(base) + 0x20U))
#define EDMA_MP_BASE(base) ((edma_core_mp_t *)((uint32_t)(uint32_t *)(base)))
/*!@brief EDMA TCD type macro */
#if defined FSL_FEATURE_EDMA_TCD_TYPEn
#define EDMA_TCD_TYPE(x) FSL_FEATURE_EDMA_TCD_TYPEn(x)
#else
#define EDMA_TCD_TYPE(x) (0)
#endif
#if defined FSL_EDMA_SOC_IP_DMA5 && FSL_EDMA_SOC_IP_DMA5
/*!@brief EDMA TCD address convert macro */
#define EDMA_TCD_SADDR(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->SADDR)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->SADDR))))
#define EDMA_TCD_SOFF(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->SOFF)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->SOFF))))
#define EDMA_TCD_ATTR(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->ATTR)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->ATTR))))
#define EDMA_TCD_NBYTES(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->NBYTES)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->NBYTES))))
#define EDMA_TCD_SLAST(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->SLAST)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->SLAST))))
#define EDMA_TCD_DADDR(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->DADDR)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->DADDR))))
#define EDMA_TCD_DOFF(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->DOFF)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->DOFF))))
#define EDMA_TCD_CITER(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->CITER)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->CITER))))
#define EDMA_TCD_DLAST_SGA(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? \
(&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->DLAST_SGA)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->DLAST_SGA))))
#define EDMA_TCD_CSR(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->CSR)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->CSR))))
#define EDMA_TCD_BITER(tcd, flag) \
(*(((edma_tcd_type_t)(flag) == kEDMA_EDMA4Flag) ? (&(((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->BITER)) : \
(&(((edma5_core_tcd_t *)(&(tcd)->TCD_REGS.edma5_tcd))->BITER))))
#else
/*!@brief EDMA TCD address convert macro */
#define EDMA_TCD_SADDR(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->SADDR)
#define EDMA_TCD_SOFF(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->SOFF)
#define EDMA_TCD_ATTR(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->ATTR)
#define EDMA_TCD_NBYTES(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->NBYTES)
#define EDMA_TCD_SLAST(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->SLAST)
#define EDMA_TCD_DADDR(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->DADDR)
#define EDMA_TCD_DOFF(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->DOFF)
#define EDMA_TCD_CITER(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->CITER)
#define EDMA_TCD_DLAST_SGA(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->DLAST_SGA)
#define EDMA_TCD_CSR(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->CSR)
#define EDMA_TCD_BITER(tcd, flag) (((edma4_core_tcd_t *)(&(tcd)->TCD_REGS.edma4_tcd))->BITER)
#endif /* FSL_EDMA_SOC_IP_DMA5 */
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
/*!
* @}
*/
#endif /* FSL_EDMA_CORE_H_ */

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,381 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2022 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexcan_edma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.flexcan_edma"
#endif
/*<! Structure definition for flexcan_edma_private_handle_t. The structure is private. */
typedef struct _flexcan_edma_private_handle
{
CAN_Type *base;
flexcan_edma_handle_t *handle;
} flexcan_edma_private_handle_t;
/* FlexCAN EDMA transfer handle. */
enum _flexcan_edma_tansfer_state
{
KFLEXCAN_RxFifoIdle = 0U, /* Rx Fifo idle. */
KFLEXCAN_RxFifoBusy = 1U, /* Rx Fifo busy. */
};
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of FlexCAN peripheral base address. */
static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS;
/* Private handle only used for internally. */
static flexcan_edma_private_handle_t s_flexcanEdmaPrivateHandle[ARRAY_SIZE(s_flexcanBases)];
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief FlexCAN EDMA receive finished callback function.
*
* This function is called when FlexCAN Rx FIFO EDMA receive finished.
* It disables the FlexCAN Rx FIFO EDMA request and sends
* @ref kStatus_FLEXCAN_RxFifoIdle to FlexCAN EDMA callback.
*
* @param handle The EDMA handle.
* @param param Callback function parameter.
*/
static void FLEXCAN_ReceiveFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
/*******************************************************************************
* Code
******************************************************************************/
static void FLEXCAN_ReceiveFifoEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
handle = handle;
tcds = tcds;
#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
flexcan_fd_frame_t *framefd;
uint32_t idHitIndex;
#endif
flexcan_edma_private_handle_t *flexcanPrivateHandle = (flexcan_edma_private_handle_t *)param;
/*
* $Branch Coverage Justification$
* (!transferDone) not covered. Unable to simulate DMA transfer error.
*/
if (transferDone)
{
#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
if (0U != (flexcanPrivateHandle->base->ERFCR & CAN_ERFCR_ERFEN_MASK))
{
framefd = flexcanPrivateHandle->handle->framefd;
for (uint32_t i = 0; i < flexcanPrivateHandle->handle->frameNum; i++)
{
/* Enhanced Rx FIFO ID HIT offset is changed dynamically according to data length code (DLC) . */
idHitIndex = (DLC_LENGTH_DECODE(framefd->length) + 3U) / 4U;
framefd->idhit = framefd->dataWord[idHitIndex];
/* Clear the unused frame data. */
for (uint32_t j = idHitIndex; j < 16U; j++)
{
framefd->dataWord[j] = 0x0U;
}
framefd++;
}
}
#endif
/* Disable transfer. */
FLEXCAN_TransferAbortReceiveFifoEDMA(flexcanPrivateHandle->base, flexcanPrivateHandle->handle);
if (NULL != flexcanPrivateHandle->handle->callback)
{
flexcanPrivateHandle->handle->callback(flexcanPrivateHandle->base, flexcanPrivateHandle->handle,
kStatus_FLEXCAN_RxFifoIdle, flexcanPrivateHandle->handle->userData);
}
}
}
/*!
* brief Initializes the FlexCAN handle, which is used in transactional functions.
*
* param base FlexCAN peripheral base address.
* param handle Pointer to flexcan_edma_handle_t structure.
* param callback The callback function.
* param userData The parameter of the callback function.
* param rxFifoEdmaHandle User-requested DMA handle for Rx FIFO DMA transfer.
*/
void FLEXCAN_TransferCreateHandleEDMA(CAN_Type *base,
flexcan_edma_handle_t *handle,
flexcan_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *rxFifoEdmaHandle)
{
assert(NULL != handle);
uint32_t instance = FLEXCAN_GetInstance(base);
s_flexcanEdmaPrivateHandle[instance].base = base;
s_flexcanEdmaPrivateHandle[instance].handle = handle;
(void)memset(handle, 0, sizeof(flexcan_edma_handle_t));
handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoIdle;
handle->rxFifoEdmaHandle = rxFifoEdmaHandle;
/* Register Callback. */
handle->callback = callback;
handle->userData = userData;
/* Configure Legacy/Enhanced Rx FIFO DMA callback. */
EDMA_SetCallback(handle->rxFifoEdmaHandle, FLEXCAN_ReceiveFifoEDMACallback, &s_flexcanEdmaPrivateHandle[instance]);
}
/*!
* brief Prepares the eDMA transfer configuration for FLEXCAN Legacy RX FIFO.
*
* This function prepares the eDMA transfer configuration structure according to FLEXCAN Legacy RX FIFO.
*
* param base FlexCAN peripheral base address.
* param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
* param pEdmaConfig The user configuration structure of type edma_transfer_t.
*
*/
void FLEXCAN_PrepareTransfConfiguration(CAN_Type *base,
flexcan_fifo_transfer_t *pFifoXfer,
edma_transfer_config_t *pEdmaConfig)
{
assert(NULL != pFifoXfer);
assert(NULL != pFifoXfer->frame);
assert(NULL != pEdmaConfig);
flexcan_frame_t *fifoAddr = (flexcan_frame_t *)FLEXCAN_GetRxFifoHeadAddr(base);
#if (defined(FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER) && FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER)
EDMA_PrepareTransfer(pEdmaConfig, (void *)fifoAddr, sizeof(flexcan_frame_t), (void *)pFifoXfer->frame,
sizeof(uint32_t), sizeof(flexcan_frame_t), sizeof(flexcan_frame_t) * pFifoXfer->frameNum,
kEDMA_PeripheralToMemory);
#else
/* The Data Size of FLEXCAN Legacy RX FIFO output port is 16 Bytes, but lots of chips not support 16Bytes width DMA
* transfer. These chips always support 4Byte width memory transfer, so we need prepare Memory to Memory mode by 4
* Bytes width mode.
*/
EDMA_PrepareTransfer(pEdmaConfig, (void *)fifoAddr, 4U, (void *)pFifoXfer->frame, sizeof(uint32_t),
sizeof(flexcan_frame_t), sizeof(flexcan_frame_t) * pFifoXfer->frameNum, kEDMA_MemoryToMemory);
#endif
}
/*!
* brief Start Transfer Data from the FLEXCAN Legacy Rx FIFO using eDMA.
*
* This function to Update edma transfer confiugration and Start eDMA transfer
*
* param base FlexCAN peripheral base address.
* param handle Pointer to flexcan_edma_handle_t structure.
* param pEdmaConfig The user configuration structure of type edma_transfer_t.
* retval kStatus_Success if succeed, others failed.
* retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
*/
status_t FLEXCAN_StartTransferDatafromRxFIFO(CAN_Type *base,
flexcan_edma_handle_t *handle,
edma_transfer_config_t *pEdmaConfig)
{
assert(NULL != handle->rxFifoEdmaHandle);
assert(NULL != pEdmaConfig);
status_t status;
/* If previous Rx FIFO receive not finished. */
if ((uint8_t)KFLEXCAN_RxFifoBusy == handle->rxFifoState)
{
status = kStatus_FLEXCAN_RxFifoBusy;
}
else
{
handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoBusy;
/* Enable FlexCAN Rx FIFO EDMA. */
FLEXCAN_EnableRxFifoDMA(base, true);
/* Submit configuration. */
(void)EDMA_SubmitTransfer(handle->rxFifoEdmaHandle, (const edma_transfer_config_t *)pEdmaConfig);
EDMA_SetModulo(handle->rxFifoEdmaHandle->base, handle->rxFifoEdmaHandle->channel, kEDMA_Modulo16bytes,
kEDMA_ModuloDisable);
/* Start transfer. */
EDMA_StartTransfer(handle->rxFifoEdmaHandle);
status = kStatus_Success;
}
return status;
}
/*!
* brief Receives the CAN Messages from the Legacy Rx FIFO using eDMA.
*
* This function receives the CAN Message using eDMA. This is a non-blocking function, which returns
* right away. After the CAN Message is received, the receive callback function is called.
*
* param base FlexCAN peripheral base address.
* param handle Pointer to flexcan_edma_handle_t structure.
* param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
* retval kStatus_Success if succeed, others failed.
* retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
*/
status_t FLEXCAN_TransferReceiveFifoEDMA(CAN_Type *base,
flexcan_edma_handle_t *handle,
flexcan_fifo_transfer_t *pFifoXfer)
{
assert(NULL != handle->rxFifoEdmaHandle);
assert(NULL != pFifoXfer->frame);
edma_transfer_config_t dmaXferConfig = {0};
status_t status;
handle->frameNum = pFifoXfer->frameNum;
/* Prepare transfer. */
FLEXCAN_PrepareTransfConfiguration(base, pFifoXfer, &dmaXferConfig);
/* Submit configuration and start edma transfer. */
status = FLEXCAN_StartTransferDatafromRxFIFO(base, handle, &dmaXferConfig);
return status;
}
/*!
* brief Gets the Legacy Rx Fifo transfer status during a interrupt non-blocking receive.
*
* param base FlexCAN peripheral base address.
* param handle FlexCAN handle pointer.
* param count Number of CAN messages receive so far by the non-blocking transaction.
* retval kStatus_InvalidArgument count is Invalid.
* retval kStatus_Success Successfully return the count.
*/
status_t FLEXCAN_TransferGetReceiveFifoCountEMDA(CAN_Type *base, flexcan_edma_handle_t *handle, size_t *count)
{
assert(NULL != handle);
status_t result = kStatus_Success;
if (handle->rxFifoState == (uint32_t)KFLEXCAN_RxFifoIdle)
{
result = kStatus_NoTransferInProgress;
}
else
{
*count = handle->frameNum -
EDMA_GetRemainingMajorLoopCount(handle->rxFifoEdmaHandle->base, handle->rxFifoEdmaHandle->channel);
}
return result;
}
/*!
* brief Aborts the receive Legacy/Enhanced Rx FIFO process which used eDMA.
*
* This function aborts the receive Legacy/Enhanced Rx FIFO process which used eDMA.
*
* param base FlexCAN peripheral base address.
* param handle Pointer to flexcan_edma_handle_t structure.
*/
void FLEXCAN_TransferAbortReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle)
{
assert(NULL != handle->rxFifoEdmaHandle);
/* Stop transfer. */
EDMA_AbortTransfer(handle->rxFifoEdmaHandle);
handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoIdle;
#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
handle->framefd = NULL;
#endif
handle->frameNum = 0U;
/* Disable FlexCAN Legacy/Enhanced Rx FIFO EDMA. */
FLEXCAN_EnableRxFifoDMA(base, false);
}
#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
/*!
* brief Receives the CAN FD Message from the Enhanced Rx FIFO using eDMA.
*
* This function receives the CAN FD Message using eDMA. This is a non-blocking function, which returns
* right away. After the CAN Message is received, the receive callback function is called.
*
* param base FlexCAN peripheral base address.
* param handle Pointer to flexcan_edma_handle_t structure.
* param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
* retval kStatus_Success if succeed, others failed.
* retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
* retval kStatus_InvalidArgument The watermark configuration is invalid, the watermark need be set to
1 to do successfully EDMA transfer with this API.
*/
status_t FLEXCAN_TransferReceiveEnhancedFifoEDMA(CAN_Type *base,
flexcan_edma_handle_t *handle,
flexcan_fifo_transfer_t *pFifoXfer)
{
assert(NULL != handle->rxFifoEdmaHandle);
assert(NULL != pFifoXfer->framefd);
edma_transfer_config_t dmaXferConfig;
edma_minor_offset_config_t dmaMinorOffsetConfig;
status_t status;
flexcan_fd_frame_t *fifoAddr = (flexcan_fd_frame_t *)E_RX_FIFO(base);
uint32_t perReadWords = ((base->ERFCR & CAN_ERFCR_DMALW_MASK) >> CAN_ERFCR_DMALW_SHIFT) + 1U;
uint32_t watermark = ((base->ERFCR & CAN_ERFCR_ERFWM_MASK) >> CAN_ERFCR_ERFWM_SHIFT) + 1U;
/* If previous Rx FIFO receive not finished. */
if ((uint8_t)KFLEXCAN_RxFifoBusy == handle->rxFifoState)
{
status = kStatus_FLEXCAN_RxFifoBusy;
}
else
{
handle->frameNum = pFifoXfer->frameNum;
handle->framefd = pFifoXfer->framefd;
/*!< To reduce the complexity of DMA software configuration, need to set watermark to 1 to make that each DMA
request read once Rx FIFO. Because a DMA transfer cannot be dynamically changed, Number of words read per
transfer (ERFCR[DMALW] + 1) should be programmed so that the Enhanced Rx FIFO element can store the largest
CAN message present on the CAN bus. */
if ((watermark != 1U) || ((sizeof(uint32_t) * perReadWords) != sizeof(flexcan_fd_frame_t)))
{
return kStatus_InvalidArgument;
}
/* Prepare transfer. */
EDMA_PrepareTransfer(
&dmaXferConfig, (void *)fifoAddr, sizeof(uint32_t), (void *)pFifoXfer->framefd, sizeof(uint32_t),
sizeof(uint32_t) * perReadWords, /* minor loop bytes : 4* perReadWords */
sizeof(uint32_t) * perReadWords * handle->frameNum, /* major loop counts : handle->frameNum */
kEDMA_MemoryToMemory);
/* Submit configuration. */
(void)EDMA_SubmitTransfer(handle->rxFifoEdmaHandle, &dmaXferConfig);
dmaMinorOffsetConfig.enableDestMinorOffset = false;
dmaMinorOffsetConfig.enableSrcMinorOffset = true;
dmaMinorOffsetConfig.minorOffset = 128U - sizeof(uint32_t) * perReadWords;
EDMA_SetMinorOffsetConfig(handle->rxFifoEdmaHandle->base, handle->rxFifoEdmaHandle->channel,
&dmaMinorOffsetConfig);
EDMA_SetModulo(handle->rxFifoEdmaHandle->base, handle->rxFifoEdmaHandle->channel, kEDMA_Modulo128bytes,
kEDMA_ModuloDisable);
handle->rxFifoState = (uint8_t)KFLEXCAN_RxFifoBusy;
/* Enable FlexCAN Rx FIFO EDMA. */
FLEXCAN_EnableRxFifoDMA(base, true);
/* Start transfer. */
EDMA_StartTransfer(handle->rxFifoEdmaHandle);
status = kStatus_Success;
}
return status;
}
#endif

View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FSL_FLEXCAN_EDMA_H_
#define FSL_FLEXCAN_EDMA_H_
#include "fsl_flexcan.h"
#include "fsl_edma.h"
/*!
* @addtogroup flexcan_edma_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*! @{ */
/*! @brief FlexCAN EDMA driver version. */
#define FSL_FLEXCAN_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 11, 3))
/*! @} */
/* Forward declaration of the handle typedef. */
typedef struct _flexcan_edma_handle flexcan_edma_handle_t;
/*! @brief FlexCAN transfer callback function. */
typedef void (*flexcan_edma_transfer_callback_t)(CAN_Type *base,
flexcan_edma_handle_t *handle,
status_t status,
void *userData);
/*!
* @brief FlexCAN eDMA handle
*/
struct _flexcan_edma_handle
{
flexcan_edma_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< FlexCAN callback function parameter.*/
edma_handle_t *rxFifoEdmaHandle; /*!< The EDMA handler for Rx FIFO. */
volatile uint8_t rxFifoState; /*!< Rx FIFO transfer state. */
size_t frameNum; /*!< The number of messages that need to be received. */
#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
flexcan_fd_frame_t *framefd; /*!< Point to the buffer of CAN Message to be received from Enhanced Rx FIFO. */
#endif
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name eDMA transactional
* @{
*/
/*!
* @brief Initializes the FlexCAN handle, which is used in transactional functions.
*
* @param base FlexCAN peripheral base address.
* @param handle Pointer to flexcan_edma_handle_t structure.
* @param callback The callback function.
* @param userData The parameter of the callback function.
* @param rxFifoEdmaHandle User-requested DMA handle for Rx FIFO DMA transfer.
*/
void FLEXCAN_TransferCreateHandleEDMA(CAN_Type *base,
flexcan_edma_handle_t *handle,
flexcan_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *rxFifoEdmaHandle);
/*!
* @brief Prepares the eDMA transfer configuration for FLEXCAN Legacy RX FIFO.
*
* This function prepares the eDMA transfer configuration structure according to FLEXCAN Legacy RX FIFO.
*
* @param base FlexCAN peripheral base address.
* @param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
* @param pEdmaConfig The user configuration structure of type edma_transfer_t.
*
*/
void FLEXCAN_PrepareTransfConfiguration(CAN_Type *base,
flexcan_fifo_transfer_t *pFifoXfer,
edma_transfer_config_t *pEdmaConfig);
/*!
* @brief Start Transfer Data from the FLEXCAN Legacy Rx FIFO using eDMA.
*
* This function to Update edma transfer confiugration and Start eDMA transfer
*
* @param base FlexCAN peripheral base address.
* @param handle Pointer to flexcan_edma_handle_t structure.
* @param pEdmaConfig The user configuration structure of type edma_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
*/
status_t FLEXCAN_StartTransferDatafromRxFIFO(CAN_Type *base,
flexcan_edma_handle_t *handle,
edma_transfer_config_t *pEdmaConfig);
/*!
* @brief Receives the CAN Message from the Legacy Rx FIFO using eDMA.
*
* This function receives the CAN Message using eDMA. This is a non-blocking function, which returns
* right away. After the CAN Message is received, the receive callback function is called.
*
* @param base FlexCAN peripheral base address.
* @param handle Pointer to flexcan_edma_handle_t structure.
* @param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
*/
status_t FLEXCAN_TransferReceiveFifoEDMA(CAN_Type *base,
flexcan_edma_handle_t *handle,
flexcan_fifo_transfer_t *pFifoXfer);
/*!
* @brief Gets the Legacy Rx Fifo transfer status during a interrupt non-blocking receive.
*
* @param base FlexCAN peripheral base address.
* @param handle FlexCAN handle pointer.
* @param count Number of CAN messages receive so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXCAN_TransferGetReceiveFifoCountEMDA(CAN_Type *base, flexcan_edma_handle_t *handle, size_t *count);
/*!
* @brief Aborts the receive Legacy/Enhanced Rx FIFO process which used eDMA.
*
* This function aborts the receive Legacy/Enhanced Rx FIFO process which used eDMA.
*
* @param base FlexCAN peripheral base address.
* @param handle Pointer to flexcan_edma_handle_t structure.
*/
void FLEXCAN_TransferAbortReceiveFifoEDMA(CAN_Type *base, flexcan_edma_handle_t *handle);
#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
/*!
* @brief Receives the CAN FD Message from the Enhanced Rx FIFO using eDMA.
*
* This function receives the CAN FD Message using eDMA. This is a non-blocking function, which returns
* right away. After the CAN Message is received, the receive callback function is called.
*
* @param base FlexCAN peripheral base address.
* @param handle Pointer to flexcan_edma_handle_t structure.
* @param pFifoXfer FlexCAN Rx FIFO EDMA transfer structure, see #flexcan_fifo_transfer_t.
* @retval kStatus_Success if succeed, others failed.
* @retval kStatus_FLEXCAN_RxFifoBusy Previous transfer ongoing.
*/
status_t FLEXCAN_TransferReceiveEnhancedFifoEDMA(CAN_Type *base,
flexcan_edma_handle_t *handle,
flexcan_fifo_transfer_t *pFifoXfer);
/*!
* @brief Gets the Enhanced Rx Fifo transfer status during a interrupt non-blocking receive.
*
* @param base FlexCAN peripheral base address.
* @param handle FlexCAN handle pointer.
* @param count Number of CAN messages receive so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
static inline status_t FLEXCAN_TransferGetReceiveEnhancedFifoCountEMDA(CAN_Type *base,
flexcan_edma_handle_t *handle,
size_t *count)
{
return FLEXCAN_TransferGetReceiveFifoCountEMDA(base, handle, count);
}
#endif
/*! @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* FSL_FLEXCAN_EDMA_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,485 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2020 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 */
/*! @{ */
#define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 5, 0))
/*! @} */
/*! @brief Retry times for waiting flag. */
#ifndef I2C_RETRY_TIMES
#define I2C_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */
#endif
/*! @brief FlexIO I2C transfer status*/
enum
{
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. */
kStatus_FLEXIO_I2C_Timeout = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 3), /*!< Timeout polling status flags. */
};
/*! @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[3]; /*!< Timer index used in FlexIO I2C. */
uint32_t baudrate; /*!< Master transfer baudrate, used to calculate delay time. */
} 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. */
bool needRestart; /*!< Whether master needs to send re-start signal. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name Initialization and deinitialization
* @{
*/
#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
/*!
* @brief Make sure the bus isn't already pulled down.
*
* Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down.
*
* @param base Pointer to FLEXIO_I2C_Type structure..
* @retval kStatus_Success
* @retval kStatus_FLEXIO_I2C_Busy
*/
status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base);
#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
/*!
* @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 Resets the FlexIO I2C master
* shifer and timer config, 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 does not have any effect.
*/
static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable)
{
if (enable)
{
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, uint16_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 (uint8_t)(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.
* @retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
*/
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.
* @retval kStatus_Success Successfully read data.
* @retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
*/
status_t 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_MasterTransferGetCount 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_NoTransferInProgress There is not a non-blocking transaction currently in progress.
* @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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020,2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FSL_FLEXIO_MCULCD_EDMA_H_
#define FSL_FLEXIO_MCULCD_EDMA_H_
#include "fsl_edma.h"
#include "fsl_flexio_mculcd.h"
/*!
* @addtogroup flexio_edma_mculcd
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @{ */
/*! @brief FlexIO MCULCD EDMA driver version. */
#define FSL_FLEXIO_MCULCD_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 5))
/*! @} */
/*! @brief typedef for flexio_mculcd_edma_handle_t in advance. */
typedef struct _flexio_mculcd_edma_handle flexio_mculcd_edma_handle_t;
/*! @brief FlexIO MCULCD master callback for transfer complete.
*
* When transfer finished, the callback function is called and returns the
* @p status as kStatus_FLEXIO_MCULCD_Idle.
*/
typedef void (*flexio_mculcd_edma_transfer_callback_t)(FLEXIO_MCULCD_Type *base,
flexio_mculcd_edma_handle_t *handle,
status_t status,
void *userData);
/*! @brief FlexIO MCULCD eDMA transfer handle, users should not touch the
* content of the handle.*/
struct _flexio_mculcd_edma_handle
{
FLEXIO_MCULCD_Type *base; /*!< Pointer to the FLEXIO_MCULCD_Type. */
uint8_t txShifterNum; /*!< Number of shifters used for TX. */
uint8_t rxShifterNum; /*!< Number of shifters used for RX. */
uint32_t minorLoopBytes; /*!< eDMA transfer minor loop bytes. */
edma_modulo_t txEdmaModulo; /*!< Modulo value for the FlexIO shifter buffer access. */
edma_modulo_t rxEdmaModulo; /*!< Modulo value for the FlexIO shifter buffer access. */
uint32_t dataAddrOrSameValue; /*!< When sending the same value for many times,
this is the value to send. When writing or
reading array, this is the address of the
data array. */
size_t dataCount; /*!< Total count to be transferred. */
volatile size_t remainingCount; /*!< Remaining count still not transfered. */
volatile uint32_t state; /*!< FlexIO MCULCD driver internal state. */
edma_handle_t *txDmaHandle; /*!< DMA handle for MCULCD TX */
edma_handle_t *rxDmaHandle; /*!< DMA handle for MCULCD RX */
flexio_mculcd_edma_transfer_callback_t completionCallback; /*!< Callback for MCULCD DMA transfer */
void *userData; /*!< User Data for MCULCD DMA callback */
};
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name eDMA Transactional
* @{
*/
/*!
* @brief Initializes the FLEXO MCULCD master eDMA handle.
*
* This function initializes the FLEXO MCULCD master eDMA handle which can be
* used for other FLEXO MCULCD transactional APIs. For a specified FLEXO MCULCD
* instance, call this API once to get the initialized handle.
*
* @param base Pointer to FLEXIO_MCULCD_Type structure.
* @param handle Pointer to flexio_mculcd_edma_handle_t structure to store the
* transfer state.
* @param callback MCULCD transfer complete callback, NULL means no callback.
* @param userData callback function parameter.
* @param txDmaHandle User requested eDMA handle for FlexIO MCULCD eDMA TX,
* the DMA request source of this handle should be the first of TX shifters.
* @param rxDmaHandle User requested eDMA handle for FlexIO MCULCD eDMA RX,
* the DMA request source of this handle should be the last of RX shifters.
* @retval kStatus_Success Successfully create the handle.
*/
status_t FLEXIO_MCULCD_TransferCreateHandleEDMA(FLEXIO_MCULCD_Type *base,
flexio_mculcd_edma_handle_t *handle,
flexio_mculcd_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txDmaHandle,
edma_handle_t *rxDmaHandle);
/*!
* @brief Performs a non-blocking FlexIO MCULCD transfer using eDMA.
*
* This function returns immediately after transfer initiates. To check whether
* the transfer is completed, user could:
* 1. Use the transfer completed callback;
* 2. Polling function FLEXIO_MCULCD_GetTransferCountEDMA
*
* @param base pointer to FLEXIO_MCULCD_Type structure.
* @param handle pointer to flexio_mculcd_edma_handle_t structure to store the
* transfer state.
* @param xfer Pointer to FlexIO MCULCD transfer structure.
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_InvalidArgument Input argument is invalid.
* @retval kStatus_FLEXIO_MCULCD_Busy FlexIO MCULCD is not idle, it is running another
* transfer.
*/
status_t FLEXIO_MCULCD_TransferEDMA(FLEXIO_MCULCD_Type *base,
flexio_mculcd_edma_handle_t *handle,
flexio_mculcd_transfer_t *xfer);
/*!
* @brief Aborts a FlexIO MCULCD transfer using eDMA.
*
* @param base pointer to FLEXIO_MCULCD_Type structure.
* @param handle FlexIO MCULCD eDMA handle pointer.
*/
void FLEXIO_MCULCD_TransferAbortEDMA(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle);
/*!
* @brief Gets the remaining bytes for FlexIO MCULCD eDMA transfer.
*
* @param base pointer to FLEXIO_MCULCD_Type structure.
* @param handle FlexIO MCULCD eDMA handle pointer.
* @param count Number of count transferred so far by the eDMA transaction.
* @retval kStatus_Success Get the transferred count Successfully.
* @retval kStatus_NoTransferInProgress No transfer in process.
*/
status_t FLEXIO_MCULCD_TransferGetCountEDMA(FLEXIO_MCULCD_Type *base,
flexio_mculcd_edma_handle_t *handle,
size_t *count);
/*! @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* FSL_FLEXIO_MCULCD_EDMA_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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