Solutions for the SPI E2PROM experiments for LPC812 MAX

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI25LC080.cpp Source File

SPI25LC080.cpp

00001 #include "mbed.h"
00002 #include "SPI25LC080.h"
00003 
00004 /* SPI E2PROM command set */
00005 #define INST_WREN      0x06    /* MSB A8 is set to 0, simplifying test */
00006 #define INST_WRDI      0x04
00007 #define INST_RDSR      0x05
00008 #define INST_WRSR      0x01
00009 #define INST_READ      0x03
00010 #define INST_WRITE     0x02
00011 
00012 /* RDSR status bit definition */
00013 #define RDSR_RDY       0x01
00014 #define RDSR_WEN       0x02
00015 
00016 /* Page size of E2PROM */
00017 #define PAGE_SIZE        16
00018 
00019 #define LOCAL_MIN(__a, __b)  ( ((__a) < (__b)) ? (__a) : (__b) )
00020 
00021 SPI25LC080::SPI25LC080(PinName mosi, PinName sclk, PinName miso, PinName ssel) :
00022     m_spi(mosi, miso, sclk), m_ssel(ssel)
00023 {
00024 }
00025 
00026 void SPI25LC080::read(uint16_t address, uint8_t* pData, uint32_t length)
00027 {
00028     //pull SSEL/CS low
00029     m_ssel = 0;
00030 
00031     //output read command and address
00032     m_spi.write(INST_READ);
00033     m_spi.write((address >> 8) & 0xff);
00034     m_spi.write(address & 0xff);
00035 
00036     //read bytes from E2PROM
00037     for (uint32_t i = 0; i < length; i++) {
00038         pData[i] = m_spi.write(0x00); // write dummy byte to get read next value
00039     }
00040 
00041     //pull SSEL/CS high
00042     m_ssel = 1;
00043 }
00044 
00045 uint8_t SPI25LC080::status()
00046 {
00047     //pull SSEL/CS low
00048     m_ssel = 0;
00049 
00050     uint8_t status = m_spi.write(INST_RDSR);
00051 
00052     //pull SSEL/CS high
00053     m_ssel = 1;
00054     
00055     return status;
00056 }
00057 
00058 void SPI25LC080::write_enable()
00059 {
00060   //pull SSEL/CS low
00061   m_ssel = 0;
00062 
00063   //output write command and address
00064   m_spi.write(INST_WREN);
00065 
00066   //pull SSEL/CS high
00067   m_ssel = 1;
00068 }
00069 
00070 void SPI25LC080::write(uint16_t address, uint8_t* pData, uint32_t length)
00071 {
00072   uint32_t left = length;
00073   uint32_t offset = address;
00074   uint32_t len = 0;
00075 
00076   // find length of first page write
00077   if ((address / PAGE_SIZE) != ((address + length) / PAGE_SIZE)) {
00078     //spans across at least one boundary
00079     len = PAGE_SIZE - (address % PAGE_SIZE);
00080   } else {
00081     // ends inside same page => use normal length
00082     len = length % PAGE_SIZE;
00083   }
00084 
00085   //insert code here to break up large write operation into several
00086   //page write operations (16 or 32 byte pages)
00087   while (left > 0) {
00088 
00089     //Enable write latch
00090     write_enable();
00091 
00092     //pull SSEL/CS low
00093     m_ssel = 0;
00094 
00095     //output write command and address
00096     m_spi.write(INST_WRITE);
00097     m_spi.write((offset >> 8) & 0xff);
00098     m_spi.write(offset & 0xff);
00099 
00100     //send bytes to write E2PROM
00101     for (uint32_t i = 0; i < len; i++) {
00102         m_spi.write(pData[offset + i]);
00103     }
00104 
00105     //pull SSEL/CS high
00106     m_ssel = 1;
00107 
00108     offset += len;
00109     left -= len;
00110     len = LOCAL_MIN(left, PAGE_SIZE);
00111 
00112     //wait until write operations is done
00113     //for now, just wait. A more sophisticated method is to poll the status register
00114     wait_ms(5);
00115   }
00116 }
00117