2020-07-18 00:22:43 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020 Nordic Semiconductor ASA
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SOC_FLASH_NRF_H__
|
|
|
|
#define __SOC_FLASH_NRF_H__
|
|
|
|
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/kernel.h>
|
2021-03-04 18:22:54 +08:00
|
|
|
#include <soc.h>
|
2020-07-18 00:22:43 +08:00
|
|
|
|
|
|
|
#define FLASH_OP_DONE (0) /* 0 for compliance with the driver API. */
|
2021-01-20 00:27:13 +08:00
|
|
|
#define FLASH_OP_ONGOING 1
|
2020-07-18 00:22:43 +08:00
|
|
|
|
|
|
|
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]. */
|
2020-07-19 00:08:33 +08:00
|
|
|
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
2020-07-18 00:22:43 +08:00
|
|
|
uint8_t enable_time_limit; /* set execution limited to the execution
|
|
|
|
* window.
|
|
|
|
*/
|
2020-07-19 00:08:33 +08:00
|
|
|
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
2020-07-18 00:22:43 +08:00
|
|
|
#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 */
|
|
|
|
|
2020-07-19 00:08:33 +08:00
|
|
|
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
2020-07-18 00:22:43 +08:00
|
|
|
|
2022-09-22 17:20:19 +08:00
|
|
|
/* The timeout is multiplied by CONFIG_SOC_FLASH_NRF_TIMEOUT_MULTIPLIER/10
|
|
|
|
* because switching tasks may take a significant portion of time.
|
2020-07-18 00:22:43 +08:00
|
|
|
*/
|
|
|
|
#define FLASH_TIMEOUT_MS ((FLASH_PAGE_ERASE_MAX_TIME_US) * \
|
2022-09-22 17:20:19 +08:00
|
|
|
(FLASH_PAGE_MAX_CNT) / 1000 * \
|
|
|
|
CONFIG_SOC_FLASH_NRF_TIMEOUT_MULTIPLIER / 10)
|
2020-07-18 00:22:43 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @defgroup nrf_flash_sync sync backend API
|
|
|
|
*
|
|
|
|
* API declared below contains prototypes of function which shall be
|
|
|
|
* implemented by the synchronization backend.
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback which executes the flash operation.
|
|
|
|
*
|
|
|
|
* @param context pointer to flash_context structure.
|
|
|
|
* @retval @ref FLASH_OP_DONE once operation was done, @ref FLASH_OP_ONGOING if
|
2021-01-20 00:27:13 +08:00
|
|
|
* operation needs more time for execution and a negative error code if
|
|
|
|
* operation was aborted.
|
2020-07-18 00:22:43 +08:00
|
|
|
*/
|
|
|
|
typedef int (*flash_op_handler_t) (void *context);
|
|
|
|
|
|
|
|
struct flash_op_desc {
|
|
|
|
flash_op_handler_t handler;
|
|
|
|
struct flash_context *context; /* [in,out] */
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronization backend driver initialization procedure.
|
|
|
|
*
|
|
|
|
* This will be run within flash driver initialization
|
|
|
|
*/
|
|
|
|
int nrf_flash_sync_init(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set synchronization context for synchronous operations.
|
|
|
|
*
|
|
|
|
* This function set backend's internal context for expected timing parameter.
|
|
|
|
*
|
|
|
|
* @param duration Duration of the execution window [us]
|
|
|
|
*/
|
|
|
|
void nrf_flash_sync_set_context(uint32_t duration);
|
|
|
|
|
|
|
|
/**
|
2022-02-24 20:00:55 +08:00
|
|
|
* Check if the operation need to be run synchronous with radio.
|
2020-07-18 00:22:43 +08:00
|
|
|
*
|
|
|
|
* @retval True if operation need to be run synchronously, otherwise False
|
|
|
|
*/
|
|
|
|
bool nrf_flash_sync_is_required(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute the flash operation synchronously along the radio operations.
|
|
|
|
*
|
2022-02-24 20:00:55 +08:00
|
|
|
* Function executes callbacks op_desc->handler() in execution windows according
|
2020-07-18 00:22:43 +08:00
|
|
|
* to timing settings requested by nrf_flash_sync_set_context().
|
|
|
|
* This routine need to be called the handler as many time as it returns
|
2022-02-24 20:00:55 +08:00
|
|
|
* FLASH_OP_ONGOING, however an operation timeout should be implemented.
|
2021-01-20 00:27:13 +08:00
|
|
|
* When the handler() returns FLASH_OP_DONE or an error code, no further
|
|
|
|
* execution windows are needed so function should return as the handler()
|
|
|
|
* finished its operation.
|
2020-07-18 00:22:43 +08:00
|
|
|
*
|
2021-01-20 00:27:13 +08:00
|
|
|
* @retval 0 if op_desc->handler() was executed and finished its operation
|
|
|
|
* successfully. Otherwise (handler returned error, timeout, couldn't schedule
|
|
|
|
* execution...) a negative error code.
|
2020-07-18 00:22:43 +08:00
|
|
|
*
|
|
|
|
* execution window
|
|
|
|
* Driver task task
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* nrf_flash_sync_ # |
|
|
|
|
* set_context() # |
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* call nrf_flash_ # |
|
|
|
|
* sync_exe() # |
|
|
|
|
* #---------------->|
|
|
|
|
* | |
|
|
|
|
* | # execution window 0
|
|
|
|
* | # call flash_op_handler_t handler()
|
|
|
|
* | #
|
|
|
|
* | #
|
|
|
|
* | # flash_op_handler_t handler() return
|
|
|
|
* | # FLASH_OP_ONGOING
|
|
|
|
* | # {backend request/allow
|
|
|
|
* | | the next execution window}
|
|
|
|
* . .
|
|
|
|
* . .
|
|
|
|
* . .
|
|
|
|
* | |
|
|
|
|
* | # execution window N
|
|
|
|
* | # call flash_op_handler_t handler()
|
|
|
|
* | #
|
|
|
|
* | #
|
|
|
|
* | #
|
|
|
|
* | # flash_op_handler_t handler() returns
|
|
|
|
* | # FLASH_OP_DONE
|
|
|
|
* |<----------------# {backend transfer execution
|
|
|
|
* # | to the driver back}
|
|
|
|
* nrf_flash_ # |
|
|
|
|
* sync_exe() | |
|
|
|
|
* return | |
|
|
|
|
*/
|
|
|
|
int nrf_flash_sync_exe(struct flash_op_desc *op_desc);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @defgroup nrf_flash_sync_timing sync timing backend API
|
|
|
|
* @ingroup nrf_flash_sync
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* API which is used by nrf flash driver for check where execution fill in
|
|
|
|
* the execution window.
|
|
|
|
*
|
|
|
|
* API is used as follows:
|
|
|
|
* begin of execution window
|
|
|
|
* call flash_op_handler_t handler()
|
|
|
|
* nrf_flash_sync_get_timestamp_begin()
|
|
|
|
* [does some chunk of work]
|
|
|
|
* nrf_flash_sync_check_time_limit() == false
|
|
|
|
* [does some chunk of work]
|
|
|
|
* nrf_flash_sync_check_time_limit() == false
|
|
|
|
* [does some chunk of work]
|
|
|
|
* ...
|
|
|
|
* nrf_flash_sync_check_time_limit() == true
|
|
|
|
* [preserve work context for next execution window]
|
|
|
|
* return form flash_op_handler_t handler()
|
|
|
|
* [return from execution window]
|
|
|
|
* end of execution window
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get timestamp and store it in synchronization backend
|
|
|
|
* context data as operation beginning time reference.
|
2022-02-24 20:00:55 +08:00
|
|
|
* This timestamp will be used by @ref nrf_flash_sync_check_time_limit()
|
2020-07-18 00:22:43 +08:00
|
|
|
* as the execution window begin reference.
|
|
|
|
*/
|
|
|
|
void nrf_flash_sync_get_timestamp_begin(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Estimate whether next iteration will fit in time constraints.
|
|
|
|
* This function fetch current timestamp and compare it with the operation
|
2022-02-24 20:00:55 +08:00
|
|
|
* beginning timestamp reference stored by
|
2020-07-18 00:22:43 +08:00
|
|
|
* @ref nrf_flash_sync_get_timestamp_begin() in the synchronization backend
|
|
|
|
* context data.
|
|
|
|
*
|
|
|
|
* @param iteration iteration number.
|
|
|
|
* @retval true if estimated time excess, false otherwise.
|
|
|
|
*/
|
|
|
|
bool nrf_flash_sync_check_time_limit(uint32_t iteration);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2020-07-19 00:08:33 +08:00
|
|
|
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
2020-07-18 00:22:43 +08:00
|
|
|
#endif /* !__SOC_FLASH_NRF_H__ */
|