u5 - flash burst programming

cepetr/cordic-experiment
tychovrahe 9 months ago
parent 2e9f832b39
commit e6bdce63b8

@ -671,11 +671,11 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
const uint32_t *const src = (const uint32_t *const)CHUNK_BUFFER_PTR;
for (int i = 0; i < chunk_size / (sizeof(uint32_t) * 4); i++) {
ensure(flash_area_write_quadword(
for (int i = 0; i < chunk_size / (sizeof(uint32_t) * 8 * 4); i++) {
ensure(flash_area_write_burst(
&FIRMWARE_AREA,
firmware_block * IMAGE_CHUNK_SIZE + i * 4 * sizeof(uint32_t),
&src[4 * i]),
firmware_block * IMAGE_CHUNK_SIZE + i * 8 * 4 * sizeof(uint32_t),
&src[8 * 4 * i]),
NULL);
}

@ -171,7 +171,7 @@ secbool flash_area_erase(const flash_area_t *area,
}
}
done_pages++;
if (progress) {
if (progress && done_pages % 16 == 0) {
progress(done_pages, total_pages);
}
}
@ -276,6 +276,48 @@ secbool flash_write_quadword(uint16_t sector, uint32_t offset,
return sectrue;
}
secbool flash_write_burst(uint16_t sector, uint32_t offset,
const uint32_t *data) {
uint32_t address =
(uint32_t)flash_get_address(sector, offset, 8 * 4 * sizeof(uint32_t));
if (address == 0) {
return secfalse;
}
if (offset %
(8 * 4 * sizeof(uint32_t))) { // we write only at 16-byte boundary
return secfalse;
}
for (int i = 0; i < 8 * 4; i++) {
if (data[i] != (data[i] & *((const uint32_t *)address + i))) {
return secfalse;
}
}
secbool all_match = sectrue;
for (int i = 0; i < 8 * 4; i++) {
if (data[i] != *((const uint32_t *)address + i)) {
all_match = secfalse;
break;
}
}
if (all_match == sectrue) {
return sectrue;
}
if (HAL_OK !=
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BURST, address, (uint32_t)data)) {
return secfalse;
}
for (int i = 0; i < 8 * 4; i++) {
if (data[i] != *((const uint32_t *)address + i)) {
return secfalse;
}
}
return sectrue;
}
secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
const uint32_t *data) {
uint32_t tmp_offset = offset;
@ -307,6 +349,37 @@ secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
return secfalse;
}
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data) {
uint32_t tmp_offset = offset;
for (int i = 0; i < area->num_subareas; i++) {
uint16_t sector = area->subarea[i].first_sector;
uint32_t sub_size = flash_subarea_get_size(&area->subarea[i]);
if (tmp_offset >= sub_size) {
tmp_offset -= sub_size;
continue;
}
// in correct subarea
for (int s = 0; s < area->subarea[i].num_sectors; s++) {
const uint32_t sector_size = flash_sector_size(sector);
if (tmp_offset >= sector_size) {
tmp_offset -= sector_size;
sector++;
if (s == area->subarea[i].num_sectors - 1) {
return secfalse;
}
continue;
}
// in correct sector
return flash_write_burst(sector, tmp_offset, data);
}
}
return secfalse;
}
secbool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data,
uint8_t datalen) {
if (block >= FLASH_OTP_NUM_BLOCKS ||

@ -43,4 +43,7 @@ secbool __wur flash_area_write_word(const flash_area_t *area, uint32_t offset,
secbool __wur flash_area_write_quadword(const flash_area_t *area,
uint32_t offset, const uint32_t *data);
secbool __wur flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data);
#endif

@ -128,3 +128,17 @@ secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
}
return sectrue;
}
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
const uint32_t *data) {
if (offset % (8 * 16) != 0) {
return secfalse;
}
for (int i = 0; i < (8 * 4); i++) {
if (sectrue !=
flash_area_write_word(area, offset + i * sizeof(uint32_t), data[i])) {
return secfalse;
}
}
return sectrue;
}

Loading…
Cancel
Save