Skip to content

Commit 93d4fb2

Browse files
author
Nathan Seidle
committed
Changed bootloader from mass erase to page erase.
1 parent 8c7610f commit 93d4fb2

File tree

1 file changed

+71
-38
lines changed

1 file changed

+71
-38
lines changed
Lines changed: 71 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,22 @@
3030
-------
3131
3232
The factory secure bootloader (SBL) lives at 0x00 to 0xC000.
33-
The SparkFun Artemis bootloader begins at 0xC000 and takes ~20k bytes
34-
We load user code starting at 0xC000 + 0x8000 (32768) = 0x14000
35-
If our bootloader times out, we jump to 0x14000 to begin running user code
33+
The SparkFun Artemis bootloader begins at 0xC000 and takes ~7300 bytes (with debug statements it's ~10k)
34+
We load user code starting at 0xC000 + 8192 = 0xE000
35+
If our bootloader completes or times out, we jump to 0xE000+4 to begin running user code
3636
3737
TODO:
3838
Protect bootloader section in flash
39+
Combine Ambiq SBL with SparkFun BL
40+
Upload combined over JTAG
41+
Adjust Arduino linker script for all varients
42+
Adjust Arduino tools to artemis uart loader
3943
Make sure all RAM is released
4044
*/
45+
4146
static uint32_t ui32Source[512];
4247

43-
#define MAX_WAIT_IN_MS 100 //Millisecond wait before bootload timeout and begin user code
48+
#define MAX_WAIT_IN_MS 50 //Millisecond wait before bootload timeout and begin user code
4449

4550
enum BL_COMMANDS {
4651
BL_COMMAND_ANNOUNCE = 0x05,
@@ -56,10 +61,11 @@ uint16_t frame_size = 0;
5661
uint32_t incoming_crc32 = 0;
5762
uint32_t crc32 = 0;
5863
uint32_t frame_address = 0;
64+
uint16_t last_page_erased = 0;
5965

6066
// Location in flash to begin storing user's code
61-
//#define USERCODE_OFFSET 0x14000
62-
#define USERCODE_OFFSET 0x80000 // Should be start of flash instance 1
67+
// Linker script needs to be adjusted to offset user's flash to this address
68+
#define USERCODE_OFFSET 0xC000 + 0x4000
6369

6470
//Comment out this line to turn off debug statements on Serial1
6571
#define DEBUG 1
@@ -74,6 +80,7 @@ void setup() {
7480
Serial1.println("Debug");
7581
#endif
7682

83+
delay(3); //Necessary to separate a blip on TX line when port opens from annouce command
7784
Serial.write(BL_COMMAND_ANNOUNCE); //Tell the world we can be bootloaded
7885

7986
//Check to see if the computer responded
@@ -82,34 +89,27 @@ void setup() {
8289
{
8390
if (count++ > MAX_WAIT_IN_MS)
8491
{
92+
#ifdef DEBUG
93+
Serial1.println("No reponse from computer");
94+
#endif
8595
app_start();
8696
}
8797
delay(1);
8898
}
89-
if (Serial.read() != BL_COMMAND_AOK) app_start(); //If the computer did not respond correctly with a AOK, we jump to user's program
99+
if (Serial.read() != BL_COMMAND_AOK)
100+
{
101+
#ifdef DEBUG
102+
Serial1.println("Invalid response from computer");
103+
#endif
104+
app_start(); //If the computer did not respond correctly with a AOK, we jump to user's program
105+
}
90106

91107
//Now get upload baud rate from caller
92108
uint32_t uploadRate = get4Bytes();
93109

94110
Serial.flush();
95111
Serial.begin(uploadRate); //Go to new baud rate
96112

97-
//We need to give the computer some time to switch baud rates
98-
//Let's erase the flash while we wait
99-
100-
#ifdef DEBUG
101-
Serial1.printf("Erasing all of flash instance %d.\n\r", AM_HAL_FLASH_ADDR2INST(USERCODE_OFFSET));
102-
#endif
103-
104-
int32_t i32ReturnCode = am_hal_flash_mass_erase(AM_HAL_FLASH_PROGRAM_KEY, AM_HAL_FLASH_ADDR2INST(USERCODE_OFFSET));
105-
106-
#ifdef DEBUG
107-
if (i32ReturnCode)
108-
{
109-
Serial1.printf("FLASH_MASS_ERASE i32ReturnCode = 0x%x.\n\r", i32ReturnCode);
110-
}
111-
#endif
112-
113113
delay(10); //Give the computer some time to switch baud rates
114114

115115
#ifdef DEBUG
@@ -150,6 +150,9 @@ RESTART:
150150

151151
if (frame_size == BL_COMMAND_ALL_DONE) //Check to see if we are done
152152
{
153+
#ifdef DEBUG
154+
Serial1.println("Done!");
155+
#endif
153156
am_hal_reset_control(AM_HAL_RESET_CONTROL_SWPOI, 0); //Cause a system Power On Init to release as much of the stack as possible
154157
}
155158

@@ -183,13 +186,41 @@ RESTART:
183186
if (incoming_crc32 == crc32)
184187
{
185188
#ifdef DEBUG
186-
Serial1.println("CRC good. Record array");
189+
Serial1.println("CRC good.");
190+
#endif
191+
192+
int32_t i32ReturnCode = 0;
193+
194+
//Frames coming from the computer are 2k bytes, but we erase 8k bytes in a page
195+
//Only erase a page if we haven't erased it before
196+
if (last_page_erased < AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET))
197+
{
198+
#ifdef DEBUG
199+
Serial1.printf("Erasing instance %d, page %d\n\r", AM_HAL_FLASH_ADDR2INST(frame_address + USERCODE_OFFSET), AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET));
200+
#endif
201+
202+
//Erase the 8k page for this address
203+
i32ReturnCode = am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY,
204+
AM_HAL_FLASH_ADDR2INST(frame_address + USERCODE_OFFSET),
205+
AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET) );
206+
last_page_erased = AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET);
207+
}
208+
209+
#ifdef DEBUG
210+
if (i32ReturnCode)
211+
{
212+
Serial1.printf("FLASH_MASS_ERASE i32ReturnCode = 0x%x.\n\r", i32ReturnCode);
213+
}
187214
#endif
188-
int32_t i32ReturnCode = program_array(frame_address + USERCODE_OFFSET);
215+
216+
//Record the array
217+
i32ReturnCode = program_array(frame_address + USERCODE_OFFSET);
189218

190219
#ifdef DEBUG
191220
if (i32ReturnCode)
192-
Serial1.printf("FLASH_WRITE error = 0x%x.\n", i32ReturnCode);
221+
Serial1.printf("FLASH_WRITE error = 0x%x.\n\r", i32ReturnCode);
222+
else
223+
Serial1.println("Array recorded to flash");
193224
#endif
194225
}
195226
else
@@ -244,19 +275,21 @@ uint32_t get4BytesReversed(void)
244275

245276
void app_start()
246277
{
278+
#ifdef DEBUG
247279
// Print a section of flash
248-
// uint32_t start_address = USERCODE_OFFSET;
249-
// Serial1.printf("Printing page starting at offset 0x%04X", start_address);
250-
// for (uint16_t x = 0; x < 512; x++)
251-
// {
252-
// if (x % 8 == 0)
253-
// {
254-
// Serial1.println();
255-
// Serial1.printf("Adr: 0x%04X", start_address + (x * 4));
256-
// }
257-
// Serial1.printf(" 0x%08X", *(uint32_t *)(start_address + (x * 4)));
258-
// }
259-
// Serial1.println();
280+
uint32_t start_address = USERCODE_OFFSET;
281+
Serial1.printf("Printing page starting at offset 0x%04X", start_address);
282+
for (uint16_t x = 0; x < 512; x++)
283+
{
284+
if (x % 8 == 0)
285+
{
286+
Serial1.println();
287+
Serial1.printf("Adr: 0x%04X", start_address + (x * 4));
288+
}
289+
Serial1.printf(" 0x%08X", *(uint32_t *)(start_address + (x * 4)));
290+
}
291+
Serial1.println();
292+
#endif
260293

261294
uint32_t entryPoint = *(uint32_t *)(USERCODE_OFFSET + 4);
262295

0 commit comments

Comments
 (0)