This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How can i write external qspi flash over BLE DFU?

Hello 

i'm use nrf52840 and I want write external qspi flash over BLE DFU but cannot be use

how can i solve this problem?

DFU log

<info> app: Inside main
<debug> app: In nrf_bootloader_init
<debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
<debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
<debug> nrf_dfu_settings: Using settings page.
<debug> nrf_dfu_settings: Copying forbidden parts from backup page.
<debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
<info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
<debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
<debug> app: Enter nrf_bootloader_fw_activate
<info> app: No firmware to activate.
<info> app: Boot validation failed. No valid app to boot.
<debug> app: DFU mode because app is not valid.
<info> nrf_bootloader_wdt: WDT is not enabled
<debug> app: in weak nrf_dfu_init_user
<debug> app: timer_stop (0x200059A0)
<debug> app: timer_activate (0x200059A0)
<info> app: Entering DFU mode.
<debug> app: Initializing transports (found: 1)
<debug> nrf_dfu_ble: Initializing BLE DFU transport
<debug> nrf_dfu_ble: Setting up vector table: 0x000EE000
<debug> nrf_dfu_ble: Enabling SoftDevice.
<debug> app: nrf_fstorage_sdh_req_handler
<debug> app: nrf_fstorage_sdh_state_handler state 0
<debug> app: nrf_fstorage_sdh_state_handler state 1
<debug> nrf_dfu_ble: Configuring BLE stack.
<debug> nrf_dfu_ble: Enabling the BLE stack.
<debug> nrf_dfu_ble: No advertising name found
<debug> nrf_dfu_ble: Using default advertising name
<debug> nrf_dfu_ble: Advertising...
<debug> nrf_dfu_ble: BLE DFU transport initialized.
<debug> nrf_dfu_flash: Initializing nrf_fstorage_sd backend.
<debug> app: Enter main loop
<debug> nrf_dfu_ble: Connected
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_CONN_PARAM_UPDATE
<debug> nrf_dfu_ble: max_conn_interval: 12
<debug> nrf_dfu_ble: min_conn_interval: 12
<debug> nrf_dfu_ble: slave_latency: 0
<debug> nrf_dfu_ble: conn_sup_timeout: 600
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_CONN_PARAM_UPDATE
<debug> nrf_dfu_ble: max_conn_interval: 6
<debug> nrf_dfu_ble: min_conn_interval: 6
<debug> nrf_dfu_ble: slave_latency: 0
<debug> nrf_dfu_ble: conn_sup_timeout: 500
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_CONN_PARAM_UPDATE
<debug> nrf_dfu_ble: max_conn_interval: 12
<debug> nrf_dfu_ble: min_conn_interval: 12
<debug> nrf_dfu_ble: slave_latency: 0
<debug> nrf_dfu_ble: conn_sup_timeout: 600
<debug> nrf_dfu_ble: Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (request: 517, reply: 247).
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST.
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_DATA_LENGTH_UPDATE (251, max_rx_time 2120).
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: CMD req
<debug> nrf_dfu_req_handler: nrf_dfu_command_req() REQ : 6
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (command)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Set receipt notif
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> app: Shutting down transports (found: 1)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: CMD req
<debug> nrf_dfu_req_handler: nrf_dfu_command_req() REQ : 1
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (command)
<debug> app: timer_stop (0x200059A0)
<debug> app: timer_activate (0x200059A0)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x200076FC acquired, len 141 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: CMD req
<debug> nrf_dfu_req_handler: nrf_dfu_command_req() REQ : 8
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (command)
<debug> nrf_dfu_ble: Freeing buffer 0x200076FC
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: CMD req
<debug> nrf_dfu_req_handler: nrf_dfu_command_req() REQ : 3
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (command)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: CMD req
<debug> nrf_dfu_req_handler: nrf_dfu_command_req() REQ : 4
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (command)
<debug> nrf_dfu_validation: PB: Init packet data len: 64
<info> nrf_dfu_validation: Signature required. Checking signature.
<info> nrf_dfu_validation: Calculating hash (len: 64)
<info> nrf_dfu_validation: Verify signature
<info> nrf_dfu_validation: Image verified
<debug> app: Enter nrf_dfu_cache_prepare()
<debug> app: required_size: 0x2D598.
<debug> app: single_bank: false.
<debug> app: keep_app: false.
<debug> app: keep_softdevice: true.
<debug> app: SD_PRESENT: true.
<debug> app: Bank contents:
<debug> app: Bank 0 code: 0x00: Size: 0x0
<debug> app: Bank 1 code: 0x00: Size: 0x0
<debug> app: pass: 0.
<debug> app: cache_address: 0x27000.
<debug> app: cache_too_small: false.
<debug> app: keep_firmware: false.
<debug> app: delete_more: false.
<debug> nrf_dfu_validation: Write address set to 0x00027000
<debug> nrf_dfu_settings: Writing settings...
<debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 0
<debug> app: sd erase
<debug> app: queue_start() queue_running : 0, paused : 0
<debug> app: SD Erase page address : 0xFF000
<debug> app: Que Excute code : 1, rc : 1
<debug> app: Queue Excute sd_enabled : 1
<debug> app: queue process error  0x1
<debug> nrf_dfu_flash: dfu_fstorage_evt_handler()
<debug> nrf_dfu_flash: Flash erase failed (0x3): addr=0x000FF000, len=0x1 bytes, pending 0
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20008798, len=896 bytes), queue usage: 1
<debug> app: sd Write
<debug> app: queue_start() queue_running : 0, paused : 0
<debug> app: Que Excute code : 0, rc : 0
<debug> app: Queue Excute sd_enabled : 1
<info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
<debug> nrf_dfu_settings: Writing settings...
<debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 2
<debug> app: sd erase
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x20008B18, len=896 bytes), queue usage: 3
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Writing valid init command to flash.
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Set receipt notif
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_select_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (data)
<debug> nrf_dfu_req_handler: crc = 0x0, offset = 0x0, max_size = 0x1000
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_create_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00027000, len=1 pages), queue usage: 4
<debug> app: sd erase
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Creating object with size: 4096. Offset: 0x00000000, CRC: 0x00000000
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x200076FC acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0x0
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027000, src=0x200076FC, len=244 bytes), queue usage: 5
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x200077F0 acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xF4
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000270F4, src=0x200077F0, len=244 bytes), queue usage: 6
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x200078E4 acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000271E8, src=0x200078E4, len=244 bytes), queue usage: 7
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x200079D8 acquired, len 244 (244)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000272DC, src=0x200079D8, len=244 bytes), queue usage: 8
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000273D0, src=0x20007ACC, len=244 bytes), queue usage: 9
<debug> app: sd Write
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> app: sd Write
<debug> app: queue_start() queue_running : 1, paused : 0
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x20007DA8 acquired, len 244 (244)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x20007E9C acquired, len 244 (244)
<debug> nrf_dfu_ble: Buffer 0x20007F90 acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
Logs dropped (1)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027988, src=0x20008084, len=244 bytes), queue usage: 15
Logs dropped (1)
<debug> app: sd Write
Logs dropped (2)
<debug> app: queue_start() queue_running : 1, paused : 0
Logs dropped (2)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x20008178 acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
Logs dropped (2)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xA7C
Logs dropped (1)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027A7C, src=0x20008178, len=244 bytes), queue usage: 16
<debug> nrf_dfu_ble: Buffer 0x2000826C acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
Logs dropped (2)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xB70
Logs dropped (1)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027B70, src=0x2000826C, len=244 bytes), queue usage: 17
Logs dropped (1)
<debug> app: sd Write
Logs dropped (2)
<warning> nrf_dfu_flash: nrf_fstorage_write() failed with error 0x4.
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
Logs dropped (1)
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xB70
Logs dropped (3)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027B70, src=0x2000826C, len=244 bytes), queue usage: 17
Logs dropped (1)
<debug> app: sd Write
Logs dropped (2)
<warning> nrf_dfu_flash: nrf_fstorage_write() failed with error 0x4.
<debug> nrf_dfu_req_handler: Write flash error
Logs dropped (1)
<debug> nrf_dfu_ble: Freeing buffer 0x2000826C
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x2000826C acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
Logs dropped (2)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xB70
Logs dropped (3)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027B70, src=0x2000826C, len=244 bytes), queue usage: 17
Logs dropped (1)
<debug> app: sd Write
Logs dropped (1)
<warning> nrf_dfu_flash: nrf_fstorage_write() failed with error 0x4.
<debug> nrf_dfu_req_handler: Write flash error
<debug> nrf_dfu_ble: Freeing buffer 0x2000826C
Logs dropped (2)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x2000826C acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
Logs dropped (1)
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
Logs dropped (1)
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
Logs dropped (2)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xB70
Logs dropped (2)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027B70, src=0x2000826C, len=244 bytes), queue usage: 17
Logs dropped (1)
<debug> app: sd Write
<warning> nrf_dfu_flash: nrf_fstorage_write() failed with error 0x4.
Logs dropped (1)
<debug> nrf_dfu_req_handler: Write flash error
Logs dropped (1)
<debug> nrf_dfu_ble: Freeing buffer 0x2000826C
Logs dropped (1)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x2000826C acquired, len 192 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
Logs dropped (1)
<debug> nrf_dfu_req_handler: DFU req
Logs dropped (1)
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
Logs dropped (1)
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
Logs dropped (2)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xB70
Logs dropped (1)
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027B70, src=0x2000826C, len=192 bytes), queue usage: 17
<debug> app: sd Write
Logs dropped (5)
<warning> nrf_dfu_flash: nrf_fstorage_write() failed with error 0x4.
<debug> nrf_dfu_req_handler: Write flash error
Logs dropped (3)
<debug> nrf_dfu_ble: Freeing buffer 0x2000826C
Logs dropped (1)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_crc_request
Logs dropped (1)
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
Logs dropped (2)
<debug> nrf_dfu_req_handler: Offset:2928, CRC:0xCCAD3863
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Set receipt notif
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_RECEIPT_NOTIF_SET
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_ble: Buffer 0x2000826C acquired, len 244 (244)
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_write_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
<debug> nrf_dfu_req_handler: Start address : 0x27000, address offset 0xB70
<debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00027B70, src=0x2000826C, len=244 bytes), queue usage: 17
<debug> app: sd Write
<warning> nrf_dfu_flash: nrf_fstorage_write() failed with error 0x4.
Logs dropped (2)
<debug> nrf_dfu_req_handler: Write flash error
Logs dropped (3)
<debug> nrf_dfu_ble: Freeing buffer 0x2000826C
Logs dropped (3)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_crc_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
Logs dropped (2)
<debug> nrf_dfu_req_handler: Offset:2928, CRC:0xCCAD3863
Logs dropped (1)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
<debug> nrf_dfu_req_handler: nrf_dfu_req_handler_req_process()
<debug> nrf_dfu_req_handler: nrf_dfu_obj_op()
<debug> nrf_dfu_req_handler: DFU req
<debug> nrf_dfu_req_handler: Req on_data_obj_create_request
<debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
<debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00027000, len=1 pages), queue usage: 17
Logs dropped (2)
<debug> app: sd erase
Logs dropped (2)
<warning> nrf_dfu_flash: nrf_fstorage_erase() failed with error 0x4.
Logs dropped (2)
<error> nrf_dfu_req_handler: Erase operation failed
Logs dropped (1)
<debug> nrf_dfu_req_handler: Request handling complete. Result: 0x5
Logs dropped (1)
<warning> nrf_dfu_ble: DFU request 1 failed with error: 0x5
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_CONN_PARAM_UPDATE
<debug> nrf_dfu_ble: max_conn_interval: 6
<debug> nrf_dfu_ble: min_conn_interval: 6
<debug> nrf_dfu_ble: slave_latency: 0
<debug> nrf_dfu_ble: conn_sup_timeout: 500
<debug> nrf_dfu_ble: Received BLE_GAP_EVT_CONN_PARAM_UPDATE
<debug> nrf_dfu_ble: max_conn_interval: 12
<debug> nrf_dfu_ble: min_conn_interval: 12
<debug> nrf_dfu_ble: slave_latency: 0
<debug> nrf_dfu_ble: conn_sup_timeout: 600

modified  nrf_fstorage_sd.c 

static uint32_t write_execute(nrf_fstorage_sd_op_t const * p_op)
{
    //uint32_t chunk_len;

    //chunk_len = MIN(p_op->write.len - p_op->write.offset, NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
    //chunk_len = MAX(1, chunk_len / m_flash_info.program_unit);

    ///* Cast to p_src to uint32_t to perform arithmetic. */
    //uint32_t       * p_dest = (uint32_t*)(p_op->write.dest + p_op->write.offset);
    //uint32_t const * p_src  = (uint32_t*)((uint32_t)p_op->write.p_src + p_op->write.offset);
    
    //return sd_flash_write(p_dest, p_src, chunk_len);

    uint32_t err_code;
    uint32_t chunk_len;

    chunk_len = MIN(p_op->write.len - p_op->write.offset, NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
    chunk_len = MAX(1, chunk_len / m_flash_info.program_unit);

    /* Cast to p_src to uint32_t to perform arithmetic. */
    uint32_t         p_dest = (p_op->write.dest + p_op->write.offset);
    uint32_t const * p_src  = (uint32_t*)((uint32_t)p_op->write.p_src + p_op->write.offset);
    
    err_code = nrfx_qspi_write(p_src, chunk_len, p_dest);

    return err_code;
}

static uint32_t erase_execute(nrf_fstorage_sd_op_t const * p_op)
{
    //NRF_LOG_DEBUG("Erase page number %d, progress %d", p_op->erase.page, p_op->erase.progress);

    //return sd_flash_page_erase(p_op->erase.page + p_op->erase.progress);        
    
    uint32_t err_code;
    uint32_t erase_start_addr = (p_op->erase.page + p_op->erase.progress) * 4096;  
       
    nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, erase_start_addr);    

    NRF_LOG_DEBUG("SD Erase page address : 0x%x", erase_start_addr);

    return err_code;
}

static ret_code_t read(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len)
{
    //memcpy(p_dest, (uint32_t*)src, len);
    
    //NRF_LOG_DEBUG("sd Read");

    //return NRF_SUCCESS;

    ret_code_t err_code;
    err_code = nrfx_qspi_read(p_dest, len, src);
    
    return err_code;
}

Parents
  • Hi,

    I see the log and your modified nrf_fstorage_sd.c but I am not sure how you use this and how you intend it to work, nor how it fails. Can you elaborate by providing more overview and also details about this?

  • hello Einar, I'm want to write external flash instead of internal flash using BLE DFU.
    when the download is complete and I will copy it to internal flash memory. but it stop while receiving data over BLE.


    I think that 'nrf_fstorage_sys_evt_handler()' was not called because a problem occurred after using 'erase_execute', 'write_execute'


    Is there a way to call the 'nrf_fstorage_sys_evt_handler()'?

    attach modified nrf_fstorage_sd.c  

    /**
     * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    #include "sdk_common.h"
    
    #if NRF_MODULE_ENABLED(NRF_FSTORAGE)
    
    #include "nrf_fstorage_sd.h"
    #include <stdint.h>
    #include <string.h>
    #include <stdbool.h>
    #include "nordic_common.h"
    #include "nrf_soc.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_atomic.h"
    #include "nrf_atfifo.h"
    #include "app_util_platform.h"
    
    #include "nrf_log.h"
    
    #include "nrfx_qspi.h"
    #if (NRF_FSTORAGE_SD_MAX_WRITE_SIZE % 4)
    #error NRF_FSTORAGE_SD_MAX_WRITE_SIZE must be a multiple of the word size.
    #endif
    
    
    /**@brief   fstorage operation codes. */
    typedef enum
    {
        NRF_FSTORAGE_OP_WRITE,  //!< Write bytes to flash.
        NRF_FSTORAGE_OP_ERASE   //!< Erase flash pages.
    } nrf_fstorage_sd_opcode_t;
    
    ANON_UNIONS_ENABLE;
    /**@brief   fstorage operation queue element. */
    typedef struct
    {
        nrf_fstorage_t           const * p_fs;     //!< The fstorage instance that requested the operation.
        nrf_fstorage_sd_opcode_t         op_code;  //!< Requested operation.
        void                           * p_param;  //!< User-defined parameter passed to the event handler.
        union
        {
            struct
            {
                void     const * p_src;     //!< Data to be written to flash.
                uint32_t         dest;      //!< Destination of the data in flash.
                uint32_t         len;       //!< Length of the data to be written (in bytes).
                uint32_t         offset;    //!< Write offset.
            } write;
            struct
            {
                uint32_t page;              //!< Physical page number.
                uint32_t progress;          //!< Number of pages erased.
                uint32_t pages_to_erase;    //!< Total number of pages to erase.
            } erase;
        };
    } nrf_fstorage_sd_op_t;
    ANON_UNIONS_DISABLE;
    
    typedef enum
    {
        NRF_FSTORAGE_STATE_IDLE,            //!< No operations requested to the SoftDevice.
        NRF_FSTORAGE_STATE_OP_PENDING,      //!< A non-fstorage operation is pending.
        NRF_FSTORAGE_STATE_OP_EXECUTING,    //!< An fstorage operation is executing.
    } nrf_fstorage_sd_state_t;
    
    /**@brief   Internal state. */
    typedef struct
    {
        nrf_atomic_flag_t       initialized;    //!< fstorage is initalized.
        nrf_atomic_flag_t       queue_running;  //!< The queue is running.
                                                /** Prevent API calls from entering queue_process(). */
        nrf_fstorage_sd_state_t state;          //!< Internal fstorage state.
        uint32_t                retries;        //!< Number of times an operation has been retried on timeout.
        bool                    sd_enabled;     //!< The SoftDevice is enabled.
        bool                    paused;         //!< A SoftDevice state change is impending.
                                                /** Do not load a new operation when the last one completes. */
    } nrf_fstorage_sd_work_t;
    
    
    void nrf_fstorage_sys_evt_handler(uint32_t, void *);
    bool nrf_fstorage_sdh_req_handler(nrf_sdh_req_evt_t, void *);
    void nrf_fstorage_sdh_state_handler(nrf_sdh_state_evt_t, void *);
    
    
    /* Flash device information. */
    static nrf_fstorage_info_t m_flash_info =
    {
    #if   defined(NRF51)
        .erase_unit   = 1024,
    #elif defined(NRF52_SERIES)
        .erase_unit   = 4096,
    #endif
        .program_unit = 4,
        .rmap         = true,
        .wmap         = false,
    };
    
    /* Queue of fstorage operations. */
    NRF_ATFIFO_DEF(m_fifo, nrf_fstorage_sd_op_t, NRF_FSTORAGE_SD_QUEUE_SIZE);
    
    /* Define a nrf_sdh_soc event observer to receive SoftDevice system events. */
    NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, nrf_fstorage_sys_evt_handler, NULL);
    
    /* nrf_sdh request observer. */
    NRF_SDH_REQUEST_OBSERVER(m_req_obs, 0) =
    {
        .handler = nrf_fstorage_sdh_req_handler,
    };
    
    /* nrf_sdh state observer. */
    NRF_SDH_STATE_OBSERVER(m_state_obs, 0) =
    {
        .handler = nrf_fstorage_sdh_state_handler,
    };
    
    static nrf_fstorage_sd_work_t   m_flags;        /* Internal status. */
    static nrf_fstorage_sd_op_t   * m_p_cur_op;     /* The current operation being executed. */
    static nrf_atfifo_item_get_t    m_iget_ctx;     /* Context for nrf_atfifo_item_get() and nrf_atfifo_item_free(). */
    
    
    /* Send events to the application. */
    static void event_send(nrf_fstorage_sd_op_t const * p_op, ret_code_t result)
    {
        if (p_op->p_fs->evt_handler == NULL)
        {
            /* Nothing to do. */
            return;
        }
    
        nrf_fstorage_evt_t evt =
        {
            .result  = result,
            .p_param = p_op->p_param,
        };
    
        switch (p_op->op_code)
        {
            case NRF_FSTORAGE_OP_WRITE:
                evt.id    = NRF_FSTORAGE_EVT_WRITE_RESULT;
                evt.addr  = p_op->write.dest;
                evt.p_src = p_op->write.p_src;
                evt.len   = p_op->write.len;
                break;
    
            case NRF_FSTORAGE_OP_ERASE:
                evt.id   = NRF_FSTORAGE_EVT_ERASE_RESULT;
                evt.addr = (p_op->erase.page * m_flash_info.erase_unit);
                evt.len  = p_op->erase.pages_to_erase;
                break;
    
            default:
                /* Should not happen. */
                break;
        }
    
        p_op->p_fs->evt_handler(&evt);
    }
    
    
    /* Write to flash. */
    static uint32_t write_execute(nrf_fstorage_sd_op_t const * p_op)
    {
        //uint32_t chunk_len;
    
        //chunk_len = MIN(p_op->write.len - p_op->write.offset, NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
        //chunk_len = MAX(1, chunk_len / m_flash_info.program_unit);
    
        ///* Cast to p_src to uint32_t to perform arithmetic. */
        //uint32_t       * p_dest = (uint32_t*)(p_op->write.dest + p_op->write.offset);
        //uint32_t const * p_src  = (uint32_t*)((uint32_t)p_op->write.p_src + p_op->write.offset);
        
        //return sd_flash_write(p_dest, p_src, chunk_len);
    
        uint32_t err_code;
        uint32_t chunk_len;
    
        chunk_len = MIN(p_op->write.len - p_op->write.offset, NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
        chunk_len = MAX(1, chunk_len / m_flash_info.program_unit);
    
        /* Cast to p_src to uint32_t to perform arithmetic. */
        uint32_t         p_dest = (p_op->write.dest + p_op->write.offset);
        uint32_t const * p_src  = (uint32_t*)((uint32_t)p_op->write.p_src + p_op->write.offset);
        
        err_code = nrfx_qspi_write(p_src, chunk_len, p_dest);
    
        sd_flash_write(NULL, NULL, chunk_len);
    
        return err_code;
    }
    
    
    /* Erase flash page(s). */
    static uint32_t erase_execute(nrf_fstorage_sd_op_t const * p_op)
    {
        //NRF_LOG_DEBUG("Erase page number %d, progress %d", p_op->erase.page, p_op->erase.progress);
    
        //return sd_flash_page_erase(p_op->erase.page + p_op->erase.progress);        
        
        uint32_t err_code;
        uint32_t erase_start_addr = (p_op->erase.page + p_op->erase.progress) * 4096;  
           
        nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, erase_start_addr);    
        
        NRF_LOG_DEBUG("SD Erase page address : 0x%x", erase_start_addr);
    
        return err_code;
    }
    
    
    /* Free the current queue element. */
    static void queue_free(void)
    {
        (void) nrf_atfifo_item_free(m_fifo, &m_iget_ctx);
    }
    
    
    /* Load a new operation from the queue. */
    static bool queue_load_next(void)
    {
        m_p_cur_op = nrf_atfifo_item_get(m_fifo, &m_iget_ctx);
    
        return (m_p_cur_op != NULL);
    }
    
    
    /* Execute an operation in the queue. */
    static void queue_process(void)
    {
        uint32_t rc;
    
        if (m_flags.state == NRF_FSTORAGE_STATE_IDLE)
        {
            if (!queue_load_next())
            {
                /* No more operations, nothing to do. */
                m_flags.queue_running = false;
                return;
            }
        }
    
        m_flags.state = NRF_FSTORAGE_STATE_OP_EXECUTING;
        
        switch (m_p_cur_op->op_code)
        {
            case NRF_FSTORAGE_OP_WRITE:            
                rc = write_execute(m_p_cur_op);
                break;
    
            case NRF_FSTORAGE_OP_ERASE:
                rc = erase_execute(m_p_cur_op);
                break;
    
             default:
                rc = NRF_ERROR_INTERNAL;
                break;
        }
        
        NRF_LOG_DEBUG("Que Excute code : %d, rc : %d", m_p_cur_op->op_code,rc);    
        NRF_LOG_DEBUG("Queue Excute sd_enabled : %d", m_flags.sd_enabled);
    
        if(rc != 0)
          NRF_LOG_DEBUG("queue process error  0x%x", rc);
        
    
        switch (rc)
        {
            case NRF_SUCCESS:
            {
                /* The operation was accepted by the SoftDevice.
                 * If the SoftDevice is enabled, wait for a system event. Otherwise,
                 * the SoftDevice call is synchronous and will not send an event so we simulate it. */
                if (!m_flags.sd_enabled)
                {
                    nrf_fstorage_sys_evt_handler(NRF_EVT_FLASH_OPERATION_SUCCESS, NULL);
                }
            } break;
    
            case NRF_ERROR_BUSY:
            {
                /* The SoftDevice is executing a flash operation that was not requested by fstorage.
                 * Stop processing the queue until a system event is received. */
                m_flags.state = NRF_FSTORAGE_STATE_OP_PENDING;
            } break;
    
            default:
            {
                /* An error has occurred. We cannot proceed further with this operation. */
                event_send(m_p_cur_op, NRF_ERROR_INTERNAL);
                /* Reset the internal state so we can accept other operations. */
                m_flags.state         = NRF_FSTORAGE_STATE_IDLE;
                m_flags.queue_running = false;
                /* Free the current queue element. */
                queue_free();
            } break;
        }
    }
    
    
    /* Start processing the queue if it is not running and fstorage is not paused. */
    static void queue_start(void)
    {
        NRF_LOG_DEBUG("queue_start() queue_running : %d, paused : %d", m_flags.queue_running, m_flags.paused);
        if (   (!nrf_atomic_flag_set_fetch(&m_flags.queue_running))
            && (!m_flags.paused))
        {
            queue_process();
        }
    }
    
    
    /* Flash operation success callback. Keeps track of the progress of an operation. */
    static bool on_operation_success(nrf_fstorage_sd_op_t * const p_op)
    {
        /* Reset the retry counter on success. */
        m_flags.retries = 0;
    
        switch (p_op->op_code)
        {
            case NRF_FSTORAGE_OP_WRITE:
            {
                /* Update the offset only if the operation is successful
                 * so that it can be retried in case it times out. */
                uint32_t const chunk_len = MIN(p_op->write.len - p_op->write.offset,
                                               NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
    
                p_op->write.offset += chunk_len;
    
                if (p_op->write.offset == p_op->write.len)
                {
                    return true;
                }
            } break;
    
            case NRF_FSTORAGE_OP_ERASE:
            {
                p_op->erase.progress++;
    
                if (p_op->erase.progress == p_op->erase.pages_to_erase)
                {
                    return true;
                }
            } break;
    
            default:
                /* Should not happen. */
                break;
        }
    
        return false;
    }
    
    
    /* Flash operation failure callback. */
    static bool on_operation_failure(nrf_fstorage_sd_op_t const * p_op)
    {
        UNUSED_PARAMETER(p_op);
    
        m_flags.retries++;
    
        if (m_flags.retries > NRF_FSTORAGE_SD_MAX_RETRIES)
        {
            /* Maximum amount of retries reached. Give up. */
            m_flags.retries = 0;
            return true;
        }
    
        return false;
    }
    
    
    static ret_code_t init(nrf_fstorage_t * p_fs, void * p_param)
    {
        UNUSED_PARAMETER(p_param);
    
        p_fs->p_flash_info = &m_flash_info;
    
        if (!nrf_atomic_flag_set_fetch(&m_flags.initialized))
        {
    #if NRF_SDH_ENABLED
            m_flags.sd_enabled = nrf_sdh_is_enabled();
    #endif
            (void) NRF_ATFIFO_INIT(m_fifo);
        }
    
        return NRF_SUCCESS;
    }
    
    
    static ret_code_t uninit(nrf_fstorage_t * p_fs, void * p_param)
    {
        UNUSED_PARAMETER(p_fs);
        UNUSED_PARAMETER(p_param);
    
        /* The state is re-initialized upon init().
         * The common uninitialization code is run by the caller. */
    
        memset(&m_flags, 0x00, sizeof(m_flags));
    
        (void) nrf_atfifo_clear(m_fifo);
    
        return NRF_SUCCESS;
    }
    
    
    static ret_code_t write(nrf_fstorage_t const * p_fs,
                            uint32_t               dest,
                            void           const * p_src,
                            uint32_t               len,
                            void                 * p_param)
    {
        nrf_fstorage_sd_op_t  * p_op;
        nrf_atfifo_item_put_t   iput_ctx;
        
        NRF_LOG_DEBUG("sd Write");
        /* Get a free queue element. */
        p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
    
        if (p_op == NULL)
        {
            return NRF_ERROR_NO_MEM;
        }
    
        /* Initialize the operation. */
        memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
    
        p_op->op_code     = NRF_FSTORAGE_OP_WRITE;
        p_op->p_fs        = p_fs;
        p_op->p_param     = p_param;
        p_op->write.dest  = dest;
        p_op->write.p_src = p_src;
        p_op->write.len   = len;
    
        /* Put the operation on the queue. */
        (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
    
        queue_start();
    
        return NRF_SUCCESS;
    }
    
    
    static ret_code_t read(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len)
    {
        //memcpy(p_dest, (uint32_t*)src, len);
        
        //NRF_LOG_DEBUG("sd Read");
    
        //return NRF_SUCCESS;
    
        ret_code_t err_code;
        err_code = nrfx_qspi_read(p_dest, len, src);
        
        return err_code;
    }
    
    
    static ret_code_t erase(nrf_fstorage_t const * p_fs,
                            uint32_t               page_addr,
                            uint32_t               len,
                            void                 * p_param)
    {
        nrf_fstorage_sd_op_t  * p_op;
        nrf_atfifo_item_put_t   iput_ctx;
    
        /* Get a free queue element. */
        p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
        
        NRF_LOG_DEBUG("sd erase");
        if (p_op == NULL)
        {
            return NRF_ERROR_NO_MEM;
        }
    
        /* Initialize the operation. */
        memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
    
        p_op->op_code              = NRF_FSTORAGE_OP_ERASE;
        p_op->p_fs                 = p_fs;
        p_op->p_param              = p_param;
        p_op->erase.page           = (page_addr / m_flash_info.erase_unit);
        p_op->erase.pages_to_erase = len;
    
        /* Put the operation on the queue. */
        (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
    
        queue_start();
    
        return NRF_SUCCESS;
    }
    
    
    static uint8_t const * rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
    {
        UNUSED_PARAMETER(p_fs);
    
        return (uint8_t*)addr;
    }
    
    
    static uint8_t * wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
    {
        UNUSED_PARAMETER(p_fs);
        UNUSED_PARAMETER(addr);
    
        /* Not supported. */
        return NULL;
    }
    
    
    static bool is_busy(nrf_fstorage_t const * p_fs)
    {
        UNUSED_PARAMETER(p_fs);
    
        return (m_flags.state != NRF_FSTORAGE_STATE_IDLE);
    }
    
    
    void nrf_fstorage_sys_evt_handler(uint32_t sys_evt, void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        if (   (sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS)
            && (sys_evt != NRF_EVT_FLASH_OPERATION_ERROR))
        {
            /* Ignore any non-flash events. */
            return;
        }
    
        NRF_LOG_DEBUG("nrf_fstorage_sys_evt_handler() flag state %d, paused %d, sys_evt %d ",m_flags.state, m_flags.paused, sys_evt);
    
        switch (m_flags.state)
        {
            case NRF_FSTORAGE_STATE_IDLE:
                /* Ignore flash events if no flash operation was requested. */
                return;
    
            case NRF_FSTORAGE_STATE_OP_PENDING:
                /* The SoftDevice has completed a flash operation that was not requested by fstorage.
                 * It should be possible to request an operation now.
                 * Process the queue at the end of this function. */
                break;
    
            case NRF_FSTORAGE_STATE_OP_EXECUTING:
            {
                /* Handle the result of a flash operation initiated by this module. */
                bool operation_finished = false;
    
                switch (sys_evt)
                {
                    case NRF_EVT_FLASH_OPERATION_SUCCESS:
                        operation_finished = on_operation_success(m_p_cur_op);
                        break;
    
                    case NRF_EVT_FLASH_OPERATION_ERROR:
                        operation_finished = on_operation_failure(m_p_cur_op);
                        break;
    
                    default:
                        break;
                }
    
                if (operation_finished)
                {
                    /* The operation has finished. Change state to NRF_FSTORAGE_STATE_IDLE
                     * so that queue_process() will fetch a new operation from the queue. */
                    m_flags.state = NRF_FSTORAGE_STATE_IDLE;
    
                    event_send(m_p_cur_op, (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) ?
                                            NRF_SUCCESS : NRF_ERROR_TIMEOUT);
                    
                    NRF_LOG_DEBUG("operation_finished  m_flags.state %d",  m_flags.state);
                    /* Free the queue element after sending out the event to prevent API calls made
                     * in the event context to queue elements indefinitely, without this function
                     * ever returning in case the SoftDevice calls are synchronous. */
                    queue_free();
                }
            } break;
        }
    
        if (!m_flags.paused)
        {
            queue_process();
        }
        else
        {
            /* A flash operation has completed. Let the SoftDevice change state. */
            (void) nrf_sdh_request_continue();
        }
    }
    
    
    bool nrf_fstorage_sdh_req_handler(nrf_sdh_req_evt_t req, void * p_context)
    {
        UNUSED_PARAMETER(req);
        UNUSED_PARAMETER(p_context);
    
        m_flags.paused = true;  
        
        NRF_LOG_DEBUG("nrf_fstorage_sdh_req_handler");
        /* If there are any operations ongoing, pause the SoftDevice state change. */
        return (m_flags.state == NRF_FSTORAGE_STATE_IDLE);
    }
    
    
    void nrf_fstorage_sdh_state_handler(nrf_sdh_state_evt_t state, void * p_context)
    {
        UNUSED_PARAMETER(p_context);
        
        NRF_LOG_DEBUG("nrf_fstorage_sdh_state_handler state %d", state);
        if (    (state == NRF_SDH_EVT_STATE_ENABLED)
            ||  (state == NRF_SDH_EVT_STATE_DISABLED))
        {
            m_flags.paused     = false;
            m_flags.sd_enabled = (state == NRF_SDH_EVT_STATE_ENABLED);
    
            /* Execute any operations still in the queue. */
            queue_process();
        }
    }
    
    
    /* Exported API implementation. */
    nrf_fstorage_api_t nrf_fstorage_sd =
    {
        .init    = init,
        .uninit  = uninit,
        .read    = read,
        .write   = write,
        .erase   = erase,                           
        .rmap    = rmap,
        .wmap    = wmap,
        .is_busy = is_busy
    };
    
    
    #endif // NRF_FSTORAGE_ENABLED
    
    
    

  • Hi,

    nrf_fstorage_sys_evt_handler() is registered as an observer for SoC event from the SoftDevice, so whenever there is a new SoC event, nrf_fstorage_sys_evt_handler() will be called. When writing to the internal flash using the SoftDevice API you will get a SoC event whenever a operation has completed. When writing to external flash this does not happen as that does not generate a SoftDevice SoC event. In stead, you would probably want to use QSPI driver events to know that a write has completed (NRFX_QSPI_EVENT_DONE).

Reply
  • Hi,

    nrf_fstorage_sys_evt_handler() is registered as an observer for SoC event from the SoftDevice, so whenever there is a new SoC event, nrf_fstorage_sys_evt_handler() will be called. When writing to the internal flash using the SoftDevice API you will get a SoC event whenever a operation has completed. When writing to external flash this does not happen as that does not generate a SoftDevice SoC event. In stead, you would probably want to use QSPI driver events to know that a write has completed (NRFX_QSPI_EVENT_DONE).

Children
Related