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:
Fri Jan 23 17:31:56 2015 +0100
Parent:
27:0499c29688cc
Child:
29:b1ec19000e15
Commit message:
- BIOS API up to 0.2.0
- Moved I2C0 interrupt handling from BiosTouch to BiosLoader
- Added (or prepared for) ethernet MAC address reading from BIOS

Changed in this revision

Bios/BiosLoader.cpp Show annotated file Show diff for this revision Revisions of this file
Bios/BiosLoader.h Show annotated file Show diff for this revision Revisions of this file
Bios/bios.h Show annotated file Show diff for this revision Revisions of this file
Display/BiosTouch.cpp Show annotated file Show diff for this revision Revisions of this file
Display/BiosTouch.h Show annotated file Show diff for this revision Revisions of this file
--- a/Bios/BiosLoader.cpp	Fri Jan 23 13:48:44 2015 +0100
+++ b/Bios/BiosLoader.cpp	Fri Jan 23 17:31:56 2015 +0100
@@ -20,6 +20,7 @@
 #include "BiosEEPROM.h"
 #include "crc.h"
 #include "bios.h"
+#include "meas.h"
 
 #if defined(DM_BOARD_BIOS_DEVELOPMENT)
   #ifdef __cplusplus
@@ -55,15 +56,47 @@
 #define SUPPORTED_BIOS_VER   0x000000
 #define SUPPORTED_BIOS_MASK  0xff0000  // only look at the Major component
 #define SUPPORTED_VERSION(__ver) (((__ver)&SUPPORTED_BIOS_MASK) == SUPPORTED_BIOS_VER)
-    
+
+#define MAC_IN_SDK
+
 /******************************************************************************
  * Local variables
  *****************************************************************************/
 
 /******************************************************************************
+ * Global functions
+ *****************************************************************************/
+
+#if !defined(MAC_IN_SDK)
+/* The LPC4088QSB platform in the MBED SDK have defined the WEAK function
+ * mbed_mac_address (ethernet_api.c) to read a unique MAC address from the
+ * onboard EEPROM.
+ * The LPC4088DM platform in the MBED SDK does not have the WEAK function
+ * so it is implemented here instead. This version of the function will ask
+ * the bios for a MAC address.
+ */
+void mbed_mac_address(char *mac) {
+  static char cache[6];
+  static bool haveIt = false;
+  if (!haveIt) {
+    BiosLoader::instance().getMacAddress(cache);
+    haveIt = true;
+  }
+  memcpy(mac, cache, 6);
+}
+#endif
+
+/******************************************************************************
  * Private Functions
  *****************************************************************************/
 
+// Called by the NVIC
+static void loader_i2c0_irq_handler()
+{
+  BiosLoader::instance().handleI2CInterrupt();
+}
+
+
 // Function called from the BIOS
 static uint32_t readTimeMs()
 {
@@ -196,6 +229,7 @@
         break;
       }
       
+#if defined(MAC_IN_SDK)
       // The BIOS has been read so we know that the I2C bus is working. After the
       // BIOS is "started" it will take ownership of the bus and it can cause
       // problems for other peripherals on it. The only other peripheral today
@@ -204,6 +238,7 @@
       // we prevent future access to the I2C bus.
       char mac[6] = {0};
       mbed_mac_address(mac);
+#endif
       
       // Extract the function pointers so that they can be modified to match the
       // actual location of the code
@@ -248,6 +283,11 @@
         err = DMBoard::BiosInvalidError;
         break;
       }
+
+      // Setup the mandatory I2C0 interrupt handler after initParams but before all other calls
+      NVIC_DisableIRQ(I2C0_IRQn);
+      NVIC_SetVector(I2C0_IRQn, (uint32_t)loader_i2c0_irq_handler);      
+      NVIC_EnableIRQ(I2C0_IRQn);
       
       _initialized = true;
     } while(0);
@@ -287,3 +327,34 @@
   }
   return false;
 }
+
+void BiosLoader::getMacAddress(char mac[6])
+{
+  if (!_initialized) {
+    init();
+  }
+  if (_initialized) {
+    BiosError_t err = _bios.ethernetMac(_biosData, mac);
+    if (err == BiosError_Ok) {
+      return;
+    }
+  }
+  
+  // We always consider the MAC address to be retrieved even though
+  // reading is failed. If it wasn't possible to read then the default
+  // address will be used.
+  mac[0] = 0x00;
+  mac[1] = 0x02;
+  mac[2] = 0xF7;
+  mac[3] = 0xF0;
+  mac[4] = 0x00;
+  mac[5] = 0x01;
+}
+
+void BiosLoader::handleI2CInterrupt()
+{
+  SET_MEAS_PIN_2();
+  _bios.i2cIRQHandler(_biosData);
+  CLR_MEAS_PIN_2();
+}
+
--- a/Bios/BiosLoader.h	Fri Jan 23 13:48:44 2015 +0100
+++ b/Bios/BiosLoader.h	Fri Jan 23 17:31:56 2015 +0100
@@ -40,8 +40,10 @@
     }
   
 
+    void getMacAddress(char mac[6]);
     bool isKnownSPIFIMemory(uint8_t mfgr, uint8_t devType, uint8_t devID, uint32_t memSize, uint32_t* eraseBlockSize);
-    
+    void handleI2CInterrupt();    
+
     friend class BiosDisplay;
     friend class BiosTouch;
     friend class DMBoard;
--- a/Bios/bios.h	Fri Jan 23 13:48:44 2015 +0100
+++ b/Bios/bios.h	Fri Jan 23 17:31:56 2015 +0100
@@ -5,7 +5,7 @@
 #include <stdbool.h>
 
 #define BIOS_MAGIC  0xEA0123EA
-#define BIOS_VER      0x000100  // MAJOR.MINOR.BUILD
+#define BIOS_VER      0x000200  // MAJOR.MINOR.BUILD
 #define BIOS_VER_MASK 0xffffff
 
 typedef enum {
@@ -32,11 +32,19 @@
     uint16_t z;
 } touch_coordinate_t;
 
+typedef enum {
+    TOUCH_IRQ_RISING_EDGE,
+    TOUCH_IRQ_FALLING_EDGE,
+    TOUCH_IRQ_HIGH_LEVEL,
+    TOUCH_IRQ_LOW_LEVEL,
+} touch_irq_trigger_t;
+
 typedef void (*delayUsFunc)(int us);
 typedef uint32_t (*readTimeMsFunc)(void);
 
 typedef BiosError_t (*initParamFunc)(void* data, uint32_t SystemCoreClock, uint32_t PeripheralClock, delayUsFunc delay, readTimeMsFunc readMs);
 typedef BiosError_t (*simpleFunc)(void* data);
+typedef BiosError_t (*macFunc)(void* data, char* mac);
 
 typedef BiosError_t (*powerUpFunc)(void* data, void* framebuffer, Resolution_t wanted);
 typedef BiosError_t (*backlightFunc)(void* data, int percent);
@@ -50,10 +58,9 @@
 typedef BiosError_t (*infoFuncT)(void* data,
                                  bool* supportsTouch,
                                  bool* supportsCalibration,
-                                 bool* resistive,
                                  uint8_t* numPoints);
 
-typedef void (*touchIrqFunc)(uint32_t arg, bool enable, bool rising);
+typedef void (*touchIrqFunc)(uint32_t arg, bool enable, touch_irq_trigger_t trigger);
 typedef void (*touchNewDataFunc)(uint32_t arg, touch_coordinate_t* coords, int num);
 typedef BiosError_t (*touchInitFunc)(void* data, 
                                      touchIrqFunc irqEnabler, uint32_t enablerArg, 
@@ -65,6 +72,9 @@
 
 typedef struct {
   initParamFunc initParams;
+  simpleFunc    i2cIRQHandler;
+  spifiFunc     spifiIsSupported;
+  macFunc       ethernetMac;
 
   simpleFunc    displayInit;
   powerUpFunc   displayPowerUp;
@@ -82,9 +92,6 @@
   simpleFunc    touchIrqHandler;
   infoFuncT     touchInformation;
 
-  simpleFunc    touchI2CIRQHandler;
-    
-  spifiFunc     spifiIsSupported;
 } bios_header_t;
 
 typedef struct {
--- a/Display/BiosTouch.cpp	Fri Jan 23 13:48:44 2015 +0100
+++ b/Display/BiosTouch.cpp	Fri Jan 23 17:31:56 2015 +0100
@@ -41,9 +41,8 @@
            _listener(NULL), _lostData(0),
            _dbgAdded(0), _dbgRemoved(0) {}
         void handleTouchInterrupt();
-        void handleI2CInterrupt();
         void handleNewData(touch_coordinate_t* coord, int num);
-        void changeTouchInterrupt(bool enable, bool rising);
+        void changeTouchInterrupt(bool enable, touch_irq_trigger_t trigger);
         TouchPanel::TouchError read(touch_coordinate_t* coord, int num);
         void run();
         FunctionPointer* setListener(FunctionPointer* listener);
@@ -65,19 +64,10 @@
  * Local variables
  *****************************************************************************/
 
-static TouchHandler* theTouchHandler = NULL; // ugly but needed for IRQ
-
 /******************************************************************************
  * Private Functions
  *****************************************************************************/
 
-static void touch_i2c0_irq_handler()
-{
-  if (theTouchHandler != NULL) {
-    theTouchHandler->handleI2CInterrupt();
-  }
-}
-
 BiosTouch::BiosTouch() : 
     _initialized(false),
     _haveInfo(false),
@@ -106,9 +96,9 @@
 }
 
 // Function called from the BIOS
-static void touchIrqEnabler(uint32_t arg, bool enable, bool rising)
+static void touchIrqEnabler(uint32_t arg, bool enable, touch_irq_trigger_t trigger)
 {
-  ((TouchHandler*)arg)->changeTouchInterrupt(enable, rising);
+  ((TouchHandler*)arg)->changeTouchInterrupt(enable, trigger);
 }
 
 // Function called from the BIOS
@@ -192,13 +182,6 @@
   CLR_MEAS_PIN_2();
 }
 
-void TouchHandler::handleI2CInterrupt()
-{
-  SET_MEAS_PIN_3();
-  _bios->touchI2CIRQHandler(_biosData);
-  CLR_MEAS_PIN_3();
-}
-
 void TouchHandler::handleNewData(touch_coordinate_t* coord, int num)
 {
   SET_MEAS_PIN_4();
@@ -215,20 +198,30 @@
   CLR_MEAS_PIN_4();
 }
 
-void TouchHandler::changeTouchInterrupt(bool enable, bool rising)
+void TouchHandler::changeTouchInterrupt(bool enable, touch_irq_trigger_t trigger)
 {
-  if (enable) {
-    if (rising) {
-      _touchIRQ.rise(this, &TouchHandler::handleTouchInterrupt);
-    } else {
-      _touchIRQ.fall(this, &TouchHandler::handleTouchInterrupt);
-    }
-  } else {
-    if (rising) {
-      _touchIRQ.rise(NULL);
-    } else {
-      _touchIRQ.fall(NULL);
-    }
+  switch (trigger) {
+    case TOUCH_IRQ_RISING_EDGE:
+      if (enable) {
+        _touchIRQ.rise(this, &TouchHandler::handleTouchInterrupt);
+      } else {
+        _touchIRQ.rise(NULL);
+      }
+      break;
+
+    case TOUCH_IRQ_FALLING_EDGE:
+      if (enable) {
+        _touchIRQ.fall(this, &TouchHandler::handleTouchInterrupt);
+      } else {
+        _touchIRQ.fall(NULL);
+      }
+      break;
+          
+    case TOUCH_IRQ_HIGH_LEVEL:
+    case TOUCH_IRQ_LOW_LEVEL:
+    default:
+      DMBoard::instance().logger()->printf("BIOS requests unknown trigger type %d\n", trigger);
+      break;
   }
 }
 
@@ -256,7 +249,7 @@
         break;
       }
       
-      result = (TouchError)_bios->touchInformation(_biosData, &_supportsTouch, &_supportsTouchCalibration, &_touchIsResistive, &_touchNumFingers);
+      result = (TouchError)_bios->touchInformation(_biosData, &_supportsTouch, &_supportsTouchCalibration, &_touchNumFingers);
       if (result != TouchError_Ok) {
         break;
       }
@@ -268,10 +261,7 @@
         break;
       }
       
-      NVIC_DisableIRQ(I2C0_IRQn);
-      NVIC_SetVector(I2C0_IRQn, (uint32_t)touch_i2c0_irq_handler);      
-      _handler = theTouchHandler = new TouchHandler(_bios, _biosData, _touchNumFingers);
-      NVIC_EnableIRQ(I2C0_IRQn);
+      _handler = new TouchHandler(_bios, _biosData, _touchNumFingers);
           
       result = (TouchError)_bios->touchInit(_biosData, touchIrqEnabler, (uint32_t)_handler, touchNewData, (uint32_t)_handler);
       if (result != TouchError_Ok) {
@@ -292,7 +282,6 @@
       if (_handler != NULL) {
         delete _handler;
         _handler = NULL;
-        theTouchHandler = NULL;
       }
     }
   }
@@ -327,7 +316,6 @@
   if (!_haveInfo) {
       err = TouchError_NoInit;
   } else {
-    *resistive = _touchIsResistive;
     *maxPoints = _touchNumFingers;
     *calibrated = _supportsTouchCalibration;
   }      
--- a/Display/BiosTouch.h	Fri Jan 23 13:48:44 2015 +0100
+++ b/Display/BiosTouch.h	Fri Jan 23 17:31:56 2015 +0100
@@ -85,7 +85,6 @@
     bool _supportsTouch;
     bool _supportsTouchCalibration;
     uint8_t _touchNumFingers;
-    bool _touchIsResistive;
 
     explicit BiosTouch();
     // hide copy constructor