Solutions for the SPI E2PROM experiments for LPC812 MAX

Dependencies:   mbed

Revision:
1:819f21483c01
Parent:
0:aa38ad0bf51d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SPI25LC080.cpp	Thu Nov 28 12:17:45 2013 +0000
@@ -0,0 +1,117 @@
+#include "mbed.h"
+#include "SPI25LC080.h"
+
+/* SPI E2PROM command set */
+#define INST_WREN      0x06    /* MSB A8 is set to 0, simplifying test */
+#define INST_WRDI      0x04
+#define INST_RDSR      0x05
+#define INST_WRSR      0x01
+#define INST_READ      0x03
+#define INST_WRITE     0x02
+
+/* RDSR status bit definition */
+#define RDSR_RDY       0x01
+#define RDSR_WEN       0x02
+
+/* Page size of E2PROM */
+#define PAGE_SIZE        16
+
+#define LOCAL_MIN(__a, __b)  ( ((__a) < (__b)) ? (__a) : (__b) )
+
+SPI25LC080::SPI25LC080(PinName mosi, PinName sclk, PinName miso, PinName ssel) :
+    m_spi(mosi, miso, sclk), m_ssel(ssel)
+{
+}
+
+void SPI25LC080::read(uint16_t address, uint8_t* pData, uint32_t length)
+{
+    //pull SSEL/CS low
+    m_ssel = 0;
+
+    //output read command and address
+    m_spi.write(INST_READ);
+    m_spi.write((address >> 8) & 0xff);
+    m_spi.write(address & 0xff);
+
+    //read bytes from E2PROM
+    for (uint32_t i = 0; i < length; i++) {
+        pData[i] = m_spi.write(0x00); // write dummy byte to get read next value
+    }
+
+    //pull SSEL/CS high
+    m_ssel = 1;
+}
+
+uint8_t SPI25LC080::status()
+{
+    //pull SSEL/CS low
+    m_ssel = 0;
+
+    uint8_t status = m_spi.write(INST_RDSR);
+
+    //pull SSEL/CS high
+    m_ssel = 1;
+    
+    return status;
+}
+
+void SPI25LC080::write_enable()
+{
+  //pull SSEL/CS low
+  m_ssel = 0;
+
+  //output write command and address
+  m_spi.write(INST_WREN);
+
+  //pull SSEL/CS high
+  m_ssel = 1;
+}
+
+void SPI25LC080::write(uint16_t address, uint8_t* pData, uint32_t length)
+{
+  uint32_t left = length;
+  uint32_t offset = address;
+  uint32_t len = 0;
+
+  // find length of first page write
+  if ((address / PAGE_SIZE) != ((address + length) / PAGE_SIZE)) {
+    //spans across at least one boundary
+    len = PAGE_SIZE - (address % PAGE_SIZE);
+  } else {
+    // ends inside same page => use normal length
+    len = length % PAGE_SIZE;
+  }
+
+  //insert code here to break up large write operation into several
+  //page write operations (16 or 32 byte pages)
+  while (left > 0) {
+
+    //Enable write latch
+    write_enable();
+
+    //pull SSEL/CS low
+    m_ssel = 0;
+
+    //output write command and address
+    m_spi.write(INST_WRITE);
+    m_spi.write((offset >> 8) & 0xff);
+    m_spi.write(offset & 0xff);
+
+    //send bytes to write E2PROM
+    for (uint32_t i = 0; i < len; i++) {
+        m_spi.write(pData[offset + i]);
+    }
+
+    //pull SSEL/CS high
+    m_ssel = 1;
+
+    offset += len;
+    left -= len;
+    len = LOCAL_MIN(left, PAGE_SIZE);
+
+    //wait until write operations is done
+    //for now, just wait. A more sophisticated method is to poll the status register
+    wait_ms(5);
+  }
+}
+