1 /* 2 * Copyright (c) 2020 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __SOC_FLASH_NRF_H__ 8 #define __SOC_FLASH_NRF_H__ 9 10 #include <zephyr/kernel.h> 11 #include <soc.h> 12 13 #define FLASH_OP_DONE (0) /* 0 for compliance with the driver API. */ 14 #define FLASH_OP_ONGOING 1 15 16 struct flash_context { 17 uint32_t data_addr; /* Address of data to write. */ 18 uint32_t flash_addr; /* Address of flash to write or erase. */ 19 uint32_t len; /* Size of data to write or erase [B]. */ 20 #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE 21 uint8_t enable_time_limit; /* set execution limited to the execution 22 * window. 23 */ 24 #endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */ 25 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) 26 uint32_t flash_addr_next; 27 #endif /* CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE */ 28 }; /*< Context type for f. @ref write_op @ref erase_op */ 29 30 #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE 31 32 /* The timeout is multiplied by CONFIG_SOC_FLASH_NRF_TIMEOUT_MULTIPLIER/10 33 * because switching tasks may take a significant portion of time. 34 */ 35 #define FLASH_TIMEOUT_MS ((FLASH_PAGE_ERASE_MAX_TIME_US) * \ 36 (FLASH_PAGE_MAX_CNT) / 1000 * \ 37 CONFIG_SOC_FLASH_NRF_TIMEOUT_MULTIPLIER / 10) 38 39 /** 40 * @defgroup nrf_flash_sync sync backend API 41 * 42 * API declared below contains prototypes of function which shall be 43 * implemented by the synchronization backend. 44 * @{ 45 */ 46 47 /** 48 * Callback which executes the flash operation. 49 * 50 * @param context pointer to flash_context structure. 51 * @retval @ref FLASH_OP_DONE once operation was done, @ref FLASH_OP_ONGOING if 52 * operation needs more time for execution and a negative error code if 53 * operation was aborted. 54 */ 55 typedef int (*flash_op_handler_t) (void *context); 56 57 struct flash_op_desc { 58 flash_op_handler_t handler; 59 struct flash_context *context; /* [in,out] */ 60 }; 61 62 /** 63 * Synchronization backend driver initialization procedure. 64 * 65 * This will be run within flash driver initialization 66 */ 67 int nrf_flash_sync_init(void); 68 69 /** 70 * Set synchronization context for synchronous operations. 71 * 72 * This function set backend's internal context for expected timing parameter. 73 * 74 * @param duration Duration of the execution window [us] 75 */ 76 void nrf_flash_sync_set_context(uint32_t duration); 77 78 /** 79 * Check if the operation need to be run synchronous with radio. 80 * 81 * @retval True if operation need to be run synchronously, otherwise False 82 */ 83 bool nrf_flash_sync_is_required(void); 84 85 /** 86 * Execute the flash operation synchronously along the radio operations. 87 * 88 * Function executes callbacks op_desc->handler() in execution windows according 89 * to timing settings requested by nrf_flash_sync_set_context(). 90 * This routine need to be called the handler as many time as it returns 91 * FLASH_OP_ONGOING, however an operation timeout should be implemented. 92 * When the handler() returns FLASH_OP_DONE or an error code, no further 93 * execution windows are needed so function should return as the handler() 94 * finished its operation. 95 * 96 * @retval 0 if op_desc->handler() was executed and finished its operation 97 * successfully. Otherwise (handler returned error, timeout, couldn't schedule 98 * execution...) a negative error code. 99 * 100 * execution window 101 * Driver task task 102 * | | 103 * | | 104 * nrf_flash_sync_ # | 105 * set_context() # | 106 * | | 107 * | | 108 * call nrf_flash_ # | 109 * sync_exe() # | 110 * #---------------->| 111 * | | 112 * | # execution window 0 113 * | # call flash_op_handler_t handler() 114 * | # 115 * | # 116 * | # flash_op_handler_t handler() return 117 * | # FLASH_OP_ONGOING 118 * | # {backend request/allow 119 * | | the next execution window} 120 * . . 121 * . . 122 * . . 123 * | | 124 * | # execution window N 125 * | # call flash_op_handler_t handler() 126 * | # 127 * | # 128 * | # 129 * | # flash_op_handler_t handler() returns 130 * | # FLASH_OP_DONE 131 * |<----------------# {backend transfer execution 132 * # | to the driver back} 133 * nrf_flash_ # | 134 * sync_exe() | | 135 * return | | 136 */ 137 int nrf_flash_sync_exe(struct flash_op_desc *op_desc); 138 139 /** 140 * @} 141 */ 142 143 /** 144 * @defgroup nrf_flash_sync_timing sync timing backend API 145 * @ingroup nrf_flash_sync 146 * @{ 147 * 148 * API which is used by nrf flash driver for check where execution fill in 149 * the execution window. 150 * 151 * API is used as follows: 152 * begin of execution window 153 * call flash_op_handler_t handler() 154 * nrf_flash_sync_get_timestamp_begin() 155 * [does some chunk of work] 156 * nrf_flash_sync_check_time_limit() == false 157 * [does some chunk of work] 158 * nrf_flash_sync_check_time_limit() == false 159 * [does some chunk of work] 160 * ... 161 * nrf_flash_sync_check_time_limit() == true 162 * [preserve work context for next execution window] 163 * return form flash_op_handler_t handler() 164 * [return from execution window] 165 * end of execution window 166 */ 167 168 /** 169 * Get timestamp and store it in synchronization backend 170 * context data as operation beginning time reference. 171 * This timestamp will be used by @ref nrf_flash_sync_check_time_limit() 172 * as the execution window begin reference. 173 */ 174 void nrf_flash_sync_get_timestamp_begin(void); 175 176 /** 177 * Estimate whether next iteration will fit in time constraints. 178 * This function fetch current timestamp and compare it with the operation 179 * beginning timestamp reference stored by 180 * @ref nrf_flash_sync_get_timestamp_begin() in the synchronization backend 181 * context data. 182 * 183 * @param iteration iteration number. 184 * @retval true if estimated time excess, false otherwise. 185 */ 186 bool nrf_flash_sync_check_time_limit(uint32_t iteration); 187 188 /** 189 * @} 190 */ 191 192 #endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */ 193 #endif /* !__SOC_FLASH_NRF_H__ */ 194