|
|
|
@ -26,7 +26,7 @@
|
|
|
|
|
|
|
|
|
|
#include "common-hal/nvm/ByteArray.h"
|
|
|
|
|
|
|
|
|
|
#include "asf/sam0/drivers/nvm/nvm.h"
|
|
|
|
|
#include "hal_flash.h"
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
@ -36,48 +36,12 @@ uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
|
|
|
|
|
uint32_t start_index, uint8_t* values, uint32_t len) {
|
|
|
|
|
uint32_t total_written = 0;
|
|
|
|
|
for (uint32_t i = 0; i < self->len / NVMCTRL_ROW_SIZE; i++) {
|
|
|
|
|
uint32_t row_start = NVMCTRL_ROW_SIZE * i;
|
|
|
|
|
if (row_start + NVMCTRL_ROW_SIZE < start_index || start_index + len < row_start) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
uint8_t temp_row[NVMCTRL_ROW_SIZE];
|
|
|
|
|
memcpy(temp_row,
|
|
|
|
|
self->start_address + row_start,
|
|
|
|
|
NVMCTRL_ROW_SIZE);
|
|
|
|
|
enum status_code error_code;
|
|
|
|
|
do {
|
|
|
|
|
error_code = nvm_erase_row((uint32_t) self->start_address + row_start);
|
|
|
|
|
} while (error_code == STATUS_BUSY);
|
|
|
|
|
if (error_code != STATUS_OK) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
uint32_t data_start = 0;
|
|
|
|
|
if (start_index > row_start) {
|
|
|
|
|
data_start = start_index - row_start;
|
|
|
|
|
}
|
|
|
|
|
uint32_t data_len = len;
|
|
|
|
|
uint32_t data_remaining = data_len - total_written;
|
|
|
|
|
uint32_t row_remaining = NVMCTRL_ROW_SIZE - data_start;
|
|
|
|
|
if (data_remaining > row_remaining) {
|
|
|
|
|
data_len = row_remaining;
|
|
|
|
|
}
|
|
|
|
|
memcpy(temp_row + data_start,
|
|
|
|
|
values + total_written,
|
|
|
|
|
data_len);
|
|
|
|
|
for (int page = 0; page < NVMCTRL_ROW_SIZE / NVMCTRL_PAGE_SIZE; page++) {
|
|
|
|
|
do {
|
|
|
|
|
error_code = nvm_write_buffer((uint32_t) self->start_address + row_start + page * NVMCTRL_PAGE_SIZE,
|
|
|
|
|
temp_row + page * NVMCTRL_PAGE_SIZE,
|
|
|
|
|
NVMCTRL_PAGE_SIZE);
|
|
|
|
|
} while (error_code == STATUS_BUSY);
|
|
|
|
|
if (error_code != STATUS_OK) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
uint32_t start_index, uint8_t* values, uint32_t len) {
|
|
|
|
|
// We don't use features that use any advanced NVMCTRL features so we can fake the descriptor
|
|
|
|
|
// whenever we need it instead of storing it long term.
|
|
|
|
|
struct flash_descriptor desc;
|
|
|
|
|
desc.dev.hw = NVMCTRL;
|
|
|
|
|
flash_write(&desc, (uint32_t) self->start_address + start_index, values, len);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|