Sonder Design Team / Memory25L16_fast

Dependents:   BlackBoard_Firmware_Fast_read_not_test

Fork of Memory by Sonder Design Team

Memory.cpp

Committer:
ThomasSonderDesign
Date:
2017-02-09
Revision:
4:bb4fd1147054
Parent:
3:339efdc5134f
Child:
5:2fa79108a29b

File content as of revision 4:bb4fd1147054:

#include "mbed.h"
#include "Memory.h"


Memory::Memory(PinName chipSelect) : _cs_mem(chipSelect)
{
    _cs_mem=1;
}
/**
 * Reads 'length' elements into a char array starting at the 24bit Address.
 *If length is greater than BufferSize (3840 bytes) the function will terminate
 *and return the start address.
 */
int Memory::readData(SPI my_spi, char value [], int Address, int length)
{
    if(length>bufferSize) {
        printf("\nLength %i exceeds Max Length\n",length);
        return Address;
    }
    _cs_mem = 1;             //Ensure cs is deselected
    wait_us(10);
    _cs_mem = 0;                     //memory is selected
    my_spi.write(0x03);         //Send read command
    my_spi.write(Address>>16);  //Send high address byte
    my_spi.write(Address>>8);   //Send mid address byte
    my_spi.write(Address);      //Send low address byte


    for(int i =0; i <length; i++) {
        value[i]= my_spi.write(dummy);//Send dummy byte to read out value ate Address
        Address++;
    }
    _cs_mem = 1;
    return Address;     //Return the address of the next unread byte
}


/**
 * Sector  Erase, erases everything in the 4KB sector that includes Address
 */
void Memory::sectorErase(SPI my_spi, long Address)
{
    _cs_mem = 1;
    _cs_mem=0;
    my_spi.write(0x06);     //Send Write enable command
    _cs_mem= 1;
    wait_us(5);
    _cs_mem=0;
    my_spi.write(0x20);     //Send sector erase comand
    my_spi.write(Address>>16);  //Send high address byte
    my_spi.write(Address>>8);   //Send mid address byte
    my_spi.write(Address);      //Send low address byte
    _cs_mem=1;
    wait_us(5);

    //Pol the status register untill the Write In Progress bit is no longer set
    _cs_mem=0;
    my_spi.write(05);
    int byte1 = my_spi.write(dummy);
    while(byte1>0) {
        byte1 = my_spi.write(dummy);
    }
    _cs_mem=1;
}


/**
 * Block  Erase, erases everything in a 4KB block that includes Address
 */
void Memory::blockErase(SPI my_spi, int Address)
{
    _cs_mem = 1;
    _cs_mem=0;
    my_spi.write(0x06);     //Send Write enable command
    _cs_mem= 1;
    wait_us(5);
    _cs_mem=0;
    my_spi.write(0xD8);     //Send sector erase comand
    my_spi.write((Address>>16)&0xff);  //Send high address byte
    my_spi.write((Address>>8)&0xff);   //Send mid address byte
    my_spi.write((Address)&0xff);      //Send low address byte
    _cs_mem=1;
    wait_us(5);

    //Pol the status register untill the Write In Progress bit is no longer set
    _cs_mem=0;
    my_spi.write(05);
    int byte1 = my_spi.write(dummy);
    while(byte1>0) {
        byte1 = my_spi.write(dummy);
    }
    _cs_mem=1;
}

/**
 * Writes a char array containg 'length' elements to memory sarting at address.
 *If length is greater than BufferSize (3840 bytes) the function will terminate
 *and return the start address.
 */
int Memory::writeData(SPI my_spi, char buffer[], int address, int length)
{
    if(length>bufferSize) {
        printf("\nLength %i exceeds Max Length\n",length);
        return address;
    }
    
    //Enable the memory for wiring. This segment is only required if not writing to the start of a page.
    if(address%256!=0){
        _cs_mem=1;
        _cs_mem=0;                      //Selet memory
        my_spi.write(06);               //Set Write Enable flag in the status reg
        _cs_mem=1;                      //Deslect memory
        wait_us(10);
        _cs_mem=0;                      //Selet memory
        my_spi.write(0x02);             //Send write comand
        my_spi.write(address>>16);      //Send high address byte
        my_spi.write(address>>8);       //Send middle adress byte
        my_spi.write(address);          //Send low address
    }    
    
    for(int i =0; i<length; i++) {
        //Handle start and end of pages. aAt the page boundry the memory must be deselected and and re-enabled for writng to the next page.
        if(address%256==0) {                
                _cs_mem=1;
                wait_us(10);
                //wait for the WIP bit to go low
                _cs_mem=0;                           //Selet memory
                my_spi.write(0x05);             //Send read status register command
                int byte1 = my_spi.write(dummy);//Send dummy byte to read status reg
                while ((byte1&1)>0) {
                    wait_us(10);
                    my_spi.write(0x05);         //Send read status register command
                    byte1 = my_spi.write(dummy);//Send dummy byte to read status reg
                }
                _cs_mem=1;
                _cs_mem=0;                      //Selet memory
                my_spi.write(06);               //Set Write Enable flag in the status reg
                _cs_mem=1;                      //Deslect memory
                wait_us(10);
                _cs_mem=0;                      //Selet memory
                my_spi.write(0x02);             //Send write comand
                my_spi.write(address>>16);      //Send high address byte
                my_spi.write(address>>8);       //Send middle adress byte
                my_spi.write(address);          //Send low address
        }
        
        my_spi.write(buffer[i]);            //Write the value of the buffer to memory
        wait_us(5);
        address=address+1;                  //Increment address
    }
    _cs_mem=1;
    return address;
}

/**
 * Arrange the data to the NEW address for icon refreshing
 */
int Memory::arrangeData(SPI my_spi, int Address, int addressNew, int length)
{
    char value[length];
    _cs_mem = 1;             //Ensure cs is deselected
    wait_us(10);
    _cs_mem = 0;                     //memory is selected
    my_spi.write(0x03);         //Send read command
    my_spi.write(Address>>16);  //Send high address byte
    my_spi.write(Address>>8);   //Send mid address byte
    my_spi.write(Address);      //Send low address byte


    for(int i =0; i <length; i++) {
        value[i]= my_spi.write(dummy);//Send dummy byte to read out value ate Address
        Address++;
    }
    _cs_mem = 1;
    
    wait_ms(50);//wait for command transfer
    
    for(int i =0; i<length; i++) {
        if(addressNew%256==0) {                //Handle start and end of pages
            _cs_mem=1;
            wait_us(10);
            //wait for the WIP bit to go low
            _cs_mem=0;                           //Selet memory
            my_spi.write(0x05);             //Send read status register command
            int byte1 = my_spi.write(dummy);//Send dummy byte to read status reg
            while ((byte1&1)>0) {
                wait_us(10);
                my_spi.write(0x05);         //Send read status register command
                byte1 = my_spi.write(dummy);//Send dummy byte to read status reg
            }
            _cs_mem=1;

            _cs_mem=0;                           //Selet memory
            my_spi.write(06);               //Set Write Enable flag in the status reg
            _cs_mem=1;
            wait_us(10);

            _cs_mem=0;                           //Selet memory
            my_spi.write(0x02);               //Send read comand
            my_spi.write(addressNew>>16);      //Send high address byte
            my_spi.write(addressNew>>8);       //Send middle adress byte
            my_spi.write(addressNew);          //Send low address

        }
        my_spi.write(value[i]);            //Write the calue of the buffer to memory
        wait_us(5);
        addressNew=addressNew+1;                  //Increment address
    }
    _cs_mem=1;
    wait_ms(10); //Need to wait register response, otherwise will cause the output full of dummies
    return addressNew;
}