ATMEL: ushell_task.c Source File

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# ushell_task.c

Go to the documentation of this file.

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