Dependencies: DM_FATFileSystem EthernetInterface HTTPClient mbed-rtos mbed-src
Fork of DMSupport by
Memory/SPIFI.h@42:39e97a2ea6be, 2016-06-02 (annotated)
- Committer:
- destinyXfate
- Date:
- Thu Jun 02 05:03:52 2016 +0000
- Revision:
- 42:39e97a2ea6be
- Parent:
- 37:07659b5d90ce
;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:6b68dac0d986 | 1 | /* |
embeddedartists | 9:a33326afd686 | 2 | * Copyright 2014 Embedded Artists AB |
embeddedartists | 0:6b68dac0d986 | 3 | * |
embeddedartists | 0:6b68dac0d986 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
embeddedartists | 0:6b68dac0d986 | 5 | * you may not use this file except in compliance with the License. |
embeddedartists | 0:6b68dac0d986 | 6 | * You may obtain a copy of the License at |
embeddedartists | 0:6b68dac0d986 | 7 | * |
embeddedartists | 0:6b68dac0d986 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
embeddedartists | 0:6b68dac0d986 | 9 | * |
embeddedartists | 0:6b68dac0d986 | 10 | * Unless required by applicable law or agreed to in writing, software |
embeddedartists | 0:6b68dac0d986 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
embeddedartists | 0:6b68dac0d986 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
embeddedartists | 0:6b68dac0d986 | 13 | * See the License for the specific language governing permissions and |
embeddedartists | 0:6b68dac0d986 | 14 | * limitations under the License. |
embeddedartists | 0:6b68dac0d986 | 15 | */ |
embeddedartists | 0:6b68dac0d986 | 16 | |
embeddedartists | 0:6b68dac0d986 | 17 | #ifndef SPIFI_H |
embeddedartists | 0:6b68dac0d986 | 18 | #define SPIFI_H |
embeddedartists | 0:6b68dac0d986 | 19 | |
embeddedartists | 0:6b68dac0d986 | 20 | #include "mbed.h" |
embeddedartists | 0:6b68dac0d986 | 21 | #include "spifi_rom_api.h" |
embeddedartists | 0:6b68dac0d986 | 22 | |
embeddedartists | 0:6b68dac0d986 | 23 | /** |
embeddedartists | 0:6b68dac0d986 | 24 | * SPIFI Example |
embeddedartists | 0:6b68dac0d986 | 25 | * |
embeddedartists | 0:6b68dac0d986 | 26 | * @code |
embeddedartists | 0:6b68dac0d986 | 27 | * #include "mbed.h" |
embeddedartists | 0:6b68dac0d986 | 28 | * #include "SPIFI.h" |
embeddedartists | 0:6b68dac0d986 | 29 | * |
embeddedartists | 0:6b68dac0d986 | 30 | * int main(void) { |
embeddedartists | 0:6b68dac0d986 | 31 | * SPIFI::SpifiError err; |
embeddedartists | 0:6b68dac0d986 | 32 | * |
embeddedartists | 0:6b68dac0d986 | 33 | * err = SPIFI::instance().init(); |
embeddedartists | 0:6b68dac0d986 | 34 | * if (err != SPIFI::Ok) { |
embeddedartists | 0:6b68dac0d986 | 35 | * printf("Failed to initialize SPIFI, error %d\n", err); |
embeddedartists | 0:6b68dac0d986 | 36 | * } |
embeddedartists | 0:6b68dac0d986 | 37 | * |
embeddedartists | 0:6b68dac0d986 | 38 | * // Write "Hello World!" into the first bytes of the SPIFI |
embeddedartists | 0:6b68dac0d986 | 39 | * char buff[20] = "Hello World!"; |
embeddedartists | 0:6b68dac0d986 | 40 | * err = SPIFI::instance().program(0, strlen(buff)+1, buff, SPIFI::EraseAsRequired); |
embeddedartists | 0:6b68dac0d986 | 41 | * if (err != SPIFI::Ok) { |
embeddedartists | 0:6b68dac0d986 | 42 | * printf("Failed to write to SPIFI, error %d\n", err); |
embeddedartists | 0:6b68dac0d986 | 43 | * } |
embeddedartists | 0:6b68dac0d986 | 44 | * |
embeddedartists | 0:6b68dac0d986 | 45 | * // Now verify that it can be read |
embeddedartists | 0:6b68dac0d986 | 46 | * if (memcmp((char*)SPIFI::SpifiMemBase, buff, strlen(buff)+1) == 0) { |
embeddedartists | 0:6b68dac0d986 | 47 | * printf("Readback from memory OK: '%s'\n", SPIFI::SpifiMemBase); |
embeddedartists | 0:6b68dac0d986 | 48 | * } else { |
embeddedartists | 0:6b68dac0d986 | 49 | * printf("Spifi does not contain the correct data!\n"); |
embeddedartists | 0:6b68dac0d986 | 50 | * } |
embeddedartists | 0:6b68dac0d986 | 51 | * } |
embeddedartists | 0:6b68dac0d986 | 52 | * @endcode |
embeddedartists | 0:6b68dac0d986 | 53 | */ |
embeddedartists | 0:6b68dac0d986 | 54 | class SPIFI { |
embeddedartists | 0:6b68dac0d986 | 55 | public: |
embeddedartists | 0:6b68dac0d986 | 56 | |
embeddedartists | 0:6b68dac0d986 | 57 | enum Constants { |
embeddedartists | 0:6b68dac0d986 | 58 | SpifiMemBase = 0x28000000 |
embeddedartists | 0:6b68dac0d986 | 59 | }; |
embeddedartists | 0:6b68dac0d986 | 60 | |
embeddedartists | 0:6b68dac0d986 | 61 | enum Options { |
embeddedartists | 0:6b68dac0d986 | 62 | ForceErase = (0<<2), |
embeddedartists | 0:6b68dac0d986 | 63 | EraseAsRequired = (1<<2), |
embeddedartists | 0:6b68dac0d986 | 64 | CallerErase = (1<<3) |
embeddedartists | 0:6b68dac0d986 | 65 | }; |
embeddedartists | 0:6b68dac0d986 | 66 | |
embeddedartists | 0:6b68dac0d986 | 67 | enum SpifiError { |
embeddedartists | 0:6b68dac0d986 | 68 | Ok = 0, |
embeddedartists | 0:6b68dac0d986 | 69 | Uninitialized = 1, |
embeddedartists | 0:6b68dac0d986 | 70 | Verification = 2, |
embeddedartists | 0:6b68dac0d986 | 71 | SameAddress = 3, |
embeddedartists | 0:6b68dac0d986 | 72 | UnknownError = 4, |
embeddedartists | 0:6b68dac0d986 | 73 | InternalError = 0x20002, |
embeddedartists | 0:6b68dac0d986 | 74 | Timeout = 0x20003, |
embeddedartists | 0:6b68dac0d986 | 75 | OperandError = 0x20004, |
embeddedartists | 0:6b68dac0d986 | 76 | Status = 0x20005, |
embeddedartists | 0:6b68dac0d986 | 77 | ExtDeviceId = 0x20006, |
embeddedartists | 0:6b68dac0d986 | 78 | DeviceId = 0x20007, |
embeddedartists | 0:6b68dac0d986 | 79 | DeviceType = 0x20008, |
embeddedartists | 0:6b68dac0d986 | 80 | Manufacturer = 0x20009, |
embeddedartists | 0:6b68dac0d986 | 81 | InvalidJDECId = 0x2000A, |
embeddedartists | 0:6b68dac0d986 | 82 | EraseConflict = 0x2000B, |
embeddedartists | 0:6b68dac0d986 | 83 | }; |
embeddedartists | 0:6b68dac0d986 | 84 | |
embeddedartists | 0:6b68dac0d986 | 85 | enum Device { |
embeddedartists | 0:6b68dac0d986 | 86 | Spansion_S25FL032, /* Manufacturer: 0x01, devType: 0x02, devID: 0x15 */ |
embeddedartists | 0:6b68dac0d986 | 87 | Winbond_W25Q64FV, /* Manufacturer: 0xEF, devType: 0x40, devID: 0x17 */ |
embeddedartists | 19:2efb6f5f69a4 | 88 | Macronix_MX25L6435E, /* Manufacturer: 0xC2, devType: 0x20, devID: 0x17 */ |
embeddedartists | 19:2efb6f5f69a4 | 89 | Macronix_MX25L12835F, /* Manufacturer: 0xC2, devType: 0x20, devID: 0x18 */ |
embeddedartists | 22:1a58a518435c | 90 | SpecifiedInBios, /* The device is known by the BIOS */ |
embeddedartists | 0:6b68dac0d986 | 91 | UnknownDevice |
embeddedartists | 0:6b68dac0d986 | 92 | }; |
embeddedartists | 0:6b68dac0d986 | 93 | |
embeddedartists | 0:6b68dac0d986 | 94 | static SPIFI& instance() |
embeddedartists | 0:6b68dac0d986 | 95 | { |
embeddedartists | 0:6b68dac0d986 | 96 | static SPIFI singleton; |
embeddedartists | 0:6b68dac0d986 | 97 | return singleton; |
embeddedartists | 0:6b68dac0d986 | 98 | } |
embeddedartists | 0:6b68dac0d986 | 99 | |
embeddedartists | 0:6b68dac0d986 | 100 | |
embeddedartists | 0:6b68dac0d986 | 101 | /** Initializes the SPIFI ROM driver making the content of the external serial flash available |
embeddedartists | 0:6b68dac0d986 | 102 | * |
embeddedartists | 0:6b68dac0d986 | 103 | * @returns |
embeddedartists | 0:6b68dac0d986 | 104 | * Ok on success |
embeddedartists | 0:6b68dac0d986 | 105 | * An error code on failure |
embeddedartists | 0:6b68dac0d986 | 106 | */ |
embeddedartists | 0:6b68dac0d986 | 107 | SpifiError init(); |
embeddedartists | 0:6b68dac0d986 | 108 | |
embeddedartists | 0:6b68dac0d986 | 109 | /** Returns the detected external serial flash |
embeddedartists | 0:6b68dac0d986 | 110 | * |
embeddedartists | 0:6b68dac0d986 | 111 | * @returns |
embeddedartists | 0:6b68dac0d986 | 112 | * The detected device or UnknownDevice |
embeddedartists | 0:6b68dac0d986 | 113 | */ |
embeddedartists | 0:6b68dac0d986 | 114 | Device device() { return _device; } |
embeddedartists | 0:6b68dac0d986 | 115 | |
embeddedartists | 0:6b68dac0d986 | 116 | /** Returns the size (in bytes) of the external serial flash |
embeddedartists | 0:6b68dac0d986 | 117 | * |
embeddedartists | 0:6b68dac0d986 | 118 | * @returns |
embeddedartists | 0:6b68dac0d986 | 119 | * The size in bytes |
embeddedartists | 0:6b68dac0d986 | 120 | */ |
embeddedartists | 0:6b68dac0d986 | 121 | uint32_t memorySize() { return _memorySize; } |
embeddedartists | 0:6b68dac0d986 | 122 | |
embeddedartists | 0:6b68dac0d986 | 123 | /** Returns the size of an erase block (in bytes) on the external serial flash |
embeddedartists | 0:6b68dac0d986 | 124 | * |
embeddedartists | 0:6b68dac0d986 | 125 | * @returns |
embeddedartists | 0:6b68dac0d986 | 126 | * The erase block size in bytes |
embeddedartists | 0:6b68dac0d986 | 127 | */ |
embeddedartists | 0:6b68dac0d986 | 128 | uint32_t eraseBlockSize() { return _eraseBlockSize; } |
embeddedartists | 0:6b68dac0d986 | 129 | |
embeddedartists | 0:6b68dac0d986 | 130 | /** Returns the address where the verifcation failed. Use only after a Verification error code |
embeddedartists | 0:6b68dac0d986 | 131 | * has been retured from one of the other functions |
embeddedartists | 0:6b68dac0d986 | 132 | * |
embeddedartists | 0:6b68dac0d986 | 133 | * @returns |
embeddedartists | 0:6b68dac0d986 | 134 | * The address to where the program or erase operation failed |
embeddedartists | 0:6b68dac0d986 | 135 | */ |
embeddedartists | 0:6b68dac0d986 | 136 | uint32_t getVerificationErrorAddr() { return _verError; } |
embeddedartists | 0:6b68dac0d986 | 137 | |
embeddedartists | 0:6b68dac0d986 | 138 | /** Used by the QSPIFileSystem class to get access to all spifi internal data. |
embeddedartists | 0:6b68dac0d986 | 139 | * |
embeddedartists | 0:6b68dac0d986 | 140 | * @param initData The parameter returned by spifi_init |
embeddedartists | 0:6b68dac0d986 | 141 | * @param romPtr The location of the SPIFI ROM driver in memory |
embeddedartists | 0:6b68dac0d986 | 142 | */ |
embeddedartists | 0:6b68dac0d986 | 143 | void internalData(SPIFIobj** initData, const SPIFI_RTNS** romPtr) { *initData = _romData; *romPtr = _spifi; } |
embeddedartists | 0:6b68dac0d986 | 144 | |
embeddedartists | 0:6b68dac0d986 | 145 | /** Copies len data from src to dest. This function will split len > 256 into writes of 256 bytes each. |
embeddedartists | 0:6b68dac0d986 | 146 | * |
embeddedartists | 0:6b68dac0d986 | 147 | * Programming means that a bit can either be left at 0, or programmed from 1 to 0. Changing bits from 0 to 1 requires an erase operation. |
embeddedartists | 0:6b68dac0d986 | 148 | * While bits can be individually programmed from 1 to 0, erasing bits from 0 to 1 must be done in larger chunks (manufacturer dependant |
embeddedartists | 0:6b68dac0d986 | 149 | * but typically 4Kbyte to 64KByte at a time). |
embeddedartists | 0:6b68dac0d986 | 150 | * |
embeddedartists | 0:6b68dac0d986 | 151 | * Specify how/when erasing is done with the options parameter: |
embeddedartists | 0:6b68dac0d986 | 152 | * |
embeddedartists | 0:6b68dac0d986 | 153 | * - ForceErase causes len bytes to be erased starting at dest. If a scratch buffer (must be the size of an erase block) is |
embeddedartists | 0:6b68dac0d986 | 154 | * provided then only the len bytes will be erased. If no scratch buffer is provided then the erase block surrounding |
embeddedartists | 0:6b68dac0d986 | 155 | * dest will be erased. |
embeddedartists | 0:6b68dac0d986 | 156 | * |
embeddedartists | 0:6b68dac0d986 | 157 | * - EraseAsRequired tests if the destination can be written to without erasing. If it can then no erasing is done. If it |
embeddedartists | 0:6b68dac0d986 | 158 | * can't then behaviour is the same as if ForceErase was specified. |
embeddedartists | 0:6b68dac0d986 | 159 | * |
embeddedartists | 0:6b68dac0d986 | 160 | * - CallerErase tests if the destination can be written to without erasing. If it can then a data is written. If it |
embeddedartists | 0:6b68dac0d986 | 161 | * can't then an error code is returned and nothing is written. |
embeddedartists | 0:6b68dac0d986 | 162 | * |
embeddedartists | 0:6b68dac0d986 | 163 | * Scratch should be NULL or the address of an area of RAM that the SPIFI driver can use |
embeddedartists | 0:6b68dac0d986 | 164 | * to save data during erase operations. If provided, the scratch area should be as large |
embeddedartists | 0:6b68dac0d986 | 165 | * as the smallest erase size that is available throughout the serial flash device. If scratch |
embeddedartists | 0:6b68dac0d986 | 166 | * is NULL (zero) and an erase is necessary, any bytes in the first erase block before dest |
embeddedartists | 0:6b68dac0d986 | 167 | * are left in erased state (all ones), as are any bytes in the last erase block after dest + len |
embeddedartists | 0:6b68dac0d986 | 168 | * |
embeddedartists | 0:6b68dac0d986 | 169 | * @param dest Address to write to, highest byte must be 0x00 or 0x28 as in 0x28000000 |
embeddedartists | 0:6b68dac0d986 | 170 | * @param len Number of bytes to write |
embeddedartists | 0:6b68dac0d986 | 171 | * @param src Data to write |
embeddedartists | 0:6b68dac0d986 | 172 | * @param options How to handle content of destination |
embeddedartists | 0:6b68dac0d986 | 173 | * @param verify Should all writes be verified or not |
embeddedartists | 0:6b68dac0d986 | 174 | * @param scratch Used with ForceErase and EraseAsRequired option to preserve content of flash outside of |
embeddedartists | 0:6b68dac0d986 | 175 | * written area. Size of buffer must be at least the size of one erase block. |
embeddedartists | 0:6b68dac0d986 | 176 | * |
embeddedartists | 0:6b68dac0d986 | 177 | * @returns |
embeddedartists | 0:6b68dac0d986 | 178 | * Ok on success |
embeddedartists | 0:6b68dac0d986 | 179 | * An error code on failure |
embeddedartists | 0:6b68dac0d986 | 180 | */ |
embeddedartists | 0:6b68dac0d986 | 181 | SpifiError program(uint32_t dest, unsigned len, char* src, Options options, bool verify=false, char* scratch=NULL); |
embeddedartists | 0:6b68dac0d986 | 182 | |
embeddedartists | 0:6b68dac0d986 | 183 | /** Erases the content of the memory at the specified address |
embeddedartists | 0:6b68dac0d986 | 184 | * |
embeddedartists | 0:6b68dac0d986 | 185 | * Scratch should be NULL or the address of an area of RAM that the SPIFI driver can use |
embeddedartists | 0:6b68dac0d986 | 186 | * to save data during erase operations. If provided, the scratch area should be as large |
embeddedartists | 0:6b68dac0d986 | 187 | * as the smallest erase size that is available throughout the serial flash device. If scratch |
embeddedartists | 0:6b68dac0d986 | 188 | * is NULL (zero) and an erase is necessary, any bytes in the first erase block before dest |
embeddedartists | 0:6b68dac0d986 | 189 | * are left in erased state (all ones), as are any bytes in the last erase block after dest + len |
embeddedartists | 0:6b68dac0d986 | 190 | * |
embeddedartists | 0:6b68dac0d986 | 191 | * @param dest Address to start erasing at, highest byte must be 0x00 or 0x28 as in 0x28000000 |
embeddedartists | 0:6b68dac0d986 | 192 | * @param len Number of bytes to erase |
embeddedartists | 0:6b68dac0d986 | 193 | * @param verify Should the erased area be verified to make sure it is all 0xff |
embeddedartists | 0:6b68dac0d986 | 194 | * @param scratch Used to preserve content of flash outside of erased area. |
embeddedartists | 0:6b68dac0d986 | 195 | * Size of buffer must be at least the size of one erase block. |
embeddedartists | 0:6b68dac0d986 | 196 | * |
embeddedartists | 0:6b68dac0d986 | 197 | * @returns |
embeddedartists | 0:6b68dac0d986 | 198 | * Ok on success |
embeddedartists | 0:6b68dac0d986 | 199 | * An error code on failure |
embeddedartists | 0:6b68dac0d986 | 200 | */ |
alindvall | 37:07659b5d90ce | 201 | SpifiError erase(uint32_t dest, unsigned len, bool verify=false, char* scratch=NULL); |
embeddedartists | 0:6b68dac0d986 | 202 | |
embeddedartists | 0:6b68dac0d986 | 203 | |
embeddedartists | 0:6b68dac0d986 | 204 | private: |
embeddedartists | 0:6b68dac0d986 | 205 | |
embeddedartists | 0:6b68dac0d986 | 206 | uint32_t _verError; |
embeddedartists | 0:6b68dac0d986 | 207 | |
embeddedartists | 0:6b68dac0d986 | 208 | bool _initialized; |
embeddedartists | 0:6b68dac0d986 | 209 | |
embeddedartists | 0:6b68dac0d986 | 210 | Device _device; |
embeddedartists | 0:6b68dac0d986 | 211 | uint32_t _memorySize; |
embeddedartists | 0:6b68dac0d986 | 212 | uint32_t _eraseBlockSize; |
embeddedartists | 0:6b68dac0d986 | 213 | |
embeddedartists | 0:6b68dac0d986 | 214 | SPIFIobj* _romData; |
embeddedartists | 0:6b68dac0d986 | 215 | const SPIFI_RTNS* _spifi; |
embeddedartists | 0:6b68dac0d986 | 216 | |
embeddedartists | 0:6b68dac0d986 | 217 | char _addrConflictBuff[256]; |
embeddedartists | 0:6b68dac0d986 | 218 | |
embeddedartists | 0:6b68dac0d986 | 219 | explicit SPIFI(); |
embeddedartists | 0:6b68dac0d986 | 220 | // hide copy constructor |
embeddedartists | 0:6b68dac0d986 | 221 | SPIFI(const SPIFI&); |
embeddedartists | 0:6b68dac0d986 | 222 | // hide assign operator |
embeddedartists | 0:6b68dac0d986 | 223 | SPIFI& operator=(const SPIFI&); |
embeddedartists | 0:6b68dac0d986 | 224 | ~SPIFI(); |
embeddedartists | 0:6b68dac0d986 | 225 | |
embeddedartists | 0:6b68dac0d986 | 226 | SpifiError translateError(int err, bool verify = false); |
embeddedartists | 0:6b68dac0d986 | 227 | }; |
embeddedartists | 0:6b68dac0d986 | 228 | |
embeddedartists | 0:6b68dac0d986 | 229 | #endif |