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
Just a quick hack to get something good looking on the LPC4088DM
/media/uploads/tecnosys/lpc4088dm.jpg
Revision 5:d2f1c9185c5b, committed 2015-04-29
- 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
diff -r 5077afc9f0f4 -r d2f1c9185c5b Graphics.cpp --- /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; + } + } + } + + +
diff -r 5077afc9f0f4 -r d2f1c9185c5b Graphics.h --- /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 + + +
diff -r 5077afc9f0f4 -r d2f1c9185c5b SphereDemo.cpp --- /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); + +} +
diff -r 5077afc9f0f4 -r d2f1c9185c5b SphereDemo.h --- /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 */ +
diff -r 5077afc9f0f4 -r d2f1c9185c5b main.cpp --- 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) {