From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- utility/demo-fw/common/dfm_accelerometer.c | 647 +++++++++++++++++ utility/demo-fw/common/dfm_button.c | 248 +++++++ utility/demo-fw/common/dfm_cmd.c | 880 +++++++++++++++++++++++ utility/demo-fw/common/dfm_console.c | 216 ++++++ utility/demo-fw/common/dfm_dispboxmgr.c | 481 +++++++++++++ utility/demo-fw/common/dfm_entry.c | 142 ++++ utility/demo-fw/common/dfm_fatfs.c | 384 ++++++++++ utility/demo-fw/common/dfm_init.c | 118 ++++ utility/demo-fw/common/dfm_it.c | 638 +++++++++++++++++ utility/demo-fw/common/dfm_lcd_tsd.c | 1040 ++++++++++++++++++++++++++++ 10 files changed, 4794 insertions(+) create mode 100644 utility/demo-fw/common/dfm_accelerometer.c create mode 100644 utility/demo-fw/common/dfm_button.c create mode 100644 utility/demo-fw/common/dfm_cmd.c create mode 100644 utility/demo-fw/common/dfm_console.c create mode 100644 utility/demo-fw/common/dfm_dispboxmgr.c create mode 100644 utility/demo-fw/common/dfm_entry.c create mode 100644 utility/demo-fw/common/dfm_fatfs.c create mode 100644 utility/demo-fw/common/dfm_init.c create mode 100644 utility/demo-fw/common/dfm_it.c create mode 100644 utility/demo-fw/common/dfm_lcd_tsd.c (limited to 'utility/demo-fw/common') 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 +#include +#include +#include +#include + +#include + +#include + +#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 (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< +#include +#include +#include +#include + +#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 +#include +#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; ipGrpName, 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;ipGrpName, 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;ipCmdName); + } + + //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(" \n\r"); + iRet = 1; + } + +#else + printf("\n\r ", 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; ipGrpName, (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 +#include +#include + +#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 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 +#include +#include +#include +#include +#include +#include + +#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 +//#include +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PINS_NANDFLASH) +#include +#include +#include +#endif + +#include "fatfs_config.h" + +#include + +#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 +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dfm_cmd.h" +#include "dfm_lcd_tsd.h" +#include "dfm_dispboxmgr.h" +#include "dfm_config.h" +#include "dfm_it.h" +#include "dfm_init.h" +#include "dfm_fatfs.h" +#include "dfm_entry.h" +#include "dfm_varloc.h" + +//global LCD prompt display register entry variable +TInputEntry gLCDEntry = {0, {NULL,NULL},LCD_ShowPrompt, TSD_CommandIsReady, TSD_GetCommand, NULL}; + +#define GLOBALSLIDEINFO + +#if defined(GLOBALSLIDEINFO) +///active for slide information +RLOC_OBJ SlideINFOHeader gActiveSlideHeader _AT(ACTIVESLIDE_INFOHEAD_ADDR); +#endif + +///lcd refresh show flag +unsigned int gLcdRefreshFlag = 0; + +///current slide index shown on LCD +///the init value is the first slide after program start up. +unsigned short gActiveSlideIndex = 0; + +/// active demo bin max slides +static unsigned int gActiveBinSlideCount = 0xffffffff; + +/// point to the active demo bin file name +const char * gpActiveBinFile = LCDSLIDEIMAGEFILE; + +/// used in system tick count +volatile unsigned int gTimeStamp = 0; + +/// Coordinates at which the pen was last pressed. +static volatile unsigned int gTSDxPressed; +static volatile unsigned int gTSDyPressed; +static volatile unsigned char gTSDPressed = 0; + +/// link string index for hot zone hitted, starting from 1, 0 means not hitted +static unsigned int gLinkIndex = 0; + +///Flash1 start address to store demo bin in at91sam3u4 +#define gDemoBinAddrInFlash 0x108000 + + +//file buffer used to read bitmap data +#if defined(__CC_ARM) || defined(__ICCARM__)//up to now, KEIL AND IAR supported +RLOC_OBJ static unsigned char gpFileBuffer[FILE_BUF_SIZE] _AT(FILE_BUFFER_ADDR); +#endif + +#if defined(BOARD_PSRAM_PINS) + +#if defined(__GNUC__) && !defined(__CC_ARM) + static unsigned char *gpFileBuffer = (unsigned char *) (BOARD_EBI_PSRAM + 0xa0000); +#endif + + //PSRAM init entry + int Psram_Init(void) + { + printf("\n\r Init Psram"); + + BOARD_ConfigurePsram(); + + return 0; + } + + //init psram in level 5 + //lvl5_init(Psram_Init); + DFM_INIT(5, Psram_Init); + +#elif defined(PINS_SDRAM) + +#if defined(__GNUC__) && !defined(__CC_ARM) + static unsigned char *gpFileBuffer = (unsigned char *) (AT91C_EBI_SDRAM+ 0xa0000); +#endif + + //SDRAM init entry + int Sdram_Init(void) + { + printf("\n\r Init Sdram"); + + BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH); + } + + //init sdram in level 5 + //lvl5_init(Psram_Init); + DFM_INIT(5, Sdram_Init); + +#elif defined(PINGS_DDRAM) + +#if defined(__GNUC__) && !defined(__CC_ARM) + static unsigned char *gpFileBuffer = (unsigned char *) (AT91C_EBI_SDRAM); +#endif + + //ddram init entry + int Ddram_Init(void) + { + printf("\n\r Init Ddram"); + + //configure DDRAM for use + BOARD_ConfigureDdram(0, BOARD_DDRAM_BUSWIDTH); + } + + //init ddram in level 5 + //lvl5_init(Psram_Init); + DFM_INIT(5, Ddram_Init); + +#else + #define USE_SRAM_BUF + #define BUF_LEN_SRAM 1024 +#endif + +////////////////////////// +///LCD prompt display / +////////////////////////// + +#if defined(USE_LCD_TSD) + +#if defined(LCDC_HX8347) //USE hx8347 controller +//------------------------------------------------------------------------------ +/// Handler for SysTick interrupt. Increments the timestamp counter. +//------------------------------------------------------------------------------ +void SysTick_HandlerLcdTsd(void) +{ + gTimeStamp++; + + // Call TSD_TimerHandler per 10ms + if ((gTimeStamp % 10) == 0) { + + TSD_TimerHandler(); + } +} + +#if defined(USE_IT_CHAIN_MGR) +TDFM_ItServList gSysTkItHandlerLcdTsd = {SysTick_IRQn, SysTick_HandlerLcdTsd, NULL}; +#endif + +//------------------------------------------------------ +/// Init LCD controller of 8347 +//------------------------------------------------------ +int LCD_Init() +{ + + printf("\n\r LCD init in Level 5"); + + // 1ms tick, in driver, a wait is called. + SysTick_Configure(1, BOARD_MCK/1000, SysTick_HandlerLcdTsd); + +#if defined(USE_IT_CHAIN_MGR) + DFM_RegisterItHandler(&gSysTkItHandlerLcdTsd); +#endif + + // Initialize LCD + LCDD_Initialize(); + LCDD_Fill((void *)BOARD_LCD_BASE, COLOR_WHITE); + LCDD_Start(); + + return 0; +} + +#else //use internal LCD controller +//------------------------------------------------------ +/// Init LCD controller of 8347 +//------------------------------------------------------ +int LCD_Init() +{ + // Enable peripheral clock + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_LCDC; + +#if defined(at91sam9g10)||defined(at91sam9261) + AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_HCK1; +#endif + + // Disable the LCD and the DMA + LCD_DisableDma(); + LCD_Disable(0); + + // Configure the LCD controller + LCD_SetPixelClock(BOARD_MCK, BOARD_LCD_PIXELCLOCK); + LCD_SetDisplayType(BOARD_LCD_DISPLAYTYPE); + LCD_SetScanMode(AT91C_LCDC_SCANMOD_SINGLESCAN); + LCD_SetBitsPerPixel(BOARD_LCD_BPP); + LCD_SetPolarities(BOARD_LCD_POLARITY_INVVD, + BOARD_LCD_POLARITY_INVFRAME, + BOARD_LCD_POLARITY_INVLINE, + BOARD_LCD_POLARITY_INVCLK, + BOARD_LCD_POLARITY_INVDVAL); + LCD_SetClockMode(BOARD_LCD_CLOCKMODE); + LCD_SetMemoryFormat((unsigned int) AT91C_LCDC_MEMOR_LITTLEIND); + LCD_SetSize(BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT); + + // Configure timings + LCD_SetVerticalTimings(BOARD_LCD_TIMING_VFP, + BOARD_LCD_TIMING_VBP, + BOARD_LCD_TIMING_VPW, + BOARD_LCD_TIMING_VHDLY); + LCD_SetHorizontalTimings(BOARD_LCD_TIMING_HBP, + BOARD_LCD_TIMING_HPW, + BOARD_LCD_TIMING_HFP); + + // Configure contrast (TODO functions) + LCD_SetContrastPrescaler(AT91C_LCDC_PS_NOTDIVIDED); + LCD_SetContrastPolarity(AT91C_LCDC_POL_POSITIVEPULSE); + LCD_SetContrastValue(0x80); + LCD_EnableContrast(); + + // Configure DMA + LCD_SetFrameSize(BOARD_LCD_FRAMESIZE); + LCD_SetBurstLength(4); + + // Set frame buffer + LCD_SetFrameBufferAddress(images[0]); + + // Enable DMA and LCD + LCD_EnableDma(); + LCD_Enable(0x0C); +} + +#endif + +//lvl5_init(LCD_Init); +DFM_INIT(5, LCD_Init); + +//------------------------------------------------------------------------------ +/// Delay millisecond. Use SysTick interrupt for function implement, so ensure +/// the SysTick interrupt is enabled before using this function. +/// \param ms millisecond to be delay +//------------------------------------------------------------------------------ +void DelayMS(unsigned int ms) +{ + unsigned int st = gTimeStamp; + + while (gTimeStamp - st < ms); +} + +//------------------------------------------------------------------------------ +/// Callback called when the pen is pressed on the touchscreen +/// /param horizontal position (in pixel if ts calibrated) +/// /param vertical position (in pixel if ts calibrated) +//------------------------------------------------------------------------------ +void TSD_PenPressed(unsigned int x, unsigned int y) +{ + //printf("Pen pressed at (%03u, %03u)\n\r", x, y); + + // Save the coordinates for use by TSD_PenReleased + gTSDxPressed = x; + gTSDyPressed = y; + TSD_SetTouched(); +} + +//------------------------------------------------------------------------------ +/// Callback called when the pen is moved on the touchscreen +/// /param horizontal position (in pixel if ts calibrated) +/// /param vertical position (in pixel if ts calibrated) +//------------------------------------------------------------------------------ +void TSD_PenMoved(unsigned int x, unsigned int y) +{ + // printf("Pen moved at (%03u, %03u)\n\r", x, y); +} + +//------------------------------------------------------------------------------ +/// Callback called when the touchscreen is released on the touchscreen +/// /param horizontal position (in pixel if ts calibrated) +/// /param vertical position (in pixel if ts calibrated) +//------------------------------------------------------------------------------ +void TSD_PenReleased(unsigned int x, unsigned int y) +{ + +} + +//------------------------------------------------------------------------------ +/// Get last pen press position +/// /param point to horizontal position (in pixel if ts calibrated) +/// /param point vertical position (in pixel if ts calibrated) +//------------------------------------------------------------------------------ +void TSD_GetPenLastPosition(unsigned int *pX, unsigned int *pY) +{ + *pX = gTSDxPressed; + *pY = gTSDyPressed; +} + +//--------------------------------------------- +/// init touchscreen +//--------------------------------------------- +int TSD_Init() +{ + printf("\n\r Init TouchScreen"); + + gTSDxPressed = gTSDyPressed = 0; + +#if defined(at91sam3u4) +// Internal Flash1 +#define IFLASH1 (0x100000) +#define IFLASH1_SIZE (0x20000) +#define IFLASH1_PAGE_SIZE (256) // Internal FLASH 1 Page Size: 256 bytes +#define IFLASH1_NB_OF_PAGES (512) // Internal FLASH 1 Number of Pages: 512 +#define IFLASH1_LOCK_REGION_SIZE (8192) // Internal FLASH 1 Lock Region Size: 8 Kbytes +#define IFLASH1_NB_OF_LOCK_BITS (16) // Internal FLASH 1 Number of Lock Bits: 16 + + unsigned char error; + unsigned int pBuffer[IFLASH1_PAGE_SIZE / 4]; + unsigned int lastPageAddress; + volatile unsigned int *pLastPageData; + + // Read touch screen calibration data + // Initialize flash driver + FLASHD_Initialize(BOARD_MCK); + + // Calibration data are stored on last page + lastPageAddress = IFLASH1 + IFLASH1_SIZE - IFLASH1_PAGE_SIZE; + pLastPageData = (volatile unsigned int *) lastPageAddress; + + TSDCom_RestoreCalibrateData((void *)pLastPageData, IFLASH1_PAGE_SIZE); + + // Initialize touchscreen + TSD_Initialize((void *)BOARD_LCD_BASE); + + // Save touch screen calibration data + // Unlock whole flash + error = FLASHD_Unlock(IFLASH1, IFLASH1 + IFLASH1_SIZE, 0, 0); + if(error) { + printf(" Unlock flash fail.\n\r"); + } else { + TSDCom_ReadCalibrateData(pBuffer, sizeof(pBuffer)); + error = FLASHD_Write(lastPageAddress, pBuffer, IFLASH1_PAGE_SIZE); + if(error) { + printf(" Fail to write touch srceen calibration data.\n\r"); + } + } +#endif + + return 0; +} + +//TouchScreen init in level 5 +DFM_INIT(5, TSD_Init); + +#endif + + +/////////////////////////////////////////////////// +/// following is dealling with show slide on slide/ +/////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +/// Displays the given image on the LCD. +/// The image should be same size as the LCD. +/// TODO: this display interface should be generalized to consider other LCD properties +/// \param pImage point to image buffer +/// \param width image width in pixels. +/// \param height image height in pixels. +//------------------------------------------------------------------------------ +static void LCDD_DrawImageRGB565( + unsigned short *pImage, + unsigned int width, + unsigned int height) +{ + unsigned int i; + + if ((width != BOARD_LCD_WIDTH) || (height != BOARD_LCD_HEIGHT)) { + + printf("LCDD_DrawImageRGB565: Image size is not fit the LCD"); + return; + } + + + if(LCDD_IsBusy()) return; + + LCDD_SetBusy(); + + + LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0); + LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE); + + for (i = 0; i < (width * height); i++) { + LCD_WriteRAM((void *)BOARD_LCD_BASE, *(pImage)); + pImage++; + } + + LCDD_ClearBusy(); +} + +//------------------------------------------------------------------------------ +///Get slide info header from fatfs file interface +//------------------------------------------------------------------------------ +static unsigned int GetSlideInfoHeaderFromFile( + //fatfs file pointer to demo bin file + FIL *pFile, + //slide index for get info + unsigned int slideIdx, + //store read slide info + SlideINFOHeader *pSlideheader, + //to return actual slide index been read + unsigned int *realSlideIdx) +{ + DemoBINHeader binheader; + FRESULT res; + unsigned int i, offset; + + if(!pSlideheader) { + TRACE_ERROR(" No slide info returned for null pointer!\n\r"); + return 1; + } + + //seek to start point of file + res = f_lseek(pFile, 0); + if(res != FR_OK) { + TRACE_ERROR(" Operation demo bin file fail! \n\r"); + return 1; + } + + //Read demo bin header information + res = f_read(pFile, &binheader, sizeof(DemoBINHeader), &i); + if(res != FR_OK ) { + TRACE_ERROR(" Fail to read demo bin! \n\r"); + return 1; + } + + TRACE_DEBUG(" demo bin tag is %x \n\r", binheader.tag); + TRACE_DEBUG(" demo bin has %u slides \n\r", binheader.slidecount); + //Check if it is atmel demo bin + if( i != sizeof(DemoBINHeader) || binheader.tag != ATMLBINTAG) { + TRACE_ERROR(" Not expected demo bin file! \n\r"); + return 1; + } + + //save max slide count of active demo bin file + gActiveBinSlideCount = binheader.slidecount; + + //requested slide index larger than available one in current demo bin + if(slideIdx >= binheader.slidecount) { + TRACE_WARNING(" Reach max slide count! \n\r"); + + if(realSlideIdx) + *realSlideIdx = binheader.slidecount - 1; + + slideIdx = binheader.slidecount - 1; + } + + //seek the offset to the 'slideindex'th bit map data + offset = sizeof(DemoBINHeader) + slideIdx * sizeof(SlideINFOHeader); + + TRACE_DEBUG("\n\r slide header offset is %u", offset); + + //Seek to the position of slide information field + res = f_lseek(pFile, offset); + if(res != FR_OK) { + TRACE_ERROR(" Operation demo bin file fail! \n\r"); + return 1; + } + + //read slide information + res = f_read(pFile, pSlideheader, sizeof(SlideINFOHeader), &i); + if(res != FR_OK || i != sizeof(SlideINFOHeader)) { + TRACE_ERROR(" Read demo bin file fail! \n\r"); + return 1; + } + + return 0; +} + +//------------------------------------------------------------------------------ +/// read slide information from SDCARD, and Show +/// \param slideIdx, slidex index for reading slide and show +/// \return 0 succeed, other fail +//------------------------------------------------------------------------------ +static int ProcessBinFromSDcard(unsigned int slideIdx, const char *pFileWithPath) +{ + +// DemoBINHeader binheader; + SlideINFOHeader slideheader; + unsigned int offset; + + TRACE_DEBUG(" file name is %s \n\r", pFileWithPath); + + FIL demoBinFile; + FRESULT res; + unsigned int i; + +// strcpy(pFile,SDCARD_ROOT_DIRECTORY); +// strncat(pFile, pFileWithPath, 256-1-strlen(SDCARD_ROOT_DIRECTORY)); + + //Open demo bin file + res = f_open(&demoBinFile, pFileWithPath, FA_OPEN_EXISTING | FA_READ); + if(res != FR_OK) { + TRACE_ERROR(" Open demo bin file fail! \n\r"); + f_close(&demoBinFile); + return 1; + } + + //get slide info from file + if(GetSlideInfoHeaderFromFile(\ + &demoBinFile,\ + slideIdx,\ + &slideheader,\ + &slideIdx)) + { + TRACE_ERROR(" Read slide header fail!\n\r"); + f_close(&demoBinFile); + return 1; + } + + //set real slide index as active + gActiveSlideIndex = slideIdx; + + //get the 'slideindex'th slide bit map data offset + offset = slideheader.slideoffset; + + TRACE_DEBUG(" slide %u bitmap data at %u \n\r", slideIdx, offset); + +#if defined(GLOBALSLIDEINFO) + //copy current active slide information to global variable + memcpy(&gActiveSlideHeader, &slideheader, sizeof(SlideINFOHeader)); +#endif + + //print the link box information + TRACE_DEBUG(" slide has link %u\n\r", gActiveSlideHeader.linkcount); + if(slideheader.linkcount) { + unsigned int j; + for(j = 0; j < slideheader.linkcount; ++j) { + TRACE_DEBUG(" link bottom %u, left %u, width %u, height %u \n\r", \ + slideheader.linkinfo[j].linkboxbottom,\ + slideheader.linkinfo[j].linkboxleft,\ + slideheader.linkinfo[j].linkboxwidth,\ + slideheader.linkinfo[j].linkboxheight); + } + } + + //seek to offset of the 'slideindex'th slide bit map data + res = f_lseek(&demoBinFile, offset); + if(res != FR_OK) { + TRACE_DEBUG(" Operation demo bin file fail! \n\r"); + f_close(&demoBinFile); + return 1; + } + +#if !defined(USE_SRAM_BUF) + //Read all single slide bitmap data into PSRAM buffer, then write to LCD + TRACE_DEBUG(" Ready to read bit map data len %u \n\r", slideheader.slidedatalength); + + //read slide bit map data + res = f_read(&demoBinFile, gpFileBuffer, slideheader.slidedatalength, &i); + + TRACE_DEBUG(" Data read len is %u \n\r", i); + + if(res != FR_OK || i != slideheader.slidedatalength) { + TRACE_ERROR(" Read bitmap data fail! \n\r"); + f_close(&demoBinFile); + return 1; + } + f_close(&demoBinFile); + + //Define a pointer to cast bmp header + struct BMPHeader *header = (struct BMPHeader *)gpFileBuffer; + offset = header->offset; + + //Show slide bitmap header information + TRACE_DEBUG("============bmp header outside calling============== \n\r"); + TRACE_DEBUG(" bmp.type is %x \n\r", header->type); + TRACE_DEBUG(" bmp.filesize is %u \n\r", header->fileSize); + TRACE_DEBUG(" bmp.width is %u \n\r", header->width); + TRACE_DEBUG(" bmp.height is %u \n\r", header->height); + TRACE_DEBUG(" bmp.compressed is %u \n\r", header->compression); + TRACE_DEBUG(" bmp.bitdepth is %d \n\r", header->bits); + TRACE_DEBUG(" bmp.offset is %u \n\r", header->offset); + + //LCDD_DrawImageRGB565((unsigned short *)(pLcdBuffer),BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT); + LCDD_DrawImageRGB565((unsigned short *)(gpFileBuffer + offset),BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT); + +#else //USE_SRAM_BUF defined + + //USE sram buffer to read bitmap data and then write to LCD + unsigned int k; + char srambuf[BUF_LEN_SRAM]; + unsigned short *lcddata; + + //buffer len is not even. + if(BUF_LEN_SRAM % 2 != 0) { + TRACE_ERROR("SRAM buffer size must be even! \n\r"); + f_close(&demofilebin); + return 1; + } + + //buffer len is too short to fit a bmp file header + if(BUF_LEN_SRAM < sizeof(struct BMPHeader)) { + TRACE_ERROR("SRAM buffer size is too short, Add it large than %u \n\r", sizeof(struct BMPHeader)); + f_close(&demofilebin); + return 1; + } + + //read slide bit map header + res = f_read(&demofilebin, srambuf, sizeof(struct BMPHeader), &i); + + struct BMPHeader *header = (struct BMPHeader *)&srambuf[0]; + //Get BMP bitmap data offset + offset = header->offset + slideheader.slideoffset; + + //seek to the bitmap data offset + res = f_lseek(&demofilebin, offset); + if(res != FR_OK) { + TRACE_DEBUG(" Can't find BMP bitmap Data in bin file! \n\r"); + f_close(&demofilebin); + return 1; + } + + //prepare to write lcd + LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0); + LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE); + + for(k = 0; k < slideheader.slidedatalength && k < LCD16BITDATALEN; k += BUF_LEN_SRAM) { + + lcddata = (unsigned short *)&srambuf[0]; + + //read data to buffer + res = f_read(&demofilebin, srambuf, \ + (k + BUF_LEN_SRAM)> slideheader.slidedatalength ? (slideheader.slidedatalength - k): BUF_LEN_SRAM, &i); + + if(res != FR_OK) { + TRACE_ERROR(" Read bitmap data fail! \n\r"); + f_close(&demofilebin); + return 1; + } + + //write the data to LCD base address + while(i>0) { + LCD_WriteRAM((void *)BOARD_LCD_BASE, *(lcddata++)); + i-=2; + } + } + + f_close(&demofilebin); + +#endif//end of USE_SRAM_BUF + unsigned int k; + if(slideheader.dispboxcount) { + for(k = 0; k < slideheader.dispboxcount; ++k) { + //conversion rule based on SAM3U current setting. + unsigned int top = slideheader.dispboxinfo[k].dispboxleft; + unsigned int left = DEMOSLIDEHEIGHT - slideheader.dispboxinfo[k].dispboxbottom; + unsigned int width = slideheader.dispboxinfo[k].dispboxheight; + unsigned int height = slideheader.dispboxinfo[k].dispboxwidth; + + SetDispBoxPos(k+1, DISPBOX_ENABLE, \ + top, left, width, height); + + EnableDispBox(k); + } + + } else { + for(k = 0; k < MAX_DISPBOX_PER_SLIDE; ++k) { + DisableDispBox(k); + } + } + + return 0; +} + +//------------------------------------------------------------------------------ +///read slide information from External NandFlash, and Show +//------------------------------------------------------------------------------ +static int ProcessBinFromNandFlash(unsigned int slideIdx, const char *pFileWithPath) +{ + unsigned int iRet; + + //fatfs mounted on NAND FLASH also, so reuse SDCard code + iRet = ProcessBinFromSDcard(slideIdx, pFileWithPath); + + return iRet; +} + + +//------------------------------------------------------------------------------ +///read slide information from Internal flash, and Show +//------------------------------------------------------------------------------ +static int ProcessBinFromInternalFlash(unsigned int binStartAddr, unsigned int slideIdx) +{ + DemoBINHeader binheader; + SlideINFOHeader slideheader; + unsigned int offset; + + //get demo bin header information + binheader = *(DemoBINHeader*)binStartAddr; + TRACE_DEBUG(" bin tag is %x\n\r", binheader.tag); + TRACE_DEBUG(" filesize is %u\n\r", binheader.filesize); + TRACE_DEBUG(" headersize is %u\n\r", binheader.headersize); + TRACE_DEBUG(" bin has %u slide\n\r", binheader.slidecount); + + //check if it has atmel demo bin header tag + if(binheader.tag != ATMLBINTAG) { + TRACE_ERROR(" Not Atmel demo bin in FLASH1!\n\r"); + return 1; + } + + //check if slide index reachs max + if(slideIdx >= binheader.slidecount) { + slideIdx = binheader.slidecount - 1; + TRACE_WARNING(" Reach max slides!\n\r"); + } + + //set real slide index as active + gActiveSlideIndex = slideIdx; + + //offset of slide info header + offset = sizeof(DemoBINHeader) + slideIdx * sizeof(SlideINFOHeader); +#if defined(GLOBALSLIDEINFO) + memcpy(&gActiveSlideHeader, (void*)(binStartAddr+offset), sizeof(SlideINFOHeader)); +#endif + + slideheader = *(SlideINFOHeader *)(binStartAddr+offset); + TRACE_DEBUG(" slide has dispbox?%s\n\r",slideheader.dispboxyes?"yes":"no"); + TRACE_DEBUG(" slideoffset is %u\n\r", slideheader.slideoffset); + TRACE_DEBUG(" slidedatalength is %u\n\r", slideheader.slidedatalength); + TRACE_DEBUG(" slidewidth is %u\n\r", slideheader.slidewidth); + TRACE_DEBUG(" slideheight is %u\n\r", slideheader.slideheight); + TRACE_DEBUG(" slide has %u links\n\r", slideheader.linkcount); + if(slideheader.linkcount) { + TRACE_DEBUG(" link 0'addr is %s\n\r", slideheader.linkinfo[0].linkstring); + } + + //offset of slide bmp file + offset = slideheader.slideoffset; + BMP_displayHeader((unsigned int*)binStartAddr+offset); + + //Get slide bmp file header + struct BMPHeader *bmpheader = (struct BMPHeader*)(binStartAddr+offset); + if(bmpheader->type != 0x4d42) { + TRACE_ERROR(" Slide bitmap file is not correct!\n\r"); + return 1; + } + + //check bitdepth if it is 8. 1,4bitdepth is not supported for complicate + //pixel color conversion. 16,24bitdepth bitmap data length too big. + //TODO: Care more case of IFlash of some EK board less than 8bit bmp file size, 77k + if(bmpheader->bits !=8) { + TRACE_ERROR(" Slide bitmap color bitdepth %d is not supported!", bmpheader->bits); + return 1; + } + + BMP_Decode((void *)(binStartAddr + offset), gpFileBuffer, \ + bmpheader->width, bmpheader->height, 24); + + unsigned int i; + unsigned int color24; + unsigned short color16; + + LCD_SetCursor((void *)BOARD_LCD_BASE, 0, 0); + LCD_WriteRAM_Prepare((void *)BOARD_LCD_BASE); + unsigned char * pImage = gpFileBuffer; + for (i = 0; i < (BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT); i++) { + + color24 = (*pImage << 16) | (*(pImage+1) << 8) | (*(pImage+2)); + pImage += 3; + color16 = RGB24ToRGB16(color24); + LCD_WriteRAM((void *)BOARD_LCD_BASE, color16); + } + + + unsigned int k; + if(slideheader.dispboxcount) { + for(k = 0; k < slideheader.dispboxcount; ++k) { + //conversion rule based on SAM3U current setting. + unsigned int top = slideheader.dispboxinfo[k].dispboxleft; + unsigned int left = DEMOSLIDEHEIGHT - slideheader.dispboxinfo[k].dispboxbottom; + unsigned int width = slideheader.dispboxinfo[k].dispboxheight; + unsigned int height = slideheader.dispboxinfo[k].dispboxwidth; + + SetDispBoxPos(k+1, DISPBOX_ENABLE, \ + top, left, width, height); + + EnableDispBox(k); + } + + } else { + for(k = 0; k < MAX_DISPBOX_PER_SLIDE; ++k) { + DisableDispBox(k); + } + } + + return 0; +} + +//------------------------------------------------------------------------------ +/// Show LCD prompt information, normally it is slide from demo bin +/// \param pFileName, demo bin file name without designated drive path +//------------------------------------------------------------------------------ +int ReadSlideInfoAndShow(const char * pFileName) +{ + int iRet; + char pFile[256]; + + strcpy(pFile,SDCARD_ROOT_DIRECTORY); + strncat(pFile, pFileName, 256-1-strlen(SDCARD_ROOT_DIRECTORY)); + //gpActiveBinFile = "sam3demo.bin";//fname; + iRet = ProcessBinFromSDcard(gActiveSlideIndex, pFile); + + //read from SDCard fail + if(iRet) { + strcpy(pFile, NAND_ROOT_DIRECTORY); + strncat(pFile, pFileName, 256-1-strlen(NAND_ROOT_DIRECTORY)); + + iRet = ProcessBinFromNandFlash(gActiveSlideIndex, pFile); + + if(iRet){ + iRet = ProcessBinFromInternalFlash(gDemoBinAddrInFlash, 0); + } + } + + //both reading from sdcard and nand flash fail! + if(iRet) { + TRACE_ERROR("\n\r Read LCD prompt slide information fail!"); + } + + return iRet; +} + +//------------------------------------------------------------------------------ +/// Check the hit point if it is in hyperlink zone of active slide +/// \param slideIdx slide index to check the hyperlink on the slide +/// \return 0 means not in hot zone; other values is the link index start from 1 +//------------------------------------------------------------------------------ +static unsigned int CheckHitLink() +{ + unsigned int bottom, left, width, height; + unsigned int linkcnt; + +#if !defined(GLOBALSLIDEINFO) + SlideINFOHeader gActiveSlideHeader;//to consistent with global one + + if(GetActiveSlideInfoHeader(gActiveSlideIndex,\ + &gActiveSlideHeader,\ + 0)) + { + //can't get active slide info, Consider as not hit + return 0; + } + +#endif + + linkcnt = gActiveSlideHeader.linkcount; + unsigned int i; + for(i = 0; i < linkcnt; ++i) { + bottom = gActiveSlideHeader.linkinfo[i].linkboxbottom; + left = gActiveSlideHeader.linkinfo[i].linkboxleft; + width = gActiveSlideHeader.linkinfo[i].linkboxwidth; + height = gActiveSlideHeader.linkinfo[i].linkboxheight; + + //inside the link box? + if((gTSDxPressed > left) && (gTSDxPressed < (left + width)) && \ + (gTSDyPressed < bottom) && (gTSDyPressed > (bottom - height))) + return i+1; + } + + return 0; +} + +//------------------------------------------------------------------------------ +/// Get link string from link index on active slide +/// \param linkIdx link index on active slide, start from 1 +/// \return NULL means no link string; otherwise, link string +//------------------------------------------------------------------------------ +char * GetLinkStrFromActiveSlide(unsigned int linkIdx) +{ + +#if !defined(GLOBALSLIDEINFO) + SlideINFOHeader gActiveSlideHeader;//to consistent with global one + + if(GetActiveSlideInfoHeader(gActiveSlideIndex,\ + &gActiveSlideHeader,\ + 0)) + { + //can't get active slide info, Consider as NULL + return NULL; + } + + +#endif + return gActiveSlideHeader.linkinfo[linkIdx-1].linkstring; +} + +////////////////////////////////////////////////////// +/// exported function / +////////////////////////////////////////////////////// + +//------------------------------------------------------------------------- +/// Set Touch screen is touched +//------------------------------------------------------------------------- +void TSD_SetTouched(void) +{ + gTSDPressed = 1; +} + +//------------------------------------------------------------------------- +/// Clear Touch screen is touched +//------------------------------------------------------------------------- +void TSD_ClearTouched(void) +{ + gTSDPressed = 0; +} + +//------------------------------------------------------------------------- +/// Get Touch screen is touched +//------------------------------------------------------------------------- +unsigned char TSD_GetTouched(void) +{ + return gTSDPressed; +} + +//------------------------------------------------------------------------- +/// Check if touchscreen hit in a hot zone +/// \return 0 means no, other values mean yes +//------------------------------------------------------------------------- +unsigned int TSD_CommandIsReady() +{ + unsigned int ret; + + if(0 == gTSDxPressed && 0 == gTSDyPressed) { + return 0; + } + + ret = CheckHitLink(); + + //set global variable for link index + gLinkIndex = ret; + + gTSDxPressed = gTSDyPressed = 0; + + return ret; +} + +//---------------------------------------------------------- +/// Get ready command +/// \return string pointer to link string +//---------------------------------------------------------- +const char * TSD_GetCommand() +{ + char *pStr; + + //get link string from index + pStr = GetLinkStrFromActiveSlide(gLinkIndex); + + //clear + gLinkIndex = 0; + + return pStr; +} + +//------------------------------------------------------------------------------ +/// Set LCD fresh show flag, this will cause next call to LCD_ShowPrompt reload +/// slide page data any way. +//------------------------------------------------------------------------------ +void LCD_SetRefreshFlag() +{ + gLcdRefreshFlag = 1; +} + +//------------------------------------------------------------------------------ +/// Clear LCD fresh show flag +//------------------------------------------------------------------------------ +void LCD_ClearRefreshFlag() +{ + gLcdRefreshFlag = 0; +} + +//------------------------------------------------------------------------------ +/// Show LCD prompt information, normally it is slide from demo bin +//------------------------------------------------------------------------------ +int LCD_ShowPrompt() +{ + static unsigned int slideIndexLoaded = 0xffffffff; + int ret; + + if(gActiveSlideHeader.propyes) { + if(slideIndexLoaded != gActiveSlideIndex && slideIndexLoaded != 0xffffffff) { + ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onCloseCmds); + } + } + + //reload show only slide index changed or fresh flag is set + if(slideIndexLoaded != gActiveSlideIndex || gLcdRefreshFlag) { + ret = ReadSlideInfoAndShow(gpActiveBinFile); + + if(gActiveSlideHeader.propyes && slideIndexLoaded != gActiveSlideIndex) { + ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onInitCmds); + } + + slideIndexLoaded = gActiveSlideIndex; + gLcdRefreshFlag = 0; + } + + if(gActiveSlideHeader.propyes) { + ParseAndRunMultiCmds(gActiveSlideHeader.propinfo.onRefreshCmds); + } + + return ret; +} + -- cgit v1.2.3