summaryrefslogtreecommitdiff
path: root/ports/nrf
diff options
context:
space:
mode:
Diffstat (limited to 'ports/nrf')
-rw-r--r--ports/nrf/internal_flash.c142
-rw-r--r--ports/nrf/internal_flash.h2
-rw-r--r--ports/nrf/usb/usb_msc_flash.c71
3 files changed, 75 insertions, 140 deletions
diff --git a/ports/nrf/internal_flash.c b/ports/nrf/internal_flash.c
index 2f069a2f9..56377c973 100644
--- a/ports/nrf/internal_flash.c
+++ b/ports/nrf/internal_flash.c
@@ -36,16 +36,34 @@
#include "lib/oofatfs/ff.h"
#include "supervisor/shared/rgb_led_status.h"
-#include "nrf.h"
+#include "nrf_nvmc.h"
#ifdef BLUETOOTH_SD
#include "nrf_sdm.h"
#endif
+/*------------------------------------------------------------------*/
+/* VARIABLES
+ *------------------------------------------------------------------*/
+
// defined in linker
extern uint32_t __fatfs_flash_start_addr[];
extern uint32_t __fatfs_flash_length[];
+#define NO_CACHE 0xffffffff
+#define FL_PAGE_SZ 4096
+
+uint8_t _fl_cache[FL_PAGE_SZ] __attribute__((aligned(4)));
+uint32_t _fl_pg_addr = NO_CACHE;
+
+
+/*------------------------------------------------------------------*/
+/* Internal Flash API
+ *------------------------------------------------------------------*/
+static inline uint32_t lba2addr(uint32_t block) {
+ return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE;
+}
+
void internal_flash_init(void) {
// Activity LED for flash writes.
#ifdef MICROPY_HW_LED_MSC
@@ -67,101 +85,63 @@ uint32_t internal_flash_get_block_count(void) {
return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ;
}
+// TODO support flashing with SD enabled
void internal_flash_flush(void) {
-}
+ if (_fl_pg_addr == NO_CACHE) return;
-void flash_flush(void) {
- internal_flash_flush();
-}
+ // Skip if data is the same
+ if (memcmp(_fl_cache, (void *)_fl_pg_addr, FL_PAGE_SZ) != 0) {
+// _is_flashing = true;
+ nrf_nvmc_page_erase(_fl_pg_addr);
+ nrf_nvmc_write_words(_fl_pg_addr, (uint32_t *)_fl_cache, FL_PAGE_SZ / sizeof(uint32_t));
+ }
-static uint32_t convert_block_to_flash_addr(uint32_t block) {
- return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE;
+ _fl_pg_addr = NO_CACHE;
}
-bool internal_flash_write_block(const uint8_t *src, uint32_t block) {
- uint8_t sd_en = 0;
-
-#ifdef MICROPY_HW_LED_MSC
- port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
-#endif
- temp_status_color(ACTIVE_WRITE);
- // non-MBR block, copy to cache
-
- uint32_t dest = convert_block_to_flash_addr(block);
-
- uint32_t pagenum = dest / FLASH_PAGE_SIZE;
- uint32_t* flash_align = (uint32_t*) (pagenum*FLASH_PAGE_SIZE);
-
- // Read back current page to update only 512 portion
- __ALIGN(4) uint8_t buf[FLASH_PAGE_SIZE];
- memcpy(buf, flash_align, FLASH_PAGE_SIZE);
- memcpy(buf + (dest%FLASH_PAGE_SIZE), src, FILESYSTEM_BLOCK_SIZE);
-
-#ifdef BLUETOOTH_SD
- (void) sd_softdevice_is_enabled(&sd_en);
-
- if (sd_en) {
- if (NRF_SUCCESS != sd_flash_page_erase(pagenum)) {
- return false;
- }
-
- if (NRF_SUCCESS != sd_flash_write(flash_align, (uint32_t*) buf, FLASH_PAGE_SIZE / sizeof(uint32_t))) {
- return false;
- }
- }
-#endif
+mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
+ uint32_t src = lba2addr(block);
+ memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks);
+ return 0; // success
+}
- if (!sd_en) {
- // Erase
- NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
- while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
- NRF_NVMC->ERASEPAGE = dest;
- while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+ #ifdef MICROPY_HW_LED_MSC
+ port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
+ #endif
- NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
- while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+ while (num_blocks) {
+ uint32_t const addr = lba2addr(lba);
+ uint32_t const page_addr = addr & ~(FL_PAGE_SZ - 1);
- // Write
- uint32_t *p_src = (uint32_t*) buf;
- uint32_t *p_dest = flash_align;
- uint32_t i = 0;
+ uint32_t count = 8 - (lba%8); // up to page boundary
+ count = MIN(num_blocks, count);
- while (i < (FLASH_PAGE_SIZE / sizeof(uint32_t))) {
- NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
- while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+ if (page_addr != _fl_pg_addr) {
+ internal_flash_flush();
- *p_dest++ = *p_src++;
+ // writing previous cached data, skip current data until flashing is done
+ // tinyusb stack will invoke write_block() with the same parameters later on
+ // if ( _is_flashing ) return;
- while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+ _fl_pg_addr = page_addr;
+ memcpy(_fl_cache, (void *)page_addr, FL_PAGE_SZ);
+ }
- NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
- while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+ memcpy(_fl_cache + (addr & (FL_PAGE_SZ - 1)), src, count*FILESYSTEM_BLOCK_SIZE);
- ++i;
+ // adjust for next run
+ lba += count;
+ src += count*FILESYSTEM_BLOCK_SIZE;
+ num_blocks -= count;
}
- }
-
- clear_temp_status();
-#ifdef MICROPY_HW_LED_MSC
- port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
-#endif
- return true;
-}
-mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
- uint32_t src = convert_block_to_flash_addr(block);
- memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks);
- return 0; // success
-}
+ #ifdef MICROPY_HW_LED_MSC
+ port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
+ #endif
-mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
- for (size_t i = 0; i < num_blocks; i++) {
- if (!internal_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
- return 1; // error
- }
- }
- return 0; // success
+ return 0; // success
}
/******************************************************************************/
@@ -241,3 +221,7 @@ void flash_init_vfs(fs_user_mount_t *vfs) {
vfs->u.ioctl[0] = (mp_obj_t)&internal_flash_obj_ioctl_obj;
vfs->u.ioctl[1] = (mp_obj_t)&internal_flash_obj;
}
+
+void flash_flush(void) {
+ internal_flash_flush();
+}
diff --git a/ports/nrf/internal_flash.h b/ports/nrf/internal_flash.h
index 79b786555..e83b39d57 100644
--- a/ports/nrf/internal_flash.h
+++ b/ports/nrf/internal_flash.h
@@ -44,8 +44,6 @@ uint32_t internal_flash_get_block_size(void);
uint32_t internal_flash_get_block_count(void);
void internal_flash_irq_handler(void);
void internal_flash_flush(void);
-bool internal_flash_read_block(uint8_t *dest, uint32_t block);
-bool internal_flash_write_block(const uint8_t *src, uint32_t block);
// these return 0 on success, non-zero on error
mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
diff --git a/ports/nrf/usb/usb_msc_flash.c b/ports/nrf/usb/usb_msc_flash.c
index 22cc68988..dc88d031c 100644
--- a/ports/nrf/usb/usb_msc_flash.c
+++ b/ports/nrf/usb/usb_msc_flash.c
@@ -37,7 +37,7 @@
#ifdef NRF52840_XXAA
#include "tusb.h"
-#include "nrf_nvmc.h"
+#include "internal_flash.h"
/*------------------------------------------------------------------*/
/* MACRO TYPEDEF CONSTANT ENUM
@@ -71,11 +71,6 @@ static scsi_mode_parameters_t const msc_dev_mode_para =
/*
*------------------------------------------------------------------*/
-static inline uint32_t lba2addr(uint32_t lba)
-{
- return MSC_FLASH_ADDR_START + lba*MSC_FLASH_BLOCK_SIZE;
-}
-
//--------------------------------------------------------------------+
// tinyusb callbacks
//--------------------------------------------------------------------+
@@ -142,71 +137,29 @@ int32_t tud_msc_scsi_cb (uint8_t rhport, uint8_t lun, uint8_t const scsi_cmd[16]
}
/*------------------------------------------------------------------*/
-/* Internal Flash
- *------------------------------------------------------------------*/
-#define NO_CACHE 0xffffffff
-
-uint8_t _fl_cache[FL_PAGE_SZ] ATTR_ALIGNED(4);
-uint32_t _fl_addr = NO_CACHE;
-
-
-static void fl_flush() {
- if (_fl_addr == NO_CACHE) return;
-
- // Skip if data is the same
- if (memcmp(_fl_cache, (void *)_fl_addr, FL_PAGE_SZ) != 0) {
-// _is_flashing = true;
- nrf_nvmc_page_erase(_fl_addr);
- nrf_nvmc_write_words(_fl_addr, (uint32_t *)_fl_cache, FL_PAGE_SZ / sizeof(uint32_t));
- }
-
- _fl_addr = NO_CACHE;
-}
-
-static bool fl_write(uint32_t addr, uint8_t* buf, uint16_t bufsize)
-{
- uint32_t new_addr = addr & ~(FL_PAGE_SZ - 1);
-
- if (new_addr != _fl_addr) {
- fl_flush();
-
- // writing previous cached data, skip current data until flashing is done
- // tinyusb stack will invoke write_block() with the same parameters later on
-// if ( _is_flashing ) return;
-
- _fl_addr = new_addr;
- memcpy(_fl_cache, (void *)new_addr, FL_PAGE_SZ);
- }
-
- memcpy(_fl_cache + (addr & (FL_PAGE_SZ - 1)), buf, bufsize);
-
- return true;
-}
-
-
-/*------------------------------------------------------------------*/
/* Tinyusb Flash READ10 & WRITE10
*------------------------------------------------------------------*/
int32_t tud_msc_read10_cb (uint8_t rhport, uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
{
- (void) rhport;
- (void) lun;
+ (void) rhport; (void) lun; (void) offset;
- uint32_t addr = lba2addr(lba) + offset;
- memcpy(buffer, (uint8_t*) addr, bufsize);
+ uint32_t const block_count = bufsize/MSC_FLASH_BLOCK_SIZE;
- return bufsize;
+ internal_flash_read_blocks(buffer, lba, block_count);
+
+ return block_count*MSC_FLASH_BLOCK_SIZE;
}
int32_t tud_msc_write10_cb (uint8_t rhport, uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
{
- (void) rhport; (void) lun;
- uint32_t addr = lba2addr(lba) + offset;
+ (void) rhport; (void) lun; (void) offset;
+
+ uint32_t const block_count = bufsize/MSC_FLASH_BLOCK_SIZE;
// bufsize <= CFG_TUD_MSC_BUFSIZE (4096)
- fl_write(addr, buffer, bufsize);
+ internal_flash_write_blocks(buffer, lba, block_count);
- return bufsize;
+ return block_count*MSC_FLASH_BLOCK_SIZE;
}
void tud_msc_write10_complete_cb(uint8_t rhport, uint8_t lun)
@@ -214,7 +167,7 @@ void tud_msc_write10_complete_cb(uint8_t rhport, uint8_t lun)
(void) rhport; (void) lun;
// flush pending cache when write10 is complete
- fl_flush();
+ internal_flash_flush();
}
#endif