/* * 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_*/