Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:01

0001 /*
0002  * Copyright 2017-2019, 2022 NXP
0003  * All rights reserved.
0004  *
0005  * SPDX-License-Identifier: BSD-3-Clause
0006  */
0007 
0008 #include "fsl_sema4.h"
0009 
0010 /******************************************************************************
0011  * Definitions
0012  *****************************************************************************/
0013 
0014 /* Component ID definition, used by tools. */
0015 #ifndef FSL_COMPONENT_ID
0016 #define FSL_COMPONENT_ID "platform.drivers.sema4"
0017 #endif
0018 
0019 /* The first number write to RSTGDP when reset SEMA4 gate. */
0020 #define SEMA4_GATE_RESET_PATTERN_1 (0xE2U)
0021 /* The second number write to RSTGDP when reset SEMA4 gate. */
0022 #define SEMA4_GATE_RESET_PATTERN_2 (0x1DU)
0023 
0024 /* The first number write to RSTGDP when reset SEMA4 gate IRQ notification. */
0025 #define SEMA4_GATE_IRQ_RESET_PATTERN_1 (0x47U)
0026 /* The second number write to RSTGDP when reset SEMA4 gate IRQ notification. */
0027 #define SEMA4_GATE_IRQ_RESET_PATTERN_2 (0xB8U)
0028 
0029 #define SEMA4_RSTGT_RSTNSM_MASK (0x30U)
0030 
0031 #define SEMA4_RSTNTF_RSTNSM_MASK (0x30U)
0032 
0033 /*******************************************************************************
0034  * Prototypes
0035  ******************************************************************************/
0036 
0037 #if defined(SEMA4_CLOCKS)
0038 /*!
0039  * @brief Get instance number for SEMA4 module.
0040  *
0041  * @param base SEMA4 peripheral base address.
0042  */
0043 uint32_t SEMA4_GetInstance(SEMA4_Type *base);
0044 #endif
0045 
0046 /*******************************************************************************
0047  * Variables
0048  ******************************************************************************/
0049 
0050 #if defined(SEMA4_CLOCKS)
0051 /*! @brief Pointers to sema4 bases for each instance. */
0052 static SEMA4_Type *const s_sema4Bases[] = SEMA4_BASE_PTRS;
0053 #endif
0054 
0055 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0056 #if defined(SEMA4_CLOCKS)
0057 /*! @brief Pointers to sema4 clocks for each instance. */
0058 static const clock_ip_name_t s_sema4Clocks[] = SEMA4_CLOCKS;
0059 #endif
0060 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0061 
0062 /******************************************************************************
0063  * CODE
0064  *****************************************************************************/
0065 
0066 #if defined(SEMA4_CLOCKS)
0067 uint32_t SEMA4_GetInstance(SEMA4_Type *base)
0068 {
0069     uint32_t instance;
0070 
0071     /* Find the instance index from base address mappings. */
0072     for (instance = 0; instance < ARRAY_SIZE(s_sema4Bases); instance++)
0073     {
0074         if (s_sema4Bases[instance] == base)
0075         {
0076             break;
0077         }
0078     }
0079 
0080     assert(instance < ARRAY_SIZE(s_sema4Bases));
0081 
0082     return instance;
0083 }
0084 #endif
0085 
0086 /*!
0087  * brief Initializes the SEMA4 module.
0088  *
0089  * This function initializes the SEMA4 module. It only enables the clock but does
0090  * not reset the gates because the module might be used by other processors
0091  * at the same time. To reset the gates, call either SEMA4_ResetGate or
0092  * SEMA4_ResetAllGates function.
0093  *
0094  * param base SEMA4 peripheral base address.
0095  */
0096 void SEMA4_Init(SEMA4_Type *base)
0097 {
0098 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0099 #if defined(SEMA4_CLOCKS)
0100     CLOCK_EnableClock(s_sema4Clocks[SEMA4_GetInstance(base)]);
0101 #endif
0102 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0103 }
0104 
0105 /*!
0106  * brief De-initializes the SEMA4 module.
0107  *
0108  * This function de-initializes the SEMA4 module. It only disables the clock.
0109  *
0110  * param base SEMA4 peripheral base address.
0111  */
0112 void SEMA4_Deinit(SEMA4_Type *base)
0113 {
0114 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0115 #if defined(SEMA4_CLOCKS)
0116     CLOCK_DisableClock(s_sema4Clocks[SEMA4_GetInstance(base)]);
0117 #endif
0118 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0119 }
0120 
0121 /*!
0122  * brief Tries to lock the SEMA4 gate.
0123  *
0124  * This function tries to lock the specific SEMA4 gate. If the gate has been
0125  * locked by another processor, this function returns an error code.
0126  *
0127  * param base SEMA4 peripheral base address.
0128  * param gateNum  Gate number to lock.
0129  * param procNum  Current processor number.
0130  *
0131  * retval kStatus_Success     Lock the sema4 gate successfully.
0132  * retval kStatus_Fail Sema4 gate has been locked by another processor.
0133  */
0134 status_t SEMA4_TryLock(SEMA4_Type *base, uint8_t gateNum, uint8_t procNum)
0135 {
0136     status_t status;
0137 
0138     assert(gateNum < (uint8_t)FSL_FEATURE_SEMA4_GATE_COUNT);
0139 
0140     ++procNum;
0141 
0142     /* Try to lock. */
0143     SEMA4_GATEn(base, gateNum) = procNum;
0144 
0145     /* Check locked or not. */
0146     if (procNum != SEMA4_GATEn(base, gateNum))
0147     {
0148         status = kStatus_Fail;
0149     }
0150     else
0151     {
0152         status = kStatus_Success;
0153     }
0154 
0155     return status;
0156 }
0157 
0158 /*!
0159  * brief Locks the SEMA4 gate.
0160  *
0161  * This function locks the specific SEMA4 gate. If the gate has been
0162  * locked by other processors, this function waits until it is unlocked and then
0163  * lock it.
0164  *
0165  * param base SEMA4 peripheral base address.
0166  * param gateNum  Gate number to lock.
0167  * param procNum  Current processor number.
0168  */
0169 void SEMA4_Lock(SEMA4_Type *base, uint8_t gateNum, uint8_t procNum)
0170 {
0171     while (kStatus_Success != SEMA4_TryLock(base, gateNum, procNum))
0172     {
0173     }
0174 }
0175 
0176 /*!
0177  * brief Resets the SEMA4 gate to an unlocked status.
0178  *
0179  * This function resets a SEMA4 gate to an unlocked status.
0180  *
0181  * param base SEMA4 peripheral base address.
0182  * param gateNum  Gate number.
0183  *
0184  * retval kStatus_Success         SEMA4 gate is reset successfully.
0185  * retval kStatus_Fail Some other reset process is ongoing.
0186  */
0187 status_t SEMA4_ResetGate(SEMA4_Type *base, uint8_t gateNum)
0188 {
0189     status_t status;
0190 
0191     /*
0192      * Reset all gates if gateNum >= SEMA4_GATE_NUM_RESET_ALL
0193      * Reset specific gate if gateNum < FSL_FEATURE_SEMA4_GATE_COUNT
0194      */
0195     assert(!((gateNum < SEMA4_GATE_NUM_RESET_ALL) && (gateNum >= (uint8_t)FSL_FEATURE_SEMA4_GATE_COUNT)));
0196 
0197     /* Check whether some reset is ongoing. */
0198     if (0U != (base->RSTGT & SEMA4_RSTGT_RSTNSM_MASK))
0199     {
0200         status = kStatus_Fail;
0201     }
0202     else
0203     {
0204         /* First step. */
0205         base->RSTGT = SEMA4_RSTGT_RSTGSM_RSTGMS_RSTGDP(SEMA4_GATE_RESET_PATTERN_1);
0206         /* Second step. */
0207         base->RSTGT = SEMA4_RSTGT_RSTGSM_RSTGMS_RSTGDP(SEMA4_GATE_RESET_PATTERN_2) | SEMA4_RSTGT_RSTGTN(gateNum);
0208 
0209         status = kStatus_Success;
0210     }
0211 
0212     return status;
0213 }
0214 
0215 /*!
0216  * brief Resets the SEMA4 gate IRQ notification.
0217  *
0218  * This function resets a SEMA4 gate IRQ notification.
0219  *
0220  * param base SEMA4 peripheral base address.
0221  * param gateNum  Gate number.
0222  *
0223  * retval kStatus_Success Reset successfully.
0224  * retval kStatus_Fail    Some other reset process is ongoing.
0225  */
0226 status_t SEMA4_ResetGateNotify(SEMA4_Type *base, uint8_t gateNum)
0227 {
0228     status_t status;
0229 
0230     /*
0231      * Reset all gates if gateNum >= SEMA4_GATE_NUM_RESET_ALL
0232      * Reset specific gate if gateNum < FSL_FEATURE_SEMA4_GATE_COUNT
0233      */
0234     assert(!((gateNum < (uint8_t)SEMA4_GATE_NUM_RESET_ALL) && (gateNum >= (uint8_t)FSL_FEATURE_SEMA4_GATE_COUNT)));
0235 
0236     /* Check whether some reset is ongoing. */
0237     if (0U != (base->RSTNTF & SEMA4_RSTNTF_RSTNSM_MASK))
0238     {
0239         status = kStatus_Fail;
0240     }
0241     else
0242     {
0243         /* First step. */
0244         base->RSTNTF = SEMA4_RSTNTF_RSTNSM_RSTNMS_RSTNDP(SEMA4_GATE_IRQ_RESET_PATTERN_1);
0245         /* Second step. */
0246         base->RSTNTF = SEMA4_RSTNTF_RSTNSM_RSTNMS_RSTNDP(SEMA4_GATE_IRQ_RESET_PATTERN_2) | SEMA4_RSTNTF_RSTNTN(gateNum);
0247 
0248         status = kStatus_Success;
0249     }
0250 
0251     return status;
0252 }