Modification of Mbed-dev library for LQFP48 package microcontrollers: STM32F103C8 (STM32F103C8T6) and STM32F103CB (STM32F103CBT6) (Bluepill boards, Maple mini etc. )

Fork of mbed-STM32F103C8_org by Nothing Special

Library for STM32F103C8 (Bluepill boards etc.).
Use this instead of mbed library.
This library allows the size of the code in the FLASH up to 128kB. Therefore, code also runs on microcontrollers STM32F103CB (eg. Maple mini).
But in the case of STM32F103C8, check the size of the resulting code would not exceed 64kB.

To compile a program with this library, use NUCLEO-F103RB as the target name. !

Changes:

  • Corrected initialization of the HSE + crystal clock (mbed permanent bug), allowing the use of on-board xtal (8MHz).(1)
  • Additionally, it also set USB clock (48Mhz).(2)
  • Definitions of pins and peripherals adjusted to LQFP48 case.
  • Board led LED1 is now PC_13 (3)
  • USER_BUTTON is now PC_14 (4)

    Now the library is complete rebuilt based on mbed-dev v160 (and not yet fully tested).

notes
(1) - In case 8MHz xtal on board, CPU frequency is 72MHz. Without xtal is 64MHz.
(2) - Using the USB interface is only possible if STM32 is clocking by on-board 8MHz xtal or external clock signal 8MHz on the OSC_IN pin.
(3) - On Bluepill board led operation is reversed, i.e. 0 - led on, 1 - led off.
(4) - Bluepill board has no real user button

Information

After export to SW4STM (AC6):

  • add line #include "mbed_config.h" in files Serial.h and RawSerial.h
  • in project properties change Optimisation Level to Optimise for size (-Os)
Committer:
mega64
Date:
Thu Mar 16 06:15:53 2017 +0000
Revision:
146:03e976389d16
fully rebuild, now based on mbed-dev v160

Who changed what in which revision?

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