A board support package for the LPC4088 Display Module.

Dependencies:   DM_HttpServer DM_USBHost

Dependents:   lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more

Fork of DMSupport by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers InternalEEPROM.cpp Source File

InternalEEPROM.cpp

00001 /*
00002  *  Copyright 2014 Embedded Artists AB
00003  *
00004  *  Licensed under the Apache License, Version 2.0 (the "License");
00005  *  you may not use this file except in compliance with the License.
00006  *  You may obtain a copy of the License at
00007  *
00008  *    http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  *  Unless required by applicable law or agreed to in writing, software
00011  *  distributed under the License is distributed on an "AS IS" BASIS,
00012  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *  See the License for the specific language governing permissions and
00014  *  limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "InternalEEPROM.h"
00019 
00020 
00021 /******************************************************************************
00022  * Defines and typedefs
00023  *****************************************************************************/
00024 
00025 #define EEPROM_INT_ENDOFRW    (1<<26)
00026 #define EEPROM_INT_ENDOFPROG  (1<<28)
00027 
00028 #define EEPROM_PWRDWN          (1<<0)
00029 
00030 /*
00031  * Commands (for the LPC_EEPROM->CMD register)
00032  */
00033 #define EEPROM_CMD_8BITS_READ           (0)     /*!< EEPROM 8-bit read command */
00034 #define EEPROM_CMD_16BITS_READ          (1)     /*!< EEPROM 16-bit read command */
00035 #define EEPROM_CMD_32BITS_READ          (2)     /*!< EEPROM 32-bit read command */
00036 #define EEPROM_CMD_8BITS_WRITE          (3)     /*!< EEPROM 8-bit write command */
00037 #define EEPROM_CMD_16BITS_WRITE         (4)     /*!< EEPROM 16-bit write command */
00038 #define EEPROM_CMD_32BITS_WRITE         (5)     /*!< EEPROM 32-bit write command */
00039 #define EEPROM_CMD_ERASE_PRG_PAGE       (6)     /*!< EEPROM erase/program command */
00040 #define EEPROM_CMD_RDPREFETCH           (1 << 3)/*!< EEPROM read pre-fetch enable */
00041 
00042 
00043 /******************************************************************************
00044  * Local variables
00045  *****************************************************************************/
00046 
00047 /******************************************************************************
00048  * Private Functions
00049  *****************************************************************************/
00050 
00051 void InternalEEPROM::powerUp()
00052 {
00053   LPC_EEPROM->PWRDWN = 0;
00054 }
00055 
00056 void InternalEEPROM::clearInterrupt(uint32_t mask)
00057 {
00058   LPC_EEPROM->INT_CLR_STATUS = mask;
00059 }
00060 
00061 void InternalEEPROM::waitForInterrupt(uint32_t mask)
00062 {
00063   while ((LPC_EEPROM->INT_STATUS & mask) != mask) {
00064   }
00065 
00066   clearInterrupt(mask);
00067 }
00068 
00069 void InternalEEPROM::setAddr(uint32_t pageAddr, uint32_t pageOffset)
00070 {
00071   LPC_EEPROM->ADDR = (pageAddr << 6) | pageOffset;
00072 }
00073 
00074 void InternalEEPROM::setCmd(uint32_t cmd)
00075 {
00076   LPC_EEPROM->CMD = cmd;
00077 }
00078 
00079 void InternalEEPROM::readPage(uint32_t pageAddr, uint32_t pageOffset, uint8_t* buf, uint32_t size)
00080 {
00081   clearInterrupt(EEPROM_INT_ENDOFRW);
00082   setAddr(pageAddr, pageOffset);
00083   setCmd(EEPROM_CMD_8BITS_READ | EEPROM_CMD_RDPREFETCH);
00084   for (uint32_t i = 0; i < size; i++) {
00085     buf[i] = LPC_EEPROM->RDATA & 0xff;
00086     waitForInterrupt(EEPROM_INT_ENDOFRW);
00087   }
00088 }
00089 
00090 void InternalEEPROM::writePage(uint32_t pageAddr, uint32_t pageOffset, const uint8_t* buf, uint32_t size)
00091 {
00092   clearInterrupt(EEPROM_INT_ENDOFRW);
00093   setCmd(EEPROM_CMD_8BITS_WRITE);
00094   setAddr(pageAddr, pageOffset);
00095   for (uint32_t i = 0; i < size; i++) {
00096     LPC_EEPROM->WDATA = buf[i];
00097     waitForInterrupt(EEPROM_INT_ENDOFRW);
00098   }
00099 }
00100 
00101 void InternalEEPROM::eraseOrProgramPage(uint32_t pageAddr)
00102 {
00103   // Write data from page register to non-volatile memory
00104   clearInterrupt(EEPROM_INT_ENDOFPROG);
00105   setAddr(pageAddr, 0);
00106   setCmd(EEPROM_CMD_ERASE_PRG_PAGE);
00107   waitForInterrupt(EEPROM_INT_ENDOFPROG);
00108 }
00109 
00110 
00111 /******************************************************************************
00112  * Public Functions
00113  *****************************************************************************/
00114 
00115 InternalEEPROM::InternalEEPROM() : _initialized(false)
00116 {
00117 }
00118 
00119 InternalEEPROM::~InternalEEPROM()
00120 {
00121 }
00122 
00123 void InternalEEPROM::init()
00124 {
00125   if (!_initialized) {
00126                  
00127     // Bring EEPROM device out of power down mode
00128     powerUp();
00129 
00130     // Setup EEPROM timing to 375KHz based on PCLK rate
00131     uint32_t clk = SystemCoreClock;
00132     LPC_EEPROM->CLKDIV = SystemCoreClock / 375000 - 1;
00133 
00134     // Setup wait states (ticks needed for 15ms, 55ms and 35ms)
00135     uint32_t val;
00136     val  = ((((clk / 1000000) * 15) / 1000) + 1);
00137     val |= (((((clk / 1000000) * 55) / 1000) + 1) << 8);
00138     val |= (((((clk / 1000000) * 35) / 1000) + 1) << 16);
00139     LPC_EEPROM->WSTATE = val;
00140 
00141     _initialized = true;
00142   }
00143 }
00144 
00145 void InternalEEPROM::powerDown()
00146 {
00147   LPC_EEPROM->PWRDWN = EEPROM_PWRDWN;
00148 }
00149 
00150 int InternalEEPROM::read(uint32_t addr, uint8_t* data, uint32_t size)
00151 {
00152   uint32_t numRead = 0;
00153   uint32_t pageAddr = addr/EEPROM_PAGE_SIZE;
00154   uint32_t readOffset = (addr & (EEPROM_PAGE_SIZE - 1));
00155   uint32_t readSize = EEPROM_PAGE_SIZE - readOffset;
00156   
00157   // Prevent reading past the end of the memory
00158   if (addr >= EEPROM_MEMORY_SIZE) {
00159     return 0;
00160   }
00161   if ((size + addr) > EEPROM_MEMORY_SIZE) {
00162     size = EEPROM_MEMORY_SIZE - addr;
00163   }
00164 
00165   powerUp();
00166 
00167   // Read and store data in buffer
00168   while (size) {
00169     // Make sure we don't write past the end of the buffer
00170     if (readSize > size) {
00171       readSize = size;
00172     }
00173     
00174     readPage(pageAddr, readOffset, &(data[numRead]), readSize);
00175     numRead += readSize;
00176     size -= readSize;
00177 
00178     // Change to next page
00179     pageAddr++;
00180     readOffset = 0;
00181     readSize = EEPROM_PAGE_SIZE;
00182   }
00183   return numRead;
00184 }
00185 
00186 int InternalEEPROM::write(uint32_t addr, const uint8_t* data, uint32_t size)
00187 {
00188   uint32_t numWritten = 0;
00189   uint32_t pageAddr = addr/EEPROM_PAGE_SIZE;
00190   uint32_t writeOffset = (addr & (EEPROM_PAGE_SIZE - 1));
00191   uint32_t writeSize = EEPROM_PAGE_SIZE - writeOffset;
00192 
00193   // Prevent writing past the end of the memory
00194   if (addr >= EEPROM_MEMORY_SIZE) {
00195     return 0;
00196   }
00197   if ((size + addr) > EEPROM_MEMORY_SIZE) {
00198     size = EEPROM_MEMORY_SIZE - addr;
00199   }
00200 
00201   powerUp();
00202 
00203   // Read and store data in buffer
00204   while (size) {
00205     // Make sure we don't read past the end of the buffer
00206     if (writeSize > size) {
00207       writeSize = size;
00208     }
00209     
00210     writePage(pageAddr, writeOffset, &(data[numWritten]), writeSize);
00211     eraseOrProgramPage(pageAddr);
00212     numWritten += writeSize;
00213     size -= writeSize;
00214 
00215     // Change to next page
00216     pageAddr++;
00217     writeOffset = 0;
00218     writeSize = EEPROM_PAGE_SIZE;
00219   }
00220   return numWritten;
00221 }