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

Files at this revision

API Documentation at this revision

Comitter:
embeddedartists
Date:
Wed Jan 07 14:02:39 2015 +0100
Parent:
16:80f1723b15e2
Child:
18:e5eb986b2a83
Commit message:
Moved BIOS from internal to external EEPROM

Changed in this revision

DMBoard.cpp Show annotated file Show diff for this revision Revisions of this file
DMBoard.h Show annotated file Show diff for this revision Revisions of this file
Memory/BiosEEPROM.cpp Show annotated file Show diff for this revision Revisions of this file
Memory/BiosEEPROM.h Show annotated file Show diff for this revision Revisions of this file
Memory/InternalEEPROM.cpp Show annotated file Show diff for this revision Revisions of this file
Memory/InternalEEPROM.h Show annotated file Show diff for this revision Revisions of this file
dm_board_config.h.txt Show annotated file Show diff for this revision Revisions of this file
--- a/DMBoard.cpp	Fri Jan 02 14:17:03 2015 +0000
+++ b/DMBoard.cpp	Wed Jan 07 14:02:39 2015 +0100
@@ -16,7 +16,7 @@
 
 #include "mbed.h"
 #include "DMBoard.h"
-#include "InternalEEPROM.h"
+#include "BiosEEPROM.h"
 #include "bios.h"
 #include "crc.h"
 
@@ -59,6 +59,17 @@
 static DevNull null("null");
 #endif
 
+/*
+ * Make sure that we reserve at least this amount of RAM for future
+ * expansion of the BIOS. This prevents the user from squeezing out
+ * the last drop of available RAM in his application.
+ */
+#define BIOS_RESERVED_CHUNK  0x1000
+#define BIOS_MAX_SIZE        0x100000
+#ifndef MAX
+  #define MAX(__a, __b) (((__a)>(__b))?(__a):(__b))
+#endif
+
 /******************************************************************************
  * Local variables
  *****************************************************************************/
@@ -94,108 +105,71 @@
   }
 }
 
-DMBoard::BoardError DMBoard::readConfiguration()
-{
-  if (_conf == NULL) {
-    InternalEEPROM mem;
-    mem.init();
-    
-    _confSize = mem.memorySize();
-    _conf = (uint8_t*)malloc(_confSize);
-    if (_conf == NULL) {
-      _confSize = 0;
-      return MemoryError;
-    }
-    mem.read(0, 0, _conf, _confSize);
-    mem.powerDown();
-  }
-#if 0  
-  uint8_t* p = buff;
-  _logger.printf("\n-------\nBEFORE:\n-------\n");
-  for (int i = 0; i < 63; i++) {
-    for (int j = 0; j < 4; j++) {
-      _logger.printf("0x%04x  %02x %02x %02x %02x %02x %02x %02x %02x  %02x %02x %02x %02x %02x %02x %02x %02x\n",
-        i,
-        p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],
-        p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
-      p += 16;
-    }
-    _logger.printf("\n");
-  }
-  
-  // find first non-zero page and write to that
-  for (int page = 0; page < mem.numPages(); page++) {
-    bool zeroPage = true;
-    for (int i = 0; i < mem.pageSize(); i++) {
-      if (buff[i + page*mem.pageSize()] != 0) {
-        zeroPage = false;
-        break;
-      }
-    }
-    if (zeroPage) {
-      _logger.printf("Will fill page 0x%04x (%d) with 0x00..0x3f\n", page, page);
-      p = buff;
-      for (int i = 0; i < mem.pageSize(); i++) {
-        *p++ = i;
-      }
-      mem.write(page, 0, buff, mem.pageSize());
-      memset(buff, 0, mem.memorySize());
-      mem.read(0, 0, buff, mem.memorySize());
-      p = buff;
-      _logger.printf("\n-------\nAFTER:\n-------\n");
-      for (int i = 0; i < 63; i++) {
-        for (int j = 0; j < 4; j++) {
-          _logger.printf("0x%04x  %02x %02x %02x %02x %02x %02x %02x %02x  %02x %02x %02x %02x %02x %02x %02x %02x\n",
-            i,
-            p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],
-            p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
-          p += 16;
-        }
-        _logger.printf("\n");
-      }
-      break;
-    }
-  }  
-#endif
-  return Ok;
-}
-
 #if defined(DM_BOARD_USE_DISPLAY)
 DMBoard::BoardError DMBoard::readDisplayConfiguration(uint8_t** data, uint32_t* size)
 {
-  BoardError err = readConfiguration();
+  BoardError err = Ok;
+  BiosEEPROM eeprom;
+  file_header_t fh;
+
+  if (_conf != NULL) {
+    *data = _conf;
+    *size = _confSize;
+    return Ok;
+  }      
   do {
-    if (err != Ok) {
+    if (!eeprom.read(0, (char*)&fh, sizeof(file_header_t))) {
+      err = BiosStorageError;
       break;
     }
     
-    file_header_t* fh = (file_header_t*)_conf;
-    if (fh->magic != BIOS_MAGIC) {
+    if (fh.magic != BIOS_MAGIC) {
       err = BiosInvalidError;
       break;
     }
     
-    if (fh->version != BIOS_VER) {
+    if (fh.version != BIOS_VER) {
       err = BiosVersionError;
       break;
     }
     
-    if ((fh->headerSize + fh->size) > _confSize) {
+    if ((fh.headerSize + fh.size) > BIOS_MAX_SIZE) {
       err = BiosInvalidError;
       break;
     }
     
-    uint32_t crc = crc_Buffer((uint32_t*)(&_conf[fh->headerSize]), fh->size/4);
-    if (crc != fh->crc) {
+    _confSize = fh.headerSize + fh.size;
+    _conf = (uint8_t*)malloc(MAX(_confSize,BIOS_RESERVED_CHUNK));
+    if (_conf == NULL) {
+      _confSize = 0;
+      err = MemoryError;
+      break;
+    }
+    
+    if (!eeprom.read(0, (char*)_conf, _confSize)) {
+      err = BiosStorageError;
+      break;
+    }
+    
+    uint32_t crc = crc_Buffer((uint32_t*)(&_conf[fh.headerSize]), fh.size/4);
+    if (crc != fh.crc) {
       err = BiosInvalidError;
       break;
     }
     
     // Bios header has been verified and seems ok
     *data = _conf;
-    *size = fh->headerSize + fh->size;
+    *size = _confSize;
     err = Ok;
   } while (false);
+  
+  if (err != Ok) {
+    if (_conf != NULL) {
+      free(_conf);
+      _conf = NULL;
+      _confSize = 0;
+    }
+  }
 
   return err;
 }
@@ -245,8 +219,6 @@
       }
 #endif
       
-      readConfiguration();
-      
 #if defined(DM_BOARD_USE_DISPLAY)
       if (BiosDisplayAndTouch::instance().initDisplay() != Display::DisplayError_Ok) {
         err = DisplayError;
--- a/DMBoard.h	Fri Jan 02 14:17:03 2015 +0000
+++ b/DMBoard.h	Wed Jan 07 14:02:39 2015 +0100
@@ -67,6 +67,7 @@
         TouchError,
         BiosInvalidError,
         BiosVersionError,
+        BiosStorageError,
     };
     
     /** Get the only instance of the DMBoard
@@ -168,7 +169,6 @@
     DMBoard& operator=(const DMBoard&);
     ~DMBoard();
     
-    BoardError readConfiguration();
 #if defined(DM_BOARD_USE_DISPLAY)
     BoardError readDisplayConfiguration(uint8_t** data, uint32_t* size);
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Memory/BiosEEPROM.cpp	Wed Jan 07 14:02:39 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 2014 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "mbed.h"
+#include "BiosEEPROM.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+#define BIOS_EEPROM_ADDR      (0xAC)
+
+
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+/******************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+BiosEEPROM::BiosEEPROM() : _i2c(P0_27, P0_28)
+{
+    _i2c.frequency(400000);
+}
+
+bool BiosEEPROM::read(uint32_t address, char* data, uint32_t size)
+{
+    bool success = false;
+    do {
+        char buf[2];
+        buf[0] = address >> 8;
+        buf[1] = address & 0xff;
+        
+        if (_i2c.write(BIOS_EEPROM_ADDR, buf, 2) == 0) {
+            if (_i2c.read(BIOS_EEPROM_ADDR, data, size) == 0) {
+                success = true;
+                break;
+            }
+        }
+    } while(false);
+    return success;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Memory/BiosEEPROM.h	Wed Jan 07 14:02:39 2015 +0100
@@ -0,0 +1,46 @@
+/*
+ *  Copyright 2014 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef BIOS_EEPROM_H
+#define BIOS_EEPROM_H
+
+#include "mbed.h"
+
+/**
+ * Bios EEPROM Driver
+ */
+class BiosEEPROM {
+public:
+    
+    BiosEEPROM();
+
+    /** Reads
+     *
+     * @param address   the address to read from
+     * @param data      buffer to store read data in
+     * @param size      number of bytes to read
+     *
+     *  @returns
+     *       True on success
+     *       False on failure
+     */
+    bool read(uint32_t address, char* data, uint32_t size);
+  
+private:
+    I2C _i2c;
+};
+
+#endif
--- a/Memory/InternalEEPROM.cpp	Fri Jan 02 14:17:03 2015 +0000
+++ b/Memory/InternalEEPROM.cpp	Wed Jan 07 14:02:39 2015 +0100
@@ -176,7 +176,7 @@
 
 int InternalEEPROM::write(uint32_t pageAddr, uint32_t pageOffset, const uint8_t* data, uint32_t size)
 {
-#if defined(DM_BOARD_USE_INT_EEPROM_WRITE)
+#if defined(DM_BOARD_ENABLE_INT_EEPROM_WRITE)
   uint32_t numWritten = 0;
   uint32_t writeOffset = (pageOffset & (EEPROM_PAGE_SIZE - 1));
   uint32_t writeSize = EEPROM_PAGE_SIZE - writeOffset;
@@ -208,7 +208,7 @@
 
 void InternalEEPROM::erasePage(uint32_t pageAddr)
 {
-#if defined(DM_BOARD_USE_INT_EEPROM_WRITE)
+#if defined(DM_BOARD_ENABLE_INT_EEPROM_WRITE)
     
   powerUp();
 
--- a/Memory/InternalEEPROM.h	Fri Jan 02 14:17:03 2015 +0000
+++ b/Memory/InternalEEPROM.h	Wed Jan 07 14:02:39 2015 +0100
@@ -20,35 +20,7 @@
 #include "mbed.h"
 
 /**
- * Internal EEPROM Example
- *
- * @code
- * #include "mbed.h"
- * #include "InternalEEPROM.h"
- *
- * int main(void) {
- *    InternalEEPROM mem;
- *
- *    err = SPIFI::instance().init();
- *    if (err != SPIFI::Ok) {
- *        printf("Failed to initialize SPIFI, error %d\n", err);
- *    }
- *    
- *    // Write "Hello World!" into the first bytes of the SPIFI
- *    char buff[20] = "Hello World!";
- *    err = SPIFI::instance().program(0, strlen(buff)+1, buff, SPIFI::EraseAsRequired);
- *    if (err != SPIFI::Ok) {
- *        printf("Failed to write to SPIFI, error %d\n", err);
- *    }
- *
- *    // Now verify that it can be read
- *    if (memcmp((char*)SPIFI::SpifiMemBase, buff, strlen(buff)+1) == 0) {
- *        printf("Readback from memory OK: '%s'\n", SPIFI::SpifiMemBase);
- *    } else {
- *        printf("Spifi does not contain the correct data!\n");
- *    }
- * }
- * @endcode
+ * Internal EEPROM Driver
  */
 class InternalEEPROM {
 public:
@@ -62,7 +34,7 @@
     InternalEEPROM();
     ~InternalEEPROM();
 
-    /** Initializes the SPIFI ROM driver making the content of the external serial flash available
+    /** Initializes the EEPROM
      *
      *  @returns
      *       Ok on success
--- a/dm_board_config.h.txt	Fri Jan 02 14:17:03 2015 +0000
+++ b/dm_board_config.h.txt	Wed Jan 07 14:02:39 2015 +0100
@@ -29,7 +29,7 @@
 // #define DM_BOARD_USE_TOUCH
 // #define DM_BOARD_USE_ETHERNET
 #define DM_BOARD_USE_FAST_UART
-// #define DM_BOARD_USE_INT_EEPROM_WRITE
+// #define DM_BOARD_ENABLE_INT_EEPROM_WRITE
 // #define DM_BOARD_DISABLE_STANDARD_PRINTF
 // #define DM_BOARD_ENABLE_MEASSURING_PINS
 // #define DM_BOARD_BIOS_DEVELOPMENT