/* ---------------------------------------------------------------------------- * ATMEL Microcontroller Software Support * ---------------------------------------------------------------------------- * Copyright (c) 2008, Atmel Corporation * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Atmel's name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ---------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include "dfm_cmd.h" #include "dfm_lcd_tsd.h" #include "dfm_dispboxmgr.h" #include "dfm_config.h" #include "dfm_it.h" #include "dfm_init.h" #include "dfm_fatfs.h" #include "dfm_entry.h" #include "dfm_varloc.h" //global LCD prompt display register entry variable TInputEntry gLCDEntry = {0, {NULL,NULL},LCD_ShowPrompt, TSD_CommandIsReady, TSD_GetCommand, NULL}; #define GLOBALSLIDEINFO #if defined(GLOBALSLIDEINFO) ///active for slide information RLOC_OBJ SlideINFOHeader gActiveSlideHeader _AT(ACTIVESLIDE_INFOHEAD_ADDR); #endif ///lcd refresh show flag unsigned int gLcdRefreshFlag = 0; ///current slide index shown on LCD ///the init value is the first slide after program start up. unsigned short gActiveSlideIndex = 0; /// active demo bin max slides static unsigned int gActiveBinSlideCount = 0xffffffff; /// point to the active demo bin file name const char * gpActiveBinFile = LCDSLIDEIMAGEFILE; /// used in system tick count volatile unsigned int gTimeStamp = 0; /// Coordinates at which the pen was last pressed. static volatile unsigned int gTSDxPressed; static volatile unsigned int gTSDyPressed; static volatile unsigned char gTSDPressed = 0; /// link string index for hot zone hitted, starting from 1, 0 means not hitted static unsigned int gLinkIndex = 0; ///Flash1 start address to store demo bin in at91sam3u4 #define gDemoBinAddrInFlash 0x108000 //file buffer used to read bitmap data #if defined(__CC_ARM) || defined(__ICCARM__)//up to now, KEIL AND IAR supported RLOC_OBJ static unsigned char gpFileBuffer[FILE_BUF_SIZE] _AT(FILE_BUFFER_ADDR); #endif #if defined(BOARD_PSRAM_PINS) #if defined(__GNUC__) && !defined(__CC_ARM) static unsigned char *gpFileBuffer = (unsigned char *) (BOARD_EBI_PSRAM + 0xa0000); #endif //PSRAM init entry int Psram_Init(void) { printf("\n\r Init Psram"); BOARD_ConfigurePsram(); return 0; } //init psram in level 5 //lvl5_init(Psram_Init); DFM_INIT(5, Psram_Init); #elif defined(PINS_SDRAM) #if defined(__GNUC__) && !defined(__CC_ARM) static unsigned char *gpFileBuffer = (unsigned char *) (AT91C_EBI_SDRAM+ 0xa0000); #endif //SDRAM init entry int Sdram_Init(void) { printf("\n\r Init Sdram"); BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH); } //init sdram in level 5 //lvl5_init(Psram_Init); DFM_INIT(5, Sdram_Init); #elif defined(PINGS_DDRAM) #if defined(__GNUC__) && !defined(__CC_ARM) static unsigned char *gpFileBuffer = (unsigned char *) (AT91C_EBI_SDRAM); #endif //ddram init entry int Ddram_Init(void) { printf("\n\r Init Ddram"); //configure DDRAM for use BOARD_ConfigureDdram(0, BOARD_DDRAM_BUSWIDTH); } //init ddram in level 5 //lvl5_init(Psram_Init); DFM_INIT(5, Ddram_Init); #else #define USE_SRAM_BUF #define BUF_LEN_SRAM 1024 #endif ////////////////////////// ///LCD prompt display / ////////////////////////// #if defined(USE_LCD_TSD) #if defined(LCDC_HX8347) //USE hx8347 controller //------------------------------------------------------------------------------ /// Handler for SysTick interrupt. Increments the timestamp counter. //------------------------------------------------------------------------------ void SysTick_HandlerLcdTsd(void) { gTimeStamp++; // Call TSD_TimerHandler per 10ms if ((gTimeStamp % 10) == 0) { TSD_TimerHandler(); } } #if defined(USE_IT_CHAIN_MGR) TDFM_ItServList gSysTkItHandlerLcdTsd = {SysTick_IRQn, SysTick_HandlerLcdTsd, NULL}; #endif //------------------------------------------------------ /// Init LCD controller of 8347 //------------------------------------------------------ int LCD_Init() { printf("\n\r LCD init in Level 5"); // 1ms tick, in driver, a wait is called. SysTick_Configure(1, BOARD_MCK/1000, SysTick_HandlerLcdTsd); #if defined(USE_IT_CHAIN_MGR) DFM_RegisterItHandler(&gSysTkItHandlerLcdTsd); #endif // Initialize LCD LCDD_Initialize(); LCDD_Fill((void *)BOARD_LCD_BASE, COLOR_WHITE); LCDD_Start(); return 0; } #else //use internal LCD controller //------------------------------------------------------ /// Init LCD controller of 8347 //------------------------------------------------------ int LCD_Init() { // Enable peripheral clock AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_LCDC; #if defined(at91sam9g10)||defined(at91sam9261) AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_HCK1; #endif // Disable the LCD and the DMA LCD_DisableDma(); LCD_Disable(0); // Configure the LCD controller LCD_SetPixelClock(BOARD_MCK, BOARD_LCD_PIXELCLOCK); LCD_SetDisplayType(BOARD_LCD_DISPLAYTYPE); LCD_SetScanMode(AT91C_LCDC_SCANMOD_SINGLESCAN); LCD_SetBitsPerPixel(BOARD_LCD_BPP); LCD_SetPolarities(BOARD_LCD_POLARITY_INVVD, BOARD_LCD_POLARITY_INVFRAME, BOARD_LCD_POLARITY_INVLINE, BOARD_LCD_POLARITY_INVCLK, BOARD_LCD_POLARITY_INVDVAL); LCD_SetClockMode(BOARD_LCD_CLOCKMODE); LCD_SetMemoryFormat((unsigned int) AT91C_LCDC_MEMOR_LITTLEIND); LCD_SetSize(BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT); // Configure timings LCD_SetVerticalTimings(BOARD_LCD_TIMING_VFP, BOARD_LCD_TIMING_VBP, BOARD_LCD_TIMING_VPW, BOARD_LCD_TIMING_VHDLY); LCD_SetHorizontalTimings(BOARD_LCD_TIMING_HBP, BOARD_LCD_TIMING_HPW, BOARD_LCD_TIMING_HFP); // Configure contrast (TODO functions) LCD_SetContrastPrescaler(AT91C_LCDC_PS_NOTDIVIDED); LCD_SetContrastPolarity(AT91C_LCDC_POL_POSITIVEPULSE); LCD_SetContrastValue(0x80); LCD_EnableContrast(); // Configure DMA LCD_SetFrameSize(BOARD_LCD_FRAMESIZE); LCD_SetBurstLength(4); // Set frame buffer LCD_SetFrameBufferAddress(images[0]); // Enable DMA and LCD LCD_EnableDma(); LCD_Enable(0x0C); } #endif //lvl5_init(LCD_Init); DFM_INIT(5, LCD_Init); //------------------------------------------------------------------------------ /// Delay millisecond. Use SysTick interrupt for function implement, so ensure /// the SysTick interrupt is enabled before using this function. /// \param ms millisecond to be delay //------------------------------------------------------------------------------ void DelayMS(unsigned int ms) { unsigned int st = gTimeStamp; while (gTimeStamp - st < ms); } //------------------------------------------------------------------------------ /// Callback called when the pen is pressed on the touchscreen /// /param horizontal position (in pixel if ts calibrated) /// /param vertical position (in pixel if ts calibrated) //------------------------------------------------------------------------------ void TSD_PenPressed(unsigned int x, unsigned int y) { //printf("Pen pressed at (%03u, %03u)\n\r", x, y); // Save the coordinates for use by TSD_PenReleased gTSDxPressed = x; gTSDyPressed = y; TSD_SetTouched(); } //------------------------------------------------------------------------------ /// Callback called when the pen is moved on the touchscreen /// /param horizontal position (in pixel if ts calibrated) /// /param vertical position (in pixel if ts calibrated) //------------------------------------------------------------------------------ void TSD_PenMoved(unsigned int x, unsigned int y) { // printf("Pen moved at (%03u, %03u)\n\r", x, y); } //------------------------------------------------------------------------------ /// Callback called when the touchscreen is released on the touchscreen /// /param horizontal position (in pixel if ts calibrated) /// /param vertical position (in pixel if ts calibrated) //------------------------------------------------------------------------------ void TSD_PenReleased(unsigned int x, unsigned int y) { } //------------------------------------------------------------------------------ /// Get last pen press position /// /param point to horizontal position (in pixel if ts calibrated) /// /param point vertical position (in pixel if ts calibrated) //------------------------------------------------------------------------------ void TSD_GetPenLastPosition(unsigned int *pX, unsigned int *pY) { *pX = gTSDxPressed; *pY = gTSDyPressed; } //--------------------------------------------- /// init touchscreen //--------------------------------------------- int TSD_Init() { printf("\n\r Init TouchScreen"); gTSDxPressed = gTSDyPressed = 0; #if defined(at91sam3u4) // Internal Flash1 #define IFLASH1 (0x100000) #define IFLASH1_SIZE (0x20000) #define IFLASH1_PAGE_SIZE (256) // Internal FLASH 1 Page Size: 256 bytes #define IFLASH1_NB_OF_PAGES (512) // Internal FLASH 1 Number of Pages: 512 #define IFLASH1_LOCK_REGION_SIZE (8192) // Internal FLASH 1 Lock Region Size: 8 Kbytes #define IFLASH1_NB_OF_LOCK_BITS (16) // Internal FLASH 1 Number of Lock Bits: 16 unsigned char error; unsigned int pBuffer[IFLASH1_PAGE_SIZE / 4]; unsigned int lastPageAddress; volatile unsigned int *pLastPageData; // Read touch screen calibration data // Initialize flash driver FLASHD_Initialize(BOARD_MCK); // Calibration data are stored on last page lastPageAddress = IFLASH1 + IFLASH1_SIZE - IFLASH1_PAGE_SIZE; pLastPageData = (volatile unsigned int *) lastPageAddress; TSDCom_RestoreCalibrateData((void *)pLastPageData, IFLASH1_PAGE_SIZE); // Initialize touchscreen TSD_Initialize((void *)BOARD_LCD_BASE); // Save touch screen calibration data // Unlock whole flash error = FLASHD_Unlock(IFLASH1, IFLASH1 + IFLASH1_SIZE, 0, 0); if(error) { printf(" Unlock flash fail.\n\r"); } else { TSDCom_ReadCalibrateData(pBuffer, sizeof(pBuffer)); error = FLASHD_Write(lastPageAddress, pBuffer, IFLASH1_PAGE_SIZE); if(error) { printf(" Fail to write touch srceen calibration data.\n\r"); } } #endif return 0; } //TouchScreen init in level 5 DFM_INIT(5, TSD_Init); #endif /////////////////////////////////////////////////// /// following is dealling with show slide on slide/ /////////////////////////////////////////////////// //----------------------------------------------------------------------------- /// Displays the given image on the LCD. /// The image should be same size as the LCD. /// TODO: this display interface should be generalized to consider other LCD properties /// \param pImage point to image buffer /// \param width image width in pixels. /// \param height image height in pixels. //------------------------------------------------------------------------------ static void LCDD_DrawImageRGB565( unsigned short *pImage, unsigned int width, unsigned int height) { unsigned int i; if ((width != BOARD_LCD_WIDTH) || (height != BOARD_LCD_HEIGHT)) { printf("LCDD_DrawImageRGB565: Image size is not fit the LCD"); return; } if(LCDD_IsBusy()) return; LCDD_SetBusy(); LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0); LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE); for (i = 0; i < (width * height); i++) { LCD_WriteRAM((void *)BOARD_LCD_BASE, *(pImage)); pImage++; } LCDD_ClearBusy(); } //------------------------------------------------------------------------------ ///Get slide info header from fatfs file interface //------------------------------------------------------------------------------ static unsigned int GetSlideInfoHeaderFromFile( //fatfs file pointer to demo bin file FIL *pFile, //slide index for get info unsigned int slideIdx, //store read slide info SlideINFOHeader *pSlideheader, //to return actual slide index been read unsigned int *realSlideIdx) { DemoBINHeader binheader; FRESULT res; unsigned int i, offset; if(!pSlideheader) { TRACE_ERROR(" No slide info returned for null pointer!\n\r"); return 1; } //seek to start point of file res = f_lseek(pFile, 0); if(res != FR_OK) { TRACE_ERROR(" Operation demo bin file fail! \n\r"); return 1; } //Read demo bin header information res = f_read(pFile, &binheader, sizeof(DemoBINHeader), &i); if(res != FR_OK ) { TRACE_ERROR(" Fail to read demo bin! \n\r"); return 1; } TRACE_DEBUG(" demo bin tag is %x \n\r", binheader.tag); TRACE_DEBUG(" demo bin has %u slides \n\r", binheader.slidecount); //Check if it is atmel demo bin if( i != sizeof(DemoBINHeader) || binheader.tag != ATMLBINTAG) { TRACE_ERROR(" Not expected demo bin file! \n\r"); return 1; } //save max slide count of active demo bin file gActiveBinSlideCount = binheader.slidecount; //requested slide index larger than available one in current demo bin if(slideIdx >= binheader.slidecount) { TRACE_WARNING(" Reach max slide count! \n\r"); if(realSlideIdx) *realSlideIdx = binheader.slidecount - 1; slideIdx = binheader.slidecount - 1; } //seek the offset to the 'slideindex'th bit map data offset = sizeof(DemoBINHeader) + slideIdx * sizeof(SlideINFOHeader); TRACE_DEBUG("\n\r slide header offset is %u", offset); //Seek to the position of slide information field res = f_lseek(pFile, offset); if(res != FR_OK) { TRACE_ERROR(" Operation demo bin file fail! \n\r"); return 1; } //read slide information res = f_read(pFile, pSlideheader, sizeof(SlideINFOHeader), &i); if(res != FR_OK || i != sizeof(SlideINFOHeader)) { TRACE_ERROR(" Read demo bin file fail! \n\r"); return 1; } return 0; } //------------------------------------------------------------------------------ /// read slide information from SDCARD, and Show /// \param slideIdx, slidex index for reading slide and show /// \return 0 succeed, other fail //------------------------------------------------------------------------------ static int ProcessBinFromSDcard(unsigned int slideIdx, const char *pFileWithPath) { // DemoBINHeader binheader; SlideINFOHeader slideheader; unsigned int offset; TRACE_DEBUG(" file name is %s \n\r", pFileWithPath); FIL demoBinFile; FRESULT res; unsigned int i; // strcpy(pFile,SDCARD_ROOT_DIRECTORY); // strncat(pFile, pFileWithPath, 256-1-strlen(SDCARD_ROOT_DIRECTORY)); //Open demo bin file res = f_open(&demoBinFile, pFileWithPath, FA_OPEN_EXISTING | FA_READ); if(res != FR_OK) { TRACE_ERROR(" Open demo bin file fail! \n\r"); f_close(&demoBinFile); return 1; } //get slide info from file if(GetSlideInfoHeaderFromFile(\ &demoBinFile,\ slideIdx,\ &slideheader,\ &slideIdx)) { TRACE_ERROR(" Read slide header fail!\n\r"); f_close(&demoBinFile); return 1; } //set real slide index as active gActiveSlideIndex = slideIdx; //get the 'slideindex'th slide bit map data offset offset = slideheader.slideoffset; TRACE_DEBUG(" slide %u bitmap data at %u \n\r", slideIdx, offset); #if defined(GLOBALSLIDEINFO) //copy current active slide information to global variable memcpy(&gActiveSlideHeader, &slideheader, sizeof(SlideINFOHeader)); #endif //print the link box information TRACE_DEBUG(" slide has link %u\n\r", gActiveSlideHeader.linkcount); if(slideheader.linkcount) { unsigned int j; for(j = 0; j < slideheader.linkcount; ++j) { TRACE_DEBUG(" link bottom %u, left %u, width %u, height %u \n\r", \ slideheader.linkinfo[j].linkboxbottom,\ slideheader.linkinfo[j].linkboxleft,\ slideheader.linkinfo[j].linkboxwidth,\ slideheader.linkinfo[j].linkboxheight); } } //seek to offset of the 'slideindex'th slide bit map data res = f_lseek(&demoBinFile, offset); if(res != FR_OK) { TRACE_DEBUG(" Operation demo bin file fail! \n\r"); f_close(&demoBinFile); return 1; } #if !defined(USE_SRAM_BUF) //Read all single slide bitmap data into PSRAM buffer, then write to LCD TRACE_DEBUG(" Ready to read bit map data len %u \n\r", slideheader.slidedatalength); //read slide bit map data res = f_read(&demoBinFile, gpFileBuffer, slideheader.slidedatalength, &i); TRACE_DEBUG(" Data read len is %u \n\r", i); if(res != FR_OK || i != slideheader.slidedatalength) { TRACE_ERROR(" Read bitmap data fail! \n\r"); f_close(&demoBinFile); return 1; } f_close(&demoBinFile); //Define a pointer to cast bmp header struct BMPHeader *header = (struct BMPHeader *)gpFileBuffer; offset = header->offset; //Show slide bitmap header information TRACE_DEBUG("============bmp header outside calling============== \n\r"); TRACE_DEBUG(" bmp.type is %x \n\r", header->type); TRACE_DEBUG(" bmp.filesize is %u \n\r", header->fileSize); TRACE_DEBUG(" bmp.width is %u \n\r", header->width); TRACE_DEBUG(" bmp.height is %u \n\r", header->height); TRACE_DEBUG(" bmp.compressed is %u \n\r", header->compression); TRACE_DEBUG(" bmp.bitdepth is %d \n\r", header->bits); TRACE_DEBUG(" bmp.offset is %u \n\r", header->offset); //LCDD_DrawImageRGB565((unsigned short *)(pLcdBuffer),BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT); LCDD_DrawImageRGB565((unsigned short *)(gpFileBuffer + offset),BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT); #else //USE_SRAM_BUF defined //USE sram buffer to read bitmap data and then write to LCD unsigned int k; char srambuf[BUF_LEN_SRAM]; unsigned short *lcddata; //buffer len is not even. if(BUF_LEN_SRAM % 2 != 0) { TRACE_ERROR("SRAM buffer size must be even! \n\r"); f_close(&demofilebin); return 1; } //buffer len is too short to fit a bmp file header if(BUF_LEN_SRAM < sizeof(struct BMPHeader)) { TRACE_ERROR("SRAM buffer size is too short, Add it large than %u \n\r", sizeof(struct BMPHeader)); f_close(&demofilebin); return 1; } //read slide bit map header res = f_read(&demofilebin, srambuf, sizeof(struct BMPHeader), &i); struct BMPHeader *header = (struct BMPHeader *)&srambuf[0]; //Get BMP bitmap data offset offset = header->offset + slideheader.slideoffset; //seek to the bitmap data offset res = f_lseek(&demofilebin, offset); if(res != FR_OK) { TRACE_DEBUG(" Can't find BMP bitmap Data in bin file! \n\r"); f_close(&demofilebin); return 1; } //prepare to write lcd LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0); LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE); for(k = 0; k < slideheader.slidedatalength && k < LCD16BITDATALEN; k += BUF_LEN_SRAM) { lcddata = (unsigned short *)&srambuf[0]; //read data to buffer res = f_read(&demofilebin, srambuf, \ (k + BUF_LEN_SRAM)> slideheader.slidedatalength ? (slideheader.slidedatalength - k): BUF_LEN_SRAM, &i); if(res != FR_OK) { TRACE_ERROR(" Read bitmap data fail! \n\r"); f_close(&demofilebin); return 1; } //write the data to LCD base address while(i>0) { LCD_WriteRAM((void *)BOARD_LCD_BASE, *(lcddata++)); i-=2; } } f_close(&demofilebin); #endif//end of USE_SRAM_BUF unsigned int k; if(slideheader.dispboxcount) { for(k = 0; k < slideheader.dispboxcount; ++k) { //conversion rule based on SAM3U current setting. unsigned int top = slideheader.dispboxinfo[k].dispboxleft; unsigned int left = DEMOSLIDEHEIGHT - slideheader.dispboxinfo[k].dispboxbottom; unsigned int width = slideheader.dispboxinfo[k].dispboxheight; unsigned int height = slideheader.dispboxinfo[k].dispboxwidth; SetDispBoxPos(k+1, DISPBOX_ENABLE, \ top, left, width, height); EnableDispBox(k); } } else { for(k = 0; k < MAX_DISPBOX_PER_SLIDE; ++k) { DisableDispBox(k); } } return 0; } //------------------------------------------------------------------------------ ///read slide information from External NandFlash, and Show //------------------------------------------------------------------------------ static int ProcessBinFromNandFlash(unsigned int slideIdx, const char *pFileWithPath) { unsigned int iRet; //fatfs mounted on NAND FLASH also, so reuse SDCard code iRet = ProcessBinFromSDcard(slideIdx, pFileWithPath); return iRet; } //------------------------------------------------------------------------------ ///read slide information from Internal flash, and Show //------------------------------------------------------------------------------ static int ProcessBinFromInternalFlash(unsigned int binStartAddr, unsigned int slideIdx) { DemoBINHeader binheader; SlideINFOHeader slideheader; unsigned int offset; //get demo bin header information binheader = *(DemoBINHeader*)binStartAddr; TRACE_DEBUG(" bin tag is %x\n\r", binheader.tag); TRACE_DEBUG(" filesize is %u\n\r", binheader.filesize); TRACE_DEBUG(" headersize is %u\n\r", binheader.headersize); TRACE_DEBUG(" bin has %u slide\n\r", binheader.slidecount); //check if it has atmel demo bin header tag if(binheader.tag != ATMLBINTAG) { TRACE_ERROR(" Not Atmel demo bin in FLASH1!\n\r"); return 1; } //check if slide index reachs max if(slideIdx >= binheader.slidecount) { slideIdx = binheader.slidecount - 1; TRACE_WARNING(" Reach max slides!\n\r"); } //set real slide index as active gActiveSlideIndex = slideIdx; //offset of slide info header offset = sizeof(DemoBINHeader) + slideIdx * sizeof(SlideINFOHeader); #if defined(GLOBALSLIDEINFO) memcpy(&gActiveSlideHeader, (void*)(binStartAddr+offset), sizeof(SlideINFOHeader)); #endif slideheader = *(SlideINFOHeader *)(binStartAddr+offset); TRACE_DEBUG(" slide has dispbox?%s\n\r",slideheader.dispboxyes?"yes":"no"); TRACE_DEBUG(" slideoffset is %u\n\r", slideheader.slideoffset); TRACE_DEBUG(" slidedatalength is %u\n\r", slideheader.slidedatalength); TRACE_DEBUG(" slidewidth is %u\n\r", slideheader.slidewidth); TRACE_DEBUG(" slideheight is %u\n\r", slideheader.slideheight); TRACE_DEBUG(" slide has %u links\n\r", slideheader.linkcount); if(slideheader.linkcount) { TRACE_DEBUG(" link 0'addr is %s\n\r", slideheader.linkinfo[0].linkstring); } //offset of slide bmp file offset = slideheader.slideoffset; BMP_displayHeader((unsigned int*)binStartAddr+offset); //Get slide bmp file header struct BMPHeader *bmpheader = (struct BMPHeader*)(binStartAddr+offset); if(bmpheader->type != 0x4d42) { TRACE_ERROR(" Slide bitmap file is not correct!\n\r"); return 1; } //check bitdepth if it is 8. 1,4bitdepth is not supported for complicate //pixel color conversion. 16,24bitdepth bitmap data length too big. //TODO: Care more case of IFlash of some EK board less than 8bit bmp file size, 77k if(bmpheader->bits !=8) { TRACE_ERROR(" Slide bitmap color bitdepth %d is not supported!", bmpheader->bits); return 1; } BMP_Decode((void *)(binStartAddr + offset), gpFileBuffer, \ bmpheader->width, bmpheader->height, 24); unsigned int i; unsigned int color24; unsigned short color16; LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0); LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE); unsigned char * pImage = gpFileBuffer; for (i = 0; i < (BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT); i++) { color24 = (*pImage << 16) | (*(pImage+1) << 8) | (*(pImage+2)); pImage += 3; color16 = RGB24ToRGB16(color24); LCD_WriteRAM((void *)BOARD_LCD_BASE, color16); } unsigned int k; if(slideheader.dispboxcount) { for(k = 0; k < slideheader.dispboxcount; ++k) { //conversion rule based on SAM3U current setting. unsigned int top = slideheader.dispboxinfo[k].dispboxleft; unsigned int left = DEMOSLIDEHEIGHT - slideheader.dispboxinfo[k].dispboxbottom; unsigned int width = slideheader.dispboxinfo[k].dispboxheight; unsigned int height = slideheader.dispboxinfo[k].dispboxwidth; SetDispBoxPos(k+1, DISPBOX_ENABLE, \ top, left, width, height); EnableDispBox(k); } } else { for(k = 0; k < MAX_DISPBOX_PER_SLIDE; ++k) { DisableDispBox(k); } } return 0; } //------------------------------------------------------------------------------ /// Show LCD prompt information, normally it is slide from demo bin /// \param pFileName, demo bin file name without designated drive path //------------------------------------------------------------------------------ int ReadSlideInfoAndShow(const char * pFileName) { int iRet; char pFile[256]; strcpy(pFile,SDCARD_ROOT_DIRECTORY); strncat(pFile, pFileName, 256-1-strlen(SDCARD_ROOT_DIRECTORY)); //gpActiveBinFile = "sam3demo.bin";//fname; iRet = ProcessBinFromSDcard(gActiveSlideIndex, pFile); //read from SDCard fail if(iRet) { strcpy(pFile, NAND_ROOT_DIRECTORY); strncat(pFile, pFileName, 256-1-strlen(NAND_ROOT_DIRECTORY)); iRet = ProcessBinFromNandFlash(gActiveSlideIndex, pFile); if(iRet){ iRet = ProcessBinFromInternalFlash(gDemoBinAddrInFlash, 0); } } //both reading from sdcard and nand flash fail! if(iRet) { TRACE_ERROR("\n\r Read LCD prompt slide information fail!"); } return iRet; } //------------------------------------------------------------------------------ /// Check the hit point if it is in hyperlink zone of active slide /// \param slideIdx slide index to check the hyperlink on the slide /// \return 0 means not in hot zone; other values is the link index start from 1 //------------------------------------------------------------------------------ static unsigned int CheckHitLink() { unsigned int bottom, left, width, height; unsigned int linkcnt; #if !defined(GLOBALSLIDEINFO) SlideINFOHeader gActiveSlideHeader;//to consistent with global one if(GetActiveSlideInfoHeader(gActiveSlideIndex,\ &gActiveSlideHeader,\ 0)) { //can't get active slide info, Consider as not hit return 0; } #endif linkcnt = gActiveSlideHeader.linkcount; unsigned int i; for(i = 0; i < linkcnt; ++i) { bottom = gActiveSlideHeader.linkinfo[i].linkboxbottom; left = gActiveSlideHeader.linkinfo[i].linkboxleft; width = gActiveSlideHeader.linkinfo[i].linkboxwidth; height = gActiveSlideHeader.linkinfo[i].linkboxheight; //inside the link box? if((gTSDxPressed > left) && (gTSDxPressed < (left + width)) && \ (gTSDyPressed < bottom) && (gTSDyPressed > (bottom - height))) return i+1; } return 0; } //------------------------------------------------------------------------------ /// Get link string from link index on active slide /// \param linkIdx link index on active slide, start from 1 /// \return NULL means no link string; otherwise, link string //------------------------------------------------------------------------------ char * GetLinkStrFromActiveSlide(unsigned int linkIdx) { #if !defined(GLOBALSLIDEINFO) SlideINFOHeader gActiveSlideHeader;//to consistent with global one if(GetActiveSlideInfoHeader(gActiveSlideIndex,\ &gActiveSlideHeader,\ 0)) { //can't get active slide info, Consider as NULL return NULL; } #endif return gActiveSlideHeader.linkinfo[linkIdx-1].linkstring; } ////////////////////////////////////////////////////// /// exported function / ////////////////////////////////////////////////////// //------------------------------------------------------------------------- /// Set Touch screen is touched //------------------------------------------------------------------------- void TSD_SetTouched(void) { gTSDPressed = 1; } //------------------------------------------------------------------------- /// Clear Touch screen is touched //------------------------------------------------------------------------- void TSD_ClearTouched(void) { gTSDPressed = 0; } //------------------------------------------------------------------------- /// Get Touch screen is touched //------------------------------------------------------------------------- unsigned char TSD_GetTouched(void) { return gTSDPressed; } //------------------------------------------------------------------------- /// Check if touchscreen hit in a hot zone /// \return 0 means no, other values mean yes //------------------------------------------------------------------------- unsigned int TSD_CommandIsReady() { unsigned int ret; if(0 == gTSDxPressed && 0 == gTSDyPressed) { return 0; } ret = CheckHitLink(); //set global variable for link index gLinkIndex = ret; gTSDxPressed = gTSDyPressed = 0; return ret; } //---------------------------------------------------------- /// Get ready command /// \return string pointer to link string //---------------------------------------------------------- const char * TSD_GetCommand() { char *pStr; //get link string from index pStr = GetLinkStrFromActiveSlide(gLinkIndex); //clear gLinkIndex = 0; return pStr; } //------------------------------------------------------------------------------ /// Set LCD fresh show flag, this will cause next call to LCD_ShowPrompt reload /// slide page data any way. //------------------------------------------------------------------------------ void LCD_SetRefreshFlag() { gLcdRefreshFlag = 1; } //------------------------------------------------------------------------------ /// Clear LCD fresh show flag //------------------------------------------------------------------------------ void LCD_ClearRefreshFlag() { gLcdRefreshFlag = 0; } //------------------------------------------------------------------------------ /// Show LCD prompt information, normally it is slide from demo bin //------------------------------------------------------------------------------ int LCD_ShowPrompt() { static unsigned int slideIndexLoaded = 0xffffffff; int ret; if(gActiveSlideHeader.propyes) { if(slideIndexLoaded != gActiveSlideIndex && slideIndexLoaded != 0xffffffff) { ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onCloseCmds); } } //reload show only slide index changed or fresh flag is set if(slideIndexLoaded != gActiveSlideIndex || gLcdRefreshFlag) { ret = ReadSlideInfoAndShow(gpActiveBinFile); if(gActiveSlideHeader.propyes && slideIndexLoaded != gActiveSlideIndex) { ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onInitCmds); } slideIndexLoaded = gActiveSlideIndex; gLcdRefreshFlag = 0; } if(gActiveSlideHeader.propyes) { ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onRefreshCmds); } return ret; }