753 lines
25 KiB
C
753 lines
25 KiB
C
|
/*
|
||
|
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||
|
* Copyright 2016-2021 NXP
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||
|
*/
|
||
|
#ifndef _FSL_MU_H_
|
||
|
#define _FSL_MU_H_
|
||
|
|
||
|
#include "fsl_common.h"
|
||
|
|
||
|
/*!
|
||
|
* @addtogroup mu
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Definitions
|
||
|
*****************************************************************************/
|
||
|
|
||
|
/* Compatibility Macros */
|
||
|
#ifndef MU_CR_NMI_MASK
|
||
|
#define MU_CR_NMI_MASK 0U
|
||
|
#endif
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
|
||
|
|
||
|
#ifndef FSL_FEATURE_MU_HAS_RESET_ASSERT_INT
|
||
|
#define FSL_FEATURE_MU_HAS_RESET_ASSERT_INT 1
|
||
|
#endif
|
||
|
|
||
|
#ifndef FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT
|
||
|
#define FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT 1
|
||
|
#endif
|
||
|
|
||
|
#endif /* FSL_FEATURE_MU_HAS_RESET_INT */
|
||
|
|
||
|
/*! @name Driver version */
|
||
|
/*@{*/
|
||
|
/*! @brief MU driver version. */
|
||
|
#define FSL_MU_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
|
||
|
/*@}*/
|
||
|
|
||
|
/*!
|
||
|
* @brief MU status flags.
|
||
|
*/
|
||
|
enum _mu_status_flags
|
||
|
{
|
||
|
kMU_Tx0EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 3U)), /*!< TX0 empty. */
|
||
|
kMU_Tx1EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 2U)), /*!< TX1 empty. */
|
||
|
kMU_Tx2EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 1U)), /*!< TX2 empty. */
|
||
|
kMU_Tx3EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 0U)), /*!< TX3 empty. */
|
||
|
|
||
|
kMU_Rx0FullFlag = (1U << (MU_SR_RFn_SHIFT + 3U)), /*!< RX0 full. */
|
||
|
kMU_Rx1FullFlag = (1U << (MU_SR_RFn_SHIFT + 2U)), /*!< RX1 full. */
|
||
|
kMU_Rx2FullFlag = (1U << (MU_SR_RFn_SHIFT + 1U)), /*!< RX2 full. */
|
||
|
kMU_Rx3FullFlag = (1U << (MU_SR_RFn_SHIFT + 0U)), /*!< RX3 full. */
|
||
|
|
||
|
kMU_GenInt0Flag = (1U << (MU_SR_GIPn_SHIFT + 3U)), /*!< General purpose interrupt 0 pending. */
|
||
|
kMU_GenInt1Flag = (1U << (MU_SR_GIPn_SHIFT + 2U)), /*!< General purpose interrupt 0 pending. */
|
||
|
kMU_GenInt2Flag = (1U << (MU_SR_GIPn_SHIFT + 1U)), /*!< General purpose interrupt 0 pending. */
|
||
|
kMU_GenInt3Flag = (1U << (MU_SR_GIPn_SHIFT + 0U)), /*!< General purpose interrupt 0 pending. */
|
||
|
|
||
|
kMU_EventPendingFlag = MU_SR_EP_MASK, /*!< MU event pending. */
|
||
|
kMU_FlagsUpdatingFlag = MU_SR_FUP_MASK, /*!< MU flags update is on-going. */
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
kMU_ResetAssertInterruptFlag = MU_SR_RAIP_MASK, /*!< The other core reset assert interrupt pending. */
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT)
|
||
|
kMU_ResetDeassertInterruptFlag = MU_SR_RDIP_MASK, /*!< The other core reset de-assert interrupt pending. */
|
||
|
#endif
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
|
||
|
kMU_OtherSideInResetFlag = MU_SR_RS_MASK, /*!< The other side is in reset. */
|
||
|
#endif
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
|
||
|
kMU_MuResetInterruptFlag = MU_SR_MURIP_MASK, /*!< The other side initializes MU reset. */
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
|
||
|
kMU_HardwareResetInterruptFlag = MU_SR_HRIP_MASK, /*!< Current side has been hardware reset by the other side. */
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
* @brief MU interrupt source to enable.
|
||
|
*/
|
||
|
enum _mu_interrupt_enable
|
||
|
{
|
||
|
kMU_Tx0EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 3U)), /*!< TX0 empty. */
|
||
|
kMU_Tx1EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 2U)), /*!< TX1 empty. */
|
||
|
kMU_Tx2EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 1U)), /*!< TX2 empty. */
|
||
|
kMU_Tx3EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 0U)), /*!< TX3 empty. */
|
||
|
|
||
|
kMU_Rx0FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 3U)), /*!< RX0 full. */
|
||
|
kMU_Rx1FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 2U)), /*!< RX1 full. */
|
||
|
kMU_Rx2FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 1U)), /*!< RX2 full. */
|
||
|
kMU_Rx3FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 0U)), /*!< RX3 full. */
|
||
|
|
||
|
kMU_GenInt0InterruptEnable = (int)(1U << (MU_CR_GIEn_SHIFT + 3U)), /*!< General purpose interrupt 0. */
|
||
|
kMU_GenInt1InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 2U)), /*!< General purpose interrupt 1. */
|
||
|
kMU_GenInt2InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 1U)), /*!< General purpose interrupt 2. */
|
||
|
kMU_GenInt3InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 0U)), /*!< General purpose interrupt 3. */
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
kMU_ResetAssertInterruptEnable = MU_CR_RAIE_MASK, /*!< The other core reset assert interrupt. */
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
kMU_ResetDeassertInterruptEnable = MU_CR_RDIE_MASK, /*!< The other core reset de-assert interrupt. */
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
|
||
|
kMU_MuResetInterruptEnable = MU_CR_MURIE_MASK, /*!< The other side initializes MU reset. The interrupt
|
||
|
is ORed with the general purpose interrupt 3. The
|
||
|
general purpose interrupt 3 is issued when the other side
|
||
|
set the MU reset and this interrupt is enabled. */
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
|
||
|
kMU_HardwareResetInterruptEnable = MU_CR_HRIE_MASK, /*!< Current side has been hardware reset by the other side. */
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
* @brief MU interrupt that could be triggered to the other core.
|
||
|
*/
|
||
|
enum _mu_interrupt_trigger
|
||
|
{
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_NMI) && FSL_FEATURE_MU_NO_NMI)
|
||
|
kMU_NmiInterruptTrigger = MU_CR_NMI_MASK, /*!< NMI interrupt. */
|
||
|
#endif
|
||
|
kMU_GenInt0InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 3U)), /*!< General purpose interrupt 0. */
|
||
|
kMU_GenInt1InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 2U)), /*!< General purpose interrupt 1. */
|
||
|
kMU_GenInt2InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 1U)), /*!< General purpose interrupt 2. */
|
||
|
kMU_GenInt3InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 0U)) /*!< General purpose interrupt 3. */
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
* @brief MU message register.
|
||
|
*/
|
||
|
typedef enum _mu_msg_reg_index
|
||
|
{
|
||
|
kMU_MsgReg0 = 0,
|
||
|
kMU_MsgReg1,
|
||
|
kMU_MsgReg2,
|
||
|
kMU_MsgReg3,
|
||
|
} mu_msg_reg_index_t;
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* API
|
||
|
******************************************************************************/
|
||
|
|
||
|
#if defined(__cplusplus)
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/*!
|
||
|
* @name MU initialization.
|
||
|
* @{
|
||
|
*/
|
||
|
/*!
|
||
|
* @brief Initializes the MU module.
|
||
|
*
|
||
|
* This function enables the MU clock only.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
*/
|
||
|
void MU_Init(MU_Type *base);
|
||
|
|
||
|
/*!
|
||
|
* @brief De-initializes the MU module.
|
||
|
*
|
||
|
* This function disables the MU clock only.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
*/
|
||
|
void MU_Deinit(MU_Type *base);
|
||
|
|
||
|
/* @} */
|
||
|
|
||
|
/*!
|
||
|
* @name MU Message
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/*!
|
||
|
* @brief Writes a message to the TX register.
|
||
|
*
|
||
|
* This function writes a message to the specific TX register. It does not check
|
||
|
* whether the TX register is empty or not. The upper layer should make sure the TX
|
||
|
* register is empty before calling this function. This function can be used
|
||
|
* in ISR for better performance.
|
||
|
*
|
||
|
* @code
|
||
|
* while (!(kMU_Tx0EmptyFlag & MU_GetStatusFlags(base))) { } Wait for TX0 register empty.
|
||
|
* MU_SendMsgNonBlocking(base, kMU_MsgReg0, MSG_VAL); Write message to the TX0 register.
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param regIndex TX register index, see @ref mu_msg_reg_index_t.
|
||
|
* @param msg Message to send.
|
||
|
*/
|
||
|
static inline void MU_SendMsgNonBlocking(MU_Type *base, uint32_t regIndex, uint32_t msg)
|
||
|
{
|
||
|
assert(regIndex < MU_TR_COUNT);
|
||
|
|
||
|
base->TR[regIndex] = msg;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Blocks to send a message.
|
||
|
*
|
||
|
* This function waits until the TX register is empty and sends the message.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param regIndex MU message register, see @ref mu_msg_reg_index_t
|
||
|
* @param msg Message to send.
|
||
|
*/
|
||
|
void MU_SendMsg(MU_Type *base, uint32_t regIndex, uint32_t msg);
|
||
|
|
||
|
/*!
|
||
|
* @brief Reads a message from the RX register.
|
||
|
*
|
||
|
* This function reads a message from the specific RX register. It does not check
|
||
|
* whether the RX register is full or not. The upper layer should make sure the RX
|
||
|
* register is full before calling this function. This function can be used
|
||
|
* in ISR for better performance.
|
||
|
*
|
||
|
* @code
|
||
|
* uint32_t msg;
|
||
|
* while (!(kMU_Rx0FullFlag & MU_GetStatusFlags(base)))
|
||
|
* {
|
||
|
* } Wait for the RX0 register full.
|
||
|
*
|
||
|
* msg = MU_ReceiveMsgNonBlocking(base, kMU_MsgReg0); Read message from RX0 register.
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param RX register index, see @ref mu_msg_reg_index_t.
|
||
|
* @return The received message.
|
||
|
*/
|
||
|
static inline uint32_t MU_ReceiveMsgNonBlocking(MU_Type *base, uint32_t regIndex)
|
||
|
{
|
||
|
assert(regIndex < MU_TR_COUNT);
|
||
|
|
||
|
return base->RR[regIndex];
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Blocks to receive a message.
|
||
|
*
|
||
|
* This function waits until the RX register is full and receives the message.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param regIndex MU message register, see @ref mu_msg_reg_index_t
|
||
|
* @return The received message.
|
||
|
*/
|
||
|
uint32_t MU_ReceiveMsg(MU_Type *base, uint32_t regIndex);
|
||
|
|
||
|
/* @} */
|
||
|
|
||
|
/*!
|
||
|
* @name MU Flags
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/*!
|
||
|
* @brief Sets the 3-bit MU flags reflect on the other MU side.
|
||
|
*
|
||
|
* This function sets the 3-bit MU flags directly. Every time the 3-bit MU flags are changed,
|
||
|
* the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
|
||
|
* updating to the other side. After the 3-bit MU flags are updated, the status flag
|
||
|
* \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
|
||
|
* the flags cannot be changed. The upper layer should make sure the status flag
|
||
|
* \c kMU_FlagsUpdatingFlag is cleared before calling this function.
|
||
|
*
|
||
|
* @code
|
||
|
* while (kMU_FlagsUpdatingFlag & MU_GetStatusFlags(base))
|
||
|
* {
|
||
|
* } Wait for previous MU flags updating.
|
||
|
*
|
||
|
* MU_SetFlagsNonBlocking(base, 0U); Set the mU flags.
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param flags The 3-bit MU flags to set.
|
||
|
*/
|
||
|
static inline void MU_SetFlagsNonBlocking(MU_Type *base, uint32_t flags)
|
||
|
{
|
||
|
uint32_t reg = base->CR;
|
||
|
reg = (reg & ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | MU_CR_Fn_MASK)) | MU_CR_Fn(flags);
|
||
|
base->CR = reg;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Blocks setting the 3-bit MU flags reflect on the other MU side.
|
||
|
*
|
||
|
* This function blocks setting the 3-bit MU flags. Every time the 3-bit MU flags are changed,
|
||
|
* the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
|
||
|
* updating to the other side. After the 3-bit MU flags are updated, the status flag
|
||
|
* \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
|
||
|
* the flags cannot be changed. This function waits for the MU status flag
|
||
|
* \c kMU_FlagsUpdatingFlag cleared and sets the 3-bit MU flags.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param flags The 3-bit MU flags to set.
|
||
|
*/
|
||
|
void MU_SetFlags(MU_Type *base, uint32_t flags);
|
||
|
|
||
|
/*!
|
||
|
* @brief Gets the current value of the 3-bit MU flags set by the other side.
|
||
|
*
|
||
|
* This function gets the current 3-bit MU flags on the current side.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @return flags Current value of the 3-bit flags.
|
||
|
*/
|
||
|
static inline uint32_t MU_GetFlags(MU_Type *base)
|
||
|
{
|
||
|
return (base->SR & MU_SR_Fn_MASK) >> MU_SR_Fn_SHIFT;
|
||
|
}
|
||
|
|
||
|
/* @} */
|
||
|
|
||
|
/*!
|
||
|
* @name Status and Interrupt.
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/*!
|
||
|
* @brief Gets the MU status flags.
|
||
|
*
|
||
|
* This function returns the bit mask of the MU status flags. See _mu_status_flags.
|
||
|
*
|
||
|
* @code
|
||
|
* uint32_t flags;
|
||
|
* flags = MU_GetStatusFlags(base); Get all status flags.
|
||
|
* if (kMU_Tx0EmptyFlag & flags)
|
||
|
* {
|
||
|
* The TX0 register is empty. Message can be sent.
|
||
|
* MU_SendMsgNonBlocking(base, kMU_MsgReg0, MSG0_VAL);
|
||
|
* }
|
||
|
* if (kMU_Tx1EmptyFlag & flags)
|
||
|
* {
|
||
|
* The TX1 register is empty. Message can be sent.
|
||
|
* MU_SendMsgNonBlocking(base, kMU_MsgReg1, MSG1_VAL);
|
||
|
* }
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @return Bit mask of the MU status flags, see _mu_status_flags.
|
||
|
*/
|
||
|
static inline uint32_t MU_GetStatusFlags(MU_Type *base)
|
||
|
{
|
||
|
return (base->SR & (MU_SR_TEn_MASK | MU_SR_RFn_MASK | MU_SR_GIPn_MASK | MU_SR_EP_MASK | MU_SR_FUP_MASK
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
|
||
|
| MU_SR_RS_MASK
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
| MU_SR_RAIP_MASK
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
| MU_SR_RDIP_MASK
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
|
||
|
| MU_SR_MURIP_MASK
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
|
||
|
| MU_SR_HRIP_MASK
|
||
|
#endif
|
||
|
));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Gets the MU IRQ pending status.
|
||
|
*
|
||
|
* This function returns the bit mask of the pending MU IRQs.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @return Bit mask of the MU IRQs pending.
|
||
|
*/
|
||
|
static inline uint32_t MU_GetInterruptsPending(MU_Type *base)
|
||
|
{
|
||
|
uint32_t irqMask = base->CR & (MU_CR_GIEn_MASK | MU_CR_TIEn_MASK | MU_CR_RIEn_MASK);
|
||
|
return (base->SR & irqMask);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Clears the specific MU status flags.
|
||
|
*
|
||
|
* This function clears the specific MU status flags. The flags to clear should
|
||
|
* be passed in as bit mask. See _mu_status_flags.
|
||
|
*
|
||
|
* @code
|
||
|
* Clear general interrupt 0 and general interrupt 1 pending flags.
|
||
|
* MU_ClearStatusFlags(base, kMU_GenInt0Flag | kMU_GenInt1Flag);
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mask Bit mask of the MU status flags. See _mu_status_flags. The following
|
||
|
* flags are cleared by hardware, this function could not clear them.
|
||
|
* - kMU_Tx0EmptyFlag
|
||
|
* - kMU_Tx1EmptyFlag
|
||
|
* - kMU_Tx2EmptyFlag
|
||
|
* - kMU_Tx3EmptyFlag
|
||
|
* - kMU_Rx0FullFlag
|
||
|
* - kMU_Rx1FullFlag
|
||
|
* - kMU_Rx2FullFlag
|
||
|
* - kMU_Rx3FullFlag
|
||
|
* - kMU_EventPendingFlag
|
||
|
* - kMU_FlagsUpdatingFlag
|
||
|
* - kMU_OtherSideInResetFlag
|
||
|
*/
|
||
|
static inline void MU_ClearStatusFlags(MU_Type *base, uint32_t mask)
|
||
|
{
|
||
|
/* regMask is the mask of w1c status bits. */
|
||
|
uint32_t regMask = MU_SR_GIPn_MASK;
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
regMask |= MU_SR_RAIP_MASK;
|
||
|
#endif
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT)
|
||
|
regMask |= MU_SR_RDIP_MASK;
|
||
|
#endif
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
|
||
|
regMask |= MU_SR_MURIP_MASK;
|
||
|
#endif
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
|
||
|
regMask |= MU_SR_HRIP_MASK;
|
||
|
#endif
|
||
|
|
||
|
base->SR = (mask & regMask);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Enables the specific MU interrupts.
|
||
|
*
|
||
|
* This function enables the specific MU interrupts. The interrupts to enable
|
||
|
* should be passed in as bit mask. See _mu_interrupt_enable.
|
||
|
*
|
||
|
* @code
|
||
|
* Enable general interrupt 0 and TX0 empty interrupt.
|
||
|
* MU_EnableInterrupts(base, kMU_GenInt0InterruptEnable | kMU_Tx0EmptyInterruptEnable);
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mask Bit mask of the MU interrupts. See _mu_interrupt_enable.
|
||
|
*/
|
||
|
static inline void MU_EnableInterrupts(MU_Type *base, uint32_t mask)
|
||
|
{
|
||
|
uint32_t reg = base->CR;
|
||
|
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | mask;
|
||
|
base->CR = reg;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Disables the specific MU interrupts.
|
||
|
*
|
||
|
* This function disables the specific MU interrupts. The interrupts to disable
|
||
|
* should be passed in as bit mask. See _mu_interrupt_enable.
|
||
|
*
|
||
|
* @code
|
||
|
* Disable general interrupt 0 and TX0 empty interrupt.
|
||
|
* MU_DisableInterrupts(base, kMU_GenInt0InterruptEnable | kMU_Tx0EmptyInterruptEnable);
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mask Bit mask of the MU interrupts. See _mu_interrupt_enable.
|
||
|
*/
|
||
|
static inline void MU_DisableInterrupts(MU_Type *base, uint32_t mask)
|
||
|
{
|
||
|
uint32_t reg = base->CR;
|
||
|
reg &= ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | mask);
|
||
|
base->CR = reg;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Triggers interrupts to the other core.
|
||
|
*
|
||
|
* This function triggers the specific interrupts to the other core. The interrupts
|
||
|
* to trigger are passed in as bit mask. See \ref _mu_interrupt_trigger.
|
||
|
* The MU should not trigger an interrupt to the other core when the previous interrupt
|
||
|
* has not been processed by the other core. This function checks whether the
|
||
|
* previous interrupts have been processed. If not, it returns an error.
|
||
|
*
|
||
|
* @code
|
||
|
* if (kStatus_Success != MU_TriggerInterrupts(base, kMU_GenInt0InterruptTrigger | kMU_GenInt2InterruptTrigger))
|
||
|
* {
|
||
|
* Previous general purpose interrupt 0 or general purpose interrupt 2
|
||
|
* has not been processed by the other core.
|
||
|
* }
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mask Bit mask of the interrupts to trigger. See _mu_interrupt_trigger.
|
||
|
* @retval kStatus_Success Interrupts have been triggered successfully.
|
||
|
* @retval kStatus_Fail Previous interrupts have not been accepted.
|
||
|
*/
|
||
|
status_t MU_TriggerInterrupts(MU_Type *base, uint32_t mask);
|
||
|
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_NMI) && FSL_FEATURE_MU_NO_NMI)
|
||
|
/*!
|
||
|
* @brief Clear non-maskable interrupt (NMI) sent by the other core.
|
||
|
*
|
||
|
* This function clears non-maskable interrupt (NMI) sent by the other core.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
*/
|
||
|
static inline void MU_ClearNmi(MU_Type *base)
|
||
|
{
|
||
|
base->SR = MU_SR_NMIC_MASK;
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_NO_NMI */
|
||
|
|
||
|
/* @} */
|
||
|
|
||
|
/*!
|
||
|
* @name MU misc functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH)
|
||
|
/*!
|
||
|
* @brief Boots the core at B side.
|
||
|
*
|
||
|
* This function sets the B side core's boot configuration and releases the
|
||
|
* core from reset.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mode Core B boot mode.
|
||
|
* @note Only MU side A can use this function.
|
||
|
*/
|
||
|
void MU_BootCoreB(MU_Type *base, mu_core_boot_mode_t mode);
|
||
|
|
||
|
/*!
|
||
|
* @brief Holds the core reset of B side.
|
||
|
*
|
||
|
* This function causes the core of B side to be held in reset following any reset event.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @note Only A side could call this function.
|
||
|
*/
|
||
|
static inline void MU_HoldCoreBReset(MU_Type *base)
|
||
|
{
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
|
||
|
base->CCR |= MU_CCR_RSTH_MASK;
|
||
|
#else /* FSL_FEATURE_MU_HAS_CCR */
|
||
|
uint32_t reg = base->CR;
|
||
|
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | MU_CR_RSTH_MASK;
|
||
|
base->CR = reg;
|
||
|
#endif /* FSL_FEATURE_MU_HAS_CCR */
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* @brief Boots the other core.
|
||
|
*
|
||
|
* This function boots the other core with a boot configuration.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mode The other core boot mode.
|
||
|
*/
|
||
|
void MU_BootOtherCore(MU_Type *base, mu_core_boot_mode_t mode);
|
||
|
|
||
|
/*!
|
||
|
* @brief Holds the other core reset.
|
||
|
*
|
||
|
* This function causes the other core to be held in reset following any reset event.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
*/
|
||
|
static inline void MU_HoldOtherCoreReset(MU_Type *base)
|
||
|
{
|
||
|
/*
|
||
|
* MU_HoldOtherCoreReset and MU_HoldCoreBReset are the same, MU_HoldCoreBReset
|
||
|
* is kept for compatible with older platforms.
|
||
|
*/
|
||
|
MU_HoldCoreBReset(base);
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_NO_RSTH */
|
||
|
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_MUR) && FSL_FEATURE_MU_NO_MUR)
|
||
|
/*!
|
||
|
* @brief Resets the MU for both A side and B side.
|
||
|
*
|
||
|
* This function resets the MU for both A side and B side. Before reset, it is
|
||
|
* recommended to interrupt processor B, because this function may affect the
|
||
|
* ongoing processor B programs.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @note For some platforms, only MU side A could use this function, check
|
||
|
* reference manual for details.
|
||
|
*/
|
||
|
static inline void MU_ResetBothSides(MU_Type *base)
|
||
|
{
|
||
|
uint32_t reg = base->CR;
|
||
|
reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | MU_CR_MUR_MASK;
|
||
|
base->CR = reg;
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
|
||
|
/* Wait for the other side out of reset. */
|
||
|
while (0U != (base->SR & MU_SR_RS_MASK))
|
||
|
{
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_HAS_SR_RS */
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_NO_MUR */
|
||
|
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_HRM) && FSL_FEATURE_MU_HAS_HRM)
|
||
|
/*!
|
||
|
* @brief Mask hardware reset by the other core.
|
||
|
*
|
||
|
* The other core could call MU_HardwareResetOtherCore() to reset current core.
|
||
|
* To mask the reset, call this function and pass in true.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param mask Pass true to mask the hardware reset, pass false to unmask it.
|
||
|
*/
|
||
|
static inline void MU_MaskHardwareReset(MU_Type *base, bool mask)
|
||
|
{
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
|
||
|
if (mask)
|
||
|
{
|
||
|
base->CCR |= MU_CCR_HRM_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base->CCR &= ~MU_CCR_HRM_MASK;
|
||
|
}
|
||
|
#else /* FSL_FEATURE_MU_HAS_CCR */
|
||
|
if (mask)
|
||
|
{
|
||
|
base->CR |= MU_CR_HRM_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base->CR &= ~MU_CR_HRM_MASK;
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_HAS_CCR */
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_HAS_HRM */
|
||
|
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_HR) && FSL_FEATURE_MU_NO_HR)
|
||
|
/*!
|
||
|
* @brief Hardware reset the other core.
|
||
|
*
|
||
|
* This function resets the other core, the other core could mask the
|
||
|
* hardware reset by calling MU_MaskHardwareReset. The hardware reset
|
||
|
* mask feature is only available for some platforms.
|
||
|
* This function could be used together with MU_BootOtherCore to control the
|
||
|
* other core reset workflow.
|
||
|
*
|
||
|
* Example 1: Reset the other core, and no hold reset
|
||
|
* @code
|
||
|
* MU_HardwareResetOtherCore(MU_A, true, false, bootMode);
|
||
|
* @endcode
|
||
|
* In this example, the core at MU side B will reset with the specified boot mode.
|
||
|
*
|
||
|
* Example 2: Reset the other core and hold it, then boot the other core later.
|
||
|
* @code
|
||
|
* Here the other core enters reset, and the reset is hold
|
||
|
* MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare);
|
||
|
* Current core boot the other core when necessary.
|
||
|
* MU_BootOtherCore(MU_A, bootMode);
|
||
|
* @endcode
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param waitReset Wait the other core enters reset.
|
||
|
* - true: Wait until the other core enters reset, if the other
|
||
|
* core has masked the hardware reset, then this function will
|
||
|
* be blocked.
|
||
|
* - false: Don't wait the reset.
|
||
|
* @param holdReset Hold the other core reset or not.
|
||
|
* - true: Hold the other core in reset, this function returns
|
||
|
* directly when the other core enters reset.
|
||
|
* - false: Don't hold the other core in reset, this function
|
||
|
* waits until the other core out of reset.
|
||
|
* @param bootMode Boot mode of the other core, if @p holdReset is true, this
|
||
|
* parameter is useless.
|
||
|
*/
|
||
|
void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode);
|
||
|
#endif /* FSL_FEATURE_MU_NO_HR */
|
||
|
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_CLKE) && FSL_FEATURE_MU_NO_CLKE)
|
||
|
/*!
|
||
|
* @brief Enables or disables the clock on the other core.
|
||
|
*
|
||
|
* This function enables or disables the platform clock on the other core when
|
||
|
* that core enters a stop mode. If disabled, the platform clock for the other
|
||
|
* core is disabled when it enters stop mode. If enabled, the platform clock
|
||
|
* keeps running on the other core in stop mode, until this core also enters
|
||
|
* stop mode.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @param enable Enable or disable the clock on the other core.
|
||
|
*/
|
||
|
static inline void MU_SetClockOnOtherCoreEnable(MU_Type *base, bool enable)
|
||
|
{
|
||
|
#if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
|
||
|
if (enable)
|
||
|
{
|
||
|
base->CCR |= MU_CCR_CLKE_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base->CCR &= ~MU_CCR_CLKE_MASK;
|
||
|
}
|
||
|
#else /* FSL_FEATURE_MU_HAS_CCR */
|
||
|
uint32_t reg = base->CR;
|
||
|
|
||
|
reg &= ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK);
|
||
|
|
||
|
if (enable)
|
||
|
{
|
||
|
reg |= MU_CR_CLKE_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
reg &= ~MU_CR_CLKE_MASK;
|
||
|
}
|
||
|
|
||
|
base->CR = reg;
|
||
|
#endif /* FSL_FEATURE_MU_HAS_CCR */
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_NO_CLKE */
|
||
|
|
||
|
#if !(defined(FSL_FEATURE_MU_NO_PM) && FSL_FEATURE_MU_NO_PM)
|
||
|
/*!
|
||
|
* @brief Gets the power mode of the other core.
|
||
|
*
|
||
|
* This function gets the power mode of the other core.
|
||
|
*
|
||
|
* @param base MU peripheral base address.
|
||
|
* @return Power mode of the other core.
|
||
|
*/
|
||
|
static inline mu_power_mode_t MU_GetOtherCorePowerMode(MU_Type *base)
|
||
|
{
|
||
|
uint32_t ret = (base->SR & MU_SR_PM_MASK) >> MU_SR_PM_SHIFT;
|
||
|
|
||
|
return (mu_power_mode_t)ret;
|
||
|
}
|
||
|
#endif /* FSL_FEATURE_MU_NO_PM */
|
||
|
|
||
|
/* @} */
|
||
|
|
||
|
#if defined(__cplusplus)
|
||
|
}
|
||
|
#endif /*_cplusplus*/
|
||
|
/*@}*/
|
||
|
|
||
|
#endif /* _FSL_MU_H_*/
|