mbed HRM11017を使ってkonashi.jsでナイトライダー
Dependencies: BLE_API_Native_IRC mbed
Fork of BLE_RCBController by
pstorage.cpp
00001 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 #include <stdlib.h> 00014 #include <stdint.h> 00015 #include <string.h> 00016 #include "nordic_common.h" 00017 #include "nrf_error.h" 00018 #include "nrf_assert.h" 00019 //#include "nrf.h" 00020 #include "nrf_soc.h" 00021 #include "app_util.h " 00022 #include "pstorage.h " 00023 00024 00025 #define INVALID_OPCODE 0x00 /**< Invalid op code identifier. */ 00026 #define SOC_MAX_WRITE_SIZE 1024 /**< Maximum write size allowed for a single call to \ref sd_flash_write as specified in the SoC API. */ 00027 00028 /** 00029 * @defgroup api_param_check API Parameters check macros. 00030 * 00031 * @details Macros that verify parameters passed to the module in the APIs. These macros 00032 * could be mapped to nothing in final versions of code to save execution and size. 00033 * 00034 * @{ 00035 */ 00036 /** 00037 * @brief Check if the input pointer is NULL, if it is returns NRF_ERROR_NULL. 00038 */ 00039 #define NULL_PARAM_CHECK(PARAM) \ 00040 if ((PARAM) == NULL) \ 00041 { \ 00042 return NRF_ERROR_NULL; \ 00043 } 00044 00045 /** 00046 * @brief Verifies the module identifier supplied by the application is within permissible 00047 * range. 00048 */ 00049 #define MODULE_ID_RANGE_CHECK(ID) \ 00050 if ((((ID)->module_id) >= PSTORAGE_MAX_APPLICATIONS) || \ 00051 (m_app_table[(ID)->module_id].cb == NULL)) \ 00052 { \ 00053 return NRF_ERROR_INVALID_PARAM; \ 00054 } 00055 00056 /** 00057 * @brief Verifies the block identifier supplied by the application is within the permissible 00058 * range. 00059 */ 00060 #define BLOCK_ID_RANGE_CHECK(ID) \ 00061 if (((ID)->block_id) >= (m_app_table[(ID)->module_id].base_id + \ 00062 (m_app_table[(ID)->module_id].block_count * MODULE_BLOCK_SIZE(ID)))) \ 00063 { \ 00064 return NRF_ERROR_INVALID_PARAM; \ 00065 } 00066 00067 00068 /** 00069 * @brief Verifies the block size requested by the application can be supported by the module. 00070 */ 00071 #define BLOCK_SIZE_CHECK(X) \ 00072 if (((X) > PSTORAGE_MAX_BLOCK_SIZE) || ((X) < PSTORAGE_MIN_BLOCK_SIZE)) \ 00073 { \ 00074 return NRF_ERROR_INVALID_PARAM; \ 00075 } 00076 00077 /** 00078 * @brief Verifies block size requested by Application in registration API. 00079 */ 00080 #define BLOCK_COUNT_CHECK(COUNT, SIZE) \ 00081 if (((COUNT) == 0) || ((m_next_page_addr + ((COUNT) *(SIZE)) > PSTORAGE_DATA_END_ADDR))) \ 00082 { \ 00083 return NRF_ERROR_INVALID_PARAM; \ 00084 } 00085 00086 /** 00087 * @brief Verifies size parameter provided by application in API. 00088 */ 00089 #define SIZE_CHECK(ID, SIZE) \ 00090 if(((SIZE) == 0) || ((SIZE) > MODULE_BLOCK_SIZE(ID))) \ 00091 { \ 00092 return NRF_ERROR_INVALID_PARAM; \ 00093 } 00094 00095 /** 00096 * @brief Verifies offset parameter provided by application in API. 00097 */ 00098 #define OFFSET_CHECK(ID, OFFSET, SIZE) \ 00099 if(((SIZE) + (OFFSET)) > MODULE_BLOCK_SIZE(ID)) \ 00100 { \ 00101 return NRF_ERROR_INVALID_PARAM; \ 00102 } 00103 00104 #ifdef PSTORAGE_RAW_MODE_ENABLE 00105 00106 /** 00107 * @brief Verifies the module identifier supplied by the application is registered for raw mode. 00108 */ 00109 #define MODULE_RAW_ID_RANGE_CHECK(ID) \ 00110 if ((PSTORAGE_MAX_APPLICATIONS+1 != ((ID)->module_id)) || \ 00111 (m_raw_app_table.cb == NULL)) \ 00112 { \ 00113 return NRF_ERROR_INVALID_PARAM; \ 00114 } 00115 00116 #endif // PSTORAGE_RAW_MODE_ENABLE 00117 00118 /**@} */ 00119 00120 /**@brief Verify module's initialization status. 00121 * 00122 * @details Verify module's initialization status. Returns NRF_ERROR_INVALID_STATE in case a 00123 * module API is called without initializing the module. 00124 */ 00125 #define VERIFY_MODULE_INITIALIZED() \ 00126 do \ 00127 { \ 00128 if (!m_module_initialized) \ 00129 { \ 00130 return NRF_ERROR_INVALID_STATE; \ 00131 } \ 00132 } while(0) 00133 00134 /**@brief Macro to fetch the block size registered for the module. */ 00135 #define MODULE_BLOCK_SIZE(ID) (m_app_table[(ID)->module_id].block_size) 00136 00137 /**@} */ 00138 00139 /** 00140 * @brief Application registration information. 00141 * 00142 * @details Define application specific information that application needs to maintain to be able 00143 * to process requests from each one of them. 00144 */ 00145 typedef struct 00146 { 00147 pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of result of flash access. */ 00148 pstorage_block_t base_id; /**< Base block id assigned to the module */ 00149 pstorage_size_t block_size; /**< Size of block for the module */ 00150 pstorage_size_t block_count; /**< Number of block requested by application */ 00151 pstorage_size_t no_of_pages; /**< Variable to remember how many pages have been allocated for this module. This information is used for clearing of block, so that application does not need to have knowledge of number of pages its using. */ 00152 } pstorage_module_table_t; 00153 00154 #ifdef PSTORAGE_RAW_MODE_ENABLE 00155 /** 00156 * @brief Application registration information. 00157 * 00158 * @details Define application specific information that application registered for raw mode. 00159 */ 00160 typedef struct 00161 { 00162 pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of result of flash access. */ 00163 uint16_t no_of_pages; /**< Variable to remember how many pages have been allocated for this module. This information is used for clearing of block, so that application does not need to have knowledge of number of pages its using. */ 00164 } pstorage_raw_module_table_t; 00165 #endif // PSTORAGE_RAW_MODE_ENABLE 00166 00167 00168 00169 00170 /** 00171 * @brief Defines command queue element. 00172 * 00173 * @details Defines command queue element. Each element encapsulates needed information to process 00174 * a flash access command. 00175 */ 00176 typedef struct 00177 { 00178 uint8_t op_code; /**< Identifies flash access operation being queued. Element is free is op-code is INVALID_OPCODE */ 00179 pstorage_size_t size; /**< Identifies size in bytes requested for the operation. */ 00180 pstorage_size_t offset; /**< Offset requested by the application for access operation. */ 00181 pstorage_handle_t storage_addr; /**< Address/Identifier for persistent memory. */ 00182 uint8_t * p_data_addr; /**< Address/Identifier for data memory. This is assumed to be resident memory. */ 00183 } cmd_queue_element_t; 00184 00185 00186 /** 00187 * @brief Defines command queue, an element is free is op_code field is not invalid. 00188 * 00189 * @details Defines commands enqueued for flash access. At any point of time, this queue has one or 00190 * more flash access operation pending if the count field is not zero. When the queue is 00191 * not empty, the rp (read pointer) field points to the flash access command in progress 00192 * or to requested next. The queue implements a simple first in first out algorithm. 00193 * Data addresses are assumed to be resident. 00194 */ 00195 typedef struct 00196 { 00197 uint8_t rp; /**< Read pointer, pointing to flash access that is ongoing or to be requested next. */ 00198 uint8_t count; /**< Number of elements in the queue. */ 00199 bool flash_access; /**< Flag to ensure an flash event received is for an request issued by the module. */ 00200 cmd_queue_element_t cmd[PSTORAGE_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details */ 00201 }cmd_queue_t; 00202 00203 static cmd_queue_t m_cmd_queue; /**< Flash operation request queue. */ 00204 static pstorage_module_table_t m_app_table[PSTORAGE_MAX_APPLICATIONS]; /**< Registered application information table. */ 00205 00206 #ifdef PSTORAGE_RAW_MODE_ENABLE 00207 static pstorage_raw_module_table_t m_raw_app_table; /**< Registered application information table for raw mode. */ 00208 #endif // PSTORAGE_RAW_MODE_ENABLE 00209 00210 static pstorage_size_t m_next_app_instance; /**< Points to the application module instance that can be allocated next */ 00211 static uint32_t m_next_page_addr; /**< Points to the flash address that can be allocated to a module next, this is needed as blocks of a module can span across flash pages. */ 00212 static bool m_module_initialized = false; /**< Flag for checking if module has been initialized. */ 00213 static pstorage_size_t m_round_val; /**< Round value for multiple round operations. For erase operations, the round value will contain current round counter which is identical to number of pages erased. For store operations, the round value contains current round of operation * SOC_MAX_WRITE_SIZE to ensure each store to the SoC Flash API is within the SoC limit. */ 00214 00215 static uint32_t process_cmd(void); 00216 static void app_notify (uint32_t reason); 00217 00218 /** 00219 * @defgroup utility_functions Utility internal functions. 00220 * @{ 00221 * @details Utility functions needed for interfacing with flash through SoC APIs. 00222 * SoC APIs are non blocking and provide the result of flash access through an event. 00223 * 00224 * @note Only one flash access operation is permitted at a time by SoC. Hence a queue is 00225 * maintained by this module. 00226 */ 00227 00228 /** 00229 * @brief Initializes command queue element. 00230 */ 00231 static void cmd_queue_init_element(uint32_t index) 00232 { 00233 // Internal function and checks on range of index can be avoided 00234 m_cmd_queue.cmd[index].op_code = INVALID_OPCODE; 00235 m_cmd_queue.cmd[index].size = 0; 00236 m_cmd_queue.cmd[index].storage_addr.module_id = PSTORAGE_MAX_APPLICATIONS; 00237 m_cmd_queue.cmd[index].storage_addr.block_id = 0; 00238 m_cmd_queue.cmd[index].p_data_addr = NULL; 00239 m_cmd_queue.cmd[index].offset = 0; 00240 } 00241 00242 00243 /** 00244 * @brief Initializes command queue. 00245 */ 00246 static void cmd_queue_init (void) 00247 { 00248 uint32_t cmd_index; 00249 00250 m_round_val = 0; 00251 m_cmd_queue.rp = 0; 00252 m_cmd_queue.count = 0; 00253 m_cmd_queue.flash_access = false; 00254 00255 for(cmd_index = 0; cmd_index < PSTORAGE_CMD_QUEUE_SIZE; cmd_index++) 00256 { 00257 cmd_queue_init_element(cmd_index); 00258 } 00259 } 00260 00261 00262 /** 00263 * @brief Routine to enqueue a flash access operation. 00264 */ 00265 static uint32_t cmd_queue_enqueue(uint8_t opcode, pstorage_handle_t * p_storage_addr,uint8_t * p_data_addr, pstorage_size_t size, pstorage_size_t offset) 00266 { 00267 uint32_t retval; 00268 uint8_t write_index = 0; 00269 retval = NRF_ERROR_NO_MEM; 00270 00271 // Check if flash access is ongoing. 00272 if ((m_cmd_queue.flash_access == false) && (m_cmd_queue.count == 0)) 00273 { 00274 m_cmd_queue.rp = 0; 00275 m_cmd_queue.cmd[m_cmd_queue.rp].op_code = opcode; 00276 m_cmd_queue.cmd[m_cmd_queue.rp].p_data_addr = p_data_addr; 00277 m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr = (*p_storage_addr); 00278 m_cmd_queue.cmd[m_cmd_queue.rp].size = size; 00279 m_cmd_queue.cmd[m_cmd_queue.rp].offset = offset; 00280 m_cmd_queue.count++; 00281 retval = process_cmd(); 00282 if ((retval == NRF_SUCCESS) || (retval == NRF_ERROR_BUSY)) 00283 { 00284 // In case of busy error code, it is possible to attempt to access flash 00285 retval = NRF_SUCCESS; 00286 } 00287 } 00288 else if (m_cmd_queue.count != PSTORAGE_CMD_QUEUE_SIZE) 00289 { 00290 // Enqueue the command if it is queue is not full 00291 write_index = m_cmd_queue.rp + m_cmd_queue.count; 00292 00293 if (write_index >= PSTORAGE_CMD_QUEUE_SIZE) 00294 { 00295 write_index -= PSTORAGE_CMD_QUEUE_SIZE; 00296 } 00297 00298 m_cmd_queue.cmd[write_index].op_code = opcode; 00299 m_cmd_queue.cmd[write_index].p_data_addr = p_data_addr; 00300 m_cmd_queue.cmd[write_index].storage_addr = (*p_storage_addr); 00301 m_cmd_queue.cmd[write_index].size = size; 00302 m_cmd_queue.cmd[write_index].offset = offset; 00303 m_cmd_queue.count++; 00304 00305 retval = NRF_SUCCESS; 00306 00307 } 00308 00309 return retval; 00310 } 00311 00312 00313 /** 00314 * @brief Dequeues a command element. 00315 */ 00316 static uint32_t cmd_queue_dequeue(void) 00317 { 00318 uint32_t retval; 00319 00320 cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 00321 // Update count and read pointer to process any queued requests 00322 if(m_round_val >= p_cmd->size) 00323 { 00324 // Initialize/free the element as it is now processed. 00325 cmd_queue_init_element(m_cmd_queue.rp); 00326 m_round_val = 0; 00327 m_cmd_queue.count--; 00328 m_cmd_queue.rp++; 00329 } 00330 00331 retval = NRF_SUCCESS; 00332 00333 // If any flash operation is enqueued, schedule 00334 if (m_cmd_queue.count) 00335 { 00336 retval = process_cmd(); 00337 00338 if (retval != NRF_SUCCESS) 00339 { 00340 // Flash could be accessed by modules other than Bond Manager, hence a busy error is 00341 // acceptable, but any other error needs to be indicated to the bond manager 00342 if (retval != NRF_ERROR_BUSY) 00343 { 00344 app_notify (retval); 00345 } 00346 else 00347 { 00348 // In case of busy next trigger will be a success or a failure event 00349 } 00350 } 00351 } 00352 else 00353 { 00354 // No flash access request pending 00355 } 00356 00357 return retval; 00358 } 00359 00360 00361 /** 00362 * @brief Routine to notify application of any errors. 00363 */ 00364 static void app_notify (uint32_t result) 00365 { 00366 pstorage_ntf_cb_t ntf_cb; 00367 uint8_t op_code = m_cmd_queue.cmd[m_cmd_queue.rp].op_code; 00368 00369 #ifdef PSTORAGE_RAW_MODE_ENABLE 00370 if(m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr.module_id == (PSTORAGE_MAX_APPLICATIONS + 1)) 00371 { 00372 ntf_cb = m_raw_app_table.cb; 00373 } 00374 else 00375 #endif // PSTORAGE_RAW_MODE_ENABLE 00376 { 00377 ntf_cb = m_app_table[m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr.module_id].cb; 00378 } 00379 00380 // Indicate result to client. 00381 // For PSTORAGE_CLEAR_OP_CODE no size is returned as the size field is used only internally 00382 // for clients registering multiple pages. 00383 ntf_cb(&m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr, 00384 op_code, 00385 result, 00386 m_cmd_queue.cmd[m_cmd_queue.rp].p_data_addr, 00387 op_code == PSTORAGE_CLEAR_OP_CODE ? 0 : m_cmd_queue.cmd[m_cmd_queue.rp].size); 00388 } 00389 00390 00391 /** 00392 * @brief Handles Flash Access Result Events. 00393 */ 00394 void pstorage_sys_event_handler (uint32_t sys_evt) 00395 { 00396 uint32_t retval; 00397 00398 retval = NRF_SUCCESS; 00399 00400 // Its possible the flash access was not initiated by bond manager, hence 00401 // event is processed only if the event triggered was for an operation requested by the 00402 // bond manager. 00403 if (m_cmd_queue.flash_access == true) 00404 { 00405 cmd_queue_element_t * p_cmd; 00406 m_cmd_queue.flash_access = false; 00407 switch (sys_evt) 00408 { 00409 case NRF_EVT_FLASH_OPERATION_SUCCESS: 00410 p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 00411 if ((p_cmd->op_code != PSTORAGE_CLEAR_OP_CODE) || (m_round_val >= p_cmd->size)) 00412 { 00413 app_notify(retval); 00414 } 00415 // Schedule any queued flash access operations 00416 retval = cmd_queue_dequeue (); 00417 if (retval != NRF_SUCCESS) 00418 { 00419 app_notify(retval); 00420 } 00421 00422 break; 00423 case NRF_EVT_FLASH_OPERATION_ERROR: 00424 app_notify(NRF_ERROR_TIMEOUT); 00425 break; 00426 default: 00427 // No implementation needed. 00428 break; 00429 } 00430 } 00431 } 00432 00433 00434 /** 00435 * @brief Routine called to actually issue the flash access request to the SoftDevice. 00436 */ 00437 static uint32_t process_cmd(void) 00438 { 00439 uint32_t retval; 00440 uint32_t storage_addr; 00441 cmd_queue_element_t * p_cmd; 00442 00443 retval = NRF_ERROR_FORBIDDEN; 00444 00445 p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 00446 00447 storage_addr = p_cmd->storage_addr.block_id; 00448 00449 if (p_cmd->op_code == PSTORAGE_CLEAR_OP_CODE) 00450 { 00451 // Calculate page number before copy. 00452 uint32_t page_number; 00453 00454 page_number = ((storage_addr / PSTORAGE_FLASH_PAGE_SIZE) + 00455 m_round_val); 00456 00457 retval = sd_flash_page_erase(page_number); 00458 00459 if (NRF_SUCCESS == retval) 00460 { 00461 m_round_val++; 00462 } 00463 } 00464 else if (p_cmd->op_code == PSTORAGE_STORE_OP_CODE) 00465 { 00466 uint32_t size; 00467 uint8_t * p_data_addr = p_cmd->p_data_addr; 00468 00469 p_data_addr += m_round_val; 00470 00471 storage_addr += (p_cmd->offset + m_round_val); 00472 00473 size = p_cmd->size - m_round_val; 00474 00475 if (size < SOC_MAX_WRITE_SIZE) 00476 { 00477 retval = sd_flash_write(((uint32_t *)storage_addr), 00478 (uint32_t *)p_data_addr, 00479 size / sizeof(uint32_t)); 00480 } 00481 else 00482 { 00483 retval = sd_flash_write(((uint32_t *)storage_addr), 00484 (uint32_t *)p_data_addr, 00485 SOC_MAX_WRITE_SIZE / sizeof(uint32_t)); 00486 } 00487 00488 00489 if (retval == NRF_SUCCESS) 00490 { 00491 m_round_val += SOC_MAX_WRITE_SIZE; 00492 } 00493 } 00494 else 00495 { 00496 // Should never reach here. 00497 } 00498 00499 if (retval == NRF_SUCCESS) 00500 { 00501 m_cmd_queue.flash_access = true; 00502 } 00503 00504 return retval; 00505 } 00506 /** @} */ 00507 00508 00509 /** 00510 * @brief Module initialization routine to be called once by the application. 00511 */ 00512 uint32_t pstorage_init(void) 00513 { 00514 unsigned int index; 00515 cmd_queue_init(); 00516 00517 m_next_app_instance = 0; 00518 m_next_page_addr = PSTORAGE_DATA_START_ADDR; 00519 m_round_val = 0; 00520 00521 for(index = 0; index < PSTORAGE_MAX_APPLICATIONS; index++) 00522 { 00523 m_app_table[index].cb = NULL; 00524 m_app_table[index].block_size = 0; 00525 m_app_table[index].no_of_pages = 0; 00526 m_app_table[index].block_count = 0; 00527 } 00528 00529 #ifdef PSTORAGE_RAW_MODE_ENABLE 00530 m_raw_app_table.cb = NULL; 00531 m_raw_app_table.no_of_pages = 0; 00532 #endif //PSTORAGE_RAW_MODE_ENABLE 00533 00534 m_module_initialized = true; 00535 return NRF_SUCCESS; 00536 } 00537 00538 /** 00539 * @brief Registration routine to request persistent memory of certain sizes based on 00540 * application module requirements. 00541 */ 00542 uint32_t pstorage_register(pstorage_module_param_t * p_module_param, 00543 pstorage_handle_t * p_block_id) 00544 { 00545 uint16_t page_count; 00546 uint32_t total_size; 00547 00548 VERIFY_MODULE_INITIALIZED(); 00549 NULL_PARAM_CHECK(p_module_param); 00550 NULL_PARAM_CHECK(p_block_id); 00551 NULL_PARAM_CHECK(p_module_param->cb); 00552 BLOCK_SIZE_CHECK(p_module_param->block_size); 00553 BLOCK_COUNT_CHECK(p_module_param->block_count, p_module_param->block_size); 00554 00555 if (m_next_app_instance == PSTORAGE_MAX_APPLICATIONS) 00556 { 00557 return NRF_ERROR_NO_MEM; 00558 } 00559 00560 p_block_id->module_id = m_next_app_instance; 00561 p_block_id->block_id = m_next_page_addr; 00562 m_app_table[m_next_app_instance].base_id = p_block_id->block_id; 00563 m_app_table[m_next_app_instance].cb = p_module_param->cb; 00564 m_app_table[m_next_app_instance].block_size = p_module_param->block_size; 00565 m_app_table[m_next_app_instance].block_count = p_module_param->block_count; 00566 00567 // Calculate number of flash pages allocated for the device. 00568 page_count = 0; 00569 total_size = p_module_param->block_size * p_module_param->block_count; 00570 do 00571 { 00572 page_count++; 00573 if (total_size > PSTORAGE_FLASH_PAGE_SIZE) 00574 { 00575 total_size -= PSTORAGE_FLASH_PAGE_SIZE; 00576 } 00577 else 00578 { 00579 total_size = 0; 00580 } 00581 m_next_page_addr += PSTORAGE_FLASH_PAGE_SIZE; 00582 }while(total_size >= PSTORAGE_FLASH_PAGE_SIZE); 00583 00584 m_app_table[m_next_app_instance].no_of_pages = page_count; 00585 m_next_app_instance++; 00586 00587 return NRF_SUCCESS; 00588 } 00589 00590 00591 /** 00592 * @brief API to get the next block identifier. 00593 */ 00594 uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id, 00595 pstorage_size_t block_num, 00596 pstorage_handle_t * p_block_id) 00597 { 00598 pstorage_handle_t temp_id; 00599 00600 VERIFY_MODULE_INITIALIZED(); 00601 NULL_PARAM_CHECK(p_base_id); 00602 NULL_PARAM_CHECK(p_block_id); 00603 MODULE_ID_RANGE_CHECK(p_base_id); 00604 00605 temp_id = (*p_base_id); 00606 temp_id.block_id += (block_num * MODULE_BLOCK_SIZE(p_base_id)); 00607 BLOCK_ID_RANGE_CHECK(&temp_id); 00608 (*p_block_id) = temp_id; 00609 00610 return NRF_SUCCESS; 00611 } 00612 00613 00614 /** 00615 * @brief API to store data persistently. 00616 */ 00617 uint32_t pstorage_store(pstorage_handle_t * p_dest, 00618 uint8_t * p_src, 00619 pstorage_size_t size, 00620 pstorage_size_t offset) 00621 { 00622 VERIFY_MODULE_INITIALIZED(); 00623 NULL_PARAM_CHECK(p_src); 00624 NULL_PARAM_CHECK(p_dest); 00625 MODULE_ID_RANGE_CHECK (p_dest); 00626 BLOCK_ID_RANGE_CHECK(p_dest); 00627 SIZE_CHECK(p_dest,size); 00628 OFFSET_CHECK(p_dest,offset,size); 00629 00630 // Verify word alignment. 00631 if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset))) 00632 { 00633 return NRF_ERROR_INVALID_ADDR; 00634 } 00635 00636 return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); 00637 } 00638 00639 00640 /** 00641 * @brief API to load data from persistent memory. 00642 */ 00643 uint32_t pstorage_load(uint8_t * p_dest, 00644 pstorage_handle_t * p_src, 00645 pstorage_size_t size, 00646 pstorage_size_t offset) 00647 { 00648 VERIFY_MODULE_INITIALIZED(); 00649 NULL_PARAM_CHECK(p_src); 00650 NULL_PARAM_CHECK(p_dest); 00651 MODULE_ID_RANGE_CHECK (p_src); 00652 BLOCK_ID_RANGE_CHECK(p_src); 00653 SIZE_CHECK(p_src,size); 00654 OFFSET_CHECK(p_src,offset,size); 00655 00656 // Verify word alignment. 00657 if ((!is_word_aligned (p_dest)) || (!is_word_aligned (p_dest + offset))) 00658 { 00659 return NRF_ERROR_INVALID_ADDR; 00660 } 00661 00662 memcpy (p_dest, (((uint8_t *)p_src->block_id) + offset), size); 00663 00664 return NRF_SUCCESS; 00665 } 00666 00667 00668 /** 00669 * @brief API to clear data in blocks of persistent memory. 00670 */ 00671 uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size) 00672 { 00673 uint32_t retval; 00674 uint32_t pages; 00675 00676 VERIFY_MODULE_INITIALIZED(); 00677 NULL_PARAM_CHECK(p_dest); 00678 MODULE_ID_RANGE_CHECK(p_dest); 00679 BLOCK_ID_RANGE_CHECK(p_dest); 00680 00681 pages = m_app_table[p_dest->module_id].no_of_pages; 00682 00683 retval = cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL , pages , 0); 00684 00685 return retval; 00686 } 00687 00688 00689 #ifdef PSTORAGE_RAW_MODE_ENABLE 00690 00691 /** 00692 * @brief Registration routine to request persistent memory of certain sizes based on 00693 * application module requirements. 00694 */ 00695 uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param, 00696 pstorage_handle_t * p_block_id) 00697 { 00698 VERIFY_MODULE_INITIALIZED(); 00699 NULL_PARAM_CHECK(p_module_param); 00700 NULL_PARAM_CHECK(p_block_id); 00701 NULL_PARAM_CHECK(p_module_param->cb); 00702 00703 if (m_raw_app_table.cb != NULL) 00704 { 00705 return NRF_ERROR_NO_MEM; 00706 } 00707 00708 p_block_id->module_id = PSTORAGE_MAX_APPLICATIONS + 1; 00709 m_raw_app_table.cb = p_module_param->cb; 00710 00711 return NRF_SUCCESS; 00712 } 00713 00714 00715 /** 00716 * @brief API to store data persistently. 00717 */ 00718 uint32_t pstorage_raw_store(pstorage_handle_t * p_dest, 00719 uint8_t * p_src, 00720 uint32_t size, 00721 uint32_t offset) 00722 { 00723 VERIFY_MODULE_INITIALIZED(); 00724 NULL_PARAM_CHECK(p_src); 00725 NULL_PARAM_CHECK(p_dest); 00726 MODULE_RAW_ID_RANGE_CHECK(p_dest); 00727 00728 // Verify word alignment. 00729 if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset))) 00730 { 00731 return NRF_ERROR_INVALID_ADDR; 00732 } 00733 00734 return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); 00735 } 00736 00737 00738 /** 00739 * @brief API to clear data in blocks of persistent memory. 00740 */ 00741 uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, uint32_t size) 00742 { 00743 uint32_t retval; 00744 uint32_t pages; 00745 00746 VERIFY_MODULE_INITIALIZED(); 00747 NULL_PARAM_CHECK(p_dest); 00748 MODULE_RAW_ID_RANGE_CHECK(p_dest); 00749 00750 retval = NRF_SUCCESS; 00751 00752 pages = CEIL_DIV(size, PSTORAGE_FLASH_PAGE_SIZE); 00753 00754 retval = cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL , pages, 0); 00755 00756 return retval; 00757 } 00758 00759 #endif // PSTORAGE_RAW_MODE_ENABLE
Generated on Tue Jul 12 2022 18:49:54 by 1.7.2