/********************************************************************* * @fn OADTarget_disableCache * * @brief Resumes system after a write to flash, if necessary. * * @param None. * * @return VIMS_MODE_ENABLED if cache was in use before this operation, * VIMS_MODE_DISABLED otherwise. */ static uint8_t OADTarget_disableCache(void) { uint8_t state = VIMSModeGet(VIMS_BASE); // Check VIMS state if (state != VIMS_MODE_DISABLED) { // Invalidate cache VIMSModeSet(VIMS_BASE, VIMS_MODE_DISABLED); // Wait for disabling to be complete while (VIMSModeGet(VIMS_BASE) != VIMS_MODE_DISABLED); } return state; }
/******************************************************************************* * @fn Main * * @brief Application Main * * input parameters * * @param None. * * output parameters * * @param None. * * @return None. */ int main() { #ifdef CACHE_AS_RAM // Invalidate cache VIMSModeSet( VIMS_BASE, VIMS_MODE_DISABLED ); // Wait for disabling to be complete while ( VIMSModeGet( VIMS_BASE ) != VIMS_MODE_DISABLED ); // retain cache during standby Power_setConstraint(PowerCC26XX_SB_VIMS_CACHE_RETAIN); #endif RegisterAssertCback(AssertHandler); PIN_init(BoardGpioInitTable); #ifndef POWER_SAVING /* Set constraints for Standby, powerdown and idle mode */ Power_setConstraint(PowerCC26XX_SB_DISALLOW); Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW); #endif //POWER_SAVING #ifdef PRINTF_ENABLED // Enable System_printf(..) UART output UART_Params uartParams; UART_Params_init(&uartParams); uartParams.baudRate = 1000000; UartPrintf_init(UART_open(Board_UART, &uartParams)); System_printf("Printf enabled\r\n"); #endif /* Initialize ICall module */ ICall_init(); /* Start tasks of external images - Priority 5 */ ICall_createRemoteTasks(); /* Kick off profile - Priority 3 */ GAPRole_createTask(); Keys_createTask(); /* Kick off application - Priority 1 */ SimpleTopology_createTask(); /* enable interrupts and start SYS/BIOS */ BIOS_start(); return 0; }
//***************************************************************************** // // Safe setting of new VIMS mode // - Function might be blocking // - Can be called for any mode change (also if actually not changing mode) // //***************************************************************************** void VIMSModeSafeSet( uint32_t ui32Base, uint32_t ui32NewMode, bool blocking ) { uint32_t currentMode; // Check the arguments. ASSERT(VIMSBaseValid(ui32Base)); ASSERT((ui32NewMode == VIMS_MODE_DISABLED) || (ui32NewMode == VIMS_MODE_ENABLED) || (ui32NewMode == VIMS_MODE_OFF)); // Make sure that only the mode bits are set in the input parameter // (done just for security since it is critical to the code flow) ui32NewMode &= VIMS_CTL_MODE_M; // Wait for any pending change to complete and get current VIMS mode // (This is a blocking point but will typically only be a blocking point // only if mode is changed multiple times with blocking=0) do { currentMode = VIMSModeGet( ui32Base ); } while ( currentMode == VIMS_MODE_CHANGING ); // First check that it actually is a mode change request if ( ui32NewMode != currentMode ) { // Due to a hw-problem it is strongly recommended to go via VIMS_MODE_OFF // when leaving VIMS_MODE_ENABLED (=VIMS_CTL_MODE_CACHE) // (And no need to go via OFF, if OFF is the final state and will be set later) if (( currentMode == VIMS_CTL_MODE_CACHE ) && ( ui32NewMode != VIMS_CTL_MODE_OFF ) ) { VIMSModeSet( ui32Base, VIMS_MODE_OFF ); while ( HWREGBITW( VIMS_BASE + VIMS_O_STAT, VIMS_STAT_MODE_CHANGING_BITN )) { // Do nothing - wait for change to complete. // (Needed blocking point but it takes only some few cycles) } } // Set new mode VIMSModeSet( ui32Base, ui32NewMode ); // Wait for final mode change to complete - if blocking is requested if ( blocking ) { while ( HWREGBITW( VIMS_BASE + VIMS_O_STAT, VIMS_STAT_MODE_CHANGING_BITN )) { // Do nothing - wait for change to complete. } } } }
/* * ======== Power_sleep ======== */ Power_Status Power_sleep(Power_SleepState sleepState, UArg arg0, UArg arg1) { Power_Status status = Power_SOK; UInt xosc_hf_active = FALSE; Power_Event postEventLate; UInt32 poweredDomains = 0; Bool exitNow = FALSE; Power_Event preEvent; Power_Event postEvent; UInt32 constraints; Bool retainCache = FALSE; UInt32 modeVIMS; UInt taskKey; UInt swiKey; UInt hwiKey; /* first validate the sleep code */ if ( sleepState != Power_STANDBY) { status = Power_EFAIL; } if (status == Power_SOK) { /* make sure Power is not still busy with a previous transition */ hwiKey = Hwi_disable(); if (Power_module->state == Power_ACTIVE) { /* set transition state to entering sleep */ Power_module->state = Power_ENTERING_SLEEP; } else { exitNow = TRUE; } Hwi_restore(hwiKey); if (exitNow == TRUE) { status = Power_EBUSY; } else { /* setup sleep vars */ if (sleepState == Power_STANDBY) { preEvent = Power_ENTERING_STANDBY; postEvent = Power_AWAKE_STANDBY; postEventLate = Power_AWAKE_STANDBY_LATE; } /* disable Task scheduling; allow Swis and Hwis for notifications */ taskKey = Task_disable(); /* signal all clients registered for pre-sleep notification */ status = Power_notify(preEvent); /* check for any error */ if (status != Power_SOK) { Power_module->state = Power_ACTIVE; Task_restore(taskKey); /* re-enable scheduler */ return (status); } /* now disable Swi scheduling */ swiKey = Swi_disable(); /* freeze the IOs on the boundary between MCU and AON */ AONIOCFreezeEnable(); /* if XOSC_HF is active, force it off */ if(OSCClockSourceGet(OSC_SRC_CLK_HF) == OSC_XOSC_HF) { xosc_hf_active = TRUE; ti_sysbios_family_arm_cc26xx_Power_XOSC_HF(DISABLE); } /* allow AUX to power down */ AONWUCAuxWakeupEvent(AONWUC_AUX_ALLOW_SLEEP); /* make sure writes take effect */ SysCtrlAonSync(); /* invoke specific sequences to activate sleep states... */ if (sleepState == Power_STANDBY) { /* query and save domain states before powering them off */ if (Power_getDependencyCount(DOMAIN_RFCORE)) { poweredDomains |= PRCM_DOMAIN_RFCORE; } if (Power_getDependencyCount(DOMAIN_SERIAL)){ poweredDomains |= PRCM_DOMAIN_SERIAL; } if (Power_getDependencyCount(DOMAIN_PERIPH)) { poweredDomains |= PRCM_DOMAIN_PERIPH; } /* gate running deep sleep clocks for Crypto and DMA */ if (Power_getDependencyCount(PERIPH_CRYPTO)) { PRCMPeripheralDeepSleepDisable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_CRYPTO].driverlibID); } if (Power_getDependencyCount(PERIPH_UDMA)) { PRCMPeripheralDeepSleepDisable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_UDMA].driverlibID); } /* make sure clock settings take effect */ PRCMLoadSet(); /* request power off of domains in the MCU voltage domain */ PRCMPowerDomainOff(poweredDomains | PRCM_DOMAIN_CPU); /* request uLDO during standby */ PRCMMcuUldoConfigure(true); /* query constraints to determine if cache should be retained */ constraints = Power_getConstraintInfo(); if ((constraints & Power_SB_VIMS_CACHE_RETAIN) != 0) { retainCache = TRUE; } /* if don't want retention in standby, disable it now ... */ if (retainCache == FALSE) { modeVIMS = VIMSModeGet(VIMS_BASE); /* wait if invalidate in progress... */ while (modeVIMS == VIMS_MODE_CHANGING) { modeVIMS = VIMSModeGet(VIMS_BASE); } PRCMCacheRetentionDisable(); VIMSModeSet(VIMS_BASE, VIMS_MODE_OFF); } /* setup recharge parameters */ SysCtrlSetRechargeBeforePowerDown(XoscInHighPowerMode); /* make sure all writes have taken effect */ SysCtrlAonSync(); /* invoke deep sleep to go to STANDBY */ PRCMDeepSleep(); /* if didn't retain cache in standby, re-enable retention now */ if (retainCache == FALSE) { VIMSModeSet(VIMS_BASE, modeVIMS); PRCMCacheRetentionEnable(); } /* force power on of AUX to keep it on when system is not * sleeping; this also counts as a write to the AON interface * ensuring that a following sync of the AON interface will * force an update of all registers */ AONWUCAuxWakeupEvent(AONWUC_AUX_WAKEUP); while(!(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON)) {}; /* if XOSC_HF was forced off above, initiate switch back */ if (xosc_hf_active == TRUE) { ti_sysbios_family_arm_cc26xx_Power_XOSC_HF(ENABLE); } /* restore power domain states in effect before standby */ PRCMPowerDomainOn(poweredDomains); while (PRCMPowerDomainStatus(poweredDomains) != PRCM_DOMAIN_POWER_ON){}; /* restore deep sleep clocks of Crypto and DMA */ if (Power_getDependencyCount(PERIPH_CRYPTO)) { PRCMPeripheralDeepSleepEnable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_CRYPTO].driverlibID); } if (Power_getDependencyCount(PERIPH_UDMA)) { PRCMPeripheralDeepSleepEnable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_UDMA].driverlibID); } /* make sure clock settings take effect */ PRCMLoadSet(); } /* release request for uLDO */ PRCMMcuUldoConfigure(false); /* set transition state to EXITING_SLEEP */ Power_module->state = Power_EXITING_SLEEP; /* * signal clients registered for early post-sleep notification; * this should be used to initialize any timing critical or IO * dependent hardware */ status = Power_notify(postEvent); /* disable IO freeze and ensure RTC shadow value is updated */ AONIOCFreezeDisable(); SysCtrlAonSync(); /* re-enable interrupts */ CPUcpsie(); /* signal all clients registered for late post-sleep notification */ status = Power_notify(postEventLate); /* now clear the transition state before re-enabling scheduler */ Power_module->state = Power_ACTIVE; /* re-enable Swi scheduling */ Swi_restore(swiKey); /* adjust recharge parameters */ SysCtrlAdjustRechargeAfterPowerDown(); /* re-enable Task scheduling */ Task_restore(taskKey); /* check for any notification error */ if (status != Power_SOK) { return (status); } } } return (status); }