Projectkk2glider/issue 4086 usb and serial (#4097)

* Serial2 changes:
  * stm32 driver moved to common dir.
  * earlier start of driver (Taranis)
  * wait for free buffer time limited
USB changes:
 * Upgrade to ST USB-Host-Device_Lib_V2.2.0 (from V2.1.0) - this fixed a problem with USB serial #4086)
 * other fixes for #4086

* USB-Host-Device_Lib: renamed directory to V2.2.0 (from V2.1.0)
This commit is contained in:
Damjan Adamic
2016-12-06 20:32:30 +01:00
committed by Bertrand Songis
parent 9a6e64e67b
commit 5a5cf7cf33
77 changed files with 2772 additions and 749 deletions
@@ -107,7 +107,6 @@ set(TARGET_SRC
trainer_driver.cpp
audio_driver.cpp
telemetry_driver.cpp
${SERIAL2_DRIVER}
)
set(FIRMWARE_SRC
${FIRMWARE_SRC}
@@ -1,7 +1,7 @@
set(LUA "NO" CACHE STRING "Lua scripts (YES/NO/NO_MODEL_SCRIPTS)")
set(USB "JOYSTICK" CACHE STRING "USB option (JOYSTICK/MASSSTORAGE/SERIAL)")
set(ARCH ARM)
set(STM32USB_DIR ${THIRDPARTY_DIR}/STM32_USB-Host-Device_Lib_V2.1.0/Libraries)
set(STM32USB_DIR ${THIRDPARTY_DIR}/STM32_USB-Host-Device_Lib_V2.2.0/Libraries)
add_definitions(-DSTM32 -DLUA_INPUTS -DVARIO -DSBUS -DCROSSFIRE)
include_directories(${RADIO_SRC_DIRECTORY}/targets/common/arm/stm32)
include_directories(${STM32USB_DIR}/STM32_USB_OTG_Driver/inc)
@@ -9,6 +9,8 @@ include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Core/inc)
include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/msc/inc)
include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/hid/inc)
include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/cdc/inc)
include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Core/inc/)
include_directories(${STM32USB_DIR}/STM32_USB_OTG_Driver/inc)
set(STM32USB_SRC
STM32_USB_OTG_Driver/src/usb_core.c
STM32_USB_OTG_Driver/src/usb_dcd.c
@@ -21,6 +23,7 @@ set(TARGET_SRC
${TARGET_SRC}
../common/arm/stm32/rtc_driver.cpp
../common/arm/stm32/cpu_id.cpp
${SERIAL2_DRIVER}
)
set(FIRMWARE_TARGET_SRC
${FIRMWARE_TARGET_SRC}
@@ -106,9 +106,15 @@ void serial2Init(unsigned int mode, unsigned int protocol)
void serial2Putc(char c)
{
while (serial2TxFifo.isFull());
#if !defined(SIMU)
int n = 0;
while (serial2TxFifo.isFull()) {
delay_ms(1);
if (++n > 100) return;
}
serial2TxFifo.push(c);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, ENABLE);
#endif
}
void serial2SbusInit()
@@ -19,7 +19,7 @@
*/
#include "board.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h"
#include "usb_dcd_int.h"
#include "debug.h"
int usbPlugged(void)
+46 -28
View File
@@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@@ -18,8 +18,8 @@
* GNU General Public License for more details.
*/
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#pragma data_alignment = 4
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#pragma data_alignment = 4
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
#include "opentx.h"
@@ -35,7 +35,7 @@ extern "C" {
/* Private variables ---------------------------------------------------------*/
/* These are external variables imported from CDC core to be used for IN
/* 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
@@ -53,7 +53,7 @@ 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 =
CDC_IF_Prop_TypeDef VCP_fops =
{
VCP_Init,
VCP_DeInit,
@@ -95,13 +95,13 @@ static uint16_t VCP_DeInit(void)
/**
* @brief VCP_Ctrl
* Manage the CDC class requests
* @param Cmd: Command code
* @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:
@@ -138,8 +138,8 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
case SEND_BREAK:
/* Not needed for this driver */
break;
break;
default:
break;
}
@@ -153,39 +153,57 @@ uint16_t charsWritten = 0;
void usbSerialPutc(uint8_t c)
{
/*
Apparently there is no reliable way to tell if the
virtual serial port is opened or not.
The cdcConnected variable only reports the state
of the physical USB connection.
*/
if (!cdcConnected) return;
uint32_t txDataLen;
do {
txDataLen = APP_RX_DATA_SIZE + APP_Rx_ptr_in - APP_Rx_ptr_out;
if (txDataLen >= APP_RX_DATA_SIZE) {
txDataLen -= APP_RX_DATA_SIZE;
}
// TODO timeout exit
} while (txDataLen >= (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE));
uint32_t prim = __get_PRIMASK();
__disable_irq();
uint32_t txDataLen = APP_RX_DATA_SIZE + APP_Rx_ptr_in - APP_Rx_ptr_out;
if (!prim) __enable_irq();
if (txDataLen >= APP_RX_DATA_SIZE) {
txDataLen -= APP_RX_DATA_SIZE;
}
if (txDataLen > (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE)) return; // buffer is too full, skip this write
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_Buffer and associated variables must be modified
atomically, because they are used from the interrupt
*/
/* Read PRIMASK register, check interrupt status before you disable them */
/* Returns 0 if they are enabled, or non-zero if disabled */
prim = __get_PRIMASK();
__disable_irq();
APP_Rx_Buffer[APP_Rx_ptr_in++] = c;
if(APP_Rx_ptr_in >= APP_RX_DATA_SIZE)
{
APP_Rx_ptr_in = 0;
++usbWraps;
}
else {
APP_Rx_ptr_in++;
}
if (!prim) __enable_irq();
}
/**
* @brief VCP_DataRx
* Data received over USB OUT endpoint is available here
*
*
* @note
* This function will block any OUT packet reception on USB endpoint
* 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
* 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!
@@ -205,7 +223,7 @@ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
for (uint32_t i = 0; i < Len; i++)
{
cliRxFifo.push(Buf[i]);
}
}
#endif
return USBD_OK;
@@ -138,6 +138,8 @@ __ALIGN_BEGIN const uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END
HIBYTE(USBD_LANGID_STRING),
};
__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ; // modified by OpenTX
/*
* @brief USBD_USR_DeviceDescriptor
* return the device descriptor
+1 -1
View File
@@ -66,7 +66,7 @@ if(INTERNAL_GPS)
add_definitions(-DINTERNAL_GPS)
message("Internal GPS enabled")
endif()
set(SERIAL2_DRIVER serial2_driver.cpp)
set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp)
set(GVAR_SCREEN model_gvars.cpp)
set(TARGET_SRC
${TARGET_SRC}
+4 -2
View File
@@ -23,8 +23,8 @@
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#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"
#include "usb_dcd_int.h"
#include "usb_bsp.h"
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
@@ -158,7 +158,9 @@ void boardInit()
// FrSky removed the volume chip in latest board, that's why it doesn't answer!
// i2cInit();
#if defined(DEBUG)
serial2Init(0, 0); // default serial mode (None if DEBUG not defined)
#endif
__enable_irq();
+1 -2
View File
@@ -96,6 +96,7 @@ set(TARGET_SRC
haptic_driver.cpp
sdcard_driver.cpp
massstorage.cpp
serial2_driver.cpp
)
set(FIRMWARE_SRC
@@ -107,5 +108,3 @@ set(SRC
${SRC}
debug.cpp
)
set(SERIAL2_DRIVER serial2_driver.cpp)
+3 -3
View File
@@ -17,7 +17,7 @@ if(PCB STREQUAL X9E)
bluetooth_driver.cpp
startup_stm32f40_41xxx.s
)
set(SERIAL2_DRIVER serial2_driver.cpp)
set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp)
if(STICKS STREQUAL HORUS)
add_definitions(-DHORUS_STICKS)
endif()
@@ -38,7 +38,7 @@ elseif(PCB STREQUAL X9D+)
set(GUI_SRC ${GUI_SRC} bmp.cpp)
set(BITMAPS_TARGET taranis_bitmaps)
set(LCD_DRIVER lcd_driver_spi.cpp)
set(SERIAL2_DRIVER serial2_driver.cpp)
set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp)
set(GVAR_SCREEN model_gvars.cpp)
elseif(PCB STREQUAL X9D)
set(CPU_TYPE STM32F2)
@@ -52,7 +52,7 @@ elseif(PCB STREQUAL X9D)
set(GUI_SRC ${GUI_SRC} bmp.cpp)
set(BITMAPS_TARGET taranis_bitmaps)
set(LCD_DRIVER lcd_driver_aspi.cpp)
set(SERIAL2_DRIVER serial2_driver.cpp)
set(SERIAL2_DRIVER ../common/arm/stm32/serial2_driver.cpp)
set(GVAR_SCREEN model_gvars.cpp)
elseif(PCB STREQUAL X7D)
set(CPU_TYPE STM32F2)
+7 -2
View File
@@ -23,8 +23,8 @@
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
#endif
#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"
#include "usb_dcd_int.h"
#include "usb_bsp.h"
#if defined(__cplusplus) && !defined(SIMU)
}
#endif
@@ -139,6 +139,11 @@ void boardInit()
i2cInit();
usbInit();
#if defined(DEBUG)
serial2Init(0, 0); // default serial mode (None if DEBUG not defined)
TRACE("\nTaranis board started :)");
#endif
#if defined(HAPTIC)
hapticInit();
#endif
@@ -1,165 +0,0 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "opentx.h"
uint8_t serial2Mode = 0;
Fifo<uint8_t, 512> serial2TxFifo;
DMAFifo<32> serial2RxFifo __DMA (SERIAL_DMA_Stream_RX);
void uart3Setup(unsigned int baudrate, bool dma)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig(SERIAL_GPIO, SERIAL_GPIO_PinSource_RX, SERIAL_GPIO_AF);
GPIO_PinAFConfig(SERIAL_GPIO, SERIAL_GPIO_PinSource_TX, SERIAL_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = SERIAL_GPIO_PIN_TX | SERIAL_GPIO_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(SERIAL_GPIO, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(SERIAL_USART, &USART_InitStructure);
if (dma) {
DMA_InitTypeDef DMA_InitStructure;
serial2RxFifo.clear();
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, DISABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
DMA_InitStructure.DMA_Channel = SERIAL_DMA_Channel_RX;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&SERIAL_USART->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(serial2RxFifo.buffer());
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = serial2RxFifo.size();
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(SERIAL_DMA_Stream_RX, &DMA_InitStructure);
USART_DMACmd(SERIAL_USART, USART_DMAReq_Rx, ENABLE);
USART_Cmd(SERIAL_USART, ENABLE);
DMA_Cmd(SERIAL_DMA_Stream_RX, ENABLE);
}
else {
USART_Cmd(SERIAL_USART, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
NVIC_SetPriority(SERIAL_USART_IRQn, 7);
NVIC_EnableIRQ(SERIAL_USART_IRQn);
}
}
void serial2Init(unsigned int mode, unsigned int protocol)
{
serial2Stop();
serial2Mode = mode;
switch (mode) {
case UART_MODE_TELEMETRY_MIRROR:
uart3Setup(FRSKY_SPORT_BAUDRATE, false);
break;
#if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI))
case UART_MODE_DEBUG:
uart3Setup(DEBUG_BAUDRATE, false);
break;
#endif
case UART_MODE_TELEMETRY:
if (protocol == PROTOCOL_FRSKY_D_SECONDARY) {
uart3Setup(FRSKY_D_BAUDRATE, true);
}
break;
}
}
void serial2Putc(char c)
{
while (serial2TxFifo.isFull());
serial2TxFifo.push(c);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, ENABLE);
}
void serial2SbusInit()
{
uart3Setup(SBUS_BAUDRATE, true);
SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ;
}
void serial2Stop()
{
DMA_DeInit(SERIAL_DMA_Stream_RX);
USART_DeInit(SERIAL_USART);
}
uint8_t serial2TracesEnabled()
{
#if defined(DEBUG)
return (serial2Mode == UART_MODE_DEBUG);
#else
return false;
#endif
}
extern "C" void SERIAL_USART_IRQHandler(void)
{
DEBUG_INTERRUPT(INT_SER2);
// Send
if (USART_GetITStatus(SERIAL_USART, USART_IT_TXE) != RESET) {
uint8_t txchar;
if (serial2TxFifo.pop(txchar)) {
/* Write one byte to the transmit data register */
USART_SendData(SERIAL_USART, txchar);
}
else {
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
}
}
#if !defined(USB_SERIAL) && defined(CLI)
// Receive
uint32_t status = SERIAL_USART->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
uint8_t data = SERIAL_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
switch (serial2Mode) {
case UART_MODE_DEBUG:
cliRxFifo.push(data);
break;
}
}
status = SERIAL_USART->SR;
}
#endif
}