1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_MU_H_
9 #define _FSL_MU_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup mu
15  * @{
16  */
17 
18 /******************************************************************************
19  * Definitions
20  *****************************************************************************/
21 
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief MU driver version 2.0.1. */
25 #define FSL_MU_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
26 /*@}*/
27 
28 /*!
29  * @brief MU status flags.
30  */
31 enum _mu_status_flags
32 {
33     kMU_Tx0EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 3U)), /*!< TX0 empty. */
34     kMU_Tx1EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 2U)), /*!< TX1 empty. */
35     kMU_Tx2EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 1U)), /*!< TX2 empty. */
36     kMU_Tx3EmptyFlag = (1U << (MU_SR_TEn_SHIFT + 0U)), /*!< TX3 empty. */
37 
38     kMU_Rx0FullFlag = (1U << (MU_SR_RFn_SHIFT + 3U)), /*!< RX0 full.  */
39     kMU_Rx1FullFlag = (1U << (MU_SR_RFn_SHIFT + 2U)), /*!< RX1 full.  */
40     kMU_Rx2FullFlag = (1U << (MU_SR_RFn_SHIFT + 1U)), /*!< RX2 full.  */
41     kMU_Rx3FullFlag = (1U << (MU_SR_RFn_SHIFT + 0U)), /*!< RX3 full.  */
42 
43     kMU_GenInt0Flag = (1U << (MU_SR_GIPn_SHIFT + 3U)), /*!< General purpose interrupt 0 pending. */
44     kMU_GenInt1Flag = (1U << (MU_SR_GIPn_SHIFT + 2U)), /*!< General purpose interrupt 0 pending. */
45     kMU_GenInt2Flag = (1U << (MU_SR_GIPn_SHIFT + 1U)), /*!< General purpose interrupt 0 pending. */
46     kMU_GenInt3Flag = (1U << (MU_SR_GIPn_SHIFT + 0U)), /*!< General purpose interrupt 0 pending. */
47 
48     kMU_EventPendingFlag = MU_SR_EP_MASK,   /*!< MU event pending.               */
49     kMU_FlagsUpdatingFlag = MU_SR_FUP_MASK, /*!< MU flags update is on-going.    */
50 
51 #if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
52     kMU_ResetAssertInterruptFlag = MU_SR_RAIP_MASK,   /*!< The other core reset assert interrupt pending.    */
53     kMU_ResetDeassertInterruptFlag = MU_SR_RDIP_MASK, /*!< The other core reset de-assert interrupt pending. */
54 #endif
55 
56 #if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
57     kMU_OtherSideInResetFlag = MU_SR_RS_MASK /*!< The other side is in reset. */
58 #endif
59 
60 #if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
61     kMU_MuResetInterruptFlag = MU_SR_MURIP_MASK, /*!< The other side initializes MU reset. */
62 #endif
63 #if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
64     kMU_HardwareResetInterruptFlag = MU_SR_HRIP_MASK, /*!< Current side has been hardware reset by the other side. */
65 #endif
66 };
67 
68 /*!
69  * @brief MU interrupt source to enable.
70  */
71 enum _mu_interrupt_enable
72 {
73     kMU_Tx0EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 3U)), /*!< TX0 empty. */
74     kMU_Tx1EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 2U)), /*!< TX1 empty. */
75     kMU_Tx2EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 1U)), /*!< TX2 empty. */
76     kMU_Tx3EmptyInterruptEnable = (1U << (MU_CR_TIEn_SHIFT + 0U)), /*!< TX3 empty. */
77 
78     kMU_Rx0FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 3U)), /*!< RX0 full.  */
79     kMU_Rx1FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 2U)), /*!< RX1 full.  */
80     kMU_Rx2FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 1U)), /*!< RX2 full.  */
81     kMU_Rx3FullInterruptEnable = (1U << (MU_CR_RIEn_SHIFT + 0U)), /*!< RX3 full.  */
82 
83     kMU_GenInt0InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 3U)), /*!< General purpose interrupt 0. */
84     kMU_GenInt1InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 2U)), /*!< General purpose interrupt 1. */
85     kMU_GenInt2InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 1U)), /*!< General purpose interrupt 2. */
86     kMU_GenInt3InterruptEnable = (1U << (MU_CR_GIEn_SHIFT + 0U)), /*!< General purpose interrupt 3. */
87 
88 #if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
89     kMU_ResetAssertInterruptEnable = MU_CR_RAIE_MASK,   /*!< The other core reset assert interrupt.    */
90     kMU_ResetDeassertInterruptEnable = MU_CR_RDIE_MASK, /*!< The other core reset de-assert interrupt. */
91 #endif
92 #if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
93     kMU_MuResetInterruptEnable = MU_CR_MURIE_MASK, /*!< The other side initializes MU reset. The interrupt
94                                                      is ORed with the general purpose interrupt 3. The
95                                                      general purpose interrupt 3 is issued when the other side
96                                                      set the MU reset and this interrupt is enabled. */
97 #endif
98 #if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
99     kMU_HardwareResetInterruptEnable = MU_CR_HRIE_MASK, /*!< Current side has been hardware reset by the other side. */
100 #endif
101 };
102 
103 /*!
104  * @brief MU interrupt that could be triggered to the other core.
105  */
106 enum _mu_interrupt_trigger
107 {
108     kMU_NmiInterruptTrigger = MU_CR_NMI_MASK,                      /*!< NMI interrupt.               */
109     kMU_GenInt0InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 3U)), /*!< General purpose interrupt 0. */
110     kMU_GenInt1InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 2U)), /*!< General purpose interrupt 1. */
111     kMU_GenInt2InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 1U)), /*!< General purpose interrupt 2. */
112     kMU_GenInt3InterruptTrigger = (1U << (MU_CR_GIRn_SHIFT + 0U))  /*!< General purpose interrupt 3. */
113 };
114 
115 /*******************************************************************************
116  * API
117  ******************************************************************************/
118 
119 #if defined(__cplusplus)
120 extern "C" {
121 #endif
122 
123 /*!
124  * @name MU initialization.
125  * @{
126  */
127 /*!
128  * @brief Initializes the MU module.
129  *
130  * This function enables the MU clock only.
131  *
132  * @param base MU peripheral base address.
133  */
134 void MU_Init(MU_Type *base);
135 
136 /*!
137  * @brief De-initializes the MU module.
138  *
139  * This function disables the MU clock only.
140  *
141  * @param base MU peripheral base address.
142  */
143 void MU_Deinit(MU_Type *base);
144 
145 /* @} */
146 
147 /*!
148  * @name MU Message
149  * @{
150  */
151 
152 /*!
153  * @brief Writes a message to the TX register.
154  *
155  * This function writes a message to the specific TX register. It does not check
156  * whether the TX register is empty or not. The upper layer should make sure the TX
157  * register is empty before calling this function. This function can be used
158  * in ISR for better performance.
159  *
160  * @code
161  * while (!(kMU_Tx0EmptyFlag & MU_GetStatusFlags(base))) { } // Wait for TX0 register empty.
162  * MU_SendMsgNonBlocking(base, 0U, MSG_VAL); // Write message to the TX0 register.
163  * @endcode
164  *
165  * @param base MU peripheral base address.
166  * @param regIndex  TX register index.
167  * @param msg      Message to send.
168  */
MU_SendMsgNonBlocking(MU_Type * base,uint32_t regIndex,uint32_t msg)169 static inline void MU_SendMsgNonBlocking(MU_Type *base, uint32_t regIndex, uint32_t msg)
170 {
171     assert(regIndex < MU_TR_COUNT);
172 
173     base->TR[regIndex] = msg;
174 }
175 
176 /*!
177  * @brief Blocks to send a message.
178  *
179  * This function waits until the TX register is empty and sends the message.
180  *
181  * @param base MU peripheral base address.
182  * @param regIndex  TX register index.
183  * @param msg      Message to send.
184  */
185 void MU_SendMsg(MU_Type *base, uint32_t regIndex, uint32_t msg);
186 
187 /*!
188  * @brief Reads a message from the RX register.
189  *
190  * This function reads a message from the specific RX register. It does not check
191  * whether the RX register is full or not. The upper layer should make sure the RX
192  * register is full before calling this function. This function can be used
193  * in ISR for better performance.
194  *
195  * @code
196  * uint32_t msg;
197  * while (!(kMU_Rx0FullFlag & MU_GetStatusFlags(base)))
198  * {
199  * } // Wait for the RX0 register full.
200  *
201  * msg = MU_ReceiveMsgNonBlocking(base, 0U);  // Read message from RX0 register.
202  * @endcode
203  *
204  * @param base MU peripheral base address.
205  * @param regIndex  TX register index.
206  * @return The received message.
207  */
MU_ReceiveMsgNonBlocking(MU_Type * base,uint32_t regIndex)208 static inline uint32_t MU_ReceiveMsgNonBlocking(MU_Type *base, uint32_t regIndex)
209 {
210     assert(regIndex < MU_TR_COUNT);
211 
212     return base->RR[regIndex];
213 }
214 
215 /*!
216  * @brief Blocks to receive a message.
217  *
218  * This function waits until the RX register is full and receives the message.
219  *
220  * @param base MU peripheral base address.
221  * @param regIndex  RX register index.
222  * @return The received message.
223  */
224 uint32_t MU_ReceiveMsg(MU_Type *base, uint32_t regIndex);
225 
226 /* @} */
227 
228 /*!
229  * @name MU Flags
230  * @{
231  */
232 
233 /*!
234  * @brief Sets the 3-bit MU flags reflect on the other MU side.
235  *
236  * This function sets the 3-bit MU flags directly. Every time the 3-bit MU flags are changed,
237  * the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
238  * updating to the other side. After the 3-bit MU flags are updated, the status flag
239  * \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
240  * the flags cannot be changed. The upper layer should make sure the status flag
241  * \c kMU_FlagsUpdatingFlag is cleared before calling this function.
242  *
243  * @code
244  * while (kMU_FlagsUpdatingFlag & MU_GetStatusFlags(base))
245  * {
246  * } // Wait for previous MU flags updating.
247  *
248  * MU_SetFlagsNonBlocking(base, 0U); // Set the mU flags.
249  * @endcode
250  *
251  * @param base MU peripheral base address.
252  * @param flags The 3-bit MU flags to set.
253  */
MU_SetFlagsNonBlocking(MU_Type * base,uint32_t flags)254 static inline void MU_SetFlagsNonBlocking(MU_Type *base, uint32_t flags)
255 {
256     uint32_t reg = base->CR;
257     reg = (reg & ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | MU_CR_Fn_MASK)) | MU_CR_Fn(flags);
258     base->CR = reg;
259 }
260 
261 /*!
262  * @brief Blocks setting the 3-bit MU flags reflect on the other MU side.
263  *
264  * This function blocks setting the 3-bit MU flags. Every time the 3-bit MU flags are changed,
265  * the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are
266  * updating to the other side. After the 3-bit MU flags are updated, the status flag
267  * \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period,
268  * the flags cannot be changed. This function waits for the MU status flag
269  * \c kMU_FlagsUpdatingFlag cleared and sets the 3-bit MU flags.
270  *
271  * @param base MU peripheral base address.
272  * @param flags The 3-bit MU flags to set.
273  */
274 void MU_SetFlags(MU_Type *base, uint32_t flags);
275 
276 /*!
277  * @brief Gets the current value of the 3-bit MU flags set by the other side.
278  *
279  * This functions gets the current 3-bit MU flags on the current side.
280  *
281  * @param base MU peripheral base address.
282  * @return flags   Current value of the 3-bit flags.
283  */
MU_GetFlags(MU_Type * base)284 static inline uint32_t MU_GetFlags(MU_Type *base)
285 {
286     return (base->SR & MU_SR_Fn_MASK) >> MU_SR_Fn_SHIFT;
287 }
288 
289 /* @} */
290 
291 /*!
292  * @name Status and Interrupt.
293  * @{
294  */
295 
296 /*!
297  * @brief Gets the MU status flags.
298  *
299  * This function returns the bit mask of the MU status flags. See _mu_status_flags.
300  *
301  * @code
302  * uint32_t flags;
303  * flags = MU_GetStatusFlags(base); // Get all status flags.
304  * if (kMU_Tx0EmptyFlag & flags)
305  * {
306  *     // The TX0 register is empty. Message can be sent.
307  *     MU_SendMsgNonBlocking(base, 0U, MSG0_VAL);
308  * }
309  * if (kMU_Tx1EmptyFlag & flags)
310  * {
311  *     // The TX1 register is empty. Message can be sent.
312  *     MU_SendMsgNonBlocking(base, 1U, MSG1_VAL);
313  * }
314  * @endcode
315  *
316  * @param base MU peripheral base address.
317  * @return      Bit mask of the MU status flags, see _mu_status_flags.
318  */
MU_GetStatusFlags(MU_Type * base)319 static inline uint32_t MU_GetStatusFlags(MU_Type *base)
320 {
321     return (base->SR & (MU_SR_TEn_MASK | MU_SR_RFn_MASK | MU_SR_GIPn_MASK | MU_SR_EP_MASK | MU_SR_FUP_MASK
322 #if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
323                 | MU_SR_RS_MASK
324 #endif
325 #if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
326                 | MU_SR_RDIP_MASK | MU_SR_RAIP_MASK
327 #endif
328 #if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
329                 | MU_SR_MURIP_MASK
330 #endif
331 #if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
332                 | MU_SR_HRIP_MASK
333 #endif
334                 ));
335 }
336 
337 /*!
338  * @brief Clears the specific MU status flags.
339  *
340  * This function clears the specific MU status flags. The flags to clear should
341  * be passed in as bit mask. See _mu_status_flags.
342  *
343  * @code
344  * //Clear general interrupt 0 and general interrupt 1 pending flags.
345  * MU_ClearStatusFlags(base, kMU_GenInt0Flag | kMU_GenInt1Flag);
346  * @endcode
347  *
348  * @param base MU peripheral base address.
349  * @param mask  Bit mask of the MU status flags. See _mu_status_flags. The following
350  *              flags are cleared by hardware, this function could not clear them.
351  *                - kMU_Tx0EmptyFlag
352  *                - kMU_Tx1EmptyFlag
353  *                - kMU_Tx2EmptyFlag
354  *                - kMU_Tx3EmptyFlag
355  *                - kMU_Rx0FullFlag
356  *                - kMU_Rx1FullFlag
357  *                - kMU_Rx2FullFlag
358  *                - kMU_Rx3FullFlag
359  *                - kMU_EventPendingFlag
360  *                - kMU_FlagsUpdatingFlag
361  *                - kMU_OtherSideInResetFlag
362  */
MU_ClearStatusFlags(MU_Type * base,uint32_t mask)363 static inline void MU_ClearStatusFlags(MU_Type *base, uint32_t mask)
364 {
365     /* regMask is the mask of w1c status bits. */
366     uint32_t regMask = MU_SR_GIPn_MASK;
367 
368 #if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
369     regMask |= (MU_SR_RDIP_MASK | MU_SR_RAIP_MASK);
370 #endif
371 
372 #if (defined(FSL_FEATURE_MU_HAS_SR_MURIP) && FSL_FEATURE_MU_HAS_SR_MURIP)
373     regMask |= MU_SR_MURIP_MASK;
374 #endif
375 
376 #if (defined(FSL_FEATURE_MU_HAS_SR_HRIP) && FSL_FEATURE_MU_HAS_SR_HRIP)
377     regMask |= MU_SR_HRIP_MASK;
378 #endif
379 
380     base->SR = (mask & regMask);
381 }
382 
383 /*!
384  * @brief Enables the specific MU interrupts.
385  *
386  * This function enables the specific MU interrupts. The interrupts to enable
387  * should be passed in as bit mask. See _mu_interrupt_enable.
388  *
389  * @code
390  * // Enable general interrupt 0 and TX0 empty interrupt.
391  * MU_EnableInterrupts(base, kMU_GenInt0InterruptEnable | kMU_Tx0EmptyInterruptEnable);
392  * @endcode
393  *
394  * @param base MU peripheral base address.
395  * @param mask  Bit mask of the MU interrupts. See _mu_interrupt_enable.
396  */
MU_EnableInterrupts(MU_Type * base,uint32_t mask)397 static inline void MU_EnableInterrupts(MU_Type *base, uint32_t mask)
398 {
399     uint32_t reg = base->CR;
400     reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | mask;
401     base->CR = reg;
402 }
403 
404 /*!
405  * @brief Disables the specific MU interrupts.
406  *
407  * This function disables the specific MU interrupts. The interrupts to disable
408  * should be passed in as bit mask. See _mu_interrupt_enable.
409  *
410  * @code
411  * // Disable general interrupt 0 and TX0 empty interrupt.
412  * MU_DisableInterrupts(base, kMU_GenInt0InterruptEnable | kMU_Tx0EmptyInterruptEnable);
413  * @endcode
414  *
415  * @param base MU peripheral base address.
416  * @param mask  Bit mask of the MU interrupts. See _mu_interrupt_enable.
417  */
MU_DisableInterrupts(MU_Type * base,uint32_t mask)418 static inline void MU_DisableInterrupts(MU_Type *base, uint32_t mask)
419 {
420     uint32_t reg = base->CR;
421     reg &= ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | mask);
422     base->CR = reg;
423 }
424 
425 /*!
426  * @brief Triggers interrupts to the other core.
427  *
428  * This function triggers the specific interrupts to the other core. The interrupts
429  * to trigger are passed in as bit mask. See \ref _mu_interrupt_trigger.
430  * The MU should not trigger an interrupt to the other core when the previous interrupt
431  * has not been processed by the other core. This function checks whether the
432  * previous interrupts have been processed. If not, it returns an error.
433  *
434  * @code
435  * if (kStatus_Success != MU_TriggerInterrupts(base, kMU_GenInt0InterruptTrigger | kMU_GenInt2InterruptTrigger))
436  * {
437  *     // Previous general purpose interrupt 0 or general purpose interrupt 2
438  *     // has not been processed by the other core.
439  * }
440  * @endcode
441  *
442  * @param base MU peripheral base address.
443  * @param mask Bit mask of the interrupts to trigger. See _mu_interrupt_trigger.
444  * @retval kStatus_Success    Interrupts have been triggered successfully.
445  * @retval kStatus_Fail       Previous interrupts have not been accepted.
446  */
447 status_t MU_TriggerInterrupts(MU_Type *base, uint32_t mask);
448 
449 /*!
450  * @brief Clear non-maskable interrupt (NMI) sent by the other core.
451  *
452  * This functions clears non-maskable interrupt (NMI) sent by the other core.
453  *
454  * @param base MU peripheral base address.
455  */
MU_ClearNmi(MU_Type * base)456 static inline void MU_ClearNmi(MU_Type *base)
457 {
458     base->SR = MU_SR_NMIC_MASK;
459 }
460 
461 /* @} */
462 
463 /*!
464  * @name MU misc functions
465  * @{
466  */
467 
468 /*!
469  * @brief Boots the core at B side.
470  *
471  * This function sets the B side core's boot configuration and releases the
472  * core from reset.
473  *
474  * @param base MU peripheral base address.
475  * @param mode Core B boot mode.
476  * @note Only MU side A can use this function.
477  */
478 void MU_BootCoreB(MU_Type *base, mu_core_boot_mode_t mode);
479 
480 /*!
481  * @brief Holds the core reset of B side.
482  *
483  * This function causes the core of B side to be held in reset following any reset event.
484  *
485  * @param base MU peripheral base address.
486  * @note Only A side could call this function.
487  */
MU_HoldCoreBReset(MU_Type * base)488 static inline void MU_HoldCoreBReset(MU_Type *base)
489 {
490 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
491     base->CCR |= MU_CCR_RSTH_MASK;
492 #else /* FSL_FEATURE_MU_HAS_CCR */
493     uint32_t reg = base->CR;
494     reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | MU_CR_RSTH_MASK;
495     base->CR = reg;
496 #endif /* FSL_FEATURE_MU_HAS_CCR */
497 }
498 
499 /*!
500  * @brief Boots the other core.
501  *
502  * This function boots the other core with a boot configuration.
503  *
504  * @param base MU peripheral base address.
505  * @param mode The other core boot mode.
506  */
507 void MU_BootOtherCore(MU_Type *base, mu_core_boot_mode_t mode);
508 
509 /*!
510  * @brief Holds the other core reset.
511  *
512  * This function causes the other core to be held in reset following any reset event.
513  *
514  * @param base MU peripheral base address.
515  */
MU_HoldOtherCoreReset(MU_Type * base)516 static inline void MU_HoldOtherCoreReset(MU_Type *base)
517 {
518     /*
519      * MU_HoldOtherCoreReset and MU_HoldCoreBReset are the same, MU_HoldCoreBReset
520      * is kept for compatible with older platforms.
521      */
522     MU_HoldCoreBReset(base);
523 }
524 
525 /*!
526  * @brief Resets the MU for both A side and B side.
527  *
528  * This function resets the MU for both A side and B side. Before reset, it is
529  * recommended to interrupt processor B, because this function may affect the
530  * ongoing processor B programs.
531  *
532  * @param base MU peripheral base address.
533  * @note For some platforms, only MU side A could use this function, check
534  * reference manual for details.
535  */
MU_ResetBothSides(MU_Type * base)536 static inline void MU_ResetBothSides(MU_Type *base)
537 {
538     uint32_t reg = base->CR;
539     reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | MU_CR_MUR_MASK;
540     base->CR = reg;
541 
542 #if (defined(FSL_FEATURE_MU_HAS_SR_RS) && FSL_FEATURE_MU_HAS_SR_RS)
543     /* Wait for the other side out of reset. */
544     while (base->SR & MU_SR_RS_MASK)
545     {
546     }
547 #endif /* FSL_FEATURE_MU_HAS_SR_RS */
548 }
549 
550 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
551 /*!
552  * @brief Mask hardware reset by the other core.
553  *
554  * The other core could call MU_HardwareResetOtherCore() to reset current core.
555  * To mask the reset, call this function and pass in true.
556  *
557  * @param base MU peripheral base address.
558  * @param mask Pass true to mask the hardware reset, pass false to unmask it.
559  */
MU_MaskHardwareReset(MU_Type * base,bool mask)560 static inline void MU_MaskHardwareReset(MU_Type *base, bool mask)
561 {
562     if (mask)
563     {
564         base->CCR |= MU_CCR_HRM_MASK;
565     }
566     else
567     {
568         base->CCR &= ~MU_CCR_HRM_MASK;
569     }
570 }
571 #endif
572 
573 /*!
574  * @brief Hardware reset the other core.
575  *
576  * This function resets the other core, the other core could mask the
577  * hardware reset by calling @ref MU_MaskHardwareReset. The hardware reset
578  * mask feature is only available for some platforms.
579  * This function could be used together with MU_BootOtherCore to control the
580  * other core reset workflow.
581  *
582  * Example 1: Reset the other core, and no hold reset
583  * @code
584  * MU_HardwareResetOtherCore(MU_A, true, false, bootMode);
585  * @endcode
586  * In this example, the core at MU side B will reset with the specified boot mode.
587  *
588  * Example 2: Reset the other core and hold it, then boot the other core later.
589  * @code
590  * // Here the other core enters reset, and the reset is hold
591  * MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare);
592  * // Current core boot the other core when necessary.
593  * MU_BootOtherCore(MU_A, bootMode);
594  * @endcode
595  *
596  * @param base MU peripheral base address.
597  * @param waitReset Wait the other core enters reset.
598  *                    - true: Wait until the other core enters reset, if the other
599  *                      core has masked the hardware reset, then this function will
600  *                      be blocked.
601  *                    - false: Don't wait the reset.
602  * @param holdReset Hold the other core reset or not.
603  *                    - true: Hold the other core in reset, this function returns
604  *                      directly when the other core enters reset.
605  *                    - false: Don't hold the other core in reset, this function
606  *                      waits until the other core out of reset.
607  * @param bootMode Boot mode of the other core, if @p holdReset is true, this
608  *                 parameter is useless.
609  */
610 void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode);
611 
612 /*!
613  * @brief Enables or disables the clock on the other core.
614  *
615  * This function enables or disables the platform clock on the other core when
616  * that core enters a stop mode. If disabled, the platform clock for the other
617  * core is disabled when it enters stop mode. If enabled, the platform clock
618  * keeps running on the other core in stop mode, until this core also enters
619  * stop mode.
620  *
621  * @param base MU peripheral base address.
622  * @param enable   Enable or disable the clock on the other core.
623  */
MU_SetClockOnOtherCoreEnable(MU_Type * base,bool enable)624 static inline void MU_SetClockOnOtherCoreEnable(MU_Type *base, bool enable)
625 {
626 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
627     if (enable)
628     {
629         base->CCR |= MU_CCR_CLKE_MASK;
630     }
631     else
632     {
633         base->CCR &= ~MU_CCR_CLKE_MASK;
634     }
635 #else /* FSL_FEATURE_MU_HAS_CCR */
636     uint32_t reg = base->CR;
637 
638     reg &= ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK);
639 
640     if (enable)
641     {
642         reg |= MU_CR_CLKE_MASK;
643     }
644     else
645     {
646         reg &= ~MU_CR_CLKE_MASK;
647     }
648 
649     base->CR = reg;
650 #endif /* FSL_FEATURE_MU_HAS_CCR */
651 }
652 
653 /*!
654  * @brief Gets the power mode of the other core.
655  *
656  * This function gets the power mode of the other core.
657  *
658  * @param base MU peripheral base address.
659  * @return Power mode of the other core.
660  */
MU_GetOtherCorePowerMode(MU_Type * base)661 static inline mu_power_mode_t MU_GetOtherCorePowerMode(MU_Type *base)
662 {
663     return (mu_power_mode_t)((base->SR & MU_SR_PM_MASK) >> MU_SR_PM_SHIFT);
664 }
665 
666 /* @} */
667 
668 #if defined(__cplusplus)
669 }
670 #endif /*_cplusplus*/
671 /*@}*/
672 
673 #endif /* _FSL_MU_H_*/
674