Port of the LPC4088 QSB EA LCD Sphere Demo to the LPC4088 DM using the DMSupport lib. Dropping the QSB EALib

Dependencies:   DMBasicGUI DMSupport

Fork of lpc4088_displaymodule_hello_world by Embedded Artists

Just a quick hack to get something good looking on the LPC4088DM

/media/uploads/tecnosys/lpc4088dm.jpg

Files at this revision

API Documentation at this revision

Comitter:
tecnosys
Date:
Wed Apr 29 05:34:03 2015 +0000
Parent:
4:5077afc9f0f4
Commit message:
initial port of EA LCD Demo to DMSupport libs

Changed in this revision

Graphics.cpp Show annotated file Show diff for this revision Revisions of this file
Graphics.h Show annotated file Show diff for this revision Revisions of this file
SphereDemo.cpp Show annotated file Show diff for this revision Revisions of this file
SphereDemo.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphics.cpp	Wed Apr 29 05:34:03 2015 +0000
@@ -0,0 +1,230 @@
+
+#include "mbed.h"
+#include "Graphics.h"
+
+
+Graphics::Graphics(uint16_t *pFrmBuf, uint16_t dispWidth, uint16_t dispHeight)
+{
+	this->windowX = dispWidth;
+	this->windowY = dispHeight;
+	this->pFrmBuf = pFrmBuf;
+}
+
+void Graphics::setFrameBuffer( uint16_t *pFrmBuf )
+{
+	this->pFrmBuf = pFrmBuf;
+}
+
+int32_t Graphics::abs(int32_t v1) const
+{
+   if (v1 > 0)
+     return v1;
+
+  return -v1;
+}
+
+/***********************************************************************
+ *
+ * Function: swim_put_line_raw
+ *
+ * Purpose: Draw a line on the physical display
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win : Window identifier
+ *     x1  : Physical X position of X line start
+ *     y1  : Physical Y position of Y line start
+ *     x2  : Physical X position of X line end
+ *     y2  : Physical Y position of Y line end
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::put_line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int16_t color)
+{
+    int32_t e2, sx, sy, dx, dy, err;
+    
+    /* calculate delta_x and delta_y */
+    dx = abs(x2 - x1);
+    dy = abs(y2 - y1);
+
+    /* set the direction for the step for both x and y, and
+       initialize the error */
+    if (x1 < x2)
+        sx = 1;
+    else
+        sx = -1;
+
+    if (y1 < y2)
+        sy = 1;
+    else
+        sy = -1;
+
+    err = dx - dy;
+   
+    while (1)
+    {
+        if ((x1 >= 0) && (x1 < this->windowX) && 
+            (y1 >= 0) && (y1 < this->windowY))
+            this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+
+        if ((x1 == x2) && (y1 == y2))
+            return;
+
+        e2 = 2 * err;
+        if (e2 > -dy)
+        {
+            err -= dy;
+            x1 += sx;
+        }
+        if (e2 < dx)
+        {
+            err += dx;
+            y1 += sy;
+        }
+    }
+}
+
+/***********************************************************************
+ *
+ * Function: plot4points
+ *
+ * Purpose:
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win    : Window identifier
+ *     cx     :
+ *     cy     :
+ *     x      :
+ *     y      :
+ *     Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::plot4points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled )
+   {
+   int16_t x0, x1, y0, y1;
+
+   y0 = cy + y;
+   y1 = cy - y;
+   if( Filled )
+      {
+      for( x0=cx - x; x0<=cx + x; x0++ )
+         {
+         if ((x0>=0) && (x0<this->windowX) && (y0>=0) && (y0<this->windowY))
+            this->pFrmBuf[x0 + (this->windowX*y0)] = color;
+         if ((x0>=0) && (x0<this->windowX) && (y1>=0) && (y1<this->windowY))
+            this->pFrmBuf[x0 + (this->windowX*y1)] = color;
+         }
+      }
+   else
+      {
+      x0 = cx + x;
+      x1 = cx - x;
+      if ((x0>=0) && (x0<this->windowX) && (y0>=0) && (y0<this->windowY))
+         this->pFrmBuf[x0 + (this->windowX*y0)] = color;
+      if ((x != 0) && 
+          (x1>=0) && (x1<this->windowX) && (y0>=0) && (y0<this->windowY))
+         this->pFrmBuf[x1 + (this->windowX*y0)] = color;
+      if ((y != 0) &&
+          (x0>=0) && (x0<this->windowX) && (y1>=0) && (y1<this->windowY))
+         this->pFrmBuf[x0 + (this->windowX*y1)] = color;
+      if ((x != 0 && y != 0) &&
+          (x1>=0) && (x1<this->windowX) && (y1>=0) && (y1<this->windowY))
+         this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+      }
+   }
+
+/***********************************************************************
+ *
+ * Function: plot8points
+ *
+ * Purpose:
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win    : Window identifier
+ *     cx     :
+ *     cy     :
+ *     x      :
+ *     y      :
+ *     Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::plot8points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled )
+   {
+   plot4points( cx, cy, x, y, color, Filled );
+   if (x != y)
+      plot4points( cx, cy, y, x, color, Filled );
+   }
+
+/***********************************************************************
+ *
+ * Function: swim_put_circle
+ *
+ * Purpose:
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win    : Window identifier
+ *     cx     :
+ *     cy     :
+ *     radius :
+ *     Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::put_circle( int32_t cx, int32_t cy, int16_t color, int32_t radius, int32_t Filled )
+   {
+   int32_t Error = -radius;
+   int16_t x = radius;
+   int16_t y = 0;
+
+   while( x >= y )
+      {
+      plot8points( cx, cy, x, y, color, Filled );
+
+      Error += y;
+      ++y;
+      Error += y;
+
+      if( Error >= 0 )
+         {
+         --x;
+         Error -= x;
+         Error -= x;
+         }
+      }
+   }
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphics.h	Wed Apr 29 05:34:03 2015 +0000
@@ -0,0 +1,29 @@
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+class Graphics {
+public:
+
+	Graphics(uint16_t *pFrmBuf, uint16_t dispWidth, uint16_t dispHeight);
+
+	void setFrameBuffer( uint16_t *pFrmBuf );
+	void put_line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int16_t color);
+    void put_circle( int32_t cx, int32_t cy, int16_t color, int32_t radius, int32_t Filled );
+
+protected:
+	uint16_t windowX;
+	uint16_t windowY;
+	uint16_t *pFrmBuf;
+	
+    int32_t abs(int32_t v1) const;
+    
+    virtual void plot4points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled );
+    void plot8points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled );
+    
+};
+
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SphereDemo.cpp	Wed Apr 29 05:34:03 2015 +0000
@@ -0,0 +1,303 @@
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "mbed.h"
+#include "DMBoard.h"
+//#include "LcdController.h"
+#//include "EaLcdBoard.h"
+#include "SphereDemo.h"
+
+#include <math.h>
+
+/******************************************************************************
+ * Typedefs and defines
+ *****************************************************************************/
+
+#define PI2 6.283185307179586476925286766559
+
+/* Red color mask, 565 mode */
+#define REDMASK       0xF800
+/* Red shift value, 565 mode */
+#define REDSHIFT      11
+/* Green color mask, 565 mode */
+#define GREENMASK     0x07E0
+/* Green shift value, 565 mode */
+#define GREENSHIFT    5
+/* Blue color mask, 565 mode */
+#define BLUEMASK      0x001F
+/* Blue shift value, 565 mode */
+#define BLUESHIFT     0
+
+/* Number of colors in 565 mode */
+#define NUM_COLORS    65536
+/* Number of red colors in 565 mode */
+#define RED_COLORS    0x20
+/* Number of green colors in 565 mode */
+#define GREEN_COLORS  0x40
+/* Number of blue colors in 565 mode */
+#define BLUE_COLORS   0x20
+
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * External variables
+ *****************************************************************************/
+//extern EaLcdBoard lcdBoard;
+    Display* _disp;
+extern bool abortTest;
+
+/******************************************************************************
+ * Local functions
+ *****************************************************************************/
+
+uint16_t SphereDemo::fastsqrt(uint32_t n) const {
+ uint16_t c = 0x8000;
+ uint16_t g = 0x8000;
+ for(;;) {
+  if(g*g > n)
+   g ^= c;
+  c >>= 1;
+  if(c == 0)
+   return g;
+  g |= c;
+ }
+}
+
+void SphereDemo::matrix(int16_t xyz[3][N], uint8_t rgb[3][N]) {
+ static uint32_t t = 0;
+ uint16_t i;
+ int16_t x = -SCALE;
+ int16_t y = -SCALE;
+ uint16_t d;
+ uint16_t s;
+
+ for(i = 0; i < N; i++) {
+
+  xyz[0][i] = x;
+  xyz[1][i] = y;
+
+  d = fastsqrt(x * x + y * y);
+  s = sine[(t * 30) % SCALE] + SCALE;
+
+  xyz[2][i] = sine[(d + s) % SCALE] *
+              sine[(t * 10) % SCALE] / SCALE / 2;
+
+  rgb[0][i] = (cosi[xyz[2][i] + SCALE / 2] + SCALE) *
+              (RED_COLORS - 1) / SCALE / 2;
+
+  rgb[1][i] = (cosi[(xyz[2][i] + SCALE / 2 + 2 * SCALE / 3) % SCALE] + SCALE) *
+              (GREEN_COLORS - 1) / SCALE / 2;
+
+  rgb[2][i] = (cosi[(xyz[2][i] + SCALE / 2 + SCALE / 3) % SCALE] + SCALE) *
+              (BLUE_COLORS - 1) / SCALE / 2;
+
+  x += INCREMENT;
+  if(x >= SCALE) {
+   x = -SCALE;
+   y += INCREMENT;
+  }
+
+ }
+ t++;
+}
+
+void SphereDemo::rotate(int16_t xyz[3][N], uint8_t rgb[3][N],
+                   uint16_t angleX, uint16_t angleY, uint16_t angleZ) {
+ uint16_t i;
+ int16_t tmpX;
+ int16_t tmpY;
+ int16_t sinx = sine[angleX];
+ int16_t cosx = cosi[angleX];
+ int16_t siny = sine[angleY];
+ int16_t cosy = cosi[angleY];
+ int16_t sinz = sine[angleZ];
+ int16_t cosz = cosi[angleZ];
+
+ for(i = 0; i < N; i++) {
+  tmpX      = (xyz[0][i] * cosx - xyz[2][i] * sinx) / SCALE;
+  xyz[2][i] = (xyz[0][i] * sinx + xyz[2][i] * cosx) / SCALE;
+  xyz[0][i] = tmpX;
+
+  tmpY      = (xyz[1][i] * cosy - xyz[2][i] * siny) / SCALE;
+  xyz[2][i] = (xyz[1][i] * siny + xyz[2][i] * cosy) / SCALE;
+  xyz[1][i] = tmpY;
+
+  tmpX      = (xyz[0][i] * cosz - xyz[1][i] * sinz) / SCALE;
+  xyz[1][i] = (xyz[0][i] * sinz + xyz[1][i] * cosz) / SCALE;
+  xyz[0][i] = tmpX;
+ }
+}
+
+void SphereDemo::draw(int16_t xyz[3][N], uint8_t rgb[3][N]) {
+// static uint16_t oldProjX[N] = {0};
+// static uint16_t oldProjY[N] = {0};
+// static uint8_t oldDotSize[N] = {0};
+ uint16_t i;
+ uint16_t projX;
+ uint16_t projY;
+ uint16_t projZ;
+ uint16_t dotSize;
+ static uint8_t cnt=0;
+
+  if (cnt == 0)
+  {
+    cnt = 1;
+    pFrmBuf = pFrmBuf1;
+  }
+  else if (cnt == 1)
+  {
+    cnt = 2;
+    pFrmBuf = pFrmBuf2;
+  }
+  else
+  {
+    cnt = 0;
+    pFrmBuf = pFrmBuf3;
+  }
+  
+  graphics.setFrameBuffer(pFrmBuf);
+
+  memset((void*)(pFrmBuf), 0x00, windowX * windowY * 2);
+
+ for(i = 0; i < N; i++) {
+  projZ   = SCALE - (xyz[2][i] + SCALE) / 4; //4;
+  projX   = windowX / 2 + (xyz[0][i] * projZ / SCALE) / 40; //EA 25;
+  projY   = windowY / 2 + (xyz[1][i] * projZ / SCALE) / 40; //EA 25;
+  dotSize = 3 - (xyz[2][i] + SCALE) * 2 / SCALE;
+//EA  put_circle(oldProjX[i], oldProjY[i], 0, dotSize, 1);
+
+  if((projX > dotSize) &&
+     (projY > dotSize) &&
+     (projX < (windowX - dotSize)) &&
+     (projY < (windowY - dotSize))) {
+
+   graphics.put_circle(projX, projY, (rgb[0][i] << REDSHIFT) + (rgb[1][i] << GREENSHIFT) + (rgb[2][i] << BLUESHIFT), dotSize, 1);
+
+//   oldProjX[i] = projX;
+//   oldProjY[i] = projY;
+//   oldDotSize[i] = dotSize;
+  }
+ }
+}
+
+
+
+/******************************************************************************
+ * Public functions
+ *****************************************************************************/
+SphereDemo::SphereDemo(void *pFrameBuf, int dispWidth, int dispHeight) 
+    : graphics((uint16_t *)pFrameBuf, dispWidth, dispHeight)
+{
+    this->windowX = dispWidth;
+    this->windowY = dispHeight;
+    this->pFrmBuf  = (uint16_t *)pFrameBuf;
+    this->pFrmBuf1 = (uint16_t *)pFrameBuf;
+    this->pFrmBuf2 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*2);
+    this->pFrmBuf3 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*4);
+
+    for(uint16_t i = 0; i < SCALE; i++) {
+        sine[i] = (int)(sin(PI2 * i / SCALE) * SCALE);
+        cosi[i] = (int)(cos(PI2 * i / SCALE) * SCALE);
+    }
+}
+
+void SphereDemo::run(uint32_t loops, uint32_t delayMs)
+{
+  printf("SphereDemo, %d loops, %dms delay\n", loops, delayMs);
+  
+    int16_t angleX = 0;
+    int16_t angleY = 1000;
+    int16_t angleZ = 0;
+    
+    int16_t speedX = 0;
+    int16_t speedY = 0;
+    int16_t speedZ = 0;
+    
+    int16_t xyz[3][N];
+    uint8_t rgb[3][N];
+    
+    loops = 2*820;
+  for(int32_t n=0;n<loops;n++) {
+
+   matrix(xyz, rgb);
+
+   rotate(xyz, rgb, angleX, angleY, angleZ);
+
+   draw(xyz, rgb);
+  //update framebuffer
+  _disp = DMBoard::instance().display();
+  
+  _disp->swapFramebuffer(this->pFrmBuf);
+  //lcdBoard.setFrameBuffer((uint32_t)this->pFrmBuf);
+
+#if 0
+   if(joyState & JOYSTICK_RIGHT)
+    speedX -= SPEED;
+   else if(joyState & JOYSTICK_LEFT)
+    speedX += SPEED;
+   else if(joyState & JOYSTICK_UP)
+    speedY -= SPEED;
+   else if(joyState & JOYSTICK_DOWN)
+    speedY += SPEED;
+   else if(ledState & KEY1)
+    speedZ -= SPEED;
+   else if(ledState & KEY2)
+    speedZ += SPEED;
+   else if(ledState & KEY3) {
+    speedX = 0;
+    speedY = 0;
+    speedZ = 0;
+    angleX = 0;
+    angleY = 0;
+    angleZ = 0;
+   } else
+#endif
+    {
+    if(speedX > 0)
+     speedX -= SPEED;
+    else if(speedX < 0)
+     speedX += SPEED;
+
+    if(speedY > 0)
+     speedY -= SPEED;
+    else if(speedY < 0)
+     speedY += SPEED;
+
+    if(speedZ > 0)
+     speedZ -= SPEED;
+    else if(speedZ < 0)
+     speedZ += SPEED;
+   }
+
+   angleX += 0; //speedX;
+   angleY += 0; //speedY;
+   angleZ += 2; //speedZ;
+
+   if(angleX >= SCALE)
+    angleX -= SCALE;
+   else if(angleX < 0)
+    angleX += SCALE;
+
+   if(angleY >= SCALE)
+    angleY -= SCALE;
+   else if(angleY < 0)
+    angleY += SCALE;
+
+   if(angleZ >= SCALE)
+    angleZ -= SCALE;
+   else if(angleZ < 0)
+    angleZ += SCALE;
+   
+    if (abortTest) {
+      return;
+    }   
+  }
+//wait_ms(delayMs);
+   wait_ms(1000);
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SphereDemo.h	Wed Apr 29 05:34:03 2015 +0000
@@ -0,0 +1,63 @@
+
+#ifndef SPHEREDEMO_H
+#define SPHEREDEMO_H
+
+#include "Graphics.h"
+//#include "GFXFb.h"
+
+class SphereDemo {
+public:
+
+    /** Set the address of the frame buffer to use.
+     *
+     *  It is the content of the frame buffer that is shown on the
+     *  display. All the drawing on the frame buffer can be done
+     *  'offline' and whenever it should be shown this function
+     *  can be called with the address of the offline frame buffer.
+     *
+     *  @param pFrameBuf  Pointer to the frame buffer, which must be
+     *                    3 times as big as the frame size (for tripple
+     *                    buffering).
+     *         dispWidth  The width of the display (in pixels).
+     *         dispHeight The height of the display (in pixels).
+     *         loops      Number of loops in the demo code.
+     *         delayMs    Delay in milliseconds between schreen updates.
+     *
+     *  @returns
+     *       none
+     */
+    SphereDemo(void *pFrameBuf, int dispWidth, int dispHeight);
+    
+    void run(uint32_t loops, uint32_t delayMs);
+
+private:
+
+    enum Constants {
+        N         = 1024, // Number of dots
+        SCALE     = 8192,
+        INCREMENT = 512,  // INCREMENT = SCALE / sqrt(N) * 2
+        SPEED     = 5
+    };
+
+    int32_t windowX;
+    int32_t windowY;
+    uint16_t *pFrmBuf;
+    uint16_t *pFrmBuf1;
+    uint16_t *pFrmBuf2;
+    uint16_t *pFrmBuf3;
+    
+    Graphics graphics;
+    //Display* _disp;
+
+    
+    int16_t sine[SCALE];
+    int16_t cosi[SCALE];
+    
+    uint16_t fastsqrt(uint32_t n) const;
+    void matrix(int16_t xyz[3][N], uint8_t rgb[3][N]);
+    void rotate(int16_t xyz[3][N], uint8_t rgb[3][N], uint16_t angleX, uint16_t angleY, uint16_t angleZ);
+    void draw(int16_t xyz[3][N], uint8_t rgb[3][N]);
+};
+
+#endif /* SPHEREDEMO_H */
+
--- a/main.cpp	Fri Mar 20 14:22:33 2015 +0000
+++ b/main.cpp	Wed Apr 29 05:34:03 2015 +0000
@@ -1,14 +1,19 @@
 #include "mbed.h"
 #include "DMBoard.h"
-#include "lpc_swim.h"
-#include "lpc_swim_font.h"
+//#include "lpc_swim.h"
+//#include "lpc_swim_font.h"
+#include "SphereDemo.h"
+
+bool abortTest;
 
 int main()
 {
+  
   DMBoard::BoardError err;
   DMBoard* board = &DMBoard::instance();
   RtosLog* log = board->logger();
   Display* disp = board->display();
+  abortTest=false;
   
   do {
     err = board->init();
@@ -17,9 +22,9 @@
       break;
     }
     
-    log->printf("\n\nHello World!\n\n");
+    //log->printf("\n\nHello World!\n\n");
     
-    SWIM_WINDOW_T win;
+   // SWIM_WINDOW_T win;
     void* fb = disp->allocateFramebuffer();
     if (fb == NULL) {
       log->printf("Failed to allocate memory for a frame buffer\r\n");
@@ -27,24 +32,23 @@
       break;
     }
     
-    // Prepare fullscreen
-    swim_window_open(&win, 
-                     disp->width(), disp->height(),         // full size
-                     (COLOR_T*)fb,
-                     0,0,disp->width()-1, disp->height()-1, // window position and size
-                     1,                                     // border
-                     WHITE, BLUE, BLACK);                   // colors: pen, backgr, forgr
-    swim_set_title(&win, "My Program", BLACK);
-  
-    // Message
-    swim_put_text_xy(&win, "Hello World!", 100, 100);
-    
+ 
     // Start display in default mode (16-bit)
     Display::DisplayError disperr = disp->powerUp(fb);
     if (disperr != Display::DisplayError_Ok) {
       log->printf("Failed to initialize the display, got error %d\r\n", disperr);
       break;
     }
+    
+    
+//memset((void*)fb, 0x0, lcdCfg.width*lcdCfg.height*2 *3);
+
+        SphereDemo sphereDemo(fb, disp->width(), disp->height());//(uint8_t *)frameBuf1
+        while (1) {
+            sphereDemo.run(750, 50);
+            //.RESET_FLAG;
+        }
+    
   } while(false);
 
   if (err != DMBoard::Ok) {