IP12B512 class for comunicating with the IPSiLog IP12B512 SPI RAM

Revision:
0:35077a3db00c
Child:
1:bcbe2cf57840
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IP12B512.cpp	Fri Nov 04 07:58:20 2016 +0000
@@ -0,0 +1,164 @@
+/** 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;
+}
\ No newline at end of file