void app_loop(bool threaded) { DECLARE_SYS_HEALTH(ENTERED_WLAN_Loop); if (!threaded) Spark_Idle(); static uint8_t SPARK_WIRING_APPLICATION = 0; if(threaded || SPARK_WLAN_SLEEP || !SPARK_CLOUD_CONNECT || SPARK_CLOUD_CONNECTED || SPARK_WIRING_APPLICATION || (system_mode()!=AUTOMATIC)) { if(threaded || !SPARK_FLASH_UPDATE) { if ((SPARK_WIRING_APPLICATION != 1)) { //Execute user application setup only once DECLARE_SYS_HEALTH(ENTERED_Setup); if (system_mode()!=SAFE_MODE) setup(); SPARK_WIRING_APPLICATION = 1; } //Execute user application loop DECLARE_SYS_HEALTH(ENTERED_Loop); if (system_mode()!=SAFE_MODE) { loop(); DECLARE_SYS_HEALTH(RAN_Loop); #if !MODULAR_FIRMWARE serialEventRun(); #endif } } } }
/******************************************************************************* * Function Name : main. * Description : main routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void app_setup_and_loop(void) { system_part2_post_init(); HAL_Core_Init(); // We have running firmware, otherwise we wouldn't have gotten here DECLARE_SYS_HEALTH(ENTERED_Main); PMIC().begin(); FuelGauge().wakeup(); DEBUG("Hello from Particle!"); String s = spark_deviceID(); INFO("Device %s started", s.c_str()); manage_safe_mode(); #if defined (START_DFU_FLASHER_SERIAL_SPEED) || defined (START_YMODEM_FLASHER_SERIAL_SPEED) USB_USART_LineCoding_BitRate_Handler(system_lineCodingBitRateHandler); #endif bool threaded = system_thread_get_state(NULL) != spark::feature::DISABLED && (system_mode()!=SAFE_MODE); Network_Setup(threaded); #if PLATFORM_THREADING if (threaded) { SystemThread.start(); ApplicationThread.start(); } else { SystemThread.setCurrentThread(); ApplicationThread.setCurrentThread(); } #endif if(!threaded) { /* Main loop */ while (1) { app_loop(false); } } }
/******************************************************************************* * Function Name : HAL_Core_Config. * Description : Called in startup routine, before calling C++ constructors. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void HAL_Core_Config(void) { // this ensures the stm32_it.c functions aren't dropped by the linker, thinking // they are unused. Without this none of the interrupts handlers are linked. linkme(); DECLARE_SYS_HEALTH(ENTERED_SparkCoreConfig); #ifdef DFU_BUILD_ENABLE /* Set the Vector Table(VT) base location at 0x5000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x5000); USE_SYSTEM_FLAGS = 1; #endif #ifdef SWD_JTAG_DISABLE /* Disable the Serial Wire JTAG Debug Port SWJ-DP */ GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); #else #ifdef SWD_ENABLE_JTAG_DISABLE /* Disable JTAG, but enable SWJ-DP */ GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); #endif #endif Set_System(); SysTick_Configuration(); /* Enable CRC clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); HAL_RTC_Configuration(); /* Execute Stop mode if STOP mode flag is set via System.sleep(pin, mode) */ HAL_Core_Execute_Stop_Mode(); LED_SetRGBColor(RGB_COLOR_WHITE); LED_On(LED_RGB); #ifdef IWDG_RESET_ENABLE // ToDo this needs rework for new bootloader /* Check if the system has resumed from IWDG reset */ if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) { /* IWDGRST flag set */ IWDG_SYSTEM_RESET = 1; /* Clear reset flags */ RCC_ClearFlag(); } /* We are duplicating the IWDG call here for compatibility with old bootloader */ /* Set IWDG Timeout to 3 secs */ IWDG_Reset_Enable(3 * TIMING_IWDG_RELOAD); #endif #ifdef DFU_BUILD_ENABLE Load_SystemFlags(); #endif sFLASH_Init(); module_user_init_hook(); }
/******************************************************************************* * Function Name : HAL_Core_Config. * Description : Called in startup routine, before calling C++ constructors. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void HAL_Core_Config(void) { DECLARE_SYS_HEALTH(ENTERED_SparkCoreConfig); #ifdef DFU_BUILD_ENABLE //Currently this is done through WICED library API so commented. //NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x20000); USE_SYSTEM_FLAGS = 1; #endif Set_System(); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); //Wiring pins default to inputs #if !defined(USE_SWD_JTAG) && !defined(USE_SWD) for (pin_t pin=0; pin<=19; pin++) HAL_Pin_Mode(pin, INPUT); #if PLATFORM_ID==8 // Additional pins for P1 for (pin_t pin=24; pin<=29; pin++) HAL_Pin_Mode(pin, INPUT); #endif #if PLATFORM_ID==10 // Additional pins for Electron for (pin_t pin=24; pin<=35; pin++) HAL_Pin_Mode(pin, INPUT); #endif #endif HAL_Core_Config_systick_configuration(); HAL_RTC_Configuration(); HAL_RNG_Configuration(); #ifdef DFU_BUILD_ENABLE Load_SystemFlags(); #endif LED_SetRGBColor(RGB_COLOR_WHITE); LED_On(LED_RGB); // override the WICED interrupts, specifically SysTick - there is a bug // where WICED isn't ready for a SysTick until after main() has been called to // fully intialize the RTOS. HAL_Core_Setup_override_interrupts(); #if MODULAR_FIRMWARE // write protect system module parts if not already protected FLASH_WriteProtectMemory(FLASH_INTERNAL, CORE_FW_ADDRESS, USER_FIRMWARE_IMAGE_LOCATION - CORE_FW_ADDRESS, true); #endif #ifdef HAS_SERIAL_FLASH //Initialize Serial Flash sFLASH_Init(); #else FLASH_AddToFactoryResetModuleSlot(FLASH_INTERNAL, INTERNAL_FLASH_FAC_ADDRESS, FLASH_INTERNAL, USER_FIRMWARE_IMAGE_LOCATION, FIRMWARE_IMAGE_SIZE, FACTORY_RESET_MODULE_FUNCTION, MODULE_VERIFY_CRC|MODULE_VERIFY_FUNCTION|MODULE_VERIFY_DESTINATION_IS_START_ADDRESS); //true to verify the CRC during copy also #endif }
/******************************************************************************* * Function Name : HAL_SysTick_Handler * Description : Decrements the various Timing variables related to SysTick. * Input : None * Output : None. * Return : None. ************************************************ *******************************/ extern "C" void HAL_SysTick_Handler(void) { if (LED_RGB_IsOverRidden()) { #ifndef SPARK_NO_CLOUD if (LED_Spark_Signal != 0) { LED_Signaling_Override(); } #endif } else if (TimingLED != 0x00) { TimingLED--; } else if(SPARK_FLASH_UPDATE || Spark_Error_Count || network.listening()) { //Do nothing } else if (SYSTEM_POWEROFF) { LED_SetRGBColor(RGB_COLOR_GREY); LED_On(LED_RGB); } else if(SPARK_LED_FADE && (!SPARK_CLOUD_CONNECTED || system_cloud_active())) { LED_Fade(LED_RGB); TimingLED = 20;//Breathing frequency kept constant } else if(SPARK_CLOUD_CONNECTED) { LED_SetRGBColor(system_mode()==SAFE_MODE ? RGB_COLOR_MAGENTA : RGB_COLOR_CYAN); LED_On(LED_RGB); SPARK_LED_FADE = 1; } else { LED_Toggle(LED_RGB); if(SPARK_CLOUD_SOCKETED || ( network.connected() && !network.ready())) TimingLED = 50; //50ms else TimingLED = 100; //100ms } if(SPARK_FLASH_UPDATE) { #ifndef SPARK_NO_CLOUD if (TimingFlashUpdateTimeout >= TIMING_FLASH_UPDATE_TIMEOUT) { //Reset is the only way now to recover from stuck OTA update HAL_Core_System_Reset(); } else { TimingFlashUpdateTimeout++; } #endif } else if(network.listening() && HAL_Core_Mode_Button_Pressed(10000)) { network.listen_command(); } // determine if the button press needs to change the state (and hasn't done so already)) else if(!network.listening() && HAL_Core_Mode_Button_Pressed(3000) && !wasListeningOnButtonPress) { if (network.connecting()) { network.connect_cancel(true, true); } // fire the button event to the user, then enter listening mode (so no more button notifications are sent) // there's a race condition here - the HAL_notify_button_state function should // be thread safe, but currently isn't. HAL_Notify_Button_State(0, false); network.listen(); HAL_Notify_Button_State(0, true); } #ifdef IWDG_RESET_ENABLE if (TimingIWDGReload >= TIMING_IWDG_RELOAD) { TimingIWDGReload = 0; /* Reload WDG counter */ HAL_Notify_WDT(); DECLARE_SYS_HEALTH(CLEARED_WATCHDOG); } else { TimingIWDGReload++; } #endif }