ushell_task.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00013 
00014 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
00015  *
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions are met:
00018  *
00019  * 1. Redistributions of source code must retain the above copyright notice,
00020  * this list of conditions and the following disclaimer.
00021  *
00022  * 2. Redistributions in binary form must reproduce the above copyright notice,
00023  * this list of conditions and the following disclaimer in the documentation
00024  * and/or other materials provided with the distribution.
00025  *
00026  * 3. The name of ATMEL may not be used to endorse or promote products derived
00027  * from this software without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00030  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00031  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
00032  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00033  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00034  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00035  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00036  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00038  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  */
00040 
00041 //_____  I N C L U D E S ___________________________________________________
00042 
00043 #include "config.h"
00044 #include "ushell_task.h"
00045 #include <stdio.h>
00046 #include "lib_mem/df/df_mem.h"
00047 #include "lib_mcu/wdt/wdt_drv.h"
00048 #include "lib_mcu/uart/uart_lib.h"
00049 #include "lib_mcu/usb/usb_drv.h"
00050 #include "lib_mcu/timer/timer16_drv.h"
00051 #if (TARGET_BOARD==SPIDER)
00052 #include "lib_board/spider/spider_drv.h"
00053 #include "lib_board/intermcu_spi/intermcu_spi_drv.h"
00054 #endif
00055 #include "modules/file_system/fat.h"
00056 #include "modules/file_system/fs_com.h"
00057 #include "modules/file_system/navigation.h"
00058 #include "modules/file_system/file.h"
00059 #include "modules/file_system/nav_utils.h"
00060 #include "modules/usb/device_chap9/usb_standard_request.h"
00061 #include "modules/control_access/ctrl_access.h"
00062 
00063 #ifndef USHELL_RF
00064    #define USHELL_RF DISABLE
00065    #define ushell_putchar  uart_putchar
00066    #define ushell_test_hit uart_test_hit
00067    #define ushell_get_char uart_getchar
00068 #endif
00069 
00070 #if (USHELL_RF==ENABLE)
00071    #include "rf_task.h"
00072    void rf_task_init(void);
00073 #endif
00074 
00075 
00076 #if (USHELL_DFU==ENABLE)
00077 #include "modules/usb/host_chap9/usb_host_task.h"
00078 #include "modules/usb/host_chap9/usb_host_enum.h"
00079 #include "host_dfu_task.h"
00080 #endif
00081 
00082 #if (USHELL_USB==ENABLE)
00083 #include "conf_usb.h"
00084 #include "modules/usb/host_chap9/usb_host_task.h"
00085 #include "modules/usb/host_chap9/usb_host_enum.h"
00086 #include "modules/usb/device_chap9/usb_standard_request.h"
00087 #  if(USB_HUB_SUPPORT==ENABLE)
00088 #include "modules/usb/host_chap9/usb_host_hub.h"
00089 #  endif
00090 #endif
00091 
00092 #if (USHELL_HID==ENABLE)
00093 #include "host_hid_task.h"
00094 #endif
00095 
00096 
00097 //_____ M A C R O S ________________________________________________________
00098 
00099 #ifndef USHELL_DFU
00100 #warning USHELL_DFU is not defined as ENABLE or DISABLE, using DISABLE by default...
00101 #define  USHELL_DFU DISABLE
00102 #endif
00103 
00104 #ifndef USHELL_USB
00105 #warning USHELL_USB is not defined as ENABLE or DISABLE, using DISABLE by default...
00106 #define  USHELL_USB DISABLE
00107 #endif
00108 
00109 #ifndef USHELL_HID
00110 #warning USHELL_HID is not defined as ENABLE or DISABLE, using DISABLE by default...
00111 #define  USHELL_HID DISABLE
00112 #endif
00113 
00114 #ifndef USHELL_HISTORY
00115 #warning USHELL_HISTORY value is not defined using 10 as default value
00116 #define  USHELL_HISTORY 10
00117 #endif
00118 
00119 #ifndef USHELL_NB_LINE
00120 #warning USHELL_NB_LINE value is not defined using 20 as default value
00121 #define USHELL_NB_LINE  20
00122 #endif
00123 
00124 #ifndef USHELL_NB_COL
00125 #warning USHELL_NB_COL value is not defined using 80 as default value
00126 #define USHELL_NB_COL  80
00127 #endif
00128 
00129 
00130 #define USHELL_SIZE_CMD_LINE  70
00131 #define USHELL_MAX_NB_ARG     2
00132 
00133 //_____ D E C L A R A T I O N S ____________________________________________
00134 
00135 
00136 // Manage task
00137 static Bool g_b_ushell_task_run = FALSE;
00138 
00139 // To manage command line
00140 static U8   g_u8_escape_sequence=0;
00141 static U8   g_u8_cmd_size=0;
00142 static U8   g_u8_history_pos=0;
00143 static U8   g_u8_history_pos_search=0;
00144 static char g_s_cmd_his[USHELL_HISTORY][USHELL_SIZE_CMD_LINE];
00145 static char g_s_cmd[USHELL_SIZE_CMD_LINE];
00146 static char g_s_arg[USHELL_MAX_NB_ARG][USHELL_SIZE_CMD_LINE];
00147 
00148 // To manage a file system shortcut
00149 static Fs_index g_mark_index;
00150 
00151 
00152 //* To store all shell messages
00153 U8 code str_cd[]=STR_CD;
00154 U8 code str_mount[]=STR_MOUNT;
00155 U8 code str_cp[]=STR_CP;
00156 U8 code str_ls[]=STR_LS;
00157 U8 code str_ls_more[]=STR_LS_MORE;
00158 U8 code str_rm[]=STR_RM;
00159 U8 code str_df[]=STR_DF;
00160 U8 code str_space[]=STR_SPACE;
00161 U8 code str_mkdir[]=STR_MKDIR;
00162 U8 code str_touch[]=STR_TOUCH;
00163 U8 code str_append[]=STR_APPEND;
00164 U8 code str_cat[]=STR_CAT;
00165 U8 code str_cat_more[]=STR_CAT_MORE;
00166 U8 code str_up[]=STR_UP;
00167 U8 code str_disk[]=STR_DISK;
00168 U8 code str_mark[]=STR_MARK;
00169 U8 code str_goto[]=STR_GOTO;
00170 U8 code str_mv[]=STR_MV;
00171 U8 code str_help[]=STR_HELP;
00172 U8 code str_format[]=STR_FORMAT;
00173 U8 code str_sync[]=STR_SYNC;
00174 U8 code str_perform[]=STR_PERFORM;
00175 U8 code str_reboot[]=STR_REBOOT;
00176 #if (USHELL_USB==ENABLE)
00177 U8 code str_ls_usb[]=STR_LS_USB;
00178 U8 code str_usb_suspend[]=STR_USB_SUSPEND;
00179 U8 code str_usb_resume[]=STR_USB_RESUME;
00180 U8 code str_usb_force_enum[]=STR_USB_FORCE_ENUM;
00181 #endif
00182 #if (USHELL_DFU==ENABLE)
00183 U8 code str_dfu_erase[]=STR_DFU_ERASE;
00184 U8 code str_dfu_load[]=STR_DFU_LOAD;
00185 U8 code str_dfu_start[]=STR_DFU_START;
00186 #endif
00187 #if (USHELL_HID==ENABLE)
00188 U8 code str_hid_enter_dfu[]=STR_HID_ENTER_DFU;
00189 U8 code str_hid_get_info[]=STR_HID_GET_INFO;
00190 #endif
00191 U8 code msg_paste_fail[]=MSG_ER_PASTE;
00192 U8 code msg_prompt[]=MSG_PROMPT;
00193 U8 code msg_welcome[]=MSG_WELCOME;
00194 U8 code msg_exit[]=MSG_EXIT;
00195 U8 code msg_er_mount[]=MSG_ER_MOUNT;
00196 U8 code msg_er_drive[]=MSG_ER_DRIVE;
00197 U8 code msg_er_rm[]=MSG_ER_RM;
00198 U8 code msg_er_unknown_file[]=MSG_ER_UNKNOWN_FILE;
00199 U8 code msg_er_cmd_not_found[]=MSG_ER_CMD_NOT_FOUND;
00200 U8 code msg_er_format[]=MSG_ER_FORMAT;
00201 U8 code msg_append_welcome[]=MSG_APPEND_WELCOME;
00202 U8 code msg_help[]=MSG_HELP;
00203 U8 code msg_no_device[]=MSG_NO_DEVICE;
00204 U8 code msg_ok[]=MSG_OK;
00205 U8 code msg_ko[]=MSG_KO;
00206 #if (USHELL_USB==ENABLE)
00207 U8 code msg_remote_wake_up_ok[]=MSG_REMOTE_WAKEUP_OK;
00208 U8 code msg_remote_wake_up_ko[]=MSG_REMOTE_WAKEUP_KO;
00209 U8 code msg_device_self_powered[]=MSG_SELF_POWERED;
00210 U8 code msg_device_bus_powered[]=MSG_BUS_POWERED;
00211 U8 code msg_usb_suspended[]=MSG_USB_SUSPENDED;
00212 U8 code msg_device_full_speed[]=MSG_DEVICE_FULL_SPEED;
00213 U8 code msg_device_low_speed[]=MSG_DEVICE_LOW_SPEED;
00214 #endif
00215 
00216 
00217 // Internal sub routines
00218 Bool  ushell_cmd_scan         ( void );
00219 U8    ushell_cmd_decode       ( void );
00220 void  ushell_clean_cmd_line   ( void );
00221 void  ushell_history_up       ( void );
00222 void  ushell_history_down     ( void );
00223 void  ushell_history_display  ( void );
00224 #ifdef __GNUC__
00225    U8    mystrncmp      (char *str1,U8 *str2,U8 i);
00226    void  print_msg      (U8 *str);
00227 #else
00228    U8    mystrncmp      (char *str1,U8 code *str2,U8 i);
00229    void  print_msg      (U8 code *str);
00230 #endif
00231 Bool  ushell_more_wait        ( void );
00232 // Internal sub routines for file system commands
00233 void  ushell_cmd_nb_drive     ( void );
00234 void  ushell_cmd_free_space   ( void );
00235 void  ushell_cmd_format       ( void );
00236 void  ushell_cmd_mount        ( void );
00237 void  ushell_cmd_space        ( void );
00238 void  ushell_cmd_ls           ( Bool b_more );
00239 void  ushell_cmd_cd           ( void );
00240 void  ushell_cmd_gotoparent   ( void );
00241 void  ushell_cmd_cat          ( Bool b_more);
00242 void  ushell_cmd_help         ( void );
00243 void  ushell_cmd_mkdir        ( void );
00244 void  ushell_cmd_touch        ( void );
00245 void  ushell_cmd_rm           ( void );
00246 void  ushell_cmd_append_file  ( void );
00247 void  ushell_cmd_copy         ( void );
00248 void  ushell_cmd_rename       ( void );
00249 void  ushell_cmd_reboot       ( void );
00250 Bool  ushell_cmd_sync         ( void );
00251 void  ushell_cmd_perform      ( void );
00252 void  ushell_path_valid_syntac( char *path );
00253 // Internal sub routines for USB commands
00254 void  ushell_cmdusb_ls        ( void );
00255 void  ushell_cmdusb_suspend   ( void );
00256 void  ushell_cmdusb_resume    ( void );
00257 void  ushell_cmdusb_force_enum( void );
00258 // Internal sub routines for USB DFU commands
00259 void  ushell_cmddfu_erase     ( void );
00260 void  ushell_cmddfu_load      ( void );
00261 void  ushell_cmddfu_start     ( void );
00262 // Internal sub routines for USB HID commands
00263 void  ushell_cmdhid_enter_dfu ( void );
00264 void  ushell_cmdhid_getinfo   ( void );
00265 
00266 
00267 
00270 void ushell_task_init(void)
00271 {
00272    U8 u8_i;
00273 #if (USHELL_RF==ENABLE)
00274    rf_task_init();
00275 #else
00276    uart_init();
00277 #endif
00278 
00279 #ifdef __GNUC__
00280    fdevopen((int (*)(char, FILE*))(ushell_putchar),(int (*)(FILE*))ushell_get_char); //for printf redirection
00281 #endif
00282    g_b_ushell_task_run = FALSE;
00283    for( u8_i=0; u8_i<USHELL_HISTORY; u8_i++ ) {
00284       g_s_cmd_his[u8_i][0] = 0;  // Set end of line for all cmd line history
00285    }
00286   
00287 }
00288 
00289 
00294 void ushell_task(void)
00295 {
00296    //** Check the USB mode and autorize/unautorize ushell
00297    if(!g_b_ushell_task_run)
00298    {
00299       if( Is_usb_id_device() )
00300          return;
00301       g_b_ushell_task_run = TRUE;
00302       print_msg((U8 code *)msg_welcome);
00303       ushell_cmd_nb_drive();
00304       print_msg((U8 code *)msg_prompt);
00305       // Reset the embedded FS on ushell navigator and on first drive
00306       nav_reset();
00307       nav_select( FS_NAV_ID_USHELL_CMD );
00308    }else{
00309       if( Is_usb_id_device() )
00310       {
00311          g_b_ushell_task_run = FALSE;
00312          print_msg((U8 code *)msg_exit);
00313          nav_exit();
00314          return;
00315       }
00316    }
00317 
00318    if( !ushell_cmd_scan() )
00319       return;
00320 
00321    //** Command ready then decode and execute this one
00322    switch( ushell_cmd_decode() )
00323    {
00324       // Displays number of  drives
00325       case CMD_NB_DRIVE:
00326       ushell_cmd_nb_drive();
00327       break;
00328 
00329       // Displays free space information for all connected drives
00330       case CMD_DF:
00331       ushell_cmd_free_space();
00332       break;
00333 
00334       // Formats disk
00335       case CMD_FORMAT:
00336       ushell_cmd_format();
00337       break;
00338       
00339       // Mounts a drive (e.g. "b:")
00340       case CMD_MOUNT:
00341       ushell_cmd_mount();
00342       break;
00343 
00344       // Displays the space information for current drive
00345       case CMD_SPACE:
00346       ushell_cmd_space();
00347       break;
00348       
00349       // Lists the files present in current directory (e.g. "ls")
00350       case CMD_LS:
00351       ushell_cmd_ls(FALSE);
00352       break;
00353       case CMD_LS_MORE:
00354       ushell_cmd_ls(TRUE);
00355       break;
00356 
00357       // Enters in a directory (e.g. "cd folder_toto")
00358       case CMD_CD:
00359       ushell_cmd_cd();
00360       break;
00361 
00362       // Enters in parent directory ("cd..")
00363       case CMD_UP:
00364       ushell_cmd_gotoparent();
00365       break;
00366 
00367       // Displays a text file
00368       case CMD_CAT:
00369       ushell_cmd_cat(FALSE);
00370       break;
00371       case CMD_CAT_MORE:
00372       ushell_cmd_cat(TRUE);
00373       break;
00374          
00375       // Displays the help
00376       case CMD_HELP:
00377       ushell_cmd_help();
00378       break;
00379 
00380       // Creates directory
00381       case CMD_MKDIR:
00382       ushell_cmd_mkdir();
00383       break;
00384 
00385       // Creates file
00386       case CMD_TOUCH:
00387       ushell_cmd_touch();
00388       break;
00389       
00390       // Deletes files or directories
00391       case CMD_RM:
00392       ushell_cmd_rm();
00393       break;
00394 
00395       // Appends char to selected file
00396       case CMD_APPEND:
00397       ushell_cmd_append_file();
00398       break;
00399 
00400       // Index routines (= specific shortcut from ATMEL FileSystem)
00401       case CMD_SET_ID:
00402       g_mark_index = nav_getindex();
00403       break;
00404       case CMD_GOTO_ID:
00405       nav_gotoindex( &g_mark_index );
00406       break;
00407       
00408       // Copys file to other location
00409       case CMD_CP:
00410       ushell_cmd_copy();
00411       break;
00412 
00413       // Renames file
00414       case CMD_MV:
00415       ushell_cmd_rename();
00416       break;
00417 
00418       // Synchronize folders
00419       case CMD_SYNC:
00420       ushell_cmd_sync();
00421       break;
00422 
00423       // Perform transfer
00424       case CMD_PERFORM:
00425       ushell_cmd_perform();
00426       break;
00427 
00428       // Reboot target
00429       case CMD_REBOOT:
00430       ushell_cmd_reboot();
00431       break;
00432 
00433       // USB commands
00434 #if (USHELL_USB==ENABLE)
00435       case CMD_LS_USB:
00436       ushell_cmdusb_ls();
00437       break;
00438       case CMD_USB_SUSPEND:
00439       ushell_cmdusb_suspend();
00440       break;
00441       case CMD_USB_RESUME:
00442       ushell_cmdusb_resume();
00443       break;
00444       case CMD_USB_FORCE_ENUM:
00445       ushell_cmdusb_force_enum();
00446       break;
00447 #endif
00448 
00449       // DFU commands
00450 #if (USHELL_DFU==ENABLE)
00451       case CMD_DFU_ERASE:
00452       ushell_cmddfu_erase();
00453       break;
00454       case CMD_DFU_LOAD:
00455       ushell_cmddfu_load();
00456       break;
00457       case CMD_DFU_START:
00458       ushell_cmddfu_start();
00459       break;
00460 #endif
00461 
00462       // HID commands
00463 #if (USHELL_HID==ENABLE)
00464       case CMD_HID_ENTER_DFU:
00465       ushell_cmdhid_enter_dfu();
00466       break;
00467       case CMD_HID_GET_INFO:
00468       ushell_cmdhid_getinfo();
00469       break;
00470 #endif
00471 
00472       // Unknown command
00473       default:
00474       print_msg((U8 code *)msg_er_cmd_not_found);
00475       break;
00476    }
00477 
00478    print_msg((U8 code *)msg_prompt);
00479 }
00480 
00481 
00486 Bool ushell_cmd_scan(void)
00487 {
00488    char c_key;
00489 
00490    // Something new of the UART ?
00491    if(!ushell_test_hit())   
00492       return FALSE;
00493 
00494    c_key=ushell_get_char();
00495    
00496    if( 0 != g_u8_escape_sequence )
00497    {
00498       //** Decode escape sequence
00499       if( 1 == g_u8_escape_sequence )
00500       {
00501          if( 0x5B != c_key )
00502          {
00503             g_u8_escape_sequence=0;
00504             return FALSE;  // Escape sequence cancel
00505          }
00506          g_u8_escape_sequence=2;
00507       }
00508       else
00509       {
00510          // Decode value of the sequence
00511          switch (c_key)
00512          {
00513 /*
00514 Note: OVERRUN error on USART with an RTOS and USART without interrupt management
00515 If you want support "Escape sequence", then you have to implement USART interrupt management
00516             case 0x41:     // UP command
00517             ushell_clean_cmd_line();
00518             ushell_history_up();
00519             ushell_history_display();
00520             break;
00521             case 0x42:     // DOWN command           
00522             ushell_clean_cmd_line();
00523             ushell_history_down();
00524             ushell_history_display();
00525             break;
00526 */            
00527             default:       // Ignore other command
00528             break;
00529          }
00530          g_u8_escape_sequence=0; // End of Escape sequence 
00531       }
00532       return FALSE;
00533    }
00534    
00535    //** Normal sequence
00536    switch (c_key)
00537    {
00538       //** Command validation
00539       case ASCII_CR:
00540       ushell_putchar(ASCII_CR);     // Echo
00541       ushell_putchar(ASCII_LF);     // Add new line flag
00542       g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size]=0;  // Add NULL terminator at the end of command line
00543       return TRUE;
00544       
00545       //** Enter in escape sequence
00546       case ASCII_ESCAPE:
00547       g_u8_escape_sequence=1;
00548       break;
00549       
00550       //** backspace
00551       case ASCII_BKSPACE:
00552       if(g_u8_cmd_size>0)        // Beginning of line ?
00553       {
00554          // Remove the last character on terminal
00555          ushell_putchar(ASCII_BKSPACE);   // Send a backspace to go in previous character
00556          ushell_putchar(' ');             // Send a space to erase previous character
00557          ushell_putchar(ASCII_BKSPACE);   // Send a backspace to go in new end position (=previous character position)
00558          // Remove the last character on cmd line buffer
00559          g_u8_cmd_size--;
00560       }
00561       break;
00562       
00563       // History management
00564       case '!':
00565       ushell_clean_cmd_line();
00566       ushell_history_up();
00567       ushell_history_display();
00568       break;
00569       case '$':
00570       ushell_clean_cmd_line();
00571       ushell_history_down();
00572       ushell_history_display();
00573       break;
00574 
00575       //** Other char
00576       default:
00577       if( (0x1F<c_key) && (c_key<0x7F) && (USHELL_SIZE_CMD_LINE!=g_u8_cmd_size) )
00578       {
00579          // Accept char
00580          ushell_putchar(c_key);                                   // Echo
00581          g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size++] = c_key;  // append to cmd line
00582       }
00583       break;
00584    }
00585    return FALSE;
00586 }
00587 
00588 
00598 U8 ushell_cmd_decode( void )
00599 {
00600    U8 cmd_type;
00601    U8 u8_i,u8_j,u8_k;
00602    U8 u8_cmd_size;
00603    Bool b_arg_include_space;
00604    
00605    if(0==g_u8_cmd_size)
00606    {
00607       // Command line empty
00608       print_msg((U8 code *)msg_prompt);
00609       return CMD_NONE;
00610    }
00611 
00612    // Get command string and Change command to lower case
00613    for( u8_i=0; (g_s_cmd_his[g_u8_history_pos][u8_i]!=' ') && (u8_i<=g_u8_cmd_size); u8_i++)
00614    {
00615       g_s_cmd[u8_i] = g_s_cmd_his[g_u8_history_pos][u8_i];
00616       if( ('A'<=g_s_cmd[u8_i]) && (g_s_cmd[u8_i]<='Z') )
00617          g_s_cmd[u8_i] += ('a'-'A');
00618    }
00619    g_s_cmd[u8_i]=0;
00620    u8_cmd_size = u8_i-1;
00621 
00622    // Get arguments strings
00623    for( u8_j=0; u8_j<USHELL_MAX_NB_ARG; u8_j++ )
00624    {
00625       u8_i++;     // Jump space character
00626       // Check "
00627       b_arg_include_space = ( g_s_cmd_his[g_u8_history_pos][u8_i] == '"' );
00628       if( b_arg_include_space ) {
00629         u8_i++;
00630       }
00631       for( u8_k=0;
00632            (b_arg_include_space || (g_s_cmd_his[g_u8_history_pos][u8_i] != ' '))
00633            && ((!b_arg_include_space) || (g_s_cmd_his[g_u8_history_pos][u8_i] != '"'))
00634            && (u8_i<=g_u8_cmd_size);
00635            u8_i++, u8_k++ )
00636       {
00637          g_s_arg[u8_j][u8_k] = g_s_cmd_his[g_u8_history_pos][u8_i];
00638       }
00639       if( b_arg_include_space ) {
00640         u8_i++;   // Jump last "
00641       }
00642       g_s_arg[u8_j][u8_k] = 0;
00643    }
00644            
00645    // Reset command size and update history       
00646    g_u8_cmd_size=0;
00647    g_u8_history_pos++;
00648    if( g_u8_history_pos == USHELL_HISTORY)
00649       g_u8_history_pos = 0;
00650    g_u8_history_pos_search = g_u8_history_pos;
00651    
00652    // Decode command type
00653    if ( mystrncmp(g_s_cmd,(U8 code *)str_disk,u8_cmd_size))
00654    {  cmd_type=CMD_NB_DRIVE; }
00655    else if ( mystrncmp(g_s_cmd,(U8 code *)str_df,u8_cmd_size))
00656    {  cmd_type=CMD_DF; }
00657    else if ( mystrncmp(g_s_cmd,(U8 code *)str_format,u8_cmd_size))
00658    {  cmd_type=CMD_FORMAT; }
00659    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mount,u8_cmd_size))
00660    {  cmd_type=CMD_MOUNT; }
00661    else if ( g_s_cmd[1]==':' )
00662    {  cmd_type=CMD_MOUNT; g_s_arg[0][0]=g_s_cmd[0];g_s_arg[0][1]='0'; }
00663    else if ( mystrncmp(g_s_cmd,(U8 code *)str_space,u8_cmd_size))
00664    {  cmd_type=CMD_SPACE; }
00665    else if ( mystrncmp(g_s_cmd,(U8 code *)str_ls,u8_cmd_size))
00666    {  cmd_type=CMD_LS; }
00667    else if ( mystrncmp(g_s_cmd,(U8 code *)str_ls_more,u8_cmd_size))
00668    {  cmd_type=CMD_LS_MORE; }   
00669    else if (mystrncmp(g_s_cmd,(U8 code *)str_cd,u8_cmd_size))
00670    {  cmd_type=CMD_CD; }
00671    else if ( mystrncmp(g_s_cmd,(U8 code *)str_up,u8_cmd_size))
00672    {  cmd_type=CMD_UP; }
00673    else if ( mystrncmp(g_s_cmd,(U8 code *)str_cat,u8_cmd_size))
00674    {  cmd_type=CMD_CAT; }
00675    else if ( mystrncmp(g_s_cmd,(U8 code *)str_cat_more,u8_cmd_size))
00676    {  cmd_type=CMD_CAT_MORE; }   
00677    else if ( mystrncmp(g_s_cmd,(U8 code *)str_help,u8_cmd_size))
00678    {  cmd_type=CMD_HELP; }
00679    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mkdir,u8_cmd_size))
00680    {  cmd_type=CMD_MKDIR; }
00681    else if ( mystrncmp(g_s_cmd,(U8 code *)str_touch,u8_cmd_size))
00682    {  cmd_type=CMD_TOUCH; }
00683    else if ( mystrncmp(g_s_cmd,(U8 code *)str_rm,u8_cmd_size))
00684    {  cmd_type=CMD_RM; }
00685    else if ( mystrncmp(g_s_cmd,(U8 code *)str_append,u8_cmd_size))
00686    {  cmd_type=CMD_APPEND; }
00687    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mark,u8_cmd_size))
00688    {  cmd_type=CMD_SET_ID; }
00689    else if ( mystrncmp(g_s_cmd,(U8 code *)str_goto,u8_cmd_size))
00690    {  cmd_type=CMD_GOTO_ID; }
00691    else if ( mystrncmp(g_s_cmd,(U8 code *)str_cp,u8_cmd_size))
00692    {  cmd_type=CMD_CP; }
00693    else if ( mystrncmp(g_s_cmd,(U8 code *)str_mv,u8_cmd_size))
00694    {  cmd_type=CMD_MV; }
00695    else if ( mystrncmp(g_s_cmd,(U8 code *)str_sync,u8_cmd_size))
00696    {  cmd_type=CMD_SYNC; }
00697    else if ( mystrncmp(g_s_cmd,(U8 code *)str_perform,u8_cmd_size))
00698    {  cmd_type=CMD_PERFORM; }
00699    else if ( mystrncmp(g_s_cmd,(U8 code *)str_reboot,u8_cmd_size))
00700    {  cmd_type=CMD_REBOOT; }
00701 #if (USHELL_USB==ENABLE)
00702    else if ( mystrncmp(g_s_cmd,(U8 code *)str_ls_usb,u8_cmd_size))
00703    {  cmd_type=CMD_LS_USB; }
00704    else if ( mystrncmp(g_s_cmd,(U8 code *)str_usb_suspend,u8_cmd_size))
00705    {  cmd_type=CMD_USB_SUSPEND; }
00706    else if ( mystrncmp(g_s_cmd,(U8 code *)str_usb_resume,u8_cmd_size))
00707    {  cmd_type=CMD_USB_RESUME; }
00708    else if ( mystrncmp(g_s_cmd,(U8 code *)str_usb_force_enum,u8_cmd_size))
00709    {  cmd_type=CMD_USB_FORCE_ENUM; }
00710 #endif
00711 #if (USHELL_DFU==ENABLE)
00712    else if ( mystrncmp(g_s_cmd,(U8 code *)str_dfu_erase,u8_cmd_size))
00713    {  cmd_type=CMD_DFU_ERASE; }
00714    else if ( mystrncmp(g_s_cmd,(U8 code *)str_dfu_load,u8_cmd_size))
00715    {  cmd_type=CMD_DFU_LOAD; }
00716    else if ( mystrncmp(g_s_cmd,(U8 code *)str_dfu_start,u8_cmd_size))
00717    {  cmd_type=CMD_DFU_START; }
00718 #endif
00719 #if (USHELL_HID==ENABLE)
00720    else if ( mystrncmp(g_s_cmd,(U8 code *)str_hid_enter_dfu,u8_cmd_size))
00721    {  cmd_type=CMD_HID_ENTER_DFU; }
00722    else if ( mystrncmp(g_s_cmd,(U8 code *)str_hid_get_info,u8_cmd_size))
00723    {  cmd_type=CMD_HID_GET_INFO; }
00724 #endif
00725    else
00726    {
00727       print_msg((U8 code *)msg_er_cmd_not_found);
00728       print_msg((U8 code *)msg_prompt);
00729       return CMD_NONE;
00730    }
00731    return cmd_type;
00732 }
00733 
00734 
00737 void ushell_clean_cmd_line( void )
00738 {
00739    // Clean command line display
00740    while( 0 != g_u8_cmd_size )
00741    {
00742       // Remove the last character on cmd line buffer
00743       putchar(ASCII_BKSPACE); // Send a backspace to go in previous character
00744       putchar(' ');           // Send a space to erase previous character
00745       putchar(ASCII_BKSPACE); // Send a backspace to go in new end position (=previous character position)
00746       g_u8_cmd_size--;
00747    }
00748 }
00749 
00750 
00753 void ushell_history_up( void )
00754 {
00755    if( g_u8_history_pos_search == 0 )
00756    {
00757       if( (USHELL_HISTORY-1) == g_u8_history_pos )
00758          return;  // End of history list
00759       g_u8_history_pos_search = USHELL_HISTORY-1;
00760    }else{
00761       if( (g_u8_history_pos_search-1) == g_u8_history_pos )
00762          return;  // End of history list
00763       g_u8_history_pos_search--;
00764    }
00765    if( 0 == g_s_cmd_his[g_u8_history_pos_search][0] )
00766    {
00767       // History empty then go to previous selection
00768       ushell_history_down();
00769    }
00770 }
00771 
00772 
00775 void ushell_history_down( void )
00776 {
00777    if( g_u8_history_pos_search == g_u8_history_pos )
00778       return;  // End of history list
00779    if( g_u8_history_pos == 0 )
00780    {
00781       if( (USHELL_HISTORY-1) == g_u8_history_pos_search )
00782          return;  // End of history list
00783       g_u8_history_pos_search++;
00784    }else{
00785       if( (g_u8_history_pos_search+1) == g_u8_history_pos )
00786          return;  // End of history list
00787    }
00788    g_u8_history_pos_search++;
00789    if( USHELL_HISTORY == g_u8_history_pos_search )
00790       g_u8_history_pos_search = 0;
00791 }
00792            
00793 
00796 void ushell_history_display( void )
00797 {
00798    g_u8_cmd_size=0;
00799    while( g_s_cmd_his[g_u8_history_pos_search][g_u8_cmd_size] != 0 )
00800    {
00801       putchar( g_s_cmd_his[g_u8_history_pos_search][g_u8_cmd_size] );
00802       g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size] = g_s_cmd_his[g_u8_history_pos_search][g_u8_cmd_size];
00803       g_u8_cmd_size++;
00804    }
00805    g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size] = 0;
00806 }           
00807 
00808    
00809 
00816 #ifdef __GNUC__
00817 U8 mystrncmp(char *str1,U8 *str2,U8 u8_i)
00818 #else
00819 U8 mystrncmp(char *str1,U8 code *str2,U8 u8_i)
00820 #endif
00821 {
00822    U8 j;
00823    for(j=0;j<=u8_i;j++)
00824    {
00825 #ifndef __GNUC__
00826       if(*str1!=*str2)
00827 #else
00828       if( *str1 != pgm_read_byte_near((unsigned int)str2))
00829 #endif
00830       {
00831          return FALSE;
00832       }
00833       str1++;str2++;
00834    }
00835    return TRUE;
00836 }
00837 
00838 
00843 #ifdef __GNUC__
00844 void print_msg(U8 *str)
00845 #else
00846 void print_msg(U8 code *str)
00847 #endif
00848 {
00849    char c;
00850 #ifndef __GNUC__
00851    c=*str++;
00852    while(c!=0)
00853    {
00854       ushell_putchar(c);
00855       c=*str++;
00856    }
00857 #else    // AVRGCC does not support point to PGM space
00858    c=pgm_read_byte_near((unsigned int)str++);
00859    while(c!=0)
00860    {
00861       ushell_putchar(c);
00862       c=pgm_read_byte_near((unsigned int)str++);
00863    }
00864 #endif
00865 
00866 }
00867 
00868 
00873 Bool ushell_more_wait( void )
00874 {
00875    char c_key;
00876    printf("\n\r-- space for more--"); 
00877    c_key=0;
00878    while( (c_key!='q') && (c_key!=' ') )
00879    {
00880      c_key=ushell_get_char();
00881    }
00882    printf("\r                 \r");
00883    return (c_key==' ');
00884 }
00885 
00886 
00889 void ushell_cmd_nb_drive( void )
00890 {
00891    U8 u8_tmp;
00892    
00893    printf("Memory interface available:\r\n");
00894    for( u8_tmp=0; u8_tmp<nav_drive_nb(); u8_tmp++ )
00895    {
00896       // Display drive letter name (a, b...)
00897       ushell_putchar(u8_tmp+'a');
00898       ushell_putchar(':');
00899       ushell_putchar(' ');
00900       print_msg((U8 code *)mem_name(u8_tmp));
00901       ushell_putchar(ASCII_CR); ushell_putchar(ASCII_LF);
00902    }
00903 }
00904 
00905 
00908 void ushell_cmd_free_space( void )
00909 {
00910    U8 u8_tmp;
00911    Fs_index sav_index = nav_getindex();      // Save current position
00912    for( u8_tmp=0; u8_tmp<nav_drive_nb(); u8_tmp++ )
00913    {
00914       nav_drive_set( u8_tmp );      // Select drive
00915       if( !nav_partition_mount() )  // Mount drive
00916          continue;
00917       
00918       // Display drive letter name (a, b...)
00919       ushell_putchar( u8_tmp+'a' );
00920       ushell_putchar(':');
00921       ushell_putchar(' ');
00922       print_msg((U8 code *)mem_name(u8_tmp));
00923       printf("\n\r");
00924       
00925       if( g_s_arg[0][0]=='l' )        // Choose command option
00926       {
00927          // Long and exact fonction
00928          printf("Free space: %llu Bytes / %llu Bytes\n\r", 
00929                    (double)(nav_partition_freespace() << FS_SHIFT_B_TO_SECTOR),
00930                    (double)(nav_partition_space() << FS_SHIFT_B_TO_SECTOR));
00931       }
00932       else                    
00933       {
00934          // Otherwise use fast command
00935          printf("Free space: %u %%\n\r", nav_partition_freespace_percent() );
00936       }
00937    }
00938    nav_gotoindex(&sav_index);       // Restore position
00939 }
00940 
00941 
00944 void ushell_cmd_format( void )
00945 {
00946    if( g_s_arg[0][0] == 0 )
00947       return;
00948    
00949    // Select drive to format
00950    nav_drive_set( g_s_arg[0][0]-'a');
00951    if( !nav_drive_format(FS_FORMAT_DEFAULT) )
00952    {
00953       print_msg((U8 code *)msg_er_format);
00954       return;
00955    }
00956 }
00957 
00958 
00961 void ushell_cmd_mount( void )
00962 {
00963    U8 u8_drive_lun;
00964    Fs_index sav_index;
00965 
00966    if( g_s_arg[0][0] == 0 )
00967       return;
00968    
00969    // Compute the logical unit number of drive
00970    u8_drive_lun=g_s_arg[0][0]-'a';
00971    // Check lun number
00972    if( u8_drive_lun >= nav_drive_nb() )
00973    {
00974       print_msg((U8 code *)msg_er_drive);
00975       return;
00976    }
00977 
00978    // Mount drive
00979    sav_index = nav_getindex();      // Save previous position
00980    if( nav_drive_set(u8_drive_lun))
00981    {
00982       if( nav_partition_mount() )
00983          return;                    // Here, drive mounted
00984    }
00985    print_msg((U8 code *)msg_er_mount);
00986    nav_gotoindex(&sav_index);       // Restore previous position
00987 }
00988 
00989 
00992 void ushell_cmd_space( void )
00993 {
00994    U32 u32_space;
00995    // Display drive letter name (a, b...)
00996    print_msg((U8 code *)mem_name(nav_drive_get()));
00997    ushell_putchar(' ');
00998    ushell_putchar( nav_drive_get()+'a');
00999    // Otherwise use fast command
01000    u32_space = nav_partition_space();
01001    if( 1024 >(u32_space % (2*1024)) )
01002    {
01003       u32_space = u32_space/(2*1024);
01004    }else{
01005       u32_space = (u32_space/(2*1024))+1;
01006    }
01007    printf(": space: %luMB \n\r", u32_space );
01008 }
01009 
01010 
01015 void ushell_cmd_ls( Bool b_more )
01016 {
01017    U8 str_char[MAX_FILE_LENGHT];
01018    U16 u16_i,u16_nb_file,u16_nb_dir,last_i;
01019    U8 ext_filter=FALSE;
01020 
01021    //** Print drive name
01022    printf("%c: volume is ", 'a'+nav_drive_get() );
01023    print_msg((U8 code *)mem_name(nav_drive_get()));
01024    printf("\n\rDrive uses ");
01025    switch (nav_partition_type())
01026    {
01027       case FS_TYPE_FAT_12:
01028       printf("FAT12\n\r");
01029       break;
01030       
01031       case FS_TYPE_FAT_16:
01032       printf("FAT16\n\r");
01033       break;
01034       
01035       case FS_TYPE_FAT_32:
01036       printf("FAT32\n\r");
01037       break;
01038       
01039       default:
01040       printf("an unknown partition type\r\n");
01041       return;
01042    }
01043    
01044    //** Print directory name
01045    if( !nav_dir_name( (FS_STRING)str_char, MAX_FILE_LENGHT ) )
01046    {
01047       printf("ROOT directory\n\r");
01048    }else{
01049       printf("Dir name is %s\n\r",str_char);
01050    }
01051 
01052    //** Check extension filter in extra parameters
01053    if(g_s_arg[0][0]!=0)
01054    {
01055       if(g_s_arg[0][0] == '*' && g_s_arg[0][1]=='.')
01056       {
01057          ext_filter=TRUE;
01058          for(u16_i=2; u16_i<USHELL_SIZE_CMD_LINE; u16_i++)
01059          {
01060             g_s_arg[0][u16_i-2]=g_s_arg[0][u16_i];
01061          }
01062       }
01063    }
01064    
01065    //** Print files list
01066    printf("          Size  Name\n\r");
01067    // Init loop at the begining of directory
01068    nav_filelist_reset();
01069    u16_nb_file=0;
01070    u16_nb_dir=0;
01071    last_i=0;
01072    // For each file in list
01073    while( nav_filelist_set(0,FS_FIND_NEXT) )
01074    {  
01075       if(!ext_filter)
01076       {
01077          // No extension filter
01078          if( nav_file_isdir() )
01079          {
01080             printf("Dir ");
01081             u16_nb_dir++;              // count the number of directory
01082          }else{
01083             printf("    ");
01084          }
01085       }
01086       else
01087       {
01088          // If extension filter then ignore directories
01089          if(nav_file_isdir())
01090             continue;
01091          // Check extension
01092          if(!nav_file_checkext((FS_STRING)g_s_arg[0]))
01093             continue;
01094       }
01095       u16_nb_file++;                   // count the total of files (directories and files)
01096 
01097       // Check 'more' step
01098       if( b_more && ((u16_nb_file%USHELL_NB_LINE)==0) && (u16_nb_file!=0) && (last_i != u16_nb_file) )
01099       {
01100          last_i=u16_nb_file;
01101          if( !ushell_more_wait() )
01102             return;  // Exit LS command
01103       }
01104       
01105       // Display file
01106       nav_file_name((FS_STRING)str_char, MAX_FILE_LENGHT, FS_NAME_GET, TRUE);
01107       printf("%10lu  %s\n\r", nav_file_lgt(), str_char);
01108    }
01109    // Display total number
01110    printf(" %4i Files\r\n", u16_nb_file-u16_nb_dir );
01111    printf(" %4i Dir\r\n", u16_nb_dir );
01112 }
01113 
01114 
01117 void ushell_cmd_cd( void )
01118 { 
01119    if( g_s_arg[0][0] == 0 )
01120       return;
01121    
01122    // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into.
01123    ushell_path_valid_syntac( g_s_arg[0] );
01124    
01125    // Call file system routine
01126    if( nav_setcwd((FS_STRING)g_s_arg[0],TRUE,FALSE) == FALSE )
01127    {
01128       print_msg((U8 code *)msg_er_unknown_file);
01129    }
01130 }
01131 
01132 
01135 void ushell_cmd_gotoparent( void )
01136 {
01137    nav_dir_gotoparent();
01138 }
01139 
01140 
01147 void ushell_cmd_cat( Bool b_more)
01148 {
01149    char c_file_character;
01150    U8 n_line=0;
01151    
01152    if( g_s_arg[0][0] == 0 )
01153       return;
01154    
01155    // Select file
01156    if( !nav_setcwd((FS_STRING)g_s_arg[0],TRUE,FALSE) )
01157    {
01158       print_msg((U8 code *)msg_er_unknown_file);
01159       return;
01160    }
01161      
01162    // Open file
01163    file_open(FOPEN_MODE_R);
01164    while (file_eof()==FALSE)
01165    {
01166       // Check 'more' option
01167       if( b_more && (n_line >= USHELL_NB_LINE))
01168       {
01169          n_line = 0;
01170          if( !ushell_more_wait() )
01171             break;   // Stop cat command
01172       }
01173 
01174       // Display a character
01175       c_file_character = file_getc();
01176       ushell_putchar( c_file_character );
01177 
01178       // Count the line number
01179       if (c_file_character==ASCII_LF)
01180          n_line++;
01181    }
01182    file_close();
01183 
01184    // Jump in a new line
01185    ushell_putchar(ASCII_CR);ushell_putchar(ASCII_LF);
01186 }
01187 
01188 
01191 void ushell_cmd_help( void )
01192 {
01193    print_msg((U8 code *)msg_help);
01194 }
01195 
01196 
01199 void ushell_cmd_mkdir( void )
01200 {
01201    if( g_s_arg[0][0] == 0 )
01202       return;
01203    
01204    if( !nav_dir_make((FS_STRING)g_s_arg[0]) )
01205       print_msg((U8 code *)msg_ko);      
01206 }
01207 
01208 
01211 void ushell_cmd_touch( void )
01212 {
01213    if( g_s_arg[0][0] == 0 )
01214       return;
01215    
01216    nav_file_create((FS_STRING)g_s_arg[0]);
01217 }
01218 
01219 
01222 void ushell_cmd_rm( void )
01223 {
01224    U8 u8_i = 0;
01225    Fs_index sav_index;
01226 
01227    if( g_s_arg[0][0] == 0 )
01228       return;
01229    
01230    // Save the position
01231    sav_index = nav_getindex();
01232    
01233    while( 1 )
01234    {
01235       // Restore the position
01236       nav_gotoindex(&sav_index);
01237       // Select file or directory
01238       if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
01239          break;
01240       // Delete file or directory
01241       if( !nav_file_del( FALSE ) )
01242       {
01243          print_msg((U8 code *)msg_ko);      
01244          break;
01245       }
01246       u8_i++;
01247    }
01248    printf( "%u file(s) deleted\n\r", u8_i );
01249 }
01250 
01251 
01258 void ushell_cmd_append_file( void )
01259 {
01260    char c_key;
01261   
01262    if( g_s_arg[0][0] == 0 )
01263       return;
01264    
01265    // Select file or directory
01266    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
01267    {
01268       print_msg((U8 code *)msg_er_unknown_file);
01269       return;
01270    }
01271    // Open file
01272    if( !file_open(FOPEN_MODE_APPEND) )
01273    {
01274       print_msg((U8 code *)msg_ko);
01275       return;
01276    }
01277 
01278    // Append file
01279    print_msg((U8 code *)msg_append_welcome);
01280    while( 1 )
01281    {
01282       c_key = ushell_get_char();
01283 
01284       if( c_key == ASCII_CTRL_Q )
01285          break;   // ^q to quit
01286       
01287       ushell_putchar( c_key );
01288       file_putc( c_key );
01289       if( c_key == ASCII_CR )
01290       {
01291          ushell_putchar(ASCII_LF);
01292          file_putc(ASCII_LF);
01293       }
01294    }
01295 
01296    // Close file
01297    file_close();
01298    ushell_putchar(ASCII_CR); ushell_putchar(ASCII_LF);
01299 }
01300 
01301 
01304 void ushell_cmd_copy( void )
01305 {
01306    Fs_index sav_index;
01307    U8 u8_status_copy;
01308 
01309    if( g_s_arg[0][0] == 0 )
01310       return;
01311    
01312    // Save the position
01313    sav_index = nav_getindex();
01314    
01315    // Select source file
01316    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
01317    {
01318       print_msg((U8 code *)msg_er_unknown_file);
01319       return;
01320    }
01321    // Get name of source to be used as same destination name
01322    nav_file_name( (FS_STRING)g_s_arg[0], MAX_FILE_LENGHT, FS_NAME_GET, TRUE );              
01323    // Mark this selected file like source file
01324    if( !nav_file_copy())
01325    {
01326       print_msg((U8 code *)msg_ko);
01327       goto cp_end;
01328    }
01329 
01330    // Select destination
01331    if( g_s_arg[1][0]==0 )
01332    {
01333       // g_s_arg[1] is NULL, using mark
01334       if( !nav_gotoindex(&g_mark_index) )
01335          goto cp_end;
01336    }
01337    else
01338    {
01339       // g_s_arg[1] exists, then go to this destination
01340       if( !nav_setcwd( (FS_STRING)g_s_arg[1], TRUE, FALSE ) )
01341       {
01342          print_msg((U8 code *)msg_er_unknown_file);
01343          goto cp_end;
01344       }
01345    }
01346    
01347    // Set the name destination and start paste
01348    if( !nav_file_paste_start((FS_STRING)g_s_arg[0]) )
01349    {
01350       print_msg((U8 code *)msg_paste_fail);
01351       goto cp_end;
01352    }
01353    
01354    // Performs copy
01355    do
01356    {
01357       u8_status_copy = nav_file_paste_state( FALSE );
01358    }while( u8_status_copy == COPY_BUSY );
01359 
01360    // Check status of copy action
01361    if( u8_status_copy == COPY_FAIL )
01362    {
01363       print_msg((U8 code *)msg_paste_fail);
01364       goto cp_end;
01365    }
01366 
01367 cp_end:
01368    // Restore the position
01369    nav_gotoindex(&sav_index);
01370 }
01371 
01372 
01375 void ushell_cmd_rename( void )
01376 {
01377    if( g_s_arg[0][0] == 0 )
01378       return;
01379    if( g_s_arg[1][0] == 0 )
01380       return;
01381    
01382    // Select source file
01383    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
01384    {
01385       print_msg((U8 code *)msg_er_unknown_file);
01386       return;
01387    }
01388    // Rename file or directory
01389    if( !nav_file_rename( (FS_STRING)g_s_arg[1] ) )
01390    {
01391       print_msg((U8 code *)msg_ko);
01392       return;
01393    }
01394 }
01395 
01396 
01401 Bool ushell_cmd_sync( void )
01402 {
01403    Fs_index sav_index;
01404    U8 u8_folder_level = 0;
01405 
01406    if( g_s_arg[0][0] == 0 )
01407       return FALSE;
01408    if( g_s_arg[1][0] == 0 )
01409       return FALSE;
01410    // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into.
01411    ushell_path_valid_syntac( g_s_arg[0] );
01412    ushell_path_valid_syntac( g_s_arg[1] );
01413    
01414    printf("Synchronize folders:\n\r");
01415    sav_index = nav_getindex();   // Save the position
01416    
01417    // Select source directory in COPYFILE navigator handle
01418    nav_select( FS_NAV_ID_COPYFILE );
01419    printf("Select source directory\n\r");
01420    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
01421       goto ushell_cmd_sync_error;
01422    nav_filelist_reset();
01423 
01424    // Select destination directory in USHELL navigator handle
01425    nav_select( FS_NAV_ID_USHELL_CMD );
01426    printf("Select destination directory\n\r");
01427    if( !nav_setcwd( (FS_STRING)g_s_arg[1], TRUE, TRUE ) )
01428       goto ushell_cmd_sync_error;
01429    nav_filelist_reset();
01430 
01431    // loop to scan and create ALL folders and files
01432    while(1)
01433    {
01434       while(1)
01435       {
01436          // Loop to Search files or directories
01437          // Reselect Source
01438          nav_select( FS_NAV_ID_COPYFILE );
01439          if( nav_filelist_set( 0 , FS_FIND_NEXT ) )
01440             break;   // a next file and directory is found
01441    
01442          // No other dir or file in current dir then go to parent dir on Source and Destination disk
01443          if( 0 == u8_folder_level )
01444          {
01445             // end of update folder
01446             //********* END OF COPY **************
01447             goto ushell_cmd_sync_finish;
01448          }
01449 
01450          printf("Go to parent\n\r");
01451          // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list
01452          u8_folder_level--;
01453          if( !nav_dir_gotoparent() )
01454             goto ushell_cmd_sync_error;
01455          // Select Destination navigator and go to the same dir of Source
01456          nav_select( FS_NAV_ID_USHELL_CMD );
01457          if( !nav_dir_gotoparent() )
01458             goto ushell_cmd_sync_error;
01459       } // end of while (1)
01460       
01461       if( nav_file_isdir())
01462       {
01463          printf("Dir found - create dir: ");
01464          //** here, a new directory is found and is selected
01465          // Get name of current selection (= dir name on Source)
01466          if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, FALSE ))
01467             goto ushell_cmd_sync_error;
01468          // Enter in dir (on Source)
01469          if( !nav_dir_cd())
01470             goto ushell_cmd_sync_error;
01471          u8_folder_level++;
01472          // Select Destination disk
01473          nav_select( FS_NAV_ID_USHELL_CMD );
01474          // Create folder in Destination disk
01475          printf((char*)g_s_arg[0]);
01476          printf("\n\r");
01477          if( !nav_dir_make( (FS_STRING )g_s_arg[0] ))
01478          {
01479             if( FS_ERR_FILE_EXIST != fs_g_status )
01480                goto ushell_cmd_sync_error;
01481             // here, error the name exist
01482          }
01483          // Here the navigator have selected the folder on Destination
01484          if( !nav_dir_cd())
01485          {
01486             if( FS_ERR_NO_DIR == fs_g_status )
01487             {
01488                // FYC -> Copy impossible, because a file have the same name of folder
01489             }
01490             goto ushell_cmd_sync_error;
01491          }
01492          // here, the folder is created and the navigatorS is entered in this dir
01493       }
01494       else
01495       {
01496          printf("File found - copy file: ");
01497          //** here, a new file is found and is selected
01498          // Get name of current selection (= file name on Source)
01499          if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, FALSE ))
01500             goto ushell_cmd_sync_error;
01501          printf((char*)g_s_arg[0]);
01502          printf("\n\r");
01503          if( !nav_file_copy())
01504             goto ushell_cmd_sync_error;
01505 
01506          // Paste file in current dir of Destination disk
01507          nav_select( FS_NAV_ID_USHELL_CMD );
01508          while( !nav_file_paste_start( (FS_STRING)g_s_arg[0] ) )
01509          {
01510             // Error
01511             if( fs_g_status != FS_ERR_FILE_EXIST )
01512                goto ushell_cmd_sync_error;
01513             // File exists then deletes this one
01514             printf("File exists then deletes this one.\n\r");
01515             if( !nav_file_del( TRUE ) )
01516                goto ushell_cmd_sync_error;
01517             // here, retry PASTE                   
01518          }
01519          // Copy running
01520          {
01521          U8 status;
01522          do{
01523             status = nav_file_paste_state(FALSE);
01524          }while( COPY_BUSY == status );
01525 
01526          if( COPY_FINISH != status )
01527             goto ushell_cmd_sync_error;
01528          }
01529       } // if dir OR file
01530    } // end of first while(1)
01531  
01532 ushell_cmd_sync_error:
01533    // Restore the position
01534    nav_select( FS_NAV_ID_USHELL_CMD );
01535    nav_gotoindex(&sav_index);
01536    printf("!!!Copy fail\n\r");
01537    return FALSE;
01538    
01539 ushell_cmd_sync_finish:
01540    // Restore the position
01541    nav_select( FS_NAV_ID_USHELL_CMD );
01542    nav_gotoindex(&sav_index);
01543    printf("End of copy\n\r");
01544    return TRUE;
01545 }
01546 
01547 // File alloc space (unit sector 512B)
01548 #define  FILE_ALLOC_SIZE      ((1024*1024L)/512L)      // 1MB
01549 
01550 Fs_file_segment ushell_cmd_perform_alloc( U8 lun, U16 size_alloc )
01551 {
01552    const FS_STRING file_tmp_name = "tmp.bin";
01553    Fs_file_segment g_recorder_seg;   
01554    g_recorder_seg.u16_size = 0;   
01555 
01556    if( !nav_drive_set(lun))
01557       return g_recorder_seg;
01558 
01559    if( !nav_partition_mount() )
01560       return g_recorder_seg;
01561 
01562    if( !nav_file_create((FS_STRING)file_tmp_name))
01563    {
01564       if( FS_ERR_FILE_EXIST != fs_g_status)
01565          return g_recorder_seg;
01566       nav_file_del(FALSE);
01567       if( !nav_file_create((FS_STRING)file_tmp_name))
01568          return g_recorder_seg;
01569    }
01570    // Open file
01571    if( !file_open(FOPEN_MODE_W) )
01572    {
01573       nav_file_del(FALSE);
01574       return g_recorder_seg;
01575    }
01576    // Define the size of segment to alloc (unit 512B)
01577    // Note: you can alloc more in case of you don't know total size
01578    g_recorder_seg.u16_size = size_alloc;   
01579    // Alloc in FAT a cluster list equal or inferior at segment size
01580    if( !file_write( &g_recorder_seg ))
01581    {
01582       g_recorder_seg.u16_size = 0;   
01583       file_close();
01584       nav_file_del(FALSE);
01585    }
01586    return g_recorder_seg;   //** File open and FAT allocated
01587 }
01588 
01589 void ushell_cmd_perform_transfer( Fs_file_segment seg_src, Fs_file_segment seg_dest )
01590 {
01591    U8 id_trans_memtomem;
01592    Ctrl_status status_stream;
01593    U16 u16_i, u16_ctn, u16_trans_max;
01594    U32 u32_tmp;
01595    
01596    Timer16_set_waveform_mode(TIMER16_COMP_MODE_NORMAL);
01597    Timer16_set_clock(TIMER16_CLKIO_BY_1024); // 8MHz / 1024
01598    u16_trans_max = ( seg_src.u16_size < seg_dest.u16_size )?  seg_src.u16_size : seg_dest.u16_size;
01599    for( u16_i=2; u16_i<=u16_trans_max; u16_i*=10 )
01600    {
01601       Timer16_clear_overflow_it();
01602       Timer16_set_counter(0);
01603       id_trans_memtomem = stream_mem_to_mem( seg_src.u8_lun , seg_src.u32_addr , seg_dest.u8_lun , seg_dest.u32_addr , u16_i );
01604       if( ID_STREAM_ERR == id_trans_memtomem )
01605       {
01606          printf( "Transfert error\r\n");
01607          return;
01608       }
01609       while(1)
01610       {
01611          status_stream = stream_state( id_trans_memtomem );
01612          if( CTRL_BUSY == status_stream ) continue;
01613          if( CTRL_GOOD == status_stream ) break;
01614          if( CTRL_FAIL == status_stream ) {
01615             printf( "Transfert error\r\n");
01616             return;
01617          }
01618       }
01619       u16_ctn = Timer16_get_counter();
01620       if( Timer16_get_overflow_it() )
01621       {
01622          // Counter too small to get time
01623          if( 1 == u16_i )
01624             printf( "Transfert too slow\r\n");
01625          break;
01626       }
01627       u32_tmp = ((U32)u16_i*1000)/((2*(U32)u16_ctn*1024)/8000);
01628       printf( "Transfert rate %4luKB/s - stream size %4iKB\r\n", u32_tmp, u16_i/2 );
01629    }
01630 }
01631 
01632 void ushell_cmd_perform_access( Bool b_sens_write, Fs_file_segment seg )
01633 {
01634    U16 u16_trans,u16_ctn;
01635    U32 u32_tmp;
01636    
01637    fat_cache_flush();
01638    fat_cache_reset();
01639    Timer16_set_waveform_mode(TIMER16_COMP_MODE_NORMAL);
01640    Timer16_set_clock(TIMER16_CLKIO_BY_1024); // 8MHz / 1024
01641    Timer16_clear_overflow_it();
01642    Timer16_set_counter(0);
01643    for( u16_trans=0; u16_trans<seg.u16_size; u16_trans++ )
01644    {         
01645       if( b_sens_write )
01646       {
01647          if( CTRL_GOOD != ram_2_memory( seg.u8_lun , seg.u32_addr , fs_g_sector )) {
01648             printf( "Transfert error\r\n");
01649             return;
01650          }
01651       }else{
01652          if( CTRL_GOOD != memory_2_ram( seg.u8_lun , seg.u32_addr , fs_g_sector )) {
01653             printf( "Transfert error\r\n");
01654             return;
01655          }
01656       }
01657       seg.u32_addr++;
01658       if( Timer16_get_overflow_it() )
01659       {
01660          u16_trans--;
01661          break;
01662       }
01663       u16_ctn = Timer16_get_counter();
01664    }
01665    u32_tmp = ((U32)u16_trans*1000)/((2*(U32)u16_ctn*1024)/8000);
01666    if( b_sens_write )
01667       printf( "Transfert rate - WRITE %4luKB/s\r\n", u32_tmp );
01668    else
01669       printf( "Transfert rate - READ %4luKB/s\r\n", u32_tmp );
01670 }
01671 
01674 void ushell_cmd_perform( void )
01675 {
01676    Fs_index sav_index;
01677    Fs_file_segment seg1, seg2;
01678 
01679    if( g_s_arg[0][0] == 0 )
01680       return;
01681    
01682    sav_index = nav_getindex();   // Save the position
01683    
01684    // Alloc a file on each devices
01685    printf("Alloc a file on each devices\n\r");
01686    seg1 = ushell_cmd_perform_alloc( (g_s_arg[0][0]-'a') , FILE_ALLOC_SIZE );
01687    if( seg1.u16_size == 0 )
01688    {
01689       printf("!!!Error allocation on device 1\n\r");
01690       // Restore the position
01691       nav_gotoindex(&sav_index);
01692       return;
01693    }
01694    if( g_s_arg[1][0] != 0 )
01695    {
01696       nav_select( FS_NAV_ID_COPYFILE );
01697       seg2 = ushell_cmd_perform_alloc( (g_s_arg[1][0]-'a') , FILE_ALLOC_SIZE );
01698       if( seg2.u16_size == 0 )
01699       {
01700          nav_select( FS_NAV_ID_USHELL_CMD );   
01701          file_close();
01702          nav_file_del(FALSE);
01703          printf("!!!Error allocation on device 2\n\r");
01704          // Restore the position
01705          nav_gotoindex(&sav_index);
01706          return;
01707       }   
01708       
01709       // Transfert data from device 1 to device 2
01710       printf("Transfert data from device 1 to device 2\r\n");
01711       ushell_cmd_perform_transfer(seg1,seg2);
01712       printf("Transfert data from device 2 to device 1\r\n");
01713       ushell_cmd_perform_transfer(seg2,seg1);
01714       // Delete files allocated
01715       nav_select( FS_NAV_ID_COPYFILE );   
01716       file_close();
01717       nav_file_del(FALSE);
01718       nav_select( FS_NAV_ID_USHELL_CMD );
01719    }
01720    else
01721    {
01722       ushell_cmd_perform_access( FALSE, seg1 );
01723       ushell_cmd_perform_access( TRUE, seg1 );
01724    }
01725    
01726    file_close();
01727    nav_file_del(FALSE);
01728    // Restore the position
01729    nav_gotoindex(&sav_index);
01730    printf("End of test\n\r");
01731    return;   
01732 }
01733 
01734 
01735 
01736 
01739 void ushell_path_valid_syntac( char *path )
01740 {
01741    U8 u8_tmp;
01742    
01743    // Compute size of substitute
01744    for( u8_tmp=0; u8_tmp<MAX_FILE_LENGHT; u8_tmp++ )
01745    {
01746       if( path[u8_tmp]==0)
01747          break;
01748    }
01749    // Append the '\' char for the nav_setcwd to enter the found directory
01750    if ( path[u8_tmp-1] != '\\')
01751    {
01752       path[u8_tmp]='\\';
01753       path[u8_tmp+1]=0;
01754    }
01755 }
01756 
01757 
01760 void ushell_cmd_reboot( void )
01761 {
01762    // Reset SPI interface
01763 #ifdef SPIDER_ADC_BRIDGE
01764    #if (TARGET_BOARD==SPIDER)
01765    SPI_InterMCU_Ready();
01766    Spider_bridge_reset();
01767    SPI_InterMCU_Suspend();
01768    #endif
01769 #endif
01770    // Enable watch dog
01771    wdtdrv_enable(WDTO_16MS);
01772    // Wait watch dog event
01773    while(1);
01774 }
01775 
01776 
01777 #if (USHELL_USB==ENABLE)
01782 void ushell_cmdusb_ls(void)
01783 {
01784    U8 i,j,n,s;
01785 
01786    // Check USB host status
01787    if( (!Is_host_ready()) && (!Is_host_suspended()) )
01788    {
01789       print_msg((U8 code *)msg_no_device);
01790       return;
01791    }
01792    if( Is_host_suspended() )
01793    {
01794       print_msg((U8 code *)msg_usb_suspended);
01795    }
01796    
01797    s = selected_device;
01798    for( n=0; n<Get_nb_device(); n++ )
01799    {
01800       Host_select_device(n);
01801       printf("\n\rDevice %i @:0x%02X\n\r",n+1,usb_tree.device[selected_device].device_address);
01802       printf("VID:%04X, PID:%04X, ",Get_VID(),Get_PID());
01803       printf("MaxPower is %imA, ",2*Get_maxpower());
01804       if (Is_device_self_powered())
01805       {  print_msg((U8 code *)msg_device_self_powered); }
01806       else
01807       {  print_msg((U8 code *)msg_device_bus_powered); }
01808       printf("Control Endpoint is %i bytes, ",Get_ep0_size()); 
01809       if (Is_host_full_speed())
01810       {  print_msg((U8 code *)msg_device_full_speed); }
01811       else
01812       {  print_msg((U8 code *)msg_device_low_speed); }
01813       if (Is_device_supports_remote_wakeup())
01814       {  print_msg((U8 code *)msg_remote_wake_up_ok); }
01815       else
01816       {  print_msg((U8 code *)msg_remote_wake_up_ko); }
01817       printf("Supported interface(s):%02i\n\r",Get_nb_supported_interface());
01818       for(i=0;i<Get_nb_supported_interface();i++)
01819       {
01820          printf("Interface nb:%02i, AltS nb:%02i, Class:%02i, SubClass:%02i, Protocol:%02i\n\r",\
01821             Get_interface_number(i), Get_alts_s(i), Get_class(i), Get_subclass(i), Get_protocol(i));
01822          printf(" Endpoint(s) Addr:");
01823          if(Get_nb_ep(i))
01824          {
01825             for(j=0;j<Get_nb_ep(i);j++)
01826             {
01827                printf(" %02X", Get_ep_addr(i,j));
01828             }
01829          }
01830          else
01831          {
01832             printf("None");
01833          }
01834          ushell_putchar(ASCII_CR);ushell_putchar(ASCII_LF);
01835          printf(" Physical pipe(s):");
01836          if(Get_nb_ep(i))
01837          {
01838             for(j=0;j<Get_nb_ep(i);j++)
01839             {
01840                printf(" %02X", usb_tree.device[selected_device].interface[i].ep[j].pipe_number);
01841             }
01842          }
01843          else
01844          {
01845             printf("None");
01846          }
01847          ushell_putchar(ASCII_CR);ushell_putchar(ASCII_LF);         
01848       }
01849    }
01850    selected_device=s;
01851 }
01852 
01855 void ushell_cmdusb_suspend(void)
01856 {
01857    if( !Is_host_ready() )
01858    {
01859       print_msg((U8 code *)msg_no_device);
01860    }
01861    Host_request_suspend();
01862 }
01863 
01866 void ushell_cmdusb_resume(void)
01867 {
01868    if( !Is_host_suspended() )
01869    {
01870       print_msg((U8 code *)msg_no_device);
01871    }
01872    Host_request_resume();
01873 }
01874 
01875 
01878 void ushell_cmdusb_force_enum(void)
01879 {
01880    if( !Is_host_ready() )
01881    {
01882       print_msg((U8 code *)msg_no_device);
01883    }
01884    Host_force_enumeration();
01885 }
01886 #endif //USHELL_USB==ENABLE
01887 
01888 
01889 #if (USHELL_DFU==ENABLE)
01892 void ushell_cmddfu_erase( void )
01893 {
01894    if( !Is_dfu_connected() )
01895    {
01896       print_msg((U8 code *)msg_no_device);
01897       return;
01898    }
01899    Dfu_erase();
01900 }
01901 
01904 void ushell_cmddfu_load( void )
01905 {
01906    if( !Is_dfu_connected() )
01907    {
01908       print_msg((U8 code *)msg_no_device);
01909       return;
01910    }
01911    // Select source file
01912    if( !nav_setcwd( (FS_STRING)g_s_arg[0], TRUE, FALSE ) )
01913    {
01914       print_msg((U8 code *)msg_er_unknown_file);
01915       return;
01916    }
01917    Dfu_erase();
01918    if( !dfu_load_hex() )
01919    {
01920       print_msg((U8 code *)msg_ko);
01921       return;
01922    }
01923    print_msg((U8 code *)msg_ok);
01924 }
01925 
01928 void ushell_cmddfu_start( void )
01929 {
01930    if( !Is_dfu_connected() )
01931    {
01932       print_msg((U8 code *)msg_no_device);
01933       return;
01934    }
01935    Dfu_start_appli();
01936 }
01937 #endif   // (USHELL_DFU==ENABLE)
01938 
01939 
01940 #if (USHELL_HID==ENABLE)
01943 void ushell_cmdhid_enter_dfu(void)
01944 {
01945    if( !Is_hid_connected() )
01946    {
01947       print_msg((U8 code *)msg_no_device);
01948    }
01949    Hid_send_enter_dfu();
01950 }
01951 
01954 void ushell_cmdhid_getinfo(void)
01955 {
01956    if( !Is_hid_connected() )
01957    {
01958       print_msg((U8 code *)msg_no_device);
01959       return;
01960    }         
01961 #if( HID_GENERIC_DEMO_FULL == ENABLE )         
01962    printf("Temperature %i C\n\r",Hid_get_temperature());
01963    printf("Potentiometer %i\n\r",Hid_get_potentiometer());
01964 #else
01965    printf("No data available with this HID generic configuration.\n\r");
01966 #endif
01967 }
01968 #endif // (USHELL_HID==ENABLE)
01969 
01970 
01971 #ifdef   LOG_STR_CODE
01976 extern void ushell_trace_msg(U8 code *str)
01977 {
01978    ushell_putchar(CR);
01979    ushell_putchar(LF);
01980    print_msg((U8 code *)str);
01981    ushell_putchar(CR);
01982    ushell_putchar(LF);
01983    print_msg((U8 code *)msg_prompt);
01984 }
01985 #endif
01986 

Generated on Fri May 15 15:41:37 2009 for ATMEL by  doxygen 1.5.3