Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
Driver_Storage.h
00001 00002 /** \addtogroup hal */ 00003 /** @{*/ 00004 /* 00005 * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved 00006 * SPDX-License-Identifier: Apache-2.0 00007 * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00009 * not use this file except in compliance with the License. 00010 * You may obtain a copy of the License at 00011 * 00012 * http://www.apache.org/licenses/LICENSE-2.0 00013 * 00014 * Unless required by applicable law or agreed to in writing, software 00015 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00016 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00017 * See the License for the specific language governing permissions and 00018 * limitations under the License. 00019 */ 00020 00021 #ifndef __DRIVER_STORAGE_H 00022 #define __DRIVER_STORAGE_H 00023 00024 #include <stdint.h> 00025 00026 /****** This file has been deprecated since mbed-os-5.5 *****/ 00027 00028 #ifdef __cplusplus 00029 extern "C" { 00030 #endif // __cplusplus 00031 00032 #include "Driver_Common.h" 00033 00034 #define ARM_STORAGE_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,00) /* API version */ 00035 00036 00037 #define _ARM_Driver_Storage_(n) Driver_Storage##n 00038 #define ARM_Driver_Storage_(n) _ARM_Driver_Storage_(n) 00039 00040 #define ARM_STORAGE_INVALID_OFFSET (0xFFFFFFFFFFFFFFFFULL) ///< Invalid address (relative to a storage controller's 00041 ///< address space). A storage block may never start at this address. 00042 00043 #define ARM_STORAGE_INVALID_ADDRESS (0xFFFFFFFFUL) ///< Invalid address within the processor's memory address space. 00044 ///< Refer to memory-mapped storage, i.e. < \ref ARM_DRIVER_STORAGE::ResolveAddress(). 00045 00046 /****** Storage specific error codes *****/ 00047 #define ARM_STORAGE_ERROR_NOT_ERASABLE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Part (or all) of the range provided to Erase() isn't erasable. 00048 #define ARM_STORAGE_ERROR_NOT_PROGRAMMABLE (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Part (or all) of the range provided to ProgramData() isn't programmable. 00049 #define ARM_STORAGE_ERROR_PROTECTED (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Part (or all) of the range to Erase() or ProgramData() is protected. 00050 #define ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Runtime or sanity-check failure. 00051 00052 /** 00053 * \brief Attributes of the storage range within a storage block. 00054 */ 00055 typedef struct _ARM_STORAGE_BLOCK_ATTRIBUTES { 00056 uint32_t erasable : 1; ///< Erasing blocks is permitted with a minimum granularity of 'erase_unit'. 00057 ///< @note: if 'erasable' is 0--i.e. the 'erase' operation isn't available--then 00058 ///< 'erase_unit' (see below) is immaterial and should be 0. 00059 uint32_t programmable : 1; ///< Writing to ranges is permitted with a minimum granularity of 'program_unit'. 00060 ///< Writes are typically achieved through the ProgramData operation (following an erase); 00061 ///< if storage isn't erasable (see 'erasable' above) but is memory-mapped 00062 ///< (i.e. 'memory_mapped'), it can be written directly using memory-store operations. 00063 uint32_t executable : 1; ///< This storage block can hold program data; the processor can fetch and execute code 00064 ///< sourced from it. Often this is accompanied with the device being 'memory_mapped' (see \ref ARM_STORAGE_INFO). 00065 uint32_t protectable : 1; ///< The entire block can be protected from program and erase operations. Once protection 00066 ///< is enabled for a block, its 'erasable' and 'programmable' bits are turned off. 00067 uint32_t reserved : 28; 00068 uint32_t erase_unit; ///< Minimum erase size in bytes. 00069 ///< The offset of the start of the erase-range should also be aligned with this value. 00070 ///< Applicable if the 'erasable' attribute is set for the block. 00071 ///< @note: if 'erasable' (see above) is 0--i.e. the 'erase' operation isn't available--then 00072 ///< 'erase_unit' is immaterial and should be 0. 00073 uint32_t protection_unit; ///< Minimum protectable size in bytes. Applicable if the 'protectable' 00074 ///< attribute is set for the block. This should be a divisor of the block's size. A 00075 ///< block can be considered to be made up of consecutive, individually-protectable fragments. 00076 } ARM_STORAGE_BLOCK_ATTRIBUTES; 00077 00078 /** 00079 * \brief A storage block is a range of memory with uniform attributes. Storage blocks 00080 * combine to make up the address map of a storage controller. 00081 */ 00082 typedef struct _ARM_STORAGE_BLOCK { 00083 uint64_t addr; ///< This is the start address of the storage block. It is 00084 ///< expressed as an offset from the start of the storage map 00085 ///< maintained by the owning storage controller. 00086 uint64_t size; ///< This is the size of the storage block, in units of bytes. 00087 ///< Together with addr, it describes a range [addr, addr+size). 00088 ARM_STORAGE_BLOCK_ATTRIBUTES attributes; ///< Attributes for this block. 00089 } ARM_STORAGE_BLOCK; 00090 00091 /** 00092 * The check for a valid ARM_STORAGE_BLOCK. 00093 */ 00094 #define ARM_STORAGE_VALID_BLOCK(BLK) (((BLK)->addr != ARM_STORAGE_INVALID_OFFSET) && ((BLK)->size != 0)) 00095 00096 /** 00097 * \brief Values for encoding storage memory-types with respect to programmability. 00098 * 00099 * Please ensure that the maximum of the following memory types doesn't exceed 16; we 00100 * encode this in a 4-bit field within ARM_STORAGE_INFO::programmability. 00101 */ 00102 #define ARM_STORAGE_PROGRAMMABILITY_RAM (0x0) 00103 #define ARM_STORAGE_PROGRAMMABILITY_ROM (0x1) ///< Read-only memory. 00104 #define ARM_STORAGE_PROGRAMMABILITY_WORM (0x2) ///< write-once-read-only-memory (WORM). 00105 #define ARM_STORAGE_PROGRAMMABILITY_ERASABLE (0x3) ///< re-programmable based on erase. Supports multiple writes. 00106 00107 /** 00108 * Values for encoding data-retention levels for storage blocks. 00109 * 00110 * Please ensure that the maximum of the following retention types doesn't exceed 16; we 00111 * encode this in a 4-bit field within ARM_STORAGE_INFO::retention_level. 00112 */ 00113 #define ARM_RETENTION_WHILE_DEVICE_ACTIVE (0x0) ///< Data is retained only during device activity. 00114 #define ARM_RETENTION_ACROSS_SLEEP (0x1) ///< Data is retained across processor sleep. 00115 #define ARM_RETENTION_ACROSS_DEEP_SLEEP (0x2) ///< Data is retained across processor deep-sleep. 00116 #define ARM_RETENTION_BATTERY_BACKED (0x3) ///< Data is battery-backed. Device can be powered off. 00117 #define ARM_RETENTION_NVM (0x4) ///< Data is retained in non-volatile memory. 00118 00119 /** 00120 * Device Data Security Protection Features. Applicable mostly to EXTERNAL_NVM. 00121 */ 00122 typedef struct _ARM_STORAGE_SECURITY_FEATURES { 00123 uint32_t acls : 1; ///< Protection against internal software attacks using ACLs. 00124 uint32_t rollback_protection : 1; ///< Roll-back protection. Set to true if the creator of the storage 00125 ///< can ensure that an external attacker can't force an 00126 ///< older firmware to run or to revert back to a previous state. 00127 uint32_t tamper_proof : 1; ///< Tamper-proof memory (will be deleted on tamper-attempts using board level or chip level sensors). 00128 uint32_t internal_flash : 1; ///< Internal flash. 00129 uint32_t reserved1 : 12; 00130 00131 /** 00132 * Encode support for hardening against various classes of attacks. 00133 */ 00134 uint32_t software_attacks : 1; ///< device software (malware running on the device). 00135 uint32_t board_level_attacks : 1; ///< board level attacks (debug probes, copy protection fuses.) 00136 uint32_t chip_level_attacks : 1; ///< chip level attacks (tamper-protection). 00137 uint32_t side_channel_attacks : 1; ///< side channel attacks. 00138 uint32_t reserved2 : 12; 00139 } ARM_STORAGE_SECURITY_FEATURES; 00140 00141 #define ARM_STORAGE_PROGRAM_CYCLES_INFINITE (0UL) /**< Infinite or unknown endurance for reprogramming. */ 00142 00143 /** 00144 * \brief Storage information. This contains device-metadata. It is the return 00145 * value from calling GetInfo() on the storage driver. 00146 * 00147 * \details These fields serve a different purpose than the ones contained in 00148 * \ref ARM_STORAGE_CAPABILITIES, which is another structure containing 00149 * device-level metadata. ARM_STORAGE_CAPABILITIES describes the API 00150 * capabilities, whereas ARM_STORAGE_INFO describes the device. Furthermore 00151 * ARM_STORAGE_CAPABILITIES fits within a single word, and is designed to be 00152 * passed around by value; ARM_STORAGE_INFO, on the other hand, contains 00153 * metadata which doesn't fit into a single word and requires the use of 00154 * pointers to be moved around. 00155 */ 00156 typedef struct _ARM_STORAGE_INFO { 00157 uint64_t total_storage; ///< Total available storage, in bytes. 00158 uint32_t program_unit; ///< Minimum programming size in bytes. 00159 ///< The offset of the start of the program-range should also be aligned with this value. 00160 ///< Applicable only if the 'programmable' attribute is set for a block. 00161 ///< @note: setting program_unit to 0 has the effect of disabling the size and alignment 00162 ///< restrictions (setting it to 1 also has the same effect). 00163 uint32_t optimal_program_unit; ///< Optimal programming page-size in bytes. Some storage controllers 00164 ///< have internal buffers into which to receive data. Writing in chunks of 00165 ///< 'optimal_program_unit' would achieve maximum programming speed. 00166 ///< Applicable only if the 'programmable' attribute is set for the underlying block(s). 00167 uint32_t program_cycles; ///< A measure of endurance for reprogramming. 00168 ///< Use ARM_STORAGE_PROGRAM_CYCLES_INFINITE for infinite or unknown endurance. 00169 uint32_t erased_value : 1; ///< Contents of erased memory (usually 1 to indicate erased bytes with state 0xFF). 00170 uint32_t memory_mapped : 1; ///< This storage device has a mapping onto the processor's memory address space. 00171 ///< @note: For a memory-mapped block which isn't erasable but is programmable (i.e. if 00172 ///< 'erasable' is set to 0, but 'programmable' is 1), writes should be possible directly to 00173 ///< the memory-mapped storage without going through the ProgramData operation. 00174 uint32_t programmability : 4; ///< A value to indicate storage programmability. 00175 uint32_t retention_level : 4; 00176 uint32_t reserved : 22; 00177 ARM_STORAGE_SECURITY_FEATURES security; ///< \ref ARM_STORAGE_SECURITY_FEATURES 00178 } ARM_STORAGE_INFO; 00179 00180 /** 00181 \brief Operating status of the storage controller. 00182 */ 00183 typedef struct _ARM_STORAGE_STATUS { 00184 uint32_t busy : 1; ///< Controller busy flag 00185 uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) 00186 } ARM_STORAGE_STATUS; 00187 00188 /** 00189 * \brief Storage Driver API Capabilities. 00190 * 00191 * This data structure is designed to fit within a single word so that it can be 00192 * fetched cheaply using a call to driver->GetCapabilities(). 00193 */ 00194 typedef struct _ARM_STORAGE_CAPABILITIES { 00195 uint32_t asynchronous_ops : 1; ///< Used to indicate if APIs like initialize, 00196 ///< read, erase, program, etc. can operate in asynchronous mode. 00197 ///< Setting this bit to 1 means that the driver is capable 00198 ///< of launching asynchronous operations; command completion is 00199 ///< signaled by the invocation of a completion callback. If 00200 ///< set to 1, drivers may still complete asynchronous 00201 ///< operations synchronously as necessary--in which case they 00202 ///< return a positive error code to indicate synchronous completion. 00203 uint32_t erase_all : 1; ///< Supports EraseAll operation. 00204 uint32_t reserved : 30; 00205 } ARM_STORAGE_CAPABILITIES; 00206 00207 /** 00208 * Command opcodes for Storage. Completion callbacks use these codes to refer to 00209 * completing commands. Refer to \ref ARM_Storage_Callback_t. 00210 */ 00211 typedef enum _ARM_STORAGE_OPERATION { 00212 ARM_STORAGE_OPERATION_GET_VERSION, 00213 ARM_STORAGE_OPERATION_GET_CAPABILITIES, 00214 ARM_STORAGE_OPERATION_INITIALIZE, 00215 ARM_STORAGE_OPERATION_UNINITIALIZE, 00216 ARM_STORAGE_OPERATION_POWER_CONTROL, 00217 ARM_STORAGE_OPERATION_READ_DATA, 00218 ARM_STORAGE_OPERATION_PROGRAM_DATA, 00219 ARM_STORAGE_OPERATION_ERASE, 00220 ARM_STORAGE_OPERATION_ERASE_ALL, 00221 ARM_STORAGE_OPERATION_GET_STATUS, 00222 ARM_STORAGE_OPERATION_GET_INFO, 00223 ARM_STORAGE_OPERATION_RESOLVE_ADDRESS, 00224 ARM_STORAGE_OPERATION_GET_NEXT_BLOCK, 00225 ARM_STORAGE_OPERATION_GET_BLOCK 00226 } ARM_STORAGE_OPERATION; 00227 00228 /** 00229 * Declaration of the callback-type for command completion. 00230 * 00231 * @param [in] status 00232 * A code to indicate the status of the completed operation. For data 00233 * transfer operations, the status field is overloaded in case of 00234 * success to return the count of items successfully transferred; this 00235 * can be done safely because error codes are negative values. 00236 * 00237 * @param [in] operation 00238 * The command op-code. This value isn't essential for the callback in 00239 * the presence of the command instance-id, but it is expected that 00240 * this information could be a quick and useful filter. 00241 */ 00242 typedef void (*ARM_Storage_Callback_t)(int32_t status, ARM_STORAGE_OPERATION operation); 00243 00244 /** 00245 * This is the set of operations constituting the Storage driver. Their 00246 * implementation is platform-specific, and needs to be supplied by the 00247 * porting effort. 00248 * 00249 * Some APIs within `ARM_DRIVER_STORAGE` will always operate synchronously: 00250 * GetVersion, GetCapabilities, GetStatus, GetInfo, ResolveAddress, 00251 * GetNextBlock, and GetBlock. This means that control returns to the caller 00252 * with a relevant status code only after the completion of the operation (or 00253 * the discovery of a failure condition). 00254 * 00255 * The remainder of the APIs: Initialize, Uninitialize, PowerControl, ReadData, 00256 * ProgramData, Erase, EraseAll, can function asynchronously if the underlying 00257 * controller supports it--i.e. if ARM_STORAGE_CAPABILITIES::asynchronous_ops is 00258 * set. In the case of asynchronous operation, the invocation returns early 00259 * (with ARM_DRIVER_OK) and results in a completion callback later. If 00260 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is not set, then all such APIs 00261 * execute synchronously, and control returns to the caller with a status code 00262 * only after the completion of the operation (or the discovery of a failure 00263 * condition). 00264 * 00265 * If ARM_STORAGE_CAPABILITIES::asynchronous_ops is set, a storage driver may 00266 * still choose to execute asynchronous operations in a synchronous manner. If 00267 * so, the driver returns a positive value to indicate successful synchronous 00268 * completion (or an error code in case of failure) and no further invocation of 00269 * completion callback should be expected. The expected return value for 00270 * synchronous completion of such asynchronous operations varies depending on 00271 * the operation. For operations involving data access, it often equals the 00272 * amount of data transferred or affected. For non data-transfer operations, 00273 * such as EraseAll or Initialize, it is usually 1. 00274 * 00275 * Here's a code snippet to suggest how asynchronous APIs might be used by 00276 * callers to handle both synchronous and asynchronous execution by the 00277 * underlying storage driver: 00278 * \code 00279 * ASSERT(ARM_DRIVER_OK == 0); // this is a precondition; it doesn't need to be put in code 00280 * int32_t returnValue = drv->asynchronousAPI(...); 00281 * if (returnValue < ARM_DRIVER_OK) { 00282 * // handle error. 00283 * } else if (returnValue == ARM_DRIVER_OK) { 00284 * ASSERT(drv->GetCapabilities().asynchronous_ops == 1); 00285 * // handle early return from asynchronous execution; remainder of the work is done in the callback handler. 00286 * } else { 00287 * ASSERT(returnValue == EXPECTED_RETURN_VALUE_FOR_SYNCHRONOUS_COMPLETION); 00288 * // handle synchronous completion. 00289 * } 00290 * \endcode 00291 */ 00292 typedef struct _ARM_DRIVER_STORAGE { 00293 /** 00294 * \brief Get driver version. 00295 * 00296 * The function GetVersion() returns version information of the driver implementation in ARM_DRIVER_VERSION. 00297 * 00298 * - API version is the version of the CMSIS-Driver specification used to implement this driver. 00299 * - Driver version is source code version of the actual driver implementation. 00300 * 00301 * Example: 00302 * \code 00303 * extern ARM_DRIVER_STORAGE *drv_info; 00304 * 00305 * void read_version (void) { 00306 * ARM_DRIVER_VERSION version; 00307 * 00308 * version = drv_info->GetVersion (); 00309 * if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher 00310 * // error handling 00311 * return; 00312 * } 00313 * } 00314 * \endcode 00315 * 00316 * @return \ref ARM_DRIVER_VERSION. 00317 * 00318 * @note This API returns synchronously--it does not result in an invocation 00319 * of a completion callback. 00320 * 00321 * @note The function GetVersion() can be called any time to obtain the 00322 * required information from the driver (even before initialization). It 00323 * always returns the same information. 00324 */ 00325 ARM_DRIVER_VERSION (*GetVersion)(void); 00326 00327 /** 00328 * \brief Get driver capabilities. 00329 * 00330 * \details The function GetCapabilities() returns information about 00331 * capabilities in this driver implementation. The data fields of the struct 00332 * ARM_STORAGE_CAPABILITIES encode various capabilities, for example if the device 00333 * is able to execute operations asynchronously. 00334 * 00335 * Example: 00336 * \code 00337 * extern ARM_DRIVER_STORAGE *drv_info; 00338 * 00339 * void read_capabilities (void) { 00340 * ARM_STORAGE_CAPABILITIES drv_capabilities; 00341 * 00342 * drv_capabilities = drv_info->GetCapabilities (); 00343 * // interrogate capabilities 00344 * 00345 * } 00346 * \endcode 00347 * 00348 * @return \ref ARM_STORAGE_CAPABILITIES. 00349 * 00350 * @note This API returns synchronously--it does not result in an invocation 00351 * of a completion callback. 00352 * 00353 * @note The function GetCapabilities() can be called any time to obtain the 00354 * required information from the driver (even before initialization). It 00355 * always returns the same information. 00356 */ 00357 ARM_STORAGE_CAPABILITIES (*GetCapabilities)(void); 00358 00359 /** 00360 * \brief Initialize the Storage Interface. 00361 * 00362 * The function Initialize is called when the middleware component starts 00363 * operation. In addition to bringing the controller to a ready state, 00364 * Initialize() receives a callback handler to be invoked upon completion of 00365 * asynchronous operations. 00366 * 00367 * Initialize() needs to be called explicitly before 00368 * powering the peripheral using PowerControl(), and before initiating other 00369 * accesses to the storage controller. 00370 * 00371 * The function performs the following operations: 00372 * - Initializes the resources needed for the Storage interface. 00373 * - Registers the \ref ARM_Storage_Callback_t callback function. 00374 * 00375 * To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: 00376 * drv->Initialize (...); // Allocate I/O pins 00377 * drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA 00378 * 00379 * - Initialize() typically allocates the I/O resources (pins) for the 00380 * peripheral. The function can be called multiple times; if the I/O resources 00381 * are already initialized it performs no operation and just returns with 00382 * ARM_DRIVER_OK. 00383 * 00384 * - PowerControl (ARM_POWER_FULL) sets the peripheral registers including 00385 * interrupt (NVIC) and optionally DMA. The function can be called multiple 00386 * times; if the registers are already set it performs no operation and just 00387 * returns with ARM_DRIVER_OK. 00388 * 00389 * To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: 00390 * drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral 00391 * drv->Uninitialize (...); // Release I/O pins 00392 * 00393 * The functions PowerControl and Uninitialize always execute and can be used 00394 * to put the peripheral into a Safe State, for example after any data 00395 * transmission errors. To restart the peripheral in an error condition, 00396 * you should first execute the Stop Sequence and then the Start Sequence. 00397 * 00398 * @param [in] callback 00399 * Caller-defined callback to be invoked upon command completion 00400 * for asynchronous APIs (including the completion of 00401 * initialization). Use a NULL pointer when no callback 00402 * signals are required. 00403 * 00404 * @note This API may execute asynchronously if 00405 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00406 * execution is optional even if 'asynchronous_ops' is set. 00407 * 00408 * @return If asynchronous activity is launched, an invocation returns 00409 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00410 * future with a status value of ARM_DRIVER_OK or an error-code. In the 00411 * case of synchronous execution, control returns after completion with a 00412 * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. 00413 */ 00414 int32_t (*Initialize)(ARM_Storage_Callback_t callback); 00415 00416 /** 00417 * \brief De-initialize the Storage Interface. 00418 * 00419 * The function Uninitialize() de-initializes the resources of Storage interface. 00420 * 00421 * It is called when the middleware component stops operation, and wishes to 00422 * release the software resources used by the interface. 00423 * 00424 * @note This API may execute asynchronously if 00425 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00426 * execution is optional even if 'asynchronous_ops' is set. 00427 * 00428 * @return If asynchronous activity is launched, an invocation returns 00429 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00430 * future with a status value of ARM_DRIVER_OK or an error-code. In the 00431 * case of synchronous execution, control returns after completion with a 00432 * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. 00433 */ 00434 int32_t (*Uninitialize)(void); 00435 00436 /** 00437 * \brief Control the Storage interface power. 00438 * 00439 * The function \b ARM_Storage_PowerControl operates the power modes of the Storage interface. 00440 * 00441 * To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: 00442 * drv->Initialize (...); // Allocate I/O pins 00443 * drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA 00444 * 00445 * - Initialize() typically allocates the I/O resources (pins) for the 00446 * peripheral. The function can be called multiple times; if the I/O resources 00447 * are already initialized it performs no operation and just returns with 00448 * ARM_DRIVER_OK. 00449 * 00450 * - PowerControl (ARM_POWER_FULL) sets the peripheral registers including 00451 * interrupt (NVIC) and optionally DMA. The function can be called multiple 00452 * times; if the registers are already set it performs no operation and just 00453 * returns with ARM_DRIVER_OK. 00454 * 00455 * To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: 00456 * 00457 * drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral 00458 * drv->Uninitialize (...); // Release I/O pins 00459 * 00460 * The functions PowerControl and Uninitialize always execute and can be used 00461 * to put the peripheral into a Safe State, for example after any data 00462 * transmission errors. To restart the peripheral in an error condition, 00463 * you should first execute the Stop Sequence and then the Start Sequence. 00464 * 00465 * @param state 00466 * \ref ARM_POWER_STATE. The target power-state for the storage controller. 00467 * The parameter state can have the following values: 00468 * - ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts 00469 * (NVIC) and optionally DMA. Can be called multiple times. If the peripheral 00470 * is already in this mode, then the function performs no operation and returns 00471 * with ARM_DRIVER_OK. 00472 * - ARM_POWER_LOW : may use power saving. Returns ARM_DRIVER_ERROR_UNSUPPORTED when not implemented. 00473 * - ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA. 00474 * 00475 * @note This API may execute asynchronously if 00476 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00477 * execution is optional even if 'asynchronous_ops' is set. 00478 * 00479 * @return If asynchronous activity is launched, an invocation returns 00480 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00481 * future with a status value of ARM_DRIVER_OK or an error-code. In the 00482 * case of synchronous execution, control returns after completion with a 00483 * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. 00484 */ 00485 int32_t (*PowerControl)(ARM_POWER_STATE state); 00486 00487 /** 00488 * \brief read the contents of a given address range from the storage device. 00489 * 00490 * \details Read the contents of a range of storage memory into a buffer 00491 * supplied by the caller. The buffer is owned by the caller and should 00492 * remain accessible for the lifetime of this command. 00493 * 00494 * @param [in] addr 00495 * This specifies the address from where to read data. 00496 * 00497 * @param [out] data 00498 * The destination of the read operation. The buffer 00499 * is owned by the caller and should remain accessible for the 00500 * lifetime of this command. 00501 * 00502 * @param [in] size 00503 * The number of bytes requested to read. The data buffer 00504 * should be at least as large as this size. 00505 * 00506 * @note This API may execute asynchronously if 00507 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00508 * execution is optional even if 'asynchronous_ops' is set. 00509 * 00510 * @return If asynchronous activity is launched, an invocation returns 00511 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00512 * future with the number of successfully transferred bytes passed in as 00513 * the 'status' parameter. In the case of synchronous execution, control 00514 * returns after completion with a positive transfer-count. Return values 00515 * less than ARM_DRIVER_OK (0) signify errors. 00516 */ 00517 int32_t (*ReadData)(uint64_t addr, void *data, uint32_t size); 00518 00519 /** 00520 * \brief program (write into) the contents of a given address range of the storage device. 00521 * 00522 * \details Write the contents of a given memory buffer into a range of 00523 * storage memory. In the case of flash memory, the destination range in 00524 * storage memory typically has its contents in an erased state from a 00525 * preceding erase operation. The source memory buffer is owned by the 00526 * caller and should remain accessible for the lifetime of this command. 00527 * 00528 * @param [in] addr 00529 * This is the start address of the range to be written into. It 00530 * needs to be aligned to the device's \em program_unit 00531 * specified in \ref ARM_STORAGE_INFO. 00532 * 00533 * @param [in] data 00534 * The source of the write operation. The buffer is owned by the 00535 * caller and should remain accessible for the lifetime of this 00536 * command. 00537 * 00538 * @param [in] size 00539 * The number of bytes requested to be written. The buffer 00540 * should be at least as large as this size. \note 'size' should 00541 * be a multiple of the device's 'program_unit' (see \ref 00542 * ARM_STORAGE_INFO). 00543 * 00544 * @note It is best for the middleware to write in units of 00545 * 'optimal_program_unit' (\ref ARM_STORAGE_INFO) of the device. 00546 * 00547 * @note This API may execute asynchronously if 00548 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00549 * execution is optional even if 'asynchronous_ops' is set. 00550 * 00551 * @return If asynchronous activity is launched, an invocation returns 00552 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00553 * future with the number of successfully transferred bytes passed in as 00554 * the 'status' parameter. In the case of synchronous execution, control 00555 * returns after completion with a positive transfer-count. Return values 00556 * less than ARM_DRIVER_OK (0) signify errors. 00557 */ 00558 int32_t (*ProgramData)(uint64_t addr, const void *data, uint32_t size); 00559 00560 /** 00561 * @brief Erase Storage range. 00562 * 00563 * @details This function erases a range of storage specified by [addr, addr + 00564 * size). Both 'addr' and 'addr + size' should align with the 00565 * 'erase_unit'(s) of the respective owning storage block(s) (see \ref 00566 * ARM_STORAGE_BLOCK and \ref ARM_STORAGE_BLOCK_ATTRIBUTES). The range to 00567 * be erased will have its contents returned to the un-programmed state-- 00568 * i.e. to 'erased_value' (see \ref ARM_STORAGE_BLOCK_ATTRIBUTES), which 00569 * is usually 1 to indicate the pattern of all ones: 0xFF. 00570 * 00571 * @param [in] addr 00572 * This is the start-address of the range to be erased. It must 00573 * start at an 'erase_unit' boundary of the underlying block. 00574 * 00575 * @param [in] size 00576 * Size (in bytes) of the range to be erased. 'addr + size' 00577 * must be aligned with the 'erase_unit' of the underlying 00578 * block. 00579 * 00580 * @note This API may execute asynchronously if 00581 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00582 * execution is optional even if 'asynchronous_ops' is set. 00583 * 00584 * @return 00585 * If the range to be erased doesn't align with the erase_units of the 00586 * respective start and end blocks, ARM_DRIVER_ERROR_PARAMETER is returned. 00587 * If any part of the range is protected, ARM_STORAGE_ERROR_PROTECTED is 00588 * returned. If any part of the range is not erasable, 00589 * ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All such sanity-check 00590 * failures result in the error code being returned synchronously and the 00591 * storage bytes within the range remain unaffected. 00592 * Otherwise the function executes in the following ways: 00593 * If asynchronous activity is launched, an invocation returns 00594 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00595 * future with the number of successfully erased bytes passed in as 00596 * the 'status' parameter. In the case of synchronous execution, control 00597 * returns after completion with a positive erase-count. Return values 00598 * less than ARM_DRIVER_OK (0) signify errors. 00599 * 00600 * @note Erase() may return a smaller (positive) value than the size of the 00601 * requested range. The returned value indicates the actual number of bytes 00602 * erased. It is the caller's responsibility to follow up with an appropriate 00603 * request to complete the operation. 00604 * 00605 * @note in the case of a failed erase (except when 00606 * ARM_DRIVER_ERROR_PARAMETER, ARM_STORAGE_ERROR_PROTECTED, or 00607 * ARM_STORAGE_ERROR_NOT_ERASABLE is returned synchronously), the 00608 * requested range should be assumed to be in an unknown state. The 00609 * previous contents may not be retained. 00610 */ 00611 int32_t (*Erase)(uint64_t addr, uint32_t size); 00612 00613 /** 00614 * @brief Erase complete storage. Optional function for faster erase of the complete device. 00615 * 00616 * This optional function erases the complete device. If the device does not 00617 * support global erase then the function returns the error value \ref 00618 * ARM_DRIVER_ERROR_UNSUPPORTED. The data field \em 'erase_all' = 00619 * \token{1} of the structure \ref ARM_STORAGE_CAPABILITIES encodes that 00620 * \ref ARM_STORAGE_EraseAll is supported. 00621 * 00622 * @note This API may execute asynchronously if 00623 * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous 00624 * execution is optional even if 'asynchronous_ops' is set. 00625 * 00626 * @return 00627 * If any part of the storage range is protected, 00628 * ARM_STORAGE_ERROR_PROTECTED is returned. If any part of the storage 00629 * range is not erasable, ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All 00630 * such sanity-check failures result in the error code being returned 00631 * synchronously and the storage bytes within the range remain unaffected. 00632 * Otherwise the function executes in the following ways: 00633 * If asynchronous activity is launched, an invocation returns 00634 * ARM_DRIVER_OK, and the caller can expect to receive a callback in the 00635 * future with ARM_DRIVER_OK passed in as the 'status' parameter. In the 00636 * case of synchronous execution, control returns after completion with a 00637 * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. 00638 */ 00639 int32_t (*EraseAll)(void); 00640 00641 /** 00642 * @brief Get the status of the current (or previous) command executed by the 00643 * storage controller; stored in the structure \ref ARM_STORAGE_STATUS. 00644 * 00645 * @return 00646 * The status of the underlying controller. 00647 * 00648 * @note This API returns synchronously--it does not result in an invocation 00649 * of a completion callback. 00650 */ 00651 ARM_STORAGE_STATUS (*GetStatus)(void); 00652 00653 /** 00654 * @brief Get information about the Storage device; stored in the structure \ref ARM_STORAGE_INFO. 00655 * 00656 * @param [out] info 00657 * A caller-supplied buffer capable of being filled in with an 00658 * \ref ARM_STORAGE_INFO. 00659 * 00660 * @return ARM_DRIVER_OK if a ARM_STORAGE_INFO structure containing top level 00661 * metadata about the storage controller is filled into the supplied 00662 * buffer, else an appropriate error value. 00663 * 00664 * @note It is the caller's responsibility to ensure that the buffer passed in 00665 * is able to be initialized with a \ref ARM_STORAGE_INFO. 00666 * 00667 * @note This API returns synchronously--it does not result in an invocation 00668 * of a completion callback. 00669 */ 00670 int32_t (*GetInfo)(ARM_STORAGE_INFO *info); 00671 00672 /** 00673 * \brief For memory-mapped storage, resolve an address relative to 00674 * the storage controller into a memory address. 00675 * 00676 * @param addr 00677 * This is the address for which we want a resolution to the 00678 * processor's physical address space. It is an offset from the 00679 * start of the storage map maintained by the owning storage 00680 * controller. 00681 * 00682 * @return 00683 * The resolved address in the processor's address space; else 00684 * ARM_STORAGE_INVALID_ADDRESS, if no resolution is possible. 00685 * 00686 * @note This API returns synchronously. The invocation should return quickly, 00687 * and result in a resolved address. 00688 */ 00689 uint32_t (*ResolveAddress)(uint64_t addr); 00690 00691 /** 00692 * @brief Advance to the successor of the current block (iterator), or fetch 00693 * the first block (if 'prev_block' is passed in as NULL). 00694 * 00695 * @details This helper function fetches (an iterator to) the next block (or 00696 * the first block if 'prev_block' is passed in as NULL). In the failure 00697 * case, a terminating, invalid block iterator is filled into the out 00698 * parameter: 'next_block'. In combination with \ref 00699 * ARM_STORAGE_VALID_BLOCK(), it can be used to iterate over the sequence 00700 * of blocks within the storage map: 00701 * 00702 * \code 00703 * ARM_STORAGE_BLOCK block; 00704 * for (drv->GetNextBlock(NULL, &block); ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) { 00705 * // make use of block 00706 * } 00707 * \endcode 00708 * 00709 * @param[in] prev_block 00710 * An existing block (iterator) within the same storage 00711 * controller. The memory buffer holding this block is owned 00712 * by the caller. This pointer may be NULL; if so, the 00713 * invocation fills in the first block into the out parameter: 00714 * 'next_block'. 00715 * 00716 * @param[out] next_block 00717 * A caller-owned buffer large enough to be filled in with 00718 * the following ARM_STORAGE_BLOCK. It is legal to provide the 00719 * same buffer using 'next_block' as was passed in with 'prev_block'. It 00720 * is also legal to pass a NULL into this parameter if the 00721 * caller isn't interested in populating a buffer with the next 00722 * block--i.e. if the caller only wishes to establish the 00723 * presence of a next block. 00724 * 00725 * @return ARM_DRIVER_OK if a valid next block is found (or first block, if 00726 * prev_block is passed as NULL); upon successful operation, the contents 00727 * of the next (or first) block are filled into the buffer pointed to by 00728 * the parameter 'next_block' and ARM_STORAGE_VALID_BLOCK(next_block) is 00729 * guaranteed to be true. Upon reaching the end of the sequence of blocks 00730 * (iterators), or in case the driver is unable to fetch information about 00731 * the next (or first) block, an error (negative) value is returned and an 00732 * invalid StorageBlock is populated into the supplied buffer. If 00733 * prev_block is NULL, the first block is returned. 00734 * 00735 * @note This API returns synchronously--it does not result in an invocation 00736 * of a completion callback. 00737 */ 00738 int32_t (*GetNextBlock)(const ARM_STORAGE_BLOCK* prev_block, ARM_STORAGE_BLOCK *next_block); 00739 00740 /** 00741 * @brief Find the storage block (iterator) encompassing a given storage address. 00742 * 00743 * @param[in] addr 00744 * Storage address in bytes. 00745 * 00746 * @param[out] block 00747 * A caller-owned buffer large enough to be filled in with the 00748 * ARM_STORAGE_BLOCK encapsulating the given address. This value 00749 * can also be passed in as NULL if the caller isn't interested 00750 * in populating a buffer with the block--if the caller only 00751 * wishes to establish the presence of a containing storage 00752 * block. 00753 * 00754 * @return ARM_DRIVER_OK if a containing storage-block is found. In this case, 00755 * if block is non-NULL, the buffer pointed to by it is populated with 00756 * the contents of the storage block--i.e. if block is valid and a block is 00757 * found, ARM_STORAGE_VALID_BLOCK(block) would return true following this 00758 * call. If there is no storage block containing the given offset, or in 00759 * case the driver is unable to resolve an address to a storage-block, an 00760 * error (negative) value is returned and an invalid StorageBlock is 00761 * populated into the supplied buffer. 00762 * 00763 * @note This API returns synchronously--it does not result in an invocation 00764 * of a completion callback. 00765 */ 00766 int32_t (*GetBlock)(uint64_t addr, ARM_STORAGE_BLOCK *block); 00767 } const ARM_DRIVER_STORAGE; 00768 00769 #ifdef __cplusplus 00770 } 00771 #endif // __cplusplus 00772 00773 #endif /* __DRIVER_STORAGE_H */ 00774 00775 /** @}*/ 00776
Generated on Tue Jul 12 2022 14:46:33 by
