summaryrefslogtreecommitdiff
path: root/utility/demo-fw/common/dfm_lcd_tsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'utility/demo-fw/common/dfm_lcd_tsd.c')
-rw-r--r--utility/demo-fw/common/dfm_lcd_tsd.c1040
1 files changed, 1040 insertions, 0 deletions
diff --git a/utility/demo-fw/common/dfm_lcd_tsd.c b/utility/demo-fw/common/dfm_lcd_tsd.c
new file mode 100644
index 0000000..f1d826c
--- /dev/null
+++ b/utility/demo-fw/common/dfm_lcd_tsd.c
@@ -0,0 +1,1040 @@
+/* ----------------------------------------------------------------------------
+ * 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 <board.h>
+#include <board_memories.h>
+#include <utility/trace.h>
+#include <utility/bmp.h>
+#include <systick/systick.h>
+#include <lcd/color.h>
+#include <lcd/draw.h>
+#include <lcd/lcdd.h>
+#include <hx8347/hx8347.h>
+#include <tsd/tsd.h>
+#include <flash/flashd.h>
+
+#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;
+}
+
personal git repositories of Harald Welte. Your mileage may vary