* USB: enable DFU interface and stub
* nano_nora: add Arduino Nano ESP32 board support
* [pin_remap 1/3] platform: define ARDUINO_CORE_BUILD when building core files
* [pin_remap 2/3] core,libs: add pin remap hooks
* [pin_remap 3/3] nano_nora: implement and enable pin remap
* nano_nora: fix: reset all matrix connections at boot
* nano_nora: add recovery image for release/v2.x
* nano_nora: use official Arduino branding
* nano_nora: core split + recovery mode rework
Use an absolute address in SPIRAM to store the magic tokens, almost at the
end of the memory, to avoid the markers from being overwritten on any kind
of sketch and core combination.
Also, only start the recovery once if a valid binary is present in the
Flash, by immediately setting that for the next boot when recovery
starts.
* platform: fix: use {compiler.sdk.path} for sdk path
In preparation for the sdk -> tool transition
* package_index: remove dfu-util from template
The tool is already available in mainline package_index.json
* on_release: allow single board packages
---------
Co-authored-by: Luca Burelli <l.burelli@arduino.cc>
128 lines
3.6 KiB
C++
128 lines
3.6 KiB
C++
// Enable pin remapping in this file, so pin constants are meaningful
|
|
#undef ARDUINO_CORE_BUILD
|
|
|
|
#include "Arduino.h"
|
|
|
|
#include "double_tap.h"
|
|
|
|
#include <esp_system.h>
|
|
#include <esp_ota_ops.h>
|
|
#include <esp_partition.h>
|
|
|
|
extern "C" {
|
|
void initVariant() {
|
|
// FIXME: fix issues with GPIO matrix not being soft reset properly
|
|
for (int pin = 0; pin<NUM_DIGITAL_PINS; ++pin) {
|
|
switch (pin) {
|
|
case LED_RED:
|
|
case LED_GREEN:
|
|
case LED_BLUE:
|
|
// set RGB pins to dig outputs, HIGH=off
|
|
pinMode(pin, OUTPUT);
|
|
digitalWrite(pin, HIGH);
|
|
break;
|
|
|
|
case TX:
|
|
case RX:
|
|
// leave UART pins alone
|
|
break;
|
|
|
|
default:
|
|
// initialize other pins to dig inputs
|
|
pinMode(pin, INPUT);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// global, accessible from recovery sketch
|
|
bool _recovery_marker_found; // double tap detected
|
|
bool _recovery_active; // running from factory partition
|
|
|
|
#define DELAY_US 10000
|
|
#define FADESTEP 8
|
|
static void rgb_pulse_delay(void)
|
|
{
|
|
// Bv R^ G x
|
|
int widths[4] = { 192, 64, 0, 0 };
|
|
int dec_led = 0;
|
|
|
|
// initialize RGB signals from weak pinstraps
|
|
pinMode(LED_RED, OUTPUT);
|
|
pinMode(LED_GREEN, OUTPUT);
|
|
pinMode(LED_BLUE, OUTPUT);
|
|
while (dec_led < 3) {
|
|
widths[dec_led] -= FADESTEP;
|
|
widths[dec_led+1] += FADESTEP;
|
|
if (widths[dec_led] <= 0) {
|
|
widths[dec_led] = 0;
|
|
dec_led = dec_led+1;
|
|
widths[dec_led] = 255;
|
|
}
|
|
|
|
analogWrite(LED_RED, 255-widths[1]);
|
|
analogWrite(LED_GREEN, 255-widths[2]);
|
|
analogWrite(LED_BLUE, 255-widths[0]);
|
|
delayMicroseconds(DELAY_US);
|
|
}
|
|
|
|
// reset pins to digital HIGH before leaving
|
|
digitalWrite(LED_RED, HIGH);
|
|
digitalWrite(LED_GREEN, HIGH);
|
|
digitalWrite(LED_BLUE, HIGH);
|
|
pinMode(LED_RED, OUTPUT);
|
|
pinMode(LED_GREEN, OUTPUT);
|
|
pinMode(LED_BLUE, OUTPUT);
|
|
}
|
|
|
|
static void NANO_ESP32_enter_bootloader(void)
|
|
{
|
|
if (!_recovery_active) {
|
|
// check for valid partition scheme
|
|
const esp_partition_t *ota_part = esp_ota_get_next_update_partition(NULL);
|
|
const esp_partition_t *fact_part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
|
if (ota_part && fact_part) {
|
|
// set tokens so the recovery FW will find them
|
|
double_tap_mark();
|
|
// invalidate other OTA image
|
|
esp_partition_erase_range(ota_part, 0, 4096);
|
|
// activate factory partition
|
|
esp_ota_set_boot_partition(fact_part);
|
|
}
|
|
}
|
|
|
|
esp_restart();
|
|
}
|
|
|
|
static void boot_double_tap_logic()
|
|
{
|
|
const esp_partition_t *part = esp_ota_get_running_partition();
|
|
_recovery_active = (part->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY);
|
|
|
|
double_tap_init();
|
|
|
|
_recovery_marker_found = double_tap_check_match();
|
|
if (_recovery_marker_found && !_recovery_active) {
|
|
// double tap detected in user application, reboot to factory
|
|
NANO_ESP32_enter_bootloader();
|
|
}
|
|
|
|
// delay with mark set then proceed
|
|
// - for normal startup, to detect first double tap
|
|
// - in recovery mode, to ignore several short presses
|
|
double_tap_mark();
|
|
rgb_pulse_delay();
|
|
double_tap_invalidate();
|
|
}
|
|
|
|
namespace {
|
|
class DoubleTap {
|
|
public:
|
|
DoubleTap() {
|
|
boot_double_tap_logic();
|
|
}
|
|
};
|
|
|
|
DoubleTap dt __attribute__ ((init_priority (101)));
|
|
}
|