Working flash pages for nvm.ByteArray adafruit/circuitpython#1042

import microcontroller

def dump(n = microcontroller.nvm):
    for i in range(0,len(n)):
        print ("%02X " % n[i], end="")
        if i % 16 == 15: print('')

microcontroller.nvm[0:4096] = bytes([1,2,3,4,5,6,7,8]) * 512
microcontroller.nvm[4096:8192] = bytes([16,17,18,19]) * 1024
microcontroller.nvm[4090:4101] = b'thisisatest'
microcontroller.nvm[100:105] = b'hello'
microcontroller.nvm[8000:8007] = b'goodbye'
dump()
This commit is contained in:
Nick Moore 2019-01-31 15:48:19 +11:00
parent 592bd0140a
commit 8e7fee2246
2 changed files with 33 additions and 3 deletions

View File

@ -32,7 +32,9 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Feather nRF52840 Express"
#define MICROPY_HW_MCU_NAME "nRF52840"
#define MICROPY_PY_SYS_PLATFORM "Feather52840Express"
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (4096)
#define MICROPY_HW_NEOPIXEL (&pin_P0_16)

View File

@ -35,11 +35,39 @@ uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
return self->len;
}
static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_t *bytes) {
// Write a whole page to flash, buffering it first and then erasing and rewriting
// it since we can only clear a whole page at a time.
// TODO (maybe) check if only clearing bits (don't need to erase)
// XXX should this suspend interrupts so erase/write is atomic?
if (offset == 0 && len == FLASH_PAGE_SIZE) {
nrf_nvmc_page_erase(page_addr);
nrf_nvmc_write_bytes(page_addr, bytes, FLASH_PAGE_SIZE);
} else {
uint8_t buffer[FLASH_PAGE_SIZE];
memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE);
memcpy(buffer + offset, bytes, len);
nrf_nvmc_page_erase(page_addr);
nrf_nvmc_write_bytes(page_addr, buffer, FLASH_PAGE_SIZE);
}
}
bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
uint32_t start_index, uint8_t* values, uint32_t len) {
printf("%ld %ld\n", start_index, len);
nrf_nvmc_page_erase(self->start_address);
nrf_nvmc_write_bytes(self->start_address + start_index, values, len);
uint32_t address = self->start_address + start_index;
uint32_t offset = address % FLASH_PAGE_SIZE;
uint32_t page_addr = address - offset;
while (len) {
uint32_t write_len = MIN(len, FLASH_PAGE_SIZE - offset);
write_page(page_addr, offset, write_len, values);
len -= write_len;
values += write_len;
page_addr += FLASH_PAGE_SIZE;
offset = 0;
}
return true;
}