Standalone Xenon user firmware execution

TLDR: I can flash my Xenon, but can’t get it to execute my user firmware, it appears to remain in listening mode (flashing blue).
How can I configure the Xenon to run my user firmware instead?

Background:
Hello, I previously used a RedBear Duo as a standalone BLE central device, reading advertisements from sensors of interest. As the RedBear devices lose support, Particle staff suggested that a Xenon would be a suitable replacement.

I currently have a Xenon device, and I’m able to compile and flash my custom firmware to it using Workbench or Particle CLI. I am able to put the Xenon into DFU mode and the firmware flash reports successful completion. Unfortunately, the Xenon does not appear to be executing my firmware. It continues flashing the blue LED (indicating listening mode?) and if I connect to it over USB serial at 9600 baud, it will respond with the Device ID, etc if I send “i” to it.

I do not have any other Particle devices besides the Xenon, so I was not able to set it up as part of a mesh network. I don’t want or need the mesh capability, I just want to scan BLE advertisements and send the data out from the serial port.

Relevant steps I’ve taken to try to resolve this:

  1. I suspected that perhaps it was staying in listening mode because the mesh network setup was never executed, so I used DFU to mark setup done:
echo -n -e \\x01 > dummy.bin 
dfu-util -d 2b04:d00e -a 1 -s 0x1fc6:leave -D dummy.bin
  1. My code has the following at the top (per this post):
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);
  1. I tried using Particle CLI to send “particle usb stop-listening” which reports Done, but doesn’t change the Xenon’s behavior

  2. I used the Workbench command palette to configure the project for the device, including the specific device ID.

  3. I’m using just a simple blinking LED test code:

#include "Particle.h"

int LED = D7;

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);

// setup() runs once, when the device is first turned on.
void setup() {
  // Put initialization like pinMode and begin functions here.
  pinMode(LED, OUTPUT);    // sets pin as output
}

void loop()
{
  digitalWrite(LED, HIGH); // sets the LED on
  delay(200);              // waits for 200mS
  digitalWrite(LED, LOW);  // sets the LED off
  delay(200);              // waits for 200mS
}

If anyone has any suggestions I would really appreciate it! This seems like it should be very simple but I’ve researched and tried to get it working and now I need to ask the community for help. Thank you in advance!

Dominic

It’s not necessary to set the setup done flag on a Xenon, only an Argon or Boron.

The most common reason for staying in listening mode is that you have a bootloader that needs upgrading. Normally you’d go into safe mode and it would be downloaded from the cloud, but since you’re using the device standalone it will go into listening mode instead of safe mode because there are no credentials set.

If you manually flash the system part, make sure you also flash the matching bootloader on the Xenon in standalone mode.

The same sort of thing could happen if you’ve built your user firmware targeting a newer Device OS version than is on the device.

To find out if there are unmet dependencies, connect the Xenon by USB and while in listening mode:

particle serial inspect

Thank you so very much @rickkas7, I was able to get it working with your help!

Details for future searchers:
I ran particle serial inspect and this was the result:

Platform: 14 - Xenon
Modules
Bootloader module #0 - version 301, main location, 49152 bytes max size
Integrity: PASS
Address Range: PASS
Platform: PASS
Dependencies: PASS
System module #1 - version 1301, main location, 671744 bytes max size
Integrity: PASS
Address Range: PASS
Platform: PASS
Dependencies: FAIL
Bootloader module #0 - version 311
User module #1 - version 6, main location, 131072 bytes max size
UUID: DFD2A9E357C2FF394D2A7F6E63CA5F6A7B0F50F89A59277B1BBEB9C4EB3EFDFB
Integrity: PASS
Address Range: PASS
Platform: PASS
Dependencies: PASS
System module #1 - version 1301

As rickkas7 predicted, this showed a failed dependency, indicating that the Bootloader needed to be updated to version 311, so I ran particle update.

This updated the Bootloader to 311, but downgraded the System from 1301 to 1213. New result of particle serial inspect:

Platform: 14 - Xenon
Modules
Bootloader module #0 - version 311, main location, 49152 bytes max size
Integrity: PASS
Address Range: PASS
Platform: PASS
Dependencies: PASS
System module #1 - version 1213, main location, 671744 bytes max size
Integrity: PASS
Address Range: PASS
Platform: PASS
Dependencies: PASS
Bootloader module #0 - version 311
User module #1 - version 6, main location, 131072 bytes max size
UUID: DFD2A9E357C2FF394D2A7F6E63CA5F6A7B0F50F89A59277B1BBEB9C4EB3EFDFB
Integrity: PASS
Address Range: PASS
Platform: PASS
Dependencies: FAIL
System module #1 - version 1301

It shows that my user code will need System version 1301 (for BLE API support), so then I used Workbench to flash the application and DeviceOS. When the flash process completed the Xenon was running my user firmware finally!!

Thank you again so much rikkas7!

Dominic