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:
parent
8b73ae7d16
commit
e2939dae2a
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
51
flight/Bootloaders/Revolution/inc/pios_usb_board_data.h
Normal file
51
flight/Bootloaders/Revolution/inc/pios_usb_board_data.h
Normal 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 */
|
@ -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;
|
||||
}
|
||||
|
120
flight/Bootloaders/Revolution/pios_usb_board_data.c
Normal file
120
flight/Bootloaders/Revolution/pios_usb_board_data.c
Normal 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;
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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_ */
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
290
flight/PiOS/STM32F4xx/pios_usb.c
Normal file
290
flight/PiOS/STM32F4xx/pios_usb.c
Normal 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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
400
flight/PiOS/STM32F4xx/pios_usb_cdc.c
Normal file
400
flight/PiOS/STM32F4xx/pios_usb_cdc.c
Normal 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 */
|
497
flight/PiOS/STM32F4xx/pios_usb_hid.c
Normal file
497
flight/PiOS/STM32F4xx/pios_usb_hid.c
Normal 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 */
|
897
flight/PiOS/STM32F4xx/pios_usbhook.c
Normal file
897
flight/PiOS/STM32F4xx/pios_usbhook.c
Normal 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
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
/**
|
||||
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -17,6 +17,8 @@
|
||||
#ifndef __USB_PWR_H
|
||||
#define __USB_PWR_H
|
||||
|
||||
#include "usb_core.h"
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef enum _RESUME_STATE {
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -149,8 +149,6 @@
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
/* USB Libs */
|
||||
#include <usb_lib.h>
|
||||
#include <pios_usb.h>
|
||||
#endif
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
45
flight/Revolution/System/inc/pios_usb_board_data.h
Normal file
45
flight/Revolution/System/inc/pios_usb_board_data.h
Normal 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 */
|
@ -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)
|
||||
|
||||
|
120
flight/Revolution/System/pios_usb_board_data.c
Normal file
120
flight/Revolution/System/pios_usb_board_data.c
Normal 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;
|
||||
}
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user