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

Committer:
llumpu
Date:
2012-10-27
Revision:
0:c0dc2df7c9fe

File content as of revision 0:c0dc2df7c9fe:

/* Copyright (c) <2012> <llumpu>, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/* 
 * Inspired by Steen Joergensen (stjo2809) and Chris Styles AT45 libraries
 */

#include "mbed.h"
#include "USBMSD.h"

#ifndef USBMSD_AT45_H
#define USBMSD_AT45_H


/** USBMSD device (USB flashdisk) with Atmel AT45DBxx serial flash
 *
 * Example:
 * @code
 * #include "mbed.h"
 * #include "USBMSD_AT45.h"
 *
 * USBMSD_AT45 Flash(p5, p6, p7, p8, 512);  // Mosi, Miso, Sclk, CS, Size of block being transported over USB
 *                                 // each time. Can be 512, 1024, 2048, 4096. Best is to select same
 *                                 // size as AT45DBxx SRAM buffer size. If page size of flash is not
 *                                 // binary 2^N (256, 512, 1024 bytes) but is 264, 528 or 1056 bytes
 *                                 // before each write we read block being written to SRAM then rewrite
 *                                 // part of them with data from host and write whole SRAM buffer back
 *                                 // to flash. This avoids to data being rewritten in other blocks
 *                                 // we actually do not write to.
 * int main() {
 *
 *  while(1) {
 *
 *  // Do something else here
 *
 *   }
 *  }
 * @endcode
 */

class USBMSD_AT45 : public USBMSD
{
public:

    /**
    * Constructor
    *
    * Create an instance of the USBMSD_AT45 connected to specfied SPI pins, with the specified CHIP SELECT pin
    *
    * @param mosi The SPI mosi Pin (p5 or p11)
    * @param miso The SPI miso Pin (p6 or p12)
    * @param sclk The SPI sclk Pin (p7 or p13)
    * @param ncs The SPI chip select Pin (any digital out pin)
    * @param transport_block_size The size of block being transported over USB
    */

    USBMSD_AT45(PinName mosi, PinName miso, PinName sclk, PinName ncs, int transport_block_size);

    /** disk_read()
    *
    * Reads block of data from storage chip. Size of block is set in constructor
    *
    * @param data Pointer to buffer where data will be read to
    * @param block Number of requested block
    */

    virtual int disk_read(char * data, int block);

    /** disk_write()
    *
    * Writes block of data to storage chip. Size of block is set in constructor
    *
    * @param data Pointer to buffer from which contains data to be written to storage chip
    * @param block Number of block to be written to
    */

    virtual int disk_write(const char * data, int block);

    /** disk_size()
    *
    * @param returns Size of storage chip in bytes
    */

    virtual int disk_size();

    /** disk_sectors()
    *
    * @param returns Count of sectors of storage chip
    */

    virtual int disk_sectors();

    /** disk_status()
    *
    * @param returns Status of storage chip - 0x00 ready, 0x01 not initialized (disk_initialize is then called)
    */

    virtual int disk_status();

    /** disk_initialize()
    *
    * This method is called when disk_status returns 0x01 (not initialized)
    */

    virtual int disk_initialize();


protected:

// SPI bus and Chip select

    SPI _spi; // SPI bus
    DigitalOut _ncs; // Chip Select pin

// Protected variables storing flash chip parameters

    int _flash_size; // Total size of storage chip in bytes
    int _flash_buffer_size; // !!! Used size of memory page (and SRAM buffer) in bytes

    int _page_size; // !!! Real size of memory page (and SRAM buffer) in bytes
    int _transport_block_size; // Size of block transported over USB in bytes
    int _init_status; // Status of storage chip - 0x00 ready, 0x01 not initialized

// Helper routines

    void _initialize(); // Determine parameters of connected storage chip
    void _busy (void);  // Check if storage chip is not busy

// Transferring SRAM buffers to/from FLASH

    void _flashwrite (int buffer, int paddr);
    void _flashread (int buffer, int paddr);

// Calculate page/subpage addresses

    int _getpaddr (int address);

// Send 3 byte address

    void _sendaddr (int address);

};
#endif