IP12B512 class for comunicating with the IPSiLog IP12B512 SPI RAM

IP12B512.cpp

Committer:
adamumpsimus
Date:
2016-11-04
Revision:
0:35077a3db00c
Child:
1:bcbe2cf57840

File content as of revision 0:35077a3db00c:

/** IP12B512 class.
 *  Main class for comunicating with the IP12B512 SPI RAM.
 */
#include "IP12B512.h"

/** Constructor: setup the SPI and write to "Status Register" that we are going to use it in "Virtual Chip Mode"
 * 
 * Notes:
 * - the MOSI and MISO pins must have 5k6 pulldown resistors
 * - the SCLK pin has a 5k6 pulldown resistor
 * - the HOLD pin is connected to VCC
 * - the CS pin has a 5k6 pullup resistor
 * 
 * @param pin_mosi the hardware MOSI pin on the board
 * @param pin_miso the hardware MISO pin on the board
 * @param pin_sclk the hardware SCLK pin on the board
 * @param pin_cs the software CS pin on the board (can be any output pin)
 *
 * Example:
 * @code
 *
 * #include "mbed.h"
 * #include "IP12B512.cpp"
 *
 * IP12B512 sram(SPI_MOSI, SPI_MISO, SPI_SCK, D6); // MOSI, MISO, SCK, CS
 *
 * int main() {
 *     // GET SRAM SIZE
 *     uint32_t ram_size = sram.GetRamSize();
 *     printf("ram_size %d\n", ram_size);
 *     
 *     // CLEAR ALL SRAM
 *     sram.ClearAll();
 *     
 *     // WRITE A SINGLE BYTE TO SRAM
 *     uint16_t ram_addr = 0;
 *     uint8_t sent_data = 0x6F;
 *     sram.Write(ram_addr, sent_data);
 *     printf("written at address %d data 0x%02X\n", ram_addr, sent_data);
 *     
 *     // READ A SINGLE BYTE FROM RAM
 *     uint8_t rec_data = sram.Read(address);
 *     printf("read at address %d data 0x%02X\n", address, rec_data);
 * }
 * @endcode
 */
IP12B512::IP12B512(
    PinName pin_mosi, 
    PinName pin_miso, 
    PinName pin_sclk, 
    PinName pin_cs
) : 
    _device(pin_mosi, pin_miso, pin_sclk),
    _cs(pin_cs, 1) // even with pullup resistor, this pin goes down at startup, so a HIGH value is preferred
{
    // Configure Interface
    _device.format(8, 0);                   // NOTE: different format (not 8.3)
    _device.frequency(20e6);                // max speed of IP12B512 SRAM is 20MHz

    // Idle SPI RAM
    _cs = 0;
    _cs = 1;

    // Configure SPI RAM
    _cs = 0;
    _device.write(IP12B512_WRSR);           // Write to Status Register
    _device.write(0x41);                    // Set to Virtual Chip Mode (0x40 - with HOLD, 0x41 - no HOLD)
    _cs = 1;
}

/// Write SRAM in byte mode (sends the most data to SRAM prior to write)
void IP12B512::Write(uint16_t addr, uint8_t data)
{
    _cs = 0;
    _device.write(IP12B512_WRITE);          // OpCode
    _device.write(addr >> 8);               // Addr
    _device.write(addr);                    // Addr
    _device.write(data);                    // Pump out data to RAM
    _cs = 1;
}

/// Write SRAM in stream mode (sends the least data to SRAM prior to write)
void IP12B512::StreamWrite(uint16_t addr, uint8_t *data, uint32_t size)
{
    uint8_t * p = data;
    uint32_t i;

    _cs = 0;
    _device.write(IP12B512_WRITE);          // OpCode
    _device.write(addr >> 8);               // Addr
    _device.write(addr);                    // Addr

    for (i = 0; i < size; i++) {
        _device.write(*p++);                // Write to SPI ram
    }
    _cs = 1;
}

/// Read SRAM in byte mode (sends the most data to SRAM prior to read)
uint8_t IP12B512::Read(uint16_t addr)
{
    uint8_t data;

    _cs = 0;
    _device.write(IP12B512_READ);           // OpCode
    _device.write(addr >> 8);               // Addr
    _device.write(addr);                    // Addr
    data = _device.write(0x00);             // Clock in data from RAM (doesn't matter the value)
    _cs = 1;

    return data;
}

/// Read SRAM in stream mode (sends the least data to SRAM prior to read)
void IP12B512::StreamRead(uint16_t addr, uint8_t *data, uint32_t size)
{
    uint8_t * p = data;
    uint32_t i;

    _cs = 0;
    _device.write(IP12B512_READ);           // OpCode
    _device.write(addr >> 8);               // Addr
    _device.write(addr);                    // Addr

    for (i = 0; i < size; i++) {
        *p++ = _device.write(0x00);         // Clock in data from RAM(doesn't matter the value)
    }
    _cs = 1;
}

/// Fill SRAM with data
void IP12B512::ClearAll()
{
    uint32_t ram_size = GetRamSize();
    uint32_t i;

    _cs = 0;
    _device.write(IP12B512_WRITE);          // OpCode
    _device.write(0x00);                    // Addr
    _device.write(0x00);                    // Addr

    for (i = 0; i < ram_size; i++) {
        _device.write(0x00);                // Write to SPI ram
    }
    _cs = 1;
}

/// Gets the SRAM size in bytes
uint32_t IP12B512::GetRamSize()
{
    uint8_t data;

    _cs = 0;
    _device.write(IP12B512_RDMI);           // OpCode
    data = _device.write(0xFF);             // Clock in data from RAM
    _cs = 1;

    if (data == 0b0000) return (64  * 1024) / 8; // 64Kbit  = 8KByte
    if (data == 0b0001) return (128 * 1024) / 8; // 128Kbit = 16KByte
    if (data == 0b0010) return (256 * 1024) / 8; // 256Kbit = 32KByte
    if (data == 0b0011) return (512 * 1024) / 8; // 512Kbit = 64KByte

    return 0;
}