1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

revo usb: Add support for USB to Revo

This commit is contained in:
Stacey Sheldon 2012-02-07 02:12:55 -05:00
parent 8b73ae7d16
commit e2939dae2a
36 changed files with 2791 additions and 60 deletions

View File

@ -80,6 +80,7 @@ OPUAVSYNTHDIR = $(OUTDIR)/../uavobject-synthetics/flight
## BOOTLOADER:
SRC += main.c
SRC += pios_board.c
SRC += pios_usb_board_data.c
SRC += bl_fsm.c
## PIOS Hardware (STM32F4xx)
@ -91,7 +92,9 @@ SRC += $(FLIGHTLIB)/fifo_buffer.c
# PIOS Hardware (Common)
#SRC += $(PIOSCOMMON)/pios_com.c
SRC += $(PIOSCOMMON)/pios_board_info.c
SRC += $(PIOSCOMMON)/pios_com_msg.c
SRC += $(PIOSCOMMON)/printf-stdarg.c
SRC += $(PIOSCOMMON)/pios_usb_desc_hid_only.c
# List C source files here which must be compiled in ARM-Mode (no -mthumb).
# use file-extension c for "c-only"-files
@ -224,7 +227,7 @@ CFLAGS += -fpromote-loop-indices
endif
CFLAGS += -Wall
CFLAGS += -Werror
#CFLAGS += -Werror
CFLAGS += -Wa,-adhlns=$(addprefix $(OUTDIR)/, $(notdir $(addsuffix .lst, $(basename $<))))
# Compiler flags to generate dependency files:
CFLAGS += -MD -MP -MF $(OUTDIR)/dep/$(@F).d

View File

@ -34,6 +34,9 @@
#define PIOS_INCLUDE_SPI
#define PIOS_INCLUDE_SYS
#define PIOS_INCLUDE_IAP
#define PIOS_INCLUDE_USB
#define PIOS_INCLUDE_USB_HID
#define PIOS_INCLUDE_COM_MSG
//#define PIOS_INCLUDE_BL_HELPER
//#define PIOS_INCLUDE_BL_HELPER_WRITE_SUPPORT

View File

@ -0,0 +1,51 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB_BOARD Board specific USB definitions
* @brief Board specific USB definitions
* @{
*
* @file pios_usb_board_data.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Board specific USB definitions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_USB_BOARD_DATA_H
#define PIOS_USB_BOARD_DATA_H
#define PIOS_USB_BOARD_HID_DATA_LENGTH 64
#define PIOS_USB_BOARD_EP_NUM 2
#include "pios_usb_defs.h" /* struct usb_* */
#define PIOS_USB_BOARD_PRODUCT_ID USB_PRODUCT_ID_REVOLUTION
#define PIOS_USB_BOARD_DEVICE_VER USB_OP_DEVICE_VER(USB_OP_BOARD_ID_REVOLUTION, USB_OP_BOARD_MODE_BL)
/*
* The bootloader uses a simplified report structure
* BL: <REPORT_ID><DATA>...<DATA>
* FW: <REPORT_ID><LENGTH><DATA>...<DATA>
* This define changes the behaviour in pios_usb_hid.c
*/
#define PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
#endif /* PIOS_USB_BOARD_DATA_H */

View File

@ -23,11 +23,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pios.h>
#include "bl_fsm.h" /* lfsm_* */
#include "board_hw_defs.c"
#include <pios_board_info.h>
#include <pios.h>
uint32_t pios_com_telem_usb_id;
static bool board_init_complete = false;
void PIOS_Board_Init() {
if (board_init_complete) {
@ -39,5 +41,30 @@ void PIOS_Board_Init() {
PIOS_LED_Init(&pios_led_cfg);
#if 0 && defined(PIOS_INCLUDE_USB)
/* Initialize board specific USB data */
PIOS_USB_BOARD_DATA_Init();
/* Activate the HID-only USB configuration */
PIOS_USB_DESC_HID_ONLY_Init();
uint32_t pios_usb_id;
PIOS_USB_Init(&pios_usb_id, &pios_usb_main_cfg);
#if defined(PIOS_INCLUDE_USB_HID) && defined(PIOS_INCLUDE_COM_MSG)
uint32_t pios_usb_hid_id;
if (PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_cfg, pios_usb_id)) {
PIOS_Assert(0);
}
if (PIOS_COM_MSG_Init(&pios_com_telem_usb_id, &pios_usb_hid_com_driver, pios_usb_hid_id)) {
PIOS_Assert(0);
}
#endif /* PIOS_INCLUDE_USB_HID && PIOS_INCLUDE_COM_MSG */
PIOS_USBHOOK_Activate();
#endif /* PIOS_INCLUDE_USB */
board_init_complete = true;
}

View File

@ -0,0 +1,120 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB_BOARD Board specific USB definitions
* @brief Board specific USB definitions
* @{
*
* @file pios_usb_board_data.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Board specific USB definitions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "pios_usb_board_data.h" /* struct usb_*, USB_* */
#include "pios_sys.h" /* PIOS_SYS_SerialNumberGet */
#include "pios_usbhook.h" /* PIOS_USBHOOK_* */
static const uint8_t usb_product_id[22] = {
sizeof(usb_product_id),
USB_DESC_TYPE_STRING,
'R', 0,
'e', 0,
'v', 0,
'o', 0,
'l', 0,
'u', 0,
't', 0,
'i', 0,
'o', 0,
'n', 0,
};
static uint8_t usb_serial_number[52] = {
sizeof(usb_serial_number),
USB_DESC_TYPE_STRING,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0
};
static const struct usb_string_langid usb_lang_id = {
.bLength = sizeof(usb_lang_id),
.bDescriptorType = USB_DESC_TYPE_STRING,
.bLangID = htousbs(USB_LANGID_ENGLISH_UK),
};
static const uint8_t usb_vendor_id[28] = {
sizeof(usb_vendor_id),
USB_DESC_TYPE_STRING,
'o', 0,
'p', 0,
'e', 0,
'n', 0,
'p', 0,
'i', 0,
'l', 0,
'o', 0,
't', 0,
'.', 0,
'o', 0,
'r', 0,
'g', 0
};
int32_t PIOS_USB_BOARD_DATA_Init(void)
{
/* Load device serial number into serial number string */
uint8_t sn[25];
PIOS_SYS_SerialNumberGet((char *)sn);
for (uint8_t i = 0; sn[i] != '\0' && (2 * i) < usb_serial_number[0]; i++) {
usb_serial_number[2 + 2 * i] = sn[i];
}
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_PRODUCT, (uint8_t *)&usb_product_id, sizeof(usb_product_id));
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_SERIAL, (uint8_t *)&usb_serial_number, sizeof(usb_serial_number));
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_LANG, (uint8_t *)&usb_lang_id, sizeof(usb_lang_id));
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_VENDOR, (uint8_t *)&usb_vendor_id, sizeof(usb_vendor_id));
return 0;
}

View File

@ -53,7 +53,7 @@ USE_GPS ?= YES
USE_I2C ?= YES
# Set to YES when using Code Sourcery toolchain
CODE_SOURCERY ?= YES
CODE_SOURCERY ?= NO
# Remove command is different for Code Sourcery on Windows
ifeq ($(CODE_SOURCERY), YES)

View File

@ -102,7 +102,6 @@ MODULE_INITCALL(AltitudeInitialize, AltitudeStart)
static void altitudeTask(void *parameters)
{
BaroAltitudeData data;
portTickType lastSysTime;
#if defined(PIOS_INCLUDE_HCSR04)
SonarAltitudeData sonardata;
@ -115,7 +114,6 @@ static void altitudeTask(void *parameters)
// TODO: Check the pressure sensor and set a warning if it fails test
// Main task loop
lastSysTime = xTaskGetTickCount();
while (1)
{
#if defined(PIOS_INCLUDE_HCSR04)

View File

@ -170,7 +170,6 @@ int32_t gyro_test;
static void AttitudeTask(void *parameters)
{
uint8_t init = 0;
portTickType lastSysTime;
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
// Set critical error and wait until the accel is producing data
@ -205,8 +204,6 @@ static void AttitudeTask(void *parameters)
// Force settings update to make sure rotation loaded
settingsUpdatedCb(AttitudeSettingsHandle());
lastSysTime = xTaskGetTickCount();
// Main task loop
while (1) {

View File

@ -229,6 +229,12 @@ extern uint32_t pios_com_telem_usb_id;
// None.
//-------------------------
//-------------------------
// USB
//-------------------------
#define PIOS_USB_MAX_DEVS 1
#define PIOS_USB_ENABLED 1 /* Should remove all references to this */
#define PIOS_USB_HID_MAX_DEVS 1
#endif /* STM3210E_INS_H_ */
/**

View File

@ -32,6 +32,7 @@
#include "pios_usb_defs.h" /* struct usb_*, USB_* */
#include "pios_usb_board_data.h" /* PIOS_USB_BOARD_* */
#include "pios_usbhook.h" /* PIOS_USBHOOK_Register* */
#include "pios_usb_hid.h" /* PIOS_USB_HID_Register* */
static const struct usb_device_desc device_desc = {
.bLength = sizeof(struct usb_device_desc),
@ -249,8 +250,8 @@ int32_t PIOS_USB_DESC_HID_CDC_Init(void)
PIOS_USBHOOK_RegisterDevice((uint8_t *)&device_desc, sizeof(device_desc));
PIOS_USBHOOK_RegisterHidInterface((uint8_t *)&(config_hid_cdc.hid_if), sizeof(config_hid_cdc.hid_if));
PIOS_USBHOOK_RegisterHidReport((uint8_t *)hid_report_desc, sizeof(hid_report_desc));
PIOS_USB_HID_RegisterHidInterface((uint8_t *)&(config_hid_cdc.hid_if), sizeof(config_hid_cdc.hid_if));
PIOS_USB_HID_RegisterHidReport((uint8_t *)hid_report_desc, sizeof(hid_report_desc));
return 0;
}

View File

@ -32,6 +32,7 @@
#include "pios_usb_defs.h" /* struct usb_*, USB_* */
#include "pios_usb_board_data.h" /* PIOS_USB_BOARD_* */
#include "pios_usbhook.h" /* PIOS_USBHOOK_Register* */
#include "pios_usb_hid.h" /* PIOS_USB_HID_Register* */
static const struct usb_device_desc device_desc = {
.bLength = sizeof(struct usb_device_desc),
@ -75,7 +76,7 @@ static const uint8_t hid_report_desc[36] = {
HID_MAIN_ITEM_1 (HID_TAG_MAIN_INPUT),
0x03, /* Variable, Constant (read-only) */
/* Host -> Host emulated serial channel */
/* Host -> Device emulated serial channel */
HID_GLOBAL_ITEM_1 (HID_TAG_GLOBAL_REPORT_ID),
0x02, /* OpenPilot emulated Serial Channel (Host -> Device) */
HID_LOCAL_ITEM_1 (HID_TAG_LOCAL_USAGE),
@ -157,8 +158,8 @@ int32_t PIOS_USB_DESC_HID_ONLY_Init(void)
PIOS_USBHOOK_RegisterDevice((uint8_t *)&device_desc, sizeof(device_desc));
PIOS_USBHOOK_RegisterHidInterface((uint8_t *)&(config_hid_only.hid_if), sizeof(config_hid_only.hid_if));
PIOS_USBHOOK_RegisterHidReport((uint8_t *)hid_report_desc, sizeof(hid_report_desc));
PIOS_USB_HID_RegisterHidInterface((uint8_t *)&(config_hid_only.hid_if), sizeof(config_hid_only.hid_if));
PIOS_USB_HID_RegisterHidReport((uint8_t *)hid_report_desc, sizeof(hid_report_desc));
return 0;
}

View File

@ -335,6 +335,7 @@ int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint32_t slave_id, uint8_t pin_value
* \param[in] spi SPI number (0 or 1)
* \param[in] b the byte which should be transfered
*/
static uint8_t dummy;
int32_t PIOS_SPI_TransferByte(uint32_t spi_id, uint8_t b)
{
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
@ -342,7 +343,6 @@ int32_t PIOS_SPI_TransferByte(uint32_t spi_id, uint8_t b)
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
uint8_t dummy;
uint8_t rx_byte;
/*

View File

@ -148,7 +148,7 @@ out_fail:
* \return < 0 on errors
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
*/
int32_t PIOS_USB_ChangeConnectionState(uint32_t Connected)
int32_t PIOS_USB_ChangeConnectionState(bool Connected)
{
// In all cases: re-initialise USB HID driver
if (Connected) {

View File

@ -38,6 +38,9 @@
#include "pios_usb_cdc_priv.h"
#include "pios_usb_board_data.h" /* PIOS_BOARD_*_DATA_LENGTH */
/* STM32 USB Library Definitions */
#include "usb_lib.h"
static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail);
@ -312,6 +315,7 @@ static void PIOS_USB_CDC_DATA_EP_OUT_Callback(void)
#endif /* PIOS_INCLUDE_FREERTOS */
}
static uint16_t control_line_state;
RESULT PIOS_USB_CDC_SetControlLineState(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
@ -319,8 +323,6 @@ RESULT PIOS_USB_CDC_SetControlLineState(void)
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
static uint16_t control_line_state;
uint8_t wValue0 = pInformation->USBwValue0;
uint8_t wValue1 = pInformation->USBwValue1;

View File

@ -38,6 +38,9 @@
#include "pios_usb_hid_priv.h"
#include "pios_usb_board_data.h" /* PIOS_BOARD_*_DATA_LENGTH */
/* STM32 USB Library Definitions */
#include "usb_lib.h"
static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbhid_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbhid_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USB_HID_TxStart(uint32_t usbhid_id, uint16_t tx_bytes_avail);

View File

@ -36,6 +36,9 @@
#include "pios_usb_cdc_priv.h" /* PIOS_USB_CDC_* */
#include "pios_usb_board_data.h" /* PIOS_USB_BOARD_* */
/* STM32 USB Library Definitions */
#include "usb_lib.h"
static ONE_DESCRIPTOR Device_Descriptor;
void PIOS_USBHOOK_RegisterDevice(const uint8_t * desc, uint16_t desc_size)
@ -64,7 +67,7 @@ void PIOS_USBHOOK_RegisterString(enum usb_string_desc string_id, const uint8_t *
static ONE_DESCRIPTOR Hid_Interface_Descriptor;
void PIOS_USBHOOK_RegisterHidInterface(const uint8_t * desc, uint16_t desc_size)
void PIOS_USB_HID_RegisterHidInterface(const uint8_t * desc, uint16_t desc_size)
{
Hid_Interface_Descriptor.Descriptor = desc;
Hid_Interface_Descriptor.Descriptor_Size = desc_size;
@ -72,7 +75,7 @@ void PIOS_USBHOOK_RegisterHidInterface(const uint8_t * desc, uint16_t desc_size)
static ONE_DESCRIPTOR Hid_Report_Descriptor;
void PIOS_USBHOOK_RegisterHidReport(const uint8_t * desc, uint16_t desc_size)
void PIOS_USB_HID_RegisterHidReport(const uint8_t * desc, uint16_t desc_size)
{
Hid_Report_Descriptor.Descriptor = desc;
Hid_Report_Descriptor.Descriptor_Size = desc_size;
@ -290,6 +293,8 @@ static void PIOS_USBHOOK_Status_Out(void)
* Output : None.
* Return : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
extern const uint8_t *PIOS_USB_CDC_GetLineCoding(uint16_t Length);
static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo)
{
const uint8_t *(*CopyRoutine) (uint16_t);
@ -318,7 +323,7 @@ static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo)
switch (pInformation->USBwIndex0) {
case 0: /* HID Interface */
switch (RequestNo) {
case GET_PROTOCOL:
case USB_HID_REQ_GET_PROTOCOL:
CopyRoutine = PIOS_USBHOOK_GetProtocolValue;
break;
}
@ -327,7 +332,7 @@ static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo)
#if defined(PIOS_INCLUDE_USB_CDC)
case 1: /* CDC Call Control Interface */
switch (RequestNo) {
case GET_LINE_CODING:
case USB_CDC_REQ_GET_LINE_CODING:
CopyRoutine = PIOS_USB_CDC_GetLineCoding;
break;
}
@ -363,6 +368,9 @@ static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo)
* Output : None.
* Return : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
extern RESULT PIOS_USB_CDC_SetControlLineState(void);
extern RESULT PIOS_USB_CDC_SetLineCoding(void);
static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo)
{
switch (Type_Recipient) {
@ -370,7 +378,7 @@ static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo)
switch (pInformation->USBwIndex0) {
case 0: /* HID */
switch (RequestNo) {
case SET_PROTOCOL:
case USB_HID_REQ_SET_PROTOCOL:
return PIOS_USBHOOK_SetProtocol();
break;
}
@ -380,10 +388,10 @@ static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo)
#if defined(PIOS_INCLUDE_USB_CDC)
case 1: /* CDC Call Control Interface */
switch (RequestNo) {
case SET_LINE_CODING:
case USB_CDC_REQ_SET_LINE_CODING:
return PIOS_USB_CDC_SetLineCoding();
break;
case SET_CONTROL_LINE_STATE:
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
return PIOS_USB_CDC_SetControlLineState();
break;
}

View File

@ -94,7 +94,7 @@ void PIOS_SYS_Init(void)
//RCC_AHB2Periph_CRYP | No crypto
//RCC_AHB2Periph_HASH | No hash generator
//RCC_AHB2Periph_RNG | No random numbers @todo might be good to have later if entropy is desired
RCC_AHB2Periph_OTG_FS |
//RCC_AHB2Periph_OTG_FS |
0, ENABLE);
RCC_AHB3PeriphClockCmd(
//RCC_AHB3Periph_FSMC | No external static memory

View File

@ -0,0 +1,290 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB USB Setup Functions
* @brief PIOS USB device implementation
* @{
*
* @file pios_usb.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief USB device functions (STM32 dependent code)
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Project Includes */
#include "pios.h"
#include "usb_core.h"
#include "pios_usb_board_data.h"
#include "pios_usb.h"
#include "pios_usb_priv.h"
#if defined(PIOS_INCLUDE_USB)
/* Rx/Tx status */
static uint8_t transfer_possible = 0;
enum pios_usb_dev_magic {
PIOS_USB_DEV_MAGIC = 0x17365904,
};
struct pios_usb_dev {
enum pios_usb_dev_magic magic;
const struct pios_usb_cfg * cfg;
};
/**
* @brief Validate the usb device structure
* @returns true if valid device or false otherwise
*/
static bool PIOS_USB_validate(struct pios_usb_dev * usb_dev)
{
return (usb_dev && (usb_dev->magic == PIOS_USB_DEV_MAGIC));
}
#if defined(PIOS_INCLUDE_FREERTOS)
static struct pios_usb_dev * PIOS_USB_alloc(void)
{
struct pios_usb_dev * usb_dev;
usb_dev = (struct pios_usb_dev *)pvPortMalloc(sizeof(*usb_dev));
if (!usb_dev) return(NULL);
usb_dev->magic = PIOS_USB_DEV_MAGIC;
return(usb_dev);
}
#else
static struct pios_usb_dev pios_usb_devs[PIOS_USB_MAX_DEVS];
static uint8_t pios_usb_num_devs;
static struct pios_usb_dev * PIOS_USB_alloc(void)
{
struct pios_usb_dev * usb_dev;
if (pios_usb_num_devs >= PIOS_USB_MAX_DEVS) {
return (NULL);
}
usb_dev = &pios_usb_devs[pios_usb_num_devs++];
usb_dev->magic = PIOS_USB_DEV_MAGIC;
return (usb_dev);
}
#endif
/**
* Bind configuration to USB BSP layer
* \return < 0 if initialisation failed
*/
static uint32_t pios_usb_id;
int32_t PIOS_USB_Init(uint32_t * usb_id, const struct pios_usb_cfg * cfg)
{
PIOS_Assert(usb_id);
PIOS_Assert(cfg);
struct pios_usb_dev * usb_dev;
usb_dev = (struct pios_usb_dev *) PIOS_USB_alloc();
if (!usb_dev) goto out_fail;
/* Bind the configuration to the device instance */
usb_dev->cfg = cfg;
/*
* This is a horrible hack to make this available to
* the interrupt callbacks. This should go away ASAP.
*/
pios_usb_id = (uint32_t) usb_dev;
*usb_id = (uint32_t) usb_dev;
return 0; /* No error */
out_fail:
return(-1);
}
/**
* This function is called by the USB driver on cable connection/disconnection
* \param[in] connected connection status (1 if connected)
* \return < 0 on errors
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
*/
int32_t PIOS_USB_ChangeConnectionState(bool connected)
{
// In all cases: re-initialise USB HID driver
if (connected) {
transfer_possible = 1;
//TODO: Check SetEPRxValid(ENDP1);
#if defined(USB_LED_ON)
USB_LED_ON; // turn the USB led on
#endif
} else {
// Cable disconnected: disable transfers
transfer_possible = 0;
#if defined(USB_LED_OFF)
USB_LED_OFF; // turn the USB led off
#endif
}
return 0;
}
/**
* This function returns the connection status of the USB interface
* \return 1: interface available
* \return 0: interface not available
*/
uint32_t usb_found;
bool PIOS_USB_CheckAvailable(uint8_t id)
{
struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_id;
if(!PIOS_USB_validate(usb_dev))
return false;
usb_found = (usb_dev->cfg->vsense.gpio->IDR & usb_dev->cfg->vsense.init.GPIO_Pin);
return usb_found;
return usb_found != 0 && transfer_possible ? 1 : 0;
}
/*
*
* Provide STM32 USB OTG BSP layer API
*
*/
#include "usb_bsp.h"
void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{
struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_id;
bool valid = PIOS_USB_validate(usb_dev);
PIOS_Assert(valid);
#define FORCE_DISABLE_USB_IRQ 1
#if FORCE_DISABLE_USB_IRQ
/* Make sure we disable the USB interrupt since it may be left on by bootloader */
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure = usb_dev->cfg->irq.init;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
/* Configure USB D-/D+ (DM/DP) pins */
GPIO_InitTypeDef GPIO_InitStructure;
#define FORCE_USB_DP_DM_LOW 1
#if FORCE_USB_DP_DM_LOW
/* Force D-/D+ low for 50ms to trigger a disconnect */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, 0);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, 0);
GPIO_ResetBits(GPIOA, GPIO_Pin_12);
GPIO_ResetBits(GPIOA, GPIO_Pin_11);
PIOS_DELAY_WaitmS(50);
#endif
/* Set up D-/D+ as USB function again */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG1_FS);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG1_FS);
/* Configure VBUS sense pin */
GPIO_Init(usb_dev->cfg->vsense.gpio, &usb_dev->cfg->vsense.init);
/* Enable USB OTG Clock */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE);
}
void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
{
struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_id;
bool valid = PIOS_USB_validate(usb_dev);
PIOS_Assert(valid);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_Init(&usb_dev->cfg->irq.init);
}
#ifdef USE_HOST_MODE
void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev, uint8_t state)
{
}
void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev)
{
}
#endif /* USE_HOST_MODE */
void USB_OTG_BSP_TimeInit ( void )
{
}
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
uint32_t count = 0;
const uint32_t utime = (120 * usec / 7);
do {
if (++count > utime) {
return ;
}
}
while (1);
}
void USB_OTG_BSP_mDelay (const uint32_t msec)
{
USB_OTG_BSP_uDelay(msec * 1000);
}
void USB_OTG_BSP_TimerIRQ (void)
{
}
#endif /* PIOS_INCLUDE_USB */
/**
* @}
* @}
*/

View File

@ -0,0 +1,400 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB_COM USB COM Functions
* @brief PIOS USB COM implementation for CDC interfaces
* @notes This implements a CDC Serial Port
* @{
*
* @file pios_usb_com_cdc.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief USB COM functions (STM32 dependent code)
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Project Includes */
#include "pios.h"
#if defined(PIOS_INCLUDE_USB_CDC)
#include "pios_usb.h"
#include "pios_usb_cdc_priv.h"
#include "pios_usb_board_data.h" /* PIOS_BOARD_*_DATA_LENGTH */
static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail);
static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail);
const struct pios_com_driver pios_usb_cdc_com_driver = {
.tx_start = PIOS_USB_CDC_TxStart,
.rx_start = PIOS_USB_CDC_RxStart,
.bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
.bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
};
enum pios_usb_cdc_dev_magic {
PIOS_USB_CDC_DEV_MAGIC = 0xAABBCCDD,
};
struct pios_usb_cdc_dev {
enum pios_usb_cdc_dev_magic magic;
const struct pios_usb_cdc_cfg * cfg;
uint32_t lower_id;
pios_com_callback rx_in_cb;
uint32_t rx_in_context;
pios_com_callback tx_out_cb;
uint32_t tx_out_context;
uint8_t rx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH];
uint8_t tx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH];
uint32_t rx_dropped;
uint32_t rx_oversize;
};
static bool PIOS_USB_CDC_validate(struct pios_usb_cdc_dev * usb_cdc_dev)
{
return (usb_cdc_dev && (usb_cdc_dev->magic == PIOS_USB_CDC_DEV_MAGIC));
}
#if defined(PIOS_INCLUDE_FREERTOS)
static struct pios_usb_cdc_dev * PIOS_USB_CDC_alloc(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev;
usb_cdc_dev = (struct pios_usb_cdc_dev *)pvPortMalloc(sizeof(*usb_cdc_dev));
if (!usb_cdc_dev) return(NULL);
usb_cdc_dev->magic = PIOS_USB_CDC_DEV_MAGIC;
return(usb_cdc_dev);
}
#else
static struct pios_usb_cdc_dev pios_usb_cdc_devs[PIOS_USB_CDC_MAX_DEVS];
static uint8_t pios_usb_cdc_num_devs;
static struct pios_usb_cdc_dev * PIOS_USB_CDC_alloc(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev;
if (pios_usb_cdc_num_devs >= PIOS_USB_CDC_MAX_DEVS) {
return (NULL);
}
usb_cdc_dev = &pios_usb_cdc_devs[pios_usb_cdc_num_devs++];
usb_cdc_dev->magic = PIOS_USB_CDC_DEV_MAGIC;
return (usb_cdc_dev);
}
#endif
static void PIOS_USB_CDC_DATA_EP_IN_Callback(void);
static void PIOS_USB_CDC_DATA_EP_OUT_Callback(void);
static void PIOS_USB_CDC_CTRL_EP_IN_Callback(void);
static uint32_t pios_usb_cdc_id;
/* Need a better way to pull these in */
extern void (*pEpInt_IN[7])(void);
extern void (*pEpInt_OUT[7])(void);
int32_t PIOS_USB_CDC_Init(uint32_t * usbcdc_id, const struct pios_usb_cdc_cfg * cfg, uint32_t lower_id)
{
PIOS_Assert(usbcdc_id);
PIOS_Assert(cfg);
struct pios_usb_cdc_dev * usb_cdc_dev;
usb_cdc_dev = (struct pios_usb_cdc_dev *) PIOS_USB_CDC_alloc();
if (!usb_cdc_dev) goto out_fail;
/* Bind the configuration to the device instance */
usb_cdc_dev->cfg = cfg;
usb_cdc_dev->lower_id = lower_id;
pios_usb_cdc_id = (uint32_t) usb_cdc_dev;
/* Bind lower level callbacks into the USB infrastructure */
pEpInt_OUT[cfg->ctrl_tx_ep - 1] = PIOS_USB_CDC_CTRL_EP_IN_Callback;
pEpInt_IN[cfg->data_tx_ep - 1] = PIOS_USB_CDC_DATA_EP_IN_Callback;
pEpInt_OUT[cfg->data_rx_ep - 1] = PIOS_USB_CDC_DATA_EP_OUT_Callback;
*usbcdc_id = (uint32_t) usb_cdc_dev;
return 0;
out_fail:
return -1;
}
static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
/*
* Order is important in these assignments since ISR uses _cb
* field to determine if it's ok to dereference _cb and _context
*/
usb_cdc_dev->rx_in_context = context;
usb_cdc_dev->rx_in_cb = rx_in_cb;
}
static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
/*
* Order is important in these assignments since ISR uses _cb
* field to determine if it's ok to dereference _cb and _context
*/
usb_cdc_dev->tx_out_context = context;
usb_cdc_dev->tx_out_cb = tx_out_cb;
}
static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail) {
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
if (!PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id)) {
return;
}
// If endpoint was stalled and there is now space make it valid
PIOS_IRQ_Disable();
if ((GetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep) != EP_RX_VALID) &&
(rx_bytes_avail >= sizeof(usb_cdc_dev->rx_packet_buffer))) {
SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID);
}
PIOS_IRQ_Enable();
}
static void PIOS_USB_CDC_SendData(struct pios_usb_cdc_dev * usb_cdc_dev)
{
uint16_t bytes_to_tx;
if (!usb_cdc_dev->tx_out_cb) {
return;
}
bool need_yield = false;
bytes_to_tx = (usb_cdc_dev->tx_out_cb)(usb_cdc_dev->tx_out_context,
usb_cdc_dev->tx_packet_buffer,
sizeof(usb_cdc_dev->tx_packet_buffer),
NULL,
&need_yield);
if (bytes_to_tx == 0) {
return;
}
UserToPMABufferCopy(usb_cdc_dev->tx_packet_buffer,
GetEPTxAddr(usb_cdc_dev->cfg->data_tx_ep),
bytes_to_tx);
SetEPTxCount(usb_cdc_dev->cfg->data_tx_ep, bytes_to_tx);
SetEPTxValid(usb_cdc_dev->cfg->data_tx_ep);
#if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) {
vPortYieldFromISR();
}
#endif /* PIOS_INCLUDE_FREERTOS */
}
static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
if (!PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id)) {
return;
}
if (GetEPTxStatus(usb_cdc_dev->cfg->data_tx_ep) == EP_TX_VALID) {
/* Endpoint is already transmitting */
return;
}
PIOS_USB_CDC_SendData(usb_cdc_dev);
}
static void PIOS_USB_CDC_DATA_EP_IN_Callback(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
PIOS_USB_CDC_SendData(usb_cdc_dev);
}
static void PIOS_USB_CDC_DATA_EP_OUT_Callback(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
uint32_t DataLength;
/* Get the number of received data on the selected Endpoint */
DataLength = GetEPRxCount(usb_cdc_dev->cfg->data_rx_ep);
if (DataLength > sizeof(usb_cdc_dev->rx_packet_buffer)) {
usb_cdc_dev->rx_oversize++;
DataLength = sizeof(usb_cdc_dev->rx_packet_buffer);
}
/* Use the memory interface function to read from the selected endpoint */
PMAToUserBufferCopy((uint8_t *) usb_cdc_dev->rx_packet_buffer,
GetEPRxAddr(usb_cdc_dev->cfg->data_rx_ep),
DataLength);
if (!usb_cdc_dev->rx_in_cb) {
/* No Rx call back registered, disable the receiver */
SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK);
return;
}
uint16_t headroom;
bool need_yield = false;
uint16_t rc;
rc = (usb_cdc_dev->rx_in_cb)(usb_cdc_dev->rx_in_context,
usb_cdc_dev->rx_packet_buffer,
DataLength,
&headroom,
&need_yield);
if (rc < DataLength) {
/* Lost bytes on rx */
usb_cdc_dev->rx_dropped += (DataLength - rc);
}
if (headroom >= sizeof(usb_cdc_dev->rx_packet_buffer)) {
/* We have room for a maximum length message */
SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID);
} else {
/* Not enough room left for a message, apply backpressure */
SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK);
}
#if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) {
vPortYieldFromISR();
}
#endif /* PIOS_INCLUDE_FREERTOS */
}
RESULT PIOS_USB_CDC_SetControlLineState(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
static uint16_t control_line_state;
uint8_t wValue0 = pInformation->USBwValue0;
uint8_t wValue1 = pInformation->USBwValue1;
control_line_state = wValue1 << 8 | wValue0;
return USB_SUCCESS;
}
static struct usb_cdc_line_coding line_coding = {
.dwDTERate = htousbl(57600),
.bCharFormat = USB_CDC_LINE_CODING_STOP_1,
.bParityType = USB_CDC_LINE_CODING_PARITY_NONE,
.bDataBits = 8,
};
RESULT PIOS_USB_CDC_SetLineCoding(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
return USB_SUCCESS;
}
const uint8_t *PIOS_USB_CDC_GetLineCoding(uint16_t Length)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
if (Length == 0) {
pInformation->Ctrl_Info.Usb_wLength = sizeof(line_coding);
return NULL;
} else {
return ((uint8_t *) &line_coding);
}
}
struct usb_cdc_serial_state_report uart_state = {
.bmRequestType = 0xA1,
.bNotification = USB_CDC_NOTIFICATION_SERIAL_STATE,
.wValue = 0,
.wIndex = htousbs(1),
.wLength = htousbs(2),
.bmUartState = htousbs(0),
};
static void PIOS_USB_CDC_CTRL_EP_IN_Callback(void)
{
struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
PIOS_Assert(valid);
/* Give back UART State Bitmap */
/* UART State Bitmap
* 15-7: reserved
* 6: bOverRun overrun error
* 5: bParity parity error
* 4: bFraming framing error
* 3: bRingSignal RI
* 2: bBreak break reception
* 1: bTxCarrier DSR
* 0: bRxCarrier DCD
*/
uart_state.bmUartState = htousbs(0x0003);
UserToPMABufferCopy((uint8_t *) &uart_state,
GetEPTxAddr(usb_cdc_dev->cfg->data_tx_ep),
sizeof(uart_state));
SetEPTxCount(usb_cdc_dev->cfg->data_tx_ep, PIOS_USB_BOARD_CDC_MGMT_LENGTH);
SetEPTxValid(usb_cdc_dev->cfg->data_tx_ep);
}
#endif /* PIOS_INCLUDE_USB_CDC */

View File

@ -0,0 +1,497 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB_HID USB COM Functions
* @brief PIOS USB COM implementation for HID interfaces
* @notes This implements serial emulation over HID reports
* @{
*
* @file pios_usb_hid.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief USB COM functions (STM32 dependent code)
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Project Includes */
#include "pios.h"
#if defined(PIOS_INCLUDE_USB_HID)
#include "pios_usb.h"
#include "pios_usb_hid_priv.h"
#include "pios_usb_board_data.h" /* PIOS_BOARD_*_DATA_LENGTH */
#include "pios_usbhook.h" /* PIOS_USBHOOK_* */
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbhid_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbhid_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USB_HID_TxStart(uint32_t usbhid_id, uint16_t tx_bytes_avail);
static void PIOS_USB_HID_RxStart(uint32_t usbhid_id, uint16_t rx_bytes_avail);
const struct pios_com_driver pios_usb_hid_com_driver = {
.tx_start = PIOS_USB_HID_TxStart,
.rx_start = PIOS_USB_HID_RxStart,
.bind_tx_cb = PIOS_USB_HID_RegisterTxCallback,
.bind_rx_cb = PIOS_USB_HID_RegisterRxCallback,
};
enum pios_usb_hid_dev_magic {
PIOS_USB_HID_DEV_MAGIC = 0xAA00BB00,
};
struct pios_usb_hid_dev {
enum pios_usb_hid_dev_magic magic;
const struct pios_usb_hid_cfg * cfg;
uint32_t lower_id;
pios_com_callback rx_in_cb;
uint32_t rx_in_context;
pios_com_callback tx_out_cb;
uint32_t tx_out_context;
uint8_t rx_packet_buffer[PIOS_USB_BOARD_HID_DATA_LENGTH];
uint8_t tx_packet_buffer[PIOS_USB_BOARD_HID_DATA_LENGTH];
uint32_t rx_dropped;
uint32_t rx_oversize;
};
static bool PIOS_USB_HID_validate(struct pios_usb_hid_dev * usb_hid_dev)
{
return (usb_hid_dev && (usb_hid_dev->magic == PIOS_USB_HID_DEV_MAGIC));
}
#if defined(PIOS_INCLUDE_FREERTOS)
static struct pios_usb_hid_dev * PIOS_USB_HID_alloc(void)
{
struct pios_usb_hid_dev * usb_hid_dev;
usb_hid_dev = (struct pios_usb_hid_dev *)pvPortMalloc(sizeof(*usb_hid_dev));
if (!usb_hid_dev) return(NULL);
usb_hid_dev->magic = PIOS_USB_HID_DEV_MAGIC;
return(usb_hid_dev);
}
#else
static struct pios_usb_hid_dev pios_usb_hid_devs[PIOS_USB_HID_MAX_DEVS];
static uint8_t pios_usb_hid_num_devs;
static struct pios_usb_hid_dev * PIOS_USB_HID_alloc(void)
{
struct pios_usb_hid_dev * usb_hid_dev;
if (pios_usb_hid_num_devs >= PIOS_USB_HID_MAX_DEVS) {
return (NULL);
}
usb_hid_dev = &pios_usb_hid_devs[pios_usb_hid_num_devs++];
usb_hid_dev->magic = PIOS_USB_HID_DEV_MAGIC;
return (usb_hid_dev);
}
#endif
static void PIOS_USB_HID_IF_Init(uint32_t usb_hid_id);
static void PIOS_USB_HID_IF_DeInit(uint32_t usb_hid_id);
static bool PIOS_USB_HID_IF_Setup(uint32_t usb_hid_id, struct usb_setup_request *req);
static void PIOS_USB_HID_IF_CtrlDataOut(uint32_t usb_hid_id, struct usb_setup_request *req);
static struct pios_usb_ifops usb_hid_ifops = {
.init = PIOS_USB_HID_IF_Init,
.deinit = PIOS_USB_HID_IF_DeInit,
.setup = PIOS_USB_HID_IF_Setup,
.ctrl_data_out = PIOS_USB_HID_IF_CtrlDataOut,
};
static bool PIOS_USB_HID_EP_IN_Callback(uint32_t usb_hid_id, uint8_t epnum, uint16_t len);
static bool PIOS_USB_HID_EP_OUT_Callback(uint32_t usb_hid_id, uint8_t epnum, uint16_t len);
int32_t PIOS_USB_HID_Init(uint32_t * usbhid_id, const struct pios_usb_hid_cfg * cfg, uint32_t lower_id)
{
PIOS_Assert(usbhid_id);
PIOS_Assert(cfg);
struct pios_usb_hid_dev * usb_hid_dev;
usb_hid_dev = (struct pios_usb_hid_dev *) PIOS_USB_HID_alloc();
if (!usb_hid_dev) goto out_fail;
/* Bind the configuration to the device instance */
usb_hid_dev->cfg = cfg;
usb_hid_dev->lower_id = lower_id;
/* Register class specific interface callbacks with the USBHOOK layer */
PIOS_USBHOOK_RegisterIfOps(cfg->data_if, &usb_hid_ifops, (uint32_t) usb_hid_dev);
*usbhid_id = (uint32_t) usb_hid_dev;
return 0;
out_fail:
return -1;
}
static struct pios_usbhook_descriptor hid_if_desc;
void PIOS_USB_HID_RegisterHidInterface(const uint8_t * desc, uint16_t length)
{
hid_if_desc.descriptor = desc;
hid_if_desc.length = length;
}
static struct pios_usbhook_descriptor hid_report_desc;
void PIOS_USB_HID_RegisterHidReport(const uint8_t * desc, uint16_t length)
{
hid_report_desc.descriptor = desc;
hid_report_desc.length = length;
}
static bool PIOS_USB_HID_SendReport(struct pios_usb_hid_dev * usb_hid_dev)
{
uint16_t bytes_to_tx;
if (!usb_hid_dev->tx_out_cb) {
return false;
}
bool need_yield = false;
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
&usb_hid_dev->tx_packet_buffer[1],
sizeof(usb_hid_dev->tx_packet_buffer)-1,
NULL,
&need_yield);
#else
bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
&usb_hid_dev->tx_packet_buffer[2],
sizeof(usb_hid_dev->tx_packet_buffer)-2,
NULL,
&need_yield);
#endif
if (bytes_to_tx == 0) {
return false;
}
/* Always set type as report ID */
usb_hid_dev->tx_packet_buffer[0] = 1;
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
PIOS_USBHOOK_EndpointTx(usb_hid_dev->cfg->data_tx_ep,
usb_hid_dev->tx_packet_buffer,
bytes_to_tx + 1);
#else
usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx;
PIOS_USBHOOK_EndpointTx(usb_hid_dev->cfg->data_tx_ep,
usb_hid_dev->tx_packet_buffer,
bytes_to_tx + 2);
#endif
#if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) {
vPortYieldFromISR();
}
#endif /* PIOS_INCLUDE_FREERTOS */
return true;
}
static void PIOS_USB_HID_RxStart(uint32_t usbhid_id, uint16_t rx_bytes_avail) {
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbhid_id;
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
PIOS_Assert(valid);
if (!PIOS_USB_CheckAvailable(usb_hid_dev->lower_id)) {
return;
}
// If endpoint was stalled and there is now space make it valid
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1;
#else
uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2;
#endif
PIOS_IRQ_Disable();
if (rx_bytes_avail >= max_payload_length) {
/*
* FIXME should make sure we do not already have a buffer queued
*/
PIOS_USBHOOK_EndpointRx(usb_hid_dev->cfg->data_rx_ep,
usb_hid_dev->rx_packet_buffer,
sizeof(usb_hid_dev->rx_packet_buffer));
}
PIOS_IRQ_Enable();
}
static void PIOS_USB_HID_TxStart(uint32_t usbhid_id, uint16_t tx_bytes_avail)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbhid_id;
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
PIOS_Assert(valid);
if (!PIOS_USB_CheckAvailable(usb_hid_dev->lower_id)) {
return;
}
#if 0
if (GetEPTxStatus(usb_hid_dev->cfg->data_tx_ep) == EP_TX_VALID) {
/* Endpoint is already transmitting */
return;
}
#else
/*
* FIXME start transmitter
*/
#endif
PIOS_USB_HID_SendReport(usb_hid_dev);
}
static void PIOS_USB_HID_RegisterRxCallback(uint32_t usbhid_id, pios_com_callback rx_in_cb, uint32_t context)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbhid_id;
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
PIOS_Assert(valid);
/*
* Order is important in these assignments since ISR uses _cb
* field to determine if it's ok to dereference _cb and _context
*/
usb_hid_dev->rx_in_context = context;
usb_hid_dev->rx_in_cb = rx_in_cb;
}
static void PIOS_USB_HID_RegisterTxCallback(uint32_t usbhid_id, pios_com_callback tx_out_cb, uint32_t context)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbhid_id;
bool valid = PIOS_USB_HID_validate(usb_hid_dev);
PIOS_Assert(valid);
/*
* Order is important in these assignments since ISR uses _cb
* field to determine if it's ok to dereference _cb and _context
*/
usb_hid_dev->tx_out_context = context;
usb_hid_dev->tx_out_cb = tx_out_cb;
}
static void PIOS_USB_HID_IF_Init(uint32_t usb_hid_id)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id;
if (!PIOS_USB_HID_validate(usb_hid_dev)) {
return;
}
/* Register endpoint specific callbacks with the USBHOOK layer */
PIOS_USBHOOK_RegisterEpInCallback(usb_hid_dev->cfg->data_tx_ep,
sizeof(usb_hid_dev->rx_packet_buffer),
PIOS_USB_HID_EP_IN_Callback,
(uint32_t) usb_hid_dev);
PIOS_USBHOOK_RegisterEpOutCallback(usb_hid_dev->cfg->data_rx_ep,
sizeof(usb_hid_dev->rx_packet_buffer),
PIOS_USB_HID_EP_OUT_Callback,
(uint32_t) usb_hid_dev);
}
static void PIOS_USB_HID_IF_DeInit(uint32_t usb_hid_id)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id;
if (!PIOS_USB_HID_validate(usb_hid_dev)) {
return;
}
/* DeRegister endpoint specific callbacks with the USBHOOK layer */
PIOS_USBHOOK_DeRegisterEpInCallback(usb_hid_dev->cfg->data_tx_ep);
PIOS_USBHOOK_DeRegisterEpOutCallback(usb_hid_dev->cfg->data_rx_ep);
}
static uint8_t hid_protocol;
static uint8_t hid_altset;
static bool PIOS_USB_HID_IF_Setup(uint32_t usb_hid_id, struct usb_setup_request *req)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id;
if (!PIOS_USB_HID_validate(usb_hid_dev)) {
return false;
}
/* Make sure this is a request for an interface we know about */
uint8_t ifnum = req->wIndex & 0xFF;
if (ifnum != usb_hid_dev->cfg->data_if) {
return (false);
}
switch (req->bmRequestType & (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK)) {
case (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_INTERFACE):
switch (req->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
switch (req->wValue >> 8) {
case USB_DESC_TYPE_REPORT:
PIOS_USBHOOK_CtrlTx(hid_report_desc.descriptor,
MIN(hid_report_desc.length, req->wLength));
break;
case USB_DESC_TYPE_HID:
PIOS_USBHOOK_CtrlTx(hid_if_desc.descriptor,
MIN(hid_if_desc.length, req->wLength));
break;
default:
/* Unhandled descriptor request */
return false;
break;
}
break;
case USB_REQ_GET_INTERFACE:
PIOS_USBHOOK_CtrlTx(&hid_altset, 1);
break;
case USB_REQ_SET_INTERFACE:
hid_altset = (uint8_t)(req->wValue);
break;
default:
/* Unhandled standard request */
return false;
break;
}
break;
case (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE):
switch (req->bRequest) {
case USB_HID_REQ_SET_PROTOCOL:
hid_protocol = (uint8_t)(req->wValue);
break;
case USB_HID_REQ_GET_PROTOCOL:
PIOS_USBHOOK_CtrlTx(&hid_protocol, 1);
break;
case USB_HID_REQ_GET_REPORT:
{
/* Give back a dummy input report */
uint8_t dummy_report[2] = {
[0] = req->wValue >> 8, /* Report ID */
[1] = 0x00,
};
PIOS_USBHOOK_CtrlTx(dummy_report, sizeof(dummy_report));
}
break;
default:
/* Unhandled class request */
return false;
break;
}
break;
default:
/* Unhandled request */
return false;
}
return true;
}
static void PIOS_USB_HID_IF_CtrlDataOut(uint32_t usb_hid_id, struct usb_setup_request *req)
{
/* HID devices don't have any OUT data stages on the control endpoint */
PIOS_Assert(0);
}
/**
* @brief Callback used to indicate a transmission from device INto host completed
* Checks if any data remains, pads it into HID packet and sends.
*/
static bool PIOS_USB_HID_EP_IN_Callback(uint32_t usb_hid_id, uint8_t epnum, uint16_t len)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id;
if (!PIOS_USB_HID_validate(usb_hid_dev)) {
return false;
}
if (!PIOS_USB_CheckAvailable(usb_hid_dev->lower_id)) {
return false;
}
return (PIOS_USB_HID_SendReport(usb_hid_dev));
}
/**
* EP1 OUT Callback Routine
*/
static bool PIOS_USB_HID_EP_OUT_Callback(uint32_t usb_hid_id, uint8_t epnum, uint16_t len)
{
struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id;
if (!PIOS_USB_HID_validate(usb_hid_dev)) {
return false;
}
if (len > sizeof(usb_hid_dev->rx_packet_buffer)) {
len = sizeof(usb_hid_dev->rx_packet_buffer);
}
if (!usb_hid_dev->rx_in_cb) {
/* No Rx call back registered, disable the receiver */
return false;
}
/* The first byte is report ID (not checked), the second byte is the valid data length */
uint16_t headroom;
bool need_yield = false;
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
&usb_hid_dev->rx_packet_buffer[1],
len-1,
&headroom,
&need_yield);
#else
(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
&usb_hid_dev->rx_packet_buffer[2],
usb_hid_dev->rx_packet_buffer[1],
&headroom,
&need_yield);
#endif
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1;
#else
uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2;
#endif
if (headroom >= max_payload_length) {
/* We have room for a maximum length message */
return true;
} else {
/* Not enough room left for a message, apply backpressure */
return false;
}
#if defined(PIOS_INCLUDE_FREERTOS)
if (need_yield) {
vPortYieldFromISR();
}
#endif /* PIOS_INCLUDE_FREERTOS */
}
#endif /* PIOS_INCLUDE_USB_HID */

View File

@ -0,0 +1,897 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USBHOOK USB glue code
* @brief Glue between PiOS and STM32 libs
* @{
*
* @file pios_usbhook.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Glue between PiOS and STM32 libs
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "pios.h"
#include "pios_usb.h" /* PIOS_USB_* */
#include "pios_usbhook.h"
#include "pios_usb_defs.h" /* struct usb_* */
#include "pios_usb_cdc_priv.h" /* PIOS_USB_CDC_* */
#include "pios_usb_board_data.h" /* PIOS_USB_BOARD_* */
/* STM32 USB Library Definitions */
#include "usb_core.h" /* USBD_Class_cb_TypeDef */
#include "usbd_core.h" /* USBD_Init USBD_OK*/
#include "usbd_ioreq.h" /* USBD_CtlPrepareRx, USBD_CtlSendData */
#include "usbd_req.h" /* USBD_CtlError */
#include "usb_dcd_int.h" /* USBD_OTG_ISR_Handler */
/*
* External API
*/
static struct pios_usbhook_descriptor Device_Descriptor;
void PIOS_USBHOOK_RegisterDevice(const uint8_t * desc, uint16_t length)
{
Device_Descriptor.descriptor = desc;
Device_Descriptor.length = length;
}
static struct pios_usbhook_descriptor String_Descriptor[4];
void PIOS_USBHOOK_RegisterString(enum usb_string_desc string_id, const uint8_t * desc, uint16_t desc_size)
{
if (string_id < NELEMENTS(String_Descriptor)) {
String_Descriptor[string_id].descriptor = desc;
String_Descriptor[string_id].length = desc_size;
}
}
static struct pios_usbhook_descriptor Config_Descriptor;
void PIOS_USBHOOK_RegisterConfig(uint8_t config_id, const uint8_t * desc, uint16_t desc_size)
{
Config_Descriptor.descriptor = desc;
Config_Descriptor.length = desc_size;
}
static USB_OTG_CORE_HANDLE pios_usb_otg_core_handle;
static USBD_Class_cb_TypeDef class_callbacks;
static USBD_DEVICE device_callbacks;
static USBD_Usr_cb_TypeDef user_callbacks;
void PIOS_USBHOOK_Activate(void)
{
USBD_Init(&pios_usb_otg_core_handle,
USB_OTG_FS_CORE_ID,
&device_callbacks,
&class_callbacks,
&user_callbacks);
}
void OTG_FS_IRQHandler(void)
{
if(!USBD_OTG_ISR_Handler(&pios_usb_otg_core_handle)) {
/* spurious interrupt, disable IRQ */
}
}
struct usb_if_entry {
struct pios_usb_ifops *ifops;
uint32_t context;
};
static struct usb_if_entry usb_if_table[3];
void PIOS_USBHOOK_RegisterIfOps(uint8_t ifnum, struct pios_usb_ifops * ifops, uint32_t context)
{
PIOS_Assert(ifnum < NELEMENTS(usb_if_table));
PIOS_Assert(ifops);
usb_if_table[ifnum].ifops = ifops;
usb_if_table[ifnum].context = context;
}
struct usb_ep_entry {
pios_usbhook_epcb cb;
uint32_t context;
uint16_t max_len;
};
static struct usb_ep_entry usb_epin_table[6];
void PIOS_USBHOOK_RegisterEpInCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uint32_t context)
{
PIOS_Assert(epnum < NELEMENTS(usb_epin_table));
PIOS_Assert(cb);
usb_epin_table[epnum].cb = cb;
usb_epin_table[epnum].context = context;
usb_epin_table[epnum].max_len = max_len;
DCD_EP_Open(&pios_usb_otg_core_handle,
epnum | 0x80,
max_len,
USB_OTG_EP_INT);
/*
* FIXME do not hardcode endpoint type
*/
}
extern void PIOS_USBHOOK_DeRegisterEpInCallback(uint8_t epnum)
{
PIOS_Assert(epnum < NELEMENTS(usb_epin_table));
usb_epin_table[epnum].cb = NULL;
DCD_EP_Close(&pios_usb_otg_core_handle, epnum | 0x80);
}
static struct usb_ep_entry usb_epout_table[6];
void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uint32_t context)
{
PIOS_Assert(epnum < NELEMENTS(usb_epout_table));
PIOS_Assert(cb);
usb_epout_table[epnum].cb = cb;
usb_epout_table[epnum].context = context;
usb_epout_table[epnum].max_len = max_len;
DCD_EP_Open(&pios_usb_otg_core_handle,
epnum,
max_len,
USB_OTG_EP_INT);
/*
* FIXME do not hardcode endpoint type
*/
}
extern void PIOS_USBHOOK_DeRegisterEpOutCallback(uint8_t epnum)
{
PIOS_Assert(epnum < NELEMENTS(usb_epout_table));
usb_epout_table[epnum].cb = NULL;
DCD_EP_Close(&pios_usb_otg_core_handle, epnum);
}
void PIOS_USBHOOK_CtrlTx(const uint8_t *buf, uint16_t len)
{
USBD_CtlSendData(&pios_usb_otg_core_handle, buf, len);
}
void PIOS_USBHOOK_CtrlRx(uint8_t *buf, uint16_t len)
{
USBD_CtlPrepareRx(&pios_usb_otg_core_handle, buf, len);
}
void PIOS_USBHOOK_EndpointTx(uint8_t epnum, const uint8_t *buf, uint16_t len)
{
if (pios_usb_otg_core_handle.dev.device_status == USB_OTG_CONFIGURED) {
DCD_EP_Tx(&pios_usb_otg_core_handle, epnum, buf, len);
}
}
void PIOS_USBHOOK_EndpointRx(uint8_t epnum, uint8_t *buf, uint16_t len)
{
DCD_EP_PrepareRx(&pios_usb_otg_core_handle, epnum, buf, len);
}
/*
* Device level hooks into STM USB library
*/
static const uint8_t * PIOS_USBHOOK_DEV_GetDeviceDescriptor(uint8_t speed, uint16_t *length)
{
*length = Device_Descriptor.length;
return Device_Descriptor.descriptor;
}
static const uint8_t * PIOS_USBHOOK_DEV_GetLangIDStrDescriptor(uint8_t speed, uint16_t *length)
{
*length = String_Descriptor[USB_STRING_DESC_LANG].length;
return String_Descriptor[USB_STRING_DESC_LANG].descriptor;
}
static const uint8_t * PIOS_USBHOOK_DEV_GetManufacturerStrDescriptor(uint8_t speed, uint16_t *length)
{
*length = String_Descriptor[USB_STRING_DESC_VENDOR].length;
return String_Descriptor[USB_STRING_DESC_VENDOR].descriptor;
}
static const uint8_t * PIOS_USBHOOK_DEV_GetProductStrDescriptor(uint8_t speed, uint16_t *length)
{
*length = String_Descriptor[USB_STRING_DESC_PRODUCT].length;
return String_Descriptor[USB_STRING_DESC_PRODUCT].descriptor;
}
static const uint8_t * PIOS_USBHOOK_DEV_GetSerialStrDescriptor(uint8_t speed, uint16_t *length)
{
*length = String_Descriptor[USB_STRING_DESC_SERIAL].length;
return String_Descriptor[USB_STRING_DESC_SERIAL].descriptor;
}
static const uint8_t * PIOS_USBHOOK_DEV_GetConfigurationStrDescriptor(uint8_t speed, uint16_t *length)
{
return NULL;
}
static const uint8_t * PIOS_USBHOOK_DEV_GetInterfaceStrDescriptor(uint8_t speed, uint16_t *length)
{
return NULL;
}
static USBD_DEVICE device_callbacks = {
.GetDeviceDescriptor = PIOS_USBHOOK_DEV_GetDeviceDescriptor,
.GetLangIDStrDescriptor = PIOS_USBHOOK_DEV_GetLangIDStrDescriptor,
.GetManufacturerStrDescriptor = PIOS_USBHOOK_DEV_GetManufacturerStrDescriptor,
.GetProductStrDescriptor = PIOS_USBHOOK_DEV_GetProductStrDescriptor,
.GetSerialStrDescriptor = PIOS_USBHOOK_DEV_GetSerialStrDescriptor,
.GetConfigurationStrDescriptor = PIOS_USBHOOK_DEV_GetConfigurationStrDescriptor,
.GetInterfaceStrDescriptor = PIOS_USBHOOK_DEV_GetInterfaceStrDescriptor,
};
static void PIOS_USBHOOK_USR_Init(void)
{
PIOS_USB_ChangeConnectionState(false);
#if 1
/* Force a physical disconnect/reconnect */
DCD_DevDisconnect(&pios_usb_otg_core_handle);
DCD_DevConnect(&pios_usb_otg_core_handle);
#endif
}
static void PIOS_USBHOOK_USR_DeviceReset(uint8_t speed)
{
PIOS_USB_ChangeConnectionState(false);
}
static void PIOS_USBHOOK_USR_DeviceConfigured(void)
{
PIOS_USB_ChangeConnectionState(true);
}
static void PIOS_USBHOOK_USR_DeviceSuspended(void)
{
/* Unhandled */
}
static void PIOS_USBHOOK_USR_DeviceResumed(void)
{
/* Unhandled */
}
static void PIOS_USBHOOK_USR_DeviceConnected(void)
{
/* NOP */
}
static void PIOS_USBHOOK_USR_DeviceDisconnected(void)
{
PIOS_USB_ChangeConnectionState(false);
}
static USBD_Usr_cb_TypeDef user_callbacks = {
.Init = PIOS_USBHOOK_USR_Init,
.DeviceReset = PIOS_USBHOOK_USR_DeviceReset,
.DeviceConfigured = PIOS_USBHOOK_USR_DeviceConfigured,
.DeviceSuspended = PIOS_USBHOOK_USR_DeviceSuspended,
.DeviceResumed = PIOS_USBHOOK_USR_DeviceResumed,
.DeviceConnected = PIOS_USBHOOK_USR_DeviceConnected,
.DeviceDisconnected = PIOS_USBHOOK_USR_DeviceDisconnected,
};
static uint8_t PIOS_USBHOOK_CLASS_Init(void *pdev, uint8_t cfgidx)
{
/* Call all of the registered init callbacks */
for (uint8_t i = 0; i < NELEMENTS(usb_if_table); i++) {
struct usb_if_entry * usb_if = &(usb_if_table[i]);
if (usb_if->ifops && usb_if->ifops->init) {
usb_if->ifops->init(usb_if->context);
}
}
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_DeInit(void *pdev, uint8_t cfgidx)
{
/* Call all of the registered deinit callbacks */
for (uint8_t i = 0; i < NELEMENTS(usb_if_table); i++) {
struct usb_if_entry * usb_if = &(usb_if_table[i]);
if (usb_if->ifops && usb_if->ifops->deinit) {
usb_if->ifops->deinit(usb_if->context);
}
}
return USBD_OK;
}
static struct usb_setup_request usb_ep0_active_req;
static uint8_t PIOS_USBHOOK_CLASS_Setup(void *pdev, USB_SETUP_REQ *req)
{
switch (req->bmRequest & (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK)) {
case (USB_REQ_TYPE_STANDARD | USB_REQ_RECIPIENT_INTERFACE):
case (USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE):
{
uint8_t ifnum = LOBYTE(req->wIndex);
if ((ifnum < NELEMENTS(usb_if_table)) &&
(usb_if_table[ifnum].ifops && usb_if_table[ifnum].ifops->setup)) {
usb_if_table[ifnum].ifops->setup(usb_if_table[ifnum].context,
(struct usb_setup_request *)req);
if (req->bmRequest & 0x80 && req->wLength > 0) {
/* Request is a host-to-device data setup packet, keep track of the request details for the EP0_RxRead call */
usb_ep0_active_req.bmRequestType = req->bmRequest;
usb_ep0_active_req.bRequest = req->bRequest;
usb_ep0_active_req.wValue = req->wValue;
usb_ep0_active_req.wIndex = req->wIndex;
usb_ep0_active_req.wLength = req->wLength;
}
} else {
/* No Setup handler or Setup handler failed */
USBD_CtlError (&pios_usb_otg_core_handle, req);
}
break;
}
default:
/* Unhandled Setup */
USBD_CtlError (&pios_usb_otg_core_handle, req);
break;
}
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_EP0_TxSent(void *pdev)
{
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_EP0_RxReady(void *pdev)
{
uint8_t ifnum = LOBYTE(usb_ep0_active_req.wIndex);
if ((ifnum < NELEMENTS(usb_if_table)) &&
(usb_if_table[ifnum].ifops && usb_if_table[ifnum].ifops->ctrl_data_out)) {
usb_if_table[ifnum].ifops->ctrl_data_out(usb_if_table[ifnum].context,
&usb_ep0_active_req);
}
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_DataIn(void *pdev, uint8_t epnum)
{
/* Make sure the previous transfer has completed before starting a new one */
DCD_EP_Flush(pdev, epnum); /* NOT SURE IF THIS IS REQUIRED */
/* Remove the direction bit so we can use this as an index */
epnum = epnum & 0xF;
if ((epnum < NELEMENTS(usb_epin_table)) && usb_epin_table[epnum].cb) {
struct usb_ep_entry *ep = &(usb_epin_table[epnum]);
ep->cb(ep->context, epnum, ep->max_len);
}
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_DataOut(void *pdev, uint8_t epnum)
{
/* Remove the direction bit so we can use this as an index */
epnum = epnum & 0xF;
if ((epnum < NELEMENTS(usb_epout_table)) && usb_epout_table[epnum].cb) {
struct usb_ep_entry *ep = &(usb_epout_table[epnum]);
ep->cb(ep->context, epnum, ep->max_len);
}
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_SOF(void *pdev)
{
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_IsoINIncomplete(void *pdev)
{
return USBD_OK;
}
static uint8_t PIOS_USBHOOK_CLASS_IsoOUTIncomplete(void *pdev)
{
return USBD_OK;
}
static const uint8_t * PIOS_USBHOOK_CLASS_GetConfigDescriptor(uint8_t speed, uint16_t *length)
{
*length = Config_Descriptor.length;
return Config_Descriptor.descriptor;
}
#ifdef USB_OTG_HS_CORE
static const uint8_t * PIOS_USBHOOK_CLASS_GetOtherConfigDescriptor(uint8_t speed, uint16_t *length)
{
return PIOS_USBHOOK_CLASS_GetConfigDescriptor(speed, length);
}
#endif /* USB_OTG_HS_CORE */
#ifdef USB_SUPPORT_USER_STRING_DESC
static const uint8_t * PIOS_USBHOOK_CLASS_GetUsrStrDescriptor(uint8_t speed, uint8_t index, uint16_t *length)
{
return NULL;
}
#endif /* USB_SUPPORT_USER_STRING_DESC */
static USBD_Class_cb_TypeDef class_callbacks = {
.Init = PIOS_USBHOOK_CLASS_Init,
.DeInit = PIOS_USBHOOK_CLASS_DeInit,
.Setup = PIOS_USBHOOK_CLASS_Setup,
.EP0_TxSent = PIOS_USBHOOK_CLASS_EP0_TxSent,
.EP0_RxReady = PIOS_USBHOOK_CLASS_EP0_RxReady,
.DataIn = PIOS_USBHOOK_CLASS_DataIn,
.DataOut = PIOS_USBHOOK_CLASS_DataOut,
.SOF = PIOS_USBHOOK_CLASS_SOF,
.IsoINIncomplete = PIOS_USBHOOK_CLASS_IsoINIncomplete,
.IsoOUTIncomplete = PIOS_USBHOOK_CLASS_IsoOUTIncomplete,
.GetConfigDescriptor = PIOS_USBHOOK_CLASS_GetConfigDescriptor,
#ifdef USB_OTG_HS_CORE
.GetOtherConfigDescriptor = PIOS_USBHOOK_CLASS_GetOtherConfigDescriptor,
#endif /* USB_OTG_HS_CORE */
#ifdef USB_SUPPORT_USER_STRING_DESC
.GetUsrStrDescriptor = PIOS_USBHOOK_CLASS_GetUsrStrDescriptor,
#endif /* USB_SUPPORT_USER_STRING_DESC */
};
#if 0
#include "stm32f10x.h" /* __IO */
__IO uint8_t EXTI_Enable;
uint32_t ProtocolValue;
DEVICE Device_Table = {
PIOS_USB_BOARD_EP_NUM,
1
};
static void PIOS_USBHOOK_Init(void);
static void PIOS_USBHOOK_Reset(void);
static void PIOS_USBHOOK_Status_In(void);
static void PIOS_USBHOOK_Status_Out(void);
static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo);
static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo);
static RESULT PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length);
static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length);
static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length);
DEVICE_PROP Device_Property = {
.Init = PIOS_USBHOOK_Init,
.Reset = PIOS_USBHOOK_Reset,
.Process_Status_IN = PIOS_USBHOOK_Status_In,
.Process_Status_OUT = PIOS_USBHOOK_Status_Out,
.Class_Data_Setup = PIOS_USBHOOK_Data_Setup,
.Class_NoData_Setup = PIOS_USBHOOK_NoData_Setup,
.Class_Get_Interface_Setting = PIOS_USBHOOK_Get_Interface_Setting,
.GetDeviceDescriptor = PIOS_USBHOOK_GetDeviceDescriptor,
.GetConfigDescriptor = PIOS_USBHOOK_GetConfigDescriptor,
.GetStringDescriptor = PIOS_USBHOOK_GetStringDescriptor,
.RxEP_buffer = 0,
.MaxPacketSize = 0x40,
};
static void PIOS_USBHOOK_SetConfiguration(void);
static void PIOS_USBHOOK_SetDeviceAddress(void);
USER_STANDARD_REQUESTS User_Standard_Requests = {
.User_GetConfiguration = NOP_Process,
.User_SetConfiguration = PIOS_USBHOOK_SetConfiguration,
.User_GetInterface = NOP_Process,
.User_SetInterface = NOP_Process,
.User_GetStatus = NOP_Process,
.User_ClearFeature = NOP_Process,
.User_SetEndPointFeature = NOP_Process,
.User_SetDeviceFeature = NOP_Process,
.User_SetDeviceAddress = PIOS_USBHOOK_SetDeviceAddress
};
static RESULT PIOS_USBHOOK_SetProtocol(void);
static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length);
static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length);
static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length);
/*******************************************************************************
* Function Name : PIOS_USBHOOK_Init.
* Description : Custom HID init routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void PIOS_USBHOOK_Init(void)
{
pInformation->Current_Configuration = 0;
/* Connect the device */
PowerOn();
/* Perform basic device initialization operations */
USB_SIL_Init();
bDeviceState = UNCONNECTED;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_Reset.
* Description : Custom HID reset routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void PIOS_USBHOOK_Reset(void)
{
/* Set DEVICE as not configured */
pInformation->Current_Configuration = 0;
pInformation->Current_Interface = 0; /*the default Interface */
/* Current Feature initialization */
pInformation->Current_Feature = 0;
#ifdef STM32F10X_CL
/* EP0 is already configured in DFU_Init() by USB_SIL_Init() function */
/* Init EP1 IN as Interrupt endpoint */
OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_INT, 2);
/* Init EP1 OUT as Interrupt endpoint */
OTG_DEV_EP_Init(EP1_OUT, OTG_DEV_EP_TYPE_INT, 2);
#else
SetBTABLE(BTABLE_ADDRESS);
/* Initialize Endpoint 0 (Control) */
SetEPType(ENDP0, EP_CONTROL);
SetEPTxAddr(ENDP0, ENDP0_TXADDR);
SetEPTxStatus(ENDP0, EP_TX_STALL);
Clear_Status_Out(ENDP0);
SetEPRxAddr(ENDP0, ENDP0_RXADDR);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
SetEPRxValid(ENDP0);
#if defined(PIOS_INCLUDE_USB_HID)
/* Initialize Endpoint 1 (HID) */
SetEPType(ENDP1, EP_INTERRUPT);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxCount(ENDP1, PIOS_USB_BOARD_HID_DATA_LENGTH);
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxAddr(ENDP1, ENDP1_RXADDR);
SetEPRxCount(ENDP1, PIOS_USB_BOARD_HID_DATA_LENGTH);
SetEPRxStatus(ENDP1, EP_RX_VALID);
#endif /* PIOS_INCLUDE_USB_HID */
#if defined(PIOS_INCLUDE_USB_CDC)
/* Initialize Endpoint 2 (CDC Call Control) */
SetEPType(ENDP2, EP_INTERRUPT);
SetEPTxAddr(ENDP2, ENDP2_TXADDR);
SetEPTxStatus(ENDP2, EP_TX_NAK);
SetEPRxAddr(ENDP2, ENDP2_RXADDR);
SetEPRxCount(ENDP2, PIOS_USB_BOARD_CDC_MGMT_LENGTH);
SetEPRxStatus(ENDP2, EP_RX_DIS);
/* Initialize Endpoint 3 (CDC Data) */
SetEPType(ENDP3, EP_BULK);
SetEPTxAddr(ENDP3, ENDP3_TXADDR);
SetEPTxStatus(ENDP3, EP_TX_NAK);
SetEPRxAddr(ENDP3, ENDP3_RXADDR);
SetEPRxCount(ENDP3, PIOS_USB_BOARD_CDC_DATA_LENGTH);
SetEPRxStatus(ENDP3, EP_RX_VALID);
#endif /* PIOS_INCLUDE_USB_CDC */
/* Set this device to response on default address */
SetDeviceAddress(0);
#endif /* STM32F10X_CL */
bDeviceState = ATTACHED;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_SetConfiguration.
* Description : Update the device state to configured
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void PIOS_USBHOOK_SetConfiguration(void)
{
if (pInformation->Current_Configuration != 0) {
/* Device configured */
bDeviceState = CONFIGURED;
}
/* Enable transfers */
PIOS_USB_ChangeConnectionState(pInformation->Current_Configuration != 0);
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_SetConfiguration.
* Description : Update the device state to addressed.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void PIOS_USBHOOK_SetDeviceAddress(void)
{
bDeviceState = ADDRESSED;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_Status_In.
* Description : status IN routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void PIOS_USBHOOK_Status_In(void)
{
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_Status_Out
* Description : status OUT routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void PIOS_USBHOOK_Status_Out(void)
{
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_Data_Setup
* Description : Handle the data class specific requests.
* Input : Request Nb.
* Output : None.
* Return : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
static RESULT PIOS_USBHOOK_Data_Setup(uint8_t RequestNo)
{
const uint8_t *(*CopyRoutine) (uint16_t);
CopyRoutine = NULL;
switch (Type_Recipient) {
case (STANDARD_REQUEST | INTERFACE_RECIPIENT):
switch (pInformation->USBwIndex0) {
case 0: /* HID Interface */
switch (RequestNo) {
case GET_DESCRIPTOR:
switch (pInformation->USBwValue1) {
case USB_DESC_TYPE_REPORT:
CopyRoutine = PIOS_USBHOOK_GetReportDescriptor;
break;
case USB_DESC_TYPE_HID:
CopyRoutine = PIOS_USBHOOK_GetHIDDescriptor;
break;
}
}
}
break;
case (CLASS_REQUEST | INTERFACE_RECIPIENT):
switch (pInformation->USBwIndex0) {
case 0: /* HID Interface */
switch (RequestNo) {
case GET_PROTOCOL:
CopyRoutine = PIOS_USBHOOK_GetProtocolValue;
break;
}
break;
#if defined(PIOS_INCLUDE_USB_CDC)
case 1: /* CDC Call Control Interface */
switch (RequestNo) {
case GET_LINE_CODING:
CopyRoutine = PIOS_USB_CDC_GetLineCoding;
break;
}
break;
case 2: /* CDC Data Interface */
switch (RequestNo) {
case 0:
break;
}
break;
#endif /* PIOS_INCLUDE_USB_CDC */
}
break;
}
if (CopyRoutine == NULL) {
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyDataIn = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine) (0);
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_NoData_Setup
* Description : handle the no data class specific requests
* Input : Request Nb.
* Output : None.
* Return : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
static RESULT PIOS_USBHOOK_NoData_Setup(uint8_t RequestNo)
{
switch (Type_Recipient) {
case (CLASS_REQUEST | INTERFACE_RECIPIENT):
switch (pInformation->USBwIndex0) {
case 0: /* HID */
switch (RequestNo) {
case SET_PROTOCOL:
return PIOS_USBHOOK_SetProtocol();
break;
}
break;
#if defined(PIOS_INCLUDE_USB_CDC)
case 1: /* CDC Call Control Interface */
switch (RequestNo) {
case SET_LINE_CODING:
return PIOS_USB_CDC_SetLineCoding();
break;
case SET_CONTROL_LINE_STATE:
return PIOS_USB_CDC_SetControlLineState();
break;
}
break;
#endif /* PIOS_INCLUDE_USB_CDC */
}
break;
}
return USB_UNSUPPORT;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_GetDeviceDescriptor.
* Description : Gets the device descriptor.
* Input : Length
* Output : None.
* Return : The address of the device descriptor.
*******************************************************************************/
static const uint8_t *PIOS_USBHOOK_GetDeviceDescriptor(uint16_t Length)
{
return Standard_GetDescriptorData(Length, &Device_Descriptor);
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_GetConfigDescriptor.
* Description : Gets the configuration descriptor.
* Input : Length
* Output : None.
* Return : The address of the configuration descriptor.
*******************************************************************************/
static const uint8_t *PIOS_USBHOOK_GetConfigDescriptor(uint16_t Length)
{
return Standard_GetDescriptorData(Length, &Config_Descriptor);
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_GetStringDescriptor
* Description : Gets the string descriptors according to the needed index
* Input : Length
* Output : None.
* Return : The address of the string descriptors.
*******************************************************************************/
static const uint8_t *PIOS_USBHOOK_GetStringDescriptor(uint16_t Length)
{
uint8_t wValue0 = pInformation->USBwValue0;
if (wValue0 > 4) {
return NULL;
} else {
return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
}
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_GetReportDescriptor.
* Description : Gets the HID report descriptor.
* Input : Length
* Output : None.
* Return : The address of the configuration descriptor.
*******************************************************************************/
static const uint8_t *PIOS_USBHOOK_GetReportDescriptor(uint16_t Length)
{
return Standard_GetDescriptorData(Length, &Hid_Report_Descriptor);
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_GetHIDDescriptor.
* Description : Gets the HID descriptor.
* Input : Length
* Output : None.
* Return : The address of the configuration descriptor.
*******************************************************************************/
static const uint8_t *PIOS_USBHOOK_GetHIDDescriptor(uint16_t Length)
{
return Standard_GetDescriptorData(Length, &Hid_Interface_Descriptor);
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_Get_Interface_Setting.
* Description : tests the interface and the alternate setting according to the
* supported one.
* Input : - Interface : interface number.
* - AlternateSetting : Alternate Setting number.
* Output : None.
* Return : USB_SUCCESS or USB_UNSUPPORT.
*******************************************************************************/
static RESULT PIOS_USBHOOK_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
{
if (AlternateSetting > 0) {
return USB_UNSUPPORT;
} else if (Interface > 0) {
return USB_UNSUPPORT;
}
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_SetProtocol
* Description : Set Protocol request routine.
* Input : None.
* Output : None.
* Return : USB SUCCESS.
*******************************************************************************/
static RESULT PIOS_USBHOOK_SetProtocol(void)
{
uint8_t wValue0 = pInformation->USBwValue0;
ProtocolValue = wValue0;
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : PIOS_USBHOOK_GetProtocolValue
* Description : get the protocol value
* Input : Length.
* Output : None.
* Return : address of the protcol value.
*******************************************************************************/
static const uint8_t *PIOS_USBHOOK_GetProtocolValue(uint16_t Length)
{
if (Length == 0) {
pInformation->Ctrl_Info.Usb_wLength = 1;
return NULL;
} else {
return (uint8_t *) (&ProtocolValue);
}
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
#endif

View File

@ -30,9 +30,11 @@
#ifndef PIOS_USB_H
#define PIOS_USB_H
#include <stdbool.h>
/* Global functions */
extern int32_t PIOS_USB_Reenumerate();
extern int32_t PIOS_USB_ChangeConnectionState(uint32_t Connected);
extern int32_t PIOS_USB_ChangeConnectionState(bool connected);
extern bool PIOS_USB_CheckAvailable(uint8_t id);
#endif /* PIOS_USB_H */

View File

@ -31,8 +31,6 @@
#ifndef PIOS_USB_CDC_PRIV_H
#define PIOS_USB_CDC_PRIV_H
#include "usb_core.h" /* RESULT */
struct pios_usb_cdc_cfg {
uint8_t ctrl_if;
uint8_t ctrl_tx_ep;
@ -46,10 +44,6 @@ extern const struct pios_com_driver pios_usb_cdc_com_driver;
extern int32_t PIOS_USB_CDC_Init(uint32_t * usbcdc_id, const struct pios_usb_cdc_cfg * cfg, uint32_t lower_id);
extern const uint8_t *PIOS_USB_CDC_GetLineCoding(uint16_t Length);
extern RESULT PIOS_USB_CDC_SetControlLineState(void);
extern RESULT PIOS_USB_CDC_SetLineCoding(void);
#endif /* PIOS_USB_CDC_PRIV_H */
/**

View File

@ -219,6 +219,57 @@ struct usb_endpoint_desc {
uint8_t bInterval;
} __attribute__((packed));
struct usb_setup_request {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__((packed));
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_MASK 0x60
#define USB_REQ_RECIPIENT_DEVICE 0x00
#define USB_REQ_RECIPIENT_INTERFACE 0x01
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
#define USB_REQ_RECIPIENT_MASK 0x03
enum usb_standard_requests {
USB_REQ_GET_STATUS = 0x00,
USB_REQ_CLEAR_FEATURE = 0x01,
/* what is 0x02? */
USB_REQ_SET_FEATURE = 0x03,
/* what is 0x04? */
USB_REQ_SET_ADDRESS = 0x05,
USB_REQ_GET_DESCRIPTOR = 0x06,
USB_REQ_SET_DESCRIPTOR = 0x07,
USB_REQ_GET_CONFIGURATION = 0x08,
USB_REQ_SET_CONFIGURATION = 0x09,
USB_REQ_GET_INTERFACE = 0x0A,
USB_REQ_SET_INTERFACE = 0x0B,
USB_REQ_SYNCH_FRAME = 0x0C,
};
enum usb_hid_requests {
USB_HID_REQ_GET_REPORT = 0x01,
USB_HID_REQ_GET_IDLE = 0x02,
USB_HID_REQ_GET_PROTOCOL = 0x03,
/* 0x04-0x08 Reserved */
USB_HID_REQ_SET_REPORT = 0x09,
USB_HID_REQ_SET_IDLE = 0x0A,
USB_HID_REQ_SET_PROTOCOL = 0x0B,
};
enum usb_cdc_requests {
USB_CDC_REQ_SET_LINE_CODING = 0x20,
USB_CDC_REQ_GET_LINE_CODING = 0x21,
USB_CDC_REQ_SET_CONTROL_LINE_STATE = 0x23,
};
struct usb_cdc_header_func_desc {
uint8_t bLength;
uint8_t bDescriptorType;
@ -301,6 +352,10 @@ enum usb_product_ids {
USB_PRODUCT_ID_OPENPILOT_MAIN = 0x415A,
USB_PRODUCT_ID_COPTERCONTROL = 0x415B,
USB_PRODUCT_ID_PIPXTREME = 0x415C,
USB_PRODUCT_ID_CC3D = 0x415D,
USB_PRODUCT_ID_REVOLUTION = 0x415E,
USB_PRODUCT_ID_OSD = 0x4194,
USB_PRODUCT_ID_SPARE = 0x4195,
} __attribute__((packed));
enum usb_op_board_ids {
@ -308,6 +363,7 @@ enum usb_op_board_ids {
/* Board ID 2 may be unused or AHRS */
USB_OP_BOARD_ID_PIPXTREME = 3,
USB_OP_BOARD_ID_COPTERCONTROL = 4,
USB_OP_BOARD_ID_REVOLUTION = 5,
} __attribute__((packed));
enum usb_op_board_modes {

View File

@ -31,10 +31,13 @@
#define PIOS_USB_HID_H
/* Global functions */
extern int32_t PIOS_USB_HID_Reenumerate();
extern int32_t PIOS_USB_HID_Reenumerate(void);
extern int32_t PIOS_USB_HID_ChangeConnectionState(uint32_t Connected);
extern bool PIOS_USB_HID_CheckAvailable(uint8_t id);
extern void PIOS_USB_HID_RegisterHidInterface(const uint8_t * desc, uint16_t length);
extern void PIOS_USB_HID_RegisterHidReport(const uint8_t * desc, uint16_t length);
#endif /* PIOS_USB_HID_H */
/**

View File

@ -31,8 +31,6 @@
#ifndef PIOS_USB_HID_PRIV_H
#define PIOS_USB_HID_PRIV_H
#include "usb_core.h" /* RESULT */
struct pios_usb_hid_cfg {
uint8_t data_if;
uint8_t data_rx_ep;

View File

@ -17,6 +17,8 @@
#ifndef __USB_PWR_H
#define __USB_PWR_H
#include "usb_core.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RESUME_STATE {

View File

@ -31,21 +31,14 @@
#ifndef PIOS_USBHOOK_H
#define PIOS_USBHOOK_H
typedef enum _HID_REQUESTS {
GET_REPORT = 1,
GET_IDLE,
GET_PROTOCOL,
#include <stdbool.h>
#include <stdint.h>
#include "pios_usb_defs.h" /* usb_setup_request */
SET_REPORT = 9,
SET_IDLE,
SET_PROTOCOL
} HID_REQUESTS;
typedef enum CDC_REQUESTS {
SET_LINE_CODING = 0x20,
GET_LINE_CODING = 0x21,
SET_CONTROL_LINE_STATE = 0x23,
} CDC_REQUESTS;
struct pios_usbhook_descriptor {
const uint8_t * descriptor;
uint16_t length;
};
enum usb_string_desc {
USB_STRING_DESC_LANG = 0,
@ -57,8 +50,28 @@ enum usb_string_desc {
extern void PIOS_USBHOOK_RegisterDevice(const uint8_t * desc, uint16_t desc_size);
extern void PIOS_USBHOOK_RegisterConfig(uint8_t config_id, const uint8_t * desc, uint16_t desc_size);
extern void PIOS_USBHOOK_RegisterString(enum usb_string_desc string_id, const uint8_t * desc, uint16_t desc_size);
extern void PIOS_USBHOOK_RegisterHidInterface(const uint8_t * desc, uint16_t desc_size);
extern void PIOS_USBHOOK_RegisterHidReport(const uint8_t * desc, uint16_t desc_size);
struct pios_usb_ifops {
void (*init)(uint32_t context);
void (*deinit)(uint32_t context);
bool (*setup)(uint32_t context, struct usb_setup_request * req);
void (*ctrl_data_out)(uint32_t context, struct usb_setup_request * req);
};
extern void PIOS_USBHOOK_RegisterIfOps(uint8_t ifnum, struct pios_usb_ifops * ifops, uint32_t context);
typedef bool (*pios_usbhook_epcb)(uint32_t context, uint8_t epnum, uint16_t len);
extern void PIOS_USBHOOK_RegisterEpInCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uint32_t context);
extern void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_usbhook_epcb cb, uint32_t context);
extern void PIOS_USBHOOK_DeRegisterEpInCallback(uint8_t epnum);
extern void PIOS_USBHOOK_DeRegisterEpOutCallback(uint8_t epnum);
extern void PIOS_USBHOOK_CtrlTx(const uint8_t *buf, uint16_t len);
extern void PIOS_USBHOOK_CtrlRx(uint8_t *buf, uint16_t len);
extern void PIOS_USBHOOK_EndpointTx(uint8_t epnum, const uint8_t *buf, uint16_t len);
extern void PIOS_USBHOOK_EndpointRx(uint8_t epnum, uint8_t *buf, uint16_t len);
extern void PIOS_USBHOOK_Activate(void);
#endif /* PIOS_USBHOOK_H */

View File

@ -149,8 +149,6 @@
#endif
#if defined(PIOS_INCLUDE_USB)
/* USB Libs */
#include <usb_lib.h>
#include <pios_usb.h>
#endif

View File

@ -30,5 +30,5 @@ target create $_TARGETNAME stm32_stlink -chain-position $_TARGETNAME -rtos auto
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stm32f2x 0x08000000 0 0 0 $_TARGETNAME
#set _FLASHNAME $_CHIPNAME.flash
#flash bank $_FLASHNAME stm32f2x 0x08000000 0 0 0 $_TARGETNAME

View File

@ -117,6 +117,7 @@ SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}}
SRC += ${OPMODULEDIR}/System/systemmod.c
SRC += $(OPSYSTEM)/revolution.c
SRC += $(OPSYSTEM)/pios_board.c
SRC += $(OPSYSTEM)/pios_usb_board_data.c
SRC += $(OPSYSTEM)/alarms.c
SRC += $(OPUAVTALK)/uavtalk.c
SRC += $(OPUAVOBJ)/uavobjectmanager.c
@ -148,6 +149,8 @@ SRC += $(PIOSCOMMON)/pios_rcvr.c
SRC += $(PIOSCOMMON)/pios_flash_jedec.c
SRC += $(PIOSCOMMON)/pios_flashfs_objlist.c
SRC += $(PIOSCOMMON)/printf-stdarg.c
SRC += $(PIOSCOMMON)/pios_usb_desc_hid_cdc.c
SRC += $(PIOSCOMMON)/pios_usb_desc_hid_only.c
include ./UAVObjects.inc
SRC += $(UAVOBJSRC)
@ -312,7 +315,7 @@ ifeq ($(CODE_SOURCERY), YES)
CFLAGS += -fpromote-loop-indices
endif
#CFLAGS += -Wall
CFLAGS += -Wall
#CFLAGS += -Werror
CFLAGS += -Wa,-adhlns=$(addprefix $(OUTDIR)/, $(notdir $(addsuffix .lst, $(basename $<))))
# Compiler flags to generate dependency files:

View File

@ -49,7 +49,8 @@
#define PIOS_INCLUDE_SPI
#define PIOS_INCLUDE_SYS
#define PIOS_INCLUDE_USART
//#define PIOS_INCLUDE_USB_HID
#define PIOS_INCLUDE_USB
#define PIOS_INCLUDE_USB_HID
//#define PIOS_INCLUDE_GPIO
#define PIOS_INCLUDE_EXTI
#define PIOS_INCLUDE_RTC

View File

@ -0,0 +1,45 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB_BOARD Board specific USB definitions
* @brief Board specific USB definitions
* @{
*
* @file pios_usb_board_data.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Board specific USB definitions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_USB_BOARD_DATA_H
#define PIOS_USB_BOARD_DATA_H
#define PIOS_USB_BOARD_CDC_DATA_LENGTH 64
#define PIOS_USB_BOARD_CDC_MGMT_LENGTH 32
#define PIOS_USB_BOARD_HID_DATA_LENGTH 64
#define PIOS_USB_BOARD_EP_NUM 4
#include "pios_usb_defs.h" /* USB_* macros */
#define PIOS_USB_BOARD_PRODUCT_ID USB_PRODUCT_ID_REVOLUTION
#define PIOS_USB_BOARD_DEVICE_VER USB_OP_DEVICE_VER(USB_OP_BOARD_ID_REVOLUTION, USB_OP_BOARD_MODE_FW)
#endif /* PIOS_USB_BOARD_DATA_H */

View File

@ -251,6 +251,12 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE];
#define PIOS_COM_GPS_RX_BUF_LEN 32
#define PIOS_COM_TELEM_USB_RX_BUF_LEN 65
#define PIOS_COM_TELEM_USB_TX_BUF_LEN 65
#define PIOS_COM_BRIDGE_RX_BUF_LEN 65
#define PIOS_COM_BRIDGE_TX_BUF_LEN 12
uint32_t pios_com_aux_id;
uint32_t pios_com_gps_id;
uint32_t pios_com_telem_usb_id;
@ -321,7 +327,137 @@ void PIOS_Board_Init(void) {
/* IAP System Setup */
//PIOS_IAP_Init();
#if defined(PIOS_INCLUDE_USB)
/* Initialize board specific USB data */
PIOS_USB_BOARD_DATA_Init();
/* Flags to determine if various USB interfaces are advertised */
bool usb_hid_present = false;
bool usb_cdc_present = false;
uint8_t hwsettings_usb_devicetype;
HwSettingsUSB_DeviceTypeGet(&hwsettings_usb_devicetype);
switch (hwsettings_usb_devicetype) {
case HWSETTINGS_USB_DEVICETYPE_HIDONLY:
if (PIOS_USB_DESC_HID_ONLY_Init()) {
PIOS_Assert(0);
}
usb_hid_present = true;
break;
case HWSETTINGS_USB_DEVICETYPE_HIDVCP:
if (PIOS_USB_DESC_HID_CDC_Init()) {
PIOS_Assert(0);
}
usb_hid_present = true;
usb_cdc_present = true;
break;
case HWSETTINGS_USB_DEVICETYPE_VCPONLY:
break;
default:
PIOS_Assert(0);
}
uint32_t pios_usb_id;
PIOS_USB_Init(&pios_usb_id, &pios_usb_main_cfg);
#if defined(PIOS_INCLUDE_USB_CDC)
uint8_t hwsettings_usb_vcpport;
/* Configure the USB VCP port */
HwSettingsUSB_VCPPortGet(&hwsettings_usb_vcpport);
if (!usb_cdc_present) {
/* Force VCP port function to disabled if we haven't advertised VCP in our USB descriptor */
hwsettings_usb_vcpport = HWSETTINGS_USB_VCPPORT_DISABLED;
}
switch (hwsettings_usb_vcpport) {
case HWSETTINGS_USB_VCPPORT_DISABLED:
break;
case HWSETTINGS_USB_VCPPORT_USBTELEMETRY:
#if defined(PIOS_INCLUDE_COM)
{
uint32_t pios_usb_cdc_id;
if (PIOS_USB_CDC_Init(&pios_usb_cdc_id, &pios_usb_cdc_cfg, pios_usb_id)) {
PIOS_Assert(0);
}
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_USB_RX_BUF_LEN);
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_USB_TX_BUF_LEN);
PIOS_Assert(rx_buffer);
PIOS_Assert(tx_buffer);
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id,
rx_buffer, PIOS_COM_TELEM_USB_RX_BUF_LEN,
tx_buffer, PIOS_COM_TELEM_USB_TX_BUF_LEN)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_COM */
break;
case HWSETTINGS_USB_VCPPORT_COMBRIDGE:
#if defined(PIOS_INCLUDE_COM)
{
uint32_t pios_usb_cdc_id;
if (PIOS_USB_CDC_Init(&pios_usb_cdc_id, &pios_usb_cdc_cfg, pios_usb_id)) {
PIOS_Assert(0);
}
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_BRIDGE_RX_BUF_LEN);
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_BRIDGE_TX_BUF_LEN);
PIOS_Assert(rx_buffer);
PIOS_Assert(tx_buffer);
if (PIOS_COM_Init(&pios_com_vcp_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id,
rx_buffer, PIOS_COM_BRIDGE_RX_BUF_LEN,
tx_buffer, PIOS_COM_BRIDGE_TX_BUF_LEN)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_COM */
break;
}
#endif /* PIOS_INCLUDE_USB_CDC */
#if defined(PIOS_INCLUDE_USB_HID)
/* Configure the usb HID port */
uint8_t hwsettings_usb_hidport;
HwSettingsUSB_HIDPortGet(&hwsettings_usb_hidport);
if (!usb_hid_present) {
/* Force HID port function to disabled if we haven't advertised HID in our USB descriptor */
hwsettings_usb_hidport = HWSETTINGS_USB_HIDPORT_DISABLED;
}
switch (hwsettings_usb_hidport) {
case HWSETTINGS_USB_HIDPORT_DISABLED:
break;
case HWSETTINGS_USB_HIDPORT_USBTELEMETRY:
#if defined(PIOS_INCLUDE_COM)
{
uint32_t pios_usb_hid_id;
if (PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_cfg, pios_usb_id)) {
PIOS_Assert(0);
}
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_USB_RX_BUF_LEN);
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_USB_TX_BUF_LEN);
PIOS_Assert(rx_buffer);
PIOS_Assert(tx_buffer);
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_hid_com_driver, pios_usb_hid_id,
rx_buffer, PIOS_COM_TELEM_USB_RX_BUF_LEN,
tx_buffer, PIOS_COM_TELEM_USB_TX_BUF_LEN)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_COM */
break;
}
#endif /* PIOS_INCLUDE_USB_HID */
if (usb_hid_present || usb_cdc_present) {
PIOS_USBHOOK_Activate();
}
#endif /* PIOS_INCLUDE_USB */
#if defined(PIOS_INCLUDE_COM)
#if defined(PIOS_INCLUDE_GPS)

View File

@ -0,0 +1,120 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_USB_BOARD Board specific USB definitions
* @brief Board specific USB definitions
* @{
*
* @file pios_usb_board_data.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Board specific USB definitions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "pios_usb_board_data.h" /* struct usb_*, USB_* */
#include "pios_sys.h" /* PIOS_SYS_SerialNumberGet */
#include "pios_usbhook.h" /* PIOS_USBHOOK_* */
static const uint8_t usb_product_id[22] = {
sizeof(usb_product_id),
USB_DESC_TYPE_STRING,
'R', 0,
'e', 0,
'v', 0,
'o', 0,
'l', 0,
'u', 0,
't', 0,
'i', 0,
'o', 0,
'n', 0,
};
static uint8_t usb_serial_number[52] = {
sizeof(usb_serial_number),
USB_DESC_TYPE_STRING,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0
};
static const struct usb_string_langid usb_lang_id = {
.bLength = sizeof(usb_lang_id),
.bDescriptorType = USB_DESC_TYPE_STRING,
.bLangID = htousbs(USB_LANGID_ENGLISH_UK),
};
static const uint8_t usb_vendor_id[28] = {
sizeof(usb_vendor_id),
USB_DESC_TYPE_STRING,
'o', 0,
'p', 0,
'e', 0,
'n', 0,
'p', 0,
'i', 0,
'l', 0,
'o', 0,
't', 0,
'.', 0,
'o', 0,
'r', 0,
'g', 0
};
int32_t PIOS_USB_BOARD_DATA_Init(void)
{
/* Load device serial number into serial number string */
uint8_t sn[25];
PIOS_SYS_SerialNumberGet((char *)sn);
for (uint8_t i = 0; sn[i] != '\0' && (2 * i) < usb_serial_number[0]; i++) {
usb_serial_number[2 + 2 * i] = sn[i];
}
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_PRODUCT, (uint8_t *)&usb_product_id, sizeof(usb_product_id));
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_SERIAL, (uint8_t *)&usb_serial_number, sizeof(usb_serial_number));
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_LANG, (uint8_t *)&usb_lang_id, sizeof(usb_lang_id));
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_VENDOR, (uint8_t *)&usb_vendor_id, sizeof(usb_vendor_id));
return 0;
}

View File

@ -1416,5 +1416,61 @@ static const struct pios_ppm_cfg pios_ppm_cfg = {
#endif
#if defined(PIOS_INCLUDE_USB)
#include "pios_usb_priv.h"
static const struct pios_usb_cfg pios_usb_main_cfg = {
.irq = {
.init = {
.NVIC_IRQChannel = OTG_FS_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
.NVIC_IRQChannelSubPriority = 3,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.vsense = {
.gpio = GPIOD,
.init = {
.GPIO_Pin = GPIO_Pin_11,
.GPIO_Speed = GPIO_Speed_25MHz,
.GPIO_Mode = GPIO_Mode_IN,
.GPIO_OType = GPIO_OType_OD,
},
}
};
#include "pios_usb_board_data_priv.h"
#include "pios_usb_desc_hid_cdc_priv.h"
#include "pios_usb_desc_hid_only_priv.h"
#include "pios_usbhook.h"
#endif /* PIOS_INCLUDE_USB */
#if defined(PIOS_INCLUDE_COM_MSG)
#include <pios_com_msg_priv.h>
#endif /* PIOS_INCLUDE_COM_MSG */
#if defined(PIOS_INCLUDE_USB_HID)
#include <pios_usb_hid_priv.h>
const struct pios_usb_hid_cfg pios_usb_hid_cfg = {
.data_if = 0,
.data_rx_ep = 1,
.data_tx_ep = 1,
};
#endif /* PIOS_INCLUDE_USB_HID */
#if defined(PIOS_INCLUDE_USB_CDC)
#include <pios_usb_cdc_priv.h>
const struct pios_usb_cdc_cfg pios_usb_cdc_cfg = {
.ctrl_if = 1,
.ctrl_tx_ep = 2,
.data_if = 2,
.data_rx_ep = 3,
.data_tx_ep = 3,
};
#endif /* PIOS_INCLUDE_USB_CDC */