/* * ======== 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); }
int main(void) { uint8_t payload[ADVLEN]; //Disable JTAG to allow for Standby AONWUCJtagPowerOff(); //Force AUX on powerEnableAuxForceOn(); powerEnableRFC(); powerEnableXtalInterface(); // Divide INF clk to save Idle mode power (increases interrupt latency) powerDivideInfClkDS(PRCM_INFRCLKDIVDS_RATIO_DIV32); initRTC(); powerEnablePeriph(); powerEnableGPIOClockRunMode(); /* Wait for domains to power on */ while((PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON)); sensorsInit(); ledInit(); //Config IOID4 for external interrupt on rising edge and wake up //IOCPortConfigureSet(BOARD_IOID_KEY_RIGHT, IOC_PORT_GPIO, IOC_IOMODE_NORMAL | IOC_FALLING_EDGE | IOC_INT_ENABLE | IOC_IOPULL_UP | IOC_INPUT_ENABLE | IOC_WAKE_ON_LOW); // Config reedSwitch as input IOCPortConfigureSet(BOARD_IOID_DP0, IOC_PORT_GPIO, IOC_IOMODE_NORMAL | IOC_RISING_EDGE | IOC_INT_ENABLE | IOC_IOPULL_DOWN | IOC_INPUT_ENABLE | IOC_WAKE_ON_HIGH); //Set device to wake MCU from standby on PIN 4 (BUTTON1) HWREG(AON_EVENT_BASE + AON_EVENT_O_MCUWUSEL) = AON_EVENT_MCUWUSEL_WU0_EV_PAD; //Does not work with AON_EVENT_MCUWUSEL_WU0_EV_PAD4 --> WHY?? IntEnable(INT_EDGE_DETECT); powerDisablePeriph(); //Disable clock for GPIO in CPU run mode HWREGBITW(PRCM_BASE + PRCM_O_GPIOCLKGR, PRCM_GPIOCLKGR_CLK_EN_BITN) = 0; // Load clock settings HWREGBITW(PRCM_BASE + PRCM_O_CLKLOADCTL, PRCM_CLKLOADCTL_LOAD_BITN) = 1; initInterrupts(); initRadio(); // baek: before while powerEnablePeriph(); powerEnableGPIOClockRunMode(); /* Wait for domains to power on */ while((PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON)); // CRASH !!!!!!!!!!!!!! sensorsInit(); ledInit(); // end baek: // Turn off FLASH in idle mode powerDisableFlashInIdle(); // Cache retention must be enabled in Idle if flash domain is turned off (to avoid cache corruption) powerEnableCacheRetention(); //AUX - request to power down (takes no effect since force on is set) powerEnableAUXPdReq(); powerDisableAuxRamRet(); //Clear payload buffer memset(payload, 0, ADVLEN); while(1) { //if((g_count& 0x04)== 1){ rfBootDone = 0; rfSetupDone = 0; rfAdvertisingDone = 0; select_bmp_280(); // activates I2C for bmp-sensor enable_bmp_280(1); // works //Wait until RF Core PD is ready before accessing radio waitUntilRFCReady(); initRadioInts(); runRadio(); //Wait until AUX is ready before configuring oscillators waitUntilAUXReady(); //Enable 24MHz XTAL OSCHF_TurnOnXosc(); //IDLE until BOOT_DONE interrupt from RFCore is triggered while( ! rfBootDone) { powerDisableCPU(); PRCMDeepSleep(); } //This code runs after BOOT_DONE interrupt has woken up the CPU again // -> //Request radio to keep on system bus radioCmdBusRequest(true); //Patch CM0 - no RFE patch needed for TX only radioPatch(); //Start radio timer radioCmdStartRAT(); //Enable Flash access while doing radio setup powerEnableFlashInIdle(); //Switch to XTAL while( !OSCHF_AttemptToSwitchToXosc()) {} /* baek: before while powerEnablePeriph(); powerEnableGPIOClockRunMode(); /* Wait for domains to power on */ /* while((PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON)); // CRASH !!!!!!!!!!!!!! sensorsInit(); ledInit(); */ /*****************************************************************************************/ // Read sensor values uint32_t pressure = 0; // only 3 Bytes used //uint32_t temp = 0; select_bmp_280(); // activates I2C for bmp-sensor enable_bmp_280(1); // works do{ pressure = value_bmp_280(BMP_280_SENSOR_TYPE_PRESS); // read and converts in pascal (96'000 Pa) //temp = value_bmp_280(BMP_280_SENSOR_TYPE_TEMP); }while(pressure == 0x80000000); if(pressure == 0x80000000){ CPUdelay(100); pressure = value_bmp_280(BMP_280_SENSOR_TYPE_PRESS); // read and converts in pascal (96'000 Pa) } //Start Temp measurement uint16_t temperature; enable_tmp_007(1); //Wait for, read and calc temperature { int count = 0; do{ temperature = value_tmp_007(TMP_007_SENSOR_TYPE_AMBIENT); //g_count++; }while( ((temperature == 0x80000000) || (temperature == 0)) && (count <=5) ); count++; count--; } enable_tmp_007(0); char char_temp[2]; //start hum measurement configure_hdc_1000(); start_hdc_1000(); // //Wait for, read and calc humidity while(!read_data_hdc_1000()); int humidity = value_hdc_1000(HDC_1000_SENSOR_TYPE_HUMIDITY); // char char_hum[5]; //END read sensor values /*****************************************************************************************/ powerDisablePeriph(); // Disable clock for GPIO in CPU run mode HWREGBITW(PRCM_BASE + PRCM_O_GPIOCLKGR, PRCM_GPIOCLKGR_CLK_EN_BITN) = 0; // Load clock settings HWREGBITW(PRCM_BASE + PRCM_O_CLKLOADCTL, PRCM_CLKLOADCTL_LOAD_BITN) = 1; /*****************************************************************************************/ // Set payload and transmit uint8_t p; p = 0; /*jedes 5.te mal senden*/ payload[p++] = ADVLEN-1; /* len */ payload[p++] = 0x03; payload[p++] = 0xde; payload[p++] = 0xba; payload[p++] =(sequenceNumber >> 8); // laufnummer payload[p++] = sequenceNumber; // Speed payload[p++] = g_diff >> 24; // higher seconds payload[p++] = g_diff >> 16; // lower seconds payload[p++] = g_diff >> 8; // higher subseconds payload[p++] = g_diff; // lower subseconds //pressure payload[p++] = 0; payload[p++] = 0; //(pressure >> 16); payload[p++] = 0; //(pressure >> 8); payload[p++] = 0; //pressure; //temperature payload[p++] = 0; payload[p++] = 0; // char_temp[2]; payload[p++] = 0;//temperature >> 8; // char_temp[1]; payload[p++] = 0; //temperature; //char_temp[0]; // huminity payload[p++] = 0; payload[p++] = 0;//char_hum[0]; payload[p++] = 0;//char_hum[1]; payload[p++] = 0;//char_hum[2]; payload[p++] = 0; payload[p++] = 0; //Start radio setup and linked advertisment radioUpdateAdvData(ADVLEN, payload); //Start radio setup and linked advertisment radioSetupAndTransmit(); //} //END: Transmit /*****************************************************************************************/ //Wait in IDLE for CMD_DONE interrupt after radio setup. ISR will disable radio interrupts while( ! rfSetupDone) { powerDisableCPU(); PRCMDeepSleep(); } //Disable flash in IDLE after CMD_RADIO_SETUP is done (radio setup reads FCFG trim values) powerDisableFlashInIdle(); //Wait in IDLE for LAST_CMD_DONE after 3 adv packets while( ! rfAdvertisingDone) { powerDisableCPU(); PRCMDeepSleep(); } //Request radio to not force on system bus any more radioCmdBusRequest(false); // } // end if // g_count++; // // Standby procedure // powerDisableXtal(); // Turn off radio powerDisableRFC(); // Switch to RCOSC_HF OSCHfSourceSwitch(); // Allow AUX to turn off again. No longer need oscillator interface powerDisableAuxForceOn(); // Goto Standby. MCU will now request to be powered down on DeepSleep powerEnableMcuPdReq(); // Disable cache and retention powerDisableCache(); powerDisableCacheRetention(); //Calculate next recharge SysCtrlSetRechargeBeforePowerDown(XOSC_IN_HIGH_POWER_MODE); // Synchronize transactions to AON domain to ensure AUX has turned off SysCtrlAonSync(); // // Enter Standby // powerDisableCPU(); PRCMDeepSleep(); SysCtrlAonUpdate(); SysCtrlAdjustRechargeAfterPowerDown(); SysCtrlAonSync(); // // Wakeup from RTC, code starts execution from here // powerEnableRFC(); powerEnableAuxForceOn(); //Re-enable cache and retention powerEnableCache(); powerEnableCacheRetention(); //MCU will not request to be powered down on DeepSleep -> System goes only to IDLE powerDisableMcuPdReq(); } }