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