30 #define SAME5_PAGES_PER_BLOCK 16
31 #define SAME5_NUM_PROT_BLOCKS 32
32 #define SAMD_PAGE_SIZE_MAX 1024
34 #define SAMD_FLASH 0x00000000
35 #define SAMD_USER_ROW 0x00804000
37 #define SAME5_PAC 0x40000000
39 #define SAMD_DSU 0x41002000
40 #define SAMD_NVMCTRL 0x41004000
42 #define SAMD_DSU_STATUSA 1
43 #define SAMD_DSU_DID 0x18
44 #define SAMD_DSU_CTRL_EXT 0x100
46 #define SAME5_NVMCTRL_CTRLA 0x00
47 #define SAME5_NVMCTRL_CTRLB 0x04
48 #define SAMD_NVMCTRL_PARAM 0x08
49 #define SAME5_NVMCTRL_INTFLAG 0x10
50 #define SAME5_NVMCTRL_STATUS 0x12
51 #define SAME5_NVMCTRL_ADDR 0x14
52 #define SAME5_NVMCTRL_LOCK 0x18
54 #define SAMD_CMDEX_KEY 0xA5UL
55 #define SAMD_NVM_CMD(n) ((SAMD_CMDEX_KEY << 8) | (n & 0x7F))
58 #define SAME5_NVM_CMD_EP 0x00
59 #define SAME5_NVM_CMD_EB 0x01
60 #define SAME5_NVM_CMD_WP 0x03
61 #define SAME5_NVM_CMD_WQW 0x04
62 #define SAME5_NVM_CMD_LR 0x11
63 #define SAME5_NVM_CMD_UR 0x12
64 #define SAME5_NVM_CMD_PBC 0x15
65 #define SAME5_NVM_CMD_SSB 0x16
68 #define SAME5_NVMCTRL_CTRLA_WMODE_MASK 0x30
70 #define SAME5_NVMCTRL_INTFLAG_DONE (1 << 0)
71 #define SAME5_NVMCTRL_INTFLAG_ADDRE (1 << 1)
72 #define SAME5_NVMCTRL_INTFLAG_PROGE (1 << 2)
73 #define SAME5_NVMCTRL_INTFLAG_LOCKE (1 << 3)
74 #define SAME5_NVMCTRL_INTFLAG_ECCSE (1 << 4)
75 #define SAME5_NVMCTRL_INTFLAG_ECCDE (1 << 5)
76 #define SAME5_NVMCTRL_INTFLAG_NVME (1 << 6)
80 #define SAMD_PROCESSOR_M0 0x01
81 #define SAMD_PROCESSOR_M4 0x06
82 #define SAMD_FAMILY_D 0x00
83 #define SAMD_FAMILY_E 0x03
84 #define SAMD_SERIES_51 0x06
85 #define SAME_SERIES_51 0x01
86 #define SAME_SERIES_53 0x03
87 #define SAME_SERIES_54 0x04
90 #define SAMD_GET_PROCESSOR(id) (id >> 28)
91 #define SAMD_GET_FAMILY(id) (((id >> 23) & 0x1F))
92 #define SAMD_GET_SERIES(id) (((id >> 16) & 0x3F))
93 #define SAMD_GET_DEVSEL(id) (id & 0xFF)
96 #define NVMUSERROW_SAM_E5_D5_MASK ((uint64_t)0x7FFF00FF3C007FFF)
109 { 0x00,
"SAMD51P20A", 1024, 256 },
110 { 0x01,
"SAMD51P19A", 512, 192 },
111 { 0x02,
"SAMD51N20A", 1024, 256 },
112 { 0x03,
"SAMD51N19A", 512, 192 },
113 { 0x04,
"SAMD51J20A", 1024, 256 },
114 { 0x05,
"SAMD51J19A", 512, 192 },
115 { 0x06,
"SAMD51J18A", 256, 128 },
116 { 0x07,
"SAMD51G19A", 512, 192 },
117 { 0x08,
"SAMD51G18A", 256, 128 },
122 { 0x00,
"SAME51N20A", 1024, 256 },
123 { 0x01,
"SAME51N19A", 512, 192 },
124 { 0x02,
"SAME51J19A", 512, 192 },
125 { 0x03,
"SAME51J18A", 256, 128 },
126 { 0x04,
"SAME51J20A", 1024, 256 },
127 { 0x05,
"SAME51G19A", 512, 192 },
128 { 0x06,
"SAME51G18A", 256, 128 },
133 { 0x02,
"SAME53N20A", 1024, 256 },
134 { 0x03,
"SAME53N19A", 512, 192 },
135 { 0x04,
"SAME53J20A", 1024, 256 },
136 { 0x05,
"SAME53J19A", 512, 192 },
137 { 0x06,
"SAME53J18A", 256, 128 },
138 { 0x55,
"LAN9255/ZMX020", 1024, 256 },
139 { 0x56,
"LAN9255/ZMX019", 512, 192 },
140 { 0x57,
"LAN9255/ZMX018", 256, 128 },
145 { 0x00,
"SAME54P20A", 1024, 256 },
146 { 0x01,
"SAME54P19A", 512, 192 },
147 { 0x02,
"SAME54N20A", 1024, 256 },
148 { 0x03,
"SAME54N19A", 512, 192 },
175 const struct samd_params *
par;
219 for (
unsigned i = 0; i <
family->num_parts; i++) {
220 if (
family->parts[i].id == devsel)
238 for (
unsigned int prot_block = 0; prot_block <
bank->num_prot_blocks; prot_block++)
239 bank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));
245 uint32_t *sizep,
int *nump)
255 *sizep = (8 << ((
param >> 16) & 0x7));
258 *nump =
param & 0xFFFF;
260 LOG_ERROR(
"Couldn't read NVM Parameters register");
278 LOG_ERROR(
"Couldn't read Device ID register");
284 LOG_ERROR(
"Couldn't find part corresponding to DID %08" PRIx32,
id);
288 bank->size = part->flash_kb * 1024;
293 LOG_ERROR(
"Couldn't determine Flash page size");
300 LOG_WARNING(
"SAM: bank size doesn't match NVM parameters. "
301 "Identified %" PRIu32
"KB Flash but NVMCTRL reports %u %" PRIu32
"B pages",
320 if (!
bank->prot_blocks)
328 LOG_INFO(
"SAM MCU: %s (%" PRIu32
"KB Flash, %" PRIu32
"KB RAM)", part->name,
329 part->flash_kb, part->ram_kb);
340 int timeout_ms = 200 * 5;
348 LOG_ERROR(
"SAM: error reading the NVMCTRL_INTFLAG register");
354 }
while (
timeval_ms() - ts_start < timeout_ms);
357 LOG_ERROR(
"SAM: NVM programming timed out");
393 LOG_ERROR(
"Can't clear NVM error conditions");
438 LOG_ERROR(
"Failed to erase block containing %08" PRIx32, address);
462 LOG_ERROR(
"The flash controller must be in manual write mode. Issue 'reset init' and retry.");
483 const uint8_t *data,
const uint8_t *
mask,
492 LOG_ERROR(
"Couldn't determine Flash page size");
509 for (i = 0; i <
count; i++) {
510 uint8_t old_b = buf[
offset+i];
511 uint8_t new_b = (old_b & ~
mask[i]) | (data[i] &
mask[i]);
554 uint8_t startb, uint8_t endb)
556 uint8_t buf_val[8] = { 0 };
557 uint8_t buf_mask[8] = { 0 };
559 assert(startb <= endb && endb < 64);
560 buf_set_u32(buf_val, startb, endb + 1 - startb, value);
561 buf_set_u32(buf_mask, startb, endb + 1 - startb, 0xffffffff);
564 buf_val, buf_mask, 0, 8);
580 for (
unsigned int prot_block = first; prot_block <= last; prot_block++) {
581 if (set !=
bank->prot_blocks[prot_block].is_protected) {
585 bank->prot_blocks[prot_block].offset);
600 const uint8_t lock[4] = { 0, 0, 0, 0 };
601 const uint8_t unlock[4] = { 0xff, 0xff, 0xff, 0xff };
602 uint8_t
mask[4] = { 0, 0, 0, 0 };
607 set ? lock : unlock,
mask, 8, 4);
609 LOG_WARNING(
"SAM: protect settings were not made persistent!");
635 for (
unsigned int s = first; s <= last; s++) {
638 LOG_ERROR(
"SAM: failed to erase sector %d at 0x%08" PRIx32, s,
bank->sectors[s].offset);
689 memcpy(pb + pg_offset,
buffer, nb);
694 assert(pg_offset % 4 == 0);
697 nw = (nb +
offset % 4 + 3) / 4;
698 assert(pg_offset + 4 * nw <= chip->
page_size);
706 assert(pg_offset + 4 * nw <= chip->
page_size);
718 LOG_ERROR(
"%s: write failed at address 0x%08" PRIx32, __func__, address);
743 chip = calloc(1,
sizeof(*chip));
745 LOG_ERROR(
"No memory for flash bank chip info");
752 bank->driver_priv = chip;
802 uint8_t val_buf[8], mask_buf[8];
807 val_buf, mask_buf, 0,
sizeof(val_buf));
816 LOG_ERROR(
"USER PAGE could not be read.");
837 uint32_t code = (
size + 8191) / 8192;
840 "see datasheet for a list valid sizes.");
850 uint32_t code = (val >> 26) & 0xf;
851 uint32_t
size = (15 - code) * 8192;
853 PRIu32
" bytes",
size);
902 .
name =
"dsu_reset_deassert",
904 .handler = samd_handle_reset_deassert,
906 .help =
"Deassert internal reset held by DSU."
909 .name =
"chip-erase",
911 .handler = same5_handle_chip_erase_command,
913 .help =
"Erase the entire Flash by using the Chip-"
914 "Erase feature in the Device Service Unit (DSU).",
917 .name =
"bootloader",
918 .usage =
"[size_in_bytes]",
919 .handler = same5_handle_bootloader_command,
921 .help =
"Show or set the bootloader protection size, stored in the User Row. "
922 "Changes are stored immediately but take affect after the MCU is "
927 .usage =
"[value] [mask]",
928 .handler = same5_handle_userpage_command,
930 .help =
"Show or set the first 64-bit part of user page "
931 "located at address 0x804000. Use the optional mask argument "
932 "to prevent changes at positions where the bitvalue is zero. "
933 "For security reasons the reserved-bits are masked out "
934 "in background and therefore cannot be changed.",
943 .help =
"atsame5 flash command group",
953 .flash_bank_command = same5_flash_bank_command,
static struct aice_port_param_s param
COMMAND_HANDLER(same5_handle_chip_erase_command)
static int same5_wait_and_check_error(struct target *target)
#define SAMD_GET_SERIES(id)
static const struct samd_part same51_parts[]
#define SAME5_NUM_PROT_BLOCKS
static int same5_pre_write_check(struct target *target)
#define SAMD_PROCESSOR_M4
static int same5_issue_nvmctrl_command(struct target *target, uint16_t cmd)
#define SAME5_NVMCTRL_INTFLAG_ADDRE
static int samd_get_flash_page_info(struct target *target, uint32_t *sizep, int *nump)
static const struct samd_family * samd_find_family(uint32_t id)
Gives the family structure to specific device id.
#define SAME5_NVMCTRL_ADDR
static int same5_protect_check(struct flash_bank *bank)
#define SAMD_GET_DEVSEL(id)
#define SAMD_GET_FAMILY(id)
#define SAME5_PAGES_PER_BLOCK
#define SAME5_NVMCTRL_LOCK
static int same5_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
#define NVMUSERROW_SAM_E5_D5_MASK
static int same5_modify_user_row_masked(struct target *target, const uint8_t *data, const uint8_t *mask, uint32_t offset, uint32_t count)
Modify the contents of the User Row in Flash.
#define SAMD_GET_PROCESSOR(id)
static const struct samd_part same53_parts[]
static int same5_probe(struct flash_bank *bank)
static int same5_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
#define SAMD_DSU_CTRL_EXT
#define SAMD_NVMCTRL_PARAM
#define SAME5_NVM_CMD_PBC
#define SAME5_NVMCTRL_INTFLAG_ECCSE
#define SAMD_PAGE_SIZE_MAX
#define SAME5_NVMCTRL_INTFLAG_LOCKE
#define SAME5_NVMCTRL_INTFLAG_PROGE
FLASH_BANK_COMMAND_HANDLER(same5_flash_bank_command)
static const struct command_registration same5_command_handlers[]
#define SAME5_NVM_CMD_WQW
static const struct samd_part same54_parts[]
#define SAME5_NVMCTRL_CTRLA
const struct flash_driver atsame5_flash
#define SAME5_NVMCTRL_INTFLAG
#define SAME5_NVMCTRL_INTFLAG_ECCDE
static const struct samd_part * samd_find_part(uint32_t id)
Gives the part structure to specific device id.
static const struct samd_family samd_families[]
static const struct samd_part samd51_parts[]
static const struct command_registration same5_exec_command_handlers[]
#define SAME5_NVMCTRL_INTFLAG_DONE
static int same5_modify_user_row(struct target *target, uint32_t value, uint8_t startb, uint8_t endb)
Modifies the user row register to the given value.
#define SAME5_NVMCTRL_CTRLB
static int same5_erase_block(struct target *target, uint32_t address)
Erases a flash block or page at the given address.
static int same5_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
#define SAME5_NVMCTRL_CTRLA_WMODE_MASK
#define SAME5_NVMCTRL_INTFLAG_NVME
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_FLASH_OPER_UNSUPPORTED
#define ERROR_FLASH_PROTECTED
#define ERROR_FLASH_BANK_NOT_PROBED
#define ERROR_FLASH_OPERATION_FAILED
struct flash_sector * alloc_block_array(uint32_t offset, uint32_t size, unsigned int num_blocks)
Allocate and fill an array of sectors or protection blocks.
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
static enum reset_types jtag_reset_config
enum reset_types jtag_get_reset_config(void)
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
bool changed
Whether configuration changed.
size_t size
Size of the control block search area.
char id[RTT_CB_MAX_ID_LENGTH]
Control block identifier.
Provides details of a flash bank, available either on-chip or through a major interface.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
const struct samd_part * parts
const struct samd_params * par
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)
int target_write_u8(struct target *target, target_addr_t address, uint8_t value)
int target_write_u16(struct target *target, target_addr_t address, uint16_t value)
int target_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Write count items of size bytes to the memory of target at the address given.
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_examine_one(struct target *target)
Examine the specified target, letting it perform any Initialisation that requires JTAG access.
int target_poll(struct target *target)
int target_read_u16(struct target *target, target_addr_t address, uint16_t *value)
void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value)
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
struct target * get_current_target(struct command_context *cmd_ctx)
#define ERROR_TARGET_NOT_HALTED
static bool target_was_examined(struct target *target)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.