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.h@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.h" |
llumpu | 0:c0dc2df7c9fe | 25 | |
llumpu | 0:c0dc2df7c9fe | 26 | #ifndef USBMSD_AT45_H |
llumpu | 0:c0dc2df7c9fe | 27 | #define USBMSD_AT45_H |
llumpu | 0:c0dc2df7c9fe | 28 | |
llumpu | 0:c0dc2df7c9fe | 29 | |
llumpu | 0:c0dc2df7c9fe | 30 | /** USBMSD device (USB flashdisk) with Atmel AT45DBxx serial flash |
llumpu | 0:c0dc2df7c9fe | 31 | * |
llumpu | 0:c0dc2df7c9fe | 32 | * Example: |
llumpu | 0:c0dc2df7c9fe | 33 | * @code |
llumpu | 0:c0dc2df7c9fe | 34 | * #include "mbed.h" |
llumpu | 0:c0dc2df7c9fe | 35 | * #include "USBMSD_AT45.h" |
llumpu | 0:c0dc2df7c9fe | 36 | * |
llumpu | 0:c0dc2df7c9fe | 37 | * USBMSD_AT45 Flash(p5, p6, p7, p8, 512); // Mosi, Miso, Sclk, CS, Size of block being transported over USB |
llumpu | 0:c0dc2df7c9fe | 38 | * // each time. Can be 512, 1024, 2048, 4096. Best is to select same |
llumpu | 0:c0dc2df7c9fe | 39 | * // size as AT45DBxx SRAM buffer size. If page size of flash is not |
llumpu | 0:c0dc2df7c9fe | 40 | * // binary 2^N (256, 512, 1024 bytes) but is 264, 528 or 1056 bytes |
llumpu | 0:c0dc2df7c9fe | 41 | * // before each write we read block being written to SRAM then rewrite |
llumpu | 0:c0dc2df7c9fe | 42 | * // part of them with data from host and write whole SRAM buffer back |
llumpu | 0:c0dc2df7c9fe | 43 | * // to flash. This avoids to data being rewritten in other blocks |
llumpu | 0:c0dc2df7c9fe | 44 | * // we actually do not write to. |
llumpu | 0:c0dc2df7c9fe | 45 | * int main() { |
llumpu | 0:c0dc2df7c9fe | 46 | * |
llumpu | 0:c0dc2df7c9fe | 47 | * while(1) { |
llumpu | 0:c0dc2df7c9fe | 48 | * |
llumpu | 0:c0dc2df7c9fe | 49 | * // Do something else here |
llumpu | 0:c0dc2df7c9fe | 50 | * |
llumpu | 0:c0dc2df7c9fe | 51 | * } |
llumpu | 0:c0dc2df7c9fe | 52 | * } |
llumpu | 0:c0dc2df7c9fe | 53 | * @endcode |
llumpu | 0:c0dc2df7c9fe | 54 | */ |
llumpu | 0:c0dc2df7c9fe | 55 | |
llumpu | 0:c0dc2df7c9fe | 56 | class USBMSD_AT45 : public USBMSD |
llumpu | 0:c0dc2df7c9fe | 57 | { |
llumpu | 0:c0dc2df7c9fe | 58 | public: |
llumpu | 0:c0dc2df7c9fe | 59 | |
llumpu | 0:c0dc2df7c9fe | 60 | /** |
llumpu | 0:c0dc2df7c9fe | 61 | * Constructor |
llumpu | 0:c0dc2df7c9fe | 62 | * |
llumpu | 0:c0dc2df7c9fe | 63 | * Create an instance of the USBMSD_AT45 connected to specfied SPI pins, with the specified CHIP SELECT pin |
llumpu | 0:c0dc2df7c9fe | 64 | * |
llumpu | 0:c0dc2df7c9fe | 65 | * @param mosi The SPI mosi Pin (p5 or p11) |
llumpu | 0:c0dc2df7c9fe | 66 | * @param miso The SPI miso Pin (p6 or p12) |
llumpu | 0:c0dc2df7c9fe | 67 | * @param sclk The SPI sclk Pin (p7 or p13) |
llumpu | 0:c0dc2df7c9fe | 68 | * @param ncs The SPI chip select Pin (any digital out pin) |
llumpu | 0:c0dc2df7c9fe | 69 | * @param transport_block_size The size of block being transported over USB |
llumpu | 0:c0dc2df7c9fe | 70 | */ |
llumpu | 0:c0dc2df7c9fe | 71 | |
llumpu | 0:c0dc2df7c9fe | 72 | USBMSD_AT45(PinName mosi, PinName miso, PinName sclk, PinName ncs, int transport_block_size); |
llumpu | 0:c0dc2df7c9fe | 73 | |
llumpu | 0:c0dc2df7c9fe | 74 | /** disk_read() |
llumpu | 0:c0dc2df7c9fe | 75 | * |
llumpu | 0:c0dc2df7c9fe | 76 | * Reads block of data from storage chip. Size of block is set in constructor |
llumpu | 0:c0dc2df7c9fe | 77 | * |
llumpu | 0:c0dc2df7c9fe | 78 | * @param data Pointer to buffer where data will be read to |
llumpu | 0:c0dc2df7c9fe | 79 | * @param block Number of requested block |
llumpu | 0:c0dc2df7c9fe | 80 | */ |
llumpu | 0:c0dc2df7c9fe | 81 | |
llumpu | 0:c0dc2df7c9fe | 82 | virtual int disk_read(char * data, int block); |
llumpu | 0:c0dc2df7c9fe | 83 | |
llumpu | 0:c0dc2df7c9fe | 84 | /** disk_write() |
llumpu | 0:c0dc2df7c9fe | 85 | * |
llumpu | 0:c0dc2df7c9fe | 86 | * Writes block of data to storage chip. Size of block is set in constructor |
llumpu | 0:c0dc2df7c9fe | 87 | * |
llumpu | 0:c0dc2df7c9fe | 88 | * @param data Pointer to buffer from which contains data to be written to storage chip |
llumpu | 0:c0dc2df7c9fe | 89 | * @param block Number of block to be written to |
llumpu | 0:c0dc2df7c9fe | 90 | */ |
llumpu | 0:c0dc2df7c9fe | 91 | |
llumpu | 0:c0dc2df7c9fe | 92 | virtual int disk_write(const char * data, int block); |
llumpu | 0:c0dc2df7c9fe | 93 | |
llumpu | 0:c0dc2df7c9fe | 94 | /** disk_size() |
llumpu | 0:c0dc2df7c9fe | 95 | * |
llumpu | 0:c0dc2df7c9fe | 96 | * @param returns Size of storage chip in bytes |
llumpu | 0:c0dc2df7c9fe | 97 | */ |
llumpu | 0:c0dc2df7c9fe | 98 | |
llumpu | 0:c0dc2df7c9fe | 99 | virtual int disk_size(); |
llumpu | 0:c0dc2df7c9fe | 100 | |
llumpu | 0:c0dc2df7c9fe | 101 | /** disk_sectors() |
llumpu | 0:c0dc2df7c9fe | 102 | * |
llumpu | 0:c0dc2df7c9fe | 103 | * @param returns Count of sectors of storage chip |
llumpu | 0:c0dc2df7c9fe | 104 | */ |
llumpu | 0:c0dc2df7c9fe | 105 | |
llumpu | 0:c0dc2df7c9fe | 106 | virtual int disk_sectors(); |
llumpu | 0:c0dc2df7c9fe | 107 | |
llumpu | 0:c0dc2df7c9fe | 108 | /** disk_status() |
llumpu | 0:c0dc2df7c9fe | 109 | * |
llumpu | 0:c0dc2df7c9fe | 110 | * @param returns Status of storage chip - 0x00 ready, 0x01 not initialized (disk_initialize is then called) |
llumpu | 0:c0dc2df7c9fe | 111 | */ |
llumpu | 0:c0dc2df7c9fe | 112 | |
llumpu | 0:c0dc2df7c9fe | 113 | virtual int disk_status(); |
llumpu | 0:c0dc2df7c9fe | 114 | |
llumpu | 0:c0dc2df7c9fe | 115 | /** disk_initialize() |
llumpu | 0:c0dc2df7c9fe | 116 | * |
llumpu | 0:c0dc2df7c9fe | 117 | * This method is called when disk_status returns 0x01 (not initialized) |
llumpu | 0:c0dc2df7c9fe | 118 | */ |
llumpu | 0:c0dc2df7c9fe | 119 | |
llumpu | 0:c0dc2df7c9fe | 120 | virtual int disk_initialize(); |
llumpu | 0:c0dc2df7c9fe | 121 | |
llumpu | 0:c0dc2df7c9fe | 122 | |
llumpu | 0:c0dc2df7c9fe | 123 | protected: |
llumpu | 0:c0dc2df7c9fe | 124 | |
llumpu | 0:c0dc2df7c9fe | 125 | // SPI bus and Chip select |
llumpu | 0:c0dc2df7c9fe | 126 | |
llumpu | 0:c0dc2df7c9fe | 127 | SPI _spi; // SPI bus |
llumpu | 0:c0dc2df7c9fe | 128 | DigitalOut _ncs; // Chip Select pin |
llumpu | 0:c0dc2df7c9fe | 129 | |
llumpu | 0:c0dc2df7c9fe | 130 | // Protected variables storing flash chip parameters |
llumpu | 0:c0dc2df7c9fe | 131 | |
llumpu | 0:c0dc2df7c9fe | 132 | int _flash_size; // Total size of storage chip in bytes |
llumpu | 0:c0dc2df7c9fe | 133 | int _flash_buffer_size; // !!! Used size of memory page (and SRAM buffer) in bytes |
llumpu | 0:c0dc2df7c9fe | 134 | |
llumpu | 0:c0dc2df7c9fe | 135 | int _page_size; // !!! Real size of memory page (and SRAM buffer) in bytes |
llumpu | 0:c0dc2df7c9fe | 136 | int _transport_block_size; // Size of block transported over USB in bytes |
llumpu | 0:c0dc2df7c9fe | 137 | int _init_status; // Status of storage chip - 0x00 ready, 0x01 not initialized |
llumpu | 0:c0dc2df7c9fe | 138 | |
llumpu | 0:c0dc2df7c9fe | 139 | // Helper routines |
llumpu | 0:c0dc2df7c9fe | 140 | |
llumpu | 0:c0dc2df7c9fe | 141 | void _initialize(); // Determine parameters of connected storage chip |
llumpu | 0:c0dc2df7c9fe | 142 | void _busy (void); // Check if storage chip is not busy |
llumpu | 0:c0dc2df7c9fe | 143 | |
llumpu | 0:c0dc2df7c9fe | 144 | // Transferring SRAM buffers to/from FLASH |
llumpu | 0:c0dc2df7c9fe | 145 | |
llumpu | 0:c0dc2df7c9fe | 146 | void _flashwrite (int buffer, int paddr); |
llumpu | 0:c0dc2df7c9fe | 147 | void _flashread (int buffer, int paddr); |
llumpu | 0:c0dc2df7c9fe | 148 | |
llumpu | 0:c0dc2df7c9fe | 149 | // Calculate page/subpage addresses |
llumpu | 0:c0dc2df7c9fe | 150 | |
llumpu | 0:c0dc2df7c9fe | 151 | int _getpaddr (int address); |
llumpu | 0:c0dc2df7c9fe | 152 | |
llumpu | 0:c0dc2df7c9fe | 153 | // Send 3 byte address |
llumpu | 0:c0dc2df7c9fe | 154 | |
llumpu | 0:c0dc2df7c9fe | 155 | void _sendaddr (int address); |
llumpu | 0:c0dc2df7c9fe | 156 | |
llumpu | 0:c0dc2df7c9fe | 157 | }; |
llumpu | 0:c0dc2df7c9fe | 158 | #endif |