A simple example using a display and networking at the same time.
Dependencies: EALib EthernetInterface mbed-rtos mbed
Revision 0:833824a40ced, committed 2014-07-21
- Comitter:
- embeddedartists
- Date:
- Mon Jul 21 09:42:16 2014 +0000
- Commit message:
- Very basic example of using display and networking at the same time.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BubbleDemo.cpp Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,187 @@ +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" + +#include "LcdController.h" +#include "EaLcdBoard.h" +#include "BubbleDemo.h" + +#include "wchar.h" + +/****************************************************************************** + * Typedefs and defines + *****************************************************************************/ + +#define PI 3.1415926535897932384626433832795 + +/* 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; +extern bool abortTest; + +/****************************************************************************** + * Local functions + *****************************************************************************/ + + +void BubbleDemo::initialize() { + float radian; + const float phase1 = 2 * PI / 3; + const float phase2 = 4 * PI / 3; + + for(i = 0; i < NumBalls; i++) { + x[i] = this->windowX / 2; + y[i] = this->windowY / 2; + r[i] = i * 2 + 10; + + oldX[i] = x[i]; + oldY[i] = y[i]; + + velX[i] = 1; + velY[i] = 1; + + radian = i * 2 * PI / NumBalls; + red[i] = cos(radian) * RED_COLORS / 2 + (RED_COLORS / 2 - 1); + green[i] = cos(radian + phase2) * GREEN_COLORS / 2 + (GREEN_COLORS / 2 - 1); + blue[i] = cos(radian + phase1) * BLUE_COLORS / 2 + (BLUE_COLORS / 2 - 1); + } +} + +void BubbleDemo::collision() { + float disX = x[j] - x[i]; + float disY = y[j] - y[i]; + float d2 = disX * disX + disY * disY; + + if(d2 != 0) { + float rij = r[i] + r[j]; + float rij2 = rij * rij; + + if(d2 < rij2) { + float ii = (disX * velX[i] + disY * velY[i]) / d2; + float ji = (disX * velY[i] - disY * velX[i]) / d2; + float ij = (disX * velX[j] + disY * velY[j]) / d2; + float jj = (disX * velY[j] - disY * velX[j]) / d2; + float ratio = rij / sqrt(d2); + + velX[i] = ij * disX - ii * disY; + velY[i] = ij * disY + ii * disX; + velX[j] = ji * disX - jj * disY; + velY[j] = ji * disY + jj * disX; + + disX *= (ratio - 1) / 2; + disY *= (ratio - 1) / 2; + + x[j] += disX; + y[j] += disY; + x[i] -= disX; + y[i] -= disY; + } + } +} + +void BubbleDemo::borders() { + if(x[i] >= this->windowX - r[i] - 1) { + x[i] = this->windowX - r[i] - 1; + velX[i] = -velX[i]; + } else if(x[i] <= r[i]) { + x[i] = r[i]; + velX[i] = -velX[i]; + } + + if(y[i] >= this->windowY - r[i] - 1) { + y[i] = this->windowY - r[i] - 1; + velY[i] = -velY[i]; + } else if(y[i] <= r[i]) { + y[i] = r[i]; + velY[i] = -velY[i]; + } +} + +void BubbleDemo::draw() { + graphics.put_circle( oldX[i], oldY[i], 0, r[i], 0 ); + graphics.put_circle( x[i], y[i], (red[i] << REDSHIFT) + (green[i] << GREENSHIFT) + (blue[i] << BLUESHIFT), r[i], 0); + + oldX[i] = x[i]; + oldY[i] = y[i]; +} + + +/****************************************************************************** + * Public functions + *****************************************************************************/ + +BubbleDemo::BubbleDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t 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); + + initialize(); +} + +void BubbleDemo::run(uint32_t loops, uint32_t delayMs) { + + printf("BubbleDemo, %d loops, %dms delay\n", loops, delayMs); + + //update framebuffer + graphics.setFrameBuffer(this->pFrmBuf); + lcdBoard.setFrameBuffer((uint32_t)this->pFrmBuf); + memset((void*)(pFrmBuf), 0, this->windowX * this->windowY * 2); + + for(int32_t n=0;n<loops;n++) { + + for(i = 0; i < NumBalls; i++) { + x[i] += velX[i]; + y[i] += velY[i]; + + for(j = i + 1; j < NumBalls; j++) + collision(); + + borders(); + + if((int)x[i] != (int)oldX[i] || (int)y[i] != (int)oldY[i]) + draw(); + } + if (abortTest) { + break; + } + + wait_ms(delayMs); + } + memset((void*)(pFrmBuf), 0, this->windowX * this->windowY * 2); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BubbleDemo.h Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,71 @@ + +#ifndef BUBBLEDEMO_H +#define BUBBLEDEMO_H + +#include "Graphics.h" + +class BubbleDemo { +public: + + enum Constants { + NumBalls = 17 + }; + + /** 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 + */ + BubbleDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t dispHeight); + + void run(uint32_t loops, uint32_t delayMs); + +private: + int32_t windowX; + int32_t windowY; + uint16_t *pFrmBuf; + uint16_t *pFrmBuf1; + uint16_t *pFrmBuf2; + uint16_t *pFrmBuf3; + + Graphics graphics; + + uint8_t i; + uint8_t j; + + float x[NumBalls]; + float y[NumBalls]; + uint8_t r[NumBalls]; + + float oldX[NumBalls]; + float oldY[NumBalls]; + + float velX[NumBalls]; + float velY[NumBalls]; + + uint8_t red[NumBalls]; + uint8_t green[NumBalls]; + uint8_t blue[NumBalls]; + + + void initialize(); + void collision(); + void borders(); + void draw(); +}; + +#endif /* BUBBLEDEMO_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EALib.lib Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/embeddedartists/code/EALib/#d868b74fd08e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#e6b79f0ccd95
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Graphics.cpp Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,229 @@ + +#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 Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,28 @@ + +#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/main.cpp Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,164 @@ +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" + +#include "LcdController.h" +#include "EaLcdBoard.h" +#include "sdram.h" + +#include "BubbleDemo.h" +#include "EthernetInterface.h" +#include "TCPSocketConnection.h" +#include "cmsis_os.h" + + +/****************************************************************************** + * Typedefs and defines + *****************************************************************************/ + +#define RESET_FLAG \ + do { \ + if (abortTest) { \ + abortTest = false; \ + wait(0.04); \ + } \ + } while(false) + +/****************************************************************************** + * Local variables + *****************************************************************************/ + +static InterruptIn buttonInterrupt(P2_10); +static DigitalOut led(LED1); +static DigitalOut led3(LED3); + +static BubbleDemo* bubbleDemo; + +/****************************************************************************** + * Global variables + *****************************************************************************/ + +EaLcdBoard lcdBoard(P0_27, P0_28); +bool abortTest = false; + +/****************************************************************************** + * Interrupt functions + *****************************************************************************/ + +void trigger() { + abortTest = true; +} + +/****************************************************************************** + * Main + *****************************************************************************/ + +void bubble_thread(void const *argument) { + while (true) { + bubbleDemo->run(750, 20); + RESET_FLAG; + } +} +void net_thread(void const *argument) { + EthernetInterface eth; + eth.init(); //Use DHCP + eth.connect(); + printf("IP Address is %s\n", eth.getIPAddress()); + TCPSocketConnection sock; + while (true) { + led3 = !led3; + sock.connect("mbed.org", 80); + sock.set_blocking(false, 3000); + + char http_cmd[] = "GET /media/uploads/donatien/hello.txt HTTP/1.1\r\nHost: %s\r\n\r\n"; + printf("sending:\n---\n%s\n---\n", http_cmd); + sock.send(http_cmd, sizeof(http_cmd) - 1);//, 3000); + + char in_buf[256]; + bool firstIteration = true; + int ret; + do { + printf("reading...\n"); + ret = sock.receive(in_buf, 255);//, firstIteration?3000:0); + in_buf[ret] = '\0'; + + printf("Received %d chars from server: %s\n", ret, in_buf); + firstIteration = false; + } while ( ret == 255 ); // once we get less that full buffer we know all data has been received +// } while ( ret > 0 ); + + sock.close(); + + //eth.disconnect(); + + led3 = !led3; + osDelay(500); + } +} + +osThreadDef(bubble_thread, osPriorityNormal, DEFAULT_STACK_SIZE); +osThreadDef(net_thread, osPriorityNormal, DEFAULT_STACK_SIZE); + +int main (void) { + + EaLcdBoard::Result result; + LcdController::Config lcdCfg; + uint32_t frameBuf1 = (uint32_t) SDRAM_BASE; + + printf("Simple example of using network (HTTP GET) and LCD at the same time\n"); + + // Listen for button presses + buttonInterrupt.mode(PullUp); + buttonInterrupt.fall(&trigger); + + do { + // framebuffer is put in SDRAM + if (sdram_init() == 1) { + printf("Failed to initialize SDRAM\n"); + break; + } + + result = lcdBoard.open(NULL, NULL); + if (result != EaLcdBoard::Ok) { + printf("Failed to open display: %d\n", result); + break; + } + + result = lcdBoard.setFrameBuffer(frameBuf1); + if (result != EaLcdBoard::Ok) { + printf("Failed to activate frameBuffer: %d\n", result); + break; + } + + result = lcdBoard.getLcdConfig(&lcdCfg); + if (result != EaLcdBoard::Ok) { + printf("Failed to get LCD configuration: %d\n", result); + break; + } + + // Prepare 3 consequtive framebuffers (2 will be used for background buffers) + memset((void*)frameBuf1, 0x0, lcdCfg.width*lcdCfg.height*2 *3); + + bubbleDemo = new BubbleDemo((uint8_t *)frameBuf1, lcdCfg.width, lcdCfg.height); + osThreadCreate(osThread(bubble_thread), NULL); + + osThreadCreate(osThread(net_thread), NULL); + + while (true) { + led = 0; + wait(0.1); + led = 1; + wait(0.5); + } + } while(0); + + // Blink to indicate error + while (1) { + led = 0; + wait(0.2); + led = 1; + wait(0.2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#ff95651f53c7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jul 21 09:42:16 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/04dd9b1680ae \ No newline at end of file