USBMSD device (USB Flashdisk) library using AT45DBxx serial flash storage chip. Works with 2, 4, 8, 16, 32 and 64 Mbit chips within AT45DBxx series.
Dependents: USBMSD_AT45_HelloWorld
USBMSD_AT45.cpp@0:c0dc2df7c9fe, 2012-10-27 (annotated)
- Committer:
- llumpu
- Date:
- Sat Oct 27 14:18:07 2012 +0000
- Revision:
- 0:c0dc2df7c9fe
Initial release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
llumpu | 0:c0dc2df7c9fe | 1 | /* Copyright (c) <2012> <llumpu>, MIT License |
llumpu | 0:c0dc2df7c9fe | 2 | * |
llumpu | 0:c0dc2df7c9fe | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
llumpu | 0:c0dc2df7c9fe | 4 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
llumpu | 0:c0dc2df7c9fe | 5 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
llumpu | 0:c0dc2df7c9fe | 6 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
llumpu | 0:c0dc2df7c9fe | 7 | * furnished to do so, subject to the following conditions: |
llumpu | 0:c0dc2df7c9fe | 8 | * |
llumpu | 0:c0dc2df7c9fe | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
llumpu | 0:c0dc2df7c9fe | 10 | * substantial portions of the Software. |
llumpu | 0:c0dc2df7c9fe | 11 | * |
llumpu | 0:c0dc2df7c9fe | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
llumpu | 0:c0dc2df7c9fe | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
llumpu | 0:c0dc2df7c9fe | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
llumpu | 0:c0dc2df7c9fe | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
llumpu | 0:c0dc2df7c9fe | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
llumpu | 0:c0dc2df7c9fe | 17 | */ |
llumpu | 0:c0dc2df7c9fe | 18 | |
llumpu | 0:c0dc2df7c9fe | 19 | /* |
llumpu | 0:c0dc2df7c9fe | 20 | * Inspired by Steen Joergensen (stjo2809) and Chris Styles AT45 libraries |
llumpu | 0:c0dc2df7c9fe | 21 | */ |
llumpu | 0:c0dc2df7c9fe | 22 | |
llumpu | 0:c0dc2df7c9fe | 23 | #include "mbed.h" |
llumpu | 0:c0dc2df7c9fe | 24 | #include "USBMSD_AT45.h" |
llumpu | 0:c0dc2df7c9fe | 25 | |
llumpu | 0:c0dc2df7c9fe | 26 | |
llumpu | 0:c0dc2df7c9fe | 27 | |
llumpu | 0:c0dc2df7c9fe | 28 | #define IS_PAGE_BINARY 0x01 |
llumpu | 0:c0dc2df7c9fe | 29 | #define IS_FLASH_READY 0x80 |
llumpu | 0:c0dc2df7c9fe | 30 | |
llumpu | 0:c0dc2df7c9fe | 31 | #define TWO_MBIT 0x03 |
llumpu | 0:c0dc2df7c9fe | 32 | #define FOUR_MBIT 0x04 |
llumpu | 0:c0dc2df7c9fe | 33 | #define EIGHT_MBIT 0x05 |
llumpu | 0:c0dc2df7c9fe | 34 | #define SIXTEEN_MBIT 0x06 |
llumpu | 0:c0dc2df7c9fe | 35 | #define THIRTYTWO_MBIT 0x07 |
llumpu | 0:c0dc2df7c9fe | 36 | #define SIXTYFOUR_MBIT 0x08 |
llumpu | 0:c0dc2df7c9fe | 37 | |
llumpu | 0:c0dc2df7c9fe | 38 | DigitalOut read_act_led(LED1); // LED indicating data are being read from storage chip |
llumpu | 0:c0dc2df7c9fe | 39 | DigitalOut write_act_led(LED2); // LED indicating data are being written to storage chip |
llumpu | 0:c0dc2df7c9fe | 40 | |
llumpu | 0:c0dc2df7c9fe | 41 | //Serial _pc(USBTX, USBRX); |
llumpu | 0:c0dc2df7c9fe | 42 | |
llumpu | 0:c0dc2df7c9fe | 43 | |
llumpu | 0:c0dc2df7c9fe | 44 | /************************************** Constructor **************************************/ |
llumpu | 0:c0dc2df7c9fe | 45 | |
llumpu | 0:c0dc2df7c9fe | 46 | |
llumpu | 0:c0dc2df7c9fe | 47 | USBMSD_AT45::USBMSD_AT45(PinName mosi, PinName miso, PinName sclk, PinName ncs, int transport_block_size) : |
llumpu | 0:c0dc2df7c9fe | 48 | _spi(mosi, miso, sclk), _ncs(ncs), _transport_block_size (transport_block_size) |
llumpu | 0:c0dc2df7c9fe | 49 | { |
llumpu | 0:c0dc2df7c9fe | 50 | //_pc.baud(921600); |
llumpu | 0:c0dc2df7c9fe | 51 | _spi.format(8,3); |
llumpu | 0:c0dc2df7c9fe | 52 | _spi.frequency(24000000); |
llumpu | 0:c0dc2df7c9fe | 53 | |
llumpu | 0:c0dc2df7c9fe | 54 | write_act_led = 0; |
llumpu | 0:c0dc2df7c9fe | 55 | read_act_led = 0; |
llumpu | 0:c0dc2df7c9fe | 56 | |
llumpu | 0:c0dc2df7c9fe | 57 | _init_status = 1; // memory chip is not ready, disk_initialize() will be called in connect() |
llumpu | 0:c0dc2df7c9fe | 58 | |
llumpu | 0:c0dc2df7c9fe | 59 | connect(); |
llumpu | 0:c0dc2df7c9fe | 60 | } |
llumpu | 0:c0dc2df7c9fe | 61 | |
llumpu | 0:c0dc2df7c9fe | 62 | |
llumpu | 0:c0dc2df7c9fe | 63 | /************************************ Public methods ************************************/ |
llumpu | 0:c0dc2df7c9fe | 64 | |
llumpu | 0:c0dc2df7c9fe | 65 | |
llumpu | 0:c0dc2df7c9fe | 66 | // This method is called when disk_status returns 0x01 (not initialized) |
llumpu | 0:c0dc2df7c9fe | 67 | |
llumpu | 0:c0dc2df7c9fe | 68 | int USBMSD_AT45::disk_initialize() |
llumpu | 0:c0dc2df7c9fe | 69 | { |
llumpu | 0:c0dc2df7c9fe | 70 | _initialize(); // Determine storage chip parameters |
llumpu | 0:c0dc2df7c9fe | 71 | |
llumpu | 0:c0dc2df7c9fe | 72 | write_act_led = 1; |
llumpu | 0:c0dc2df7c9fe | 73 | read_act_led = 1; |
llumpu | 0:c0dc2df7c9fe | 74 | |
llumpu | 0:c0dc2df7c9fe | 75 | _init_status = 0; // Set status to 0x00 (initialized) |
llumpu | 0:c0dc2df7c9fe | 76 | |
llumpu | 0:c0dc2df7c9fe | 77 | return _init_status; |
llumpu | 0:c0dc2df7c9fe | 78 | } |
llumpu | 0:c0dc2df7c9fe | 79 | |
llumpu | 0:c0dc2df7c9fe | 80 | // Returns size of storage chip in bytes |
llumpu | 0:c0dc2df7c9fe | 81 | |
llumpu | 0:c0dc2df7c9fe | 82 | int USBMSD_AT45::disk_size() |
llumpu | 0:c0dc2df7c9fe | 83 | { |
llumpu | 0:c0dc2df7c9fe | 84 | return _flash_size; |
llumpu | 0:c0dc2df7c9fe | 85 | } |
llumpu | 0:c0dc2df7c9fe | 86 | |
llumpu | 0:c0dc2df7c9fe | 87 | // Returns count of sectors of storage chip |
llumpu | 0:c0dc2df7c9fe | 88 | |
llumpu | 0:c0dc2df7c9fe | 89 | int USBMSD_AT45::disk_sectors() |
llumpu | 0:c0dc2df7c9fe | 90 | { |
llumpu | 0:c0dc2df7c9fe | 91 | return (_flash_size / _transport_block_size); |
llumpu | 0:c0dc2df7c9fe | 92 | } |
llumpu | 0:c0dc2df7c9fe | 93 | |
llumpu | 0:c0dc2df7c9fe | 94 | // Returns status of storage chip - 0x00 ready, 0x01 not initialized (disk_initialize is then called) |
llumpu | 0:c0dc2df7c9fe | 95 | |
llumpu | 0:c0dc2df7c9fe | 96 | int USBMSD_AT45::disk_status() |
llumpu | 0:c0dc2df7c9fe | 97 | { |
llumpu | 0:c0dc2df7c9fe | 98 | //_pc.printf("d_status \n\r "); |
llumpu | 0:c0dc2df7c9fe | 99 | return _init_status; |
llumpu | 0:c0dc2df7c9fe | 100 | } |
llumpu | 0:c0dc2df7c9fe | 101 | |
llumpu | 0:c0dc2df7c9fe | 102 | // Reads block of data from storage chip. Size of block is set in constructor. |
llumpu | 0:c0dc2df7c9fe | 103 | |
llumpu | 0:c0dc2df7c9fe | 104 | int USBMSD_AT45::disk_read(char* data, int block) |
llumpu | 0:c0dc2df7c9fe | 105 | { |
llumpu | 0:c0dc2df7c9fe | 106 | read_act_led = 0; |
llumpu | 0:c0dc2df7c9fe | 107 | |
llumpu | 0:c0dc2df7c9fe | 108 | //_pc.printf("r 0x%2d ", block); |
llumpu | 0:c0dc2df7c9fe | 109 | //_pc.printf(" \n\r"); |
llumpu | 0:c0dc2df7c9fe | 110 | |
llumpu | 0:c0dc2df7c9fe | 111 | int address = block * _transport_block_size; // Start address of block |
llumpu | 0:c0dc2df7c9fe | 112 | int count = (_transport_block_size / _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 113 | int transport_address = 0; |
llumpu | 0:c0dc2df7c9fe | 114 | |
llumpu | 0:c0dc2df7c9fe | 115 | // If block transported over USB is bigger than size of AT45 SRAM buffer. |
llumpu | 0:c0dc2df7c9fe | 116 | // We read all parts of block one by one to SRAM 1 and SRAM 2 and then transfer them to host at once. |
llumpu | 0:c0dc2df7c9fe | 117 | |
llumpu | 0:c0dc2df7c9fe | 118 | if(_transport_block_size > _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 119 | |
llumpu | 0:c0dc2df7c9fe | 120 | // We load data to first SRAM buffer and then to second SRAM buffer |
llumpu | 0:c0dc2df7c9fe | 121 | // We do this again if block transported over USB is more than 2 x bigger than SRAM buffer is |
llumpu | 0:c0dc2df7c9fe | 122 | |
llumpu | 0:c0dc2df7c9fe | 123 | for(int i=0; i<(count / 2); i++) { |
llumpu | 0:c0dc2df7c9fe | 124 | |
llumpu | 0:c0dc2df7c9fe | 125 | |
llumpu | 0:c0dc2df7c9fe | 126 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 127 | _flashread(1, address); // Read first part of block into SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 128 | |
llumpu | 0:c0dc2df7c9fe | 129 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 130 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 131 | _spi.write(0xd4); // Read data from SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 132 | _sendaddr (0x0); // Start address of block in SRAM buffer : 0 - We read entire buffer |
llumpu | 0:c0dc2df7c9fe | 133 | _spi.write (0x0); // Don't care byte |
llumpu | 0:c0dc2df7c9fe | 134 | |
llumpu | 0:c0dc2df7c9fe | 135 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 136 | data[transport_address + i] = _spi.write (0x0); |
llumpu | 0:c0dc2df7c9fe | 137 | } |
llumpu | 0:c0dc2df7c9fe | 138 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 139 | |
llumpu | 0:c0dc2df7c9fe | 140 | transport_address = (transport_address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 141 | address = (address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 142 | |
llumpu | 0:c0dc2df7c9fe | 143 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 144 | _flashread(2,address); // Read first part of block into SRAM 2 buffer |
llumpu | 0:c0dc2df7c9fe | 145 | |
llumpu | 0:c0dc2df7c9fe | 146 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 147 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 148 | _spi.write(0xd6); // Read data from SRAM 2 buffer |
llumpu | 0:c0dc2df7c9fe | 149 | _sendaddr (0x0); // Start address of block in SRAM buffer : 0 - We read entire buffer |
llumpu | 0:c0dc2df7c9fe | 150 | _spi.write (0x0); // Don't care byte |
llumpu | 0:c0dc2df7c9fe | 151 | |
llumpu | 0:c0dc2df7c9fe | 152 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 153 | data[transport_address + i] = _spi.write (0x0); |
llumpu | 0:c0dc2df7c9fe | 154 | } |
llumpu | 0:c0dc2df7c9fe | 155 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 156 | |
llumpu | 0:c0dc2df7c9fe | 157 | transport_address = (transport_address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 158 | address = (address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 159 | } |
llumpu | 0:c0dc2df7c9fe | 160 | |
llumpu | 0:c0dc2df7c9fe | 161 | } |
llumpu | 0:c0dc2df7c9fe | 162 | |
llumpu | 0:c0dc2df7c9fe | 163 | |
llumpu | 0:c0dc2df7c9fe | 164 | // If block transported over USB equals size of AT45 SRAM buffer. |
llumpu | 0:c0dc2df7c9fe | 165 | // We read whole block into SRAM 1 buffer and then transport it to host. |
llumpu | 0:c0dc2df7c9fe | 166 | |
llumpu | 0:c0dc2df7c9fe | 167 | else if(_transport_block_size == _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 168 | |
llumpu | 0:c0dc2df7c9fe | 169 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 170 | _flashread(1, address); // Read whole block into SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 171 | |
llumpu | 0:c0dc2df7c9fe | 172 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 173 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 174 | _spi.write(0xd4); // Read data from SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 175 | _sendaddr (0x0); // Start address of block in SRAM buffer : 0 - We read entire buffer |
llumpu | 0:c0dc2df7c9fe | 176 | _spi.write (0x0); // Don't care byte |
llumpu | 0:c0dc2df7c9fe | 177 | |
llumpu | 0:c0dc2df7c9fe | 178 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 179 | data[transport_address + i] = _spi.write (0x0); |
llumpu | 0:c0dc2df7c9fe | 180 | } |
llumpu | 0:c0dc2df7c9fe | 181 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 182 | |
llumpu | 0:c0dc2df7c9fe | 183 | |
llumpu | 0:c0dc2df7c9fe | 184 | } |
llumpu | 0:c0dc2df7c9fe | 185 | |
llumpu | 0:c0dc2df7c9fe | 186 | // If block transported over USB is smaller than size of AT45 SRAM buffer. |
llumpu | 0:c0dc2df7c9fe | 187 | // We read whole page into SRAM 1 and then transfer only desired part of SRAM buffer. |
llumpu | 0:c0dc2df7c9fe | 188 | |
llumpu | 0:c0dc2df7c9fe | 189 | else if(_transport_block_size < _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 190 | |
llumpu | 0:c0dc2df7c9fe | 191 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 192 | _flashread(1, address); // Read whole memory page into SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 193 | |
llumpu | 0:c0dc2df7c9fe | 194 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 195 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 196 | _spi.write(0xd4); // Read data from SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 197 | _sendaddr (0x0); // Start address of block in SRAM buffer : 0 - We read entire buffer |
llumpu | 0:c0dc2df7c9fe | 198 | _spi.write (0x0); // dont care byte |
llumpu | 0:c0dc2df7c9fe | 199 | |
llumpu | 0:c0dc2df7c9fe | 200 | for(int i = 0; i < _transport_block_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 201 | data[transport_address + i] = _spi.write (0x0); |
llumpu | 0:c0dc2df7c9fe | 202 | } |
llumpu | 0:c0dc2df7c9fe | 203 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 204 | |
llumpu | 0:c0dc2df7c9fe | 205 | |
llumpu | 0:c0dc2df7c9fe | 206 | } |
llumpu | 0:c0dc2df7c9fe | 207 | |
llumpu | 0:c0dc2df7c9fe | 208 | read_act_led = 1; |
llumpu | 0:c0dc2df7c9fe | 209 | return (0); |
llumpu | 0:c0dc2df7c9fe | 210 | |
llumpu | 0:c0dc2df7c9fe | 211 | } |
llumpu | 0:c0dc2df7c9fe | 212 | |
llumpu | 0:c0dc2df7c9fe | 213 | |
llumpu | 0:c0dc2df7c9fe | 214 | // Writes block of data to storage chip. Size of block is set in constructor |
llumpu | 0:c0dc2df7c9fe | 215 | |
llumpu | 0:c0dc2df7c9fe | 216 | int USBMSD_AT45::disk_write(const char* data, int block) |
llumpu | 0:c0dc2df7c9fe | 217 | { |
llumpu | 0:c0dc2df7c9fe | 218 | write_act_led = 0; |
llumpu | 0:c0dc2df7c9fe | 219 | |
llumpu | 0:c0dc2df7c9fe | 220 | //_pc.printf("w 0x%2d ", block); |
llumpu | 0:c0dc2df7c9fe | 221 | //_pc.printf(" \n\r"); |
llumpu | 0:c0dc2df7c9fe | 222 | |
llumpu | 0:c0dc2df7c9fe | 223 | int address = block * _transport_block_size; // This is the start address of the block |
llumpu | 0:c0dc2df7c9fe | 224 | int count = (_transport_block_size / _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 225 | int transport_address = 0; |
llumpu | 0:c0dc2df7c9fe | 226 | |
llumpu | 0:c0dc2df7c9fe | 227 | // If block transported over USB is bigger than size of AT45 SRAM buffer. |
llumpu | 0:c0dc2df7c9fe | 228 | // We write all parts of block one by one to SRAM 1 and SRAM 2 and then we write them to flash. |
llumpu | 0:c0dc2df7c9fe | 229 | |
llumpu | 0:c0dc2df7c9fe | 230 | if(_transport_block_size >_flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 231 | |
llumpu | 0:c0dc2df7c9fe | 232 | // But if memory page size (and SRAM buffer size) is not binary |
llumpu | 0:c0dc2df7c9fe | 233 | // Before each write, we must read desired block from flash to SRAM buffer first |
llumpu | 0:c0dc2df7c9fe | 234 | // then write data from host to same SRAM buffer. After this we store whole |
llumpu | 0:c0dc2df7c9fe | 235 | // SRAM buffer back to flash. This slows down writing speed but must be done because |
llumpu | 0:c0dc2df7c9fe | 236 | // SRAM buffer size is bigger than (part of) data we want to write and it would corrupt |
llumpu | 0:c0dc2df7c9fe | 237 | // previously stored data if not done. |
llumpu | 0:c0dc2df7c9fe | 238 | |
llumpu | 0:c0dc2df7c9fe | 239 | if(_page_size > _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 240 | |
llumpu | 0:c0dc2df7c9fe | 241 | for(int i=0; i<(count / 2); i++) { |
llumpu | 0:c0dc2df7c9fe | 242 | |
llumpu | 0:c0dc2df7c9fe | 243 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 244 | _flashread(1, address); // Read first part of block into SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 245 | |
llumpu | 0:c0dc2df7c9fe | 246 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 247 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 248 | _spi.write(0x84); // Write data to SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 249 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 250 | |
llumpu | 0:c0dc2df7c9fe | 251 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 252 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 253 | } |
llumpu | 0:c0dc2df7c9fe | 254 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 255 | |
llumpu | 0:c0dc2df7c9fe | 256 | _flashwrite(1, address); // Write first part of block from SRAM 1 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 257 | |
llumpu | 0:c0dc2df7c9fe | 258 | transport_address = (transport_address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 259 | address = (address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 260 | |
llumpu | 0:c0dc2df7c9fe | 261 | |
llumpu | 0:c0dc2df7c9fe | 262 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 263 | _flashread(2, address); // Read next part of block into SRAM 2 buffer |
llumpu | 0:c0dc2df7c9fe | 264 | |
llumpu | 0:c0dc2df7c9fe | 265 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 266 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 267 | _spi.write(0x87); // Write data to SRAM 2 buffer |
llumpu | 0:c0dc2df7c9fe | 268 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 269 | |
llumpu | 0:c0dc2df7c9fe | 270 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 271 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 272 | } |
llumpu | 0:c0dc2df7c9fe | 273 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 274 | |
llumpu | 0:c0dc2df7c9fe | 275 | _flashwrite(2, address); // Write next part of block from SRAM 2 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 276 | |
llumpu | 0:c0dc2df7c9fe | 277 | transport_address = (transport_address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 278 | address = (address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 279 | |
llumpu | 0:c0dc2df7c9fe | 280 | } |
llumpu | 0:c0dc2df7c9fe | 281 | |
llumpu | 0:c0dc2df7c9fe | 282 | |
llumpu | 0:c0dc2df7c9fe | 283 | } |
llumpu | 0:c0dc2df7c9fe | 284 | |
llumpu | 0:c0dc2df7c9fe | 285 | |
llumpu | 0:c0dc2df7c9fe | 286 | // Else if memory page size (and SRAM buffer size) is binary |
llumpu | 0:c0dc2df7c9fe | 287 | // We write all parts of block one by one to SRAM 1 and SRAM 2 and then store them to flash |
llumpu | 0:c0dc2df7c9fe | 288 | |
llumpu | 0:c0dc2df7c9fe | 289 | else { |
llumpu | 0:c0dc2df7c9fe | 290 | |
llumpu | 0:c0dc2df7c9fe | 291 | for(int i=0; i<(count / 2); i++) { |
llumpu | 0:c0dc2df7c9fe | 292 | |
llumpu | 0:c0dc2df7c9fe | 293 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 294 | _spi.write(0x84); // Write data to SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 295 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 296 | |
llumpu | 0:c0dc2df7c9fe | 297 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 298 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 299 | } |
llumpu | 0:c0dc2df7c9fe | 300 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 301 | |
llumpu | 0:c0dc2df7c9fe | 302 | _flashwrite(1, address); // Write first part of block from SRAM 1 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 303 | |
llumpu | 0:c0dc2df7c9fe | 304 | transport_address = (transport_address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 305 | address = (address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 306 | |
llumpu | 0:c0dc2df7c9fe | 307 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 308 | _spi.write(0x87); // Write data to SRAM 2 buffer |
llumpu | 0:c0dc2df7c9fe | 309 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 310 | |
llumpu | 0:c0dc2df7c9fe | 311 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 312 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 313 | } |
llumpu | 0:c0dc2df7c9fe | 314 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 315 | |
llumpu | 0:c0dc2df7c9fe | 316 | _flashwrite(2, address); // Write next part of block from SRAM 2 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 317 | |
llumpu | 0:c0dc2df7c9fe | 318 | transport_address = (transport_address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 319 | address = (address + _flash_buffer_size); |
llumpu | 0:c0dc2df7c9fe | 320 | |
llumpu | 0:c0dc2df7c9fe | 321 | } |
llumpu | 0:c0dc2df7c9fe | 322 | } |
llumpu | 0:c0dc2df7c9fe | 323 | |
llumpu | 0:c0dc2df7c9fe | 324 | } |
llumpu | 0:c0dc2df7c9fe | 325 | |
llumpu | 0:c0dc2df7c9fe | 326 | // If block transported over USB equals size of AT45 SRAM buffer. |
llumpu | 0:c0dc2df7c9fe | 327 | // We write whole block into SRAM 1 buffer and then we write SRAM 1 buffer to flash. |
llumpu | 0:c0dc2df7c9fe | 328 | |
llumpu | 0:c0dc2df7c9fe | 329 | else if(_transport_block_size == _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 330 | |
llumpu | 0:c0dc2df7c9fe | 331 | // But if memory page size (and SRAM buffer size) is not binary |
llumpu | 0:c0dc2df7c9fe | 332 | // Before each write, we must read desired block from flash to SRAM buffer first |
llumpu | 0:c0dc2df7c9fe | 333 | // then write data from host to same SRAM buffer. After this we store whole |
llumpu | 0:c0dc2df7c9fe | 334 | // SRAM buffer back to flash. This slows down writing speed but must be done because |
llumpu | 0:c0dc2df7c9fe | 335 | // SRAM buffer size is bigger than (part of) data we want to write and it would corrupt |
llumpu | 0:c0dc2df7c9fe | 336 | // previously stored data if not done. |
llumpu | 0:c0dc2df7c9fe | 337 | |
llumpu | 0:c0dc2df7c9fe | 338 | if(_page_size > _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 339 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 340 | _flashread(1, address); // Read block into SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 341 | |
llumpu | 0:c0dc2df7c9fe | 342 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 343 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 344 | _spi.write(0x84); // Write data to SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 345 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 346 | |
llumpu | 0:c0dc2df7c9fe | 347 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 348 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 349 | } |
llumpu | 0:c0dc2df7c9fe | 350 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 351 | |
llumpu | 0:c0dc2df7c9fe | 352 | _flashwrite(1, address); // Write block from SRAM 1 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 353 | |
llumpu | 0:c0dc2df7c9fe | 354 | |
llumpu | 0:c0dc2df7c9fe | 355 | } |
llumpu | 0:c0dc2df7c9fe | 356 | |
llumpu | 0:c0dc2df7c9fe | 357 | // Else if memory page size (and SRAM buffer size) is binary |
llumpu | 0:c0dc2df7c9fe | 358 | // We write whole block of data to SRAM 1 buffer and then store it to flash |
llumpu | 0:c0dc2df7c9fe | 359 | |
llumpu | 0:c0dc2df7c9fe | 360 | else { |
llumpu | 0:c0dc2df7c9fe | 361 | |
llumpu | 0:c0dc2df7c9fe | 362 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 363 | _spi.write(0x84); // Write data to SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 364 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 365 | |
llumpu | 0:c0dc2df7c9fe | 366 | for(int i = 0; i < _flash_buffer_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 367 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 368 | } |
llumpu | 0:c0dc2df7c9fe | 369 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 370 | |
llumpu | 0:c0dc2df7c9fe | 371 | _flashwrite(1, address); // Write block from SRAM 1 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 372 | } |
llumpu | 0:c0dc2df7c9fe | 373 | |
llumpu | 0:c0dc2df7c9fe | 374 | } |
llumpu | 0:c0dc2df7c9fe | 375 | |
llumpu | 0:c0dc2df7c9fe | 376 | // If block transported over USB is smaller than size of AT45 SRAM buffer |
llumpu | 0:c0dc2df7c9fe | 377 | // We always have to read block being written because we store whole SRAM buffer which is bigger |
llumpu | 0:c0dc2df7c9fe | 378 | // than block we want write and if not done, data in previously stored blocks will be corrupted. |
llumpu | 0:c0dc2df7c9fe | 379 | |
llumpu | 0:c0dc2df7c9fe | 380 | // Before each write, we must read desired block from flash to SRAM buffer first |
llumpu | 0:c0dc2df7c9fe | 381 | // then write data from host to same SRAM buffer. After this we store whole |
llumpu | 0:c0dc2df7c9fe | 382 | // SRAM buffer back to flash. This slows down writing speed but must be done because |
llumpu | 0:c0dc2df7c9fe | 383 | // SRAM buffer size is bigger than (part of) data we want to write and it would corrupt |
llumpu | 0:c0dc2df7c9fe | 384 | // previously stored data if not done. |
llumpu | 0:c0dc2df7c9fe | 385 | |
llumpu | 0:c0dc2df7c9fe | 386 | else if(_transport_block_size < _flash_buffer_size) { |
llumpu | 0:c0dc2df7c9fe | 387 | |
llumpu | 0:c0dc2df7c9fe | 388 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 389 | _flashread(1, address); // Read block into SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 390 | |
llumpu | 0:c0dc2df7c9fe | 391 | _busy(); // Check if we can proceed |
llumpu | 0:c0dc2df7c9fe | 392 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 393 | _spi.write(0x84); // Write data to SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 394 | _sendaddr (0); // Start address of block written to SRAM buffer : 0 - We write buffer from start |
llumpu | 0:c0dc2df7c9fe | 395 | |
llumpu | 0:c0dc2df7c9fe | 396 | for(int i = 0; i < _transport_block_size; i++) { |
llumpu | 0:c0dc2df7c9fe | 397 | _spi.write (data[transport_address + i]); |
llumpu | 0:c0dc2df7c9fe | 398 | } |
llumpu | 0:c0dc2df7c9fe | 399 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 400 | |
llumpu | 0:c0dc2df7c9fe | 401 | _flashwrite(1, address); // Write block from SRAM 1 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 402 | |
llumpu | 0:c0dc2df7c9fe | 403 | }// if block smaller ends |
llumpu | 0:c0dc2df7c9fe | 404 | |
llumpu | 0:c0dc2df7c9fe | 405 | |
llumpu | 0:c0dc2df7c9fe | 406 | |
llumpu | 0:c0dc2df7c9fe | 407 | write_act_led = 1; |
llumpu | 0:c0dc2df7c9fe | 408 | return (0); |
llumpu | 0:c0dc2df7c9fe | 409 | |
llumpu | 0:c0dc2df7c9fe | 410 | } |
llumpu | 0:c0dc2df7c9fe | 411 | |
llumpu | 0:c0dc2df7c9fe | 412 | |
llumpu | 0:c0dc2df7c9fe | 413 | |
llumpu | 0:c0dc2df7c9fe | 414 | /************************************ Protected methods ************************************/ |
llumpu | 0:c0dc2df7c9fe | 415 | |
llumpu | 0:c0dc2df7c9fe | 416 | // Determine storage chip parameters |
llumpu | 0:c0dc2df7c9fe | 417 | |
llumpu | 0:c0dc2df7c9fe | 418 | void USBMSD_AT45::_initialize() |
llumpu | 0:c0dc2df7c9fe | 419 | { |
llumpu | 0:c0dc2df7c9fe | 420 | _busy(); // Must be here? - Check status of storage chip |
llumpu | 0:c0dc2df7c9fe | 421 | |
llumpu | 0:c0dc2df7c9fe | 422 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 423 | |
llumpu | 0:c0dc2df7c9fe | 424 | _spi.write(0x9f); // Read Manufacturer ID & Device ID |
llumpu | 0:c0dc2df7c9fe | 425 | |
llumpu | 0:c0dc2df7c9fe | 426 | int ManufacturerID = (_spi.write(0x00)); |
llumpu | 0:c0dc2df7c9fe | 427 | int DeviceID_0 = (_spi.write(0x00)); |
llumpu | 0:c0dc2df7c9fe | 428 | int DeviceID_1 = (_spi.write(0x00)); |
llumpu | 0:c0dc2df7c9fe | 429 | int ExtendedID_length = (_spi.write(0x00)); |
llumpu | 0:c0dc2df7c9fe | 430 | |
llumpu | 0:c0dc2df7c9fe | 431 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 432 | |
llumpu | 0:c0dc2df7c9fe | 433 | |
llumpu | 0:c0dc2df7c9fe | 434 | int DensityCode = (DeviceID_0 & 0x1f); // Determine density of storage chip in Mbits |
llumpu | 0:c0dc2df7c9fe | 435 | |
llumpu | 0:c0dc2df7c9fe | 436 | |
llumpu | 0:c0dc2df7c9fe | 437 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 438 | |
llumpu | 0:c0dc2df7c9fe | 439 | _spi.write(0xd7); // Read status of storage chip and determine if memory page size is binary |
llumpu | 0:c0dc2df7c9fe | 440 | |
llumpu | 0:c0dc2df7c9fe | 441 | int PageIsBinary = ((_spi.write(0x00)) & IS_PAGE_BINARY); // Check if bit 0 is set to 1 |
llumpu | 0:c0dc2df7c9fe | 442 | |
llumpu | 0:c0dc2df7c9fe | 443 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 444 | |
llumpu | 0:c0dc2df7c9fe | 445 | //_pc.printf("M %x \n\r", ManufacturerID); |
llumpu | 0:c0dc2df7c9fe | 446 | //_pc.printf("D0 %x \n\r", DeviceID_0); |
llumpu | 0:c0dc2df7c9fe | 447 | //_pc.printf("D1 %x \n\r", DeviceID_1); |
llumpu | 0:c0dc2df7c9fe | 448 | //_pc.printf("E %x \n\r", ExtendedID_length); |
llumpu | 0:c0dc2df7c9fe | 449 | |
llumpu | 0:c0dc2df7c9fe | 450 | |
llumpu | 0:c0dc2df7c9fe | 451 | if (DensityCode == TWO_MBIT) { // 2Mbits |
llumpu | 0:c0dc2df7c9fe | 452 | |
llumpu | 0:c0dc2df7c9fe | 453 | if (PageIsBinary) { |
llumpu | 0:c0dc2df7c9fe | 454 | |
llumpu | 0:c0dc2df7c9fe | 455 | _flash_size = 262144; |
llumpu | 0:c0dc2df7c9fe | 456 | _flash_buffer_size = 256; |
llumpu | 0:c0dc2df7c9fe | 457 | _page_size = 256; |
llumpu | 0:c0dc2df7c9fe | 458 | |
llumpu | 0:c0dc2df7c9fe | 459 | } else { |
llumpu | 0:c0dc2df7c9fe | 460 | |
llumpu | 0:c0dc2df7c9fe | 461 | _flash_size = 270336; |
llumpu | 0:c0dc2df7c9fe | 462 | _flash_buffer_size = 256; |
llumpu | 0:c0dc2df7c9fe | 463 | _page_size = 264; |
llumpu | 0:c0dc2df7c9fe | 464 | |
llumpu | 0:c0dc2df7c9fe | 465 | } |
llumpu | 0:c0dc2df7c9fe | 466 | } else if (DensityCode == FOUR_MBIT) { // 4Mbits |
llumpu | 0:c0dc2df7c9fe | 467 | |
llumpu | 0:c0dc2df7c9fe | 468 | if (PageIsBinary) { |
llumpu | 0:c0dc2df7c9fe | 469 | |
llumpu | 0:c0dc2df7c9fe | 470 | _flash_size = 524288; |
llumpu | 0:c0dc2df7c9fe | 471 | _flash_buffer_size = 256; |
llumpu | 0:c0dc2df7c9fe | 472 | _page_size = 256; |
llumpu | 0:c0dc2df7c9fe | 473 | |
llumpu | 0:c0dc2df7c9fe | 474 | } else { |
llumpu | 0:c0dc2df7c9fe | 475 | |
llumpu | 0:c0dc2df7c9fe | 476 | _flash_size = 540672; |
llumpu | 0:c0dc2df7c9fe | 477 | _flash_buffer_size = 256; |
llumpu | 0:c0dc2df7c9fe | 478 | _page_size = 264; |
llumpu | 0:c0dc2df7c9fe | 479 | |
llumpu | 0:c0dc2df7c9fe | 480 | } |
llumpu | 0:c0dc2df7c9fe | 481 | } else if (DensityCode == EIGHT_MBIT) { // 8Mbits |
llumpu | 0:c0dc2df7c9fe | 482 | |
llumpu | 0:c0dc2df7c9fe | 483 | if (PageIsBinary) { |
llumpu | 0:c0dc2df7c9fe | 484 | |
llumpu | 0:c0dc2df7c9fe | 485 | _flash_size = 1048576; |
llumpu | 0:c0dc2df7c9fe | 486 | _flash_buffer_size = 256; |
llumpu | 0:c0dc2df7c9fe | 487 | _page_size = 256; |
llumpu | 0:c0dc2df7c9fe | 488 | |
llumpu | 0:c0dc2df7c9fe | 489 | } else { |
llumpu | 0:c0dc2df7c9fe | 490 | |
llumpu | 0:c0dc2df7c9fe | 491 | _flash_size = 1081344; |
llumpu | 0:c0dc2df7c9fe | 492 | _flash_buffer_size = 256; |
llumpu | 0:c0dc2df7c9fe | 493 | _page_size = 264; |
llumpu | 0:c0dc2df7c9fe | 494 | |
llumpu | 0:c0dc2df7c9fe | 495 | } |
llumpu | 0:c0dc2df7c9fe | 496 | } else if (DensityCode == SIXTEEN_MBIT) { // 16Mbits |
llumpu | 0:c0dc2df7c9fe | 497 | |
llumpu | 0:c0dc2df7c9fe | 498 | if (PageIsBinary) { |
llumpu | 0:c0dc2df7c9fe | 499 | |
llumpu | 0:c0dc2df7c9fe | 500 | _flash_size = 2097152; |
llumpu | 0:c0dc2df7c9fe | 501 | _flash_buffer_size = 512; |
llumpu | 0:c0dc2df7c9fe | 502 | _page_size = 512; |
llumpu | 0:c0dc2df7c9fe | 503 | |
llumpu | 0:c0dc2df7c9fe | 504 | } else { |
llumpu | 0:c0dc2df7c9fe | 505 | |
llumpu | 0:c0dc2df7c9fe | 506 | _flash_size = 2162688; |
llumpu | 0:c0dc2df7c9fe | 507 | _flash_buffer_size = 512; |
llumpu | 0:c0dc2df7c9fe | 508 | _page_size = 528; |
llumpu | 0:c0dc2df7c9fe | 509 | |
llumpu | 0:c0dc2df7c9fe | 510 | } |
llumpu | 0:c0dc2df7c9fe | 511 | } else if (DensityCode == THIRTYTWO_MBIT) { // 32Mbits |
llumpu | 0:c0dc2df7c9fe | 512 | |
llumpu | 0:c0dc2df7c9fe | 513 | if (PageIsBinary) { |
llumpu | 0:c0dc2df7c9fe | 514 | |
llumpu | 0:c0dc2df7c9fe | 515 | _flash_size = 4194304; |
llumpu | 0:c0dc2df7c9fe | 516 | _flash_buffer_size = 512; |
llumpu | 0:c0dc2df7c9fe | 517 | _page_size = 512; |
llumpu | 0:c0dc2df7c9fe | 518 | |
llumpu | 0:c0dc2df7c9fe | 519 | } else { |
llumpu | 0:c0dc2df7c9fe | 520 | |
llumpu | 0:c0dc2df7c9fe | 521 | _flash_size = 4325376; |
llumpu | 0:c0dc2df7c9fe | 522 | _flash_buffer_size = 512; |
llumpu | 0:c0dc2df7c9fe | 523 | _page_size = 528; |
llumpu | 0:c0dc2df7c9fe | 524 | |
llumpu | 0:c0dc2df7c9fe | 525 | } |
llumpu | 0:c0dc2df7c9fe | 526 | } else if (DensityCode == SIXTYFOUR_MBIT) { // 64Mbits |
llumpu | 0:c0dc2df7c9fe | 527 | |
llumpu | 0:c0dc2df7c9fe | 528 | if (PageIsBinary) { |
llumpu | 0:c0dc2df7c9fe | 529 | |
llumpu | 0:c0dc2df7c9fe | 530 | _flash_size = 8388608; |
llumpu | 0:c0dc2df7c9fe | 531 | _flash_buffer_size = 1024; |
llumpu | 0:c0dc2df7c9fe | 532 | _page_size = 1024; |
llumpu | 0:c0dc2df7c9fe | 533 | |
llumpu | 0:c0dc2df7c9fe | 534 | } else { |
llumpu | 0:c0dc2df7c9fe | 535 | |
llumpu | 0:c0dc2df7c9fe | 536 | _flash_size = 8650752; |
llumpu | 0:c0dc2df7c9fe | 537 | _flash_buffer_size = 1024; |
llumpu | 0:c0dc2df7c9fe | 538 | _page_size = 1056; |
llumpu | 0:c0dc2df7c9fe | 539 | |
llumpu | 0:c0dc2df7c9fe | 540 | } |
llumpu | 0:c0dc2df7c9fe | 541 | } else { |
llumpu | 0:c0dc2df7c9fe | 542 | |
llumpu | 0:c0dc2df7c9fe | 543 | _flash_size = -1; |
llumpu | 0:c0dc2df7c9fe | 544 | _flash_buffer_size = -1; |
llumpu | 0:c0dc2df7c9fe | 545 | _page_size = -1; |
llumpu | 0:c0dc2df7c9fe | 546 | |
llumpu | 0:c0dc2df7c9fe | 547 | } |
llumpu | 0:c0dc2df7c9fe | 548 | } |
llumpu | 0:c0dc2df7c9fe | 549 | |
llumpu | 0:c0dc2df7c9fe | 550 | |
llumpu | 0:c0dc2df7c9fe | 551 | |
llumpu | 0:c0dc2df7c9fe | 552 | void USBMSD_AT45::_busy() |
llumpu | 0:c0dc2df7c9fe | 553 | { |
llumpu | 0:c0dc2df7c9fe | 554 | //_pc.printf("BUSY? \n\r"); |
llumpu | 0:c0dc2df7c9fe | 555 | |
llumpu | 0:c0dc2df7c9fe | 556 | volatile int IsBusy = 1; |
llumpu | 0:c0dc2df7c9fe | 557 | while (IsBusy) { |
llumpu | 0:c0dc2df7c9fe | 558 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 559 | |
llumpu | 0:c0dc2df7c9fe | 560 | _spi.write(0xd7); // Read status register of storage chip |
llumpu | 0:c0dc2df7c9fe | 561 | |
llumpu | 0:c0dc2df7c9fe | 562 | int IsReady = ((_spi.write(0x00)) & IS_FLASH_READY); // If bit 7 is set we can proceed |
llumpu | 0:c0dc2df7c9fe | 563 | |
llumpu | 0:c0dc2df7c9fe | 564 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 565 | |
llumpu | 0:c0dc2df7c9fe | 566 | if (IsReady) { |
llumpu | 0:c0dc2df7c9fe | 567 | IsBusy = 0; |
llumpu | 0:c0dc2df7c9fe | 568 | |
llumpu | 0:c0dc2df7c9fe | 569 | |
llumpu | 0:c0dc2df7c9fe | 570 | |
llumpu | 0:c0dc2df7c9fe | 571 | } |
llumpu | 0:c0dc2df7c9fe | 572 | } |
llumpu | 0:c0dc2df7c9fe | 573 | } |
llumpu | 0:c0dc2df7c9fe | 574 | |
llumpu | 0:c0dc2df7c9fe | 575 | |
llumpu | 0:c0dc2df7c9fe | 576 | |
llumpu | 0:c0dc2df7c9fe | 577 | // Write and SRAM buffer to main memory |
llumpu | 0:c0dc2df7c9fe | 578 | void USBMSD_AT45::_flashwrite (int buffer, int address) |
llumpu | 0:c0dc2df7c9fe | 579 | { |
llumpu | 0:c0dc2df7c9fe | 580 | |
llumpu | 0:c0dc2df7c9fe | 581 | int cmd = 0; |
llumpu | 0:c0dc2df7c9fe | 582 | int paddr = _getpaddr(address); // Calculate address |
llumpu | 0:c0dc2df7c9fe | 583 | |
llumpu | 0:c0dc2df7c9fe | 584 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 585 | |
llumpu | 0:c0dc2df7c9fe | 586 | if (buffer == 1) { |
llumpu | 0:c0dc2df7c9fe | 587 | cmd = 0x83; // Write SRAM 1 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 588 | } else { |
llumpu | 0:c0dc2df7c9fe | 589 | cmd = 0x86; // Write SRAM 2 buffer to flash |
llumpu | 0:c0dc2df7c9fe | 590 | } |
llumpu | 0:c0dc2df7c9fe | 591 | |
llumpu | 0:c0dc2df7c9fe | 592 | _spi.write (cmd); |
llumpu | 0:c0dc2df7c9fe | 593 | _sendaddr (paddr); |
llumpu | 0:c0dc2df7c9fe | 594 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 595 | |
llumpu | 0:c0dc2df7c9fe | 596 | } |
llumpu | 0:c0dc2df7c9fe | 597 | |
llumpu | 0:c0dc2df7c9fe | 598 | // Read from Flash memory into SRAM buffer |
llumpu | 0:c0dc2df7c9fe | 599 | |
llumpu | 0:c0dc2df7c9fe | 600 | void USBMSD_AT45::_flashread (int buffer, int address) |
llumpu | 0:c0dc2df7c9fe | 601 | { |
llumpu | 0:c0dc2df7c9fe | 602 | |
llumpu | 0:c0dc2df7c9fe | 603 | int cmd = 0; |
llumpu | 0:c0dc2df7c9fe | 604 | int paddr = _getpaddr(address); // Calculate address |
llumpu | 0:c0dc2df7c9fe | 605 | |
llumpu | 0:c0dc2df7c9fe | 606 | _ncs = 0; // Chip select |
llumpu | 0:c0dc2df7c9fe | 607 | |
llumpu | 0:c0dc2df7c9fe | 608 | if (buffer == 1) { |
llumpu | 0:c0dc2df7c9fe | 609 | cmd = 0x53; // Read from flash to SRAM 1 buffer |
llumpu | 0:c0dc2df7c9fe | 610 | } else { |
llumpu | 0:c0dc2df7c9fe | 611 | cmd = 0x55; // Read from flash to SRAM 2 buffer |
llumpu | 0:c0dc2df7c9fe | 612 | } |
llumpu | 0:c0dc2df7c9fe | 613 | |
llumpu | 0:c0dc2df7c9fe | 614 | _spi.write (cmd); |
llumpu | 0:c0dc2df7c9fe | 615 | _sendaddr (paddr); |
llumpu | 0:c0dc2df7c9fe | 616 | _ncs = 1; // Chip deselect |
llumpu | 0:c0dc2df7c9fe | 617 | |
llumpu | 0:c0dc2df7c9fe | 618 | } |
llumpu | 0:c0dc2df7c9fe | 619 | |
llumpu | 0:c0dc2df7c9fe | 620 | |
llumpu | 0:c0dc2df7c9fe | 621 | |
llumpu | 0:c0dc2df7c9fe | 622 | // Work out the page address |
llumpu | 0:c0dc2df7c9fe | 623 | // If we have a 2^N page size, it is just the top N bits |
llumpu | 0:c0dc2df7c9fe | 624 | // If we have non-2^N, we use the shifted address |
llumpu | 0:c0dc2df7c9fe | 625 | |
llumpu | 0:c0dc2df7c9fe | 626 | int USBMSD_AT45::_getpaddr(int address) |
llumpu | 0:c0dc2df7c9fe | 627 | { |
llumpu | 0:c0dc2df7c9fe | 628 | |
llumpu | 0:c0dc2df7c9fe | 629 | int paddr; |
llumpu | 0:c0dc2df7c9fe | 630 | |
llumpu | 0:c0dc2df7c9fe | 631 | if (_page_size == 256) { |
llumpu | 0:c0dc2df7c9fe | 632 | paddr = address & 0xffffff00; |
llumpu | 0:c0dc2df7c9fe | 633 | } else if (_page_size == 264) { |
llumpu | 0:c0dc2df7c9fe | 634 | paddr = (address << 1) & 0xfffffe00; |
llumpu | 0:c0dc2df7c9fe | 635 | } else if (_page_size == 512) { |
llumpu | 0:c0dc2df7c9fe | 636 | paddr = address & 0xfffffe00; |
llumpu | 0:c0dc2df7c9fe | 637 | } else if (_page_size == 528 ) { |
llumpu | 0:c0dc2df7c9fe | 638 | paddr = (address << 1) & 0xfffffc00; |
llumpu | 0:c0dc2df7c9fe | 639 | } else if (_page_size == 1024) { |
llumpu | 0:c0dc2df7c9fe | 640 | paddr = address & 0xfffffc00; |
llumpu | 0:c0dc2df7c9fe | 641 | } else if (_page_size == 1056 ) { |
llumpu | 0:c0dc2df7c9fe | 642 | paddr = (address << 1) & 0xfffff800; |
llumpu | 0:c0dc2df7c9fe | 643 | } else { |
llumpu | 0:c0dc2df7c9fe | 644 | paddr = -1; |
llumpu | 0:c0dc2df7c9fe | 645 | } |
llumpu | 0:c0dc2df7c9fe | 646 | |
llumpu | 0:c0dc2df7c9fe | 647 | return (paddr); |
llumpu | 0:c0dc2df7c9fe | 648 | } |
llumpu | 0:c0dc2df7c9fe | 649 | |
llumpu | 0:c0dc2df7c9fe | 650 | |
llumpu | 0:c0dc2df7c9fe | 651 | |
llumpu | 0:c0dc2df7c9fe | 652 | // Sends the three least significant bytes of the supplied address |
llumpu | 0:c0dc2df7c9fe | 653 | |
llumpu | 0:c0dc2df7c9fe | 654 | void USBMSD_AT45::_sendaddr (int address) |
llumpu | 0:c0dc2df7c9fe | 655 | { |
llumpu | 0:c0dc2df7c9fe | 656 | _spi.write(address >> 16); |
llumpu | 0:c0dc2df7c9fe | 657 | _spi.write(address >> 8); |
llumpu | 0:c0dc2df7c9fe | 658 | _spi.write(address); |
llumpu | 0:c0dc2df7c9fe | 659 | } |