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

Committer:
llumpu
Date:
Sat Oct 27 14:18:07 2012 +0000
Revision:
0:c0dc2df7c9fe
Initial release

Who changed what in which revision?

UserRevisionLine numberNew 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 }