Skip to content

Commit

Permalink
Optimizing the half page write fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
Ant-ON committed May 26, 2021
1 parent 293db13 commit 9acf539
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
23 changes: 12 additions & 11 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2636,20 +2636,21 @@ int stlink_fread(stlink_t *sl, const char *path, bool is_ihex,
int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf,
size_t size) {
// write the buffer right after the loader
int ret = 0;
size_t chunk = size & ~0x3;
size_t rem = size & 0x3;

if (chunk) {
memcpy(sl->q_buf, buf, chunk);
stlink_write_mem32(sl, fl->buf_addr, chunk);
ret = stlink_write_mem32(sl, fl->buf_addr, chunk);
}

if (rem) {
if (rem && !ret) {
memcpy(sl->q_buf, buf + chunk, rem);
stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem);
ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem);
}

return (0);
return (ret);
}

uint32_t calculate_F4_sectornum(uint32_t flashaddr) {
Expand Down Expand Up @@ -3075,7 +3076,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
uint32_t len, uint32_t pagesize) {
unsigned int count, off;
unsigned int num_half_pages = len / pagesize;
uint32_t val, data;
uint32_t val;
uint32_t flash_regs_base = get_stm32l0_flash_base(sl);
flash_loader_t fl;
bool use_loader = true;
Expand All @@ -3102,10 +3103,10 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
}
if (!use_loader) {
ret = 0;
for (off = 0; off < pagesize && !ret; off += 4)
{
write_uint32((unsigned char *)&data, *(uint32_t *)(base + count * pagesize + off));
ret = stlink_write_debug32(sl, addr + count * pagesize + off, data);
for (off = 0; off < pagesize && !ret; off += 64) {
size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off;
memcpy(sl->q_buf, base + count * pagesize + off, chunk);
ret = stlink_write_mem32(sl, addr + count * pagesize + off, chunk);
}
}

Expand Down Expand Up @@ -3237,8 +3238,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) {

/* Flash loader initialisation */
if (stlink_flash_loader_init(sl, fl) == -1) {
ELOG("stlink_flash_loader_init() == -1\n");
return (-1);
// L0/L1 have fallback to soft write
WLOG("stlink_flash_loader_init() == -1\n");
}
} else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) ||
(sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) {
Expand Down
10 changes: 7 additions & 3 deletions src/stlink-lib/flash_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@

#define STM32F0_WDG_KR_KEY_RELOAD 0xAAAA

/* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */
/* !!!
* !!! DO NOT MODIFY FLASH LOADERS DIRECTLY!
* !!!
*
* Edit assembly files in the '/flashloaders' instead. The sizes of binary
* flash loaders must be aligned by 4 (it's written by stlink_write_mem32)
*/

/* flashloaders/stm32f0.s -- compiled with thumb2 */
static const uint8_t loader_code_stm32vl[] = {
Expand Down Expand Up @@ -322,9 +328,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe

DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size);

// TODO: This can never return -1
if (write_buffer_to_sram(sl, fl, buf, size) == -1) {
// IMPOSSIBLE!
ELOG("write_buffer_to_sram() == -1\n");
return(-1);
}
Expand Down
32 changes: 19 additions & 13 deletions src/stlink-lib/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,16 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate,
retry++;
continue;
}
WLOG("%s wait error (0x%02X)\n", cmd, rxbuf[0]);
DLOG("%s wait error (0x%02X)\n", cmd, rxbuf[0]);
break;
case STLINK_DEBUG_ERR_FAULT: WLOG("%s response fault\n", cmd); break;
case STLINK_DEBUG_ERR_AP_FAULT: WLOG("%s access port fault\n", cmd); break;
case STLINK_DEBUG_ERR_DP_FAULT: WLOG("%s debug port fault\n", cmd); break;
case STLINK_DEBUG_ERR_AP_ERROR: WLOG("%s access port error\n", cmd); break;
case STLINK_DEBUG_ERR_DP_ERROR: WLOG("%s debug port error\n", cmd); break;
case STLINK_DEBUG_ERR_WRITE_VERIFY: WLOG("%s verification error\n", cmd); break;
case STLINK_DEBUG_ERR_WRITE: WLOG("%s write error\n", cmd); break;
default: WLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break;
case STLINK_DEBUG_ERR_FAULT: DLOG("%s response fault\n", cmd); break;
case STLINK_DEBUG_ERR_AP_FAULT: DLOG("%s access port fault\n", cmd); break;
case STLINK_DEBUG_ERR_DP_FAULT: DLOG("%s debug port fault\n", cmd); break;
case STLINK_DEBUG_ERR_AP_ERROR: DLOG("%s access port error\n", cmd); break;
case STLINK_DEBUG_ERR_DP_ERROR: DLOG("%s debug port error\n", cmd); break;
case STLINK_DEBUG_ERR_WRITE_VERIFY: DLOG("%s verification error\n", cmd); break;
case STLINK_DEBUG_ERR_WRITE: DLOG("%s write error\n", cmd); break;
default: DLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break;
}

return(-1);
Expand All @@ -149,7 +149,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate,
t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000);

if (t) {
ELOG("stlink: %s read storage failed: %s\n", cmd, libusb_error_name(t));
ELOG("%s read storage failed: %s\n", cmd, libusb_error_name(t));
return(-1);
}

Expand Down Expand Up @@ -306,6 +306,12 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
unsigned char* const cmd = sl->c_buf;
int i, ret;

if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) ||
(sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) {
ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len);
return (-1);
}

i = fill_command(sl, SG_DXFER_TO_DEV, len);
cmd[i++] = STLINK_DEBUG_COMMAND;
cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT;
Expand All @@ -330,7 +336,7 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {

if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) ||
(sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) {
ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len);
ELOG("WRITEMEM_8BIT: bulk packet limits exceeded (data len %d byte)\n", len);
return (-1);
}

Expand All @@ -339,11 +345,11 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT;
write_uint32(&cmd[i], addr);
write_uint16(&cmd[i + 4], len);
ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT");
ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_8BIT");

if (ret == -1) { return(ret); }

ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT");
ret = send_only(slu, 1, data, len, "WRITEMEM_8BIT");

if (ret == -1) { return(ret); }

Expand Down

0 comments on commit 9acf539

Please sign in to comment.