mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
refine mouse demo
This commit is contained in:
parent
de7e21dc66
commit
86b3e3174d
@ -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_ */
|
||||
|
||||
/** @} */
|
||||
|
@ -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_ */
|
||||
|
||||
/** @} */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user