mbed library for slider v2
Driver_Storage.h@0:b7116bd48af6, 2016-09-14 (annotated)
- Committer:
- mturner5
- Date:
- Wed Sep 14 07:04:27 2016 +0000
- Revision:
- 0:b7116bd48af6
Tried to use the timer.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mturner5 | 0:b7116bd48af6 | 1 | /* |
mturner5 | 0:b7116bd48af6 | 2 | * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved |
mturner5 | 0:b7116bd48af6 | 3 | * SPDX-License-Identifier: Apache-2.0 |
mturner5 | 0:b7116bd48af6 | 4 | * |
mturner5 | 0:b7116bd48af6 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
mturner5 | 0:b7116bd48af6 | 6 | * not use this file except in compliance with the License. |
mturner5 | 0:b7116bd48af6 | 7 | * You may obtain a copy of the License at |
mturner5 | 0:b7116bd48af6 | 8 | * |
mturner5 | 0:b7116bd48af6 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
mturner5 | 0:b7116bd48af6 | 10 | * |
mturner5 | 0:b7116bd48af6 | 11 | * Unless required by applicable law or agreed to in writing, software |
mturner5 | 0:b7116bd48af6 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
mturner5 | 0:b7116bd48af6 | 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mturner5 | 0:b7116bd48af6 | 14 | * See the License for the specific language governing permissions and |
mturner5 | 0:b7116bd48af6 | 15 | * limitations under the License. |
mturner5 | 0:b7116bd48af6 | 16 | */ |
mturner5 | 0:b7116bd48af6 | 17 | |
mturner5 | 0:b7116bd48af6 | 18 | #ifndef __DRIVER_STORAGE_H |
mturner5 | 0:b7116bd48af6 | 19 | #define __DRIVER_STORAGE_H |
mturner5 | 0:b7116bd48af6 | 20 | |
mturner5 | 0:b7116bd48af6 | 21 | #include <stdint.h> |
mturner5 | 0:b7116bd48af6 | 22 | |
mturner5 | 0:b7116bd48af6 | 23 | #ifdef __cplusplus |
mturner5 | 0:b7116bd48af6 | 24 | extern "C" { |
mturner5 | 0:b7116bd48af6 | 25 | #endif // __cplusplus |
mturner5 | 0:b7116bd48af6 | 26 | |
mturner5 | 0:b7116bd48af6 | 27 | #include "Driver_Common.h" |
mturner5 | 0:b7116bd48af6 | 28 | |
mturner5 | 0:b7116bd48af6 | 29 | #define ARM_STORAGE_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,00) /* API version */ |
mturner5 | 0:b7116bd48af6 | 30 | |
mturner5 | 0:b7116bd48af6 | 31 | |
mturner5 | 0:b7116bd48af6 | 32 | #define _ARM_Driver_Storage_(n) Driver_Storage##n |
mturner5 | 0:b7116bd48af6 | 33 | #define ARM_Driver_Storage_(n) _ARM_Driver_Storage_(n) |
mturner5 | 0:b7116bd48af6 | 34 | |
mturner5 | 0:b7116bd48af6 | 35 | #define ARM_STORAGE_INVALID_OFFSET (0xFFFFFFFFFFFFFFFFULL) ///< Invalid address (relative to a storage controller's |
mturner5 | 0:b7116bd48af6 | 36 | ///< address space). A storage block may never start at this address. |
mturner5 | 0:b7116bd48af6 | 37 | |
mturner5 | 0:b7116bd48af6 | 38 | #define ARM_STORAGE_INVALID_ADDRESS (0xFFFFFFFFUL) ///< Invalid address within the processor's memory address space. |
mturner5 | 0:b7116bd48af6 | 39 | ///< Refer to memory-mapped storage, i.e. < \ref ARM_DRIVER_STORAGE::ResolveAddress(). |
mturner5 | 0:b7116bd48af6 | 40 | |
mturner5 | 0:b7116bd48af6 | 41 | /****** Storage specific error codes *****/ |
mturner5 | 0:b7116bd48af6 | 42 | #define ARM_STORAGE_ERROR_NOT_ERASABLE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Part (or all) of the range provided to Erase() isn't erasable. |
mturner5 | 0:b7116bd48af6 | 43 | #define ARM_STORAGE_ERROR_NOT_PROGRAMMABLE (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Part (or all) of the range provided to ProgramData() isn't programmable. |
mturner5 | 0:b7116bd48af6 | 44 | #define ARM_STORAGE_ERROR_PROTECTED (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Part (or all) of the range to Erase() or ProgramData() is protected. |
mturner5 | 0:b7116bd48af6 | 45 | #define ARM_STORAGE_ERROR_RUNTIME_OR_INTEGRITY_FAILURE (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Runtime or sanity-check failure. |
mturner5 | 0:b7116bd48af6 | 46 | |
mturner5 | 0:b7116bd48af6 | 47 | /** |
mturner5 | 0:b7116bd48af6 | 48 | * \brief Attributes of the storage range within a storage block. |
mturner5 | 0:b7116bd48af6 | 49 | */ |
mturner5 | 0:b7116bd48af6 | 50 | typedef struct _ARM_STORAGE_BLOCK_ATTRIBUTES { |
mturner5 | 0:b7116bd48af6 | 51 | uint32_t erasable : 1; ///< Erasing blocks is permitted with a minimum granularity of 'erase_unit'. |
mturner5 | 0:b7116bd48af6 | 52 | ///< @note: if 'erasable' is 0--i.e. the 'erase' operation isn't available--then |
mturner5 | 0:b7116bd48af6 | 53 | ///< 'erase_unit' (see below) is immaterial and should be 0. |
mturner5 | 0:b7116bd48af6 | 54 | uint32_t programmable : 1; ///< Writing to ranges is permitted with a minimum granularity of 'program_unit'. |
mturner5 | 0:b7116bd48af6 | 55 | ///< Writes are typically achieved through the ProgramData operation (following an erase); |
mturner5 | 0:b7116bd48af6 | 56 | ///< if storage isn't erasable (see 'erasable' above) but is memory-mapped |
mturner5 | 0:b7116bd48af6 | 57 | ///< (i.e. 'memory_mapped'), it can be written directly using memory-store operations. |
mturner5 | 0:b7116bd48af6 | 58 | uint32_t executable : 1; ///< This storage block can hold program data; the processor can fetch and execute code |
mturner5 | 0:b7116bd48af6 | 59 | ///< sourced from it. Often this is accompanied with the device being 'memory_mapped' (see \ref ARM_STORAGE_INFO). |
mturner5 | 0:b7116bd48af6 | 60 | uint32_t protectable : 1; ///< The entire block can be protected from program and erase operations. Once protection |
mturner5 | 0:b7116bd48af6 | 61 | ///< is enabled for a block, its 'erasable' and 'programmable' bits are turned off. |
mturner5 | 0:b7116bd48af6 | 62 | uint32_t reserved : 28; |
mturner5 | 0:b7116bd48af6 | 63 | uint32_t erase_unit; ///< Minimum erase size in bytes. |
mturner5 | 0:b7116bd48af6 | 64 | ///< The offset of the start of the erase-range should also be aligned with this value. |
mturner5 | 0:b7116bd48af6 | 65 | ///< Applicable if the 'erasable' attribute is set for the block. |
mturner5 | 0:b7116bd48af6 | 66 | ///< @note: if 'erasable' (see above) is 0--i.e. the 'erase' operation isn't available--then |
mturner5 | 0:b7116bd48af6 | 67 | ///< 'erase_unit' is immaterial and should be 0. |
mturner5 | 0:b7116bd48af6 | 68 | uint32_t protection_unit; ///< Minimum protectable size in bytes. Applicable if the 'protectable' |
mturner5 | 0:b7116bd48af6 | 69 | ///< attribute is set for the block. This should be a divisor of the block's size. A |
mturner5 | 0:b7116bd48af6 | 70 | ///< block can be considered to be made up of consecutive, individually-protectable fragments. |
mturner5 | 0:b7116bd48af6 | 71 | } ARM_STORAGE_BLOCK_ATTRIBUTES; |
mturner5 | 0:b7116bd48af6 | 72 | |
mturner5 | 0:b7116bd48af6 | 73 | /** |
mturner5 | 0:b7116bd48af6 | 74 | * \brief A storage block is a range of memory with uniform attributes. Storage blocks |
mturner5 | 0:b7116bd48af6 | 75 | * combine to make up the address map of a storage controller. |
mturner5 | 0:b7116bd48af6 | 76 | */ |
mturner5 | 0:b7116bd48af6 | 77 | typedef struct _ARM_STORAGE_BLOCK { |
mturner5 | 0:b7116bd48af6 | 78 | uint64_t addr; ///< This is the start address of the storage block. It is |
mturner5 | 0:b7116bd48af6 | 79 | ///< expressed as an offset from the start of the storage map |
mturner5 | 0:b7116bd48af6 | 80 | ///< maintained by the owning storage controller. |
mturner5 | 0:b7116bd48af6 | 81 | uint64_t size; ///< This is the size of the storage block, in units of bytes. |
mturner5 | 0:b7116bd48af6 | 82 | ///< Together with addr, it describes a range [addr, addr+size). |
mturner5 | 0:b7116bd48af6 | 83 | ARM_STORAGE_BLOCK_ATTRIBUTES attributes; ///< Attributes for this block. |
mturner5 | 0:b7116bd48af6 | 84 | } ARM_STORAGE_BLOCK; |
mturner5 | 0:b7116bd48af6 | 85 | |
mturner5 | 0:b7116bd48af6 | 86 | /** |
mturner5 | 0:b7116bd48af6 | 87 | * The check for a valid ARM_STORAGE_BLOCK. |
mturner5 | 0:b7116bd48af6 | 88 | */ |
mturner5 | 0:b7116bd48af6 | 89 | #define ARM_STORAGE_VALID_BLOCK(BLK) (((BLK)->addr != ARM_STORAGE_INVALID_OFFSET) && ((BLK)->size != 0)) |
mturner5 | 0:b7116bd48af6 | 90 | |
mturner5 | 0:b7116bd48af6 | 91 | /** |
mturner5 | 0:b7116bd48af6 | 92 | * \brief Values for encoding storage memory-types with respect to programmability. |
mturner5 | 0:b7116bd48af6 | 93 | * |
mturner5 | 0:b7116bd48af6 | 94 | * Please ensure that the maximum of the following memory types doesn't exceed 16; we |
mturner5 | 0:b7116bd48af6 | 95 | * encode this in a 4-bit field within ARM_STORAGE_INFO::programmability. |
mturner5 | 0:b7116bd48af6 | 96 | */ |
mturner5 | 0:b7116bd48af6 | 97 | #define ARM_STORAGE_PROGRAMMABILITY_RAM (0x0) |
mturner5 | 0:b7116bd48af6 | 98 | #define ARM_STORAGE_PROGRAMMABILITY_ROM (0x1) ///< Read-only memory. |
mturner5 | 0:b7116bd48af6 | 99 | #define ARM_STORAGE_PROGRAMMABILITY_WORM (0x2) ///< write-once-read-only-memory (WORM). |
mturner5 | 0:b7116bd48af6 | 100 | #define ARM_STORAGE_PROGRAMMABILITY_ERASABLE (0x3) ///< re-programmable based on erase. Supports multiple writes. |
mturner5 | 0:b7116bd48af6 | 101 | |
mturner5 | 0:b7116bd48af6 | 102 | /** |
mturner5 | 0:b7116bd48af6 | 103 | * Values for encoding data-retention levels for storage blocks. |
mturner5 | 0:b7116bd48af6 | 104 | * |
mturner5 | 0:b7116bd48af6 | 105 | * Please ensure that the maximum of the following retention types doesn't exceed 16; we |
mturner5 | 0:b7116bd48af6 | 106 | * encode this in a 4-bit field within ARM_STORAGE_INFO::retention_level. |
mturner5 | 0:b7116bd48af6 | 107 | */ |
mturner5 | 0:b7116bd48af6 | 108 | #define ARM_RETENTION_WHILE_DEVICE_ACTIVE (0x0) ///< Data is retained only during device activity. |
mturner5 | 0:b7116bd48af6 | 109 | #define ARM_RETENTION_ACROSS_SLEEP (0x1) ///< Data is retained across processor sleep. |
mturner5 | 0:b7116bd48af6 | 110 | #define ARM_RETENTION_ACROSS_DEEP_SLEEP (0x2) ///< Data is retained across processor deep-sleep. |
mturner5 | 0:b7116bd48af6 | 111 | #define ARM_RETENTION_BATTERY_BACKED (0x3) ///< Data is battery-backed. Device can be powered off. |
mturner5 | 0:b7116bd48af6 | 112 | #define ARM_RETENTION_NVM (0x4) ///< Data is retained in non-volatile memory. |
mturner5 | 0:b7116bd48af6 | 113 | |
mturner5 | 0:b7116bd48af6 | 114 | /** |
mturner5 | 0:b7116bd48af6 | 115 | * Device Data Security Protection Features. Applicable mostly to EXTERNAL_NVM. |
mturner5 | 0:b7116bd48af6 | 116 | */ |
mturner5 | 0:b7116bd48af6 | 117 | typedef struct _ARM_STORAGE_SECURITY_FEATURES { |
mturner5 | 0:b7116bd48af6 | 118 | uint32_t acls : 1; ///< Protection against internal software attacks using ACLs. |
mturner5 | 0:b7116bd48af6 | 119 | uint32_t rollback_protection : 1; ///< Roll-back protection. Set to true if the creator of the storage |
mturner5 | 0:b7116bd48af6 | 120 | ///< can ensure that an external attacker can't force an |
mturner5 | 0:b7116bd48af6 | 121 | ///< older firmware to run or to revert back to a previous state. |
mturner5 | 0:b7116bd48af6 | 122 | uint32_t tamper_proof : 1; ///< Tamper-proof memory (will be deleted on tamper-attempts using board level or chip level sensors). |
mturner5 | 0:b7116bd48af6 | 123 | uint32_t internal_flash : 1; ///< Internal flash. |
mturner5 | 0:b7116bd48af6 | 124 | uint32_t reserved1 : 12; |
mturner5 | 0:b7116bd48af6 | 125 | |
mturner5 | 0:b7116bd48af6 | 126 | /** |
mturner5 | 0:b7116bd48af6 | 127 | * Encode support for hardening against various classes of attacks. |
mturner5 | 0:b7116bd48af6 | 128 | */ |
mturner5 | 0:b7116bd48af6 | 129 | uint32_t software_attacks : 1; ///< device software (malware running on the device). |
mturner5 | 0:b7116bd48af6 | 130 | uint32_t board_level_attacks : 1; ///< board level attacks (debug probes, copy protection fuses.) |
mturner5 | 0:b7116bd48af6 | 131 | uint32_t chip_level_attacks : 1; ///< chip level attacks (tamper-protection). |
mturner5 | 0:b7116bd48af6 | 132 | uint32_t side_channel_attacks : 1; ///< side channel attacks. |
mturner5 | 0:b7116bd48af6 | 133 | uint32_t reserved2 : 12; |
mturner5 | 0:b7116bd48af6 | 134 | } ARM_STORAGE_SECURITY_FEATURES; |
mturner5 | 0:b7116bd48af6 | 135 | |
mturner5 | 0:b7116bd48af6 | 136 | #define ARM_STORAGE_PROGRAM_CYCLES_INFINITE (0UL) /**< Infinite or unknown endurance for reprogramming. */ |
mturner5 | 0:b7116bd48af6 | 137 | |
mturner5 | 0:b7116bd48af6 | 138 | /** |
mturner5 | 0:b7116bd48af6 | 139 | * \brief Storage information. This contains device-metadata. It is the return |
mturner5 | 0:b7116bd48af6 | 140 | * value from calling GetInfo() on the storage driver. |
mturner5 | 0:b7116bd48af6 | 141 | * |
mturner5 | 0:b7116bd48af6 | 142 | * \details These fields serve a different purpose than the ones contained in |
mturner5 | 0:b7116bd48af6 | 143 | * \ref ARM_STORAGE_CAPABILITIES, which is another structure containing |
mturner5 | 0:b7116bd48af6 | 144 | * device-level metadata. ARM_STORAGE_CAPABILITIES describes the API |
mturner5 | 0:b7116bd48af6 | 145 | * capabilities, whereas ARM_STORAGE_INFO describes the device. Furthermore |
mturner5 | 0:b7116bd48af6 | 146 | * ARM_STORAGE_CAPABILITIES fits within a single word, and is designed to be |
mturner5 | 0:b7116bd48af6 | 147 | * passed around by value; ARM_STORAGE_INFO, on the other hand, contains |
mturner5 | 0:b7116bd48af6 | 148 | * metadata which doesn't fit into a single word and requires the use of |
mturner5 | 0:b7116bd48af6 | 149 | * pointers to be moved around. |
mturner5 | 0:b7116bd48af6 | 150 | */ |
mturner5 | 0:b7116bd48af6 | 151 | typedef struct _ARM_STORAGE_INFO { |
mturner5 | 0:b7116bd48af6 | 152 | uint64_t total_storage; ///< Total available storage, in bytes. |
mturner5 | 0:b7116bd48af6 | 153 | uint32_t program_unit; ///< Minimum programming size in bytes. |
mturner5 | 0:b7116bd48af6 | 154 | ///< The offset of the start of the program-range should also be aligned with this value. |
mturner5 | 0:b7116bd48af6 | 155 | ///< Applicable only if the 'programmable' attribute is set for a block. |
mturner5 | 0:b7116bd48af6 | 156 | ///< @note: setting program_unit to 0 has the effect of disabling the size and alignment |
mturner5 | 0:b7116bd48af6 | 157 | ///< restrictions (setting it to 1 also has the same effect). |
mturner5 | 0:b7116bd48af6 | 158 | uint32_t optimal_program_unit; ///< Optimal programming page-size in bytes. Some storage controllers |
mturner5 | 0:b7116bd48af6 | 159 | ///< have internal buffers into which to receive data. Writing in chunks of |
mturner5 | 0:b7116bd48af6 | 160 | ///< 'optimal_program_unit' would achieve maximum programming speed. |
mturner5 | 0:b7116bd48af6 | 161 | ///< Applicable only if the 'programmable' attribute is set for the underlying block(s). |
mturner5 | 0:b7116bd48af6 | 162 | uint32_t program_cycles; ///< A measure of endurance for reprogramming. |
mturner5 | 0:b7116bd48af6 | 163 | ///< Use ARM_STORAGE_PROGRAM_CYCLES_INFINITE for infinite or unknown endurance. |
mturner5 | 0:b7116bd48af6 | 164 | uint32_t erased_value : 1; ///< Contents of erased memory (usually 1 to indicate erased bytes with state 0xFF). |
mturner5 | 0:b7116bd48af6 | 165 | uint32_t memory_mapped : 1; ///< This storage device has a mapping onto the processor's memory address space. |
mturner5 | 0:b7116bd48af6 | 166 | ///< @note: For a memory-mapped block which isn't erasable but is programmable (i.e. if |
mturner5 | 0:b7116bd48af6 | 167 | ///< 'erasable' is set to 0, but 'programmable' is 1), writes should be possible directly to |
mturner5 | 0:b7116bd48af6 | 168 | ///< the memory-mapped storage without going through the ProgramData operation. |
mturner5 | 0:b7116bd48af6 | 169 | uint32_t programmability : 4; ///< A value to indicate storage programmability. |
mturner5 | 0:b7116bd48af6 | 170 | uint32_t retention_level : 4; |
mturner5 | 0:b7116bd48af6 | 171 | uint32_t reserved : 22; |
mturner5 | 0:b7116bd48af6 | 172 | ARM_STORAGE_SECURITY_FEATURES security; ///< \ref ARM_STORAGE_SECURITY_FEATURES |
mturner5 | 0:b7116bd48af6 | 173 | } ARM_STORAGE_INFO; |
mturner5 | 0:b7116bd48af6 | 174 | |
mturner5 | 0:b7116bd48af6 | 175 | /** |
mturner5 | 0:b7116bd48af6 | 176 | \brief Operating status of the storage controller. |
mturner5 | 0:b7116bd48af6 | 177 | */ |
mturner5 | 0:b7116bd48af6 | 178 | typedef struct _ARM_STORAGE_STATUS { |
mturner5 | 0:b7116bd48af6 | 179 | uint32_t busy : 1; ///< Controller busy flag |
mturner5 | 0:b7116bd48af6 | 180 | uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation) |
mturner5 | 0:b7116bd48af6 | 181 | } ARM_STORAGE_STATUS; |
mturner5 | 0:b7116bd48af6 | 182 | |
mturner5 | 0:b7116bd48af6 | 183 | /** |
mturner5 | 0:b7116bd48af6 | 184 | * \brief Storage Driver API Capabilities. |
mturner5 | 0:b7116bd48af6 | 185 | * |
mturner5 | 0:b7116bd48af6 | 186 | * This data structure is designed to fit within a single word so that it can be |
mturner5 | 0:b7116bd48af6 | 187 | * fetched cheaply using a call to driver->GetCapabilities(). |
mturner5 | 0:b7116bd48af6 | 188 | */ |
mturner5 | 0:b7116bd48af6 | 189 | typedef struct _ARM_STORAGE_CAPABILITIES { |
mturner5 | 0:b7116bd48af6 | 190 | uint32_t asynchronous_ops : 1; ///< Used to indicate if APIs like initialize, |
mturner5 | 0:b7116bd48af6 | 191 | ///< read, erase, program, etc. can operate in asynchronous mode. |
mturner5 | 0:b7116bd48af6 | 192 | ///< Setting this bit to 1 means that the driver is capable |
mturner5 | 0:b7116bd48af6 | 193 | ///< of launching asynchronous operations; command completion is |
mturner5 | 0:b7116bd48af6 | 194 | ///< signaled by the invocation of a completion callback. If |
mturner5 | 0:b7116bd48af6 | 195 | ///< set to 1, drivers may still complete asynchronous |
mturner5 | 0:b7116bd48af6 | 196 | ///< operations synchronously as necessary--in which case they |
mturner5 | 0:b7116bd48af6 | 197 | ///< return a positive error code to indicate synchronous completion. |
mturner5 | 0:b7116bd48af6 | 198 | uint32_t erase_all : 1; ///< Supports EraseAll operation. |
mturner5 | 0:b7116bd48af6 | 199 | uint32_t reserved : 30; |
mturner5 | 0:b7116bd48af6 | 200 | } ARM_STORAGE_CAPABILITIES; |
mturner5 | 0:b7116bd48af6 | 201 | |
mturner5 | 0:b7116bd48af6 | 202 | /** |
mturner5 | 0:b7116bd48af6 | 203 | * Command opcodes for Storage. Completion callbacks use these codes to refer to |
mturner5 | 0:b7116bd48af6 | 204 | * completing commands. Refer to \ref ARM_Storage_Callback_t. |
mturner5 | 0:b7116bd48af6 | 205 | */ |
mturner5 | 0:b7116bd48af6 | 206 | typedef enum _ARM_STORAGE_OPERATION { |
mturner5 | 0:b7116bd48af6 | 207 | ARM_STORAGE_OPERATION_GET_VERSION, |
mturner5 | 0:b7116bd48af6 | 208 | ARM_STORAGE_OPERATION_GET_CAPABILITIES, |
mturner5 | 0:b7116bd48af6 | 209 | ARM_STORAGE_OPERATION_INITIALIZE, |
mturner5 | 0:b7116bd48af6 | 210 | ARM_STORAGE_OPERATION_UNINITIALIZE, |
mturner5 | 0:b7116bd48af6 | 211 | ARM_STORAGE_OPERATION_POWER_CONTROL, |
mturner5 | 0:b7116bd48af6 | 212 | ARM_STORAGE_OPERATION_READ_DATA, |
mturner5 | 0:b7116bd48af6 | 213 | ARM_STORAGE_OPERATION_PROGRAM_DATA, |
mturner5 | 0:b7116bd48af6 | 214 | ARM_STORAGE_OPERATION_ERASE, |
mturner5 | 0:b7116bd48af6 | 215 | ARM_STORAGE_OPERATION_ERASE_ALL, |
mturner5 | 0:b7116bd48af6 | 216 | ARM_STORAGE_OPERATION_GET_STATUS, |
mturner5 | 0:b7116bd48af6 | 217 | ARM_STORAGE_OPERATION_GET_INFO, |
mturner5 | 0:b7116bd48af6 | 218 | ARM_STORAGE_OPERATION_RESOLVE_ADDRESS, |
mturner5 | 0:b7116bd48af6 | 219 | ARM_STORAGE_OPERATION_GET_NEXT_BLOCK, |
mturner5 | 0:b7116bd48af6 | 220 | ARM_STORAGE_OPERATION_GET_BLOCK |
mturner5 | 0:b7116bd48af6 | 221 | } ARM_STORAGE_OPERATION; |
mturner5 | 0:b7116bd48af6 | 222 | |
mturner5 | 0:b7116bd48af6 | 223 | /** |
mturner5 | 0:b7116bd48af6 | 224 | * Declaration of the callback-type for command completion. |
mturner5 | 0:b7116bd48af6 | 225 | * |
mturner5 | 0:b7116bd48af6 | 226 | * @param [in] status |
mturner5 | 0:b7116bd48af6 | 227 | * A code to indicate the status of the completed operation. For data |
mturner5 | 0:b7116bd48af6 | 228 | * transfer operations, the status field is overloaded in case of |
mturner5 | 0:b7116bd48af6 | 229 | * success to return the count of items successfully transferred; this |
mturner5 | 0:b7116bd48af6 | 230 | * can be done safely because error codes are negative values. |
mturner5 | 0:b7116bd48af6 | 231 | * |
mturner5 | 0:b7116bd48af6 | 232 | * @param [in] operation |
mturner5 | 0:b7116bd48af6 | 233 | * The command op-code. This value isn't essential for the callback in |
mturner5 | 0:b7116bd48af6 | 234 | * the presence of the command instance-id, but it is expected that |
mturner5 | 0:b7116bd48af6 | 235 | * this information could be a quick and useful filter. |
mturner5 | 0:b7116bd48af6 | 236 | */ |
mturner5 | 0:b7116bd48af6 | 237 | typedef void (*ARM_Storage_Callback_t)(int32_t status, ARM_STORAGE_OPERATION operation); |
mturner5 | 0:b7116bd48af6 | 238 | |
mturner5 | 0:b7116bd48af6 | 239 | /** |
mturner5 | 0:b7116bd48af6 | 240 | * This is the set of operations constituting the Storage driver. Their |
mturner5 | 0:b7116bd48af6 | 241 | * implementation is platform-specific, and needs to be supplied by the |
mturner5 | 0:b7116bd48af6 | 242 | * porting effort. |
mturner5 | 0:b7116bd48af6 | 243 | * |
mturner5 | 0:b7116bd48af6 | 244 | * Some APIs within `ARM_DRIVER_STORAGE` will always operate synchronously: |
mturner5 | 0:b7116bd48af6 | 245 | * GetVersion, GetCapabilities, GetStatus, GetInfo, ResolveAddress, |
mturner5 | 0:b7116bd48af6 | 246 | * GetNextBlock, and GetBlock. This means that control returns to the caller |
mturner5 | 0:b7116bd48af6 | 247 | * with a relevant status code only after the completion of the operation (or |
mturner5 | 0:b7116bd48af6 | 248 | * the discovery of a failure condition). |
mturner5 | 0:b7116bd48af6 | 249 | * |
mturner5 | 0:b7116bd48af6 | 250 | * The remainder of the APIs: Initialize, Uninitialize, PowerControl, ReadData, |
mturner5 | 0:b7116bd48af6 | 251 | * ProgramData, Erase, EraseAll, can function asynchronously if the underlying |
mturner5 | 0:b7116bd48af6 | 252 | * controller supports it--i.e. if ARM_STORAGE_CAPABILITIES::asynchronous_ops is |
mturner5 | 0:b7116bd48af6 | 253 | * set. In the case of asynchronous operation, the invocation returns early |
mturner5 | 0:b7116bd48af6 | 254 | * (with ARM_DRIVER_OK) and results in a completion callback later. If |
mturner5 | 0:b7116bd48af6 | 255 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is not set, then all such APIs |
mturner5 | 0:b7116bd48af6 | 256 | * execute synchronously, and control returns to the caller with a status code |
mturner5 | 0:b7116bd48af6 | 257 | * only after the completion of the operation (or the discovery of a failure |
mturner5 | 0:b7116bd48af6 | 258 | * condition). |
mturner5 | 0:b7116bd48af6 | 259 | * |
mturner5 | 0:b7116bd48af6 | 260 | * If ARM_STORAGE_CAPABILITIES::asynchronous_ops is set, a storage driver may |
mturner5 | 0:b7116bd48af6 | 261 | * still choose to execute asynchronous operations in a synchronous manner. If |
mturner5 | 0:b7116bd48af6 | 262 | * so, the driver returns a positive value to indicate successful synchronous |
mturner5 | 0:b7116bd48af6 | 263 | * completion (or an error code in case of failure) and no further invocation of |
mturner5 | 0:b7116bd48af6 | 264 | * completion callback should be expected. The expected return value for |
mturner5 | 0:b7116bd48af6 | 265 | * synchronous completion of such asynchronous operations varies depending on |
mturner5 | 0:b7116bd48af6 | 266 | * the operation. For operations involving data access, it often equals the |
mturner5 | 0:b7116bd48af6 | 267 | * amount of data transferred or affected. For non data-transfer operations, |
mturner5 | 0:b7116bd48af6 | 268 | * such as EraseAll or Initialize, it is usually 1. |
mturner5 | 0:b7116bd48af6 | 269 | * |
mturner5 | 0:b7116bd48af6 | 270 | * Here's a code snippet to suggest how asynchronous APIs might be used by |
mturner5 | 0:b7116bd48af6 | 271 | * callers to handle both synchronous and asynchronous execution by the |
mturner5 | 0:b7116bd48af6 | 272 | * underlying storage driver: |
mturner5 | 0:b7116bd48af6 | 273 | * \code |
mturner5 | 0:b7116bd48af6 | 274 | * ASSERT(ARM_DRIVER_OK == 0); // this is a precondition; it doesn't need to be put in code |
mturner5 | 0:b7116bd48af6 | 275 | * int32_t returnValue = drv->asynchronousAPI(...); |
mturner5 | 0:b7116bd48af6 | 276 | * if (returnValue < ARM_DRIVER_OK) { |
mturner5 | 0:b7116bd48af6 | 277 | * // handle error. |
mturner5 | 0:b7116bd48af6 | 278 | * } else if (returnValue == ARM_DRIVER_OK) { |
mturner5 | 0:b7116bd48af6 | 279 | * ASSERT(drv->GetCapabilities().asynchronous_ops == 1); |
mturner5 | 0:b7116bd48af6 | 280 | * // handle early return from asynchronous execution; remainder of the work is done in the callback handler. |
mturner5 | 0:b7116bd48af6 | 281 | * } else { |
mturner5 | 0:b7116bd48af6 | 282 | * ASSERT(returnValue == EXPECTED_RETURN_VALUE_FOR_SYNCHRONOUS_COMPLETION); |
mturner5 | 0:b7116bd48af6 | 283 | * // handle synchronous completion. |
mturner5 | 0:b7116bd48af6 | 284 | * } |
mturner5 | 0:b7116bd48af6 | 285 | * \endcode |
mturner5 | 0:b7116bd48af6 | 286 | */ |
mturner5 | 0:b7116bd48af6 | 287 | typedef struct _ARM_DRIVER_STORAGE { |
mturner5 | 0:b7116bd48af6 | 288 | /** |
mturner5 | 0:b7116bd48af6 | 289 | * \brief Get driver version. |
mturner5 | 0:b7116bd48af6 | 290 | * |
mturner5 | 0:b7116bd48af6 | 291 | * The function GetVersion() returns version information of the driver implementation in ARM_DRIVER_VERSION. |
mturner5 | 0:b7116bd48af6 | 292 | * |
mturner5 | 0:b7116bd48af6 | 293 | * - API version is the version of the CMSIS-Driver specification used to implement this driver. |
mturner5 | 0:b7116bd48af6 | 294 | * - Driver version is source code version of the actual driver implementation. |
mturner5 | 0:b7116bd48af6 | 295 | * |
mturner5 | 0:b7116bd48af6 | 296 | * Example: |
mturner5 | 0:b7116bd48af6 | 297 | * \code |
mturner5 | 0:b7116bd48af6 | 298 | * extern ARM_DRIVER_STORAGE *drv_info; |
mturner5 | 0:b7116bd48af6 | 299 | * |
mturner5 | 0:b7116bd48af6 | 300 | * void read_version (void) { |
mturner5 | 0:b7116bd48af6 | 301 | * ARM_DRIVER_VERSION version; |
mturner5 | 0:b7116bd48af6 | 302 | * |
mturner5 | 0:b7116bd48af6 | 303 | * version = drv_info->GetVersion (); |
mturner5 | 0:b7116bd48af6 | 304 | * if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher |
mturner5 | 0:b7116bd48af6 | 305 | * // error handling |
mturner5 | 0:b7116bd48af6 | 306 | * return; |
mturner5 | 0:b7116bd48af6 | 307 | * } |
mturner5 | 0:b7116bd48af6 | 308 | * } |
mturner5 | 0:b7116bd48af6 | 309 | * \endcode |
mturner5 | 0:b7116bd48af6 | 310 | * |
mturner5 | 0:b7116bd48af6 | 311 | * @return \ref ARM_DRIVER_VERSION. |
mturner5 | 0:b7116bd48af6 | 312 | * |
mturner5 | 0:b7116bd48af6 | 313 | * @note This API returns synchronously--it does not result in an invocation |
mturner5 | 0:b7116bd48af6 | 314 | * of a completion callback. |
mturner5 | 0:b7116bd48af6 | 315 | * |
mturner5 | 0:b7116bd48af6 | 316 | * @note The function GetVersion() can be called any time to obtain the |
mturner5 | 0:b7116bd48af6 | 317 | * required information from the driver (even before initialization). It |
mturner5 | 0:b7116bd48af6 | 318 | * always returns the same information. |
mturner5 | 0:b7116bd48af6 | 319 | */ |
mturner5 | 0:b7116bd48af6 | 320 | ARM_DRIVER_VERSION (*GetVersion)(void); |
mturner5 | 0:b7116bd48af6 | 321 | |
mturner5 | 0:b7116bd48af6 | 322 | /** |
mturner5 | 0:b7116bd48af6 | 323 | * \brief Get driver capabilities. |
mturner5 | 0:b7116bd48af6 | 324 | * |
mturner5 | 0:b7116bd48af6 | 325 | * \details The function GetCapabilities() returns information about |
mturner5 | 0:b7116bd48af6 | 326 | * capabilities in this driver implementation. The data fields of the struct |
mturner5 | 0:b7116bd48af6 | 327 | * ARM_STORAGE_CAPABILITIES encode various capabilities, for example if the device |
mturner5 | 0:b7116bd48af6 | 328 | * is able to execute operations asynchronously. |
mturner5 | 0:b7116bd48af6 | 329 | * |
mturner5 | 0:b7116bd48af6 | 330 | * Example: |
mturner5 | 0:b7116bd48af6 | 331 | * \code |
mturner5 | 0:b7116bd48af6 | 332 | * extern ARM_DRIVER_STORAGE *drv_info; |
mturner5 | 0:b7116bd48af6 | 333 | * |
mturner5 | 0:b7116bd48af6 | 334 | * void read_capabilities (void) { |
mturner5 | 0:b7116bd48af6 | 335 | * ARM_STORAGE_CAPABILITIES drv_capabilities; |
mturner5 | 0:b7116bd48af6 | 336 | * |
mturner5 | 0:b7116bd48af6 | 337 | * drv_capabilities = drv_info->GetCapabilities (); |
mturner5 | 0:b7116bd48af6 | 338 | * // interrogate capabilities |
mturner5 | 0:b7116bd48af6 | 339 | * |
mturner5 | 0:b7116bd48af6 | 340 | * } |
mturner5 | 0:b7116bd48af6 | 341 | * \endcode |
mturner5 | 0:b7116bd48af6 | 342 | * |
mturner5 | 0:b7116bd48af6 | 343 | * @return \ref ARM_STORAGE_CAPABILITIES. |
mturner5 | 0:b7116bd48af6 | 344 | * |
mturner5 | 0:b7116bd48af6 | 345 | * @note This API returns synchronously--it does not result in an invocation |
mturner5 | 0:b7116bd48af6 | 346 | * of a completion callback. |
mturner5 | 0:b7116bd48af6 | 347 | * |
mturner5 | 0:b7116bd48af6 | 348 | * @note The function GetCapabilities() can be called any time to obtain the |
mturner5 | 0:b7116bd48af6 | 349 | * required information from the driver (even before initialization). It |
mturner5 | 0:b7116bd48af6 | 350 | * always returns the same information. |
mturner5 | 0:b7116bd48af6 | 351 | */ |
mturner5 | 0:b7116bd48af6 | 352 | ARM_STORAGE_CAPABILITIES (*GetCapabilities)(void); |
mturner5 | 0:b7116bd48af6 | 353 | |
mturner5 | 0:b7116bd48af6 | 354 | /** |
mturner5 | 0:b7116bd48af6 | 355 | * \brief Initialize the Storage Interface. |
mturner5 | 0:b7116bd48af6 | 356 | * |
mturner5 | 0:b7116bd48af6 | 357 | * The function Initialize is called when the middleware component starts |
mturner5 | 0:b7116bd48af6 | 358 | * operation. In addition to bringing the controller to a ready state, |
mturner5 | 0:b7116bd48af6 | 359 | * Initialize() receives a callback handler to be invoked upon completion of |
mturner5 | 0:b7116bd48af6 | 360 | * asynchronous operations. |
mturner5 | 0:b7116bd48af6 | 361 | * |
mturner5 | 0:b7116bd48af6 | 362 | * Initialize() needs to be called explicitly before |
mturner5 | 0:b7116bd48af6 | 363 | * powering the peripheral using PowerControl(), and before initiating other |
mturner5 | 0:b7116bd48af6 | 364 | * accesses to the storage controller. |
mturner5 | 0:b7116bd48af6 | 365 | * |
mturner5 | 0:b7116bd48af6 | 366 | * The function performs the following operations: |
mturner5 | 0:b7116bd48af6 | 367 | * - Initializes the resources needed for the Storage interface. |
mturner5 | 0:b7116bd48af6 | 368 | * - Registers the \ref ARM_Storage_Callback_t callback function. |
mturner5 | 0:b7116bd48af6 | 369 | * |
mturner5 | 0:b7116bd48af6 | 370 | * To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: |
mturner5 | 0:b7116bd48af6 | 371 | * drv->Initialize (...); // Allocate I/O pins |
mturner5 | 0:b7116bd48af6 | 372 | * drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA |
mturner5 | 0:b7116bd48af6 | 373 | * |
mturner5 | 0:b7116bd48af6 | 374 | * - Initialize() typically allocates the I/O resources (pins) for the |
mturner5 | 0:b7116bd48af6 | 375 | * peripheral. The function can be called multiple times; if the I/O resources |
mturner5 | 0:b7116bd48af6 | 376 | * are already initialized it performs no operation and just returns with |
mturner5 | 0:b7116bd48af6 | 377 | * ARM_DRIVER_OK. |
mturner5 | 0:b7116bd48af6 | 378 | * |
mturner5 | 0:b7116bd48af6 | 379 | * - PowerControl (ARM_POWER_FULL) sets the peripheral registers including |
mturner5 | 0:b7116bd48af6 | 380 | * interrupt (NVIC) and optionally DMA. The function can be called multiple |
mturner5 | 0:b7116bd48af6 | 381 | * times; if the registers are already set it performs no operation and just |
mturner5 | 0:b7116bd48af6 | 382 | * returns with ARM_DRIVER_OK. |
mturner5 | 0:b7116bd48af6 | 383 | * |
mturner5 | 0:b7116bd48af6 | 384 | * To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: |
mturner5 | 0:b7116bd48af6 | 385 | * drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral |
mturner5 | 0:b7116bd48af6 | 386 | * drv->Uninitialize (...); // Release I/O pins |
mturner5 | 0:b7116bd48af6 | 387 | * |
mturner5 | 0:b7116bd48af6 | 388 | * The functions PowerControl and Uninitialize always execute and can be used |
mturner5 | 0:b7116bd48af6 | 389 | * to put the peripheral into a Safe State, for example after any data |
mturner5 | 0:b7116bd48af6 | 390 | * transmission errors. To restart the peripheral in an error condition, |
mturner5 | 0:b7116bd48af6 | 391 | * you should first execute the Stop Sequence and then the Start Sequence. |
mturner5 | 0:b7116bd48af6 | 392 | * |
mturner5 | 0:b7116bd48af6 | 393 | * @param [in] callback |
mturner5 | 0:b7116bd48af6 | 394 | * Caller-defined callback to be invoked upon command completion |
mturner5 | 0:b7116bd48af6 | 395 | * for asynchronous APIs (including the completion of |
mturner5 | 0:b7116bd48af6 | 396 | * initialization). Use a NULL pointer when no callback |
mturner5 | 0:b7116bd48af6 | 397 | * signals are required. |
mturner5 | 0:b7116bd48af6 | 398 | * |
mturner5 | 0:b7116bd48af6 | 399 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 400 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 401 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 402 | * |
mturner5 | 0:b7116bd48af6 | 403 | * @return If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 404 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 405 | * future with a status value of ARM_DRIVER_OK or an error-code. In the |
mturner5 | 0:b7116bd48af6 | 406 | * case of synchronous execution, control returns after completion with a |
mturner5 | 0:b7116bd48af6 | 407 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 408 | */ |
mturner5 | 0:b7116bd48af6 | 409 | int32_t (*Initialize)(ARM_Storage_Callback_t callback); |
mturner5 | 0:b7116bd48af6 | 410 | |
mturner5 | 0:b7116bd48af6 | 411 | /** |
mturner5 | 0:b7116bd48af6 | 412 | * \brief De-initialize the Storage Interface. |
mturner5 | 0:b7116bd48af6 | 413 | * |
mturner5 | 0:b7116bd48af6 | 414 | * The function Uninitialize() de-initializes the resources of Storage interface. |
mturner5 | 0:b7116bd48af6 | 415 | * |
mturner5 | 0:b7116bd48af6 | 416 | * It is called when the middleware component stops operation, and wishes to |
mturner5 | 0:b7116bd48af6 | 417 | * release the software resources used by the interface. |
mturner5 | 0:b7116bd48af6 | 418 | * |
mturner5 | 0:b7116bd48af6 | 419 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 420 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 421 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 422 | * |
mturner5 | 0:b7116bd48af6 | 423 | * @return If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 424 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 425 | * future with a status value of ARM_DRIVER_OK or an error-code. In the |
mturner5 | 0:b7116bd48af6 | 426 | * case of synchronous execution, control returns after completion with a |
mturner5 | 0:b7116bd48af6 | 427 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 428 | */ |
mturner5 | 0:b7116bd48af6 | 429 | int32_t (*Uninitialize)(void); |
mturner5 | 0:b7116bd48af6 | 430 | |
mturner5 | 0:b7116bd48af6 | 431 | /** |
mturner5 | 0:b7116bd48af6 | 432 | * \brief Control the Storage interface power. |
mturner5 | 0:b7116bd48af6 | 433 | * |
mturner5 | 0:b7116bd48af6 | 434 | * The function \b ARM_Storage_PowerControl operates the power modes of the Storage interface. |
mturner5 | 0:b7116bd48af6 | 435 | * |
mturner5 | 0:b7116bd48af6 | 436 | * To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: |
mturner5 | 0:b7116bd48af6 | 437 | * drv->Initialize (...); // Allocate I/O pins |
mturner5 | 0:b7116bd48af6 | 438 | * drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA |
mturner5 | 0:b7116bd48af6 | 439 | * |
mturner5 | 0:b7116bd48af6 | 440 | * - Initialize() typically allocates the I/O resources (pins) for the |
mturner5 | 0:b7116bd48af6 | 441 | * peripheral. The function can be called multiple times; if the I/O resources |
mturner5 | 0:b7116bd48af6 | 442 | * are already initialized it performs no operation and just returns with |
mturner5 | 0:b7116bd48af6 | 443 | * ARM_DRIVER_OK. |
mturner5 | 0:b7116bd48af6 | 444 | * |
mturner5 | 0:b7116bd48af6 | 445 | * - PowerControl (ARM_POWER_FULL) sets the peripheral registers including |
mturner5 | 0:b7116bd48af6 | 446 | * interrupt (NVIC) and optionally DMA. The function can be called multiple |
mturner5 | 0:b7116bd48af6 | 447 | * times; if the registers are already set it performs no operation and just |
mturner5 | 0:b7116bd48af6 | 448 | * returns with ARM_DRIVER_OK. |
mturner5 | 0:b7116bd48af6 | 449 | * |
mturner5 | 0:b7116bd48af6 | 450 | * To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: |
mturner5 | 0:b7116bd48af6 | 451 | * |
mturner5 | 0:b7116bd48af6 | 452 | * drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral |
mturner5 | 0:b7116bd48af6 | 453 | * drv->Uninitialize (...); // Release I/O pins |
mturner5 | 0:b7116bd48af6 | 454 | * |
mturner5 | 0:b7116bd48af6 | 455 | * The functions PowerControl and Uninitialize always execute and can be used |
mturner5 | 0:b7116bd48af6 | 456 | * to put the peripheral into a Safe State, for example after any data |
mturner5 | 0:b7116bd48af6 | 457 | * transmission errors. To restart the peripheral in an error condition, |
mturner5 | 0:b7116bd48af6 | 458 | * you should first execute the Stop Sequence and then the Start Sequence. |
mturner5 | 0:b7116bd48af6 | 459 | * |
mturner5 | 0:b7116bd48af6 | 460 | * @param state |
mturner5 | 0:b7116bd48af6 | 461 | * \ref ARM_POWER_STATE. The target power-state for the storage controller. |
mturner5 | 0:b7116bd48af6 | 462 | * The parameter state can have the following values: |
mturner5 | 0:b7116bd48af6 | 463 | * - ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts |
mturner5 | 0:b7116bd48af6 | 464 | * (NVIC) and optionally DMA. Can be called multiple times. If the peripheral |
mturner5 | 0:b7116bd48af6 | 465 | * is already in this mode, then the function performs no operation and returns |
mturner5 | 0:b7116bd48af6 | 466 | * with ARM_DRIVER_OK. |
mturner5 | 0:b7116bd48af6 | 467 | * - ARM_POWER_LOW : may use power saving. Returns ARM_DRIVER_ERROR_UNSUPPORTED when not implemented. |
mturner5 | 0:b7116bd48af6 | 468 | * - ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA. |
mturner5 | 0:b7116bd48af6 | 469 | * |
mturner5 | 0:b7116bd48af6 | 470 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 471 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 472 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 473 | * |
mturner5 | 0:b7116bd48af6 | 474 | * @return If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 475 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 476 | * future with a status value of ARM_DRIVER_OK or an error-code. In the |
mturner5 | 0:b7116bd48af6 | 477 | * case of synchronous execution, control returns after completion with a |
mturner5 | 0:b7116bd48af6 | 478 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 479 | */ |
mturner5 | 0:b7116bd48af6 | 480 | int32_t (*PowerControl)(ARM_POWER_STATE state); |
mturner5 | 0:b7116bd48af6 | 481 | |
mturner5 | 0:b7116bd48af6 | 482 | /** |
mturner5 | 0:b7116bd48af6 | 483 | * \brief read the contents of a given address range from the storage device. |
mturner5 | 0:b7116bd48af6 | 484 | * |
mturner5 | 0:b7116bd48af6 | 485 | * \details Read the contents of a range of storage memory into a buffer |
mturner5 | 0:b7116bd48af6 | 486 | * supplied by the caller. The buffer is owned by the caller and should |
mturner5 | 0:b7116bd48af6 | 487 | * remain accessible for the lifetime of this command. |
mturner5 | 0:b7116bd48af6 | 488 | * |
mturner5 | 0:b7116bd48af6 | 489 | * @param [in] addr |
mturner5 | 0:b7116bd48af6 | 490 | * This specifies the address from where to read data. |
mturner5 | 0:b7116bd48af6 | 491 | * |
mturner5 | 0:b7116bd48af6 | 492 | * @param [out] data |
mturner5 | 0:b7116bd48af6 | 493 | * The destination of the read operation. The buffer |
mturner5 | 0:b7116bd48af6 | 494 | * is owned by the caller and should remain accessible for the |
mturner5 | 0:b7116bd48af6 | 495 | * lifetime of this command. |
mturner5 | 0:b7116bd48af6 | 496 | * |
mturner5 | 0:b7116bd48af6 | 497 | * @param [in] size |
mturner5 | 0:b7116bd48af6 | 498 | * The number of bytes requested to read. The data buffer |
mturner5 | 0:b7116bd48af6 | 499 | * should be at least as large as this size. |
mturner5 | 0:b7116bd48af6 | 500 | * |
mturner5 | 0:b7116bd48af6 | 501 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 502 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 503 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 504 | * |
mturner5 | 0:b7116bd48af6 | 505 | * @return If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 506 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 507 | * future with the number of successfully transferred bytes passed in as |
mturner5 | 0:b7116bd48af6 | 508 | * the 'status' parameter. In the case of synchronous execution, control |
mturner5 | 0:b7116bd48af6 | 509 | * returns after completion with a positive transfer-count. Return values |
mturner5 | 0:b7116bd48af6 | 510 | * less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 511 | */ |
mturner5 | 0:b7116bd48af6 | 512 | int32_t (*ReadData)(uint64_t addr, void *data, uint32_t size); |
mturner5 | 0:b7116bd48af6 | 513 | |
mturner5 | 0:b7116bd48af6 | 514 | /** |
mturner5 | 0:b7116bd48af6 | 515 | * \brief program (write into) the contents of a given address range of the storage device. |
mturner5 | 0:b7116bd48af6 | 516 | * |
mturner5 | 0:b7116bd48af6 | 517 | * \details Write the contents of a given memory buffer into a range of |
mturner5 | 0:b7116bd48af6 | 518 | * storage memory. In the case of flash memory, the destination range in |
mturner5 | 0:b7116bd48af6 | 519 | * storage memory typically has its contents in an erased state from a |
mturner5 | 0:b7116bd48af6 | 520 | * preceding erase operation. The source memory buffer is owned by the |
mturner5 | 0:b7116bd48af6 | 521 | * caller and should remain accessible for the lifetime of this command. |
mturner5 | 0:b7116bd48af6 | 522 | * |
mturner5 | 0:b7116bd48af6 | 523 | * @param [in] addr |
mturner5 | 0:b7116bd48af6 | 524 | * This is the start address of the range to be written into. It |
mturner5 | 0:b7116bd48af6 | 525 | * needs to be aligned to the device's \em program_unit |
mturner5 | 0:b7116bd48af6 | 526 | * specified in \ref ARM_STORAGE_INFO. |
mturner5 | 0:b7116bd48af6 | 527 | * |
mturner5 | 0:b7116bd48af6 | 528 | * @param [in] data |
mturner5 | 0:b7116bd48af6 | 529 | * The source of the write operation. The buffer is owned by the |
mturner5 | 0:b7116bd48af6 | 530 | * caller and should remain accessible for the lifetime of this |
mturner5 | 0:b7116bd48af6 | 531 | * command. |
mturner5 | 0:b7116bd48af6 | 532 | * |
mturner5 | 0:b7116bd48af6 | 533 | * @param [in] size |
mturner5 | 0:b7116bd48af6 | 534 | * The number of bytes requested to be written. The buffer |
mturner5 | 0:b7116bd48af6 | 535 | * should be at least as large as this size. \note 'size' should |
mturner5 | 0:b7116bd48af6 | 536 | * be a multiple of the device's 'program_unit' (see \ref |
mturner5 | 0:b7116bd48af6 | 537 | * ARM_STORAGE_INFO). |
mturner5 | 0:b7116bd48af6 | 538 | * |
mturner5 | 0:b7116bd48af6 | 539 | * @note It is best for the middleware to write in units of |
mturner5 | 0:b7116bd48af6 | 540 | * 'optimal_program_unit' (\ref ARM_STORAGE_INFO) of the device. |
mturner5 | 0:b7116bd48af6 | 541 | * |
mturner5 | 0:b7116bd48af6 | 542 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 543 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 544 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 545 | * |
mturner5 | 0:b7116bd48af6 | 546 | * @return If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 547 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 548 | * future with the number of successfully transferred bytes passed in as |
mturner5 | 0:b7116bd48af6 | 549 | * the 'status' parameter. In the case of synchronous execution, control |
mturner5 | 0:b7116bd48af6 | 550 | * returns after completion with a positive transfer-count. Return values |
mturner5 | 0:b7116bd48af6 | 551 | * less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 552 | */ |
mturner5 | 0:b7116bd48af6 | 553 | int32_t (*ProgramData)(uint64_t addr, const void *data, uint32_t size); |
mturner5 | 0:b7116bd48af6 | 554 | |
mturner5 | 0:b7116bd48af6 | 555 | /** |
mturner5 | 0:b7116bd48af6 | 556 | * @brief Erase Storage range. |
mturner5 | 0:b7116bd48af6 | 557 | * |
mturner5 | 0:b7116bd48af6 | 558 | * @details This function erases a range of storage specified by [addr, addr + |
mturner5 | 0:b7116bd48af6 | 559 | * size). Both 'addr' and 'addr + size' should align with the |
mturner5 | 0:b7116bd48af6 | 560 | * 'erase_unit'(s) of the respective owning storage block(s) (see \ref |
mturner5 | 0:b7116bd48af6 | 561 | * ARM_STORAGE_BLOCK and \ref ARM_STORAGE_BLOCK_ATTRIBUTES). The range to |
mturner5 | 0:b7116bd48af6 | 562 | * be erased will have its contents returned to the un-programmed state-- |
mturner5 | 0:b7116bd48af6 | 563 | * i.e. to 'erased_value' (see \ref ARM_STORAGE_BLOCK_ATTRIBUTES), which |
mturner5 | 0:b7116bd48af6 | 564 | * is usually 1 to indicate the pattern of all ones: 0xFF. |
mturner5 | 0:b7116bd48af6 | 565 | * |
mturner5 | 0:b7116bd48af6 | 566 | * @param [in] addr |
mturner5 | 0:b7116bd48af6 | 567 | * This is the start-address of the range to be erased. It must |
mturner5 | 0:b7116bd48af6 | 568 | * start at an 'erase_unit' boundary of the underlying block. |
mturner5 | 0:b7116bd48af6 | 569 | * |
mturner5 | 0:b7116bd48af6 | 570 | * @param [in] size |
mturner5 | 0:b7116bd48af6 | 571 | * Size (in bytes) of the range to be erased. 'addr + size' |
mturner5 | 0:b7116bd48af6 | 572 | * must be aligned with the 'erase_unit' of the underlying |
mturner5 | 0:b7116bd48af6 | 573 | * block. |
mturner5 | 0:b7116bd48af6 | 574 | * |
mturner5 | 0:b7116bd48af6 | 575 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 576 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 577 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 578 | * |
mturner5 | 0:b7116bd48af6 | 579 | * @return |
mturner5 | 0:b7116bd48af6 | 580 | * If the range to be erased doesn't align with the erase_units of the |
mturner5 | 0:b7116bd48af6 | 581 | * respective start and end blocks, ARM_DRIVER_ERROR_PARAMETER is returned. |
mturner5 | 0:b7116bd48af6 | 582 | * If any part of the range is protected, ARM_STORAGE_ERROR_PROTECTED is |
mturner5 | 0:b7116bd48af6 | 583 | * returned. If any part of the range is not erasable, |
mturner5 | 0:b7116bd48af6 | 584 | * ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All such sanity-check |
mturner5 | 0:b7116bd48af6 | 585 | * failures result in the error code being returned synchronously and the |
mturner5 | 0:b7116bd48af6 | 586 | * storage bytes within the range remain unaffected. |
mturner5 | 0:b7116bd48af6 | 587 | * Otherwise the function executes in the following ways: |
mturner5 | 0:b7116bd48af6 | 588 | * If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 589 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 590 | * future with the number of successfully erased bytes passed in as |
mturner5 | 0:b7116bd48af6 | 591 | * the 'status' parameter. In the case of synchronous execution, control |
mturner5 | 0:b7116bd48af6 | 592 | * returns after completion with a positive erase-count. Return values |
mturner5 | 0:b7116bd48af6 | 593 | * less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 594 | * |
mturner5 | 0:b7116bd48af6 | 595 | * @note Erase() may return a smaller (positive) value than the size of the |
mturner5 | 0:b7116bd48af6 | 596 | * requested range. The returned value indicates the actual number of bytes |
mturner5 | 0:b7116bd48af6 | 597 | * erased. It is the caller's responsibility to follow up with an appropriate |
mturner5 | 0:b7116bd48af6 | 598 | * request to complete the operation. |
mturner5 | 0:b7116bd48af6 | 599 | * |
mturner5 | 0:b7116bd48af6 | 600 | * @note in the case of a failed erase (except when |
mturner5 | 0:b7116bd48af6 | 601 | * ARM_DRIVER_ERROR_PARAMETER, ARM_STORAGE_ERROR_PROTECTED, or |
mturner5 | 0:b7116bd48af6 | 602 | * ARM_STORAGE_ERROR_NOT_ERASABLE is returned synchronously), the |
mturner5 | 0:b7116bd48af6 | 603 | * requested range should be assumed to be in an unknown state. The |
mturner5 | 0:b7116bd48af6 | 604 | * previous contents may not be retained. |
mturner5 | 0:b7116bd48af6 | 605 | */ |
mturner5 | 0:b7116bd48af6 | 606 | int32_t (*Erase)(uint64_t addr, uint32_t size); |
mturner5 | 0:b7116bd48af6 | 607 | |
mturner5 | 0:b7116bd48af6 | 608 | /** |
mturner5 | 0:b7116bd48af6 | 609 | * @brief Erase complete storage. Optional function for faster erase of the complete device. |
mturner5 | 0:b7116bd48af6 | 610 | * |
mturner5 | 0:b7116bd48af6 | 611 | * This optional function erases the complete device. If the device does not |
mturner5 | 0:b7116bd48af6 | 612 | * support global erase then the function returns the error value \ref |
mturner5 | 0:b7116bd48af6 | 613 | * ARM_DRIVER_ERROR_UNSUPPORTED. The data field \em 'erase_all' = |
mturner5 | 0:b7116bd48af6 | 614 | * \token{1} of the structure \ref ARM_STORAGE_CAPABILITIES encodes that |
mturner5 | 0:b7116bd48af6 | 615 | * \ref ARM_STORAGE_EraseAll is supported. |
mturner5 | 0:b7116bd48af6 | 616 | * |
mturner5 | 0:b7116bd48af6 | 617 | * @note This API may execute asynchronously if |
mturner5 | 0:b7116bd48af6 | 618 | * ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous |
mturner5 | 0:b7116bd48af6 | 619 | * execution is optional even if 'asynchronous_ops' is set. |
mturner5 | 0:b7116bd48af6 | 620 | * |
mturner5 | 0:b7116bd48af6 | 621 | * @return |
mturner5 | 0:b7116bd48af6 | 622 | * If any part of the storage range is protected, |
mturner5 | 0:b7116bd48af6 | 623 | * ARM_STORAGE_ERROR_PROTECTED is returned. If any part of the storage |
mturner5 | 0:b7116bd48af6 | 624 | * range is not erasable, ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All |
mturner5 | 0:b7116bd48af6 | 625 | * such sanity-check failures result in the error code being returned |
mturner5 | 0:b7116bd48af6 | 626 | * synchronously and the storage bytes within the range remain unaffected. |
mturner5 | 0:b7116bd48af6 | 627 | * Otherwise the function executes in the following ways: |
mturner5 | 0:b7116bd48af6 | 628 | * If asynchronous activity is launched, an invocation returns |
mturner5 | 0:b7116bd48af6 | 629 | * ARM_DRIVER_OK, and the caller can expect to receive a callback in the |
mturner5 | 0:b7116bd48af6 | 630 | * future with ARM_DRIVER_OK passed in as the 'status' parameter. In the |
mturner5 | 0:b7116bd48af6 | 631 | * case of synchronous execution, control returns after completion with a |
mturner5 | 0:b7116bd48af6 | 632 | * value of 1. Return values less than ARM_DRIVER_OK (0) signify errors. |
mturner5 | 0:b7116bd48af6 | 633 | */ |
mturner5 | 0:b7116bd48af6 | 634 | int32_t (*EraseAll)(void); |
mturner5 | 0:b7116bd48af6 | 635 | |
mturner5 | 0:b7116bd48af6 | 636 | /** |
mturner5 | 0:b7116bd48af6 | 637 | * @brief Get the status of the current (or previous) command executed by the |
mturner5 | 0:b7116bd48af6 | 638 | * storage controller; stored in the structure \ref ARM_STORAGE_STATUS. |
mturner5 | 0:b7116bd48af6 | 639 | * |
mturner5 | 0:b7116bd48af6 | 640 | * @return |
mturner5 | 0:b7116bd48af6 | 641 | * The status of the underlying controller. |
mturner5 | 0:b7116bd48af6 | 642 | * |
mturner5 | 0:b7116bd48af6 | 643 | * @note This API returns synchronously--it does not result in an invocation |
mturner5 | 0:b7116bd48af6 | 644 | * of a completion callback. |
mturner5 | 0:b7116bd48af6 | 645 | */ |
mturner5 | 0:b7116bd48af6 | 646 | ARM_STORAGE_STATUS (*GetStatus)(void); |
mturner5 | 0:b7116bd48af6 | 647 | |
mturner5 | 0:b7116bd48af6 | 648 | /** |
mturner5 | 0:b7116bd48af6 | 649 | * @brief Get information about the Storage device; stored in the structure \ref ARM_STORAGE_INFO. |
mturner5 | 0:b7116bd48af6 | 650 | * |
mturner5 | 0:b7116bd48af6 | 651 | * @param [out] info |
mturner5 | 0:b7116bd48af6 | 652 | * A caller-supplied buffer capable of being filled in with an |
mturner5 | 0:b7116bd48af6 | 653 | * \ref ARM_STORAGE_INFO. |
mturner5 | 0:b7116bd48af6 | 654 | * |
mturner5 | 0:b7116bd48af6 | 655 | * @return ARM_DRIVER_OK if a ARM_STORAGE_INFO structure containing top level |
mturner5 | 0:b7116bd48af6 | 656 | * metadata about the storage controller is filled into the supplied |
mturner5 | 0:b7116bd48af6 | 657 | * buffer, else an appropriate error value. |
mturner5 | 0:b7116bd48af6 | 658 | * |
mturner5 | 0:b7116bd48af6 | 659 | * @note It is the caller's responsibility to ensure that the buffer passed in |
mturner5 | 0:b7116bd48af6 | 660 | * is able to be initialized with a \ref ARM_STORAGE_INFO. |
mturner5 | 0:b7116bd48af6 | 661 | * |
mturner5 | 0:b7116bd48af6 | 662 | * @note This API returns synchronously--it does not result in an invocation |
mturner5 | 0:b7116bd48af6 | 663 | * of a completion callback. |
mturner5 | 0:b7116bd48af6 | 664 | */ |
mturner5 | 0:b7116bd48af6 | 665 | int32_t (*GetInfo)(ARM_STORAGE_INFO *info); |
mturner5 | 0:b7116bd48af6 | 666 | |
mturner5 | 0:b7116bd48af6 | 667 | /** |
mturner5 | 0:b7116bd48af6 | 668 | * \brief For memory-mapped storage, resolve an address relative to |
mturner5 | 0:b7116bd48af6 | 669 | * the storage controller into a memory address. |
mturner5 | 0:b7116bd48af6 | 670 | * |
mturner5 | 0:b7116bd48af6 | 671 | * @param addr |
mturner5 | 0:b7116bd48af6 | 672 | * This is the address for which we want a resolution to the |
mturner5 | 0:b7116bd48af6 | 673 | * processor's physical address space. It is an offset from the |
mturner5 | 0:b7116bd48af6 | 674 | * start of the storage map maintained by the owning storage |
mturner5 | 0:b7116bd48af6 | 675 | * controller. |
mturner5 | 0:b7116bd48af6 | 676 | * |
mturner5 | 0:b7116bd48af6 | 677 | * @return |
mturner5 | 0:b7116bd48af6 | 678 | * The resolved address in the processor's address space; else |
mturner5 | 0:b7116bd48af6 | 679 | * ARM_STORAGE_INVALID_ADDRESS, if no resolution is possible. |
mturner5 | 0:b7116bd48af6 | 680 | * |
mturner5 | 0:b7116bd48af6 | 681 | * @note This API returns synchronously. The invocation should return quickly, |
mturner5 | 0:b7116bd48af6 | 682 | * and result in a resolved address. |
mturner5 | 0:b7116bd48af6 | 683 | */ |
mturner5 | 0:b7116bd48af6 | 684 | uint32_t (*ResolveAddress)(uint64_t addr); |
mturner5 | 0:b7116bd48af6 | 685 | |
mturner5 | 0:b7116bd48af6 | 686 | /** |
mturner5 | 0:b7116bd48af6 | 687 | * @brief Advance to the successor of the current block (iterator), or fetch |
mturner5 | 0:b7116bd48af6 | 688 | * the first block (if 'prev_block' is passed in as NULL). |
mturner5 | 0:b7116bd48af6 | 689 | * |
mturner5 | 0:b7116bd48af6 | 690 | * @details This helper function fetches (an iterator to) the next block (or |
mturner5 | 0:b7116bd48af6 | 691 | * the first block if 'prev_block' is passed in as NULL). In the failure |
mturner5 | 0:b7116bd48af6 | 692 | * case, a terminating, invalid block iterator is filled into the out |
mturner5 | 0:b7116bd48af6 | 693 | * parameter: 'next_block'. In combination with \ref |
mturner5 | 0:b7116bd48af6 | 694 | * ARM_STORAGE_VALID_BLOCK(), it can be used to iterate over the sequence |
mturner5 | 0:b7116bd48af6 | 695 | * of blocks within the storage map: |
mturner5 | 0:b7116bd48af6 | 696 | * |
mturner5 | 0:b7116bd48af6 | 697 | * \code |
mturner5 | 0:b7116bd48af6 | 698 | * ARM_STORAGE_BLOCK block; |
mturner5 | 0:b7116bd48af6 | 699 | * for (drv->GetNextBlock(NULL, &block); ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) { |
mturner5 | 0:b7116bd48af6 | 700 | * // make use of block |
mturner5 | 0:b7116bd48af6 | 701 | * } |
mturner5 | 0:b7116bd48af6 | 702 | * \endcode |
mturner5 | 0:b7116bd48af6 | 703 | * |
mturner5 | 0:b7116bd48af6 | 704 | * @param[in] prev_block |
mturner5 | 0:b7116bd48af6 | 705 | * An existing block (iterator) within the same storage |
mturner5 | 0:b7116bd48af6 | 706 | * controller. The memory buffer holding this block is owned |
mturner5 | 0:b7116bd48af6 | 707 | * by the caller. This pointer may be NULL; if so, the |
mturner5 | 0:b7116bd48af6 | 708 | * invocation fills in the first block into the out parameter: |
mturner5 | 0:b7116bd48af6 | 709 | * 'next_block'. |
mturner5 | 0:b7116bd48af6 | 710 | * |
mturner5 | 0:b7116bd48af6 | 711 | * @param[out] next_block |
mturner5 | 0:b7116bd48af6 | 712 | * A caller-owned buffer large enough to be filled in with |
mturner5 | 0:b7116bd48af6 | 713 | * the following ARM_STORAGE_BLOCK. It is legal to provide the |
mturner5 | 0:b7116bd48af6 | 714 | * same buffer using 'next_block' as was passed in with 'prev_block'. It |
mturner5 | 0:b7116bd48af6 | 715 | * is also legal to pass a NULL into this parameter if the |
mturner5 | 0:b7116bd48af6 | 716 | * caller isn't interested in populating a buffer with the next |
mturner5 | 0:b7116bd48af6 | 717 | * block--i.e. if the caller only wishes to establish the |
mturner5 | 0:b7116bd48af6 | 718 | * presence of a next block. |
mturner5 | 0:b7116bd48af6 | 719 | * |
mturner5 | 0:b7116bd48af6 | 720 | * @return ARM_DRIVER_OK if a valid next block is found (or first block, if |
mturner5 | 0:b7116bd48af6 | 721 | * prev_block is passed as NULL); upon successful operation, the contents |
mturner5 | 0:b7116bd48af6 | 722 | * of the next (or first) block are filled into the buffer pointed to by |
mturner5 | 0:b7116bd48af6 | 723 | * the parameter 'next_block' and ARM_STORAGE_VALID_BLOCK(next_block) is |
mturner5 | 0:b7116bd48af6 | 724 | * guaranteed to be true. Upon reaching the end of the sequence of blocks |
mturner5 | 0:b7116bd48af6 | 725 | * (iterators), or in case the driver is unable to fetch information about |
mturner5 | 0:b7116bd48af6 | 726 | * the next (or first) block, an error (negative) value is returned and an |
mturner5 | 0:b7116bd48af6 | 727 | * invalid StorageBlock is populated into the supplied buffer. If |
mturner5 | 0:b7116bd48af6 | 728 | * prev_block is NULL, the first block is returned. |
mturner5 | 0:b7116bd48af6 | 729 | * |
mturner5 | 0:b7116bd48af6 | 730 | * @note This API returns synchronously--it does not result in an invocation |
mturner5 | 0:b7116bd48af6 | 731 | * of a completion callback. |
mturner5 | 0:b7116bd48af6 | 732 | */ |
mturner5 | 0:b7116bd48af6 | 733 | int32_t (*GetNextBlock)(const ARM_STORAGE_BLOCK* prev_block, ARM_STORAGE_BLOCK *next_block); |
mturner5 | 0:b7116bd48af6 | 734 | |
mturner5 | 0:b7116bd48af6 | 735 | /** |
mturner5 | 0:b7116bd48af6 | 736 | * @brief Find the storage block (iterator) encompassing a given storage address. |
mturner5 | 0:b7116bd48af6 | 737 | * |
mturner5 | 0:b7116bd48af6 | 738 | * @param[in] addr |
mturner5 | 0:b7116bd48af6 | 739 | * Storage address in bytes. |
mturner5 | 0:b7116bd48af6 | 740 | * |
mturner5 | 0:b7116bd48af6 | 741 | * @param[out] block |
mturner5 | 0:b7116bd48af6 | 742 | * A caller-owned buffer large enough to be filled in with the |
mturner5 | 0:b7116bd48af6 | 743 | * ARM_STORAGE_BLOCK encapsulating the given address. This value |
mturner5 | 0:b7116bd48af6 | 744 | * can also be passed in as NULL if the caller isn't interested |
mturner5 | 0:b7116bd48af6 | 745 | * in populating a buffer with the block--if the caller only |
mturner5 | 0:b7116bd48af6 | 746 | * wishes to establish the presence of a containing storage |
mturner5 | 0:b7116bd48af6 | 747 | * block. |
mturner5 | 0:b7116bd48af6 | 748 | * |
mturner5 | 0:b7116bd48af6 | 749 | * @return ARM_DRIVER_OK if a containing storage-block is found. In this case, |
mturner5 | 0:b7116bd48af6 | 750 | * if block is non-NULL, the buffer pointed to by it is populated with |
mturner5 | 0:b7116bd48af6 | 751 | * the contents of the storage block--i.e. if block is valid and a block is |
mturner5 | 0:b7116bd48af6 | 752 | * found, ARM_STORAGE_VALID_BLOCK(block) would return true following this |
mturner5 | 0:b7116bd48af6 | 753 | * call. If there is no storage block containing the given offset, or in |
mturner5 | 0:b7116bd48af6 | 754 | * case the driver is unable to resolve an address to a storage-block, an |
mturner5 | 0:b7116bd48af6 | 755 | * error (negative) value is returned and an invalid StorageBlock is |
mturner5 | 0:b7116bd48af6 | 756 | * populated into the supplied buffer. |
mturner5 | 0:b7116bd48af6 | 757 | * |
mturner5 | 0:b7116bd48af6 | 758 | * @note This API returns synchronously--it does not result in an invocation |
mturner5 | 0:b7116bd48af6 | 759 | * of a completion callback. |
mturner5 | 0:b7116bd48af6 | 760 | */ |
mturner5 | 0:b7116bd48af6 | 761 | int32_t (*GetBlock)(uint64_t addr, ARM_STORAGE_BLOCK *block); |
mturner5 | 0:b7116bd48af6 | 762 | } const ARM_DRIVER_STORAGE; |
mturner5 | 0:b7116bd48af6 | 763 | |
mturner5 | 0:b7116bd48af6 | 764 | #ifdef __cplusplus |
mturner5 | 0:b7116bd48af6 | 765 | } |
mturner5 | 0:b7116bd48af6 | 766 | #endif // __cplusplus |
mturner5 | 0:b7116bd48af6 | 767 | |
mturner5 | 0:b7116bd48af6 | 768 | #endif /* __DRIVER_STORAGE_H */ |