36
36
#include "cdc_enumerate.h"
37
37
38
38
const char RomBOOT_Version [] = SAM_BA_VERSION ;
39
+ const char RomBOOT_ExtendedCapabilities [] = "[Arduino:X]" ;
39
40
40
41
/* Provides one common interface to handle both USART and USB-CDC */
41
42
typedef struct
@@ -166,12 +167,18 @@ uint8_t command, *ptr_data, *ptr, data[SIZEBUFMAX];
166
167
uint8_t j ;
167
168
uint32_t u32tmp ;
168
169
170
+ uint32_t PAGE_SIZE , PAGES , MAX_FLASH ;
169
171
170
172
/**
171
173
* \brief This function starts the SAM-BA monitor.
172
174
*/
173
175
void sam_ba_monitor_run (void )
174
176
{
177
+ uint32_t pageSizes [] = { 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 };
178
+ PAGE_SIZE = pageSizes [NVMCTRL -> PARAM .bit .PSZ ];
179
+ PAGES = NVMCTRL -> PARAM .bit .NVMP ;
180
+ MAX_FLASH = PAGE_SIZE * PAGES ;
181
+
175
182
ptr_data = NULL ;
176
183
command = 'z' ;
177
184
while (1 ) {
@@ -277,6 +284,9 @@ void sam_ba_monitor_loop(void)
277
284
ptr_monitor_if -> putdata ((uint8_t * ) RomBOOT_Version ,
278
285
strlen (RomBOOT_Version ));
279
286
ptr_monitor_if -> putdata (" " , 1 );
287
+ ptr_monitor_if -> putdata ((uint8_t * ) RomBOOT_ExtendedCapabilities ,
288
+ strlen (RomBOOT_ExtendedCapabilities ));
289
+ ptr_monitor_if -> putdata (" " , 1 );
280
290
ptr = (uint8_t * ) & (__DATE__ );
281
291
i = 0 ;
282
292
while (* ptr ++ != '\0' )
@@ -290,6 +300,29 @@ void sam_ba_monitor_loop(void)
290
300
ptr_monitor_if -> putdata ((uint8_t * ) & (__TIME__ ), i );
291
301
ptr_monitor_if -> putdata ("\n\r" , 2 );
292
302
}
303
+ else if (command == 'X' )
304
+ {
305
+ // Syntax: X[ADDR]#
306
+ // Erase the flash memory starting from ADDR to the end of flash.
307
+
308
+ // Note: the flash memory is erased in ROWS, that is in block of 4 pages.
309
+ // Even if the starting address is the last byte of a ROW the entire
310
+ // ROW is erased anyway.
311
+
312
+ uint32_t dst_addr = current_number ; // starting address
313
+
314
+ while (dst_addr < MAX_FLASH ) {
315
+ // Execute "ER" Erase Row
316
+ NVMCTRL -> ADDR .reg = dst_addr / 2 ;
317
+ NVMCTRL -> CTRLA .reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER ;
318
+ while (NVMCTRL -> INTFLAG .bit .READY == 0 )
319
+ ;
320
+ dst_addr += PAGE_SIZE * 4 ; // Skip a ROW
321
+ }
322
+
323
+ // Notify command completed
324
+ ptr_monitor_if -> putdata ("X\n\r" , 3 );
325
+ }
293
326
294
327
command = 'z' ;
295
328
current_number = 0 ;
0 commit comments