summaryrefslogtreecommitdiff
path: root/utility/demo-fw/common
diff options
context:
space:
mode:
Diffstat (limited to 'utility/demo-fw/common')
-rw-r--r--utility/demo-fw/common/dfm_accelerometer.c647
-rw-r--r--utility/demo-fw/common/dfm_button.c248
-rw-r--r--utility/demo-fw/common/dfm_cmd.c880
-rw-r--r--utility/demo-fw/common/dfm_console.c216
-rw-r--r--utility/demo-fw/common/dfm_dispboxmgr.c481
-rw-r--r--utility/demo-fw/common/dfm_entry.c142
-rw-r--r--utility/demo-fw/common/dfm_fatfs.c384
-rw-r--r--utility/demo-fw/common/dfm_init.c118
-rw-r--r--utility/demo-fw/common/dfm_it.c638
-rw-r--r--utility/demo-fw/common/dfm_lcd_tsd.c1040
10 files changed, 4794 insertions, 0 deletions
diff --git a/utility/demo-fw/common/dfm_accelerometer.c b/utility/demo-fw/common/dfm_accelerometer.c
new file mode 100644
index 0000000..410fe91
--- /dev/null
+++ b/utility/demo-fw/common/dfm_accelerometer.c
@@ -0,0 +1,647 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+ //------------------------------------------------------------------------------
+/// \unit
+///
+/// This file contains algorithms and drivers for tilt sensing.
+///
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+#include "dfm_accelerometer.h"
+#include "board.h"
+#include <irq/irq.h>
+#include <pio/pio.h>
+#include <pio/pio_it.h>
+#include <adc/adc12.h>
+#include <lcd/draw.h>
+
+#include <stdio.h>
+
+#include <math.h>
+
+#include "dfm_config.h"
+#include "dfm_cmd.h"
+#include "dfm_lcd_tsd.h"
+#include "dfm_dispboxmgr.h"
+#include "dfm_it.h"
+#include "dfm_init.h"
+
+//------------------------------------------------------------------------------
+// Macros
+//------------------------------------------------------------------------------
+#define BOARD_ADC12_FREQ 5000000 //! ADC clock
+#define ADC12_VREF 3300 //! reference voltage 3.3 * 1000,make sure the jumper setting is right
+#define PINS_ACC_ADC PIN_ADC0_AD2,PIN_ADC0_AD6,PIN_ADC0_AD7
+
+#define TAN30 (37) //! fixed point for tanget tan(45)*0x40
+#define TAN15 17 //! fixed point for tangent tan(15)*0x40
+#define DELAY 100
+#define SAMPLES 1
+
+#if defined(at91sam3u4)
+#define AT91C_ID_ADC_PRESENT AT91C_ID_ADC12B
+#define AT91C_BASE_ADC AT91C_BASE_ADC12B
+#endif
+//------------------------------------------------------------------------------
+// External Variables
+//------------------------------------------------------------------------------
+extern const char * gpActiveBinFile;
+extern unsigned int gLcdRefreshFlag;
+extern int rotation_axes_cpt;
+/// record measurement times
+static int count =0;
+//------------------------------------------------------------------------------
+// Variables
+//------------------------------------------------------------------------------
+
+
+unsigned char ADC12_channel_x = ADC12_CHANNEL_2; //!< X Channel For Accelerometer
+unsigned char ADC12_channel_y = ADC12_CHANNEL_6; //!< Y Channel For Accelerometer
+unsigned char ADC12_channel_z = ADC12_CHANNEL_7; //!< Z Channel For Accelerometer
+/// Indicates that the conversion is finished.
+static volatile unsigned char conversionDone;
+
+acc_t acc = { //!< Accelerometer Instance
+ .m = { .x=0 , .y=0 , .z=0 } ,
+ .k = { .x=ACC_ZERO_X , .y=ACC_ZERO_Y , .z=ACC_ZERO_Z } ,
+ .ak = { .x=0 , .y=0 , .z=0 } ,
+} ;
+
+static const Pin pinsADC[] = {PINS_ACC_ADC};
+
+static xyz_t lastMeasure = {0};
+int gDir = DIR_UNCHANGED;
+int gLastDir = DIR_UNCHANGED;
+
+///push button to configure for the applicatino.
+static Pin pinBP4 = PIN_PUSHBUTTON_1;
+//------------------------------------------------------------------------------
+// Functions
+//------------------------------------------------------------------------------
+int DV_Check_AccStatus();
+
+//------------------------------------------------------------------------------
+/// add position
+//------------------------------------------------------------------------------
+xyz_t xyz_add (xyz_t p, xyz_t q)
+{
+ xyz_t r ;
+ r.x = p.x + q.x ;
+ r.y = p.y + q.y ;
+ r.z = p.z + q.z ;
+ return r ;
+}
+
+//------------------------------------------------------------------------------
+/// sub position
+//------------------------------------------------------------------------------
+xyz_t xyz_diff (xyz_t p, xyz_t q)
+{
+ xyz_t r ;
+ r.x = p.x - q.x ;
+ r.y = p.y - q.y ;
+ r.z = p.z - q.z ;
+ return r ;
+}
+
+//------------------------------------------------------------------------------
+/// Invoke platform api to get converted data
+/// \param pAdc address pointer for ADC12B controller
+/// \param ADC12_channel_x channel number for x axis
+/// \param ADC12_channel_y channel number for y axis
+/// \param ADC12_channel_z channel number for z axis
+/// \return converted data for three channels
+//------------------------------------------------------------------------------
+xyz_t acc_get_value ( AT91S_ADC12B *pAdc , unsigned char ADC12_channel_x, unsigned char ADC12_channel_y, unsigned char ADC12_channel_z)
+{
+ xyz_t val ;
+
+ val.x = ADC12_GetConvertedData(pAdc, ADC12_channel_x);
+ val.y = ADC12_GetConvertedData(pAdc, ADC12_channel_y);
+ val.z = ADC12_GetConvertedData(pAdc, ADC12_channel_z);
+
+ val.x = val.x>>ACC_SHIFT;
+ val.y = val.y>>ACC_SHIFT;
+ val.z = val.z>>ACC_SHIFT;
+
+ return val ;
+}
+
+
+//------------------------------------------------------------------------------
+/// get present acceleration value as 0-g value for x and y, 1-g value for z
+//------------------------------------------------------------------------------
+void DoCalibration()
+{
+ int i = 0,j;
+ xyz_t temp ={0};
+ count = 0;
+ acc.m.x = 0;
+ acc.m.y = 0;
+ acc.m.z = 0;
+ for(i = 0; i < 16 ; i++)
+ {
+ if(DV_Check_AccStatus()){
+ temp = xyz_add(acc.m,temp);
+ for(j=0;j<DELAY;j++);
+ }
+
+ }
+ acc.m.x = temp.x /count;
+ acc.m.y = temp.y /count;
+ acc.m.z = temp.z /count;
+
+ count = 0;
+ acc.k = acc.m;
+
+
+}
+
+//------------------------------------------------------------------------------
+///check if the tilt angles are big enough.If yes,get rotation direction
+///according to the sign of two axes
+/// \return rotation direction
+//------------------------------------------------------------------------------
+int DV_Accelerometer_Tilt()
+{
+ int dir = DV_Accelerometer_Unchanged;
+ int x=0,y=0,z=0;
+
+ int i = 0,j;
+ acc.m.x = 0;
+ acc.m.y = 0;
+ acc.m.z = 0;
+
+ count = 0;
+
+ for(i = 0; i < SAMPLES ; i++)
+ {
+ DV_Check_AccStatus();
+ for(j=0;j<DELAY;j++);
+ }
+ acc.m.x = acc.m.x /count;
+ acc.m.y = acc.m.y /count;
+ acc.m.z = acc.m.z /count;
+ count = 0;
+
+ acc.ak = xyz_diff(acc.m,acc.k);
+
+
+
+ x = acc.ak.x;
+ y = acc.ak.y;
+ z = (acc.ak.z + ACC_1G);
+
+
+ if( (unsigned int)(x*x)<<12 > (TAN15*TAN15)*(y*y+z*z) || (unsigned int)(y*y)<<12 > (TAN15*TAN15)*(x*x+z*z))
+ {
+ if((unsigned int)(x*x)<<12 > (TAN15*TAN15)*(y*y+z*z))
+ {
+ if((unsigned int)(y*y)<<12 > (TAN15*TAN15)*(x*x+z*z))
+ {
+ if(x < 0)
+ {
+ if(y < 0)
+ {
+ dir = DV_Accelerometer_up_right;
+ }
+ else
+ {
+ dir =DV_Accelerometer_down_right;
+ }
+ }
+ else
+ {
+ if(y < 0)
+ {
+ dir = DV_Accelerometer_up_left;
+ }
+ else
+ {
+ dir = DV_Accelerometer_down_left;
+
+ }
+ }
+ }
+ else
+ {
+ if(x < 0)
+ {
+ dir = DV_Accelerometer_right;
+ }
+ else
+ {
+ dir = DV_Accelerometer_left;
+ }
+ }
+
+ }
+ else
+ {
+ if(y < 0)
+ {
+ dir = DV_Accelerometer_up;
+ }
+ else
+ {
+ dir = DV_Accelerometer_down;
+ }
+ }
+ }
+
+ return dir;
+
+}
+
+
+//------------------------------------------------------------------------------
+/// get the direction of the board
+/// \return direction
+//------------------------------------------------------------------------------
+int DV_Accelerometer_Dir()
+{
+
+ int dir = gDir;
+ int x=0,y=0,z=0;
+ xyz_t diff = {0};
+
+ ///measure the difference between the last one and the present one
+ diff = xyz_diff(acc.m,lastMeasure);
+
+ ///check the status,acc.m will be changed after called routine
+ ///if conversion is done,otherwise,return immediately
+ DV_Check_AccStatus();
+
+
+ ///no big change since last measurement
+ if( diff.x*diff.x + diff.y*diff.y + diff.z*diff.z < ((ACC_1G*ACC_1G)>>11))
+ {
+ ///keep the old direction
+ return gDir;
+
+ }
+ ///update lastMeasure to the new one
+ lastMeasure = acc.m;
+
+ ///get acceleration offset
+ acc.ak = xyz_diff(acc.m,acc.k);
+
+
+
+ x = acc.ak.x;
+ y = acc.ak.y;
+ z = (acc.ak.z + ACC_1G);
+ /// filter non-tilting operation
+ if( (x*x + y*y+z*z > ACC_AMPLITUDE_UPPER) ||(x*x + y*y+z*z < ACC_AMPLITUDE_LOWER) ){
+ return gDir;
+ }
+
+ ///the board plane is angled with the horizontal surface
+ if( (unsigned int)(x*x)<<12 > (TAN30*TAN30)*(y*y+z*z) || (unsigned int)(y*y)<<12 > (TAN30*TAN30)*(x*x+z*z))
+ {
+
+ if(x*x > y*y + (y*y>>1))
+ {
+ if(x > 0)
+ {
+ dir = DIR_HORIZIONTAL_UP;
+ }
+ else
+ {
+ dir = DIR_HORIZIONTAL_DOWN;
+ }
+ }
+ else if(x*x + (x*x>>1) < y*y)
+ {
+ if(y > 0)
+ {
+ dir = DIR_VERTICAL_UP;
+ }
+ else
+ {
+ dir = DIR_VERTICAL_DOWN;
+ }
+ }
+ //else dir = previous dir
+ //leave gap enough for stabilization
+ ///renew the direction
+ gDir = dir;
+ }
+
+ return gDir;
+
+}
+//------------------------------------------------------------------------------
+/// Check accelerometer is ready?
+/// if the direction is unchanged since last measurement,return "not ready"
+/// \return 0 not ready, other value means ready and command string length
+//------------------------------------------------------------------------------
+unsigned int ACC_CommandIsReady()
+{
+ int dir = DIR_UNCHANGED;
+ unsigned int ret;
+ dir = DV_Accelerometer_Dir();
+ //no change of direction since last measurement
+ if(gLastDir == dir)
+ {
+ ret = 0;
+ }
+ else
+ {
+ ret = 1;
+ }
+ gLastDir = dir;
+ return ret;
+}
+
+
+//------------------------------------------------------------------------------
+// get flipped ppt page
+//------------------------------------------------------------------------------
+const char * ACC_GetCommand()
+{
+ if(gDir == DIR_HORIZIONTAL_UP || gDir == DIR_HORIZIONTAL_DOWN)
+ {
+ //update to portait image file
+ gpActiveBinFile = LCDSLIDEVIMAGEFILE;
+ gLcdRefreshFlag = 1;
+
+ }
+ else
+ {
+ gpActiveBinFile = LCDSLIDEIMAGEFILE;
+ gLcdRefreshFlag = 1;
+
+ }
+ return NULL;
+}
+
+//an example of ShowPrompt
+int ACC_ShowPrompt()
+{
+// int i;
+// switch(gDir)//gDir
+// {
+//
+// case DIR_HORIZIONTAL_UP:
+// printf("Horizontal Up!\n");
+// //LCDD_DrawRectangle((void *)BOARD_LCD_BASE, x,y,width,height,0xE0E0C0);
+// break;
+// case DIR_HORIZIONTAL_DOWN:
+// printf("Horizontal Down!\n");
+// break;
+// case DIR_VERTICAL_UP:
+// printf("Vertical Up!\n");
+// break;
+// case DIR_VERTICAL_DOWN:
+// printf("Vertical Down!\n");
+// break;
+// default:
+// printf("Unchanged!\n");
+// break;
+// }
+// for(i=0;i<5000;i++);
+ return 0;
+}
+
+//global accelerometer entry variable
+TInputEntry gAccEntry = {0, {NULL,NULL},ACC_ShowPrompt, ACC_CommandIsReady, ACC_GetCommand, NULL};
+//------------------------------------------------------------------------------
+/// Check if conversion is done.If done,read the corresponding parameters and
+///start new measurement
+//------------------------------------------------------------------------------
+int DV_Check_AccStatus()
+{
+ //check if conversation is done
+ //if done, read and measure,and start new conversation
+ //else, return directly
+
+
+ if(conversionDone == ((1<<ADC12_channel_x)|(1<<ADC12_channel_y)|(1<<ADC12_channel_z)))//x,y,z all done
+ {
+ // IRQ_DisableIT(AT91C_ID_ADC_PRESENT);
+ DV_ACCELEROMETER_Measure();
+ //sharing variable for main and isr
+ conversionDone= 0;
+ // record the number of measurement
+ count++;
+
+ // Start new measurement
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_x);//Enable EOCx interrupt
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_y);//Enable EOCx interrupt
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_z);//Enable EOCx interrupt
+ ADC12_StartConversion(AT91C_BASE_ADC);
+ // conversionDone for all 3 channels
+ return 1;
+ }else{
+ return 0;
+ }
+
+
+
+}
+
+//------------------------------------------------------------------------------
+/// Interrupt handler for the ADC. Signals that the conversion is finished by
+/// setting a flag variable.
+//------------------------------------------------------------------------------
+void ADC12B_IrqHandler(void)
+{
+ unsigned int status, i;
+ static unsigned char chns[3];
+ AT91PS_ADC12B padc = AT91C_BASE_ADC;
+ chns[0] = ADC12_channel_x;
+ chns[1] = ADC12_channel_y;
+ chns[2] = ADC12_channel_z;;
+
+
+ status = ADC12_GetStatus(padc);
+ //printf("status =0x%X\n\r", status);
+ //TRACE_DEBUG("ADC12_imr=0x%X\n\r", ADC12_GetInterruptMaskStatus());
+
+ for(i=0;i<sizeof(chns)/sizeof(unsigned char);i++) {
+ if (ADC12_IsChannelInterruptStatusSet(status, chns[i])) {
+
+ //printf("channel %d\n\r", chns[i]);
+ ADC12_DisableIt(AT91C_BASE_ADC, 1<<chns[i]);//disable EOCx interrupt
+ conversionDone |= 1<<chns[i];
+ }
+ }
+}
+
+#if defined(USE_IT_CHAIN_MGR)
+TDFM_ItServList gAccADC12BHandler = {AT91C_ID_ADC_PRESENT, ADC12B_IrqHandler, NULL};
+#endif
+//------------------------------------------------------------------------------
+/// ADC12B and accelerometer initialization
+//------------------------------------------------------------------------------
+int DV_ACCELEROMETER_Init(void)
+{
+ int cali_done = 0;
+ char keyStatus = 0;
+ Pin pinSleep;
+ pinSleep.attribute = PIO_DEFAULT;
+ pinSleep.mask = (1<<13);
+ pinSleep.id = AT91C_ID_PIOC;
+ pinSleep.pio = AT91C_BASE_PIOC;
+ pinSleep.type = PIO_OUTPUT_1;
+
+ ///Normal mode
+ PIO_Configure(&pinSleep,1);
+ PIO_Set(&pinSleep);
+
+#ifdef PINS_ADC
+ PIO_Configure(pinsADC, PIO_LISTSIZE(pinsADC));
+#endif
+ ///ADC12B configuration
+ ADC12_Initialize( AT91C_BASE_ADC,
+ AT91C_ID_ADC_PRESENT,
+ AT91C_ADC12B_MR_TRGEN_DIS,
+ 0,
+ AT91C_ADC12B_MR_SLEEP_NORMAL,
+ AT91C_ADC12B_MR_LOWRES_12_BIT,//for 12bit adc,0 means 12bits,1-10bits
+ BOARD_MCK,
+ BOARD_ADC12_FREQ,
+ 10,
+ 2400);
+ ///Enable 3 channels for x,y and z
+ ADC12_EnableChannel(AT91C_BASE_ADC, ADC12_channel_x);
+ ADC12_EnableChannel(AT91C_BASE_ADC, ADC12_channel_y);
+ ADC12_EnableChannel(AT91C_BASE_ADC, ADC12_channel_z);
+
+ ///Enable adc12b interrupt
+ //IRQ_ConfigureIT(AT91C_ID_ADC_PRESENT, 0, ADCC0_IrqHandler);
+ // IRQ_EnableIT(AT91C_ID_ADC_PRESENT);
+#if defined(USE_IT_CHAIN_MGR)
+ DFM_RegisterItHandler(&gAccADC12BHandler);
+#endif
+
+ IRQ_EnableIT(AT91C_ID_ADC_PRESENT);
+
+ conversionDone = 0;
+
+ ///Enable channel interrupt
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_x);
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_y);
+ ADC12_EnableIt(AT91C_BASE_ADC, 1<<ADC12_channel_z);
+
+ /// Start measurement
+ ADC12_StartConversion(AT91C_BASE_ADC);
+
+ ///if calibration needed here?
+
+ // Do calibration first,ineteract with users
+ LCDD_Fill(((void *)BOARD_LCD_BASE),0xffffff);
+ //LCDD_DrawString((void *)BOARD_LCD_BASE,10,100,"Put the board on \nthe horizontal \nsurface and press \nBP4 to start \ncalibration!",0x0);
+
+ //PIO_InitializeInterrupts(0);
+ //PIO_Configure(&pinBP4,1);
+ //keyStatus = 1;
+ while(cali_done == 0)
+ {
+ // Check if button state has changed
+ //unsigned char isButtonPressed = PIO_Get(&pinBP4);
+ //if (isButtonPressed != keyStatus) {
+
+ // Update button state
+ //if (!isButtonPressed) {
+
+ // Key has been pressed
+ //printf("BP4 has been pressed!\n");
+ //keyStatus = 0;
+
+ DoCalibration();
+ cali_done = 1;
+
+
+ //}
+ //}
+ }
+ return 0;
+
+}
+
+//------------------------------------------------------------------------------
+/// Get immediate acceleration
+//------------------------------------------------------------------------------
+void DV_ACCELEROMETER_Measure(void)
+{
+ acc.m = acc_get_value(AT91C_BASE_ADC, ADC12_channel_x, ADC12_channel_y, ADC12_channel_z) ;
+
+}
+
+
+//------------------------------------------------------------------------------
+///
+///Measure the direction,left,right,forward,backward,then switch rotation axis
+///appopriately
+///
+//------------------------------------------------------------------------------
+void DV_Accelerometer_Turn()
+{
+ int dir = DV_Accelerometer_Tilt();
+ switch(dir)
+ {
+ case DV_Accelerometer_Unchanged:
+ rotation_axes_cpt = 0;
+ break;
+ case DV_Accelerometer_left:
+ rotation_axes_cpt = 4;
+ break;
+ case DV_Accelerometer_right:
+ rotation_axes_cpt = 3;
+ break;
+ case DV_Accelerometer_up:
+ rotation_axes_cpt = 2;
+ break;
+ case DV_Accelerometer_down:
+ rotation_axes_cpt = 1;
+ break;
+ case DV_Accelerometer_up_right:
+ rotation_axes_cpt = 6;
+ break;
+ case DV_Accelerometer_up_left:
+ rotation_axes_cpt = 8;
+ break;
+ case DV_Accelerometer_down_right:
+ rotation_axes_cpt = 5;
+ break;
+ case DV_Accelerometer_down_left:
+ rotation_axes_cpt = 7;
+ break;
+ }
+}
+
+
+//Accelerometer init in level 6
+DFM_INIT(6, DV_ACCELEROMETER_Init);
+
+
diff --git a/utility/demo-fw/common/dfm_button.c b/utility/demo-fw/common/dfm_button.c
new file mode 100644
index 0000000..b0d9d54
--- /dev/null
+++ b/utility/demo-fw/common/dfm_button.c
@@ -0,0 +1,248 @@
+/* ----------------------------------------------------------------------------
+ * 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 <stdio.h>
+#include <pio/pio.h>
+#include <lcd/draw.h>
+#include <lcd/color.h>
+#include <utility/trace.h>
+
+#include "dfm_init.h"
+#include "dfm_cmd.h"
+#include "dfm_button.h"
+#include "dfm_lcd_tsd.h"
+
+//------------------------------------------------------------------------------
+// variable definition
+//------------------------------------------------------------------------------
+/// global BUTTON entry
+TInputEntry gButtonEntry = \
+ {0, {NULL,NULL}, BTN_ShowPrompt, BTN_CommandIsReady, BTN_GetCommand, NULL};
+
+/// global active icon, a focus circle should be drawn around it
+unsigned int gActiveIconIndex;
+
+//button pin definition
+static Pin pinsPushButtons[] = {PINS_PUSHBUTTONS};
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Init button
+//------------------------------------------------------------------------------
+int BTN_Init(void)
+{
+ printf("\n\r Init Button!");
+
+ gActiveIconIndex = 0;
+
+ //memset(keyStatus, 1, 2);
+
+ PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons));
+
+ return 0;
+}
+
+//decleare to init it in level 5
+DFM_INIT(5, BTN_Init);
+
+//------------------------------------------------------------------------------
+/// Draw a focus circle around current active icon
+/// \param colormask, color mask to generate a masked color to draw
+//------------------------------------------------------------------------------
+static void DrawIconSelection(unsigned int linkZoneIndex, unsigned int colorMask)
+{
+ unsigned int i, left, bottom, width, height;
+ unsigned short color16;
+ unsigned int color, color24;
+
+ //index correcttion
+ if(linkZoneIndex >= gActiveSlideHeader.linkcount)
+ linkZoneIndex = gActiveSlideHeader.linkcount - 1;
+
+ bottom = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxbottom;
+ left = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxleft;
+ width = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxwidth;
+ height = gActiveSlideHeader.linkinfo[linkZoneIndex].linkboxheight;
+
+#ifndef RGB16ToRGB24
+/// Convert 16-bits color to 24-bits color, detail lost, only for compatible.
+#define RGB16ToRGB24(color) (((color & 0XF800) << 8) | \
+ ((color & 0x7E0) << 5) | \
+ ((color & 0x1F) << 3))
+#endif
+
+ for(i = 0; i < (width + 2); ++i) {
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom);
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom,
+ color24);
+
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom - height - 1);
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left + i,
+ bottom - height - 1,
+ color24);
+ }
+
+ for(i = 1; i < (height + 1); ++i) {
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left,
+ bottom - i);
+
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left,
+ bottom - i,
+ color24);
+
+ color16 = LCDD_ReadPixel((void *)BOARD_LCD_BASE,
+ left + width + 1,
+ bottom - i);
+
+ color = RGB16ToRGB24(color16);
+ color24 = color ^ colorMask;
+
+ LCDD_DrawPixel((void *)BOARD_LCD_BASE,
+ left + width + 1,
+ bottom - i,
+ color24);
+ }
+
+}
+
+//------------------------------------------------------------------------------
+/// Draw a focus circle on current active icon
+//------------------------------------------------------------------------------
+int BTN_ShowPrompt()
+{
+ static unsigned int iconDrawedIndex = 0xFFFFFFFF;
+ static unsigned int slidePageLoaded = 0xFFFFFFFF;
+
+ if(slidePageLoaded != gActiveSlideIndex) {
+ slidePageLoaded = gActiveSlideIndex;
+ iconDrawedIndex = gActiveIconIndex = 0;
+
+ DrawIconSelection(gActiveIconIndex, COLOR_AZUR);
+ } else {
+ if(iconDrawedIndex != gActiveIconIndex) {
+ DrawIconSelection(iconDrawedIndex, COLOR_AZUR);
+
+ DrawIconSelection(gActiveIconIndex, COLOR_AZUR);
+
+ iconDrawedIndex = gActiveIconIndex;
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Check button press/release status, if OK button press/released, then true
+/// \return 0 means not ready, 1 means yes.
+//------------------------------------------------------------------------------
+//check if button is pressed
+unsigned int BTN_CommandIsReady()
+{
+ //unsigned int i;
+ static unsigned int selPressFlag = 0;
+ static unsigned int okPressFlag = 0;
+ unsigned int ret = 0;
+ unsigned char btnStatus;
+
+ //read icon selection button status
+ btnStatus = PIO_Get(&(pinsPushButtons[0]));
+
+ //icon selection button pressed
+ if(btnStatus == 0) {
+ if(!selPressFlag) {
+// //use same color mask to clear previous focus circle
+// DrawIconSelection(COLOR_AZUR);
+
+ //increase icon index to next
+ ++gActiveIconIndex;
+ if(gActiveIconIndex >= gActiveSlideHeader.linkcount)
+ gActiveIconIndex = 0;
+
+// //use a color mask to draw a focus circle for icon
+// DrawIconSelection(COLOR_AZUR);
+
+ //set selection button pressed flag to wait button release
+ selPressFlag = 1;
+ }
+ } else {
+ //pressed key released
+ selPressFlag = 0;
+ }
+
+ //read icon confirm button status
+ btnStatus = PIO_Get(&(pinsPushButtons[1]));
+
+ //ok button pressed
+ if(btnStatus == 0)
+ {
+ if(!okPressFlag) {
+ //set ok button pressed flag to wait button release
+ okPressFlag = 1;
+ }
+ } else {
+ if(okPressFlag) {
+ //pressed key released,then return 1 to id command is ready
+ ret = 1;
+ okPressFlag = 0;
+ }
+ }
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+/// Get commands for selected icon
+/// \return command string for the selected icon
+//------------------------------------------------------------------------------
+const char * BTN_GetCommand()
+{
+ return GetLinkStrFromActiveSlide(gActiveIconIndex + 1);
+}
+
diff --git a/utility/demo-fw/common/dfm_cmd.c b/utility/demo-fw/common/dfm_cmd.c
new file mode 100644
index 0000000..12463ad
--- /dev/null
+++ b/utility/demo-fw/common/dfm_cmd.c
@@ -0,0 +1,880 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <string.h>
+#include <stdio.h>
+#include "dfm_cmd.h"
+#include "dfm_init.h"
+#include "dfm_fatfs.h"
+#include "dfm_console.h"
+#include "dfm_lcd_tsd.h"
+#include "dfm_button.h"
+
+//------------------------------------------------------------------------------
+// variable definition
+//------------------------------------------------------------------------------
+#if defined(__ICCARM__)//IAR Compiler ID
+
+///no need for declaration of section start and end variable in IAR
+
+#elif defined(__CC_ARM) //MDK ARM Compiler ID
+
+///variables for group start/end address
+ extern unsigned int Image$$GShell_region$$Base;
+ extern unsigned int Image$$GShell_region$$Limit;
+
+#elif defined(__GNUC__)//GNU ARM Compiler ID
+
+///variables for group start/end address
+extern long __gs_section_start, __gs_section_end;
+
+#endif
+
+///active group for execution of searching of commands. End with NULL
+static char *gpActGroups[MAX_ACT_GROUP + 1] = {SYS_GROUP};// default group init first.
+
+///entry
+
+//------------------------------------------------------------------------------
+// Internal functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// parse a tring into '*argv[]', delimitor is space or tab
+/// \param pRawString, the whole line of command string
+/// \param argv, parsed argument string array
+/// \return number of parsed argument
+//------------------------------------------------------------------------------
+static int StringLineToArgs(char *pRawString, char *argv[]) {
+ int argc = 0;
+
+ if(pRawString == NULL)
+ return 0;
+
+ while(argc < MAX_CMD_ARGS) {
+
+ // skip white space characters of string head
+ while ((*pRawString == ' ') || (*pRawString == '\t')) {
+ ++pRawString;
+ }
+
+ if (*pRawString == '\0') {
+ argv[argc] = NULL;
+ return (argc);
+ }
+
+ argv[argc++] = pRawString;
+
+ // find end of string
+ while (*pRawString && (*pRawString != ' ') && (*pRawString != '\t')) {
+ ++pRawString;
+ }
+
+ if (*pRawString == '\0') {
+ argv[argc] = NULL;
+ return (argc);
+ }
+
+ *pRawString++ = '\0';
+ }
+
+ printf ("\n\r Too many arguments. Maximum argus supported is %d!", MAX_CMD_ARGS);
+
+ return (argc);
+}
+
+//------------------------------------------------------------------------------
+/// search active group name in array and return index.
+/// \param pStr, group name string
+/// \param pStrArray, group array
+/// \param iArrayLen, array length
+/// \return group index in group array, -1 if not found
+//------------------------------------------------------------------------------
+static int FindStrIdx(const char * pStr, const char * const pStrArray[], int iArrayLen)
+{
+ int i;
+
+ //search, end when find NULL or exceed max len
+ for(i = 0; i < iArrayLen && pStrArray[i] != NULL; ++i) {
+ //printf("\n\r str is %s, %s, %d",pStr, pStrArray[i], iArrayLen);
+ if(strcmp(pStr, pStrArray[i])==0) {
+ break;
+ }
+ }
+
+ //if not found
+ if(i==iArrayLen || pStrArray[i] == NULL) {
+ i = -1;
+ }
+
+ return i;
+}
+
+//------------------------------------------------------------------------------
+/// Find command in active groups
+/// \param pCmd, command name
+/// \return pointer to command portal, NULL if not found
+//------------------------------------------------------------------------------
+static FStruct * FindCommand(const char * pCmd)
+{
+ int iGrpIdxAct;
+ unsigned int i, iCmdNum;
+ unsigned short int gm, im;// max:0xffff, init value used to id fail search
+ FStruct *pTmpFs, *pFsStart, *pFsEnd;
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *)&__gs_section_start;
+ pFsEnd = (FStruct *)&__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ iCmdNum = pFsEnd - pFsStart;
+
+ for(i=0,gm=0xffff, im=0xffff; i < iCmdNum; ++i) {
+ if(strcmp((pFsStart + i)->pCmdName, pCmd)==0) {
+ iGrpIdxAct = FindStrIdx((pFsStart + i)->pGrpName,
+ gpActGroups,
+ MAX_ACT_GROUP);
+
+ //group is not in active group list
+ if(iGrpIdxAct == -1) {
+ continue;
+ }
+
+ if(iGrpIdxAct < gm) {
+ gm = iGrpIdxAct;
+ im = i;
+ }
+ }
+
+ }
+
+
+ if(gm != 0xffff) {// found
+ pTmpFs = pFsStart + im;
+ } else {//not found
+ pTmpFs = NULL;
+ }
+
+ return pTmpFs;
+}
+
+//------------------------------------------------------------------------------
+// Exported Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Parse a command string and search in active groups, run if matched
+/// \param pCmdString, command string including arguments
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int ParseAndRunCmd(const char * pCmdString)
+{
+ FStruct *pFsCmd;
+ int argc, iRet;
+ char args[DBGU_CMDBUFSIZE];
+ char *argv[MAX_CMD_ARGS + 1];
+
+ //if NULL string, no run
+ if(!pCmdString)
+ return 0;
+
+ unsigned int strLength = strlen(pCmdString);
+
+ //empty string, no run
+ if(strLength == 0)
+ return 0;
+
+ if(strLength < DBGU_CMDBUFSIZE) {
+ strcpy(args, pCmdString);
+ }
+ else {
+ memcpy(args, pCmdString, DBGU_CMDBUFSIZE-1);
+ args[DBGU_CMDBUFSIZE-1] = '\0';
+ }
+
+ // parse a command string to *argv[]
+ argc = StringLineToArgs(args, argv);
+
+ // find matched command
+ if((pFsCmd = FindCommand(argv[0])) == NULL) {
+
+ printf("\n\r Command -'%s'- not found in active groups!", argv[0]);
+ iRet = 1;
+
+ } else {
+ // run command
+ iRet = (pFsCmd->cmdProcess)(argc, argv);
+ }
+
+ // return command running result
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Parse a string line containing multi commands and arguments, then
+/// search in active groups, run if matched
+/// \param pMultiCmdStr, string line containing multi commands and arguments
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int ParseAndRunMultiCmds(const char * pMultiCmdStr)
+{
+ char pMultiCmdStrBuf[DBGU_CMDBUFSIZE];
+ char *cmds[MAX_MULTI_CMD + 1], *pCmdsStr;
+ unsigned int i;
+ int iRet;
+
+ //if NULL string, no run
+ if(!pMultiCmdStr)
+ return 0;
+
+ unsigned int strLength = strlen(pMultiCmdStr);
+
+ //empty string, no run
+ if(strLength == 0)
+ return 0;
+
+ if(strLength < DBGU_CMDBUFSIZE) {
+ strcpy(pMultiCmdStrBuf, pMultiCmdStr);
+ }
+ else {
+ memcpy(pMultiCmdStrBuf, pMultiCmdStr, DBGU_CMDBUFSIZE-1);
+ pMultiCmdStrBuf[DBGU_CMDBUFSIZE-1] = '\0';
+ }
+
+ i = 0;
+ pCmdsStr = (char *)(&pMultiCmdStrBuf[0]);
+ //parse multi commands
+ while(i < MAX_MULTI_CMD) {
+
+ // skip white space characters of string head
+ while ((*pCmdsStr == ' ') || (*pCmdsStr == '\t')) {
+ ++pCmdsStr;
+ }
+
+ if (*pCmdsStr == '\0') {
+ cmds[i] = NULL;
+ break;
+ }
+
+ cmds[i++] = pCmdsStr;
+
+ // parse commands
+ while (*pCmdsStr) {
+ if( ((*(pCmdsStr - 1) == ' ') || (*(pCmdsStr - 1) == '\t'))
+ && (*pCmdsStr == '&')
+ && (*(pCmdsStr + 1) == '&'))
+ break;// find the mark for next commands, then break
+ else
+ ++ pCmdsStr;
+ }
+
+ if (*pCmdsStr == '\0') {
+ cmds[i] = NULL;
+ break;
+ }
+
+ *(pCmdsStr - 1) = '\0';
+ pCmdsStr += 2;
+
+ }// end of parse
+
+ //if too many command in a line, warning
+ if(i >= MAX_MULTI_CMD)
+ printf ("\n\r Too many command in one line. Maximum cmds supported is %d!", MAX_MULTI_CMD);
+
+ unsigned int j;
+ for (j = 0; j < i; ++j) {
+ iRet |= ParseAndRunCmd(cmds[j]);
+ }
+
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Run batch command
+/// \param argc, number of command string
+/// \param argv, pointer array to command string
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int RunScript(int argc, char *argv[])
+{
+ int i, iRet=0;
+
+ // run script
+ for(i = 0; i<argc; ++i) {
+ iRet |= ParseAndRunMultiCmds(argv[i]);
+ }
+
+ return iRet;
+}
+
+//------------------------------------------------------------------------------
+/// Show all groups and commands, portal of command 'showall'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_ShowAllGrpCmd(int argc, char **argv)
+{
+ int i, j, iGrpCnt, iCmdCnt, iCmdNum;
+ char *pGrpList[MAX_LIST_GROUP+1];
+ FStruct *pCmdList[MAX_ACT_CMD];
+ FStruct *pFsStart, *pFsEnd, *pFsTmp;
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *) &__gs_section_start;
+ pFsEnd = (FStruct *) &__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ iCmdNum = pFsEnd - pFsStart;
+
+ //dumb, time consumption but less ram consumption way to list group
+ //get group list in section, MAX_LIST_GROUP limit
+ pGrpList[0] = NULL;
+ for(i=0,iGrpCnt=0; i<iCmdNum && iGrpCnt < MAX_LIST_GROUP; ++i) {
+
+ if(FindStrIdx((pFsStart+i)->pGrpName, pGrpList, MAX_LIST_GROUP) == -1) {
+ pGrpList[iGrpCnt++] = (pFsStart+i)->pGrpName;
+ pGrpList[iGrpCnt] = NULL;
+ }
+ }
+
+ if(iGrpCnt >= MAX_LIST_GROUP) {
+ printf("\n\r Only first 100 groups are shown!");
+ }
+
+ //list all command under group list, sorted
+ //Get command lists first
+ iGrpCnt=0;
+ while(pGrpList[iGrpCnt] != NULL) {
+ for(i=0,iCmdCnt=0;i<iCmdNum && iCmdCnt<MAX_ACT_CMD;++i) {
+ if(strcmp((pFsStart+i)->pGrpName, pGrpList[iGrpCnt]) ==0) {
+ pCmdList[iCmdCnt++]=pFsStart+i;
+ }
+ }
+
+ //show prompt info
+ if(iCmdCnt>=MAX_ACT_CMD) {
+ printf("\n\r Group: %s, (>=%d) commands", pGrpList[iGrpCnt], iCmdCnt);
+ } else {
+ printf("\n\r Group: %s, (%d) commands", pGrpList[iGrpCnt], iCmdCnt);
+ }
+
+ int bExchgFlag;
+ //sort command list
+ for(i = 0; i < iCmdCnt - 1; ++i) {
+ // flag, if no exchange, then array has been sorted
+ bExchgFlag = 0;
+
+ //bubble sort in ascending order
+ for(j = iCmdCnt - 1; j > i; --j){
+ if(strcmp(pCmdList[j]->pCmdName, pCmdList[j-1]->pCmdName) < 0) {
+ pFsTmp = pCmdList[j];
+ pCmdList[j] = pCmdList[j-1];
+ pCmdList[j-1] = pFsTmp;
+
+ // exchanged
+ bExchgFlag = 1;
+ }
+ }
+
+ // if no exchange, array sorted
+ if(!bExchgFlag)
+ break;
+ }
+
+ //print commands under group
+ for(i=0;i<iCmdCnt;++i) {
+ printf("\n\r %s",pCmdList[i]->pCmdName);
+ }
+
+ //check next group then
+ ++iGrpCnt;
+ }
+
+ printf("\n\r");
+
+ return 0;
+}
+
+///define a new system command 'showall'
+DFM_CMD(showall, DFM_ShowAllGrpCmd, "show all groups and commands.", SYS_GROUP);
+
+//------------------------------------------------------------------------------
+/// Show command help message, portal of command 'help'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_Help(int argc, char **argv)
+{
+ int i, iRet = 0;
+ FStruct *pTmpFs;
+
+ if(argc == 1) { // show all command in active groups
+ int j, iCmdNum, iCmdCnt, bExchgFlag;
+ FStruct *pFsCmds[MAX_ACT_CMD];
+ FStruct *pFsStart, *pFsEnd;
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *)&__gs_section_start;
+ pFsEnd = (FStruct *)&__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ //total command numbers in GSHELL_SECTION
+ iCmdNum = pFsEnd - pFsStart;
+
+ i = 0; iCmdCnt=0;
+ //get all commands in active groups
+ while(i < iCmdNum && iCmdCnt < MAX_ACT_CMD) {
+ if(FindStrIdx((pFsStart+i)->pGrpName, gpActGroups, MAX_ACT_GROUP) != -1) {
+ pFsCmds[iCmdCnt++] = pFsStart + i;
+ }
+ ++i;
+ }
+ //now 'iCmdCnt' has value of available command numbers in active groups
+ if(iCmdCnt < MAX_ACT_CMD) {
+ printf("\n\r Total %d commands available.\n\r", iCmdCnt);
+ } else {
+ printf("\n\r Too many, Only %d commands are shown!", MAX_ACT_CMD);
+ }
+
+
+ // sort active group commands for better help result print
+ for(i = 0; i < iCmdCnt - 1; ++i) {
+ // flag, if no exchange, then array has been sorted
+ bExchgFlag = 0;
+
+ //bubble sort in ascending order
+ for(j = iCmdCnt - 1; j > i; --j){
+ if(strcmp(pFsCmds[j]->pCmdName, pFsCmds[j-1]->pCmdName) < 0) {
+ pTmpFs = pFsCmds[j];
+ pFsCmds[j] = pFsCmds[j-1];
+ pFsCmds[j-1] = pTmpFs;
+
+ // exchanged
+ bExchgFlag = 1;
+ }
+ }
+
+ // no exchange, array sorted
+ if(!bExchgFlag)
+ break;
+ }
+
+ printf("\n\r");
+ //print command, and help message if there is
+ for(i = 0; i < iCmdCnt; ++i) {
+ if(pFsCmds[i] == NULL)
+ continue;
+
+ printf(" %s ",pFsCmds[i]->pCmdName);
+#ifdef USAGE_HELP
+ printf(" %s",pFsCmds[i]->pUsage);
+#endif
+ printf("\n\r");
+ }
+ //end of argc== 1
+
+ } else {
+
+ //print available command help or error message
+ for(i = 1; i < argc; ++i) {
+ pTmpFs = FindCommand(argv[i]);
+
+ if(pTmpFs != NULL) {
+
+#ifdef USAGE_HELP
+ printf("\n\r%s", pTmpFs->pCmdName);
+ if(pTmpFs->pUsage) {
+ printf(" %s\n\r",pTmpFs->pUsage);
+ } else {
+ printf(" <No help information>\n\r");
+ iRet = 1;
+ }
+
+#else
+ printf("\n\r <No usage help for '%s'>", argv[i]);
+
+#endif
+
+ } else {
+ printf("\n\r No command '%s' under active groups!\n\r", argv[i]);
+ iRet = 2;
+ }
+ }
+ }
+
+ return iRet;
+}
+
+///define a new system command 'help'
+DFM_CMD(help, DFM_Help, "help command usage", SYS_GROUP);
+
+//------------------------------------------------------------------------------
+/// Set active groups, portal of command 'setact'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_SetActiveGrp(int argc, char **argv)
+{
+ int i, iIdxList, iCmdNum, iRet = 0;
+ char *pGrpList[MAX_LIST_GROUP+1];
+ FStruct *pFsStart, *pFsEnd;
+
+ //fill array with NULL, last NULL will act as an end
+ for(i = 0; i < MAX_LIST_GROUP+1; ++i) {
+ pGrpList[i] = NULL;
+ }
+
+#if defined(__ICCARM__)
+ pFsStart = __section_begin(GSHELL_SECTION);
+ pFsEnd = __section_end(GSHELL_SECTION);
+#elif defined(__CC_ARM)
+ pFsStart = (FStruct *)&Image$$GShell_region$$Base;
+ pFsEnd = (FStruct *)&Image$$GShell_region$$Limit;
+#elif defined(__GNUC__)
+ pFsStart = (FStruct *)&__gs_section_start;
+ pFsEnd = (FStruct *)&__gs_section_end;
+#else
+#error "Unsupported tool chain"
+#endif
+
+ iCmdNum = pFsEnd - pFsStart;
+ //printf("\n\r pFsStart is %d", pFsStart);
+
+ if(argc == 1) { //show available groups for help
+
+ printf("\n\r Available Groups:\n\r");
+
+ //collect all buildin group names, only MAX_LIST_GROUP will be shown
+ for(i=0,iIdxList=0; i<iCmdNum && iIdxList<MAX_LIST_GROUP; ++i) {
+ //printf("\n\r group name is %s, cmd name is %s", (pFsStart+i)->pGrpName, (pFsStart+i)->pCmdName);
+ //no group name in list already
+ if(FindStrIdx((pFsStart+i)->pGrpName, pGrpList, MAX_LIST_GROUP) == -1) {
+ pGrpList[iIdxList++] = (pFsStart+i)->pGrpName;
+ //printf("\n\r %s", pGrpList[iIdxList-1]);
+ }
+ }
+
+
+ //show avail group list, MAX_LIST_GROUP
+ for(i=0; pGrpList[i] != NULL; ++i) {
+ printf(" %s\n\r", pGrpList[i]);
+ }
+
+ //reach MAX_LIST_GROUP, show info
+ if(i== MAX_LIST_GROUP) {
+ printf(" ...\n\r");
+ printf(" -Only '%d' groups will be shown!\n\r", MAX_LIST_GROUP);
+ }
+ // end of argc==1
+
+ } else {
+
+ int j,iIdxAct, bFindFlag = 0;
+
+ // used as index in active groups arrays below. Begin after 0(SYS_GROUP/"default")
+ // no appending mode. Previous active groups except SYS_GROUP/"default" will be removed,
+ // if not listed in *argv[].
+ iIdxAct = 1;
+
+ for(i = 1; i < argc ; ++i) {
+ //flag for group name argument match check/
+ bFindFlag = 0;
+
+ //reach limit number of MAX_ACT_GROUP
+ if(iIdxAct >= MAX_ACT_GROUP) {
+ printf("\n\rWarning : Active group number is limited within -'%d'- !\n\r",MAX_ACT_GROUP);
+ iRet = 1;//identify maxium active groups
+ break;
+ }
+
+ //default group is always active, and at the first priority
+ if(strcmp(argv[i], SYS_GROUP) == 0) {
+ continue;
+ }
+
+ //search for matched groups
+ for(j = 0; j < iCmdNum; ++j) {
+ if(strcmp(argv[i], (pFsStart+j)->pGrpName) == 0) {
+ bFindFlag = 1;
+ break;
+ }
+ }
+
+ //group name argument matched
+ if(bFindFlag) {
+ gpActGroups[iIdxAct++] = (pFsStart+j)->pGrpName;
+ } else {
+ printf("\n\r No group '%s' in available list!", argv[i]);
+ iRet = 2;// some error group name input
+ }
+ }
+
+ // no appending mode. previous active groups excetp SYS_GROUP/"default" will be removed,
+ // if not listed in *argv[].
+ while(iIdxAct < MAX_ACT_GROUP) {
+ gpActGroups[iIdxAct++] = NULL;
+ }
+
+ }
+
+ // show active group
+ i =0;
+ printf("\n\r\n\r ----Active Group: ");
+ while(gpActGroups[i] != NULL && i < MAX_ACT_GROUP) {
+ printf(" %s;", gpActGroups[i]);
+ i++;
+ }
+ printf(" ----\n\r");
+
+ return iRet;
+}
+
+///define a new system command 'setact'
+DFM_CMD(setact, DFM_SetActiveGrp, "set active groups", SYS_GROUP);
+
+#if defined(HELLO_TUTOR)
+//------------------------------------------------------------------------------
+/// A simple tutor for using gshell, portal of command 'showall'
+/// \param argc, number of argument
+/// \param argv, argument string array
+/// \return 0 succeed, other value failure
+//------------------------------------------------------------------------------
+int DFM_HelloTutor(int argc, char **argv)
+{
+ char *pTutorInfo = {
+ "\n\r -----------------------------Hello, World----------------------------"
+ "\n\r As a COMMAND 'thirsty' system, you may not know how to talk with me."
+ "\n\r I learnt much to write this message to explain how I can learn new "
+ "\n\r COMMANDs from you."
+ "\n\r"
+ "\n\r --- gs_cmd.h --- under project's --- include --- directory tell you"
+ "\n\r definitions of macros and limits of my system. Put it in your comma-"
+ "\n\r nd portal code's header or source file."
+ "\n\r"
+ "\n\r In this head file, an important macro acts as the translator that is"
+ "\n\r used to teach me your new commands:"
+ "\n\r DFM_CMD(cmdString, procFunc, hlpString, grpName)"
+ "\n\r"
+ "\n\r I'd like to tell you some rules about parameters of above macro."
+ "\n\r 'cmdString' is the command name you want to teach me. Double quota-"
+ "\n\r tion marks, \", is not necessary; 'procFunc' is the portal fuction t-"
+ "\n\r hat perform what this command do; 'hlpString' is help message to re-"
+ "\n\r member what is this command's usage, please note, double quotation "
+ "\n\r marks, \", is necessary; 'grpName' is double quoted string that cla-"
+ "\n\r ssify what group this command belongs to. Use it carefully to avoid "
+ "\n\r mess classification, because I don't limit the name choice."
+ "\n\r"
+ "\n\r The last thing remeber is definition of your portal function should has"
+ "\n\r the same number and type of parameters and return type like following:"
+ "\n\r int FuncName(int argc, char **argv)"
+ "\n\r"
+ "\n\r 'func' is normally pointed yourself portal function when I call this."
+ "\n\r 'argc' and '*argv[]' work as the same way that you learn C language, "
+ "\n\r but they are parsed from command string typed in my console window. "
+ "\n\r"
+ "\n\r If you want to see an example of teaching me a new command, try to type"
+ "\n\r this command under 'DFM_CMD:>' hello example"
+ "\n\r"
+ };
+
+ char *pTutorExample = {
+ "\n\r /* example, hi.c */"
+ "\n\r #include \"gs_cmd.h\""
+ "\n\r"
+ "\n\r int DFM_Hi(int argc, char *argv[])"
+ "\n\r {"
+ "\n\r printf(\"Command %s say HI!\", argv[0]);"
+ "\n\r }"
+ "\n\r"
+ "\n\r DFM_CMD(hi, DFM_Hi, \"say hi to everybody!\", \"default\");"
+ "\n\r\n\r"
+ };
+
+ if(argc == 2 && strcmp(argv[1], "example")==0) {
+ printf("\n\r%s", pTutorExample);
+ } else {
+ printf("\n\r%s", pTutorInfo);
+ }
+
+ return 0;
+}
+
+///define the new system command for tutor, 'hello'
+DFM_CMD(hello, DFM_HelloTutor, "A simple tutor for develop guide", SYS_GROUP);
+
+#endif
+
+
+//-----------------------------------------------------------------------------
+/// Exported Function
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Demo Frame main portal route to get command and interpret it to run
+/// \param argc, command number of initial running
+/// \param argv, pointer array to initial running command strings
+//------------------------------------------------------------------------------
+// void Gshell_MainProcess(int argc, char *argv[])
+// {
+// TCmdQueue *pCmdQueue;
+//
+// //Run autorun script
+// RunScript(argc, argv);
+//
+// //register input entry
+// RegisterInputEntry(&gDBGUEntry);
+// RegisterInputEntry(&gLCDEntry);
+// RegisterInputEntry(&gButtonEntry);
+//
+// ShowPrompt();
+//
+// while(1) {
+// if(!CommandIsReady())
+// continue;
+//
+// pCmdQueue = GetCommandQueue();
+//
+// RunCommandQueue(pCmdQueue);
+//
+// ShowPrompt();
+// }
+//
+// // while(1) {
+// //
+// // unsigned int index;
+// // if(index = TSD_CommandIsReady()) {
+// // pStr = TSD_GetCommand(index);
+// //
+// // printf("\n\r %s", pStr);
+// //
+// // }
+// //
+// // // Check DBGU console input is ready
+// // if(!DBGU_CommandIsReady())
+// // continue;
+// //
+// //
+// //#if 0
+// // //temp code to test sdcard and nandflash mount availability for every time
+// // // a new command is launched to run.
+// // FIL test;
+// // FRESULT res;
+// // unsigned int i;
+// // unsigned char buf[110];
+// //
+// // res = f_open(&test, SDCARD_ROOT_DIRECTORY"sam3demo.bin", FA_OPEN_EXISTING | FA_READ);
+// // if(res != FR_OK) {
+// // printf("\n\r Open file in SDCard fail!");
+// // } else {
+// // printf("\n\r Open file in SDCard succeed!");
+// // //test read file
+// // res = f_read(&test, buf, 100, &i);
+// // if(res!= FR_OK) {
+// // printf("\n\r --read first 100 bytes fail!");
+// // }else {
+// // printf("\n\r --read first 100 bytes succeeds!");
+// // }
+// // }
+// //
+// // f_close(&test);
+// //
+// // res = f_open(&test, NAND_ROOT_DIRECTORY"basic.bin", FA_OPEN_EXISTING | FA_READ);
+// // if(res != FR_OK) {
+// // printf("\n\r Open file in nandflash fail!");
+// // } else {
+// // printf("\n\r Open file in nandflash succeed!");
+// //
+// // res = f_read(&test, buf, 100, &i);
+// // if(res!= FR_OK) {
+// // printf("\n\r --read first 100 bytes fail!");
+// // }else {
+// // printf("\n\r --read first 100 bytes succeeds!");
+// // }
+// // }
+// // f_close(&test);
+// //#endif
+// //
+// //
+// // pStr = DBGU_GetCommand();
+// //
+// // // empty in DBGU command buffer
+// // if(*pStr == '\0') {
+// // continue;
+// // }
+// //
+// // if (strlen(pStr) >= DBGU_CMDBUFSIZE) {
+// // printf ("\n\r Command String is too long(max. %d)!\n\r", DBGU_CMDBUFSIZE);
+// // continue;
+// // }
+// //
+// // // create a local copy to protect console buffer
+// // strcpy (pCmdString, pStr);
+// //
+// // // parse and run command string
+// // ParseAndRunMultiCmds(pCmdString);
+// //
+// //// DBGU_ShowPrompt();
+// //// LCD_ShowPrompt();
+// //
+// // ShowPrompt();
+// // }
+// }
+
diff --git a/utility/demo-fw/common/dfm_console.c b/utility/demo-fw/common/dfm_console.c
new file mode 100644
index 0000000..7118a11
--- /dev/null
+++ b/utility/demo-fw/common/dfm_console.c
@@ -0,0 +1,216 @@
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <string.h>
+#include <dbgu/dbgu.h>
+#include <stdio.h>
+
+#include "dfm_console.h"
+#include "dfm_entry.h"
+#include "dfm_cmd.h"
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+///DBGU input buffer
+static char gpConsoleBuffer[DBGU_CMDBUFSIZE];
+
+///prompt refresh flag
+static unsigned char gDBGUPromptFlag = 0;
+
+///erase sequence
+static char gpEraseSeq[] = "\b \b";
+///used to expand TABS
+static char gpTabSeq[] = " ";
+
+//------------------------------------------------------------------------------
+// Export variables
+//------------------------------------------------------------------------------
+
+// global DBGU entry
+TInputEntry gDBGUEntry = \
+ {0, {NULL,NULL},DBGU_ShowPrompt, DBGU_CommandIsReady, DBGU_GetCommand, NULL};
+
+//------------------------------------------------------------------------------
+// Internal functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// output a string to console
+/// \param pStr, string to output to DBGU console
+//------------------------------------------------------------------------------
+static inline void DBGU_puts(const char *pStr)
+{
+ while(*pStr) {
+ DBGU_PutChar(*pStr++);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// remove charaters from buffer positions
+//------------------------------------------------------------------------------
+static char * DBGU_RemoveCharFromBuf (char *buffer, char *p, int *colp, int *np, int plen)
+{
+ char *s;
+
+ if (*np == 0) {
+ return (p);
+ }
+
+ if (*(--p) == '\t') {
+ while (*colp > plen) {
+ DBGU_puts (gpEraseSeq);
+ (*colp)--;
+ }
+ for (s=buffer; s<p; ++s) {
+ if (*s == '\t') {
+ DBGU_puts (gpTabSeq+((*colp) & 07));
+ *colp += 8 - ((*colp) & 07);
+ } else {
+ ++(*colp);
+ DBGU_PutChar (*s);
+ }
+ }
+ } else {
+ DBGU_puts (gpEraseSeq);
+ (*colp)--;
+ }
+ (*np)--;
+ return (p);
+}
+
+//------------------------------------------------------------------------------
+/// Check console is ready?
+/// \return 0 not ready, other value means ready and command string length
+//------------------------------------------------------------------------------
+unsigned int DBGU_CommandIsReady()
+{
+ unsigned char c;
+ static char *p = gpConsoleBuffer;
+ int escflag = 0;
+ char * p_buf = gpConsoleBuffer;
+ static int n = 0; // buffer index
+ int plen = 0; // prompt length
+ static int col=0; // output column cnt
+ unsigned int cmdLen;
+
+ plen = strlen(GS_SHELL_PROMPT);
+
+ //right beginning of a new command input
+ if(col == 0)
+ col = plen;
+
+Tag_for_CombinedKey:
+
+ if(DBGU_IsRxReady()) {
+ c = DBGU_GetChar();
+
+ //
+ // Special character handling
+ //
+ switch (c) {
+ case '\r': // Enter
+ case '\n':
+ *p = '\0';
+ cmdLen = p - p_buf;
+ p = gpConsoleBuffer;
+ n = 0; //clear buffer index as 0
+ col = 0; // this is set for indicate next time input considered as new command
+ gDBGUPromptFlag = 1;//DBGU_puts ("\r\n");
+ return cmdLen;
+
+ case '\0': // nul
+ return 0;
+
+ case 0x03: // ^C - break
+ //p_buf[0] = '\0'; // discard input
+ return 0;
+
+ case 0x15: // ^U - erase line
+ while (col > plen) {
+ DBGU_puts (gpEraseSeq);
+ --col;
+ }
+ p = p_buf;
+ n = 0;
+ return 0;
+
+ case 0x17: // ^W - erase word
+ p=DBGU_RemoveCharFromBuf(p_buf, p, &col, &n, plen);
+ while ((n > 0) && (*p != ' ')) {
+ p=DBGU_RemoveCharFromBuf(p_buf, p, &col, &n, plen);
+ }
+ return 0;
+
+ case 0x08: // ^H - backspace
+ case 0x7F: // DEL - backspace
+ p=DBGU_RemoveCharFromBuf(p_buf, p, &col, &n, plen);
+ return 0;
+
+ case 0x1b: // arrow, home flag
+ escflag = 1;
+ goto Tag_for_CombinedKey;//in window hyperterminal, arrow and home flag
+ // keys are combined 1b + x
+
+ case 'D': //ignore arrow,home key
+ case 'C':
+ case 'H':
+ case 'A':
+ case 'B':
+ if(escflag) {
+ escflag = 0;
+ return 0;
+ }
+
+
+ default:
+ //
+ // Must be a normal character then
+ //
+ if (n < DBGU_CMDBUFSIZE-2) {
+ if (c == '\t') { // expand TABs
+ DBGU_puts (gpTabSeq+(col&07));
+ col += 8 - (col&07);
+ } else {
+ ++col; // echo input
+ DBGU_PutChar (c);
+ }
+ *p++ = c;
+ ++n;
+ } else { // Buffer full
+ DBGU_PutChar ('\a');
+ }
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// get a const pointer to global console input buffer
+/// \return pointer to global DBGU console input buffer
+//------------------------------------------------------------------------------
+const char * DBGU_GetCommand() {
+ return (const char *)gpConsoleBuffer;
+}
+
+//------------------------------------------------------------------------------
+/// Show DBGU console prompt information
+/// \return 0, success
+//------------------------------------------------------------------------------
+int DBGU_ShowPrompt()
+{
+
+#if defined(GS_SHELL_PROMPT)
+ // print prompt
+ if(gDBGUPromptFlag) {
+ DBGU_puts("\n\r");
+ DBGU_puts (GS_SHELL_PROMPT);
+ gDBGUPromptFlag = 0;
+ }
+#endif
+
+ return 0;
+}
diff --git a/utility/demo-fw/common/dfm_dispboxmgr.c b/utility/demo-fw/common/dfm_dispboxmgr.c
new file mode 100644
index 0000000..55ad223
--- /dev/null
+++ b/utility/demo-fw/common/dfm_dispboxmgr.c
@@ -0,0 +1,481 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <string.h>
+#include <stdio.h>
+#include <lcd/font.h>
+#include <lcd/color.h>
+#include <lcd/draw.h>
+#include <components/hx8347/hx8347.h>
+#include <utility/trace.h>
+
+#include "dfm_config.h"
+#include "dfm_dispboxmgr.h"
+#include "dfm_accelerometer.h"
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+static TDISPBOX_MGR dispBoxMgr= {
+ 0,
+ {{0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0},
+ {0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0},
+ {0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0},
+ {0, {0,0,0,0}, COLOR_WHITE, COLOR_BLUE, 0, 0}}
+};
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Set default background color of display box
+//------------------------------------------------------------------------------
+void SetDispBoxBGColor(unsigned int dispBoxID, unsigned int color)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor = color;
+}
+
+//------------------------------------------------------------------------------
+/// set default Font Color of display box
+//------------------------------------------------------------------------------
+void SetDispBoxFontColor(unsigned int dispBoxID, unsigned int color)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].fontColor = color;
+}
+
+//------------------------------------------------------------------------------
+/// set display box position info
+//------------------------------------------------------------------------------
+void SetDispBoxPos(unsigned int dispBoxID,
+ unsigned int enableDispBox,
+ unsigned int top,
+ unsigned int left,
+ unsigned int width,
+ unsigned int height)
+{
+ if(dispBoxID > dispBoxMgr.dispBoxCount) {
+ if(dispBoxID < MAX_DISPBOX_PER_SLIDE) {
+ ++dispBoxMgr.dispBoxCount;
+ } else
+ return;
+ }
+
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable = enableDispBox;
+ if(enableDispBox) {
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top = top;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.left = left;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.width = width;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.height = height;
+
+ //set x,y start position
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].xCursor = \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.left + DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].yCursor = \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top + DISPMARGIN;
+
+ if(gDir > 0 && gDir < 3)
+ {
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.left + width) - DISPMARGIN ;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top + DISPMARGIN;
+ }
+
+ }
+}
+
+//------------------------------------------------------------------------------
+/// enable display box
+//------------------------------------------------------------------------------
+void EnableDispBox(unsigned int dispBoxID)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable = DISPBOX_ENABLE;
+}
+
+//------------------------------------------------------------------------------
+/// disable display box
+//------------------------------------------------------------------------------
+void DisableDispBox(unsigned int dispBoxID)
+{
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable = DISPBOX_DISABLE;
+}
+
+//------------------------------------------------------------------------------
+/// Check if any display box region is available
+/// \return 0 mean no display box, other means yes and value is number of display box
+//------------------------------------------------------------------------------
+unsigned int IsDispBoxRegionAvail()
+{
+ if(!dispBoxMgr.dispBoxCount) {
+ return 0;
+ }
+
+ return dispBoxMgr.dispBoxCount;
+}
+
+//------------------------------------------------------------------------------
+/// Check if the required display box is enabled
+/// \return 0 mean no display box, other means yes
+//------------------------------------------------------------------------------
+unsigned int IsDispBoxEnable(unsigned int dispBoxID)
+{
+ if(!dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxEnable)
+ return DISPBOX_DISABLE;
+
+ return DISPBOX_ENABLE;
+}
+
+//------------------------------------------------------------------------------
+/// Draw a string in display box with 'color'
+/// \param pBuffer, LCD base address
+/// \param dispBoxID, display box ID
+/// \param pStr, string to draw
+/// \param fontColor, font color
+/// \param bgColor, background color
+/// \param scrollFlag, idendtify if cleaning display box zone when scrolling back
+/// to display box start position
+//------------------------------------------------------------------------------
+void DrawStringInDispBox(
+ //pointer to LCD base address
+ void *pBuffer,
+ //display box index
+ unsigned int dispBoxID,
+ //pointer to string for show
+ const char *pStr,
+ //display string font color,
+ unsigned int fontColor,
+ //display string background color, 0xFFFFFFFF means no need to set bgColor
+ unsigned int bgColor,
+ //flag for scroll way, current only support 'clear or not clear display box'
+ //when display string reach end and roll back to show.
+ //0 means clear, 1 means don't clear.
+ unsigned int scrollFlag)
+{
+ unsigned int strWidth = 0;
+ unsigned int strHeight = 0;
+ extern const Font gFont;
+ const char *pString = pStr;
+
+ //text direction
+ unsigned int dir = 0;
+
+ ////////////////////////////////////
+ unsigned int width = 0;
+ unsigned int height = 0;
+ unsigned int left = 0;
+ unsigned int top = 0;
+ ///////////////////////////////////
+ TRACE_DEBUG(" draw string on lcd len is %u\n\r", strlen(pStr));
+
+ //no display box or disabled
+ if(!IsDispBoxRegionAvail() || !IsDispBoxEnable(dispBoxID)) {
+ //then display information on DBGU console;
+ printf("\n\r %s", pStr);
+ return;
+ }
+
+#if defined(LCDC_HX8347)
+
+
+ if(LCDD_IsBusy()) return;
+
+ LCDD_SetBusy();
+
+ //a temp way to resolve display direction. Further will be improved based on requirement
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x16, 0x68);//); // MY=1, MX=0, MV=1, BGR=1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x02, 0x00); // Column address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x03, 0x00); // Column address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x04, 0x01); // Column address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x05, 0x3F); // Column address end1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x06, 0x00); // Row address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x07, 0x00); // Row address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x08, 0x00); // Row address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x09, 0xEF); // Row address end1
+
+ LCDD_ClearBusy();
+#endif
+ ////////////////////////////////////////////
+
+ if(gDir < 3 && gDir > 0)
+ //if(gDir >= 3 || gDir == 0)
+ {
+ // the protrait view,coordinates was changed after loading
+ //the Y is mirrored and x-y changed
+ height = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.width;
+ //the width is to meet the algorithm calculating string lines
+
+ width = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.height;
+ //it's strange but useful
+ left = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.left + height;
+ top = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.top ;
+
+
+ //for vertical
+ dir = 1;
+
+
+ }
+ else
+ {
+ width = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.width;
+ height = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.height;
+ top = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.top;
+ left = dispBoxMgr.dispBoxInfo[dispBoxID-1].dispBoxZone.left;
+
+ dir = 0;
+
+ }
+ //count lines the string will use
+ ////////////////////////////////////////////
+ //back from start of display box, then clear dispbox zone
+
+
+ if(\
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor == \
+ left + DISPMARGIN) \
+ && \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor == \
+ top + LINEDISTANCE)\
+ )
+ {
+ ClearDispBoxZoneDefault(dispBoxID);
+ }
+
+ if(dir)
+ {
+ if(\
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor == \
+ left - DISPMARGIN) \
+ && \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor == \
+ top + LINEDISTANCE)\
+ )
+ {
+ ClearDispBoxZoneDefault(dispBoxID);
+ }
+ }
+
+ LCDD_GetStringSize(pString, &strWidth, &strHeight);
+
+ TRACE_DEBUG(" string width and height in pixel is %u, %u\n\r", strWidth, strHeight);
+
+ //count lines the string will use
+ unsigned int linecnt = \
+ (strWidth + CHARDISTANCE) \
+ / (width - DISPMARGIN) + 1;
+
+ //get how many chars the dispbox width can show
+ //to be consistent with lib API, a char width is gFont.width + CHARDISTANCE
+ unsigned int numCharLine = (width - DISPMARGIN) \
+ / (gFont.width + CHARDISTANCE) - 1;
+
+ //if line count larger than current position to bottom of dispbox, clear dispbox area,
+ //reinit x,y to start of dispbox
+ if( linecnt * (gFont.height + LINEDISTANCE) \
+ > \
+ (height - \
+ (dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor - \
+ top - LINEDISTANCE))\
+ )
+ {
+ if(scrollFlag == 0) {
+ LCDD_DrawRectangle((void *)BOARD_LCD_BASE,
+ left,
+ top,
+ width,
+ height,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].bgColor);
+ }
+
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ left + DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ top + LINEDISTANCE;
+ }
+
+ if(dir)
+ {
+ if( linecnt * (gFont.height + LINEDISTANCE) \
+ > \
+ (height - \
+ (left - dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor \
+ - LINEDISTANCE))\
+ )
+ {
+ if(scrollFlag == 0) {
+ // LCDD_DrawRectangle((void *)BOARD_LCD_BASE,
+ // left,
+ // top,
+ // width,
+ // height,
+ // dispBoxMgr.dispBoxInfo[dispBoxID-1].bgColor);
+ ClearDispBoxZoneDefault(dispBoxID);
+ }
+
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ left - DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ top + LINEDISTANCE;
+ }
+ }
+
+ //if whole string show height larger than dispbox height, then only show the content
+ //inside dispbox, the rest is not shown any more
+ if((linecnt * (gFont.height + LINEDISTANCE) > \
+ height)) {
+ linecnt = height / (gFont.height+LINEDISTANCE);
+ //shrink string to a full dispbox size.
+ strWidth = linecnt * numCharLine * (gFont.width+CHARDISTANCE);
+ }
+
+ TRACE_DEBUG(" numcharline is %u, linecnt is %u\n\r", numCharLine, linecnt);
+
+ unsigned int i;
+ for(i = 0; i < linecnt; ++i) {
+ char stringline[80];
+ if(i == linecnt - 1) {
+ //the last char doesn't have additional CHARDISTANCE, to meet API in lib
+ memcpy(stringline, pString, (strWidth+CHARDISTANCE) / (gFont.width+CHARDISTANCE) + 1);
+ stringline[(strWidth+CHARDISTANCE)/(gFont.width+CHARDISTANCE)] = '\0';
+ } else {
+ memcpy(stringline, pString, numCharLine);
+ stringline[numCharLine] = '\0';
+ strWidth -= numCharLine * (gFont.width+CHARDISTANCE);
+ }
+
+ //forward pString to next line
+ pString += numCharLine;
+
+ //draw string
+ if(bgColor == 0xFFFFFFFF) {
+ LCDD_DrawStringEx((void *)BOARD_LCD_BASE,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor,
+ stringline,
+ fontColor,dir);
+ }else {
+ LCDD_DrawStringWithBGColorEx((void *)BOARD_LCD_BASE,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor,
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor,
+ stringline,
+ fontColor,
+ bgColor,dir);
+ }
+
+ //move x, y to next line, to be consistent with lib api, height is gFont.height + 2
+ if(dir)
+ {
+ // xCursor is vertical to the direction of text,along with the lines of text
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor -= (gFont.height + LINEDISTANCE);
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor = \
+ top + DISPMARGIN;
+
+ }
+ else
+ {
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].xCursor = \
+ left + DISPMARGIN;
+ dispBoxMgr.dispBoxInfo[dispBoxID-1].yCursor += gFont.height + LINEDISTANCE;
+ }
+
+ }
+
+#if defined(LCDC_HX8347)
+
+ if(LCDD_IsBusy()) return;
+
+ LCDD_SetBusy();
+
+ //restore previous direction setting
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x16, 0xC8);//); // MY=1, MX=1, MV=0, BGR=1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x02, 0x00); // Column address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x03, 0x00); // Column address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x04, 0x00); // Column address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x05, 0xEF); // Column address end1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x06, 0x00); // Row address start2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x07, 0x00); // Row address start1
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x08, 0x01); // Row address end2
+ LCD_WriteReg((void *)BOARD_LCD_BASE, 0x09, 0x3F); // Row address end1
+
+ LCDD_ClearBusy();
+#endif
+}
+
+//Draw a string in display box with default font and background color
+//if scroll back then clear
+void DrawStrInDispBoxDefault(void *pBuffer, unsigned int dispBoxID, const char *pStr)
+{
+ DrawStringInDispBox(
+ pBuffer,
+ dispBoxID,
+ pStr,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].fontColor,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor,
+ 0);
+}
+
+//Draw a string in display box with default font and background color
+//if scroll back, don't clear
+void DrawStrInDispBoxScrollNoClear(void *pBuffer, unsigned int dispBoxID, const char *pStr)
+{
+ DrawStringInDispBox(
+ pBuffer,
+ dispBoxID,
+ pStr,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].fontColor,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor,
+ 1);
+}
+
+//clear display box zone with color
+void ClearDispBoxZoneColor(unsigned int dispBoxID, unsigned int color)
+{
+ if(IsDispBoxRegionAvail() && IsDispBoxEnable(dispBoxID)) {
+
+ LCDD_DrawRectangle((void *)BOARD_LCD_BASE, \
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.left,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.top,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.width,
+ dispBoxMgr.dispBoxInfo[dispBoxID - 1].dispBoxZone.height,
+ color);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Clear display box with default background color
+//------------------------------------------------------------------------------
+void ClearDispBoxZoneDefault(unsigned int dispBoxID)
+{
+ ClearDispBoxZoneColor(dispBoxID, dispBoxMgr.dispBoxInfo[dispBoxID - 1].bgColor);
+}
diff --git a/utility/demo-fw/common/dfm_entry.c b/utility/demo-fw/common/dfm_entry.c
new file mode 100644
index 0000000..f70c2f6
--- /dev/null
+++ b/utility/demo-fw/common/dfm_entry.c
@@ -0,0 +1,142 @@
+
+#include "dfm_entry.h"
+#include "dfm_cmd.h"
+
+//-----------------------------------------------------------------------------
+/// Internal Variables
+//-----------------------------------------------------------------------------
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+//point to first input entry
+static TInputEntry *gpFirstInputEntry = NULL;
+
+//-----------------------------------------------------------------------------
+/// Exported Function
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// register prompt display entry fucntion into prompt list for calling
+/// The image should be same size as the LCD.
+/// \param pPromptFunc, pointer to global variable of prompt display function
+/// \return 0 success, other value fail
+//------------------------------------------------------------------------------
+int RegisterInputEntry(TInputEntry *pEntryStruct)
+{
+ TInputEntry *pTmpEntry;
+
+ pTmpEntry = gpFirstInputEntry;
+
+ if(pTmpEntry == NULL) {
+ gpFirstInputEntry = pEntryStruct;
+ gpFirstInputEntry->next = NULL;
+
+ return 0;
+ }
+
+ while(pTmpEntry->next != NULL)
+ pTmpEntry = pTmpEntry->next;
+
+ pTmpEntry->next = pEntryStruct;
+ pEntryStruct->next = NULL;
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+/// Calling prompt display entry chained in prompt list
+/// \return 0 success, other value fail
+//------------------------------------------------------------------------------
+int ShowPrompt()
+{
+ TInputEntry *pTmpEntry;
+
+ pTmpEntry = gpFirstInputEntry;
+ while(pTmpEntry != NULL) {
+ //printf("\n\r ********DisplayPrompt********* ");
+ if(pTmpEntry->Prompt)
+ pTmpEntry->Prompt();
+ pTmpEntry = pTmpEntry->next;
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+/// Check if any command is ready in all input entry, if yes, set the flag
+/// \return 0 no command ready, other means yes and value represents number of
+/// ready input entry
+//------------------------------------------------------------------------------
+unsigned int CommandIsReady()
+{
+ unsigned int ret = 0;
+ TInputEntry *pTmpEntry;
+
+ pTmpEntry = gpFirstInputEntry;
+ while(pTmpEntry != NULL) {
+ if(pTmpEntry->CommandIsReady && pTmpEntry->CommandIsReady()) {
+ pTmpEntry->readyFlag = 1;
+ ++ ret;
+ }
+
+ pTmpEntry = pTmpEntry->next;
+ }
+
+ return ret;
+}
+
+//-----------------------------------------------------------------------------
+/// Get Command Queue
+/// \return 0 no command ready, other means ready and value is available numbers
+//------------------------------------------------------------------------------
+TCmdQueue * GetCommandQueue()
+{
+ TInputEntry *pTmpEntry;
+ TCmdQueue *pQueueFirst, *pTmpQueue = NULL;
+
+ pTmpEntry = gpFirstInputEntry;
+ while(pTmpEntry != NULL) {
+ //check if command ready flag is set
+ if(pTmpEntry->readyFlag) {
+
+ if(pTmpQueue == NULL) {
+ //Set pointer to first available command element of queue
+ pQueueFirst = &(pTmpEntry->CmdElement);
+ pTmpQueue = pQueueFirst;
+ } else {
+ pTmpQueue->next = &(pTmpEntry->CmdElement);
+ pTmpQueue = pTmpQueue->next;
+ }
+
+ pTmpQueue->command = pTmpEntry->GetCommand();
+ pTmpQueue->next = NULL;
+
+ pTmpEntry->readyFlag = 0;
+ }
+
+ pTmpEntry = pTmpEntry->next;
+ }
+
+ return pQueueFirst;
+}
+
+//-----------------------------------------------------------------------------
+/// Run Command Queue
+/// \return 0 success for all, other value fail
+//------------------------------------------------------------------------------
+int RunCommandQueue(TCmdQueue *pCmdQueue)
+{
+ int ret = 0;
+ TCmdQueue *pTmpQueue;
+
+ pTmpQueue = pCmdQueue;
+ while(pTmpQueue != NULL) {
+ ret |= ParseAndRunMultiCmds(pTmpQueue->command);
+ pTmpQueue = pTmpQueue->next;
+ }
+
+ return ret;
+}
diff --git a/utility/demo-fw/common/dfm_fatfs.c b/utility/demo-fw/common/dfm_fatfs.c
new file mode 100644
index 0000000..20348a0
--- /dev/null
+++ b/utility/demo-fw/common/dfm_fatfs.c
@@ -0,0 +1,384 @@
+#include "dfm_fatfs.h"
+#include "dfm_init.h"
+//#include <memories/MEDSdcard.h>
+//#include <utility/trace.h>
+//#include <string.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <irq/irq.h>
+#include <board.h>
+#include <board_memories.h>
+#include <string.h>
+#include <utility/assert.h>
+#include <utility/math.h>
+#include <utility/bmp.h>
+#include <lcd/color.h>
+#include <lcd/lcdd.h>
+#include <lcd/draw.h>
+#include <tsd/tsd.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/device/core/USBD.h>
+#include <usb/device/massstorage/MSDDriver.h>
+#include <usb/device/massstorage/MSDLun.h>
+#include <usb/device/core/USBDCallbacks.h>
+#include <memories/MEDSdcard.h>
+#include <components/hx8347/hx8347.h>
+#include <systick/systick.h>
+#include <flash/flashd.h>
+
+#if defined(PINS_NANDFLASH)
+#include <memories/MEDNandFlash.h>
+#include <memories/nandflash/RawNandFlash.h>
+#include <memories/nandflash/TranslatedNandFlash.h>
+#endif
+
+#include "fatfs_config.h"
+
+#include <hx8347/hx8347.h>
+
+#include "dfm_dispboxmgr.h"
+#include "dfm_config.h"
+#include "dfm_cmd.h"
+#include "dfm_varloc.h"
+
+/// Available medias.
+RLOC_OBJ Media medias[MAX_LUNS] _AT(FATFS_MEDIA_OBJ_ADDR);
+
+#if defined(PINS_NANDFLASH)
+/// Pins used to access to nandflash.
+const Pin gpPinsNf[] = {PINS_NANDFLASH};
+/// Nandflash device structure.
+RLOC_OBJ struct TranslatedNandFlash gTranslatedNf _AT(NANDFLASH_TRANS_TAB_ADDR);
+/// Address for transferring command bytes to the nandflash.
+unsigned int gNFCmdBytesAddr = BOARD_NF_COMMAND_ADDR;
+/// Address for transferring address bytes to the nandflash.
+unsigned int gNFAddrBytesAddr = BOARD_NF_ADDRESS_ADDR;
+/// Address for transferring data bytes to the nandflash.
+unsigned int gNFDataBytesAddr = BOARD_NF_DATA_ADDR;
+/// Nandflash chip enable pin.
+const Pin gNFCePin = BOARD_NF_CE_PIN;
+/// Nandflash ready/busy pin.
+const Pin gNFRbPin = BOARD_NF_RB_PIN;
+#endif
+
+//---------------------------------------------------------------------
+/// enable fatfs on SDCard
+//---------------------------------------------------------------------
+int Fatfs_Init_Share()
+{
+ TRACE_DEBUG("\n\r FatFs max media is %u (MAX_LUNS)!", numMedias);
+ numMedias = MAX_LUNS;
+
+ return 0;
+}
+
+DFM_INIT(7, Fatfs_Init_Share);
+
+////////////////////////////
+/// enable fatfs on SDCard /
+////////////////////////////
+
+#if defined(DFM_FATFS_SDCARD)
+//used to mount fatfs on sdcard
+RLOC_OBJ static FATFS fs_sdcard _AT(FATFS_SDCARD_OBJ_ADDR);
+//------------------------------------------------------------------------------
+/// Init sdcard for FatFS
+/// \return 0 succeed, other value failure
+//-----------------------------------------------------------------------------
+int FatFs_SDCard_Init()
+{
+ FRESULT res;
+
+ if(MEDSdcard_Detect(&medias[DRV_MMC], MCI_ID)) {
+
+ if (!MEDSdcard_Initialize(&medias[DRV_MMC], MCI_ID)) {
+ // Initialize sdcard failed
+ TRACE_ERROR("-E- SD Init fail\n\r");
+ return -1;
+ }
+
+ // Mount disk
+ printf("-I- Mount disk %d \n\r", DRV_MMC);
+
+ memset(&fs_sdcard, 0, sizeof(FATFS));
+ res = f_mount(DRV_MMC, &fs_sdcard);
+ if( res != FR_OK ) {
+ TRACE_ERROR("-E- f_mount pb: 0x%X\n\r", res);
+ return -1;
+ }
+
+ DIR dir;
+ // Test if the disk is formated
+ res = f_opendir (&dir,SDCARD_ROOT_DIRECTORY);
+ if(res == FR_OK ){
+
+ TRACE_INFO("-I- The disk is already formated. \n\r");
+ TRACE_INFO("-I- Display files contained on the SDcard :\n\r");
+ //FF_ScanDir(SDCARD_ROOT_DIRECTORY);
+ }
+ else {
+ TRACE_ERROR("-I- The disk is not formated. Exit! \n\r");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ //no sdcard detected in MCI slot
+ return -1;
+}
+
+//Init SDCard in level 6
+//lvl6_init(FatFs_SDCard_Init);
+//_define_init_lvl("6", FatFs_SDCard_Init, 6);
+DFM_INIT(6, FatFs_SDCard_Init);
+
+#endif //end of DFM_FATFS_SDCARD
+
+///////////////////////////////
+/// enable fatfs on nandflash /
+///////////////////////////////
+#if defined(DFM_FATFS_NANDFLASH)
+//used to mount fatfs on nand flash
+RLOC_OBJ static FATFS fs_nandflash _AT(FATFS_NANDFLASH_OBJ_ADDR);
+
+//------------------------------------------------------------------------------
+/// Init Nandflash for FatFS
+/// \return 0 succeed, other value failure
+//-----------------------------------------------------------------------------
+int FatFs_NandFlash_Init()
+{
+ unsigned int delay = 0;
+ unsigned char nfBusWidth = 16, nfRc;
+ unsigned short nfBaseBlock = 0;
+ struct RawNandFlash *pRaw = (struct RawNandFlash*)&gTranslatedNf;
+ struct NandFlashModel *pModel = (struct NandFlashModel*)&gTranslatedNf;
+ unsigned int nfMamagedSize;
+
+ // Configure SMC for NandFlash
+ BOARD_ConfigureNandFlash(nfBusWidth);
+ // Configure PIO for Nand Flash
+ PIO_Configure(gpPinsNf, PIO_LISTSIZE(gpPinsNf));
+
+ // Nand Flash Initialize (ALL flash mapped)
+ nfRc = RawNandFlash_Initialize(pRaw,
+ 0,
+ gNFCmdBytesAddr,
+ gNFAddrBytesAddr,
+ gNFDataBytesAddr,
+ gNFCePin,
+ gNFRbPin);
+ if (nfRc) {
+ printf("Nand not found\n\r");
+ return -1;
+ }
+ else {
+ printf("NF\tNb Blocks %d\n\r",
+ NandFlashModel_GetDeviceSizeInBlocks(pModel));
+ printf("\tBlock Size %uK\n\r",
+ (unsigned int)NandFlashModel_GetBlockSizeInBytes(pModel)/1024);
+ printf("\tPage Size %d\n\r",
+ NandFlashModel_GetPageDataSize(pModel));
+ nfBaseBlock =
+ NF_RESERVE_SIZE / NandFlashModel_GetBlockSizeInBytes(pModel);
+ }
+ printf("NF disk will use area from %dM(B%d)\n\r",
+ NF_RESERVE_SIZE/1024/1024, nfBaseBlock);
+#if 0
+ printf("!! Erase the NF Disk? (y/n):");
+ //updateDelay = INPUT_DELAY;
+ //updateView = 0;
+ while(1) {
+ if(DBGU_IsRxReady()) {
+ char key = DBGU_GetChar();
+ DBGU_PutChar(key);
+ if (key == 'y') {
+ if (nfRc == 0) {
+ unsigned int block;
+ printf(" Erase from %d ... ", nfBaseBlock);
+ for (block = nfBaseBlock;
+ block < NandFlashModel_GetDeviceSizeInBlocks(pModel);
+ block ++) {
+ RawNandFlash_EraseBlock(pRaw, block);
+ }
+ printf("OK");
+ }
+ }
+ printf("\n\r");
+ break;
+ }
+
+ if (++ delay > 0x800000) {
+ printf("n\n\r");
+ break;
+ }
+ }
+#endif
+
+ nfMamagedSize = ((NandFlashModel_GetDeviceSizeInMBytes(pModel) - NF_RESERVE_SIZE/1024/1024) > NF_MANAGED_SIZE/1024/1024) ? \
+ NF_MANAGED_SIZE/1024/1024 : (NandFlashModel_GetDeviceSizeInMBytes(pModel) - NF_RESERVE_SIZE/1024/1024);
+ if (TranslatedNandFlash_Initialize(&gTranslatedNf,
+ 0,
+ gNFCmdBytesAddr,
+ gNFAddrBytesAddr,
+ gNFDataBytesAddr,
+ gNFCePin,
+ gNFRbPin,
+ nfBaseBlock, nfMamagedSize * 1024 * 1024/NandFlashModel_GetBlockSizeInBytes(pModel))) {
+ printf("Nand init error\n\r");
+ return -1;
+ }
+ // Check the data bus width of the NandFlash
+ nfBusWidth =
+ NandFlashModel_GetDataBusWidth(pModel);
+ BOARD_ConfigureNandFlash(nfBusWidth);
+
+ // Media initialize
+ MEDNandFlash_Initialize(&medias[DRV_NAND], &gTranslatedNf);
+
+ // Initialize LUN
+ // LUN_Init(&(luns[DRV_NAND]), &(medias[DRV_NAND]),
+ // msdBuffer, MSD_BUFFER_SIZE,
+ // 0, 0, 0, 0,
+ // 0);
+ //printf("\n\r Init Nandflash is temp ignored!");
+// ++numMedias;
+
+ FRESULT res;
+ // Mount Disk
+ printf("-I- Mount disk 1\n\r");
+ memset(&fs_nandflash, 0, sizeof(FATFS)); // Clear file system object
+ res = f_mount(DRV_NAND, &fs_nandflash);
+ if( res != FR_OK ) {
+ printf("-E- f_mount pb: 0x%X\n\r", res);
+ //return 0;
+ }
+
+ DIR dir;
+ // Test if the disk is formated
+ res = f_opendir (&dir,NAND_ROOT_DIRECTORY);
+ if(res == FR_OK ){
+
+ // erase NAND to re-format it ?
+ printf("-I- The disk is already formated.\n\r");
+
+ // Display the file tree
+ printf("-I- Display files contained on the NAND :\n\r");
+ //FF_ScanDir(NAND_ROOT_DIRECTORY);
+#if 0
+ printf("-I- Erase the NAND to re-format disk ? (y/n)!\n\r");
+
+ unsigned char key = DBGU_GetChar();
+ if( (key == 'y') || (key == 'Y'))
+ {
+ TranslatedNandFlash_EraseAll(&gTranslatedNf ,NandEraseDATA);
+ res = FR_NO_FILESYSTEM;
+ }
+#endif
+ } else {
+ TRACE_ERROR(" Open fatfs on nand flash fail!\n\r");
+ return -1;
+ }
+
+
+ return 0;
+}
+
+//Init nandflash In level 6
+DFM_INIT(6, FatFs_NandFlash_Init);
+
+#endif //end of DFM_FATFS_NANDFLASH
+
+
+//------------------------------------------------------------------------------
+/// Configures the EBI for NandFlash access according to MCK.
+/// \param mck working MCK
+//------------------------------------------------------------------------------
+void ConfigureNandFlashEBI(unsigned int mck)
+{
+ AT91PS_HSMC4_CS pSMC = AT91C_BASE_HSMC4_CS1;
+
+ if (mck <= 48000000) {
+ pSMC->HSMC4_SETUP = 0
+ | ((0 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((1 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((0 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((1 << 24) & AT91C_HSMC4_NCS_RD_SETUP);
+
+ pSMC->HSMC4_PULSE = 0
+ | ((2 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | ((3 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | ((3 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | ((4 << 24) & AT91C_HSMC4_NCS_RD_PULSE);
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((4 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((7 << 16) & AT91C_HSMC4_NRD_CYCLE);
+
+ pSMC->HSMC4_TIMINGS = 0
+ | ((1 << 0) & AT91C_HSMC4_TCLR) // CLE to REN
+ | ((2 << 4) & AT91C_HSMC4_TADL) // ALE to Data
+ | ((1 << 8) & AT91C_HSMC4_TAR) // ALE to REN
+ | ((1 << 16) & AT91C_HSMC4_TRR) // Ready to REN
+ | ((2 << 24) & AT91C_HSMC4_TWB) // WEN to REN
+ | (7 << 28)
+ | (AT91C_HSMC4_NFSEL) // Nand Flash Timing
+ ;
+ }
+ else if (mck <= 84000000) {
+ pSMC->HSMC4_SETUP = 0
+ | ((0 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((1 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((0 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((1 << 24) & AT91C_HSMC4_NCS_RD_SETUP);
+
+ pSMC->HSMC4_PULSE = 0
+ | ((2 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | ((3 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | ((3 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | ((4 << 24) & AT91C_HSMC4_NCS_RD_PULSE);
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((4 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((7 << 16) & AT91C_HSMC4_NRD_CYCLE);
+
+ pSMC->HSMC4_TIMINGS = 0
+ | ((2 << 0) & AT91C_HSMC4_TCLR) // CLE to REN
+ | ((4 << 4) & AT91C_HSMC4_TADL) // ALE to Data
+ | ((2 << 8) & AT91C_HSMC4_TAR) // ALE to REN
+ | ((2 << 16) & AT91C_HSMC4_TRR) // Ready to REN
+ | ((4 << 24) & AT91C_HSMC4_TWB) // WEN to REN
+ | (7 << 28)
+ | (AT91C_HSMC4_NFSEL) // Nand Flash Timing
+ ;
+ }
+ else {
+ pSMC->HSMC4_SETUP = 0
+ | ((1 << 0) & AT91C_HSMC4_NWE_SETUP)
+ | ((2 << 8) & AT91C_HSMC4_NCS_WR_SETUP)
+ | ((1 << 16) & AT91C_HSMC4_NRD_SETUP)
+ | ((2 << 24) & AT91C_HSMC4_NCS_RD_SETUP);
+
+ pSMC->HSMC4_PULSE = 0
+ | ((3 << 0) & AT91C_HSMC4_NWE_PULSE)
+ | ((4 << 8) & AT91C_HSMC4_NCS_WR_PULSE)
+ | ((4 << 16) & AT91C_HSMC4_NRD_PULSE)
+ | ((4 << 24) & AT91C_HSMC4_NCS_RD_PULSE);
+
+ pSMC->HSMC4_CYCLE = 0
+ | ((6 << 0) & AT91C_HSMC4_NWE_CYCLE)
+ | ((9 << 16) & AT91C_HSMC4_NRD_CYCLE);
+
+ pSMC->HSMC4_TIMINGS = 0
+ | ((3 << 0) & AT91C_HSMC4_TCLR) // CLE to REN
+ | ((4 << 4) & AT91C_HSMC4_TADL) // ALE to Data
+ | ((2 << 8) & AT91C_HSMC4_TAR) // ALE to REN
+ | ((2 << 16) & AT91C_HSMC4_TRR) // Ready to REN
+ | ((4 << 24) & AT91C_HSMC4_TWB) // WEN to REN
+ | (7 << 28)
+ | (AT91C_HSMC4_NFSEL) // Nand Flash Timing
+ ;
+ }
+}
+
diff --git a/utility/demo-fw/common/dfm_init.c b/utility/demo-fw/common/dfm_init.c
new file mode 100644
index 0000000..bf0b4dc
--- /dev/null
+++ b/utility/demo-fw/common/dfm_init.c
@@ -0,0 +1,118 @@
+/* ----------------------------------------------------------------------------
+ * 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 "dfm_init.h"
+
+//------------------------------------------------------------------------------
+// variable definition
+//------------------------------------------------------------------------------
+#if defined(__ICCARM__)//IAR Compiler ID
+
+///no need for declaration of section start and end variable in IAR
+
+#elif defined(__CC_ARM) //MDK ARM Compiler ID
+
+///variables for group start/end address
+extern unsigned int Image$$GS_Init_Region$$Base;
+extern unsigned int Image$$GS_Init_Region$$Limit;
+
+#elif defined(__GNUC__)//GNU ARM Compiler ID
+
+extern unsigned int __gs_init_section_start, __gs_init_section_end;
+
+#endif
+
+//------------------------------------------------------------------------------
+/// Run all init handlers from level 1 to level 7
+/// \return 0 succeed, other value failure
+//-----------------------------------------------------------------------------
+unsigned int RunAllInit()
+{
+ T_INIT *pInitSecStart, *pInitSecEnd, *pInitTmp;
+
+#if defined(__ICCARM__)
+
+ pInitSecStart = __section_begin(".gs_initsection");
+ pInitSecEnd = __section_end(".gs_initsection");
+
+#elif defined(__CC_ARM)
+
+ pInitSecStart = (T_INIT *)&Image$$GS_Init_Region$$Base;
+ pInitSecEnd = (T_INIT *)&Image$$GS_Init_Region$$Limit;
+
+#elif defined(__GNUC__)
+
+ pInitSecStart = (T_INIT *)&__gs_init_section_start;
+ pInitSecEnd = (T_INIT *)&__gs_init_section_end;
+
+#else
+
+#error "Unsupported tool chain!"
+
+#endif
+
+ //count init handler number
+ int iInitNum = pInitSecEnd - pInitSecStart;
+
+ unsigned int i, iLvlTmp, iLvlMin = 0, iLvlMax = 0xffffffff;
+
+ iLvlTmp = 0;
+
+ while(iLvlMin <= iLvlMax && iInitNum > 0) {
+
+ pInitTmp = pInitSecStart;
+ for(i = 0; i < iInitNum && pInitTmp <= pInitSecEnd; ++i, ++pInitTmp) {
+
+ if(iLvlMin == 0)
+ iLvlMin = pInitTmp->initlvl;
+
+ if(iLvlMax == 0xffffffff)
+ iLvlMax = pInitTmp->initlvl;
+
+ if(pInitTmp->initlvl > iLvlMax)
+ iLvlMax = pInitTmp->initlvl;
+
+ if((pInitTmp->initlvl > iLvlTmp && pInitTmp->initlvl < iLvlMin) ||
+ (pInitTmp->initlvl > iLvlTmp && iLvlMin == iLvlTmp))
+ iLvlMin = pInitTmp->initlvl;
+
+ //run initHanddler
+ if(pInitTmp->initlvl == iLvlTmp)
+ pInitTmp->pfInitFunc();
+ }
+
+ if(iLvlTmp == iLvlMax)
+ break;
+
+ iLvlTmp = iLvlMin;
+ }
+
+ return 0;
+}
+
diff --git a/utility/demo-fw/common/dfm_it.c b/utility/demo-fw/common/dfm_it.c
new file mode 100644
index 0000000..e3a0863
--- /dev/null
+++ b/utility/demo-fw/common/dfm_it.c
@@ -0,0 +1,638 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+** This file contains the exception handlers that use registry calling methodology
+*/
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <rtc/rtc.h>
+
+#include "dfm_it.h"
+
+//------------------------------------------------------------------------------
+// Variables
+//------------------------------------------------------------------------------
+
+static volatile TDFM_ItServList *gpItHandlerFirst = NULL;
+
+//------------------------------------------------------------------------------
+// Exported Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Register It handler into the list
+//------------------------------------------------------------------------------
+int DFM_RegisterItHandler(TDFM_ItServList *pItHandler)
+{
+ volatile TDFM_ItServList *pTmpItHandler;
+
+ pTmpItHandler = gpItHandlerFirst;
+
+ if(pTmpItHandler == NULL) {
+ gpItHandlerFirst = pItHandler;
+ gpItHandlerFirst->next = NULL;
+
+ return 0;
+ }
+
+ while(pTmpItHandler->next != NULL)
+ pTmpItHandler = pTmpItHandler->next;
+
+ pTmpItHandler->next = pItHandler;
+ pItHandler->next = NULL;
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// UnRegister It handler into the list
+//------------------------------------------------------------------------------
+int DFM_UnRegisterItHandler(TDFM_ItServList *pItHandler)
+{
+ volatile TDFM_ItServList *pTmpItHandler;
+ volatile TDFM_ItServList *pTmpPreItHandler;
+
+ pTmpPreItHandler = gpItHandlerFirst;
+ pTmpItHandler = gpItHandlerFirst;
+
+ while(pTmpItHandler != NULL) {
+
+ if(pItHandler == gpItHandlerFirst){
+ gpItHandlerFirst = gpItHandlerFirst->next;
+ pTmpPreItHandler = gpItHandlerFirst;
+ pTmpItHandler = gpItHandlerFirst;
+ continue;
+ }
+
+ if(pTmpItHandler == pItHandler) {
+ if(pTmpPreItHandler != NULL && pTmpItHandler != NULL)
+ pTmpPreItHandler->next = pTmpItHandler->next;
+ }
+
+ //proceed to next
+ pTmpPreItHandler = pTmpItHandler;
+ pTmpItHandler = pTmpItHandler->next;
+ }
+
+ return 0;
+}
+
+////------------------------------------------------------------------------------
+//// Default irq handler
+////------------------------------------------------------------------------------
+//void IrqHandlerNotUsed(void)
+//{
+// while(1);
+//}
+//
+//------------------------------------------------------------------------------
+// Provide weak aliases for each Exception handler to the IrqHandlerNotUsed.
+// As they are weak aliases, any function with the same name will override
+// this definition.
+//------------------------------------------------------------------------------
+
+////------------------------------------------------------------------------------
+//// System interrupt
+////------------------------------------------------------------------------------
+//void NMI_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void HardFault_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void MemManage_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void BusFault_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void UsageFault_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void SVC_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void DebugMon_Handler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+////------------------------------------------------------------------------------
+//void PendSV_Handler(void)
+//{
+// while(1);
+//}
+//
+
+#if defined(cortexm3)
+//------------------------------------------------------------------------------
+// for Cortex M3
+//------------------------------------------------------------------------------
+void SysTick_Handler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == SysTick_IRQn)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------
+// External interrupt
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// for SAM7/9
+//------------------------------------------------------------------------------
+//void SYS_IrqHandler( void )
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// SUPPLY CONTROLLER
+////------------------------------------------------------------------------------
+//void SUPC_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// RESET CONTROLLER
+////------------------------------------------------------------------------------
+//void RSTC_IrqHandler(void)
+//{
+// while(1);
+//}
+
+//------------------------------------------------------------------------------
+// REAL TIME CLOCK
+//------------------------------------------------------------------------------
+void RTC_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+ unsigned int status;
+
+ status = AT91C_BASE_RTC->RTC_SR;
+ if ((status & AT91C_RTC_SECEV) == AT91C_RTC_SECEV) {
+ // Disable RTC interrupt
+ RTC_DisableIt(AT91C_RTC_SECEV);
+ }
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_RTC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+
+ AT91C_BASE_RTC->RTC_SCCR = AT91C_RTC_SECEV;
+
+ RTC_EnableIt(AT91C_RTC_SECEV);
+}
+
+//------------------------------------------------------------------------------
+// REAL TIME TIMER
+//------------------------------------------------------------------------------
+void RTT_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_RTT)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+//
+////------------------------------------------------------------------------------
+//// WATCHDOG TIMER
+////------------------------------------------------------------------------------
+//void WDT_IrqHandler(void)
+//{
+// while(1);
+//}
+
+//------------------------------------------------------------------------------
+// PMC
+//------------------------------------------------------------------------------
+void PMC_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_PMC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// EFC0
+//------------------------------------------------------------------------------
+void EFC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_EFC0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// EFC1
+//------------------------------------------------------------------------------
+void EFC1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_EFC1)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// DBGU
+//------------------------------------------------------------------------------
+void DBGU_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_DBGU)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// HSMC4
+//------------------------------------------------------------------------------
+void HSMC4_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+////------------------------------------------------------------------------------
+//// Parallel IO Controller A
+////------------------------------------------------------------------------------
+//void PIOA_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// Parallel IO Controller B
+////------------------------------------------------------------------------------
+//void PIOB_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+////------------------------------------------------------------------------------
+//// Parallel IO Controller C
+////------------------------------------------------------------------------------
+//void PIOC_IrqHandler(void)
+//{
+// while(1);
+//}
+//
+//------------------------------------------------------------------------------
+// USART 0
+//------------------------------------------------------------------------------
+void USART0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// USART 1
+//------------------------------------------------------------------------------
+void USART1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// USART 2
+//------------------------------------------------------------------------------
+void USART2_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// USART 3
+//------------------------------------------------------------------------------
+void USART3_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HSMC4)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+////------------------------------------------------------------------------------
+//// Multimedia Card Interface
+////------------------------------------------------------------------------------
+//void MCI0_IrqHandler(void)
+//{
+// while(1);
+//}
+
+//------------------------------------------------------------------------------
+// TWI 0
+//------------------------------------------------------------------------------
+void TWI0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TWI0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// TWI 1
+//------------------------------------------------------------------------------
+void TWI1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TWI1)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Serial Peripheral Interface 0
+//------------------------------------------------------------------------------
+void SPI0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_SPI0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Serial Synchronous Controller 0
+//------------------------------------------------------------------------------
+void SSC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_SSC0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Timer Counter 0
+//------------------------------------------------------------------------------
+void TC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TC0)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Timer Counter 1
+//------------------------------------------------------------------------------
+void TC1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TC1)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Timer Counter 2
+//------------------------------------------------------------------------------
+void TC2_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_TC2)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// PWM Controller
+//------------------------------------------------------------------------------
+void PWM_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_PWMC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// ADC controller0
+//------------------------------------------------------------------------------
+void ADCC0_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_ADC12B)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// ADC controller1
+//------------------------------------------------------------------------------
+void ADCC1_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_ADC)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+//------------------------------------------------------------------------------
+// HDMA
+//------------------------------------------------------------------------------
+void HDMA_IrqHandler(void)
+{
+ volatile TDFM_ItServList *pTmpItServ;
+
+ pTmpItServ = gpItHandlerFirst;
+ while(pTmpItServ != NULL) {
+ if(pTmpItServ->itID == AT91C_ID_HDMA)
+ pTmpItServ->ItHandler();
+
+ pTmpItServ = pTmpItServ->next;
+ }
+}
+
+////------------------------------------------------------------------------------
+//// USB Device High Speed UDP_HS
+////------------------------------------------------------------------------------
+//void UDPD_IrqHandler(void)
+//{
+// while(1);
+//}
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