refine mouse demo

This commit is contained in:
hathach 2013-10-16 12:05:48 +07:00
parent de7e21dc66
commit 86b3e3174d
5 changed files with 1141 additions and 1118 deletions

View File

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

View File

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

View File

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

View File

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

View File

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