1 /* 2 * Copyright 2023 NXP 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include "fsl_gdet.h" 9 10 /******************************************************************************* 11 * Definitions 12 *******************************************************************************/ 13 14 /* Component ID definition, used by tools. */ 15 #ifndef FSL_COMPONENT_ID 16 #define FSL_COMPONENT_ID "platform.drivers.gdet" 17 #endif 18 19 #define ISOLATE_ON (0x2u << 2) 20 #define ISOLATE_OFF (0x0u << 2) 21 22 /******************************************************************************* 23 * Prototypes 24 ******************************************************************************/ 25 26 /******************************************************************************* 27 * Code 28 ******************************************************************************/ 29 30 /*! 31 * Weak implementation of GDET IRQ, should be re-defined by user when using GDET IRQ 32 */ GDET_DriverIRQHandler(void)33__WEAK void GDET_DriverIRQHandler(void) 34 { 35 /* GDET generates IRQ if voltage glitching is detected 36 */ 37 } 38 39 /*! 40 * brief Initialize GDET 41 * 42 * This function initializes GDET setting and enable interrupts. 43 * 44 * param base GDET peripheral base address 45 * return Status of the init operation 46 */ GDET_Init(GDET_Type * base)47status_t GDET_Init(GDET_Type *base) 48 { 49 /* Ungate clock to GDET engine and reset it */ 50 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 51 CLOCK_EnableClock(kCLOCK_Gdet); 52 #endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 53 54 NVIC_EnableIRQ(GDET_IRQn); 55 56 return kStatus_Success; 57 } 58 59 /*! 60 * brief Deinitialize GDET 61 * 62 * This function stops GDET glitch detector. 63 * 64 * param base GDET peripheral base address 65 */ GDET_Deinit(GDET_Type * base)66void GDET_Deinit(GDET_Type *base) 67 { 68 NVIC_DisableIRQ(GDET_IRQn); 69 70 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) 71 72 CLOCK_DisableClock(kCLOCK_Gdet); 73 #endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ 74 } 75 76 /* Array of GDET peripheral base address. */ 77 static GDET_Type *const s_gdetBases[] = GDET_BASE_PTRS; 78 79 /*! 80 * brief Get the GDET instance from peripheral base address. 81 * 82 * param base GDET peripheral base address. 83 * return GDET instance. 84 */ GDET_GetInstance(GDET_Type * base)85static uint32_t GDET_GetInstance(GDET_Type *base) 86 { 87 uint32_t instance; 88 89 /* Find the instance index from base address mappings. */ 90 for (instance = 0U; instance < ARRAY_SIZE(s_gdetBases); instance++) 91 { 92 if (s_gdetBases[instance] == base) 93 { 94 break; 95 } 96 } 97 98 assert(instance < ARRAY_SIZE(s_gdetBases)); 99 100 return instance; 101 } 102 GDET_IsolateOn(GDET_Type * base)103status_t GDET_IsolateOn(GDET_Type *base) 104 { 105 status_t status = kStatus_Fail; 106 uint32_t instance; 107 108 instance = GDET_GetInstance(base); 109 110 SYSCON->GDET_CTRL[instance] = ISOLATE_ON; 111 112 if (ISOLATE_ON != SYSCON->GDET_CTRL[instance]) 113 { 114 return kStatus_Fail; 115 } 116 status = kStatus_Success; 117 118 return status; 119 } 120 GDET_IsolateOff(GDET_Type * base)121status_t GDET_IsolateOff(GDET_Type *base) 122 { 123 status_t status = kStatus_Fail; 124 uint32_t instance; 125 126 instance = GDET_GetInstance(base); 127 128 SYSCON->GDET_CTRL[instance] = ISOLATE_ON; 129 130 if (ISOLATE_ON != SYSCON->GDET_CTRL[instance]) 131 { 132 return kStatus_Fail; 133 } 134 status = kStatus_Success; 135 136 return status; 137 } 138 GDET_ReconfigureVoltageMode(GDET_Type * base,gdet_core_voltage_t voltage)139status_t GDET_ReconfigureVoltageMode(GDET_Type *base, gdet_core_voltage_t voltage) 140 { 141 uint32_t tmp0 = 0; 142 status_t status = kStatus_Fail; 143 144 if ((voltage != kGDET_MidVoltage) && (voltage != kGDET_NormalVoltage) && (voltage != kGDET_OverDriveVoltage)) 145 { 146 return kStatus_InvalidArgument; 147 } 148 149 /*Change the GDET_DLY_CTRL to select the new drive mode (and set high also GDET_DLY_CTRL[SW_VOL_CTRL] for a SW 150 * control)*/ 151 tmp0 = (((uint32_t)voltage) << GDET_GDET_DLY_CTRL_VOL_SEL_SHIFT); 152 tmp0 |= GDET_GDET_DLY_CTRL_SW_VOL_CTRL_MASK; 153 base->GDET_DLY_CTRL = tmp0; 154 155 /*Write high the GDET_RESET[SFT_RST] to issue a fast update of the detector to the new voltage level.*/ 156 base->GDET_RESET = GDET_GDET_RESET_SFT_RST(1u); 157 158 /* according to the GDET module documentation, the GDET_CFG[SFT_RST] reads as 0 */ 159 if (0u == (GDET_GDET_RESET_SFT_RST_MASK & base->GDET_RESET)) 160 { 161 status = kStatus_Success; 162 } 163 164 return status; 165 } 166