Skip to content

Commit 89fff7d

Browse files
committed
Refactor the updaters back into one sketch
1 parent a4a984d commit 89fff7d

File tree

6 files changed

+216
-301
lines changed

6 files changed

+216
-301
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* This sketch allows to support Soft Devices on Nano 33 BLE.
3+
*
4+
* To be able to support Soft Devices, the bootloader first needs to be updated.
5+
* Upload this sketch on the Nano 33 BLE to download the new bootloader in the flash.
6+
* After flashing the bootloader the sketch asks if you want to upload a SoftDevice.
7+
* This is required for the OpenMV firmware to work.
8+
*
9+
* The new bootloader is fully backwards compatible with standard sketches.
10+
*
11+
*/
12+
13+
#include "FlashIAP.h"
14+
#include "MBR.h"
15+
#include "bootloader.h"
16+
#include "nrf_nvmc.h"
17+
#include "SoftDevice.h"
18+
19+
#define SOFTDEVICE_ADDR (0xA0000)
20+
#define SOFTDEVICE_INFO_ADDR (0xFF000)
21+
#define MBR_ADDR (0x0)
22+
#define BOOTLOADER_ADDR (0xE0000)
23+
#define UICR_BOOT_ADDR (0x10001014)
24+
25+
#define BOOTLOADER_CRC 0x5E797B91
26+
#define BOOTLOADER_SIZE nano33_bootloader_hex_len
27+
const unsigned int magic = 0x5f27a93d;
28+
29+
mbed::FlashIAP flash;
30+
31+
bool hasLatestBootloader(){
32+
//Compute bootloader CRC32
33+
uint32_t crc32 = getCurrentBootloaderCrc();
34+
return crc32 == BOOTLOADER_CRC;
35+
}
36+
37+
bool getUserConfirmation(){
38+
while (true){
39+
if (Serial.available()){
40+
char choice = Serial.read();
41+
switch (choice){
42+
case 'y':
43+
case 'Y':
44+
return true;
45+
case 'n':
46+
case 'N':
47+
return false;
48+
default:
49+
continue;
50+
}
51+
}
52+
}
53+
}
54+
55+
void applyUpdate(uint32_t address, const unsigned char payload[], long len, uint32_t bin_pointer = 0) {
56+
uint32_t flash_pointer = 0;
57+
const uint32_t page_size = flash.get_page_size();
58+
char *page_buffer = new char[page_size];
59+
uint32_t addr = address;
60+
61+
uint32_t sector_size = flash.get_sector_size(addr);
62+
uint32_t next_sector = addr + sector_size;
63+
bool sector_erased = false;
64+
size_t pages_flashed = 0;
65+
uint32_t percent_done = 0;
66+
67+
while (true) {
68+
69+
if (flash_pointer >= len) {
70+
break;
71+
}
72+
73+
flash.erase(addr + flash_pointer, sector_size);
74+
75+
if ((len - flash_pointer) < sector_size) {
76+
sector_size = len - flash_pointer;
77+
}
78+
79+
// Program page
80+
flash.program(&payload[bin_pointer], addr + flash_pointer, sector_size);
81+
Serial.print("Flash Address = ");
82+
Serial.println(addr + flash_pointer, HEX);
83+
84+
bin_pointer = bin_pointer + sector_size;
85+
flash_pointer = flash_pointer + sector_size;
86+
87+
uint32_t percent_done = flash_pointer * 100 / len;
88+
Serial.println("Flashed " + String(percent_done) + "%");
89+
}
90+
Serial.println();
91+
92+
delete[] page_buffer;
93+
}
94+
95+
void updateBootloader(){
96+
Serial.println("This sketch modifies the Nano33 bootloader to support Soft Devices.");
97+
Serial.println();
98+
99+
flash.init();
100+
101+
Serial.println("Flasing MBR...");
102+
applyUpdate(MBR_ADDR, MBR_bin, MBR_bin_len);
103+
104+
Serial.println("Flasing bootloader...");
105+
applyUpdate(BOOTLOADER_ADDR, nano33_bootloader_hex, nano33_bootloader_hex_len);
106+
107+
Serial.print("Bootloader 32bit CRC is: ");
108+
uint32_t crc32 = getTargetBootloaderCrc();
109+
Serial.println(crc32, HEX);
110+
111+
Serial.println("Writing in UICR memory the address of the new bootloader...");
112+
nrf_nvmc_write_word(UICR_BOOT_ADDR, BOOTLOADER_ADDR);
113+
114+
flash.deinit();
115+
116+
Serial.println();
117+
Serial.println("Bootloader update successfully completed!");
118+
}
119+
120+
void updateSoftDevice(){
121+
flash.init();
122+
123+
Serial.println("Correct booloader found!");
124+
Serial.println();
125+
126+
Serial.println("Storing SoftDevice length info at 0xFF000...");
127+
writeSoftDeviceLen(SOFTDEVICE_INFO_ADDR);
128+
129+
Serial.println("Flasing SoftDevice...");
130+
applyUpdate(SOFTDEVICE_ADDR, Softdevice_bin, Softdevice_bin_len - 4096, 4096);
131+
132+
flash.deinit();
133+
134+
Serial.println();
135+
Serial.println("SoftDevice update complete! The board is restarting...");
136+
NVIC_SystemReset();
137+
}
138+
139+
void setup() {
140+
Serial.begin(115200);
141+
while (!Serial) {}
142+
143+
if(!hasLatestBootloader()){
144+
Serial.println("Your bootloader version is outdated (update required for Soft Device support).");
145+
Serial.println("Would you like to update it? Y/N");
146+
147+
if(getUserConfirmation()){
148+
updateBootloader();
149+
}
150+
}
151+
152+
if(hasLatestBootloader()){
153+
Serial.println("Would you like to install the Soft Device (required for OpenMV)? Y/N");
154+
if(getUserConfirmation()){
155+
updateSoftDevice();
156+
}
157+
}
158+
}
159+
160+
uint32_t getTargetBootloaderCrc() {
161+
uint32_t mask = 0;
162+
uint32_t crc = 0xFFFFFFFF;
163+
uint32_t b = 0;
164+
uint8_t bootByte = 0;
165+
166+
int iterations = BOOTLOADER_SIZE;
167+
168+
for (int i=0; i<iterations; i=i+4) {
169+
b = 0;
170+
for (int j=0; j<4; j++) {
171+
mask = 0;
172+
bootByte = nano33_bootloader_hex[i+j];
173+
mask = mask + (uint32_t)bootByte;
174+
mask = mask << 8*j;
175+
b = b | mask;
176+
}
177+
crc = crc ^ b;
178+
}
179+
return crc;
180+
}
181+
182+
uint32_t getCurrentBootloaderCrc() {
183+
uint32_t b = 0;
184+
uint32_t crc = 0xFFFFFFFF;
185+
186+
int iterations = ceil(BOOTLOADER_SIZE/4);
187+
188+
int addr = BOOTLOADER_ADDR;
189+
190+
for (int i=0; i<iterations; i++) {
191+
//Read 32 bit from flash
192+
flash.read(&b, addr, sizeof(b));
193+
//Serial.println(b, HEX);
194+
//Update crc
195+
crc = crc ^ b;
196+
//Update pointer
197+
addr = addr + 4;
198+
}
199+
return crc;
200+
}
201+
202+
void writeSoftDeviceLen(uint32_t address) {
203+
uint32_t sd_addr = SOFTDEVICE_ADDR;
204+
flash.erase(address, 16);
205+
//Write flag to let Bootloader understand that SoftDevice binary must be moved
206+
flash.program(&magic, address, 4);
207+
//Write address where the SoftDevice binary has been written
208+
flash.program(&sd_addr, address + 4, 4);
209+
//Write SoftDevice binary length
210+
unsigned int sd_len = Softdevice_bin_len - 4096;
211+
flash.program(&sd_len, address + 8, 4);
212+
}
213+
214+
void loop() {
215+
delay(1000);
216+
}

libraries/Nano33_System/examples/Nano33_updateBootloader/Nano33_updateBootloader.ino

-137
This file was deleted.

0 commit comments

Comments
 (0)