John Mitchell / DMSupport

Dependencies:   DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src

Dependents:   lpc4088_displaymodule_hello_world_Sept_2018

Fork of DMSupport by Embedded Artists

Files at this revision

API Documentation at this revision

Comitter:
embeddedartists
Date:
Fri Dec 19 09:03:25 2014 +0100
Parent:
9:a33326afd686
Child:
11:dedcebcfc869
Commit message:
- Added support for executing code in SDRAM.
- Restructured the Display/Touch interfaces.
- Added loading of Display/Touch BIOS.

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
Display/Display.h Show annotated file Show diff for this revision Revisions of this file
Display/TouchPanel.h Show annotated file Show diff for this revision Revisions of this file
Memory/sdram.cpp 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	Thu Dec 11 18:23:07 2014 +0000
+++ b/DMBoard.cpp	Fri Dec 19 09:03:25 2014 +0100
@@ -17,9 +17,11 @@
 #include "mbed.h"
 #include "DMBoard.h"
 #include "InternalEEPROM.h"
+#include "bios.h"
+#include "crc.h"
 
-#if defined(DM_BOARD_USE_TOUCH)
-  #include "AR1021.h"
+#if defined(DM_BOARD_USE_DISPLAY)
+  #include "BiosDisplayAndTouch.h"
 #endif
 
 #if defined(DM_BOARD_ENABLE_MEASSURING_PINS)
@@ -35,6 +37,10 @@
   #error The hardware supports either USB Device or USB Host - not both at the same time
 #endif
 
+#if defined(DM_BOARD_USE_TOUCH) && !defined(DM_BOARD_USE_DISPLAY)
+  #error Cannot have touch controller without a display!
+#endif
+
 /******************************************************************************
  * Defines and typedefs
  *****************************************************************************/
@@ -63,15 +69,13 @@
 
 DMBoard::DMBoard() : 
     _initialized(false),
+    _conf(NULL), _confSize(0),
 #if defined(DM_BOARD_USE_MCI_FS)
     _mcifs("mci", P4_16),
 #endif
 #if defined(DM_BOARD_USE_QSPI_FS)
     _qspifs("qspi"),
 #endif
-#if defined(DM_BOARD_USE_TOUCH)
-    _touch(NULL),
-#endif
     _buzzer(P1_5),
     _button(p23),
     _led1(LED1),
@@ -83,22 +87,28 @@
 
 DMBoard::~DMBoard()
 {
-#if defined(DM_BOARD_USE_TOUCH)
-  if (_touch != NULL) {
-    delete _touch;
-    _touch = NULL;
+  if (_conf != NULL) {
+    free(_conf);
+    _conf = NULL;
+    _confSize = 0;
   }
-#endif
 }
 
 DMBoard::BoardError DMBoard::readConfiguration()
 {
-  InternalEEPROM mem;
-  mem.init();
-  
-  uint8_t* buff = (uint8_t*)malloc(mem.memorySize());
-  mem.read(0, 0, buff, mem.memorySize());
-  mem.powerDown();
+  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");
@@ -153,56 +163,41 @@
 #if defined(DM_BOARD_USE_DISPLAY)
 DMBoard::BoardError DMBoard::readDisplayConfiguration(uint8_t** data, uint32_t* size)
 {
-  uint32_t allocsize = 17*sizeof(uint32_t);
-  uint32_t* stuff = (uint32_t*)malloc(allocsize);
-  if (stuff == NULL) {
-    return MemoryError;
-  }
-#if defined(DM_BOARD_USE_4_3_DISPLAY_TMP)
-  // Temporary setup, for a 4.3" display
+  BoardError err = readConfiguration();
+  do {
+    if (err != Ok) {
+      break;
+    }
+    
+    file_header_t* fh = (file_header_t*)_conf;
+    if (fh->magic != BIOS_MAGIC) {
+      err = BiosInvalidError;
+      break;
+    }
+    
+    if (fh->version != BIOS_VER) {
+      err = BiosVersionError;
+      break;
+    }
+    
+    if ((fh->headerSize + fh->size) > _confSize) {
+      err = BiosInvalidError;
+      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;
+    err = Ok;
+  } while (false);
 
-  stuff[ 0] = 40,    //horizontalBackPorch == HSYNC back porch
-  stuff[ 1] = 5,     //horizontalFrontPorch == HSYNC front porch
-  stuff[ 2] = 2,     //hsync  ==  HSYNC width
-  stuff[ 3] = 480,   //width == Horizontal active area
-  stuff[ 4] = 8,     //verticalBackPorch == VSYNC back porch
-  stuff[ 5] = 8,     //verticalFrontPorch == VSYNC front porch
-  stuff[ 6] = 2,     //vsync == VSYNC width
-  stuff[ 7] = 272,   //height == Vertical display area
-  stuff[ 8] = false,
-  stuff[ 9] = false,
-  stuff[10] = true,
-  stuff[11] = true,
-  stuff[12] = 1,
-  stuff[13] = Display::Resolution_16bit_rgb565;
-  stuff[14] = 9000000, //clock or 0 for external
-  stuff[15] = 0,       //LcdController::Tft,
-  stuff[16] = false;
-#else
-  // Temporary setup, for a 5" rogin display
-
-  stuff[ 0] = 46,    //horizontalBackPorch == HSYNC back porch
-  stuff[ 1] = 20,    //horizontalFrontPorch == HSYNC front porch
-  stuff[ 2] = 2,     //hsync  ==  HSYNC width
-  stuff[ 3] = 800,   //width == Horizontal active area
-  stuff[ 4] = 23,    //verticalBackPorch == VSYNC back porch
-  stuff[ 5] = 10,    //verticalFrontPorch == VSYNC front porch
-  stuff[ 6] = 3,     //vsync == VSYNC width
-  stuff[ 7] = 480,   //height == Vertical display area
-  stuff[ 8] = false,
-  stuff[ 9] = false,
-  stuff[10] = true,
-  stuff[11] = true,
-  stuff[12] = 1,
-  stuff[13] = Display::Resolution_16bit_rgb565;
-  stuff[14] = 30000000, //clock or 0 for external
-  stuff[15] = 0,        //LcdController::Tft,
-  stuff[16] = false;
-#endif  
-  *data = (uint8_t*)&(stuff[0]);
-  *size = allocsize;
-
-  return Ok;
+  return err;
 }
 #endif
 
@@ -227,7 +222,7 @@
       _led2 = 1;
       _led3 = 0;
       _led4 = 0;
-
+        
       // Make sure that the logger is always initialized even if
       // other initialization tasks fail
       _logger.init();
@@ -253,30 +248,18 @@
       readConfiguration();
       
 #if defined(DM_BOARD_USE_DISPLAY)
-      if (Display::instance().init() != Display::Ok) {
+      if (BiosDisplayAndTouch::instance().initDisplay() != Display::DisplayError_Ok) {
         err = DisplayError;
         break;
       }
 #endif
       
 #if defined(DM_BOARD_USE_TOUCH)
-      //if (... configuration says AR1021...) {
-        _touch = new AR1021(P2_27, P2_26, P2_22, P2_23, P2_25);
-        int att;
-        for (att = 1; att <= 3; att++) {
-            if (_touch->init(Display::instance().width(), Display::instance().height())) {
-              break;
-            }
-            _logger.printf("Failed to init touch, trying again...\n");
-            wait_ms(500);
-        }
-        if (att > 3) {
-          err = TouchError;
-          break;
-        }
-      //}
+      if (BiosDisplayAndTouch::instance().initTouchController() != TouchPanel::TouchError_Ok) {
+        err = TouchError;
+        break;
+      }
 #endif
-
       
       _initialized = true;
     } while(0);
@@ -320,3 +303,16 @@
 { 
   return _button.read() == 0;
 }
+
+TouchPanel* DMBoard::touchPanel()
+{
+  if (BiosDisplayAndTouch::instance().isTouchSupported()) {
+    return &BiosDisplayAndTouch::instance();
+  }
+  return NULL;
+}
+
+Display* DMBoard::display()
+{
+  return &BiosDisplayAndTouch::instance();
+}
--- a/DMBoard.h	Thu Dec 11 18:23:07 2014 +0000
+++ b/DMBoard.h	Fri Dec 19 09:03:25 2014 +0100
@@ -32,8 +32,6 @@
 #endif
 #if defined(DM_BOARD_USE_DISPLAY)
   #include "Display.h"
-#endif
-#if defined(DM_BOARD_USE_TOUCH)
   #include "TouchPanel.h"
 #endif
 
@@ -62,11 +60,13 @@
     };
   
     enum BoardError {
-        Ok            =       0,
-        MemoryError   =       1,
-        SpifiError    =       1,
-        DisplayError  =       2,
-        TouchError    =       3,
+        Ok                =       0,
+        MemoryError,
+        SpifiError,
+        DisplayError,
+        TouchError,
+        BiosInvalidError,
+        BiosVersionError,
     };
     
     /** Get the only instance of the DMBoard
@@ -115,23 +115,22 @@
      */
     bool buttonPressed();
     
-#if defined(DM_BOARD_USE_TOUCH)
+#if defined(DM_BOARD_USE_DISPLAY)
     /** Returns the TouchPanel interface
      *
      *  @returns
      *       The touch panel
      */
-    TouchPanel* touchPanel() { return _touch; }
-#endif
-#if defined(DM_BOARD_USE_DISPLAY)
+    TouchPanel* touchPanel();
+
     /** Returns the Display interface
      *
      *  @returns
      *       The display
      */
-    Display* display() { return &(Display::instance()); }
+    Display* display();
 
-    friend class Display;
+    friend class BiosDisplayAndTouch;
 #endif
     /** Returns the logger interface
      *
@@ -143,6 +142,8 @@
 private:
 
     bool _initialized;
+    uint8_t* _conf;
+    uint32_t _confSize;
 
 #if defined(DM_BOARD_USE_MCI_FS)
     MCIFileSystem _mcifs;
@@ -150,9 +151,6 @@
 #if defined(DM_BOARD_USE_QSPI_FS)
     QSPIFileSystem _qspifs;
 #endif
-#if defined(DM_BOARD_USE_TOUCH)
-    TouchPanel* _touch;
-#endif
 
     PwmOut _buzzer;
     DigitalIn _button;
--- a/Display/Display.h	Thu Dec 11 18:23:07 2014 +0000
+++ b/Display/Display.h	Fri Dec 19 09:03:25 2014 +0100
@@ -18,6 +18,7 @@
 #define DISPLAY_H
 
 #include "mbed.h"
+#include "bios.h"
 
 /**
  * Display example
@@ -54,50 +55,29 @@
  */
 class Display {
 public:
-    enum Constants {
-        NumLEDs       =  4,
-    };
-  
     enum DisplayError {
-        Ok            =       0,
-        ConfigError   =       1,
-        WrongBPP      =       2,
-        InvalidParam  =       3,
-        NoInit        =       4,
+        DisplayError_Ok                =   BiosError_Ok,
+        DisplayError_ConfigError       =   BiosError_ConfigError,
+        DisplayError_WrongBPP          =   BiosError_WrongBPP,
+        DisplayError_InvalidParam      =   BiosError_InvalidParam,
+        DisplayError_NoInit            =   BiosError_NoInit,
+        DisplayError_CalibrationError  =   BiosError_Calibration,
+        DisplayError_MemoryError,
     };
     
     enum Resolution {
-        Resolution_16bit_rgb565 = 16,
-        Resolution_18bit_rgb666 = 18,
-        Resolution_24bit_rgb888 = 24,
+        Resolution_16bit_rgb565 = Res_16bit_rgb565,
+        Resolution_18bit_rgb666 = Res_18bit_rgb666,
+        Resolution_24bit_rgb888 = Res_24bit_rgb888,
     };
     
-    /** Get the only instance of the Display
-     *
-     *  @returns The display
-     */
-    static Display& instance()
-    {
-        static Display singleton;
-        return singleton;
-    }
-  
-
-    /** Initializes the display but does not turn it on
-     *
-     *  @returns
-     *       Ok on success
-     *       An error code on failure
-     */
-    DisplayError init();
-  
     /** Turns the display on with the specified framebuffer showing
      *
      *  @returns
      *       Ok on success
      *       An error code on failure
      */
-    DisplayError powerUp(void* framebuffer, Resolution wanted = Resolution_16bit_rgb565);
+    virtual DisplayError powerUp(void* framebuffer, Resolution wanted = Resolution_16bit_rgb565) = 0;
   
     /** Turns the display off
      *
@@ -105,7 +85,7 @@
      *       Ok on success
      *       An error code on failure
      */
-    DisplayError powerDown();
+    virtual DisplayError powerDown() = 0;
   
     /** Sets the backlight level. 0% is off and 100% is fully on
      *
@@ -113,14 +93,15 @@
      *       Ok on success
      *       An error code on failure
      */
-    DisplayError backlight(int percent);
+    virtual DisplayError backlight(int percent) = 0;
   
-    uint16_t width() { return _width; }
-    uint16_t height() { return _height; }
-    uint16_t bpp() { return _bpp; }
-    uint32_t fbSize() { return _fbSize; }
-    bool landscape() { return _landscape; }
-    bool isSupported(Resolution res);
+    virtual uint16_t width() = 0;
+    virtual uint16_t height() = 0;
+    virtual uint16_t bytesPerPixel() = 0;
+    virtual uint32_t fbSize() = 0;
+    virtual bool landscape() = 0;
+    virtual bool isSupported(Resolution res) = 0;
+    virtual Resolution currentResolution() = 0;
     
     /** Replaces the current framebuffer.
      *
@@ -130,7 +111,7 @@
      *
      *  @param buff the new framebuffer
      */
-    void setFramebuffer(void* buff);
+    virtual void setFramebuffer(void* buff) = 0;
     
     /** Replaces the current framebuffer with the specified one.
      *
@@ -141,7 +122,7 @@
      *  @param buff the new framebuffer
      *  @returns the old framebuffer
      */
-    void* swapFramebuffer(void* buff);
+    virtual void* swapFramebuffer(void* buff) = 0;
     
     /** Allocate enough memory for one framebuffer
      *
@@ -152,38 +133,7 @@
      *
      *  @returns a new framebuffer or NULL if out of memory 
      */
-    void* allocateFramebuffer(Resolution res=Resolution_16bit_rgb565);
-
-private:
-
-    bool _initialized;
-    bool _poweredOn;
-    DigitalOut _pinWP;
-    DigitalOut _pin3v3;
-    DigitalOut _pin5v;
-    DigitalOut _pinDE;
-    DigitalOut _pinColDepth;
-    PwmOut _pinBacklight;
-
-    uint16_t _width;
-    uint16_t _height;
-    uint16_t _bpp;
-    uint32_t _fbSize;
-    bool _landscape;
-
-    explicit Display();
-    // hide copy constructor
-    Display(const Display&);
-    // hide assign operator
-    Display& operator=(const Display&);
-    ~Display();
-    
-    void pinInit(bool powerOn, Resolution res=Resolution_16bit_rgb565);
-    DisplayError regInit(void* info, Resolution res);
-    uint32_t getClockDivisor(uint32_t clock);
-    void set3v3(bool on);
-    void set5v(bool on);
-    void setDisplayEnable(bool enable);    
+    virtual void* allocateFramebuffer(Resolution res=Resolution_16bit_rgb565) = 0;
 };
 
 #endif
--- a/Display/TouchPanel.h	Thu Dec 11 18:23:07 2014 +0000
+++ b/Display/TouchPanel.h	Fri Dec 19 09:03:25 2014 +0100
@@ -17,6 +17,8 @@
 #ifndef TOUCHPANEL_H
 #define TOUCHPANEL_H
 
+#include "bios.h"
+
 /**
  * An abstract class that represents touch panels.
  */
@@ -24,39 +26,43 @@
 public:
 
     typedef struct {
-        int32_t x;
-        int32_t y;
-        int32_t z;
+        uint16_t x;
+        uint16_t y;
+        uint16_t z;
     } touchCoordinate_t;
 
-
-    /**
-     * Initialize the touch controller. This method must be called before
-     * calibrating or reading data from the controller
-     *
-     * @param width the width of the touch panel. This is usually the same as
-     * the width of the display
-     * @param height the height of the touch panel. This is usually the same
-     * as the height of the display.
-     *
-     * @return true if the request was successful; otherwise false
-     */
-    virtual bool init(uint16_t width, uint16_t height) = 0;
+    enum TouchError {
+        TouchError_Ok                =   BiosError_Ok,
+        TouchError_ConfigError       =   BiosError_ConfigError,
+        TouchError_WrongBPP          =   BiosError_WrongBPP,
+        TouchError_InvalidParam      =   BiosError_InvalidParam,
+        TouchError_NoInit            =   BiosError_NoInit,
+        TouchError_CalibrationError  =   BiosError_Calibration,        
+        TouchError_MemoryError,
+        TouchError_TouchNotSupported,
+        TouchError_Timeout,
+    };
 
     /**
      * Read coordinates from the touch panel.
      *
      * @param coord pointer to coordinate object. The read coordinates will be
      * written to this object.
+     *
+     *  @returns
+     *       Ok on success
+     *       An error code on failure
      */
-    virtual bool read(touchCoordinate_t &coord) = 0;
+    virtual TouchError read(touchCoordinate_t &coord) = 0;
 
     /**
      * Start to calibrate the display
      *
-     * @return true if the request was successful; otherwise false
+     *  @returns
+     *       Ok on success
+     *       An error code on failure
      */
-    virtual bool calibrateStart() = 0;
+    virtual TouchError calibrateStart() = 0;
 
     /**
      * Get the next calibration point. Draw an indicator on the screen
@@ -68,9 +74,11 @@
      * @param y    the y coordinate is written to this argument
      * @param last true if this is the last coordinate in the series
      *
-     * @return true if the request was successful; otherwise false
+     *  @returns
+     *       Ok on success
+     *       An error code on failure
      */
-    virtual bool getNextCalibratePoint(uint16_t* x, uint16_t* y, bool* last=NULL) = 0;
+    virtual TouchError getNextCalibratePoint(uint16_t* x, uint16_t* y, bool* last=NULL) = 0;
 
     /**
      * Wait for a calibration point to have been pressed and recored.
@@ -81,9 +89,11 @@
      * @param timeout maximum number of milliseconds to wait for
      * a calibration point. Set this argument to 0 to wait indefinite.
      *
-     * @return true if the request was successful; otherwise false
+     *  @returns
+     *       Ok on success
+     *       An error code on failure
      */
-    virtual bool waitForCalibratePoint(bool* morePoints, uint32_t timeout) = 0;
+    virtual TouchError waitForCalibratePoint(bool* morePoints, uint32_t timeout) = 0;
 };
 
 #endif
--- a/Memory/sdram.cpp	Thu Dec 11 18:23:07 2014 +0000
+++ b/Memory/sdram.cpp	Fri Dec 19 09:03:25 2014 +0100
@@ -406,6 +406,36 @@
   return (cnt / 10);
 }
 
+static void allowExecutionOfCodeInSDRAM(void)
+{
+  //----- Adjust MPU to allow execution of code from SDRAM
+  
+  /* Disable MPU */
+  MPU->CTRL = 0x00;
+  
+  /* Select to use the default memory map as base and only modify parts */
+  MPU->CTRL = 0x04; // PRIVDEFENA=1
+  
+#define _RBAR(_ADDR, _VALID, _REGION) \
+    ((_ADDR) | ((_VALID) << 4) | (_REGION))
+
+#define _RASR(_XN, _AP, _TYPE, _SRD, _SIZE, _ENABLE) \
+    (((_XN) << 28) | ((_AP) << 24) | ((_TYPE) << 16) | ((_SRD) << 8) | ((_SIZE) << 1) | (_ENABLE))
+
+#define AP_RW         0x03 // 011 = Full Access
+#define MEM_TYPE_ERAM 0x07 // Normal, Sharable, Cached, Buffered, write-back & write allocate
+#define SIZE_32M      0x18 // Region size in bytes = 2^(0x18+1) = 32MB
+
+  /* Setup MPU Region 4 for the SDRAM (0xA0000000 - 0xA1FFFFFF*/
+  MPU->RBAR = _RBAR(0xA0000000, 1, 4);
+  MPU->RASR = _RASR(0, AP_RW, MEM_TYPE_ERAM, 0, SIZE_32M, 1);
+
+  /* (Re-)Enable MPU */
+  MPU->CTRL |= 0x01;
+  
+  //----- End of MPU adjustments
+}
+
 /******************************************************************************
  * Public Functions
  *****************************************************************************/
@@ -583,6 +613,8 @@
 
   adjust_timing();
   
+  allowExecutionOfCodeInSDRAM();
+  
   initialized = true;
 
   return 0;//TRUE;
--- a/dm_board_config.h.txt	Thu Dec 11 18:23:07 2014 +0000
+++ b/dm_board_config.h.txt	Fri Dec 19 09:03:25 2014 +0100
@@ -34,6 +34,4 @@
 // #define DM_BOARD_DISABLE_STANDARD_PRINTF
 // #define DM_BOARD_ENABLE_MEASSURING_PINS
 
-// #define DM_BOARD_USE_4_3_DISPLAY_TMP /* temporary while debugging */
-
 #endif