drivers/flash/soc_flash_nrf: introduce synchronization api usage
Rework ticker synchronization using newly introduced radio synchronization API. In kconfig synchronization using ll ticker become choice option. If CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE is enabled the erase timing is changed so intervals become similar to slots duration. Previously interval was always ~90 ms, which looks like it was kept so disproportional by oversight while the partial erase was introduced. Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
This commit is contained in:
parent
4c2432fdd4
commit
affbafac26
|
@ -7,6 +7,7 @@ zephyr_library_sources_ifdef(CONFIG_NORDIC_QSPI_NOR nrf_qspi_nor.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_FLASH_SIMULATOR flash_simulator.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SPI_FLASH_AT45 spi_flash_at45.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF soc_flash_nrf.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF_RADIO_SYNC soc_flash_nrf_ticker.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_MCUX soc_flash_mcux.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_FLASH_PAGE_LAYOUT flash_page_layout.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE flash_handlers.c)
|
||||
|
|
|
@ -20,12 +20,25 @@ menuconfig SOC_FLASH_NRF
|
|||
|
||||
if SOC_FLASH_NRF
|
||||
|
||||
choice
|
||||
prompt "Nordic nRFx flash driver synchronization"
|
||||
default SOC_FLASH_NRF_RADIO_SYNC if BT_CTLR
|
||||
default SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
help
|
||||
synchronization between flash memory driver and radio.
|
||||
|
||||
config SOC_FLASH_NRF_RADIO_SYNC
|
||||
bool "Nordic nRFx flash driver synchronized with radio"
|
||||
default y
|
||||
depends on BT_CTLR
|
||||
help
|
||||
Enable synchronization between flash memory driver and radio.
|
||||
Enable synchronization between flash memory driver and radio using
|
||||
BLE LL controller ticker API.
|
||||
|
||||
config SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
bool "none"
|
||||
help
|
||||
disable synchronization between flash memory driver and radio.
|
||||
endchoice
|
||||
|
||||
config SOC_FLASH_NRF_PARTIAL_ERASE
|
||||
bool "Nordic nRFx flash driver partial erase"
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include <string.h>
|
||||
#include <nrfx_nvmc.h>
|
||||
|
||||
#include "soc_flash_nrf.h"
|
||||
|
||||
#if DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf51_flash_controller), okay)
|
||||
#define DT_DRV_COMPAT nordic_nrf51_flash_controller
|
||||
#elif DT_NODE_HAS_STATUS(DT_INST(0, nordic_nrf52_flash_controller), okay)
|
||||
|
@ -30,80 +32,21 @@
|
|||
|
||||
#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#include <sys/__assert.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include "controller/hal/ticker.h"
|
||||
#include "controller/ticker/ticker.h"
|
||||
#include "controller/include/ll.h"
|
||||
|
||||
#define FLASH_RADIO_ABORT_DELAY_US 1500
|
||||
#define FLASH_RADIO_WORK_DELAY_US 200
|
||||
|
||||
|
||||
#define FLASH_INTERVAL_ERASE (FLASH_RADIO_ABORT_DELAY_US + \
|
||||
FLASH_RADIO_WORK_DELAY_US + \
|
||||
FLASH_SLOT_ERASE)
|
||||
|
||||
#define FLASH_SLOT_WRITE (FLASH_INTERVAL_WRITE - \
|
||||
FLASH_RADIO_ABORT_DELAY_US - \
|
||||
FLASH_RADIO_WORK_DELAY_US)
|
||||
#define FLASH_INTERVAL_WRITE 7500
|
||||
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
#define FLASH_SLOT_WRITE 7500
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
|
||||
|
||||
/* The timeout is multiplied by 1.5 because switching tasks may take
|
||||
* significant portion of time.
|
||||
*/
|
||||
#define FLASH_TIMEOUT_MS ((FLASH_PAGE_ERASE_MAX_TIME_US) * \
|
||||
(FLASH_PAGE_MAX_CNT) / 1000 * 15 / 10)
|
||||
#define FLASH_SLOT_ERASE (MAX(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE_MS * 1000, \
|
||||
7500))
|
||||
#else
|
||||
|
||||
#define FLASH_TIMEOUT_MS ((FLASH_PAGE_ERASE_MAX_TIME_US) * \
|
||||
(FLASH_PAGE_MAX_CNT) / 1000)
|
||||
#define FLASH_SLOT_ERASE FLASH_PAGE_ERASE_MAX_TIME_US
|
||||
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */
|
||||
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
|
||||
#define FLASH_OP_DONE (0) /* 0 for compliance with the driver API. */
|
||||
#define FLASH_OP_ONGOING (-1)
|
||||
|
||||
struct flash_context {
|
||||
uint32_t data_addr; /* Address of data to write. */
|
||||
uint32_t flash_addr; /* Address of flash to write or erase. */
|
||||
uint32_t len; /* Size off data to write or erase [B]. */
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
uint8_t enable_time_limit; /* execution limited to timeslot. */
|
||||
uint32_t interval; /* timeslot interval. */
|
||||
uint32_t slot; /* timeslot length. */
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
|
||||
uint32_t flash_addr_next;
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */
|
||||
}; /*< Context type for f. @ref write_op @ref erase_op */
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
typedef int (*flash_op_handler_t) (void *context);
|
||||
|
||||
struct flash_op_desc {
|
||||
flash_op_handler_t handler;
|
||||
struct flash_context *context; /* [in,out] */
|
||||
int result;
|
||||
};
|
||||
|
||||
/* semaphore for synchronization of flash operations */
|
||||
static struct k_sem sem_sync;
|
||||
|
||||
static int write_op(void *context); /* instance of flash_op_handler_t */
|
||||
static int write_in_timeslice(off_t addr, const void *data, size_t len);
|
||||
|
||||
static int erase_op(void *context); /* instance of flash_op_handler_t */
|
||||
static int erase_in_timeslice(uint32_t addr, uint32_t size);
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
|
||||
static const struct flash_parameters flash_nrf_parameters = {
|
||||
#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS)
|
||||
|
@ -213,11 +156,11 @@ static int flash_nrf_write(const struct device *dev, off_t addr,
|
|||
|
||||
SYNC_LOCK();
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
if (ticker_is_initialized(0)) {
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
if (nrf_flash_sync_is_required()) {
|
||||
ret = write_in_timeslice(addr, data, len);
|
||||
} else
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
{
|
||||
ret = write(addr, data, len);
|
||||
}
|
||||
|
@ -256,11 +199,11 @@ static int flash_nrf_erase(const struct device *dev, off_t addr, size_t size)
|
|||
|
||||
SYNC_LOCK();
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
if (ticker_is_initialized(0)) {
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
if (nrf_flash_sync_is_required()) {
|
||||
ret = erase_in_timeslice(addr, size);
|
||||
} else
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
{
|
||||
ret = erase(addr, size);
|
||||
}
|
||||
|
@ -310,9 +253,9 @@ static int nrf_flash_init(const struct device *dev)
|
|||
{
|
||||
SYNC_INIT();
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
k_sem_init(&sem_sync, 0, 1);
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
nrf_flash_sync_init();
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
|
||||
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
|
||||
dev_layout.pages_count = nrfx_nvmc_flash_page_count_get();
|
||||
|
@ -326,147 +269,7 @@ DEVICE_AND_API_INIT(nrf_flash, DT_INST_LABEL(0), nrf_flash_init,
|
|||
NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
&flash_nrf_api);
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
|
||||
static inline int _ticker_stop(uint8_t inst_idx, uint8_t u_id, uint8_t tic_id)
|
||||
{
|
||||
int ret = ticker_stop(inst_idx, u_id, tic_id, NULL, NULL);
|
||||
|
||||
if (ret != TICKER_STATUS_SUCCESS &&
|
||||
ret != TICKER_STATUS_BUSY) {
|
||||
__ASSERT(0, "Failed to stop ticker.\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void time_slot_callback_work(uint32_t ticks_at_expire, uint32_t remainder,
|
||||
uint16_t lazy, void *context)
|
||||
{
|
||||
struct flash_op_desc *op_desc;
|
||||
uint8_t instance_index;
|
||||
uint8_t ticker_id;
|
||||
|
||||
__ASSERT(ll_radio_state_is_idle(),
|
||||
"Radio is on during flash operation.\n");
|
||||
|
||||
op_desc = context;
|
||||
if (op_desc->handler(op_desc->context) == FLASH_OP_DONE) {
|
||||
ll_timeslice_ticker_id_get(&instance_index, &ticker_id);
|
||||
|
||||
/* Stop the time slot ticker */
|
||||
_ticker_stop(instance_index, 0, ticker_id);
|
||||
|
||||
((struct flash_op_desc *)context)->result = 0;
|
||||
|
||||
/* notify thread that data is available */
|
||||
k_sem_give(&sem_sync);
|
||||
}
|
||||
}
|
||||
|
||||
static void time_slot_delay(uint32_t ticks_at_expire, uint32_t ticks_delay,
|
||||
ticker_timeout_func callback, void *context)
|
||||
{
|
||||
uint8_t instance_index;
|
||||
uint8_t ticker_id;
|
||||
int err;
|
||||
|
||||
ll_timeslice_ticker_id_get(&instance_index, &ticker_id);
|
||||
|
||||
/* start a secondary one-shot ticker after ticks_delay,
|
||||
* this will let any radio role to gracefully abort and release the
|
||||
* Radio h/w.
|
||||
*/
|
||||
err = ticker_start(instance_index, /* Radio instance ticker */
|
||||
0, /* user_id */
|
||||
(ticker_id + 1), /* ticker_id */
|
||||
ticks_at_expire, /* current tick */
|
||||
ticks_delay, /* one-shot delayed timeout */
|
||||
0, /* periodic timeout */
|
||||
0, /* periodic remainder */
|
||||
0, /* lazy, voluntary skips */
|
||||
0,
|
||||
callback, /* handler for executing radio abort or */
|
||||
/* flash work */
|
||||
context, /* the context for the flash operation */
|
||||
NULL, /* no op callback */
|
||||
NULL);
|
||||
|
||||
if (err != TICKER_STATUS_SUCCESS && err != TICKER_STATUS_BUSY) {
|
||||
((struct flash_op_desc *)context)->result = -ECANCELED;
|
||||
|
||||
/* abort flash timeslots */
|
||||
_ticker_stop(instance_index, 0, ticker_id);
|
||||
|
||||
/* notify thread that data is available */
|
||||
k_sem_give(&sem_sync);
|
||||
}
|
||||
}
|
||||
|
||||
static void time_slot_callback_abort(uint32_t ticks_at_expire, uint32_t remainder,
|
||||
uint16_t lazy, void *context)
|
||||
{
|
||||
ll_radio_state_abort();
|
||||
time_slot_delay(ticks_at_expire,
|
||||
HAL_TICKER_US_TO_TICKS(FLASH_RADIO_WORK_DELAY_US),
|
||||
time_slot_callback_work,
|
||||
context);
|
||||
}
|
||||
|
||||
static void time_slot_callback_prepare(uint32_t ticks_at_expire, uint32_t remainder,
|
||||
uint16_t lazy, void *context)
|
||||
{
|
||||
#if defined(CONFIG_BT_CTLR_LOW_LAT)
|
||||
time_slot_callback_abort(ticks_at_expire, remainder, lazy, context);
|
||||
#else /* !CONFIG_BT_CTLR_LOW_LAT */
|
||||
time_slot_delay(ticks_at_expire,
|
||||
HAL_TICKER_US_TO_TICKS(FLASH_RADIO_ABORT_DELAY_US),
|
||||
time_slot_callback_abort,
|
||||
context);
|
||||
#endif /* CONFIG_BT_CTLR_LOW_LAT */
|
||||
}
|
||||
|
||||
static int work_in_time_slice(struct flash_op_desc *p_flash_op_desc)
|
||||
{
|
||||
uint8_t instance_index;
|
||||
uint8_t ticker_id;
|
||||
int result;
|
||||
uint32_t err;
|
||||
struct flash_context *context = p_flash_op_desc->context;
|
||||
|
||||
ll_timeslice_ticker_id_get(&instance_index, &ticker_id);
|
||||
|
||||
err = ticker_start(instance_index,
|
||||
3, /* user id for thread mode */
|
||||
/* (MAYFLY_CALL_ID_PROGRAM) */
|
||||
ticker_id, /* flash ticker id */
|
||||
ticker_ticks_now_get(), /* current tick */
|
||||
0, /* first int. immediately */
|
||||
/* period */
|
||||
HAL_TICKER_US_TO_TICKS(context->interval),
|
||||
/* period remainder */
|
||||
HAL_TICKER_REMAINDER(context->interval),
|
||||
0, /* lazy, voluntary skips */
|
||||
HAL_TICKER_US_TO_TICKS(context->slot),
|
||||
time_slot_callback_prepare,
|
||||
p_flash_op_desc,
|
||||
NULL, /* no op callback */
|
||||
NULL);
|
||||
|
||||
if (err != TICKER_STATUS_SUCCESS && err != TICKER_STATUS_BUSY) {
|
||||
result = -ECANCELED;
|
||||
} else if (k_sem_take(&sem_sync, K_MSEC(FLASH_TIMEOUT_MS)) != 0) {
|
||||
/* Stop any scheduled jobs */
|
||||
_ticker_stop(instance_index, 3, ticker_id);
|
||||
|
||||
/* wait for operation's complete overrun*/
|
||||
result = -ETIMEDOUT;
|
||||
} else {
|
||||
result = p_flash_op_desc->result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
|
||||
static int erase_in_timeslice(uint32_t addr, uint32_t size)
|
||||
{
|
||||
|
@ -474,8 +277,6 @@ static int erase_in_timeslice(uint32_t addr, uint32_t size)
|
|||
.flash_addr = addr,
|
||||
.len = size,
|
||||
.enable_time_limit = 1, /* enable time limit */
|
||||
.interval = FLASH_INTERVAL_ERASE,
|
||||
.slot = FLASH_SLOT_ERASE,
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
|
||||
.flash_addr_next = addr
|
||||
#endif
|
||||
|
@ -486,7 +287,8 @@ static int erase_in_timeslice(uint32_t addr, uint32_t size)
|
|||
.context = &context
|
||||
};
|
||||
|
||||
return work_in_time_slice(&flash_op_desc);
|
||||
nrf_flash_sync_set_context(FLASH_SLOT_ERASE);
|
||||
return nrf_flash_sync_exe(&flash_op_desc);
|
||||
}
|
||||
|
||||
static int write_in_timeslice(off_t addr, const void *data, size_t len)
|
||||
|
@ -495,9 +297,7 @@ static int write_in_timeslice(off_t addr, const void *data, size_t len)
|
|||
.data_addr = (uint32_t) data,
|
||||
.flash_addr = addr,
|
||||
.len = len,
|
||||
.enable_time_limit = 1, /* enable time limit */
|
||||
.interval = FLASH_INTERVAL_WRITE,
|
||||
.slot = FLASH_SLOT_WRITE
|
||||
.enable_time_limit = 1 /* enable time limit */
|
||||
};
|
||||
|
||||
struct flash_op_desc flash_op_desc = {
|
||||
|
@ -505,25 +305,24 @@ static int write_in_timeslice(off_t addr, const void *data, size_t len)
|
|||
.context = &context
|
||||
};
|
||||
|
||||
return work_in_time_slice(&flash_op_desc);
|
||||
nrf_flash_sync_set_context(FLASH_SLOT_WRITE);
|
||||
return nrf_flash_sync_exe(&flash_op_desc);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
|
||||
static int erase_op(void *context)
|
||||
{
|
||||
uint32_t pg_size = nrfx_nvmc_flash_page_size_get();
|
||||
struct flash_context *e_ctx = context;
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
uint32_t ticks_begin = 0U;
|
||||
uint32_t ticks_diff;
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
uint32_t i = 0U;
|
||||
|
||||
if (e_ctx->enable_time_limit) {
|
||||
ticks_begin = ticker_ticks_now_get();
|
||||
nrf_flash_sync_get_timestamp_begin();
|
||||
}
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
|
||||
#ifdef CONFIG_SOC_FLASH_NRF_UICR
|
||||
if (e_ctx->flash_addr == (off_t)NRF_UICR) {
|
||||
|
@ -551,19 +350,16 @@ static int erase_op(void *context)
|
|||
e_ctx->flash_addr += pg_size;
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
i++;
|
||||
|
||||
if (e_ctx->enable_time_limit) {
|
||||
ticks_diff =
|
||||
ticker_ticks_diff_get(ticker_ticks_now_get(),
|
||||
ticks_begin);
|
||||
if (ticks_diff + ticks_diff/i >
|
||||
HAL_TICKER_US_TO_TICKS(e_ctx->slot)) {
|
||||
if (nrf_flash_sync_check_time_limit(i)) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
|
||||
} while (e_ctx->len > 0);
|
||||
|
||||
|
@ -581,15 +377,13 @@ static int write_op(void *context)
|
|||
{
|
||||
struct flash_context *w_ctx = context;
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
uint32_t ticks_begin = 0U;
|
||||
uint32_t ticks_diff;
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
uint32_t i = 1U;
|
||||
|
||||
if (w_ctx->enable_time_limit) {
|
||||
ticks_begin = ticker_ticks_now_get();
|
||||
nrf_flash_sync_get_timestamp_begin();
|
||||
}
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS)
|
||||
/* If not aligned, write unaligned beginning */
|
||||
if (!is_aligned_32(w_ctx->flash_addr)) {
|
||||
|
@ -605,18 +399,14 @@ static int write_op(void *context)
|
|||
|
||||
shift_write_context(count, w_ctx);
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
if (w_ctx->enable_time_limit) {
|
||||
ticks_diff =
|
||||
ticker_ticks_diff_get(ticker_ticks_now_get(),
|
||||
ticks_begin);
|
||||
if (ticks_diff * 2U >
|
||||
HAL_TICKER_US_TO_TICKS(w_ctx->slot)) {
|
||||
if (nrf_flash_sync_check_time_limit(1)) {
|
||||
nvmc_wait_ready();
|
||||
return FLASH_OP_ONGOING;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
}
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS */
|
||||
/* Write all the 4-byte aligned data */
|
||||
|
@ -626,20 +416,16 @@ static int write_op(void *context)
|
|||
|
||||
shift_write_context(sizeof(uint32_t), w_ctx);
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
i++;
|
||||
|
||||
if (w_ctx->enable_time_limit) {
|
||||
ticks_diff =
|
||||
ticker_ticks_diff_get(ticker_ticks_now_get(),
|
||||
ticks_begin);
|
||||
if (ticks_diff + ticks_diff/i >
|
||||
HAL_TICKER_US_TO_TICKS(w_ctx->slot)) {
|
||||
if (nrf_flash_sync_check_time_limit(i)) {
|
||||
nvmc_wait_ready();
|
||||
return FLASH_OP_ONGOING;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS)
|
||||
/* Write remaining unaligned data */
|
||||
|
@ -661,9 +447,9 @@ static int erase(uint32_t addr, uint32_t size)
|
|||
struct flash_context context = {
|
||||
.flash_addr = addr,
|
||||
.len = size,
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
.enable_time_limit = 0, /* disable time limit */
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
|
||||
.flash_addr_next = addr
|
||||
#endif
|
||||
|
@ -678,9 +464,9 @@ static int write(off_t addr, const void *data, size_t len)
|
|||
.data_addr = (uint32_t) data,
|
||||
.flash_addr = addr,
|
||||
.len = len,
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
.enable_time_limit = 0 /* disable time limit */
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
};
|
||||
|
||||
return write_op(&context);
|
||||
|
|
|
@ -16,18 +16,17 @@ struct flash_context {
|
|||
uint32_t data_addr; /* Address of data to write. */
|
||||
uint32_t flash_addr; /* Address of flash to write or erase. */
|
||||
uint32_t len; /* Size of data to write or erase [B]. */
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
uint8_t enable_time_limit; /* set execution limited to the execution
|
||||
* window.
|
||||
*/
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
|
||||
uint32_t flash_addr_next;
|
||||
#endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */
|
||||
}; /*< Context type for f. @ref write_op @ref erase_op */
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
|
||||
|
||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||
|
||||
#if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE)
|
||||
/* The timeout is multiplied by 1.5 because switching tasks may take
|
||||
|
@ -192,5 +191,5 @@ bool nrf_flash_sync_check_time_limit(uint32_t iteration);
|
|||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC) */
|
||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||
#endif /* !__SOC_FLASH_NRF_H__ */
|
||||
|
|
Loading…
Reference in a new issue