Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Added writing and reading for STM32WL option bytes #1227

Merged
merged 1 commit into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/chips/WLx5.chip
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ flash_pagesize 0x800 // 2 KB
sram_size 0x10000 // 64 KB
bootrom_base 0x1fff0000
bootrom_size 0x7000 // 28 KB
option_base 0x1fffc000
option_base 0x1fff7800
option_size 0x10 // 16 B
flags swo
8 changes: 5 additions & 3 deletions inc/stm32flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@
#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84)

// WB Flash control register.
#define STM32WB_FLASH_CR_STRT (16) /* Start */
#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */
#define STM32WB_FLASH_CR_LOCK (31) /* Lock */
#define STM32WB_FLASH_CR_STRT (16) /* Start */
#define STM32WB_FLASH_CR_OPTSTRT (17) /* Start writing option bytes */
#define STM32WB_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */
#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */
#define STM32WB_FLASH_CR_LOCK (31) /* Lock */
// WB Flash status register.
#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */
#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */
Expand Down
108 changes: 108 additions & 0 deletions src/option_bytes.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,57 @@ static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base,
return 0;
}

/**
* Write option bytes
* @param sl
* @param addr of the memory mapped option bytes
* @param base option bytes to write
* @return 0 on success, -ve on failure.
*/
static int stlink_write_option_bytes_wb(stlink_t *sl, uint8_t *base,
stm32_addr_t addr, uint32_t len) {
/* Write options bytes */
uint32_t val;
int ret = 0;
(void)len;
uint32_t data;

clear_flash_error(sl);

while (len != 0) {
write_uint32((unsigned char *)&data,
*(uint32_t *)(base)); // write options bytes

WLOG("Writing option bytes %#10x to %#10x\n", data, addr);
stlink_write_debug32(sl, addr, data);
wait_flash_busy(sl);

if ((ret = check_flash_error(sl))) {
break;
}

len -= 4;
addr += 4;
base += 4;
}

// Set Options Start bit
stlink_read_debug32(sl, STM32WB_FLASH_CR, &val);
val |= (1 << STM32WB_FLASH_CR_OPTSTRT);
stlink_write_debug32(sl, STM32WB_FLASH_CR, val);

wait_flash_busy(sl);

ret = check_flash_error(sl);

// Reload options
stlink_read_debug32(sl, STM32WB_FLASH_CR, &val);
val |= (1 << STM32WB_FLASH_CR_OBL_LAUNCH);
stlink_write_debug32(sl, STM32WB_FLASH_CR, val);

return (ret);
}

/**
* Write option bytes
* @param sl
Expand Down Expand Up @@ -536,6 +587,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base,
case STM32_FLASH_TYPE_H7:
ret = stlink_write_option_bytes_h7(sl, base, addr, len);
break;
case STM32_FLASH_TYPE_WB_WL:
ret = stlink_write_option_bytes_wb(sl, base, addr, len);
break;
default:
ELOG("Option bytes writing is currently not implemented for connected "
"chip\n");
Expand Down Expand Up @@ -715,6 +769,42 @@ stlink_write_option_control_register_f7(stlink_t *sl,
return ret;
}

/**
* Write option bytes
* @param sl
* @param option_byte value to write
* @return 0 on success, -ve on failure.
*/
static int
stlink_write_option_control_register_wb(stlink_t *sl,
uint32_t option_control_register) {
int ret = 0;

// Clear errors
clear_flash_error(sl);

ILOG("Asked to write option control register 1 %#10x to %#010x.\n",
option_control_register, STM32WB_FLASH_OPTR);

/* write option byte, ensuring we dont lock opt, and set strt bit */
stlink_write_debug32(sl, STM32WB_FLASH_OPTR, option_control_register);

wait_flash_busy(sl);

// Set Options Start bit
uint32_t val = (1 << STM32WB_FLASH_CR_OPTSTRT);
stlink_write_debug32(sl, STM32WB_FLASH_CR, val);

wait_flash_busy(sl);

ret = check_flash_error(sl);
if (!ret)
ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register,
STM32WB_FLASH_OPTR);

return ret;
}

/**
* Write option bytes
* @param sl
Expand Down Expand Up @@ -746,6 +836,10 @@ int stlink_write_option_control_register32(stlink_t *sl,
case STM32_FLASH_TYPE_F7:
ret = stlink_write_option_control_register_f7(sl, option_control_register);
break;
case STM32_FLASH_TYPE_WB_WL:
ret =
stlink_write_option_control_register_wb(sl, option_control_register);
break;
default:
ELOG("Option control register writing is currently not implemented for "
"connected chip\n");
Expand Down Expand Up @@ -1003,6 +1097,18 @@ int stlink_read_option_control_register_f0(stlink_t *sl,
return stlink_read_debug32(sl, FLASH_OBR, option_byte);
}

/**
* Read option bytes
* @param sl
* @param option_byte value to read
* @return 0 on success, -ve on failure.
*/
int stlink_read_option_control_register_wb(stlink_t *sl,
uint32_t *option_byte) {
DLOG("@@@@ Read option control register byte from %#10x\n", STM32WB_FLASH_OPTR);
return stlink_read_debug32(sl, STM32WB_FLASH_OPTR, option_byte);
}

/**
* Read option bytes
* @param sl
Expand All @@ -1021,6 +1127,8 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) {
return stlink_read_option_control_register_f0(sl, option_byte);
case STM32_FLASH_TYPE_F7:
return stlink_read_option_control_register_f7(sl, option_byte);
case STM32_FLASH_TYPE_WB_WL:
return stlink_read_option_control_register_wb(sl, option_byte);
default:
return -1;
}
Expand Down