![]() |
|
|||
File indexing completed on 2025-05-11 08:23:00
0001 /* 0002 * Copyright (c) 2015, Freescale Semiconductor, Inc. 0003 * Copyright 2016-2020 NXP 0004 * All rights reserved. 0005 * 0006 * SPDX-License-Identifier: BSD-3-Clause 0007 */ 0008 0009 #include "fsl_mu.h" 0010 0011 /* Component ID definition, used by tools. */ 0012 #ifndef FSL_COMPONENT_ID 0013 #define FSL_COMPONENT_ID "platform.drivers.mu" 0014 #endif 0015 0016 /******************************************************************************* 0017 * Variables 0018 ******************************************************************************/ 0019 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 0020 /*! @brief Pointers to mu clocks for each instance. */ 0021 static const clock_ip_name_t s_muClocks[] = MU_CLOCKS; 0022 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 0023 /*! @brief Pointers to mu bases for each instance. */ 0024 static MU_Type *const s_muBases[] = MU_BASE_PTRS; 0025 0026 /****************************************************************************** 0027 * Code 0028 *****************************************************************************/ 0029 static uint32_t MU_GetInstance(MU_Type *base) 0030 { 0031 uint32_t instance; 0032 0033 /* Find the instance index from base address mappings. */ 0034 for (instance = 0U; instance < (sizeof(s_muBases) / sizeof(s_muBases[0])); instance++) 0035 { 0036 if (s_muBases[instance] == base) 0037 { 0038 break; 0039 } 0040 } 0041 0042 assert(instance < (sizeof(s_muBases) / sizeof(s_muBases[0]))); 0043 0044 return instance; 0045 } 0046 0047 /*! 0048 * brief Initializes the MU module. 0049 * 0050 * This function enables the MU clock only. 0051 * 0052 * param base MU peripheral base address. 0053 */ 0054 void MU_Init(MU_Type *base) 0055 { 0056 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 0057 (void)CLOCK_EnableClock(s_muClocks[MU_GetInstance(base)]); 0058 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 0059 } 0060 0061 /*! 0062 * brief De-initializes the MU module. 0063 * 0064 * This function disables the MU clock only. 0065 * 0066 * param base MU peripheral base address. 0067 */ 0068 void MU_Deinit(MU_Type *base) 0069 { 0070 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 0071 (void)CLOCK_DisableClock(s_muClocks[MU_GetInstance(base)]); 0072 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 0073 } 0074 0075 /*! 0076 * brief Blocks to send a message. 0077 * 0078 * This function waits until the TX register is empty and sends the message. 0079 * 0080 * param base MU peripheral base address. 0081 * param regIndex TX register index. 0082 * param msg Message to send. 0083 */ 0084 void MU_SendMsg(MU_Type *base, uint32_t regIndex, uint32_t msg) 0085 { 0086 assert(regIndex < MU_TR_COUNT); 0087 0088 /* Wait TX register to be empty. */ 0089 while (0U == (base->SR & (((uint32_t)kMU_Tx0EmptyFlag) >> regIndex))) 0090 { 0091 ; /* Intentional empty while*/ 0092 } 0093 0094 base->TR[regIndex] = msg; 0095 } 0096 0097 /*! 0098 * brief Blocks to receive a message. 0099 * 0100 * This function waits until the RX register is full and receives the message. 0101 * 0102 * param base MU peripheral base address. 0103 * param regIndex RX register index. 0104 * return The received message. 0105 */ 0106 uint32_t MU_ReceiveMsg(MU_Type *base, uint32_t regIndex) 0107 { 0108 assert(regIndex < MU_TR_COUNT); 0109 0110 /* Wait RX register to be full. */ 0111 while (0U == (base->SR & (((uint32_t)kMU_Rx0FullFlag) >> regIndex))) 0112 { 0113 ; /* Intentional empty while*/ 0114 } 0115 0116 return base->RR[regIndex]; 0117 } 0118 0119 /*! 0120 * brief Blocks setting the 3-bit MU flags reflect on the other MU side. 0121 * 0122 * This function blocks setting the 3-bit MU flags. Every time the 3-bit MU flags are changed, 0123 * the status flag \c kMU_FlagsUpdatingFlag asserts indicating the 3-bit MU flags are 0124 * updating to the other side. After the 3-bit MU flags are updated, the status flag 0125 * \c kMU_FlagsUpdatingFlag is cleared by hardware. During the flags updating period, 0126 * the flags cannot be changed. This function waits for the MU status flag 0127 * \c kMU_FlagsUpdatingFlag cleared and sets the 3-bit MU flags. 0128 * 0129 * param base MU peripheral base address. 0130 * param flags The 3-bit MU flags to set. 0131 */ 0132 void MU_SetFlags(MU_Type *base, uint32_t flags) 0133 { 0134 /* Wait for update finished. */ 0135 while (0U != (base->SR & ((uint32_t)MU_SR_FUP_MASK))) 0136 { 0137 ; /* Intentional empty while*/ 0138 } 0139 0140 MU_SetFlagsNonBlocking(base, flags); 0141 } 0142 0143 /*! 0144 * brief Triggers interrupts to the other core. 0145 * 0146 * This function triggers the specific interrupts to the other core. The interrupts 0147 * to trigger are passed in as bit mask. See \ref _mu_interrupt_trigger. 0148 * The MU should not trigger an interrupt to the other core when the previous interrupt 0149 * has not been processed by the other core. This function checks whether the 0150 * previous interrupts have been processed. If not, it returns an error. 0151 * 0152 * code 0153 * if (kStatus_Success != MU_TriggerInterrupts(base, kMU_GenInt0InterruptTrigger | kMU_GenInt2InterruptTrigger)) 0154 * { 0155 * Previous general purpose interrupt 0 or general purpose interrupt 2 0156 * has not been processed by the other core. 0157 * } 0158 * endcode 0159 * 0160 * param base MU peripheral base address. 0161 * param mask Bit mask of the interrupts to trigger. See _mu_interrupt_trigger. 0162 * retval kStatus_Success Interrupts have been triggered successfully. 0163 * retval kStatus_Fail Previous interrupts have not been accepted. 0164 */ 0165 status_t MU_TriggerInterrupts(MU_Type *base, uint32_t mask) 0166 { 0167 status_t status = kStatus_Success; 0168 uint32_t reg = base->CR; 0169 0170 /* Previous interrupt has been accepted. */ 0171 if (0U == (reg & mask)) 0172 { 0173 /* All interrupts have been accepted, trigger now. */ 0174 reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | mask; 0175 base->CR = reg; 0176 status = kStatus_Success; 0177 } 0178 else 0179 { 0180 status = kStatus_Fail; 0181 } 0182 0183 return status; 0184 } 0185 0186 #if !(defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH) 0187 /*! 0188 * brief Boots the core at B side. 0189 * 0190 * This function sets the B side core's boot configuration and releases the 0191 * core from reset. 0192 * 0193 * param base MU peripheral base address. 0194 * param mode Core B boot mode. 0195 * note Only MU side A can use this function. 0196 */ 0197 void MU_BootCoreB(MU_Type *base, mu_core_boot_mode_t mode) 0198 { 0199 #if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) 0200 /* Clean the reset de-assert pending flag. */ 0201 base->SR = MU_SR_RDIP_MASK; 0202 #endif 0203 0204 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR) 0205 uint32_t reg = base->CCR; 0206 0207 reg = (reg & ~(MU_CCR_HR_MASK | MU_CCR_RSTH_MASK | MU_CCR_BOOT_MASK)) | MU_CCR_BOOT(mode); 0208 0209 base->CCR = reg; 0210 #else 0211 uint32_t reg = base->CR; 0212 0213 reg = (reg & ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | MU_CR_HR_MASK | MU_CR_RSTH_MASK | MU_CR_BBOOT_MASK)) | 0214 MU_CR_BBOOT(mode); 0215 0216 base->CR = reg; 0217 #endif 0218 } 0219 0220 /*! 0221 * brief Boots the other core. 0222 * 0223 * This function boots the other core with a boot configuration. 0224 * 0225 * param base MU peripheral base address. 0226 * param mode The other core boot mode. 0227 */ 0228 void MU_BootOtherCore(MU_Type *base, mu_core_boot_mode_t mode) 0229 { 0230 /* 0231 * MU_BootOtherCore and MU_BootCoreB are the same, MU_BootCoreB is kept 0232 * for compatible with older platforms. 0233 */ 0234 MU_BootCoreB(base, mode); 0235 } 0236 #endif /* FSL_FEATURE_MU_NO_RSTH */ 0237 0238 #if !(defined(FSL_FEATURE_MU_NO_HR) && FSL_FEATURE_MU_NO_HR) 0239 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR) 0240 /*! 0241 * brief Hardware reset the other core. 0242 * 0243 * This function resets the other core, the other core could mask the 0244 * hardware reset by calling ref MU_MaskHardwareReset. The hardware reset 0245 * mask feature is only available for some platforms. 0246 * This function could be used together with MU_BootOtherCore to control the 0247 * other core reset workflow. 0248 * 0249 * Example 1: Reset the other core, and no hold reset 0250 * code 0251 * MU_HardwareResetOtherCore(MU_A, true, false, bootMode); 0252 * endcode 0253 * In this example, the core at MU side B will reset with the specified boot mode. 0254 * 0255 * Example 2: Reset the other core and hold it, then boot the other core later. 0256 * code 0257 * Here the other core enters reset, and the reset is hold 0258 * MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare); 0259 * Current core boot the other core when necessary. 0260 * MU_BootOtherCore(MU_A, bootMode); 0261 * endcode 0262 * 0263 * param base MU peripheral base address. 0264 * param waitReset Wait the other core enters reset. 0265 * - true: Wait until the other core enters reset, if the other 0266 * core has masked the hardware reset, then this function will 0267 * be blocked. 0268 * - false: Don't wait the reset. 0269 * param holdReset Hold the other core reset or not. 0270 * - true: Hold the other core in reset, this function returns 0271 * directly when the other core enters reset. 0272 * - false: Don't hold the other core in reset, this function 0273 * waits until the other core out of reset. 0274 * param bootMode Boot mode of the other core, if p holdReset is true, this 0275 * parameter is useless. 0276 */ 0277 void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode) 0278 { 0279 #if (defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH) 0280 /* If MU does not support hold reset, then the parameter must be false. */ 0281 assert(false == holdReset); 0282 #endif 0283 uint32_t ccr = base->CCR & ~(MU_CCR_HR_MASK | MU_CCR_RSTH_MASK | MU_CCR_BOOT_MASK); 0284 0285 ccr |= MU_CCR_BOOT(bootMode); 0286 0287 if (holdReset) 0288 { 0289 ccr |= MU_CCR_RSTH_MASK; 0290 } 0291 0292 /* Clean the reset assert pending flag. */ 0293 base->SR = (MU_SR_RAIP_MASK | MU_SR_RDIP_MASK); 0294 0295 /* Set CCR[HR] to trigger hardware reset. */ 0296 base->CCR = ccr | MU_CCR_HR_MASK; 0297 0298 /* If wait the other core enters reset. */ 0299 if (waitReset) 0300 { 0301 /* Wait for the other core go to reset. */ 0302 while (0U == (base->SR & MU_SR_RAIP_MASK)) 0303 { 0304 ; /* Intentional empty while*/ 0305 } 0306 0307 if (!holdReset) 0308 { 0309 /* Clear CCR[HR]. */ 0310 base->CCR = ccr; 0311 0312 /* Wait for the other core out of reset. */ 0313 while (0U == (base->SR & MU_SR_RDIP_MASK)) 0314 { 0315 ; /* Intentional empty while*/ 0316 } 0317 } 0318 } 0319 } 0320 #else /* FSL_FEATURE_MU_HAS_CCR */ 0321 /*! 0322 * brief Hardware reset the other core. 0323 * 0324 * This function resets the other core, the other core could mask the 0325 * hardware reset by calling ref MU_MaskHardwareReset. The hardware reset 0326 * mask feature is only available for some platforms. 0327 * This function could be used together with MU_BootOtherCore to control the 0328 * other core reset workflow. 0329 * 0330 * Example 1: Reset the other core, and no hold reset 0331 * code 0332 * MU_HardwareResetOtherCore(MU_A, true, false, bootMode); 0333 * endcode 0334 * In this example, the core at MU side B will reset with the specified boot mode. 0335 * 0336 * Example 2: Reset the other core and hold it, then boot the other core later. 0337 * code 0338 * Here the other core enters reset, and the reset is hold 0339 * MU_HardwareResetOtherCore(MU_A, true, true, modeDontCare); 0340 * Current core boot the other core when necessary. 0341 * MU_BootOtherCore(MU_A, bootMode); 0342 * endcode 0343 * 0344 * param base MU peripheral base address. 0345 * param waitReset Wait the other core enters reset. 0346 * - true: Wait until the other core enters reset, if the other 0347 * core has masked the hardware reset, then this function will 0348 * be blocked. 0349 * - false: Don't wait the reset. 0350 * param holdReset Hold the other core reset or not. 0351 * - true: Hold the other core in reset, this function returns 0352 * directly when the other core enters reset. 0353 * - false: Don't hold the other core in reset, this function 0354 * waits until the other core out of reset. 0355 * param bootMode Boot mode of the other core, if p holdReset is true, this 0356 * parameter is useless. 0357 */ 0358 void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode) 0359 { 0360 #if (defined(FSL_FEATURE_MU_NO_RSTH) && FSL_FEATURE_MU_NO_RSTH) 0361 /* If MU does not support hold reset, then the parameter must be false. */ 0362 assert(false == holdReset); 0363 #endif 0364 uint32_t resetFlag = 0; 0365 0366 uint32_t cr = base->CR & ~(MU_CR_HR_MASK | MU_CR_RSTH_MASK | MU_CR_BOOT_MASK | MU_CR_GIRn_MASK | MU_CR_NMI_MASK); 0367 0368 cr |= MU_CR_BOOT(bootMode); 0369 0370 if (holdReset) 0371 { 0372 cr |= MU_CR_RSTH_MASK; 0373 } 0374 0375 #if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) 0376 resetFlag |= MU_SR_RAIP_MASK; 0377 #endif 0378 #if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) 0379 resetFlag |= MU_SR_RDIP_MASK; 0380 #endif 0381 /* Clean the reset assert pending flag. */ 0382 base->SR = resetFlag; 0383 0384 /* Set CR[HR] to trigger hardware reset. */ 0385 base->CR = cr | MU_CR_HR_MASK; 0386 0387 /* If wait the other core enters reset. */ 0388 if (waitReset) 0389 { 0390 #if (defined(FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) 0391 /* Wait for the other core go to reset. */ 0392 while (0U == (base->SR & MU_SR_RAIP_MASK)) 0393 { 0394 ; /* Intentional empty while*/ 0395 } 0396 #endif 0397 0398 if (!holdReset) 0399 { 0400 /* Clear CR[HR]. */ 0401 base->CR = cr; 0402 0403 #if (defined(FSL_FEATURE_MU_HAS_RESET_DEASSERT_INT) && FSL_FEATURE_MU_HAS_RESET_ASSERT_INT) 0404 /* Wait for the other core out of reset. */ 0405 while (0U == (base->SR & MU_SR_RDIP_MASK)) 0406 { 0407 ; /* Intentional empty while*/ 0408 } 0409 #endif 0410 } 0411 } 0412 } 0413 #endif /* FSL_FEATURE_MU_HAS_CCR */ 0414 #endif /* FSL_FEATURE_MU_NO_HR */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |