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
88 #define PIC32CXSG_SERIES_41 0x07
89 #define PIC32CXSG_SERIES_60 0x00
90 #define PIC32CXSG_SERIES_61 0x02
93 #define SAMD_GET_PROCESSOR(id) (id >> 28)
94 #define SAMD_GET_FAMILY(id) (((id >> 23) & 0x1F))
95 #define SAMD_GET_SERIES(id) (((id >> 16) & 0x3F))
96 #define SAMD_GET_DEVSEL(id) (id & 0xFF)
99 #define NVMUSERROW_SAM_E5_D5_MASK 0x7FFF00FF3C007FFFULL
112 { 0x00,
"SAMD51P20A", 1024, 256 },
113 { 0x01,
"SAMD51P19A", 512, 192 },
114 { 0x02,
"SAMD51N20A", 1024, 256 },
115 { 0x03,
"SAMD51N19A", 512, 192 },
116 { 0x04,
"SAMD51J20A", 1024, 256 },
117 { 0x05,
"SAMD51J19A", 512, 192 },
118 { 0x06,
"SAMD51J18A", 256, 128 },
119 { 0x07,
"SAMD51G19A", 512, 192 },
120 { 0x08,
"SAMD51G18A", 256, 128 },
125 { 0x00,
"SAME51N20A", 1024, 256 },
126 { 0x01,
"SAME51N19A", 512, 192 },
127 { 0x02,
"SAME51J19A", 512, 192 },
128 { 0x03,
"SAME51J18A", 256, 128 },
129 { 0x04,
"SAME51J20A", 1024, 256 },
130 { 0x05,
"SAME51G19A", 512, 192 },
131 { 0x06,
"SAME51G18A", 256, 128 },
136 { 0x02,
"SAME53N20A", 1024, 256 },
137 { 0x03,
"SAME53N19A", 512, 192 },
138 { 0x04,
"SAME53J20A", 1024, 256 },
139 { 0x05,
"SAME53J19A", 512, 192 },
140 { 0x06,
"SAME53J18A", 256, 128 },
141 { 0x55,
"LAN9255/ZMX020", 1024, 256 },
142 { 0x56,
"LAN9255/ZMX019", 512, 192 },
143 { 0x57,
"LAN9255/ZMX018", 256, 128 },
148 { 0x00,
"SAME54P20A", 1024, 256 },
149 { 0x01,
"SAME54P19A", 512, 192 },
150 { 0x02,
"SAME54N20A", 1024, 256 },
151 { 0x03,
"SAME54N19A", 512, 192 },
158 { 0x00,
"PIC32CX1025SG41128", 1024, 256 },
159 { 0x01,
"PIC32CX1025SG41100", 1024, 256 },
160 { 0x02,
"PIC32CX1025SG41064", 1024, 256 },
165 { 0x00,
"PIC32CX1025SG60128", 1024, 256 },
166 { 0x01,
"PIC32CX1025SG60100", 1024, 256 },
171 { 0x00,
"PIC32CX1025SG61128", 1024, 256 },
172 { 0x01,
"PIC32CX1025SG61100", 1024, 256 },
205 const struct samd_params *
par;
249 for (
unsigned int i = 0; i <
family->num_parts; i++) {
250 if (
family->parts[i].id == devsel)
268 for (
unsigned int prot_block = 0; prot_block <
bank->num_prot_blocks; prot_block++)
269 bank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));
275 uint32_t *sizep,
int *nump)
285 *sizep = (8 << ((param >> 16) & 0x7));
288 *nump = param & 0xFFFF;
290 LOG_ERROR(
"Couldn't read NVM Parameters register");
308 LOG_ERROR(
"Couldn't read Device ID register");
314 LOG_ERROR(
"Couldn't find part corresponding to DID %08" PRIx32,
id);
318 bank->size = part->flash_kb * 1024;
323 LOG_ERROR(
"Couldn't determine Flash page size");
330 LOG_WARNING(
"SAM: bank size doesn't match NVM parameters. "
331 "Identified %" PRIu32
"KB Flash but NVMCTRL reports %u %" PRIu32
"B pages",
350 if (!
bank->prot_blocks)
358 LOG_INFO(
"SAM MCU: %s (%" PRIu32
"KB Flash, %" PRIu32
"KB RAM)", part->name,
359 part->flash_kb, part->ram_kb);
370 int timeout_ms = 200 * 5;
378 LOG_ERROR(
"SAM: error reading the NVMCTRL_INTFLAG register");
384 }
while (
timeval_ms() - ts_start < timeout_ms);
387 LOG_ERROR(
"SAM: NVM programming timed out");
423 LOG_ERROR(
"Can't clear NVM error conditions");
468 LOG_ERROR(
"Failed to erase block containing %08" PRIx32, address);
492 LOG_ERROR(
"The flash controller must be in manual write mode. Issue 'reset init' and retry.");
513 const uint8_t *data,
const uint8_t *
mask,
522 LOG_ERROR(
"Couldn't determine Flash page size");
539 for (i = 0; i <
count; i++) {
540 uint8_t old_b = buf[
offset+i];
541 uint8_t new_b = (old_b & ~
mask[i]) | (data[i] &
mask[i]);
584 uint8_t startb, uint8_t endb)
586 uint8_t buf_val[8] = { 0 };
587 uint8_t buf_mask[8] = { 0 };
589 assert(startb <= endb && endb < 64);
590 buf_set_u32(buf_val, startb, endb + 1 - startb, value);
591 buf_set_u32(buf_mask, startb, endb + 1 - startb, 0xffffffff);
594 buf_val, buf_mask, 0, 8);
610 for (
unsigned int prot_block = first; prot_block <= last; prot_block++) {
611 if (set !=
bank->prot_blocks[prot_block].is_protected) {
615 bank->prot_blocks[prot_block].offset);
630 const uint8_t lock[4] = { 0, 0, 0, 0 };
631 const uint8_t unlock[4] = { 0xff, 0xff, 0xff, 0xff };
632 uint8_t
mask[4] = { 0, 0, 0, 0 };
637 set ? lock : unlock,
mask, 8, 4);
639 LOG_WARNING(
"SAM: protect settings were not made persistent!");
665 for (
unsigned int s = first; s <= last; s++) {
668 LOG_ERROR(
"SAM: failed to erase sector %d at 0x%08" PRIx32, s,
bank->sectors[s].offset);
719 memcpy(pb + pg_offset,
buffer, nb);
724 assert(pg_offset % 4 == 0);
727 nw = (nb +
offset % 4 + 3) / 4;
728 assert(pg_offset + 4 * nw <= chip->
page_size);
736 assert(pg_offset + 4 * nw <= chip->
page_size);
748 LOG_ERROR(
"%s: write failed at address 0x%08" PRIx32, __func__, address);
773 chip = calloc(1,
sizeof(*chip));
775 LOG_ERROR(
"No memory for flash bank chip info");
782 bank->driver_priv = chip;
832 uint8_t val_buf[8], mask_buf[8];
837 val_buf, mask_buf, 0,
sizeof(val_buf));
846 LOG_ERROR(
"USER PAGE could not be read.");
867 uint32_t code = (
size + 8191) / 8192;
870 "see datasheet for a list valid sizes.");
880 uint32_t code = (val >> 26) & 0xf;
881 uint32_t
size = (15 - code) * 8192;
883 PRIu32
" bytes",
size);
932 .
name =
"dsu_reset_deassert",
934 .handler = samd_handle_reset_deassert,
936 .help =
"Deassert internal reset held by DSU."
939 .name =
"chip-erase",
941 .handler = same5_handle_chip_erase_command,
943 .help =
"Erase the entire Flash by using the Chip-"
944 "Erase feature in the Device Service Unit (DSU).",
947 .name =
"bootloader",
948 .usage =
"[size_in_bytes]",
949 .handler = same5_handle_bootloader_command,
951 .help =
"Show or set the bootloader protection size, stored in the User Row. "
952 "Changes are stored immediately but take affect after the MCU is "
957 .usage =
"[value] [mask]",
958 .handler = same5_handle_userpage_command,
960 .help =
"Show or set the first 64-bit part of user page "
961 "located at address 0x804000. Use the optional mask argument "
962 "to prevent changes at positions where the bitvalue is zero. "
963 "For security reasons the reserved-bits are masked out "
964 "in background and therefore cannot be changed.",
973 .help =
"atsame5 flash command group",
983 .flash_bank_command = same5_flash_bank_command,
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 pic32cxsg60_parts[]
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.
static const struct samd_part pic32cxsg41_parts[]
#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)
static const struct samd_part pic32cxsg61_parts[]
#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)
#define PIC32CXSG_SERIES_41
static int same5_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
#define SAMD_DSU_CTRL_EXT
#define PIC32CXSG_SERIES_61
#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 PIC32CXSG_SERIES_60
#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 int first, unsigned int 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(const struct target *target)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.