Ver Fonte

refine mouse demo

hathach há 12 anos atrás
pai
commit
86b3e3174d
5 ficheiros alterados com 1141 adições e 1118 exclusões
  1. 106 103
      demos/bsp/boards/ansi_escape.h
  2. 139 138
      demos/bsp/boards/board.h
  3. 438 439
      demos/host/src/cli.c
  4. 263 263
      demos/host/src/main.c
  5. 195 175
      demos/host/src/mouse_app.c

+ 106 - 103
demos/bsp/boards/ansi_escape.h

@@ -1,103 +1,106 @@
-/**************************************************************************/
-/*!
-    @file     ansi_esc_code.h
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    This file is part of the tinyusb stack.
-*/
-/**************************************************************************/
-
-/** \file
- *  \brief TBD
- *
- *  \note TBD
- */
-
-/** \ingroup TBD
- *  \defgroup TBD
- *  \brief TBD
- *
- *  @{
- */
-
-#ifndef _TUSB_ANSI_ESC_CODE_H_
-#define _TUSB_ANSI_ESC_CODE_H_
-
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#define CSI_CODE(seq)   "\33[" seq
-#define CSI_SGR(x)      CSI_CODE(#x) "m"
-
-//------------- Cursor movement -------------//
-#define ANSI_CURSOR_UP(n)        CSI_CODE(#n "A")
-#define ANSI_CURSOR_DOWN(n)      CSI_CODE(#n "B")
-#define ANSI_CURSOR_FORWARD(n)   CSI_CODE(#n "C")
-#define ANSI_CURSOR_BACKWARD(n)  CSI_CODE(#n "D")
-#define ANSI_CURSOR_LINE_DOWN(n) CSI_CODE(#n "E")
-#define ANSI_CURSOR_LINE_UP(n)   CSI_CODE(#n "F")
-#define ANSI_CURSOR_POSITION(n, m) CSI_CODE(#n ";" #m "H")
-
-#define ANSI_ERASE_SCREEN(n)     CSI_CODE(#n "J")
-#define ANSI_ERASE_LINE(n)       CSI_CODE(#n "K")
-
-/** text color */
-#define ANSI_TEXT_BLACK          CSI_SGR(30)
-#define ANSI_TEXT_RED            CSI_SGR(31)
-#define ANSI_TEXT_GREEN          CSI_SGR(32)
-#define ANSI_TEXT_YELLOW         CSI_SGR(33)
-#define ANSI_TEXT_BLUE           CSI_SGR(34)
-#define ANSI_TEXT_MAGENTA        CSI_SGR(35)
-#define ANSI_TEXT_CYAN           CSI_SGR(36)
-#define ANSI_TEXT_WHITE          CSI_SGR(37)
-#define ANSI_TEXT_DEFAULT        CSI_SGR(39)
-
-/** background color */
-#define ANSI_BG_BLACK            CSI_SGR(40)
-#define ANSI_BG_RED              CSI_SGR(41)
-#define ANSI_BG_GREEN            CSI_SGR(42)
-#define ANSI_BG_YELLOW           CSI_SGR(43)
-#define ANSI_BG_BLUE             CSI_SGR(44)
-#define ANSI_BG_MAGENTA          CSI_SGR(45)
-#define ANSI_BG_CYAN             CSI_SGR(46)
-#define ANSI_BG_WHITE            CSI_SGR(47)
-#define ANSI_BG_DEFAULT          CSI_SGR(49)
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _TUSB_ANSI_ESC_CODE_H_ */
-
-/** @} */
+/**************************************************************************/
+/*!
+    @file     ansi_esc_code.h
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \file
+ *  \brief TBD
+ *
+ *  \note TBD
+ */
+
+/** \ingroup TBD
+ *  \defgroup TBD
+ *  \brief TBD
+ *
+ *  @{
+ */
+
+#ifndef _TUSB_ANSI_ESC_CODE_H_
+#define _TUSB_ANSI_ESC_CODE_H_
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define CSI_CODE(seq)   "\33[" seq
+#define CSI_SGR(x)      CSI_CODE(#x) "m"
+
+//------------- Cursor movement -------------//
+#define ANSI_CURSOR_UP(n)        CSI_CODE(#n "A")
+#define ANSI_CURSOR_DOWN(n)      CSI_CODE(#n "B")
+#define ANSI_CURSOR_FORWARD(n)   CSI_CODE(#n "C")
+#define ANSI_CURSOR_BACKWARD(n)  CSI_CODE(#n "D")
+#define ANSI_CURSOR_LINE_DOWN(n) CSI_CODE(#n "E")
+#define ANSI_CURSOR_LINE_UP(n)   CSI_CODE(#n "F")
+#define ANSI_CURSOR_POSITION(n, m) CSI_CODE(#n ";" #m "H")
+
+#define ANSI_ERASE_SCREEN(n)     CSI_CODE(#n "J")
+#define ANSI_ERASE_LINE(n)       CSI_CODE(#n "K")
+
+#define ANSI_SCROLL_UP(n)        CSI_CODE(#n "S")
+#define ANSI_SCROLL_DOWN(n)      CSI_CODE(#n "T")
+
+/** text color */
+#define ANSI_TEXT_BLACK          CSI_SGR(30)
+#define ANSI_TEXT_RED            CSI_SGR(31)
+#define ANSI_TEXT_GREEN          CSI_SGR(32)
+#define ANSI_TEXT_YELLOW         CSI_SGR(33)
+#define ANSI_TEXT_BLUE           CSI_SGR(34)
+#define ANSI_TEXT_MAGENTA        CSI_SGR(35)
+#define ANSI_TEXT_CYAN           CSI_SGR(36)
+#define ANSI_TEXT_WHITE          CSI_SGR(37)
+#define ANSI_TEXT_DEFAULT        CSI_SGR(39)
+
+/** background color */
+#define ANSI_BG_BLACK            CSI_SGR(40)
+#define ANSI_BG_RED              CSI_SGR(41)
+#define ANSI_BG_GREEN            CSI_SGR(42)
+#define ANSI_BG_YELLOW           CSI_SGR(43)
+#define ANSI_BG_BLUE             CSI_SGR(44)
+#define ANSI_BG_MAGENTA          CSI_SGR(45)
+#define ANSI_BG_CYAN             CSI_SGR(46)
+#define ANSI_BG_WHITE            CSI_SGR(47)
+#define ANSI_BG_DEFAULT          CSI_SGR(49)
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_ANSI_ESC_CODE_H_ */
+
+/** @} */

+ 139 - 138
demos/bsp/boards/board.h

@@ -1,138 +1,139 @@
-/**************************************************************************/
-/*!
-    @file     board.h
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    This file is part of the tinyusb stack.
-*/
-/**************************************************************************/
-
-/** \file
- *  \brief TBD
- *
- *  \note TBD
- */
-
-/**
- *  \defgroup Group_Board Boards
- *  \brief TBD
- *
- *  @{
- */
-
-#ifndef _TUSB_BOARD_H_
-#define _TUSB_BOARD_H_
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "tusb.h"
-
-//--------------------------------------------------------------------+
-// BOARD DEFINE
-//--------------------------------------------------------------------+
-#define BOARD_RF1GHZNODE            1
-#define BOARD_LPCXPRESSO1347        2
-
-#define BOARD_NGX4330               3
-#define BOARD_EA4357                4
-#define BOARD_MCB4300               5
-#define BOARD_HITEX4350             6
-#define BOARD_LPCXPRESSO1769        7
-
-#define BOARD_LPC4357USB            8
-
-//--------------------------------------------------------------------+
-// PRINTF TARGET DEFINE
-//--------------------------------------------------------------------+
-#define PRINTF_TARGET_SEMIHOST      1
-#define PRINTF_TARGET_UART          2
-#define PRINTF_TARGET_SWO           3 // aka SWV, ITM
-#define PRINTF_TARGET_NONE          4
-
-#define PRINTF(...) printf(__VA_ARGS__)
-
-#if BOARD == 0
-  #error BOARD is not defined or supported yet
-#elif BOARD == BOARD_NGX4330
-  #include "ngx/board_ngx4330.h"
-#elif BOARD == BOARD_LPCXPRESSO1347
-  #include "lpcxpresso/board_lpcxpresso1347.h"
-#elif BOARD == BOARD_RF1GHZNODE
-  #include "microbuilder/board_rf1ghznode.h"
-#elif BOARD == BOARD_EA4357
-  #include "embedded_artists/board_ea4357.h"
-#elif BOARD == BOARD_MCB4300
-  #include "keil/board_mcb4300.h"
-#elif BOARD == BOARD_HITEX4350
-  #include "hitex/board_hitex4350.h"
-#elif BOARD == BOARD_LPCXPRESSO1769
-  #include "lpcxpresso/board_lpcxpresso1769.h"
-#elif BOARD == BOARD_LPC4357USB
-  #include "microbuilder/board_lpc4357usb.h"
-#else
-  #error BOARD is not defined or supported yet
-#endif
-
-//--------------------------------------------------------------------+
-// Common Configuration
-//--------------------------------------------------------------------+
-#define CFG_TICKS_PER_SECOND 1000
-
-#if CFG_PRINTF_TARGET == PRINTF_TARGET_UART
-  #define CFG_UART_ENABLE      1
-  #define CFG_UART_BAUDRATE    115200
-#endif
-
-//--------------------------------------------------------------------+
-// Board Common API
-//--------------------------------------------------------------------+
-// Init board peripherals : Clock, UART, LEDs, Buttons
-void board_init(void);
-void board_leds(uint32_t on_mask, uint32_t off_mask);
-uint32_t board_uart_send(uint8_t *buffer, uint32_t length);
-uint32_t board_uart_recv(uint8_t *buffer, uint32_t length);
-uint8_t  board_uart_getchar(void);
-
-extern volatile uint32_t system_ticks;
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _TUSB_BOARD_H_ */
-
-/** @} */
+/**************************************************************************/
+/*!
+    @file     board.h
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \file
+ *  \brief TBD
+ *
+ *  \note TBD
+ */
+
+/**
+ *  \defgroup Group_Board Boards
+ *  \brief TBD
+ *
+ *  @{
+ */
+
+#ifndef _TUSB_BOARD_H_
+#define _TUSB_BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "ansi_escape.h"
+#include "tusb.h"
+
+//--------------------------------------------------------------------+
+// BOARD DEFINE
+//--------------------------------------------------------------------+
+#define BOARD_RF1GHZNODE            1
+#define BOARD_LPCXPRESSO1347        2
+
+#define BOARD_NGX4330               3
+#define BOARD_EA4357                4
+#define BOARD_MCB4300               5
+#define BOARD_HITEX4350             6
+#define BOARD_LPCXPRESSO1769        7
+
+#define BOARD_LPC4357USB            8
+
+//--------------------------------------------------------------------+
+// PRINTF TARGET DEFINE
+//--------------------------------------------------------------------+
+#define PRINTF_TARGET_SEMIHOST      1
+#define PRINTF_TARGET_UART          2
+#define PRINTF_TARGET_SWO           3 // aka SWV, ITM
+#define PRINTF_TARGET_NONE          4
+
+#define PRINTF(...) printf(__VA_ARGS__)
+
+#if BOARD == 0
+  #error BOARD is not defined or supported yet
+#elif BOARD == BOARD_NGX4330
+  #include "ngx/board_ngx4330.h"
+#elif BOARD == BOARD_LPCXPRESSO1347
+  #include "lpcxpresso/board_lpcxpresso1347.h"
+#elif BOARD == BOARD_RF1GHZNODE
+  #include "microbuilder/board_rf1ghznode.h"
+#elif BOARD == BOARD_EA4357
+  #include "embedded_artists/board_ea4357.h"
+#elif BOARD == BOARD_MCB4300
+  #include "keil/board_mcb4300.h"
+#elif BOARD == BOARD_HITEX4350
+  #include "hitex/board_hitex4350.h"
+#elif BOARD == BOARD_LPCXPRESSO1769
+  #include "lpcxpresso/board_lpcxpresso1769.h"
+#elif BOARD == BOARD_LPC4357USB
+  #include "microbuilder/board_lpc4357usb.h"
+#else
+  #error BOARD is not defined or supported yet
+#endif
+
+//--------------------------------------------------------------------+
+// Common Configuration
+//--------------------------------------------------------------------+
+#define CFG_TICKS_PER_SECOND 1000
+
+#if CFG_PRINTF_TARGET == PRINTF_TARGET_UART
+  #define CFG_UART_ENABLE      1
+  #define CFG_UART_BAUDRATE    115200
+#endif
+
+//--------------------------------------------------------------------+
+// Board Common API
+//--------------------------------------------------------------------+
+// Init board peripherals : Clock, UART, LEDs, Buttons
+void board_init(void);
+void board_leds(uint32_t on_mask, uint32_t off_mask);
+uint32_t board_uart_send(uint8_t *buffer, uint32_t length);
+uint32_t board_uart_recv(uint8_t *buffer, uint32_t length);
+uint8_t  board_uart_getchar(void);
+
+extern volatile uint32_t system_ticks;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_BOARD_H_ */
+
+/** @} */

+ 438 - 439
demos/host/src/cli.c

@@ -1,439 +1,438 @@
-/**************************************************************************/
-/*!
-    @file     cli.c
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-
-#include "cli.h"
-#include "ctype.h"
-
-#if TUSB_CFG_HOST_MSC
-
-#include "ff.h"
-#include "diskio.h"
-#include "boards/ansi_escape.h"
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-#define CLI_MAX_BUFFER        256
-#define CLI_FILE_READ_BUFFER  (4*1024)
-
-enum {
-  ASCII_BACKSPACE = 8,
-};
-
-typedef enum {
-  CLI_ERROR_NONE = 0,
-  CLI_ERROR_INVALID_PARA,
-  CLI_ERROR_INVALID_PATH,
-  CLI_ERROR_FILE_EXISTED,
-  CLI_ERROR_FAILED
-}cli_error_t;
-
-static char const * const cli_error_message[] =
-{
-  [CLI_ERROR_NONE         ] = 0,
-  [CLI_ERROR_INVALID_PARA ] = "Invalid parameter(s)",
-  [CLI_ERROR_INVALID_PATH ] = "No such file or directory",
-  [CLI_ERROR_FILE_EXISTED ] = "file or directory already exists",
-  [CLI_ERROR_FAILED       ] = "failed to execute"
-};
-
-//--------------------------------------------------------------------+
-// CLI Database definition
-//--------------------------------------------------------------------+
-
-// command, function, description
-#define CLI_COMMAND_TABLE(ENTRY)   \
-    ENTRY(unknown , cli_cmd_unknown  , NULL                                                                  ) \
-    ENTRY(help    , cli_cmd_help     , NULL                                                                  ) \
-    ENTRY(cls     , cli_cmd_clear    , "Clear the screen."                                                   ) \
-    ENTRY(ls      , cli_cmd_list     , "List information about the FILEs (the current directory by default).") \
-    ENTRY(cd      , cli_cmd_changedir, "change the current directory."                                       ) \
-    ENTRY(cat     , cli_cmd_cat      , "display contents of a file."                                         ) \
-    ENTRY(cp      , cli_cmd_copy     , "Copies one or more files to another location."                       ) \
-    ENTRY(mkdir   , cli_cmd_mkdir    , "Create a DIRECTORY, if it does not already exist."                   ) \
-
-//--------------------------------------------------------------------+
-// Expands the function to have the standard function signature
-//--------------------------------------------------------------------+
-#define CLI_PROTOTYPE_EXPAND(command, function, description) \
-    cli_error_t function(char *);
-
-CLI_COMMAND_TABLE(CLI_PROTOTYPE_EXPAND);
-
-//--------------------------------------------------------------------+
-// Expand to enum value
-//--------------------------------------------------------------------+
-#define CLI_ENUM_EXPAND(command, function, description)    CLI_CMDTYPE_##command,
-typedef enum {
-  CLI_COMMAND_TABLE(CLI_ENUM_EXPAND)
-  CLI_CMDTYPE_COUNT
-}cli_cmdtype_t;
-
-//--------------------------------------------------------------------+
-// Expand to string table
-//--------------------------------------------------------------------+
-#define CLI_STRING_EXPAND(command, function, description)    #command,
-char const* const cli_string_tbl[] =
-{
-  CLI_COMMAND_TABLE(CLI_STRING_EXPAND)
-  0
-};
-
-//--------------------------------------------------------------------+
-// Expand to Description table
-//--------------------------------------------------------------------+
-#define CLI_DESCRIPTION_EXPAND(command, function, description)    description,
-char const* const cli_description_tbl[] =
-{
-  CLI_COMMAND_TABLE(CLI_DESCRIPTION_EXPAND)
-  0
-};
-
-
-//--------------------------------------------------------------------+
-// Expand to Command Lookup Table
-//--------------------------------------------------------------------+
-#define CMD_LOOKUP_EXPAND(command, function, description)\
-  [CLI_CMDTYPE_##command] = function,\
-
-typedef cli_error_t (* const cli_cmdfunc_t)(char *);
-static cli_cmdfunc_t cli_command_tbl[] =
-{
-  CLI_COMMAND_TABLE(CMD_LOOKUP_EXPAND)
-};
-
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-static char cli_buffer[CLI_MAX_BUFFER];
-uint8_t fileread_buffer[CLI_FILE_READ_BUFFER] TUSB_CFG_ATTR_USBRAM;
-static char volume_label[20];
-
-static inline void drive_number2letter(char * p_path) ATTR_ALWAYS_INLINE;
-static inline void drive_number2letter(char * p_path)
-{
-  if (p_path[1] == ':')
-  {
-    p_path[0] = 'E' + p_path[0] - '0' ;
-  }
-}
-
-static inline void drive_letter2number(char * p_path) ATTR_ALWAYS_INLINE;
-static inline void drive_letter2number(char * p_path)
-{
-  if (p_path[1] == ':')
-  {
-    p_path[0] = p_path[0] - 'E' + '0';
-  }
-}
-
-
-//--------------------------------------------------------------------+
-// IMPLEMENTATION
-//--------------------------------------------------------------------+
-// NOTES: prompt re-use cli_buffer --> should not be called when cli_buffer has contents
-void cli_command_prompt(void)
-{
-  f_getcwd(cli_buffer, CLI_MAX_BUFFER);
-  drive_number2letter(cli_buffer);
-  printf("\n%s %s\n$ ",
-         (volume_label[0] !=0) ? volume_label : "No Label",
-         cli_buffer);
-
-  memclr_(cli_buffer, CLI_MAX_BUFFER);
-}
-
-void cli_init(void)
-{
-  memclr_(cli_buffer, CLI_MAX_BUFFER);
-  f_getlabel(NULL, volume_label, NULL);
-  cli_command_prompt();
-}
-
-void cli_poll(char ch)
-{
-  if ( isprint(ch) )
-  { // accumulate & echo
-    if (strlen(cli_buffer) < CLI_MAX_BUFFER)
-    {
-      cli_buffer[ strlen(cli_buffer) ] = ch;
-      putchar(ch);
-    }else
-    {
-      puts("cli buffer overflows");
-      memclr_(cli_buffer, CLI_MAX_BUFFER);
-    }
-  }
-  else if ( ch == ASCII_BACKSPACE && strlen(cli_buffer))
-  {
-    printf(ANSI_CURSOR_BACKWARD(1) ANSI_ERASE_LINE(0) ); // move cursor back & clear to the end of line
-    cli_buffer[ strlen(cli_buffer)-1 ] = 0;
-  }
-  else if ( ch == '\r')
-  { // execute command
-    //------------- Separate Command & Parameter -------------//
-    putchar('\n');
-    char* p_space = strchr(cli_buffer, ' ');
-    uint32_t command_len = (p_space == NULL) ? strlen(cli_buffer) : (p_space - cli_buffer);
-    char* p_para = (p_space == NULL) ? (cli_buffer+command_len) : (p_space+1); // point to NULL-character or after space
-
-    //------------- Find entered command in lookup table & execute it -------------//
-    cli_cmdtype_t cmd_id;
-    for(cmd_id = CLI_CMDTYPE_COUNT - 1; cmd_id > CLI_CMDTYPE_unknown; cmd_id--)
-    {
-      if( 0 == strncmp(cli_buffer, cli_string_tbl[cmd_id], command_len) )
-      {
-        break;
-      }
-    }
-
-    cli_error_t error = cli_command_tbl[cmd_id]( p_para ); // command execution, (unknown command if cannot find)
-
-    if (CLI_ERROR_NONE != error)  puts(cli_error_message[error]); // error message output if any
-
-    //------------- print out current path -------------//
-    cli_command_prompt();
-  }
-  else if (ch=='\t') // \t may be used for auto-complete later
-  {
-
-  }
-}
-
-//--------------------------------------------------------------------+
-// UNKNOWN Command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_unknown(char * para)
-{
-  puts("unknown command, please type \"help\" for list of supported commands");
-  return CLI_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// HELP command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_help(char * para)
-{
-  puts("current supported commands are:");
-  for(cli_cmdtype_t cmd_id = CLI_CMDTYPE_help+1; cmd_id < CLI_CMDTYPE_COUNT; cmd_id++)
-  {
-    printf("%s\t%s\n", cli_string_tbl[cmd_id], cli_description_tbl[cmd_id]);
-  }
-
-  return CLI_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// Clear Screen Command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_clear(char* p_para)
-{
-  printf(ANSI_ERASE_SCREEN(2) ANSI_CURSOR_POSITION(1,1) );
-  return CLI_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// LS Command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_list(char * p_para)
-{
-  if ( strlen(p_para) == 0 ) // list current directory
-  {
-    DIR target_dir;
-    if ( FR_OK != f_opendir(&target_dir, ".") ) return CLI_ERROR_FAILED;
-
-    TCHAR long_filename[_MAX_LFN];
-    FILINFO dir_entry =
-    {
-        .lfname = long_filename,
-        .lfsize = _MAX_LFN
-    };
-    while( (f_readdir(&target_dir, &dir_entry) == FR_OK)  && dir_entry.fname[0] != 0)
-    {
-      if ( dir_entry.fname[0] != '.' ) // ignore . and .. entry
-      {
-        TCHAR const * const p_name = (dir_entry.lfname[0] != 0) ? dir_entry.lfname : dir_entry.fname;
-        if ( dir_entry.fattrib & AM_DIR ) // directory
-        {
-          printf("/%s", p_name);
-        }else
-        {
-          printf("%-40s%d KB", p_name, dir_entry.fsize / 1000);
-        }
-        putchar('\n');
-      }
-    }
-
-//    (void) f_closedir(&target_dir);
-  }
-  else
-  {
-    puts("ls only supports list current directory only, try to cd to that folder first");
-    return CLI_ERROR_INVALID_PARA;
-  }
-
-  return CLI_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// CD Command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_changedir(char * p_para)
-{
-  if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA;
-
-  drive_letter2number(p_para);
-
-  if ( FR_OK != f_chdir(p_para) )
-  {
-    return CLI_ERROR_INVALID_PATH;
-  }
-
-  if ( p_para[1] == ':')
-  { // path has drive letter --> change drive, update volume label
-    f_chdrive(p_para[0] - '0');
-    f_getlabel(NULL, volume_label, NULL);
-  }
-
-  return CLI_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// CAT Command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_cat(char *p_para)
-{
-  if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA;
-
-  FIL file;
-
-  switch( f_open(&file, p_para, FA_READ) )
-  {
-    case FR_OK:
-    {
-      uint32_t bytes_read = 0;
-
-      if ( (FR_OK == f_read(&file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read)) && (bytes_read > 0) )
-      {
-        if ( file.fsize < 0x80000 ) // ~ 500KB
-        {
-          putchar('\n');
-          do {
-            for(uint32_t i=0; i<bytes_read; i++) putchar( fileread_buffer[i] );
-          }while( (FR_OK == f_read(&file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read)) && (bytes_read > 0) );
-        }else
-        { // not display file contents if first character is not printable (high chance of binary file)
-          printf("%s 's contents is too large\n", p_para);
-        }
-      }
-      f_close(&file);
-    }
-    break;
-
-    case FR_INVALID_NAME:
-      return CLI_ERROR_INVALID_PATH;
-
-    default :
-      return CLI_ERROR_FAILED;
-  }
-
-  return CLI_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// Make Directory command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_mkdir(char *p_para)
-{
-  if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA;
-
-  return (f_mkdir(p_para) == FR_OK) ? CLI_ERROR_NONE : CLI_ERROR_FAILED;
-}
-
-//--------------------------------------------------------------------+
-// COPY command
-//--------------------------------------------------------------------+
-cli_error_t cli_cmd_copy(char *p_para)
-{
-  char* p_space = strchr(p_para, ' ');
-  if ( p_space == NULL ) return CLI_ERROR_INVALID_PARA;
-
-  *p_space = 0; // replace space by NULL-character
-  char* p_dest = p_space+1;
-
-  if ( strlen(p_dest) == 0 ) return CLI_ERROR_INVALID_PARA;
-
-  drive_letter2number(p_para);
-  drive_letter2number(p_dest);
-
-  //------------- Check Existence of source & dest file -------------//
-  cli_error_t error = CLI_ERROR_NONE;
-  FIL src_file, dest_file;
-
-  if ( FR_OK != f_open(&src_file , p_para, FA_READ) )  return CLI_ERROR_INVALID_PATH;
-  switch ( f_open(&dest_file, p_dest, FA_WRITE | FA_CREATE_NEW) )
-  {
-    case FR_EXIST:
-      error = CLI_ERROR_FILE_EXISTED;
-    break;\
-
-    case FR_OK:
-      while(1)
-      {
-        uint32_t bytes_read = 0;
-        uint32_t bytes_write = 0;
-        FRESULT res;
-
-        res = f_read(&src_file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read);     /* Read a chunk of src file */
-        if ( (res != FR_OK) || (bytes_read == 0) ) break; /* error or eof */
-
-        res = f_write(&dest_file, fileread_buffer, bytes_read, &bytes_write);               /* Write it to the dst file */
-        if ( (res != FR_OK) || (bytes_write < bytes_read) ) break; /* error or disk full */
-      }
-
-      f_close(&dest_file);
-    break;
-
-    default:
-      error = CLI_ERROR_FAILED;
-    break;
-  }
-
-  f_close(&src_file);
-
-  return error;
-}
-#endif
+/**************************************************************************/
+/*!
+    @file     cli.c
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#include "cli.h"
+#include "ctype.h"
+
+#if TUSB_CFG_HOST_MSC
+
+#include "ff.h"
+#include "diskio.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+#define CLI_MAX_BUFFER        256
+#define CLI_FILE_READ_BUFFER  (4*1024)
+
+enum {
+  ASCII_BACKSPACE = 8,
+};
+
+typedef enum {
+  CLI_ERROR_NONE = 0,
+  CLI_ERROR_INVALID_PARA,
+  CLI_ERROR_INVALID_PATH,
+  CLI_ERROR_FILE_EXISTED,
+  CLI_ERROR_FAILED
+}cli_error_t;
+
+static char const * const cli_error_message[] =
+{
+  [CLI_ERROR_NONE         ] = 0,
+  [CLI_ERROR_INVALID_PARA ] = "Invalid parameter(s)",
+  [CLI_ERROR_INVALID_PATH ] = "No such file or directory",
+  [CLI_ERROR_FILE_EXISTED ] = "file or directory already exists",
+  [CLI_ERROR_FAILED       ] = "failed to execute"
+};
+
+//--------------------------------------------------------------------+
+// CLI Database definition
+//--------------------------------------------------------------------+
+
+// command, function, description
+#define CLI_COMMAND_TABLE(ENTRY)   \
+    ENTRY(unknown , cli_cmd_unknown  , NULL                                                                  ) \
+    ENTRY(help    , cli_cmd_help     , NULL                                                                  ) \
+    ENTRY(cls     , cli_cmd_clear    , "Clear the screen."                                                   ) \
+    ENTRY(ls      , cli_cmd_list     , "List information about the FILEs (the current directory by default).") \
+    ENTRY(cd      , cli_cmd_changedir, "change the current directory."                                       ) \
+    ENTRY(cat     , cli_cmd_cat      , "display contents of a file."                                         ) \
+    ENTRY(cp      , cli_cmd_copy     , "Copies one or more files to another location."                       ) \
+    ENTRY(mkdir   , cli_cmd_mkdir    , "Create a DIRECTORY, if it does not already exist."                   ) \
+
+//--------------------------------------------------------------------+
+// Expands the function to have the standard function signature
+//--------------------------------------------------------------------+
+#define CLI_PROTOTYPE_EXPAND(command, function, description) \
+    cli_error_t function(char *);
+
+CLI_COMMAND_TABLE(CLI_PROTOTYPE_EXPAND);
+
+//--------------------------------------------------------------------+
+// Expand to enum value
+//--------------------------------------------------------------------+
+#define CLI_ENUM_EXPAND(command, function, description)    CLI_CMDTYPE_##command,
+typedef enum {
+  CLI_COMMAND_TABLE(CLI_ENUM_EXPAND)
+  CLI_CMDTYPE_COUNT
+}cli_cmdtype_t;
+
+//--------------------------------------------------------------------+
+// Expand to string table
+//--------------------------------------------------------------------+
+#define CLI_STRING_EXPAND(command, function, description)    #command,
+char const* const cli_string_tbl[] =
+{
+  CLI_COMMAND_TABLE(CLI_STRING_EXPAND)
+  0
+};
+
+//--------------------------------------------------------------------+
+// Expand to Description table
+//--------------------------------------------------------------------+
+#define CLI_DESCRIPTION_EXPAND(command, function, description)    description,
+char const* const cli_description_tbl[] =
+{
+  CLI_COMMAND_TABLE(CLI_DESCRIPTION_EXPAND)
+  0
+};
+
+
+//--------------------------------------------------------------------+
+// Expand to Command Lookup Table
+//--------------------------------------------------------------------+
+#define CMD_LOOKUP_EXPAND(command, function, description)\
+  [CLI_CMDTYPE_##command] = function,\
+
+typedef cli_error_t (* const cli_cmdfunc_t)(char *);
+static cli_cmdfunc_t cli_command_tbl[] =
+{
+  CLI_COMMAND_TABLE(CMD_LOOKUP_EXPAND)
+};
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+static char cli_buffer[CLI_MAX_BUFFER];
+uint8_t fileread_buffer[CLI_FILE_READ_BUFFER] TUSB_CFG_ATTR_USBRAM;
+static char volume_label[20];
+
+static inline void drive_number2letter(char * p_path) ATTR_ALWAYS_INLINE;
+static inline void drive_number2letter(char * p_path)
+{
+  if (p_path[1] == ':')
+  {
+    p_path[0] = 'E' + p_path[0] - '0' ;
+  }
+}
+
+static inline void drive_letter2number(char * p_path) ATTR_ALWAYS_INLINE;
+static inline void drive_letter2number(char * p_path)
+{
+  if (p_path[1] == ':')
+  {
+    p_path[0] = p_path[0] - 'E' + '0';
+  }
+}
+
+
+//--------------------------------------------------------------------+
+// IMPLEMENTATION
+//--------------------------------------------------------------------+
+// NOTES: prompt re-use cli_buffer --> should not be called when cli_buffer has contents
+void cli_command_prompt(void)
+{
+  f_getcwd(cli_buffer, CLI_MAX_BUFFER);
+  drive_number2letter(cli_buffer);
+  printf("\n%s %s\n$ ",
+         (volume_label[0] !=0) ? volume_label : "No Label",
+         cli_buffer);
+
+  memclr_(cli_buffer, CLI_MAX_BUFFER);
+}
+
+void cli_init(void)
+{
+  memclr_(cli_buffer, CLI_MAX_BUFFER);
+  f_getlabel(NULL, volume_label, NULL);
+  cli_command_prompt();
+}
+
+void cli_poll(char ch)
+{
+  if ( isprint(ch) )
+  { // accumulate & echo
+    if (strlen(cli_buffer) < CLI_MAX_BUFFER)
+    {
+      cli_buffer[ strlen(cli_buffer) ] = ch;
+      putchar(ch);
+    }else
+    {
+      puts("cli buffer overflows");
+      memclr_(cli_buffer, CLI_MAX_BUFFER);
+    }
+  }
+  else if ( ch == ASCII_BACKSPACE && strlen(cli_buffer))
+  {
+    printf(ANSI_CURSOR_BACKWARD(1) ANSI_ERASE_LINE(0) ); // move cursor back & clear to the end of line
+    cli_buffer[ strlen(cli_buffer)-1 ] = 0;
+  }
+  else if ( ch == '\r')
+  { // execute command
+    //------------- Separate Command & Parameter -------------//
+    putchar('\n');
+    char* p_space = strchr(cli_buffer, ' ');
+    uint32_t command_len = (p_space == NULL) ? strlen(cli_buffer) : (p_space - cli_buffer);
+    char* p_para = (p_space == NULL) ? (cli_buffer+command_len) : (p_space+1); // point to NULL-character or after space
+
+    //------------- Find entered command in lookup table & execute it -------------//
+    cli_cmdtype_t cmd_id;
+    for(cmd_id = CLI_CMDTYPE_COUNT - 1; cmd_id > CLI_CMDTYPE_unknown; cmd_id--)
+    {
+      if( 0 == strncmp(cli_buffer, cli_string_tbl[cmd_id], command_len) )
+      {
+        break;
+      }
+    }
+
+    cli_error_t error = cli_command_tbl[cmd_id]( p_para ); // command execution, (unknown command if cannot find)
+
+    if (CLI_ERROR_NONE != error)  puts(cli_error_message[error]); // error message output if any
+
+    //------------- print out current path -------------//
+    cli_command_prompt();
+  }
+  else if (ch=='\t') // \t may be used for auto-complete later
+  {
+
+  }
+}
+
+//--------------------------------------------------------------------+
+// UNKNOWN Command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_unknown(char * para)
+{
+  puts("unknown command, please type \"help\" for list of supported commands");
+  return CLI_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
+// HELP command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_help(char * para)
+{
+  puts("current supported commands are:");
+  for(cli_cmdtype_t cmd_id = CLI_CMDTYPE_help+1; cmd_id < CLI_CMDTYPE_COUNT; cmd_id++)
+  {
+    printf("%s\t%s\n", cli_string_tbl[cmd_id], cli_description_tbl[cmd_id]);
+  }
+
+  return CLI_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
+// Clear Screen Command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_clear(char* p_para)
+{
+  printf(ANSI_ERASE_SCREEN(2) ANSI_CURSOR_POSITION(1,1) );
+  return CLI_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
+// LS Command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_list(char * p_para)
+{
+  if ( strlen(p_para) == 0 ) // list current directory
+  {
+    DIR target_dir;
+    if ( FR_OK != f_opendir(&target_dir, ".") ) return CLI_ERROR_FAILED;
+
+    TCHAR long_filename[_MAX_LFN];
+    FILINFO dir_entry =
+    {
+        .lfname = long_filename,
+        .lfsize = _MAX_LFN
+    };
+    while( (f_readdir(&target_dir, &dir_entry) == FR_OK)  && dir_entry.fname[0] != 0)
+    {
+      if ( dir_entry.fname[0] != '.' ) // ignore . and .. entry
+      {
+        TCHAR const * const p_name = (dir_entry.lfname[0] != 0) ? dir_entry.lfname : dir_entry.fname;
+        if ( dir_entry.fattrib & AM_DIR ) // directory
+        {
+          printf("/%s", p_name);
+        }else
+        {
+          printf("%-40s%d KB", p_name, dir_entry.fsize / 1000);
+        }
+        putchar('\n');
+      }
+    }
+
+//    (void) f_closedir(&target_dir);
+  }
+  else
+  {
+    puts("ls only supports list current directory only, try to cd to that folder first");
+    return CLI_ERROR_INVALID_PARA;
+  }
+
+  return CLI_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
+// CD Command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_changedir(char * p_para)
+{
+  if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA;
+
+  drive_letter2number(p_para);
+
+  if ( FR_OK != f_chdir(p_para) )
+  {
+    return CLI_ERROR_INVALID_PATH;
+  }
+
+  if ( p_para[1] == ':')
+  { // path has drive letter --> change drive, update volume label
+    f_chdrive(p_para[0] - '0');
+    f_getlabel(NULL, volume_label, NULL);
+  }
+
+  return CLI_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
+// CAT Command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_cat(char *p_para)
+{
+  if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA;
+
+  FIL file;
+
+  switch( f_open(&file, p_para, FA_READ) )
+  {
+    case FR_OK:
+    {
+      uint32_t bytes_read = 0;
+
+      if ( (FR_OK == f_read(&file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read)) && (bytes_read > 0) )
+      {
+        if ( file.fsize < 0x80000 ) // ~ 500KB
+        {
+          putchar('\n');
+          do {
+            for(uint32_t i=0; i<bytes_read; i++) putchar( fileread_buffer[i] );
+          }while( (FR_OK == f_read(&file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read)) && (bytes_read > 0) );
+        }else
+        { // not display file contents if first character is not printable (high chance of binary file)
+          printf("%s 's contents is too large\n", p_para);
+        }
+      }
+      f_close(&file);
+    }
+    break;
+
+    case FR_INVALID_NAME:
+      return CLI_ERROR_INVALID_PATH;
+
+    default :
+      return CLI_ERROR_FAILED;
+  }
+
+  return CLI_ERROR_NONE;
+}
+
+//--------------------------------------------------------------------+
+// Make Directory command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_mkdir(char *p_para)
+{
+  if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA;
+
+  return (f_mkdir(p_para) == FR_OK) ? CLI_ERROR_NONE : CLI_ERROR_FAILED;
+}
+
+//--------------------------------------------------------------------+
+// COPY command
+//--------------------------------------------------------------------+
+cli_error_t cli_cmd_copy(char *p_para)
+{
+  char* p_space = strchr(p_para, ' ');
+  if ( p_space == NULL ) return CLI_ERROR_INVALID_PARA;
+
+  *p_space = 0; // replace space by NULL-character
+  char* p_dest = p_space+1;
+
+  if ( strlen(p_dest) == 0 ) return CLI_ERROR_INVALID_PARA;
+
+  drive_letter2number(p_para);
+  drive_letter2number(p_dest);
+
+  //------------- Check Existence of source & dest file -------------//
+  cli_error_t error = CLI_ERROR_NONE;
+  FIL src_file, dest_file;
+
+  if ( FR_OK != f_open(&src_file , p_para, FA_READ) )  return CLI_ERROR_INVALID_PATH;
+  switch ( f_open(&dest_file, p_dest, FA_WRITE | FA_CREATE_NEW) )
+  {
+    case FR_EXIST:
+      error = CLI_ERROR_FILE_EXISTED;
+    break;\
+
+    case FR_OK:
+      while(1)
+      {
+        uint32_t bytes_read = 0;
+        uint32_t bytes_write = 0;
+        FRESULT res;
+
+        res = f_read(&src_file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read);     /* Read a chunk of src file */
+        if ( (res != FR_OK) || (bytes_read == 0) ) break; /* error or eof */
+
+        res = f_write(&dest_file, fileread_buffer, bytes_read, &bytes_write);               /* Write it to the dst file */
+        if ( (res != FR_OK) || (bytes_write < bytes_read) ) break; /* error or disk full */
+      }
+
+      f_close(&dest_file);
+    break;
+
+    default:
+      error = CLI_ERROR_FAILED;
+    break;
+  }
+
+  f_close(&src_file);
+
+  return error;
+}
+#endif

+ 263 - 263
demos/host/src/main.c

@@ -1,263 +1,263 @@
-/**************************************************************************/
-/*!
-    @file     main.c
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    This file is part of the tinyusb stack.
-*/
-/**************************************************************************/
-
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "boards/board.h"
-#include "tusb.h"
-
-#if TUSB_CFG_OS != TUSB_OS_NONE
-#include "app_os_prio.h"
-#endif
-
-#include "mouse_app.h"
-#include "keyboard_app.h"
-#include "msc_app.h"
-#include "cdc_serial_app.h"
-#include "rndis_app.h"
-
-#if defined(__CODE_RED) // TODO to be removed
-  #include <cr_section_macros.h>
-  #include <NXP/crp.h>
-  // Variable to store CRP value in. Will be placed automatically
-  // by the linker when "Enable Code Read Protect" selected.
-  // See crp.h header for more information
-  __CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
-#endif
-
-#if 0
-#include "lwip/opt.h"
-#include "lwip/sys.h"
-#include "lwip/memp.h"
-#include "lwip/tcpip.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-#include "lwip/timers.h"
-#include "netif/etharp.h"
-#if LWIP_DHCP
-#include "lwip/dhcp.h"
-#endif
-#include "../contrib/apps/httpserver/httpserver-netconn.h"
-#include "arch/lpc18xx_43xx_emac.h"
-#endif
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-OSAL_TASK_FUNCTION( led_blinking_task ) (void* p_task_para);
-OSAL_TASK_DEF(led_blinking_task, 128, LED_BLINKING_APP_TASK_PRIO);
-
-void print_greeting(void);
-//static inline void wait_blocking_ms(uint32_t ms);
-
-//--------------------------------------------------------------------+
-// IMPLEMENTATION
-//--------------------------------------------------------------------+
-
-#if TUSB_CFG_OS == TUSB_OS_NONE
-// like a real RTOS, this function is a main loop invoking each task in application and never return
-void os_none_start_scheduler(void)
-{
-  while (1)
-  {
-    tusb_task_runner();
-    led_blinking_task(NULL);
-
-    keyboard_app_task(NULL);
-    mouse_app_task(NULL);
-    msc_app_task(NULL);
-    cdc_serial_app_task(NULL);
-    rndis_app_task(NULL);
-
-  }
-}
-#endif
-
-int main(void)
-{
-  board_init();
-  print_greeting();
-
-  tusb_init();
-
-  //------------- application task init -------------//
-  (void) osal_task_create( OSAL_TASK_REF(led_blinking_task) );
-
-  keyboard_app_init();
-  mouse_app_init();
-  msc_app_init();
-  cdc_serial_app_init();
-  rndis_app_init();
-
-  //------------- start OS scheduler (never return) -------------//
-#if TUSB_CFG_OS == TUSB_OS_FREERTOS
-  vTaskStartScheduler();
-#elif TUSB_CFG_OS == TUSB_OS_NONE
-  os_none_start_scheduler();
-#elif TUSB_CFG_OS == TUSB_OS_CMSIS_RTX
-  while(1)
-  {
-    osDelay(osWaitForever); // CMSIS RTX osKernelStart already started, main() is a task
-  }
-#else
-  #error need to start RTOS schduler
-#endif
-
-  while(1) { } // should not be reached here
-
-  return 0;
-}
-
-//--------------------------------------------------------------------+
-// BLINKING TASK
-//--------------------------------------------------------------------+
-OSAL_TASK_FUNCTION( led_blinking_task ) (void* p_task_para)
-{
-  static uint32_t led_on_mask = 0;
-
-  #if 0
-  // FIXME OSAL NONE problem, invoke only 1
-  network_init();
-  http_server_netconn_init();
-  #endif
-  
-  OSAL_TASK_LOOP_BEGIN
-
-  osal_task_delay(1000);
-
-  board_leds(led_on_mask, 1 - led_on_mask);
-  led_on_mask = 1 - led_on_mask; // toggle
-
-  OSAL_TASK_LOOP_END
-}
-
-//--------------------------------------------------------------------+
-// HELPER FUNCTION
-//--------------------------------------------------------------------+
-void print_greeting(void)
-{
-  printf("\n\
---------------------------------------------------------------------\n\
--                     Host Demo (a tinyusb example)\n\
-- if you find any bugs or get any questions, feel free to file an\n\
-- issue at https://github.com/hathach/tinyusb\n\
---------------------------------------------------------------------\n\n"
-  );
-
-  puts("This demo support the following classes");
-  if (TUSB_CFG_HOST_HUB          ) puts("  - Hub");
-  if (TUSB_CFG_HOST_HID_MOUSE    ) puts("  - HID Mouse");
-  if (TUSB_CFG_HOST_HID_KEYBOARD ) puts("  - HID Keyboard");
-  if (TUSB_CFG_HOST_MSC          ) puts("  - Mass Storage");
-  if (TUSB_CFG_HOST_CDC          ) puts("  - Communication Device Class");
-}
-
-//static inline void wait_blocking_us(volatile uint32_t us)
-//{
-//	us *= (SystemCoreClock / 1000000) / 3;
-//	while(us--);
-//}
-//
-//static inline void wait_blocking_ms(uint32_t ms)
-//{
-//	wait_blocking_us(ms * 1000);
-//}
-
-#if 0
-static struct netif lpc_netif;
-
-/* Callback for TCPIP thread to indicate TCPIP init is done */
-static void tcpip_init_done_signal(void *arg)
-{
-	/* Tell main thread TCP/IP init is done */
-	*(uint32_t *) arg = 1;
-}
-
-void network_init(void)
-{
-	ip_addr_t ipaddr, netmask, gw;
-	volatile uint32_t tcpip_init_done = 0;
-
-#if NO_SYS
-	lwip_init();
-#else
-	/* Wait until the TCP/IP thread is finished before
-	   continuing or weird things may happen */
-	LWIP_DEBUGF(LWIP_DBG_ON, ("Waiting for TCPIP thread to initialize...\n"));
-	tcpip_init(tcpip_init_done_signal, (void*)&tcpip_init_done);
-	while (!tcpip_init_done);
-//	tcpip_init(NULL, NULL);
-#endif
-
-	/* Static IP assignment */
-#if LWIP_DHCP
-	IP4_ADDR(&gw, 0, 0, 0, 0);
-	IP4_ADDR(&ipaddr, 0, 0, 0, 0);
-	IP4_ADDR(&netmask, 0, 0, 0, 0);
-#else
-	IP4_ADDR(&gw, 192, 168, 1, 1);
-	IP4_ADDR(&ipaddr, 192, 168, 1, 57);
-	IP4_ADDR(&netmask, 255, 255, 255, 0);
-#endif
-
-	/* Add netif interface for lpc18xx_43xx */
-	if (!netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
-		tcpip_input))
-		LWIP_ASSERT("Net interface failed to initialize\r\n", 0);
-
-	netif_set_default(&lpc_netif);
-	netif_set_up(&lpc_netif);
-
-	/* Enable MAC interrupts only after LWIP is ready */
-	NVIC_SetPriority(ETHERNET_IRQn, ((0x01<<3)|0x01));
-	NVIC_EnableIRQ(ETHERNET_IRQn);
-
-#if LWIP_DHCP
-	dhcp_start(&lpc_netif);
-#endif
-}
-#endif
+/**************************************************************************/
+/*!
+    @file     main.c
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "boards/board.h"
+#include "tusb.h"
+
+#if TUSB_CFG_OS != TUSB_OS_NONE
+#include "app_os_prio.h"
+#endif
+
+#include "mouse_app.h"
+#include "keyboard_app.h"
+#include "msc_app.h"
+#include "cdc_serial_app.h"
+#include "rndis_app.h"
+
+#if defined(__CODE_RED) // TODO to be removed
+  #include <cr_section_macros.h>
+  #include <NXP/crp.h>
+  // Variable to store CRP value in. Will be placed automatically
+  // by the linker when "Enable Code Read Protect" selected.
+  // See crp.h header for more information
+  __CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
+#endif
+
+#if 0
+#include "lwip/opt.h"
+#include "lwip/sys.h"
+#include "lwip/memp.h"
+#include "lwip/tcpip.h"
+#include "lwip/ip_addr.h"
+#include "lwip/netif.h"
+#include "lwip/timers.h"
+#include "netif/etharp.h"
+#if LWIP_DHCP
+#include "lwip/dhcp.h"
+#endif
+#include "../contrib/apps/httpserver/httpserver-netconn.h"
+#include "arch/lpc18xx_43xx_emac.h"
+#endif
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+OSAL_TASK_FUNCTION( led_blinking_task ) (void* p_task_para);
+OSAL_TASK_DEF(led_blinking_task, 128, LED_BLINKING_APP_TASK_PRIO);
+
+void print_greeting(void);
+//static inline void wait_blocking_ms(uint32_t ms);
+
+//--------------------------------------------------------------------+
+// IMPLEMENTATION
+//--------------------------------------------------------------------+
+
+#if TUSB_CFG_OS == TUSB_OS_NONE
+// like a real RTOS, this function is a main loop invoking each task in application and never return
+void os_none_start_scheduler(void)
+{
+  while (1)
+  {
+    tusb_task_runner();
+    led_blinking_task(NULL);
+
+    keyboard_app_task(NULL);
+    mouse_app_task(NULL);
+    msc_app_task(NULL);
+    cdc_serial_app_task(NULL);
+    rndis_app_task(NULL);
+
+  }
+}
+#endif
+
+int main(void)
+{
+  board_init();
+  print_greeting();
+
+  tusb_init();
+
+  //------------- application task init -------------//
+  (void) osal_task_create( OSAL_TASK_REF(led_blinking_task) );
+
+  keyboard_app_init();
+  mouse_app_init();
+  msc_app_init();
+  cdc_serial_app_init();
+  rndis_app_init();
+
+  //------------- start OS scheduler (never return) -------------//
+#if TUSB_CFG_OS == TUSB_OS_FREERTOS
+  vTaskStartScheduler();
+#elif TUSB_CFG_OS == TUSB_OS_NONE
+  os_none_start_scheduler();
+#elif TUSB_CFG_OS == TUSB_OS_CMSIS_RTX
+  while(1)
+  {
+    osDelay(osWaitForever); // CMSIS RTX osKernelStart already started, main() is a task
+  }
+#else
+  #error need to start RTOS schduler
+#endif
+
+  while(1) { } // should not be reached here
+
+  return 0;
+}
+
+//--------------------------------------------------------------------+
+// BLINKING TASK
+//--------------------------------------------------------------------+
+OSAL_TASK_FUNCTION( led_blinking_task ) (void* p_task_para)
+{
+  static uint32_t led_on_mask = 0;
+
+  #if 0
+  // FIXME OSAL NONE problem, invoke only 1
+  network_init();
+  http_server_netconn_init();
+  #endif
+  
+  OSAL_TASK_LOOP_BEGIN
+
+  osal_task_delay(1000);
+
+  board_leds(led_on_mask, 1 - led_on_mask);
+  led_on_mask = 1 - led_on_mask; // toggle
+
+  OSAL_TASK_LOOP_END
+}
+
+//--------------------------------------------------------------------+
+// HELPER FUNCTION
+//--------------------------------------------------------------------+
+void print_greeting(void)
+{
+  printf("\n\
+--------------------------------------------------------------------\n\
+-                     Host Demo (a tinyusb example)\n\
+- if you find any bugs or get any questions, feel free to file an\n\
+- issue at https://github.com/hathach/tinyusb\n\
+--------------------------------------------------------------------\n\n"
+  );
+
+  puts("This demo support the following classes");
+  if (TUSB_CFG_HOST_HUB          ) puts("  - Hub (1 level only)");
+  if (TUSB_CFG_HOST_HID_MOUSE    ) puts("  - HID Mouse");
+  if (TUSB_CFG_HOST_HID_KEYBOARD ) puts("  - HID Keyboard");
+  if (TUSB_CFG_HOST_MSC          ) puts("  - Mass Storage");
+  if (TUSB_CFG_HOST_CDC          ) puts("  - Communication Device Class");
+}
+
+//static inline void wait_blocking_us(volatile uint32_t us)
+//{
+//	us *= (SystemCoreClock / 1000000) / 3;
+//	while(us--);
+//}
+//
+//static inline void wait_blocking_ms(uint32_t ms)
+//{
+//	wait_blocking_us(ms * 1000);
+//}
+
+#if 0
+static struct netif lpc_netif;
+
+/* Callback for TCPIP thread to indicate TCPIP init is done */
+static void tcpip_init_done_signal(void *arg)
+{
+	/* Tell main thread TCP/IP init is done */
+	*(uint32_t *) arg = 1;
+}
+
+void network_init(void)
+{
+	ip_addr_t ipaddr, netmask, gw;
+	volatile uint32_t tcpip_init_done = 0;
+
+#if NO_SYS
+	lwip_init();
+#else
+	/* Wait until the TCP/IP thread is finished before
+	   continuing or weird things may happen */
+	LWIP_DEBUGF(LWIP_DBG_ON, ("Waiting for TCPIP thread to initialize...\n"));
+	tcpip_init(tcpip_init_done_signal, (void*)&tcpip_init_done);
+	while (!tcpip_init_done);
+//	tcpip_init(NULL, NULL);
+#endif
+
+	/* Static IP assignment */
+#if LWIP_DHCP
+	IP4_ADDR(&gw, 0, 0, 0, 0);
+	IP4_ADDR(&ipaddr, 0, 0, 0, 0);
+	IP4_ADDR(&netmask, 0, 0, 0, 0);
+#else
+	IP4_ADDR(&gw, 192, 168, 1, 1);
+	IP4_ADDR(&ipaddr, 192, 168, 1, 57);
+	IP4_ADDR(&netmask, 255, 255, 255, 0);
+#endif
+
+	/* Add netif interface for lpc18xx_43xx */
+	if (!netif_add(&lpc_netif, &ipaddr, &netmask, &gw, NULL, lpc_enetif_init,
+		tcpip_input))
+		LWIP_ASSERT("Net interface failed to initialize\r\n", 0);
+
+	netif_set_default(&lpc_netif);
+	netif_set_up(&lpc_netif);
+
+	/* Enable MAC interrupts only after LWIP is ready */
+	NVIC_SetPriority(ETHERNET_IRQn, ((0x01<<3)|0x01));
+	NVIC_EnableIRQ(ETHERNET_IRQn);
+
+#if LWIP_DHCP
+	dhcp_start(&lpc_netif);
+#endif
+}
+#endif

+ 195 - 175
demos/host/src/mouse_app.c

@@ -1,175 +1,195 @@
-/**************************************************************************/
-/*!
-    @file     mouse_app.c
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    This file is part of the tinyusb stack.
-*/
-/**************************************************************************/
-
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include "mouse_app.h"
-
-#if TUSB_CFG_OS != TUSB_OS_NONE
-#include "app_os_prio.h"
-#endif
-
-
-#if TUSB_CFG_HOST_HID_MOUSE
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-#define QUEUE_MOUSE_REPORT_DEPTH   4
-
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-OSAL_TASK_DEF(mouse_app_task, 128, MOUSE_APP_TASK_PRIO);
-OSAL_QUEUE_DEF(queue_mouse_def, QUEUE_MOUSE_REPORT_DEPTH, tusb_mouse_report_t);
-
-static osal_queue_handle_t queue_mouse_hdl;
-static tusb_mouse_report_t usb_mouse_report TUSB_CFG_ATTR_USBRAM;
-
-static inline void process_mouse_report(tusb_mouse_report_t const * p_report);
-
-//--------------------------------------------------------------------+
-// tinyusb callback (ISR context)
-//--------------------------------------------------------------------+
-void tusbh_hid_mouse_mounted_cb(uint8_t dev_addr)
-{
-  // application set-up
-
-  puts("\na Mouse device is mounted");
-
-  osal_queue_flush(queue_mouse_hdl);
-  (void) tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); // first report
-}
-
-void tusbh_hid_mouse_unmounted_cb(uint8_t dev_addr)
-{
-  // application tear-down
-  puts("\na Mouse device is unmounted\n");
-}
-
-void tusbh_hid_mouse_isr(uint8_t dev_addr, tusb_event_t event)
-{
-  switch(event)
-  {
-    case TUSB_EVENT_XFER_COMPLETE:
-      osal_queue_send(queue_mouse_hdl, &usb_mouse_report);
-      (void) tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report);
-    break;
-
-    case TUSB_EVENT_XFER_ERROR:
-      (void) tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); // ignore & continue
-    break;
-
-    default :
-    break;
-  }
-}
-
-//--------------------------------------------------------------------+
-// APPLICATION
-// NOTICE: MOUSE REPORT IS NOT CORRECT UNTIL A DECENT HID PARSER IS
-// IMPLEMENTED, MEANWHILE IT CAN MISS DISPLAY BUTTONS OR X,Y etc
-//--------------------------------------------------------------------+
-void mouse_app_init(void)
-{
-  memclr_(&usb_mouse_report, sizeof(tusb_mouse_report_t));
-
-  queue_mouse_hdl = osal_queue_create( OSAL_QUEUE_REF(queue_mouse_def) );
-  ASSERT_PTR( queue_mouse_hdl, VOID_RETURN);
-
-  ASSERT( TUSB_ERROR_NONE == osal_task_create( OSAL_TASK_REF(mouse_app_task) ),
-          VOID_RETURN );
-}
-
-//------------- main task -------------//
-OSAL_TASK_FUNCTION( mouse_app_task ) (void* p_task_para)
-{
-  tusb_error_t error;
-  tusb_mouse_report_t mouse_report;
-
-  OSAL_TASK_LOOP_BEGIN
-
-  osal_queue_receive(queue_mouse_hdl, &mouse_report, OSAL_TIMEOUT_WAIT_FOREVER, &error);
-  process_mouse_report(&mouse_report);
-
-  OSAL_TASK_LOOP_END
-}
-
-//--------------------------------------------------------------------+
-// HELPER
-//--------------------------------------------------------------------+
-static inline void process_mouse_report(tusb_mouse_report_t const * p_report)
-{
-  static tusb_mouse_report_t prev_report = { 0 };
-
-  //------------- button state  -------------//
-  uint8_t button_changed_mask = p_report->buttons ^ prev_report.buttons;
-  if ( button_changed_mask & p_report->buttons)
-  {
-     // example only display button pressed, ignore hold & dragging etc
-    printf(" %c%c%c ",
-       p_report->buttons & MOUSE_BUTTON_LEFT   ? 'L' : '-',
-       p_report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-',
-       p_report->buttons & MOUSE_BUTTON_RIGHT  ? 'R' : '-');
-  }
-
-  //------------- movement (disabled for clearer demo) -------------//
-  if ( p_report->wheel != 0 )
-  {
-    printf(" %c ", p_report->wheel > 0 ? 'U' : 'D');
-  }
-
-//  if ( p_report->x != 0 || p_report->y != 0 )
-//  {
-//    printf(" (%d, %d) ", p_report->x, p_report->y);
-//  }
-
-}
-
-#else
-
-// dummy implementation to remove #ifdef in main.c
-void mouse_app_init(void) { }
-OSAL_TASK_FUNCTION( mouse_app_task ) (void* p_task_para)
-{
-  OSAL_TASK_LOOP_BEGIN
-  OSAL_TASK_LOOP_END
-}
-
-#endif
+/**************************************************************************/
+/*!
+    @file     mouse_app.c
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "mouse_app.h"
+
+#if TUSB_CFG_OS != TUSB_OS_NONE
+#include "app_os_prio.h"
+#endif
+
+
+#if TUSB_CFG_HOST_HID_MOUSE
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+#define QUEUE_MOUSE_REPORT_DEPTH   4
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+OSAL_TASK_DEF(mouse_app_task, 128, MOUSE_APP_TASK_PRIO);
+OSAL_QUEUE_DEF(queue_mouse_def, QUEUE_MOUSE_REPORT_DEPTH, tusb_mouse_report_t);
+
+static osal_queue_handle_t queue_mouse_hdl;
+static tusb_mouse_report_t usb_mouse_report TUSB_CFG_ATTR_USBRAM;
+
+static inline void process_mouse_report(tusb_mouse_report_t const * p_report);
+
+//--------------------------------------------------------------------+
+// tinyusb callback (ISR context)
+//--------------------------------------------------------------------+
+void tusbh_hid_mouse_mounted_cb(uint8_t dev_addr)
+{
+  // application set-up
+
+  puts("\na Mouse device is mounted");
+
+  osal_queue_flush(queue_mouse_hdl);
+  (void) tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); // first report
+}
+
+void tusbh_hid_mouse_unmounted_cb(uint8_t dev_addr)
+{
+  // application tear-down
+  puts("\na Mouse device is unmounted\n");
+}
+
+void tusbh_hid_mouse_isr(uint8_t dev_addr, tusb_event_t event)
+{
+  switch(event)
+  {
+    case TUSB_EVENT_XFER_COMPLETE:
+      osal_queue_send(queue_mouse_hdl, &usb_mouse_report);
+      (void) tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report);
+    break;
+
+    case TUSB_EVENT_XFER_ERROR:
+      (void) tusbh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); // ignore & continue
+    break;
+
+    default :
+    break;
+  }
+}
+
+//--------------------------------------------------------------------+
+// APPLICATION
+// NOTICE: MOUSE REPORT IS NOT CORRECT UNTIL A DECENT HID PARSER IS
+// IMPLEMENTED, MEANWHILE IT CAN MISS DISPLAY BUTTONS OR X,Y etc
+//--------------------------------------------------------------------+
+void mouse_app_init(void)
+{
+  memclr_(&usb_mouse_report, sizeof(tusb_mouse_report_t));
+
+  queue_mouse_hdl = osal_queue_create( OSAL_QUEUE_REF(queue_mouse_def) );
+  ASSERT_PTR( queue_mouse_hdl, VOID_RETURN);
+
+  ASSERT( TUSB_ERROR_NONE == osal_task_create( OSAL_TASK_REF(mouse_app_task) ),
+          VOID_RETURN );
+}
+
+//------------- main task -------------//
+OSAL_TASK_FUNCTION( mouse_app_task ) (void* p_task_para)
+{
+  tusb_error_t error;
+  tusb_mouse_report_t mouse_report;
+
+  OSAL_TASK_LOOP_BEGIN
+
+  osal_queue_receive(queue_mouse_hdl, &mouse_report, OSAL_TIMEOUT_WAIT_FOREVER, &error);
+  process_mouse_report(&mouse_report);
+
+  OSAL_TASK_LOOP_END
+}
+
+//--------------------------------------------------------------------+
+// HELPER
+//--------------------------------------------------------------------+
+void cursor_movement(int8_t x, int8_t y, int8_t wheel)
+{
+  //------------- X -------------//
+  if ( x < 0)
+  { // move left
+    printf(ANSI_CURSOR_BACKWARD(%d), (-x));
+  }else if ( x > 0)
+  { // move right
+    printf(ANSI_CURSOR_FORWARD(%d), x);
+  }else { }
+
+  //------------- Y -------------//
+  if ( y < 0)
+  { // move up
+    printf(ANSI_CURSOR_UP(%d), (-y));
+  }else if ( y > 0)
+  { // move down
+    printf(ANSI_CURSOR_DOWN(%d), y);
+  }else { }
+
+  //------------- wheel -------------//
+  if (wheel < 0)
+  { // scroll up
+    printf(ANSI_SCROLL_UP(%d), (-wheel));
+  }else if (wheel > 0)
+  { // scroll down
+    printf(ANSI_SCROLL_DOWN(%d), wheel);
+  }else { }
+}
+
+static inline void process_mouse_report(tusb_mouse_report_t const * p_report)
+{
+  static tusb_mouse_report_t prev_report = { 0 };
+
+  //------------- button state  -------------//
+  uint8_t button_changed_mask = p_report->buttons ^ prev_report.buttons;
+  if ( button_changed_mask & p_report->buttons)
+  {
+    printf(" %c%c%c ",
+       p_report->buttons & MOUSE_BUTTON_LEFT   ? 'L' : '-',
+       p_report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-',
+       p_report->buttons & MOUSE_BUTTON_RIGHT  ? 'R' : '-');
+  }
+
+  //------------- cursor movement -------------//
+  cursor_movement(p_report->x, p_report->y, p_report->wheel);
+}
+
+#else
+
+// dummy implementation to remove #ifdef in main.c
+void mouse_app_init(void) { }
+OSAL_TASK_FUNCTION( mouse_app_task ) (void* p_task_para)
+{
+  OSAL_TASK_LOOP_BEGIN
+  OSAL_TASK_LOOP_END
+}
+
+#endif