3535#include "py/runtime.h"
3636#include "lib/oofatfs/ff.h"
3737
38- #include "nrf_nvmc .h"
38+ #include "peripherals/nrf/nvm .h"
3939
4040#ifdef BLUETOOTH_SD
4141#include "ble_drv.h"
@@ -47,9 +47,8 @@ extern uint32_t __fatfs_flash_start_addr[];
4747extern uint32_t __fatfs_flash_length [];
4848
4949#define NO_CACHE 0xffffffff
50- #define FL_PAGE_SZ 4096
5150
52- uint8_t _flash_cache [FL_PAGE_SZ ] __attribute__((aligned (4 )));
51+ uint8_t _flash_cache [FLASH_PAGE_SIZE ] __attribute__((aligned (4 )));
5352uint32_t _flash_page_addr = NO_CACHE ;
5453
5554
@@ -71,78 +70,11 @@ uint32_t supervisor_flash_get_block_count(void) {
7170 return ((uint32_t ) __fatfs_flash_length ) / FILESYSTEM_BLOCK_SIZE ;
7271}
7372
74- #ifdef BLUETOOTH_SD
75- STATIC void sd_flash_operation_start (void ) {
76- sd_flash_operation_status = SD_FLASH_OPERATION_IN_PROGRESS ;
77- }
78-
79- STATIC sd_flash_operation_status_t sd_flash_operation_wait_until_done (void ) {
80- while (sd_flash_operation_status == SD_FLASH_OPERATION_IN_PROGRESS ) {
81- sd_app_evt_wait ();
82- }
83- return sd_flash_operation_status ;
84- }
85- #endif
86-
87- void supervisor_flash_flush (void ) {
88- if (_flash_page_addr == NO_CACHE ) return ;
89-
90- // Skip if data is the same
91- if (memcmp (_flash_cache , (void * )_flash_page_addr , FL_PAGE_SZ ) != 0 ) {
92-
93- #ifdef BLUETOOTH_SD
94- uint8_t sd_en = 0 ;
95- (void ) sd_softdevice_is_enabled (& sd_en );
96-
97- if (sd_en ) {
98- uint32_t err_code ;
99- sd_flash_operation_status_t status ;
100-
101- sd_flash_operation_start ();
102- err_code = sd_flash_page_erase (_flash_page_addr / FL_PAGE_SZ );
103- if (err_code != NRF_SUCCESS ) {
104- mp_raise_OSError_msg_varg (translate ("Flash erase failed to start, err 0x%04x" ), err_code );
105- }
106- status = sd_flash_operation_wait_until_done ();
107- if (status == SD_FLASH_OPERATION_ERROR ) {
108- mp_raise_OSError_msg (translate ("Flash erase failed" ));
109- }
110-
111- // Divide a full page into parts, because writing a full page causes an assertion failure.
112- // See https://devzone.nordicsemi.com/f/nordic-q-a/40088/sd_flash_write-cause-nrf_fault_id_sd_assert/
113- const size_t BLOCK_PARTS = 2 ;
114- size_t words_to_write = FL_PAGE_SZ / sizeof (uint32_t ) / BLOCK_PARTS ;
115- for (size_t i = 0 ; i < BLOCK_PARTS ; i ++ ) {
116- sd_flash_operation_start ();
117- err_code = sd_flash_write (((uint32_t * )_flash_page_addr ) + i * words_to_write ,
118- (uint32_t * )_flash_cache + i * words_to_write ,
119- words_to_write );
120- if (err_code != NRF_SUCCESS ) {
121- mp_raise_OSError_msg_varg (translate ("Flash write failed to start, err 0x%04x" ), err_code );
122- }
123- status = sd_flash_operation_wait_until_done ();
124- if (status == SD_FLASH_OPERATION_ERROR ) {
125- mp_raise_OSError_msg (translate ("Flash write failed" ));
126- }
127- }
128- } else {
129- #endif
130- nrf_nvmc_page_erase (_flash_page_addr );
131- nrf_nvmc_write_words (_flash_page_addr , (uint32_t * )_flash_cache , FL_PAGE_SZ / sizeof (uint32_t ));
132- #ifdef BLUETOOTH_SD
133- }
134- #endif
135-
136- }
137- _flash_page_addr = NO_CACHE ;
138- }
139-
140- void supervisor_flash_release_cache (void ) {
141- }
142-
14373mp_uint_t supervisor_flash_read_blocks (uint8_t * dest , uint32_t block , uint32_t num_blocks ) {
14474 // Must write out anything in cache before trying to read.
145- supervisor_flash_flush ();
75+ nrf_nvm_safe_flash_page_write (_flash_page_addr , _flash_cache );
76+ _flash_page_addr = NO_CACHE ;
77+
14678 uint32_t src = lba2addr (block );
14779 memcpy (dest , (uint8_t * ) src , FILESYSTEM_BLOCK_SIZE * num_blocks );
14880 return 0 ; // success
@@ -151,21 +83,21 @@ mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t n
15183mp_uint_t supervisor_flash_write_blocks (const uint8_t * src , uint32_t lba , uint32_t num_blocks ) {
15284 while (num_blocks ) {
15385 uint32_t const addr = lba2addr (lba );
154- uint32_t const page_addr = addr & ~(FL_PAGE_SZ - 1 );
86+ uint32_t const page_addr = addr & ~(FLASH_PAGE_SIZE - 1 );
15587
15688 uint32_t count = 8 - (lba % 8 ); // up to page boundary
15789 count = MIN (num_blocks , count );
15890
15991 if (page_addr != _flash_page_addr ) {
160- supervisor_flash_flush ();
161-
92+ nrf_nvm_safe_flash_page_write (_flash_page_addr , _flash_cache );
16293 _flash_page_addr = page_addr ;
94+
16395 // Copy the current contents of the entire page into the cache.
164- memcpy (_flash_cache , (void * )page_addr , FL_PAGE_SZ );
96+ memcpy (_flash_cache , (void * )page_addr , FLASH_PAGE_SIZE );
16597 }
16698
16799 // Overwrite part or all of the page cache with the src data.
168- memcpy (_flash_cache + (addr & (FL_PAGE_SZ - 1 )), src , count * FILESYSTEM_BLOCK_SIZE );
100+ memcpy (_flash_cache + (addr & (FLASH_PAGE_SIZE - 1 )), src , count * FILESYSTEM_BLOCK_SIZE );
169101
170102 // adjust for next run
171103 lba += count ;
0 commit comments