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+
4146static 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
4550enum BL_COMMANDS {
4651 BL_COMMAND_ANNOUNCE = 0x05 ,
@@ -56,10 +61,11 @@ uint16_t frame_size = 0;
5661uint32_t incoming_crc32 = 0 ;
5762uint32_t crc32 = 0 ;
5863uint32_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
245276void 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