forked from espressif/arduino-esp32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvariant.cpp
101 lines (84 loc) · 2.64 KB
/
variant.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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() {
// nothing to do
}
}
// 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);
}
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)));
} // namespace