8000 Merge pull request #1661 from dhalbert/nrf-internal-flash-fixes · rhwlo/circuitpython@b4b8ffa · GitHub
[go: up one dir, main page]

Skip to content

Commit b4b8ffa

Browse files
authored
Merge pull request adafruit#1661 from dhalbert/nrf-internal-flash-fixes
nrf: fix internal flash writes
2 parents 60f7694 + aff4e34 commit b4b8ffa

File tree

14 files changed

+975
-775
lines changed

14 files changed

+975
-775
lines changed

locale/ID.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/circuitpython.pot

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/de_DE.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/en_US.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/en_x_pirate.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/es.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/fil.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/fr.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/it_IT.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

locale/pt_BR.po

Lines changed: 89 additions & 73 deletions
Large diffs are not rendered by default.

ports/nrf/bluetooth/ble_drv.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,16 @@
3939

4040
nrf_nvic_state_t nrf_nvic_state = { 0 };
4141

42+
// Flag indicating progress of internal flash operation.
43+
sd_flash_operation_status_t sd_flash_operation_status;
44+
4245
__attribute__((aligned(4)))
4346
static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)];
4447

4548
void ble_drv_reset() {
4649
// Linked list items will be gc'd.
4750
MP_STATE_VM(ble_drv_evt_handler_entries) = NULL;
51+
sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
4852
}
4953

5054
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
@@ -85,22 +89,29 @@ extern void tusb_hal_nrf_power_event (uint32_t event);
8589
void SD_EVT_IRQHandler(void) {
8690
uint32_t evt_id;
8791
while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) {
88-
// sd_evt_handler(evt_id);
89-
9092
switch (evt_id) {
9193
// usb power event
92-
case NRF_EVT_POWER_USB_DETECTED:
93-
case NRF_EVT_POWER_USB_POWER_READY:
94-
case NRF_EVT_POWER_USB_REMOVED: {
95-
int32_t usbevt = (evt_id == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
96-
(evt_id == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
97-
(evt_id == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
98-
99-
tusb_hal_nrf_power_event(usbevt);
100-
}
94+
case NRF_EVT_POWER_USB_DETECTED:
95+
case NRF_EVT_POWER_USB_POWER_READY:
96+
case NRF_EVT_POWER_USB_REMOVED: {
97+
int32_t usbevt = (evt_id == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
98+
(evt_id == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
99+
(evt_id == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
100+
101+
tusb_hal_nrf_power_event(usbevt);
102+
}
101103
break;
102104

103-
default: break;
105+
// Set flag indicating that a flash operation has finished.
106+
case NRF_EVT_FLASH_OPERATION_SUCCESS:
107+
sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
108+
break;
109+
case NRF_EVT_FLASH_OPERATION_ERROR:
110+
sd_flash_operation_status = SD_FLASH_OPERATION_ERROR;
111+
break;
112+
113+
default:
114+
break;
104115
}
105116
}
106117

ports/nrf/bluetooth/ble_drv.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@
5050

5151
typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
5252

53+
typedef enum {
54+
SD_FLASH_OPERATION_DONE,
55+
SD_FLASH_OPERATION_IN_PROGRESS,
56+
SD_FLASH_OPERATION_ERROR,
57+
} sd_flash_operation_status_t;
58+
59+
// Flag indicating progress of internal flash operation.
60+
extern sd_flash_operation_status_t sd_flash_operation_status;
61+
5362
typedef struct ble_drv_evt_handler_entry {
5463
struct ble_drv_evt_handler_entry *next;
5564
void *param;

ports/nrf/nrfx

Submodule nrfx updated 232 files

ports/nrf/supervisor/internal_flash.c

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "nrf_nvmc.h"
3939

4040
#ifdef BLUETOOTH_SD
41+
#include "ble_drv.h"
4142
#include "nrf_sdm.h"
4243
#endif
4344

@@ -71,26 +72,15 @@ uint32_t supervisor_flash_get_block_count(void) {
7172
}
7273

7374
#ifdef BLUETOOTH_SD
74-
STATIC bool wait_for_flash_operation(void) {
75-
do {
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) {
7681
sd_app_evt_wait();
77-
uint32_t evt_id;
78-
uint32_t result = sd_evt_get(&evt_id);
79-
if (result == NRF_SUCCESS) {
80-
switch (evt_id) {
81-
case NRF_EVT_FLASH_OPERATION_SUCCESS:
82-
return true;
83-
84-
case NRF_EVT_FLASH_OPERATION_ERROR:
85-
return false;
86-
87-
default:
88-
// Some other event. Wait for a flash event.
89-
continue;
90-
}
91-
}
92-
return false;
93-
} while (true);
82+
}
83+
return sd_flash_operation_status;
9484
}
9585
#endif
9686

@@ -101,27 +91,55 @@ void supervisor_flash_flush(void) {
10191
if (memcmp(_flash_cache, (void *)_flash_page_addr, FL_PAGE_SZ) != 0) {
10292

10393
#ifdef BLUETOOTH_SD
104-
uint8_t sd_en = 0;
105-
(void) sd_softdevice_is_enabled(&sd_en);
106-
107-
if (sd_en) {
108-
sd_flash_page_erase(_flash_page_addr / FL_PAGE_SZ);
109-
wait_for_flash_operation(); // TODO: handle error return.
110-
sd_flash_write((uint32_t *)_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t));
111-
wait_for_flash_operation();
112-
} else {
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 {
113129
#endif
114-
nrf_nvmc_page_erase(_flash_page_addr);
115-
nrf_nvmc_write_words(_flash_page_addr, (uint32_t *)_flash_cache, FL_PAGE_SZ / sizeof(uint32_t));
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));
116132
#ifdef BLUETOOTH_SD
117-
}
133+
}
118134
#endif
119135

120-
_flash_page_addr = NO_CACHE;
121136
}
137+
_flash_page_addr = NO_CACHE;
122138
}
123139

124140
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
141+
// Must write out anything in cache before trying to read.
142+
supervisor_flash_flush();
125143
uint32_t src = lba2addr(block);
126144
memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks);
127145
return 0; // success
@@ -139,9 +157,11 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
139157
supervisor_flash_flush();
140158

141159
_flash_page_addr = page_addr;
160+
// Copy the current contents of the entire page into the cache.
142161
memcpy(_flash_cache, (void *)page_addr, FL_PAGE_SZ);
143162
}
144163

164+
// Overwrite part or all of the page cache with the src data.
145165
memcpy(_flash_cache + (addr & (FL_PAGE_SZ - 1)), src, count * FILESYSTEM_BLOCK_SIZE);
146166

147167
// adjust for next run

0 commit comments

Comments
 (0)
0