Demo for Embedded World 2015.
Dependencies: DMBasicGUI DMSupport
Demo running on several LPC4088 Display Modules on the Embedded World 2015 exhibition.
Information
To run the demo first drag-n-drop the to_sync.fs3 file to the MBED drive and then drag-n-drop the demo itself. This way both the file system and software are up to date.
This is what the launcher will look like:
Diff: main.cpp
- Revision:
- 0:6bd24cbb88a1
- Child:
- 1:1a01ef434a72
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Feb 19 13:54:53 2015 +0000 @@ -0,0 +1,461 @@ +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" +#include "mbed_interface.h" +#include "rtos.h" +#include "EthernetInterface.h" +#include "HTTPServer.h" +#include "mbed_rpc.h" +#include "USBHostMSD.h" +#include "USBHostMouse.h" +#include "USBHostKeyboard.h" + +#include "DMBoard.h" + +#include "AppLauncherSpecial.h" +#include "meas.h" + +#include "AppNetworkSettings.h" +#include "AppStatus.h" +#include "AppTouchCalibration.h" +#include "AppColorPicker.h" +#include "AppImageViewer.h" +#include "AppSlideShow.h" +#include "AppRTCSettings.h" +#include "AppUSBStatus.h" +#include "AppDraw.h" +#include "image_data.h" + + +/****************************************************************************** + * Typedefs and defines + *****************************************************************************/ + +/****************************************************************************** + * Local variables + *****************************************************************************/ + +/****************************************************************************** + * Global variables + *****************************************************************************/ + +EthernetInterface eth; +bool ethInitialized = false; +bool ethUsingDHCP = true; +bool haveUSBMSD = false; + +/****************************************************************************** + * Local functions + *****************************************************************************/ + +void aliveTask(void const* args) +{ + DMBoard* board = &DMBoard::instance(); + + while(true) + { + board->setLED(DMBoard::Led4, false); + board->setLED(DMBoard::Led1, true); + Thread::wait(300); + board->setLED(DMBoard::Led1, false); + board->setLED(DMBoard::Led2, true); + Thread::wait(300); + board->setLED(DMBoard::Led2, false); + board->setLED(DMBoard::Led3, true); + Thread::wait(300); + board->setLED(DMBoard::Led3, false); + board->setLED(DMBoard::Led4, true); + Thread::wait(300); + } +} + +#if defined(DM_BOARD_USE_DISPLAY) + +typedef enum { + ColorPickerApp, + ImageViewerApp, + SlideshowApp, + SettingsApp, + StatusApp, + TouchTestApp, + RtcApp, + USBStatusApp, + DrawingApp, + CalibrationApp = AppLauncherSpecial::CalibrationApp, + Placeholder, +} myapps_t; + +static App* launchApp(uint32_t id) +{ + App* a = NULL; + switch ((myapps_t)id) { + case CalibrationApp: + a = new AppTouchCalibration(); + break; + case SettingsApp: + a = new AppNetworkSettings(); + break; + case ColorPickerApp: + a = new AppColorPicker(); + break; + case ImageViewerApp: + a = new AppImageViewer(); + break; + case SlideshowApp: + a = new AppSlideShow("/qspi/slides.txt", "/qspi", 0, 0); + break; + case StatusApp: + a = new AppStatus(); + break; + case RtcApp: + a = new AppRTCSettings(); + break; + case USBStatusApp: + a = new AppUSBStatus(); + break; + case DrawingApp: + a = new AppDraw(); + break; + default: + break; + } + return a; +} + +#define SWIM_TASK_PREFIX "[SWIM] " +void swimTask(void const* args) +{ + RtosLog* log = DMBoard::instance().logger(); + + log->printf(SWIM_TASK_PREFIX"swimTask started\n"); + + AppLauncherSpecial launcher; + + + if (launcher.setup()) { + launcher.addImageButton(SettingsApp, "Network", 0x2d5c, img_super_mono_3d_93, img_size_super_mono_3d_93); + //launcher.addImageButton(Placeholder, "Logo Splash", 0x2d5c, img_super_mono_3d_part2_83, img_size_super_mono_3d_part2_83); + launcher.addImageButton(DrawingApp, "Drawing", 0x2d5c, img_super_mono_3d_22, img_size_super_mono_3d_22); + launcher.addImageButton(SlideshowApp, "Slideshow", 0x2d5c, img_super_mono_3d_87, img_size_super_mono_3d_87); + launcher.addImageButton(ColorPickerApp, "Color Picker", 0x2d5c, img_super_mono_3d_part2_19, img_size_super_mono_3d_part2_19); + launcher.addImageButton(ImageViewerApp, "Image Viewer", 0x2d5c, img_super_mono_3d_48, img_size_super_mono_3d_48); + launcher.addImageButton(StatusApp, "About", 0x2d5c, img_super_mono_3d_part2_68, img_size_super_mono_3d_part2_68); + launcher.addImageButton(USBStatusApp, "USB Status", 0x2d5c, img_super_mono_3d_57, img_size_super_mono_3d_57); + launcher.addImageButton(RtcApp, "Clock", 0x2d5c, img_super_mono_3d_02, img_size_super_mono_3d_02); + + launcher.setAppCreatorFunc(launchApp); + log->printf(SWIM_TASK_PREFIX"Starting menu system\n"); + launcher.runToCompletion(); + launcher.teardown(); + } else { + log->printf(SWIM_TASK_PREFIX"Failed to prepare menu system\n"); + } + + // Should never end up here + mbed_die(); +} + +#endif //DM_BOARD_USE_DISPLAY + + +#define NET_TASK_PREFIX "[NET] " + +void netTask(void const* args) +{ + RtosLog* log = DMBoard::instance().logger(); + log->printf(NET_TASK_PREFIX"EthernetInterface Setting up...\r\n"); + if(eth.init()!=0) { //for DHCP Server + //if(eth.init(IPAddress,NetMasks,Gateway)!=0) { //for Static IP Address + log->printf(NET_TASK_PREFIX"EthernetInterface Initialize Error \r\n"); + mbed_die(); + } + while (eth.connect() != 0) { + Thread::wait(1000); + } + + ethInitialized = true; + ethUsingDHCP = true; + + log->printf(NET_TASK_PREFIX"IP Address is %s\r\n", eth.getIPAddress()); + log->printf(NET_TASK_PREFIX"NetMask is %s\r\n", eth.getNetworkMask()); + log->printf(NET_TASK_PREFIX"Gateway Address is %s\r\n", eth.getGateway()); + log->printf(NET_TASK_PREFIX"Ethernet Setup OK\r\n"); + + HTTPServerAddHandler<SimpleHandler>("/hello"); //Default handler + FSHandler::mount("/usb", "/"); + HTTPServerAddHandler<FSHandler>("/"); + //HTTPServerAddHandler<RPCHandler>("/rpc"); + //lcd.locate(0,0); + //lcd.printf("%s",eth.getIPAddress()); + HTTPServerStart(80); +} + +static volatile int8_t mouse_button, mouse_x, mouse_y, mouse_z; +static uint16_t cursor_x=0, cursor_y=0; +void mouseEvent(uint8_t buttons, int8_t x, int8_t y, int8_t z) +{ + mouse_button = buttons; + mouse_x = x; + mouse_y = y; + mouse_z = z; + + if (x < 0) { + if (cursor_x > -x) { + cursor_x += x; + } else { + cursor_x = 0; + } + } else { + if ((cursor_x + x) >= 480) { + cursor_x = 479; + } else { + cursor_x += x; + } + } + y = y/8; + if (y < 0) { + if (cursor_y > -y) { + cursor_y += y; + } else { + cursor_y = 0; + } + } else { + if ((cursor_y + y) >= 272) { + cursor_y = 271; + } else { + cursor_y += y; + } + } + + //Chip_LCD_Cursor_SetPos(LPC_LCD, cursor_x, cursor_y); + LPC_LCD->CRSR_XY = (cursor_x & 0x3FF) | ((cursor_y & 0x3FF) << 16); +} + +#define LCD_CURSOR_32x32 0 +#define LCD_CURSOR_64x64 1 +#define CURSOR_SIZE LCD_CURSOR_32x32 +#define CURSOR_H_SIZE 32 +#define CURSOR_V_SIZE 32 +#define CURSOR_NUM 0 +#define CURSOR_H_OFS (10) +#define CURSOR_V_OFS (6) + +const unsigned char __attribute__ ((aligned(4))) Cursor[(CURSOR_H_SIZE / 4) * CURSOR_V_SIZE] = +{ + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFF, 0xEA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFB, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA +}; + +void prepareCursor(bool enable) { + //Chip_LCD_Cursor_Disable(LPC_LCD, 0); + LPC_LCD->CRSR_CTRL = (CURSOR_NUM << 4); + + if (enable) { + //Chip_LCD_Cursor_Config(LPC_LCD, LCD_CURSOR_32x32, true); + LPC_LCD->CRSR_CFG = ((true ? 1 : 0) << 1) | CURSOR_SIZE; + + //Chip_LCD_Cursor_WriteImage(LPC_LCD, 0, (void *) Cursor); + { + int i, j; + uint32_t *fifoptr, *crsr_ptr = (uint32_t *) Cursor; + + /* Check if Cursor Size was configured as 32x32 or 64x64*/ + if (CURSOR_SIZE == LCD_CURSOR_32x32) { + i = CURSOR_NUM * 64; + j = i + 64; + } + else { + i = 0; + j = 256; + } + fifoptr = (uint32_t *) &(LPC_LCD->CRSR_IMG[0]); + + /* Copy Cursor Image content to FIFO */ + for (; i < j; i++) { + + *fifoptr = *crsr_ptr; + crsr_ptr++; + fifoptr++; + } + } + + //Chip_LCD_Cursor_SetClip(LPC_LCD, CURSOR_H_OFS, CURSOR_V_OFS); + LPC_LCD->CRSR_CLIP = (CURSOR_H_OFS & 0x3F) | ((CURSOR_V_OFS & 0x3F) << 8); + + //Chip_LCD_Cursor_SetPos(LPC_LCD, cursor_x, cursor_y); + + //Chip_LCD_Cursor_Enable(LPC_LCD, 0); + LPC_LCD->CRSR_CTRL = (CURSOR_NUM << 4) | 1; + } +} + + +#define CIRCBUFF_SIZE 256 +static volatile uint8_t circbuff[CIRCBUFF_SIZE]; +static volatile uint32_t circbuff_read = 0; +static uint32_t circbuff_write = 0; +void keyEvent(uint8_t key) +{ + circbuff[circbuff_write%CIRCBUFF_SIZE] = key; + circbuff_write++; +} + +bool msdConnected = false; +bool keyboardConnected = false; +bool mouseConnected = false; + +#define USB_TASK_PREFIX "[USB] " +#define USB_CONNECTION_EVENT (1<<4) +void usbTask(void const* args) +{ + USBHostMSD* msd = new USBHostMSD("usb"); + USBHostKeyboard* keyboard = new USBHostKeyboard(); + USBHostMouse* mouse = new USBHostMouse(); + USBHost* host = USBHost::getHostInst(); + host->signalOnConnections(Thread::gettid(), USB_CONNECTION_EVENT); + + RtosLog* log = DMBoard::instance().logger(); + + log->printf(USB_TASK_PREFIX"usbTask started\n"); + + prepareCursor(false); + + while (true) { + // wait for connect/disconnect message from USBHost + Thread::signal_wait(USB_CONNECTION_EVENT); + log->printf(USB_TASK_PREFIX"got USB event\n"); + + if (msd->connected()) { + if (!msdConnected) { + msdConnected = true; + haveUSBMSD = true; + log->printf(USB_TASK_PREFIX"USB MassStorage Device - Connected\n"); + } + } else { + if (msdConnected) { + msdConnected = false; + haveUSBMSD = false; + log->printf(USB_TASK_PREFIX"USB MassStorage Device - Ejected\n"); + } + + if (msd->connect()) { + msdConnected = true; + haveUSBMSD = true; + log->printf(USB_TASK_PREFIX"USB MassStorage Device - Connected\n"); + } + } + + if (keyboard->connected()) { + if (!keyboardConnected) { + keyboardConnected = true; + log->printf(USB_TASK_PREFIX"USB Keyboard - Connected\n"); + keyboard->attach(keyEvent); + } + } else { + if (keyboardConnected) { + keyboardConnected = false; + log->printf(USB_TASK_PREFIX"USB Keyboard - Ejected\n"); + } + if (keyboard->connect()) { + keyboardConnected = true; + log->printf(USB_TASK_PREFIX"USB Keyboard - Connected\n"); + keyboard->attach(keyEvent); + } + } + + if (mouse->connected()) { + if (!mouseConnected) { + mouseConnected = true; + log->printf(USB_TASK_PREFIX"USB Mouse - Connected\n"); + mouse->attachEvent(mouseEvent); + prepareCursor(true); + } + } else { + if (mouseConnected) { + prepareCursor(false); + mouseConnected = false; + log->printf(USB_TASK_PREFIX"USB Mouse - Ejected\n"); + } + if (mouse->connect()) { + mouseConnected = true; + log->printf(USB_TASK_PREFIX"USB Mouse - Connected\n"); + mouse->attachEvent(mouseEvent); + prepareCursor(true); + } + } + } +} + + + +/****************************************************************************** + * Main function + *****************************************************************************/ +int main() +{ + DMBoard::BoardError err; + DMBoard* board = &DMBoard::instance(); + RtosLog* log = board->logger(); + err = board->init(); + if (err != DMBoard::Ok) { + log->printf("Failed to initialize the board, got error %d\r\n", err); + log->printf("\nTERMINATING\n"); + wait_ms(2000); // allow RtosLog to flush messages + mbed_die(); + } + + board->buzzer(440,50); + wait_ms(30); + board->buzzer(660,50); + wait_ms(30); + board->buzzer(440,50); + + log->printf("\n\n---\nDemo for Embedded World 2015\nBuilt: " __DATE__ " at " __TIME__ "\n\n"); + + + Thread tAlive(aliveTask); +#if defined(DM_BOARD_USE_DISPLAY) + Thread tSwim(swimTask, NULL, osPriorityNormal, 8192); +#endif + Thread tNetwork(netTask, NULL, osPriorityNormal, 8192); + Thread tUSBHandler(usbTask, NULL, osPriorityNormal, 8192); + + while(1) { + // Wait forever (in 1h increments) to prevent the tAlive, tSwim, + // tNetwork and tUSBHandler thread from being garbage collected. + Thread::wait(3600*1000); + } +} +