summaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authorNick Moore <nick@zoic.org>2019-01-31 15:48:19 +1100
committerNick Moore <nick@zoic.org>2019-04-16 14:53:44 +1000
commitd0e5af3b09f144e23029f1738f0e7d96cdd74459 (patch)
tree769ff374f97222940c5b5e13cd8a827e84fcebf0 /ports
parent531cf7eb4ca8af119c66027d60b6b32ff7b6999d (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.h2
-rw-r--r--ports/nrf/common-hal/nvm/ByteArray.c34
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;
}