/* * ======== Task_deleteTerminatedTasksFunc ======== */ Void Task_deleteTerminatedTasksFunc() { UInt hwiKey, taskKey; Task_Handle tsk; taskKey = Task_disable(); hwiKey = Hwi_disable(); if (!Queue_empty(Task_Module_State_terminatedQ())) { tsk = Queue_head(Task_Module_State_terminatedQ()); Hwi_restore(hwiKey); tsk->readyQ = NULL; Task_delete(&tsk); } else { Hwi_restore(hwiKey); } Task_restore(taskKey); }
/* * ======== Timer_trigger ======== * 1. stop timer * 2. write the period with insts * 3. start the timer. */ Void Timer_trigger(Timer_Object *obj, UInt insts) { UInt key; /* follow proper procedure for dynamic period change */ key = Hwi_disable(); /* RESET=1, ENBL=0 */ CTM_ctm.CTCR[obj->ctmid] = 2; Hwi_clearInterrupt(obj->intNum); Hwi_enableInterrupt(obj->intNum); /* set interval to insts */ CTM_ctm.TINTVLR[obj->ctmid] = insts; /* RESTART=0, INT=1, ENBL=1 */ CTM_ctm.CTCR[obj->ctmid] = 0x00000101; Hwi_restore(key); }
/* ======== initDevice ======== * * 1. Stop timer (set control registers back to default value) * 2. Disable timer interrupt * 3. Clear any pending interrupt * 4. Clear counters * */ static Void initDevice(Timer_Object *obj) { ti_catalog_msp430_peripherals_timers_TimerRegs *timer; UInt key; timer = (ti_catalog_msp430_peripherals_timers_TimerRegs *) Timer_module->device[obj->id].baseAddr; key = Hwi_disable(); /* stop timer; set default control register */ timer->control = TIMER_CONTROL_DEFAULT; /* clear timer interrupt flag */ timer->cctl_0 &= ~TIMER_COMPARE_INTR_PENDING; /* reset timer counts */ timer->control |= TIMER_CONTROL_CLEAR; Hwi_restore(key); }
/* * ======== Task_yield ======== */ Void Task_yield() { UInt tskKey, hwiKey; tskKey = Task_disable(); hwiKey = Hwi_disable(); if (Task_module->curQ) { /* move current task to end of curQ */ Queue_enqueue(Task_module->curQ, Queue_dequeue(Task_module->curQ)); } Task_module->curQ = NULL; /* force a Task_switch() */ Task_module->workFlag = 1; Hwi_restore(hwiKey); Log_write3(Task_LM_yield, (UArg)Task_module->curTask, (UArg)(Task_module->curTask->fxn), (UArg)(BIOS_getThreadType())); Task_restore(tskKey); }
/** To Unregister the ISRs with the underlying OS, if previously registered. */ void unregisterEdma3Interrupts (unsigned int edma3Id) { static UInt32 cookie = 0; Int eventId = 0; /* GEM event id */ /* Disabling the global interrupts */ cookie = Hwi_disable(); /* Transfer completion ISR */ CpIntc_disableHostInt(0, ccXferHostInt[edma3Id][dsp_num]); eventId = CpIntc_getEventId(ccXferHostInt[edma3Id][dsp_num]); EventCombiner_disableEvent(eventId); /* CC/TC Error ISR */ CpIntc_disableHostInt(0, edma3ErrHostInt[edma3Id][dsp_num]); eventId = CpIntc_getEventId(edma3ErrHostInt[edma3Id][dsp_num]); EventCombiner_disableEvent(eventId); /* Restore interrupts */ Hwi_restore(cookie); }
/* * ======== Timer_setAvailMask ======== */ Bool Timer_setAvailMask(UInt mask) { UInt i; UInt key; UInt tmpMask; key = Hwi_disable(); tmpMask = mask; for (i = 0; i < Timer_numTimerDevices; i++) { /* Check if mask is setting any currently used timer as available */ if ((tmpMask & 0x1) && (Timer_module->handles[i] != NULL)) { Hwi_restore(key); return (FALSE); } tmpMask = tmpMask >> 1; } Timer_module->availMask = mask; Hwi_restore(key); return (TRUE); }
/* * ======== Timer_disableCC3200 ======== */ Void Timer_disableCC3200(Int id) { UInt key; key = Hwi_disable(); switch (id) { case 0: GPT_A0_CLK_GATING &= ~(0x1); break; case 1: GPT_A1_CLK_GATING &= ~(0x1); break; case 2: GPT_A2_CLK_GATING &= ~(0x1); break; case 3: GPT_A3_CLK_GATING &= ~(0x1); break; default: break; } Hwi_restore(key); }
/* * ======== TimestampProvider_get64 ======== */ Void TimestampProvider_get64(Types_Timestamp64 *result) { UInt key; UInt64 timestamp; key = Hwi_disable(); if (TimestampProvider_useClockTimer) { timestamp = Clock_getTicks() * Timer_getPeriod(MOD->timer) + Timer_getExpiredCounts(MOD->timer); } else { timestamp = ((UInt64)MOD->hi << 32) + Timer_getExpiredCounts(MOD->timer); } Hwi_restore(key); result->hi = timestamp >> 32; result->lo = timestamp; }
Int32 AlgLink_scdAlgRtPrmUpdate(AlgLink_ScdObj * pObj, AlgLink_ScdChObj *pChObj, FVID2_Frame *pFrame) { System_FrameInfo *pFrameInfo; System_LinkChInfo *pChInfo; UInt32 oldIntState; pFrameInfo = (System_FrameInfo *)pFrame->appData; if(pFrameInfo==NULL) return FVID2_EFAIL; if(pFrameInfo->rtChInfoUpdate==FALSE) return FVID2_SOK; pChInfo = &pFrameInfo->rtChInfo; oldIntState = Hwi_disable(); if(pChInfo->width != pChObj->width || pChInfo->height != pChObj->height ) { pChObj->rtPrmUpdate = TRUE; pChObj->algReset = TRUE; } pChObj->width = SystemUtils_floor(pChInfo->width, ALG_LINK_SIMCOP_SCD_WIDTH_ALIGN); pChObj->height = pChInfo->height; if(pChObj->width>pObj->algCreatePrm.maxWidth) pChObj->width = pObj->algCreatePrm.maxWidth; if(pChObj->height>pObj->algCreatePrm.maxHeight) pChObj->height = pObj->algCreatePrm.maxHeight; Hwi_restore(oldIntState); return FVID2_SOK; }
/* * ======== Swi_setAttrs ======== */ Void Swi_setAttrs(Swi_Object *swi, Swi_FuncPtr fxn, Swi_Params *params) { UInt hwiKey; Swi_Params swiParams; if (params == NULL) { Swi_Params_init(&swiParams); params = &swiParams; } hwiKey = Hwi_disable(); /* defensively remove swi from its readyQ */ Queue_remove((Queue_Elem *)swi); if (fxn) { swi->fxn = fxn; } swi->posted = FALSE; swi->arg0 = params->arg0; swi->arg1 = params->arg1; if (params->priority == ~0) { swi->priority = Swi_numPriorities - 1; } else { swi->priority = params->priority; } Assert_isTrue((swi->priority < Swi_numPriorities), Swi_A_badPriority); swi->mask = 1 << swi->priority; swi->initTrigger = swi->trigger = params->trigger; swi->readyQ = Queue_Object_get(Swi_module->readyQ, swi->priority); Hwi_restore(hwiKey); }
Int IpcPower_unregisterCallback(Int event, IpcPower_CallbackFuncPtr cbck) { IArg hwiKey; IpcPower_CallbackElem **list, *node; Int status = IpcPower_E_FAIL; BIOS_ThreadType context = BIOS_getThreadType(); if ((context != BIOS_ThreadType_Task) && (context != BIOS_ThreadType_Main)) { Log_print0(Diags_ERROR, FXNN":Invalid context\n"); return (status); } list = &IpcPower_callbackList; node = NULL; hwiKey = Hwi_disable(); /* begin: critical section */ while (*list != NULL) { if ( ((*list)->callback == cbck) && ((*list)->event == event) ) { node = *list; *list = (*list)->next; status = IpcPower_S_SUCCESS; break; } list = &(*list)->next; } Hwi_restore(hwiKey); /* end: critical section */ if (status == IpcPower_S_SUCCESS) { if (node != NULL) { Memory_free(NULL, node, sizeof(IpcPower_CallbackElem)); } else { Log_print0(Diags_ERROR, FXNN":Invalid pointer\n"); } } return (status); }
/* * ======== Swi_restore ======== */ Void Swi_restore(UInt swiKey) { UInt hwiKey; if (swiKey == FALSE) { hwiKey = Hwi_disable(); if (Swi_module->curSet) { Hwi_restore(hwiKey); Swi_schedule(); /* sets locked to FALSE */ } else { Swi_module->locked = FALSE; Hwi_restore(hwiKey); } if (BIOS_taskEnabled) { /* run task scheduler if its unlocked */ TASK_RESTORE(TASK_DISABLE()); } } }
/* * ======== MemoryProtect_unlock ======== * unlocks the permission attribute table entries for the * specified controller, using the specified key. */ Void MemoryProtect_unlock(MemoryProtect_Controller *ctrl, MemoryProtect_Key *keyreg) { MemoryProtect_Lock *lock; UInt key; lock = ctrl->mpLck; key = Hwi_disable(); /* it's illegal to unlock the MemoryProtect when already unlocked */ if (lock->mpLkStat & MemoryProtect_LKSTATLK) { lock->mpLkCmd = MemoryProtect_LCKKEYR; /* must write all four key regs exactly once */ lock->mpLk0 = keyreg->key0; lock->mpLk1 = keyreg->key1; lock->mpLk2 = keyreg->key2; lock->mpLk3 = keyreg->key3; lock->mpLkCmd = MemoryProtect_LCKUNLOCK; } Hwi_restore(key); }
/* * ======== Timer_disableTiva ======== */ Void Timer_disableTiva(Int id) { UInt key; key = Hwi_disable(); //TODO: Can we remove the delays from the disable code ? /* if a pre-Flurry class device, and one of the first four timers ... */ if (((HWREG(SYSCTL_DID0) & SYSCTL_DID0_CLASS_M) < SYSCTL_DID0_CLASS_FLURRY) && (id < 4)) { /* enable run mode clock */ *RCGC1 &= ~(UInt32)(1 << (id + 16)); /* ensure at least 5 clock cycle delay for clock disable */ *RCGC1; *RCGC1; *RCGC1; *RCGC1; *RCGC1; } /* else, Flurry or later device, or 5th timer or above ... */ else { /* enable run mode clock */ *RCGCTIMERS &= ~(UInt32)(1 << id); *SCGCTIMERS &= ~(UInt32)(1 << id); *DCGCTIMERS &= ~(UInt32)(1 << id); /* ensure at least 5 clock cycle delay for clock disable */ *RCGCTIMERS; *RCGCTIMERS; *RCGCTIMERS; *RCGCTIMERS; *RCGCTIMERS; } Hwi_restore(key); }
/* * ======== PWMTiva_control ======== * @pre Function assumes that the handle is not NULL */ int PWMTiva_control(PWM_Handle handle, unsigned int cmd, void *arg) { unsigned int key; uint32_t period; uint32_t presRegVal; uint8_t prescalar; PWMTiva_Object *object = handle->object; PWMTiva_HWAttrs const *hwAttrs = handle->hwAttrs; switch(cmd) { case PWMTiva_CHANGE_GEN_PERIOD: Assert_isTrue((uint32_t *) arg != NULL, NULL); /* Calculate period in PWM timer counts */ period = (*(uint32_t *) arg) * (object->pwmStatus)->cyclesPerMicroSec; /* Ensure new period can be generated with current prescalar */ PWMTiva_calculatePrescalar(period, &presRegVal, &prescalar); if (prescalar != (object->pwmStatus)->prescalar) { return (-1); } period /= prescalar; key = Hwi_disable(); PWMGenPeriodSet(hwAttrs->baseAddr, hwAttrs->pwmOutput & PWM_GEN_MASK, period); /* Update PWM status with new period */ *((object->pwmStatus)->genPeriods + ((hwAttrs->pwmOutput / PWM_OUT_0) - 1)) = *((uint32_t *) arg); Hwi_restore(key); return (PWMTiva_CHANGE_GEN_PERIOD); } /* No implementation yet */ return (PWM_STATUS_UNDEFINEDCMD); }
/*! * ======== InterruptDsp_intRegister ======== * Register ISR for remote processor interrupt */ Void InterruptDsp_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo, Fxn func, UArg arg) { Hwi_Params hwiAttrs; UInt key; Assert_isTrue(intInfo->intVectorId <= 15, ti_sdo_ipc_Ipc_A_internal); Assert_isTrue(intInfo->localIntId >= DSP_INT0 && intInfo->localIntId <= DSP_INT3, ti_sdo_ipc_Ipc_A_internal); Assert_isTrue(intInfo->remoteIntId == ARM_INT0 || intInfo->remoteIntId == ARM_INT1, ti_sdo_ipc_Ipc_A_internal); /* Disable global interrupts */ key = Hwi_disable(); InterruptDsp_intClear(remoteProcId, intInfo); /* Register interrupt for communication between ARM and DSP */ Hwi_Params_init(&hwiAttrs); hwiAttrs.maskSetting = Hwi_MaskingOption_SELF; hwiAttrs.arg = arg; hwiAttrs.eventId = intInfo->localIntId; Hwi_create(intInfo->intVectorId, (Hwi_FuncPtr)func, &hwiAttrs, NULL); /* Restore global interrupts */ Hwi_restore(key); /* enable the interrupt vector */ Hwi_enableInterrupt(intInfo->intVectorId); }
/* ======== initDevice ======== * 1. stop timer * 2. disable timer interrupt. (IER and any timer specific interrupt enable) * 3. clear pending interrupt. (IFR and any timer specific interrupt flags) * 4. Set control registers back to reset value. * 5. clear counters * 6. clear period register. */ static Void initDevice(Timer_Object *obj) { UInt key; key = Hwi_disable(); if (obj->id == 0) { /* SysTick */ Hwi_nvic.STCSR = 0; /* stop the timer */ Hwi_nvic.STRVR = 0; /* reset reload value */ Hwi_nvic.STCVR = 0; /* reset current value */ } else { /* CTM Timer */ CTM_ctm.CTCR[obj->ctmid] = 2; /* reset, stop, disable */ } if (obj->hwi) { Hwi_disableInterrupt(obj->intNum); Hwi_clearInterrupt(obj->intNum); } Hwi_restore(key); }
/** * @b Description * @n * The function is used by the SRIO driver to indicate that * its about to access a block of memory and we need to ensure * that the cache contents for this block are invalidated before * we try and use it. * * @param[in] ptr * Pointer to the buffer which is being accessed * @param[in] size * Size of the buffer which is to be accessed. * * @retval * None */ void Osal_srioBeginMemAccess(void* ptr, uint32_t size) { #if 0 CACHE_invL1d (ptr, size, CACHE_WAIT); /* Cleanup the prefectch buffer also. */ CSL_XMC_invalidatePrefetchBuffer(); #else UInt key; /* Disable Interrupts */ key = Hwi_disable(); /* Cleanup the prefetch buffer also. */ CSL_XMC_invalidatePrefetchBuffer(); /* Invalidate the cache. */ CACHE_invL1d (ptr, size, CACHE_FENCE_WAIT); /* Reenable Interrupts. */ Hwi_restore(key); #endif }
/* * ======== Timer_start ======== * 1. Hwi_disable(); * 2. Clear the counters * 3. Clear IFR * 4. Enable timer interrupt * 5. Start timer * 6. Hwi_restore() */ Void Timer_start(Timer_Object *obj) { UInt key; key = Hwi_disable(); if (obj->hwi) { Hwi_clearInterrupt(obj->intNum); Hwi_enableInterrupt(obj->intNum); } if (obj->runMode == Timer_RunMode_CONTINUOUS) { /* RESTART=1, INT=1, ENBL=1 */ CTM_ctm.CTCR[obj->ctmid] = 0x00000501; } else { /* RESTART=0, INT=1, ENBL=1 */ CTM_ctm.CTCR[obj->ctmid] = 0x00000101; } Hwi_restore(key); }
/*! * ======== InterruptM3_intRegister ======== */ Void InterruptM3_intRegister(Hwi_FuncPtr fxn) { Hwi_Params hwiAttrs; UInt key; hostProcId = MultiProc_getId("HOST"); dspProcId = MultiProc_getId("DSP"); sysm3ProcId = MultiProc_getId("CORE0"); appm3ProcId = MultiProc_getId("CORE1"); /* Disable global interrupts */ key = Hwi_disable(); userFxn = fxn; Hwi_Params_init(&hwiAttrs); hwiAttrs.maskSetting = Hwi_MaskingOption_LOWER; if (Core_getId() == 0) { Hwi_create(M3INT_MBX, (Hwi_FuncPtr)InterruptM3_isr, &hwiAttrs, NULL); /* InterruptM3_intEnable won't enable the Hwi */ Hwi_enableInterrupt(M3INT_MBX); } else { Hwi_create(M3INT, (Hwi_FuncPtr)InterruptM3_isr, &hwiAttrs, NULL); } /* Enable the mailbox interrupt to the M3 core */ InterruptM3_intEnable(); /* Restore global interrupts */ Hwi_restore(key); }
/** * @b Description * @n * The function is used to allocate a data buffer of the specified * size. Data buffers should always be allocated from the global * address space. * * @param[in] numBytes * Number of bytes to be allocated. * * @retval * Allocated block address */ Void* Osal_srioDataBufferMalloc(UInt32 numBytes) { uint32_t index; void* ptrMemory = NULL; /* Basic Validation: Ensure that the memory size requested is within range. */ if (numBytes > gDataBufferMemMgrMaxSize) return NULL; /* Increment the allocation counter. */ malloc_counter++; /* Lock out interrupts */ Hwi_disable(); /* Cycle through for a free entry. */ for (index = 0; index < MAX_MEM_MGR_ENTRIES; index++) { /* Check if the entry is free or not? */ if (gDataBufferMemMgr[index].isFree == 1) { /* Entry was free. We can use it. */ ptrMemory = gDataBufferMemMgr[index].ptrMemory; /* Mark the entry as used. */ gDataBufferMemMgr[index].isFree = 0; /* We have found a match. */ break; } } /* Unlock interrupts. */ Hwi_enable(); /* Return the allocated memory. */ return ptrMemory; }
/* * ======== Timer_getExpiredCounts ======== */ UInt32 Timer_getExpiredCounts(Timer_Object *obj) { UInt key; UInt32 count1, count2; Bool countFlag; key = Hwi_disable(); count1 = Timer_getCount(obj); /* Test corresponding Int pending flag */ countFlag = Hwi_nvic.ISPR[0] & (1 << (obj->intNum - 16)); count2 = Timer_getCount(obj); Hwi_restore(key); if (count2 < count1 && countFlag) { return (count1 + Timer_getPeriod(obj)); } else { return (count1) ; } }
/* * ======== ti_sdo_ipc_MessageQ_registerTransport ======== * Register a transport */ Bool ti_sdo_ipc_MessageQ_registerTransport(IMessageQTransport_Handle handle, UInt16 procId, UInt priority) { Bool flag = FALSE; UInt key; /* Make sure the procId is valid */ Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors, ti_sdo_ipc_MessageQ_A_procIdInvalid); /* lock scheduler */ key = Hwi_disable(); /* Make sure the id is not already in use */ if (MessageQ_module->transports[procId][priority] == NULL) { MessageQ_module->transports[procId][priority] = handle; flag = TRUE; } /* unlock scheduler */ Hwi_restore(key); return (flag); }
/* * ======== Timer_Module_startup ======== * Calls postInit for all statically-created & constructed * timers to initialize them. */ Int Timer_Module_startup(status) { Int i; UInt hwiKey; Timer_Object *obj; hwiKey = Hwi_disable(); CTM_ctm.CTCNTL |= 1; /* enable the CTM */ Hwi_restore(hwiKey); if (Timer_startupNeeded) { for (i = 0; i < Timer_NUM_TIMER_DEVICES; i++) { obj = Timer_module->handles[i]; /* if timer was statically created/constructed */ if ((obj != NULL) && (obj->staticInst)) { postInit(obj, NULL); } } } return (Startup_DONE); }
/* * ======== Power_unregisterNotify ======== * Unregister for a power notification. * */ Power_Status Power_unregisterNotify(Power_NotifyHandle notifyHandle) { Power_Status status = Power_SOK; UInt key; /* check for NULL notifyHandle */ if (notifyHandle == NULL) { status = Power_EINVALIDHANDLE; } else { /* remove notify object from its event queue */ key = Hwi_disable(); Queue_remove((Queue_Elem *)notifyHandle); Hwi_restore(key); /* free the notify object */ Memory_free(Power_Object_heap(), notifyHandle, sizeof(Power_NotifyObj)); } return(status); }
/* * ======== IpcPower_hibernateLock ======== */ UInt IpcPower_hibernateLock() { IArg hwiKey; #ifndef SMP UInt coreIdx = Core_getId(); #endif hwiKey = Hwi_disable(); #ifndef SMP IpcPower_hibLocks[coreIdx] += 1; #else IpcPower_hibLocks++; #endif Hwi_restore(hwiKey); #ifndef SMP return (IpcPower_hibLocks[coreIdx]); #else return IpcPower_hibLocks; #endif }
static inline Void IpcPower_sleepMode(IpcPower_SleepMode opt) { IArg hwiKey; /* Set/Restore the DeepSleep bit if no timer already in use */ hwiKey = Hwi_disable(); switch (opt) { case IpcPower_SLEEP_MODE_WAKEUNLOCK: if (refWakeLockCnt) { refWakeLockCnt--; } case IpcPower_SLEEP_MODE_DEEPSLEEP: if (!refWakeLockCnt) { IpcPower_deepSleep = TRUE; } break; case IpcPower_SLEEP_MODE_WAKELOCK: refWakeLockCnt++; IpcPower_deepSleep = FALSE; break; } Hwi_restore(hwiKey); }
/* * ======== Adaptor_runScheduledServices ======== */ Void Adaptor_runScheduledServices(Void) { UInt id; UInt key; UInt32 currentTime; /* Get the current time to determine who should be called */ currentTime = Clock_getTicks(); /* Query each service */ for (id = 0; id < ServiceMgr_getNumServices(); id++) { /* To protect against a change via Adaptor_setPeriod */ key = Hwi_disable(); /* * The service must have a non-zero period to be processed. * If scheduled time has past, call the process function. * Also handle the case where the clock wraps. */ if ((Adaptor_period[id] != 0) && EXPIRED(Adaptor_scheduled[id], currentTime)) { /* Set the new scheduled time */ Adaptor_scheduled[id] = currentTime + Adaptor_period[id]; Hwi_restore(key); /* Call the service's function to let it send events */ ServiceMgr_processCallback(id, ServiceMgr_Reason_PERIODEXPIRED, NULL); } else { Hwi_restore(key); } } }
Void Hwi_handlerSELF(Hwi_Object *hwi, UInt intNum) { Int32 nestingLevel; /* remember old nesting priority level */ nestingLevel = Hwi_cpIntc.HINLR[1]; /* forcibly unmask all channels/priorities */ Hwi_cpIntc.HINLR[1] = 0x80000020; /* clear the interrupt status for this int */ Hwi_cpIntc.SICR = intNum; /* disable this int */ Hwi_cpIntc.EICR = intNum; /* re-enable IRQs */ Hwi_cpIntc.HIEISR = 1; Hwi_enable(); (hwi->fxn)(hwi->arg); Hwi_disable(); /* disable IRQs */ Hwi_cpIntc.HIDISR = 1; /* enable this int */ Hwi_cpIntc.EISR = intNum; /* restore previous nesting level */ Hwi_cpIntc.HINLR[1] = nestingLevel | 0x80000000; /* re-enable IRQs */ Hwi_cpIntc.HIEISR = 1; }
/* * ======== Timer_initDevice ======== */ Void Timer_initDevice(Timer_Object *obj, Error_Block *eb) { TimerRegs *timer; UInt hwiKey; volatile UInt tmp; Timer_TimerSupportProxy_enable(obj->id, eb); timer = (TimerRegs *)Timer_module->device[obj->id].baseAddr; hwiKey = Hwi_disable(); timer->tclr = 0; while (timer->twps & TIMER_TWPS_W_PEND_TCLR) ; timer->tcrr = 0; while (timer->twps & TIMER_TWPS_W_PEND_TCRR) ; timer->tldr = 0; while (timer->twps & TIMER_TWPS_W_PEND_TLDR) ; /* disable timer interrupts */ timer->tier = 0; /* clear any pending interrupts */ tmp = timer->tisr; timer->tisr = tmp; if (obj->hwi) { /* clear any previously latched timer interrupts */ Hwi_clearInterrupt(obj->intNum); Hwi_disableInterrupt(obj->intNum); } Hwi_restore(hwiKey); }