Content originally posted in LPCWare by rmoss on Thu Jan 31 07:36:07 MST 2013 I have an external Static RAM chip connected to the LPC1788 and when I move the GUI RAM from GUIConf.c to external static RAM, emWin crashes in GUI_Init(). Here is my linker file and GUIConf / LCDConf settings. The same behavior occurs whether I use Muliple Buffering or single buffering.
Linker icf /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x10000000; define symbol __ICFEDIT_region_RAM_end__ = 0x1000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define symbol _AHB_RAM_start__ = 0x20080000; define symbol _AHB_RAM_end__ = 0x200BFFFF; define region AHB_RAM_region = mem:[from _AHB_RAM_start__ to _AHB_RAM_end__];
define symbol _EXT_RAM_start__ = 0x90000000; define symbol _EXT_RAM_end__ = 0x903FFFFF;
define region EXT_RAM_region = mem:[from _EXT_RAM_start__ to _EXT_RAM_end__];
initialize by copy with packing = zeros { readwrite }; do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { section .intvec }; place at address mem:0x2FC { section CRPKEY }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; place in EXT_RAM_region { section VRAM, section GUI_RAM };
GUIConf.c // // Define the available number of bytes available for the GUI // #define GUI_NUMBYTES (1024 * 1024) * 32 // x MByte
// // Define the average block size // #define GUI_BLOCKSIZE 0x80
/********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * GUI_X_Config * * Purpose: * Called during the initialization process in order to set up the * available memory for the GUI. */ void GUI_X_Config(void) { // // Assign memory to emWin // GUI_ALLOC_AssignMemory(_aMemory, GUI_NUMBYTES); GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE); }
LCDConf.c /********************************************************************* * SEGGER Microcontroller GmbH & Co. KG * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 1996 - 2012 SEGGER Microcontroller GmbH & Co. KG * * * * Internet: www.segger.com Support: support@segger.com * * * **********************************************************************
** emWin V5.16 - Graphical user interface for embedded applications ** All Intellectual Property rights in the Software belongs to SEGGER. emWin is protected by international copyright laws. Knowledge of the source code may not be used to write a similar product. This file may only be used in accordance with the following terms:
The software has been licensed to Energy Micro AS whose registered office is situated at Sandakerveien 118, N-0484 Oslo, NORWAY solely for the purposes of creating libraries for Energy Micros ARM Cortex-M3, M4F processor-based devices, sublicensed and distributed under the terms and conditions of the End User License Agreement supplied by Energy Micro AS. Full source code is available at: www.segger.com
We appreciate your understanding and fairness. ---------------------------------------------------------------------- File : LCDConf.c Purpose : Display controller configuration (single layer) ---------------------------END-OF-HEADER------------------------------ */
#ifndef VRAM_ADDR #define VRAM_ADDR 0x90000000 #endif #ifndef XSIZE_PHYS #error Physical X size of display is not defined! #endif #ifndef YSIZE_PHYS #error Physical Y size of display is not defined! #endif #ifndef COLOR_CONVERSION #error Color conversion not defined! #endif #ifndef DISPLAY_DRIVER #error No display driver defined! #endif
/********************************************************************* * * _SetVRAMAddr * * Purpose: * Should set the frame buffer base address */ static void _SetVRAMAddr(void * pVRAM) { LPC_LCD->UPBASE = (uint32_t)pVRAM; }
/********************************************************************* * * _SetOrg * * Purpose: * Should set the origin of the display typically by modifying the * frame buffer base address register */ static void _SetOrg(int xPos, int yPos) { orgx = xPos; orgy = yPos; //LPC_LCD->UPBASE = (uint32_t)(VRAM_ADDR); LPC_LCD->UPBASE = (uint32_t)(VRAM_ADDR + (y * YSIZE_PHYS * PIXEL_WIDTH)); // Needs to be set, before LCDC is enabled }
/********************************************************************* * * Public code * ********************************************************************** */
/* Initialize LCD in Direct mode and touch panel */ void LCD_InitializeLCD(void) { _SetVRAMAddr((void *)(VRAM_ADDR)); _SetOrg(orgx, orgy); }
/* Enable EBI interrupts in core */ NVIC_ClearPendingIRQ(LCD_IRQn); NVIC_EnableIRQ(LCD_IRQn); }
/********************************************************************* * * LCD_X_Config * * Purpose: * Called during the initialization process in order to set up the * display driver configuration. * */ void LCD_X_Config(void) { #if MULTIBUFF GUI_MULTIBUF_Config(NUM_BUFFERS); #endif // // Set display driver and color conversion for 1st layer // GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0); // // Display driver configuration, required for Lin-driver // if (LCD_GetSwapXY()) { LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS); //LCD_SetVSizeEx(0, YSIZE_PHYS, XSIZE_PHYS); } else { LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS); //LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS); } LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR); }
/********************************************************************* * * LCD_X_DisplayDriver * * Purpose: * This function is called by the display driver for several purposes. * To support the according task the routine needs to be adapted to * the display controller. Please note that the commands marked with * 'optional' are not cogently required and should only be adapted if * the display controller supports these features. * * Parameter: * LayerIndex - Index of layer to be configured * Cmd - Please refer to the details in the switch statement below * pData - Pointer to a LCD_X_DATA structure * * Return Value: * < -1 - Error * -1 - Command not handled * 0 - Ok */ int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) { int r;
(void)LayerIndex; /* Unused parameter */
switch (Cmd) { // // Required // case LCD_X_INITCONTROLLER: { // // Called during the initialization process in order to set up the // display controller and put it into operation. If the display // controller is not initialized by any external routine this needs // to be adapted by the customer... // _InitController(); EnableVsyncInterrupt(); return 0; } case LCD_X_SETVRAMADDR: { // // Required for setting the address of the video RAM for drivers // with memory mapped video RAM which is passed in the 'pVRAM' element of p // LCD_X_SETVRAMADDR_INFO * p; p = (LCD_X_SETVRAMADDR_INFO *)pData; _SetVRAMAddr(p->pVRAM); return 0; } case LCD_X_SETORG: { // // Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p // LCD_X_SETORG_INFO * p; p = (LCD_X_SETORG_INFO *)pData; _SetOrg(p->xPos, p->yPos); return 0; }
case LCD_X_ON: { // // Required if the display controller should support switching on and off // return 0; } case LCD_X_OFF: { // // Required if the display controller should support switching on and off // // ... return 0; } case LCD_X_SHOWBUFFER: { pBufferData = (LCD_X_SHOWBUFFER_INFO *)pData; // // Remember buffer index to be used by ISR // pendingFrameIndex = pBufferData->Index; } break;
default: r = -1; } return r; }
/*************************** End of file ****************************/