Fixes #2598: added USB serial port (with echo example), use USB=SERIAL to enable. If DEBUG=YES then debug output also goes to the USB serial port

This commit is contained in:
Damjan Adamic
2015-08-09 15:41:24 +02:00
parent 5d8c86923b
commit f7a8715657
15 changed files with 328 additions and 43 deletions
+11 -3
View File
@@ -301,9 +301,10 @@ LUA = NO
MENUS_LOCK = NO
# USB options in the main image
# Values = JOYSTICK, MASSSTORAGE
# Values = JOYSTICK, MASSSTORAGE, SERIAL
# JOYSTICK: The TX will appear as a joystick
# MASSSTORAGE: The TX will appear as a drive
# SERIAL: The TX will appear as a serial port
USB = JOYSTICK
# Mixers monitor view added to Channels monitor one
@@ -913,8 +914,11 @@ ifeq ($(PCB), TARANIS)
LDSCRIPT = targets/taranis/stm32f2_flash.ld
endif
STM32USBPATH = $(THIRDPARTY)/STM32_USB-Host-Device_Lib_V2.1.0/Libraries
INCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc $(STM32USBPATH)/STM32_USB_Device_Library/Core/inc
INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/inc $(STM32USBPATH)/STM32_USB_Device_Library/Class/hid/inc
INCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc
INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Core/inc
INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/inc
INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/hid/inc
INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/cdc/inc
GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_hardware.cpp
BOARDSRC = main_arm.cpp targets/taranis/board_taranis.cpp
EXTRABOARDSRC += targets/taranis/configure_pins.cpp targets/taranis/lcd_driver.cpp targets/taranis/flash_driver.cpp targets/taranis/i2c_driver.cpp targets/taranis/aspi.c targets/taranis/delays.c
@@ -966,6 +970,10 @@ ifeq ($(PCB), TARANIS)
ifeq ($(USB), JOYSTICK)
CPPDEFS += -DUSB_JOYSTICK
SRC += targets/taranis/usbd_hid_joystick.c
else ifeq ($(USB), SERIAL)
CPPDEFS += -DUSB_SERIAL
SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
EXTRABOARDSRC += targets/taranis/usbd_cdc.cpp
else
CPPDEFS += -DUSB_MASS_STORAGE
SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c
+16 -1
View File
@@ -98,9 +98,15 @@ void menuStatisticsView(uint8_t event)
#define MENU_DEBUG_Y_MIXMAX (2*FH-3)
#define MENU_DEBUG_Y_LUA (3*FH-2)
#define MENU_DEBUG_Y_FREE_RAM (4*FH-1)
#define MENU_DEBUG_Y_STACK (5*FH)
#define MENU_DEBUG_Y_USB (5*FH)
#define MENU_DEBUG_Y_RTOS (6*FH)
#if defined(USB_SERIAL)
extern uint16_t usbWraps;
extern uint16_t charsWritten;
extern "C" uint32_t APP_Rx_ptr_in;
#endif
void menuStatisticsDebug(uint8_t event)
{
TITLE(STR_MENUDEBUG);
@@ -154,6 +160,15 @@ void menuStatisticsDebug(uint8_t event)
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
#if defined(USB_SERIAL)
lcd_putsLeft(MENU_DEBUG_Y_USB, "Usb");
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_USB, charsWritten, LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_USB, " ");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_USB, APP_Rx_ptr_in, LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_USB, " ");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_USB, usbWraps, LEFT);
#endif
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS+1, "[M]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);
+45 -13
View File
@@ -40,33 +40,62 @@ uint8_t currentSpeakerVolume = 255;
uint8_t requiredSpeakerVolume = 255;
uint8_t requestScreenshot = false;
#if defined(USB_SERIAL)
Fifo<64> cliRxFifo;
void handleCli()
{
uint8_t c;
while(cliRxFifo.pop(c)) {
//send back
sendUsbSerialChar(c);
sendUsbSerialChar('+');
}
}
#endif
void handleUsbConnection()
{
#if defined(PCBTARANIS) && !defined(SIMU)
static bool usbStarted = false;
if (!usbStarted && usbPlugged()) {
usbStarted = true;
/*
We used to initialize USB peripheral and driver here.
According to my tests this is way too late. The USB peripheral
therefore does not have enough information to start responding to
USB host request, which causes very slow USB device recognition,
multiple USB device resets, etc...
If we want to change the USB profile, the procedure is simple:
* USB cable must be disconnected
* call usbDeInit();
* call usbUnit(); which initializes USB with the new profile.
Obviously the usbInit() should be modified to have a runtime
selection of the USB profile.
*/
#if defined(USB_MASS_STORAGE)
opentxClose();
#endif
usbStart();
#if defined(USB_MASS_STORAGE)
usbPluggedIn();
#endif
usbStarted = true;
}
if (usbStarted && !usbPlugged()) {
usbStarted = false;
}
#if defined(USB_JOYSTICK)
if (usbStarted) {
if (!usbPlugged()) {
//disable USB
usbStop();
usbStarted = false;
}
else {
usbJoystickUpdate();
}
if (usbStarted ) {
usbJoystickUpdate();
}
#endif
#endif //#if defined(PCBTARANIS) && !defined(SIMU)
}
@@ -100,6 +129,9 @@ void perMain()
handleUsbConnection();
checkTrainerSettings();
checkBattery();
#if defined(USB_SERIAL)
handleCli();
#endif
uint8_t evt = getEvent(false);
if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on
+6
View File
@@ -1759,4 +1759,10 @@ extern Clipboard clipboard;
extern uint16_t s_anaFilt[NUMBER_ANALOG];
#endif
#if defined(USB_SERIAL)
extern Fifo<64> cliRxFifo;
void sendUsbSerialChar(uint8_t c);
#endif
#endif
-1
View File
@@ -1201,7 +1201,6 @@ uint32_t pwrPressed() { return false; }
#else
uint32_t pwrCheck() { return true; }
#endif
void usbStart() { }
int usbPlugged() { return false; }
void USART_DeInit(USART_TypeDef* ) { }
ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) { return SUCCESS; }
+5 -7
View File
@@ -74,9 +74,10 @@ extern "C" {
#endif
#if !defined(SIMU)
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h"
#include "usbd_cdc_core.h"
#include "usbd_msc_core.h"
#include "usbd_hid_core.h"
#include "usbd_usr.h"
#include "usbd_desc.h"
#include "usb_conf.h"
#include "usbd_conf.h"
@@ -281,10 +282,7 @@ void backlightInit(void);
// USB driver
int usbPlugged(void);
void usbInit(void);
void usbStart(void);
#if defined(USB_JOYSTICK)
void usbStop(void);
#endif
void usbDeInit(void);
#if defined(__cplusplus) && !defined(SIMU)
}
@@ -109,6 +109,8 @@ ifeq ($(PCB), TARANIS)
EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc
EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Core/inc
EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/inc
EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/hid/inc
EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/cdc/inc
EXTRAINCDIRS += .. ../../.. ../../../fonts/std
ifeq ($(PCBREV), REV4a)
CPPDEFS += -DREV4a
@@ -418,7 +418,6 @@ int main()
// SD card detect pin
sdInit();
usbInit();
usbStart();
#endif
for (;;) {
@@ -109,6 +109,10 @@ void debugPutc(const char c)
{
if (uart3Mode == UART_MODE_DEBUG) {
uart3Putc(c);
#if defined(USB_SERIAL)
// also send debug output into USB serial port (if active)
sendUsbSerialChar(c);
#endif
}
}
#endif
+1 -1
View File
@@ -47,7 +47,7 @@
* when FS core is used.
*******************************************************************************/
#ifndef USE_USB_OTG_FS
#define USE_USB_OTG_FS
#define USE_USB_OTG_FS // USB2.0 Full Speed == 12 Mbit
#endif /* USE_USB_OTG_FS */
#ifdef USE_USB_OTG_FS
+5 -11
View File
@@ -35,8 +35,6 @@
*/
#include "board_taranis.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h"
int usbPlugged(void)
{
@@ -63,28 +61,24 @@ USB_OTG_CORE_HANDLE USB_OTG_dev;
void OTG_FS_IRQHandler(void)
{
USBD_OTG_ISR_Handler (&USB_OTG_dev);
USBD_OTG_ISR_Handler(&USB_OTG_dev);
}
void usbInit(void)
{
USB_OTG_BSP_Init(&USB_OTG_dev);
}
void usbStart(void)
{
#if defined(USB_JOYSTICK)
// initialize USB as HID device
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_HID_cb, &USR_cb);
#elif defined(USB_SERIAL)
// initialize USB as CDC device (virtual serial port)
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);
#elif defined(USB_MASS_STORAGE)
// initialize USB as MSC device
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_MSC_cb, &USR_cb);
#endif
}
#if defined(USB_JOYSTICK)
void usbStop(void)
void usbDeInit(void)
{
USBD_DeInit(&USB_OTG_dev);
}
#endif
+212
View File
@@ -0,0 +1,212 @@
/**
******************************************************************************
* @file usbd_cdc_vcp.c
* @author MCD Application Team
* @version V1.1.0
* @date 19-March-2012
* @brief Generic media access Layer.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#pragma data_alignment = 4
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
#include "opentx.h"
extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc.h"
#include "usb_conf.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* These are external variables imported from CDC core to be used for IN
transfer management. */
extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer.
These data will be sent over USB IN endpoint
in the CDC core functions. */
extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
start address when writing received data
in the buffer APP_Rx_Buffer. */
/* Private function prototypes -----------------------------------------------*/
static uint16_t VCP_Init (void);
static uint16_t VCP_DeInit (void);
static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len);
// static uint16_t VCP_COMConfig(uint8_t Conf);
CDC_IF_Prop_TypeDef VCP_fops =
{
VCP_Init,
VCP_DeInit,
VCP_Ctrl,
0,
VCP_DataRx
};
} // extern "C"
bool cdcConnected = false;
/* Private functions ---------------------------------------------------------*/
/**
* @brief VCP_Init
* Initializes the Media on the STM32
* @param None
* @retval Result of the opeartion (USBD_OK in all cases)
*/
static uint16_t VCP_Init(void)
{
cdcConnected = true;
return USBD_OK;
}
/**
* @brief VCP_DeInit
* DeInitializes the Media on the STM32
* @param None
* @retval Result of the opeartion (USBD_OK in all cases)
*/
static uint16_t VCP_DeInit(void)
{
cdcConnected = false;
return USBD_OK;
}
/**
* @brief VCP_Ctrl
* Manage the CDC class requests
* @param Cmd: Command code
* @param Buf: Buffer containing command data (request parameters)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion (USBD_OK in all cases)
*/
static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
{
switch (Cmd)
{
case SEND_ENCAPSULATED_COMMAND:
/* Not needed for this driver */
break;
case GET_ENCAPSULATED_RESPONSE:
/* Not needed for this driver */
break;
case SET_COMM_FEATURE:
/* Not needed for this driver */
break;
case GET_COMM_FEATURE:
/* Not needed for this driver */
break;
case CLEAR_COMM_FEATURE:
/* Not needed for this driver */
break;
case SET_LINE_CODING:
/* Not needed for this driver */
break;
case GET_LINE_CODING:
/* Not needed for this driver */
break;
case SET_CONTROL_LINE_STATE:
/* Not needed for this driver */
break;
case SEND_BREAK:
/* Not needed for this driver */
break;
default:
break;
}
return USBD_OK;
}
// some debug vars
uint16_t usbWraps = 0;
uint16_t charsWritten = 0;
void sendUsbSerialChar(uint8_t c)
{
if (!cdcConnected) return;
APP_Rx_Buffer[APP_Rx_ptr_in] = c;
++charsWritten;
/* To avoid buffer overflow */
if(APP_Rx_ptr_in >= APP_RX_DATA_SIZE-1)
{
APP_Rx_ptr_in = 0;
++usbWraps;
}
else {
APP_Rx_ptr_in++;
}
}
/**
* @brief VCP_DataRx
* Data received over USB OUT endpoint is available here
*
* @note
* This function will block any OUT packet reception on USB endpoint
* until exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* @note
* This function is executed inside the USBD_OTG_ISR_Handler() interrupt handler!
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
*/
static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
{
// TODO: try implementing inbound flow control:
// if the cliRxFifo does not have enough free space to receive all
// available characters, return VCP_FAIL. Maybe that will throttle down
// the sender and we will receive the same packet at a later time.
//copy data to the application FIFO
for (uint32_t i = 0; i < Len; i++)
{
cliRxFifo.push(Buf[i]);
}
return USBD_OK;
}
// /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+13 -2
View File
@@ -36,13 +36,13 @@
#define USBD_ITF_MAX_NUM 1
#define USB_MAX_STR_DESC_SIZ 64
#define USBD_SELF_POWERED
#define USBD_SELF_POWERED
/* Class Layer Parameter */
#define MSC_IN_EP 0x81
#define MSC_OUT_EP 0x01
#define MSC_MAX_PACKET 64
#define MSC_MAX_PACKET 64
#define MSC_MEDIA_PACKET 4096
@@ -52,6 +52,17 @@
#define HID_IN_PACKET 9
#define HID_OUT_PACKET 9
#define CDC_IN_EP 0x81 /* EP1 for data IN */
#define CDC_OUT_EP 0x01 /* EP1 for data OUT */
#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */
#define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */
#define APP_RX_DATA_SIZE 2048 // USB serial port output buffer. TODO: tune this buffer size /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */
#define APP_FOPS VCP_fops
#endif //__USBD_CONF__H__
+5
View File
@@ -73,6 +73,11 @@
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Joystick"
#define USBD_CONFIGURATION_FS_STRING "HID Config"
#define USBD_INTERFACE_FS_STRING "HID Interface"
#elif defined(USB_SERIAL)
#define USBD_PID 0x5740 // do not change, this ID is used by the ST USB driver for Windows
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Serial Port"
#define USBD_CONFIGURATION_FS_STRING "VSP Config"
#define USBD_INTERFACE_FS_STRING "VSP Interface"
#elif defined(USB_MASS_STORAGE)
#define USBD_PID 0x5720
#define USBD_PRODUCT_FS_STRING "FrSky Taranis Mass Storage"
@@ -122,7 +122,7 @@ static uint8_t usbd_cdc_SOF (void *pdev);
CDC specific management functions
*********************************************/
static void Handle_USBAsynchXfer (void *pdev);
static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
static const uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
#ifdef USE_USB_OTG_HS
static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
#endif
@@ -134,7 +134,7 @@ static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
* @{
*/
extern CDC_IF_Prop_TypeDef APP_FOPS;
extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
extern const uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
@@ -782,7 +782,7 @@ static void Handle_USBAsynchXfer (void *pdev)
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
static const uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
{
*length = sizeof (usbd_cdc_CfgDesc);
return usbd_cdc_CfgDesc;