Here is what happened to me:
Upgraded Electron from release 0.6.1
to 0.7.0
Downgraded back to 0.6.1
by flashing the three spark firmware binaries to Electron.
Ran a test program that reports the reset reason using System.resetReason()
Whenever a reset was instigated by the reset pin, System.resetReason()
would return 0 (i.e. RESET_NONE
) instead of 20 (i.e. RESET_REASON_PIN
)
Used ST-Link utility to manually flash 0.4.8 bootloader to Electron from following link: https://github.com/rickkas7/particle_jtag/blob/master/files/bootloader-electron.bin?raw=true
After that, things started working normally again.
So, my question is: is this supposed to work like this? How do I make sure that the bootloader on any given device works with the spark firmware on that device?
Here is my test program:
#include "Particle.h"
PRODUCT_ID(xxx);
PRODUCT_VERSION(xx);
//Configure how the app runs within the Particle ecosystem
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);
//Configure Particle system (runs this code before any Particle init code runs):
STARTUP(
//Configure other Particle runtime parameters
System.enableFeature(FEATURE_RETAINED_MEMORY);
//Enable system reset information
System.enableFeature(FEATURE_RESET_INFO);
//Make sure that cloud DFU updates are enabled
System.enableUpdates();
);
//Define log handler using serial monitor (dumps logs to serial monitor)
SerialLogHandler logHandler(LOG_LEVEL_ALL,
{
{"app" , LOG_LEVEL_ALL },
}
);
static Logger myLog("app.main"); //Logger object used in this "main.cpp" file
retained uint32_t reset_data = 0;
enum spark_api_reset_reason_t{
RESET_PIN_RESET,
RESET_POWER_MANAGEMENT,
RESET_POWER_DOWN,
RESET_POWER_BROWNOUT,
RESET_WATCHDOG,
RESET_UPDATE,
RESET_UPDATE_TIMEOUT,
RESET_FACTORY_RESET,
RESET_SAFE_MODE,
RESET_DFU_MODE,
RESET_PANIC,
RESET_USER,
RESET_UNKNOWN,
RESET_NONE,
NUM_RESET_REASONS
};
const char* const spark_api_reset_reason_names[NUM_RESET_REASONS+1] = {
"RESET_PIN_RESET",
"RESET_POWER_MANAGEMENT",
"RESET_POWER_DOWN",
"RESET_POWER_BROWNOUT",
"RESET_WATCHDOG",
"RESET_UPDATE",
"RESET_UPDATE_TIMEOUT",
"RESET_FACTORY_RESET",
"RESET_SAFE_MODE",
"RESET_DFU_MODE",
"RESET_PANIC",
"RESET_USER",
"RESET_UNKNOWN",
"RESET_NONE",
"NO RESET REASON MATCHES!"
};
int resetReason;
int resetReasonData;
void setup() // Put setup code here to run once
{
Serial.begin(115200);
delay(3000);
Serial.println("========================================================================================");
Serial.println("================ EVALUATING RESET REASON ==================");
myLog.info("SysVersion: %s", System.version().c_str());
myLog.trace(
"System.resetReason() == %d | System.resetReasonData() == %lu",
System.resetReason(), System.resetReasonData()
);
Serial.println("========================================================================================");
resetReason = System.resetReason();
resetReasonData = System.resetReasonData();
spark_api_reset_reason_t decoded_reset_reason = NUM_RESET_REASONS;
switch(resetReason){
case RESET_REASON_PIN_RESET:
decoded_reset_reason = RESET_PIN_RESET;
break;
case RESET_REASON_POWER_MANAGEMENT:
decoded_reset_reason = RESET_POWER_MANAGEMENT;
break;
case RESET_REASON_POWER_DOWN:
decoded_reset_reason = RESET_POWER_DOWN;
break;
case RESET_REASON_POWER_BROWNOUT:
decoded_reset_reason = RESET_POWER_BROWNOUT;
break;
case RESET_REASON_WATCHDOG:
decoded_reset_reason = RESET_WATCHDOG;
break;
case RESET_REASON_UPDATE:
decoded_reset_reason = RESET_UPDATE;
break;
case RESET_REASON_UPDATE_TIMEOUT:
decoded_reset_reason = RESET_UPDATE_TIMEOUT;
break;
case RESET_REASON_FACTORY_RESET:
decoded_reset_reason = RESET_FACTORY_RESET;
break;
case RESET_REASON_SAFE_MODE:
decoded_reset_reason = RESET_SAFE_MODE;
break;
case RESET_REASON_DFU_MODE:
decoded_reset_reason = RESET_DFU_MODE;
break;
case RESET_REASON_PANIC:
decoded_reset_reason = RESET_PANIC;
break;
case RESET_REASON_USER:
decoded_reset_reason = RESET_USER;
break;
case RESET_REASON_UNKNOWN:
decoded_reset_reason = RESET_UNKNOWN;
break;
case RESET_REASON_NONE:
decoded_reset_reason = RESET_NONE;
break;
}
myLog.trace(
"decoded_reset_reason == %s",
spark_api_reset_reason_names[decoded_reset_reason]
);
Serial.println("========================================================================================");
Serial.println("------- LIST OF RESET REASON ENUMERATED TYPES -------");
Serial.printlnf("RESET_REASON_NONE = %d", RESET_REASON_NONE);
Serial.printlnf("RESET_REASON_UNKNOWN = %d", RESET_REASON_UNKNOWN);
Serial.printlnf("RESET_REASON_PIN_RESET = %d", RESET_REASON_PIN_RESET);
Serial.printlnf("RESET_REASON_POWER_MANAGEMENT = %d", RESET_REASON_POWER_MANAGEMENT);
Serial.printlnf("RESET_REASON_POWER_DOWN = %d", RESET_REASON_POWER_DOWN);
Serial.printlnf("RESET_REASON_POWER_BROWNOUT = %d", RESET_REASON_POWER_BROWNOUT);
Serial.printlnf("RESET_REASON_WATCHDOG = %d", RESET_REASON_WATCHDOG);
Serial.printlnf("RESET_REASON_UPDATE = %d", RESET_REASON_UPDATE);
Serial.printlnf("RESET_REASON_UPDATE_TIMEOUT = %d", RESET_REASON_UPDATE_TIMEOUT);
Serial.printlnf("RESET_REASON_FACTORY_RESET = %d", RESET_REASON_FACTORY_RESET);
Serial.printlnf("RESET_REASON_SAFE_MODE = %d", RESET_REASON_SAFE_MODE);
Serial.printlnf("RESET_REASON_DFU_MODE = %d", RESET_REASON_DFU_MODE);
Serial.printlnf("RESET_REASON_PANIC = %d", RESET_REASON_PANIC);
Serial.printlnf("RESET_REASON_USER = %d", RESET_REASON_USER);
Serial.println("========================================================================================");
}
void loop() // Put code here to loop forever
{
if(millis() > 40000){
resetReasonData++;
System.reset(resetReasonData);
}
else{
Serial.printlnf("looping");
delay(1000);
}
if(Serial.available()){
System.dfu();
}
}