diff options
| author | Nick Moore <nick@zoic.org> | 2019-01-31 15:48:19 +1100 |
|---|---|---|
| committer | Nick Moore <nick@zoic.org> | 2019-04-16 14:53:44 +1000 |
| commit | d0e5af3b09f144e23029f1738f0e7d96cdd74459 (patch) | |
| tree | 769ff374f97222940c5b5e13cd8a827e84fcebf0 /ports | |
| parent | 531cf7eb4ca8af119c66027d60b6b32ff7b6999d (diff) | |
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()
Diffstat (limited to 'ports')
| -rw-r--r-- | ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h | 2 | ||||
| -rw-r--r-- | ports/nrf/common-hal/nvm/ByteArray.c | 34 |
2 files changed, 33 insertions, 3 deletions
diff --git a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h index d007a1812..e1f43e3c9 100644 --- a/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h +++ b/ports/nrf/boards/feather_nrf52840_express/mpconfigboard.h @@ -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) diff --git a/ports/nrf/common-hal/nvm/ByteArray.c b/ports/nrf/common-hal/nvm/ByteArray.c index 6298ce18e..7393ce0a5 100644 --- a/ports/nrf/common-hal/nvm/ByteArray.c +++ b/ports/nrf/common-hal/nvm/ByteArray.c @@ -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; } |
