1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-18 08:54:15 +01:00

Merge branch 'steve/OP-1849_flexio_com_bridge' into next

This commit is contained in:
abeck70 2015-05-14 17:25:21 +10:00
commit c51bca44be
10 changed files with 157 additions and 8 deletions

View File

@ -43,6 +43,7 @@
static void com2UsbBridgeTask(void *parameters);
static void usb2ComBridgeTask(void *parameters);
static void updateSettings(UAVObjEvent *ev);
static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state);
// ****************
// Private constants
@ -95,8 +96,16 @@ static int32_t comUsbBridgeStart(void)
static int32_t comUsbBridgeInitialize(void)
{
// TODO: Get from settings object
usart_port = PIOS_COM_BRIDGE;
vcp_port = PIOS_COM_VCP;
usart_port = PIOS_COM_BRIDGE;
vcp_port = PIOS_COM_VCP;
// Register the call back handler for USB control line changes to simply
// pass these onto any handler registered on the USART
if (vcp_port) {
PIOS_COM_RegisterCtrlLineCallback(vcp_port,
usb2ComBridgeSetCtrlLine,
usart_port);
}
#ifdef MODULE_COMUSBBRIDGE_BUILTIN
bridge_enabled = true;
@ -168,6 +177,14 @@ static void usb2ComBridgeTask(__attribute__((unused)) void *parameters)
}
}
/* This routine is registered with the USB driver and will be called in the
* event of a control line state change. It will then call down to the USART
* driver to drive the required control line state.
*/
static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state)
{
PIOS_COM_SetCtrlLine(com_id, mask, state);
}
static void updateSettings(__attribute__((unused)) UAVObjEvent *ev)
{

View File

@ -283,6 +283,56 @@ int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud)
return 0;
}
/**
* Set control lines associated with the port
* \param[in] port COM port
* \param[in] mask Lines to change
* \param[in] state New state for lines
* \return -1 if port not available
* \return 0 on success
*/
int32_t PIOS_COM_SetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state)
{
struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id;
if (!PIOS_COM_validate(com_dev)) {
/* Undefined COM port for this board (see pios_board.c) */
return -1;
}
/* Invoke the driver function if it exists */
if (com_dev->driver->set_ctrl_line) {
com_dev->driver->set_ctrl_line(com_dev->lower_id, mask, state);
}
return 0;
}
/**
* Set control lines associated with the port
* \param[in] port COM port
* \param[in] ctrl_line_cb Callback function
* \param[in] context context to pass to the callback function
* \return -1 if port not available
* \return 0 on success
*/
int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t com_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context)
{
struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id;
if (!PIOS_COM_validate(com_dev)) {
/* Undefined COM port for this board (see pios_board.c) */
return -1;
}
/* Invoke the driver function if it exists */
if (com_dev->driver->bind_ctrl_line_cb) {
com_dev->driver->bind_ctrl_line_cb(com_dev->lower_id, ctrl_line_cb, context);
}
return 0;
}
static int32_t PIOS_COM_SendBufferNonBlockingInternal(struct pios_com_dev *com_dev, const uint8_t *buffer, uint16_t len)
{

View File

@ -8,6 +8,7 @@
*
* @file pios_com.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Thorsten Klose (tk@midibox.org)
* @brief COM layer functions header
* @see The GNU Public License (GPL) Version 3
*
@ -35,19 +36,29 @@
#include <stdbool.h> /* bool */
typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken);
typedef void (*pios_com_callback_ctrl_line)(uint32_t context, uint32_t mask, uint32_t state);
struct pios_com_driver {
void (*init)(uint32_t id);
void (*set_baud)(uint32_t id, uint32_t baud);
void (*set_ctrl_line)(uint32_t id, uint32_t mask, uint32_t state);
void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail);
void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail);
void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context);
void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context);
void (*bind_ctrl_line_cb)(uint32_t id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context);
bool (*available)(uint32_t id);
};
/* Control line definitions */
#define COM_CTRL_LINE_DTR_MASK 0x01
#define COM_CTRL_LINE_RTS_MASK 0x02
/* Public Functions */
extern int32_t PIOS_COM_Init(uint32_t *com_id, const struct pios_com_driver *driver, uint32_t lower_id, uint8_t *rx_buffer, uint16_t rx_buffer_len, uint8_t *tx_buffer, uint16_t tx_buffer_len);
extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud);
extern int32_t PIOS_COM_SetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state);
extern int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t usart_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context);
extern int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c);
extern int32_t PIOS_COM_SendChar(uint32_t com_id, char c);
extern int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len);

View File

@ -44,6 +44,7 @@ struct pios_usart_cfg {
USART_InitTypeDef init;
struct stm32_gpio rx;
struct stm32_gpio tx;
struct stm32_gpio dtr;
struct stm32_irq irq;
};

View File

@ -40,17 +40,19 @@
/* Provide a COM driver */
static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud);
static void PIOS_USART_SetCtrlLine(uint32_t usart_id, uint32_t mask, uint32_t state);
static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USART_TxStart(uint32_t usart_id, uint16_t tx_bytes_avail);
static void PIOS_USART_RxStart(uint32_t usart_id, uint16_t rx_bytes_avail);
const struct pios_com_driver pios_usart_com_driver = {
.set_baud = PIOS_USART_ChangeBaud,
.tx_start = PIOS_USART_TxStart,
.rx_start = PIOS_USART_RxStart,
.bind_tx_cb = PIOS_USART_RegisterTxCallback,
.bind_rx_cb = PIOS_USART_RegisterRxCallback,
.set_baud = PIOS_USART_ChangeBaud,
.set_ctrl_line = PIOS_USART_SetCtrlLine,
.tx_start = PIOS_USART_TxStart,
.rx_start = PIOS_USART_RxStart,
.bind_tx_cb = PIOS_USART_RegisterTxCallback,
.bind_rx_cb = PIOS_USART_RegisterRxCallback,
};
enum pios_usart_dev_magic {
@ -189,6 +191,12 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg)
GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init);
GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init);
/* If a DTR line is specified, initialize it */
if (usart_dev->cfg->dtr.gpio) {
GPIO_Init(usart_dev->cfg->dtr.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->dtr.init);
PIOS_USART_SetCtrlLine((uint32_t)usart_dev, COM_CTRL_LINE_DTR_MASK, 0);
}
/* Configure the USART */
USART_Init(usart_dev->cfg->regs, (USART_InitTypeDef *)&usart_dev->cfg->init);
@ -276,6 +284,22 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud)
USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
}
static void PIOS_USART_SetCtrlLine(uint32_t usart_id, uint32_t mask, uint32_t state)
{
struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id;
bool valid = PIOS_USART_validate(usart_dev);
PIOS_Assert(valid);
/* Only attempt to drive DTR if this USART has a GPIO line defined */
if (usart_dev->cfg->dtr.gpio && (mask & COM_CTRL_LINE_DTR_MASK)) {
GPIO_WriteBit(usart_dev->cfg->dtr.gpio,
usart_dev->cfg->dtr.init.GPIO_Pin,
state & COM_CTRL_LINE_DTR_MASK ? Bit_RESET : Bit_SET);
}
}
static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context)
{
struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id;

View File

@ -40,6 +40,7 @@
/* Implement COM layer driver API */
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_RegisterCtrlLineCallback(uint32_t usbcdc_id, pios_com_callback_ctrl_line ctrl_line_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);
static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id);
@ -49,6 +50,7 @@ const struct pios_com_driver pios_usb_cdc_com_driver = {
.rx_start = PIOS_USB_CDC_RxStart,
.bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
.bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
.bind_ctrl_line_cb = PIOS_USB_CDC_RegisterCtrlLineCallback,
.available = PIOS_USB_CDC_Available,
};
@ -66,6 +68,8 @@ struct pios_usb_cdc_dev {
uint32_t rx_in_context;
pios_com_callback tx_out_cb;
uint32_t tx_out_context;
pios_com_callback_ctrl_line ctrl_line_cb;
uint32_t ctrl_line_context;
bool usb_ctrl_if_enabled;
bool usb_data_if_enabled;
@ -323,6 +327,23 @@ static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callbac
usb_cdc_dev->tx_out_cb = tx_out_cb;
}
static void PIOS_USB_CDC_RegisterCtrlLineCallback(uint32_t usbcdc_id, pios_com_callback_ctrl_line ctrl_line_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->ctrl_line_context = context;
usb_cdc_dev->ctrl_line_cb = ctrl_line_cb;
}
static bool PIOS_USB_CDC_CTRL_EP_IN_Callback(uint32_t usb_cdc_id, uint8_t epnum, uint16_t len);
static void PIOS_USB_CDC_CTRL_IF_Init(uint32_t usb_cdc_id)
@ -403,6 +424,11 @@ static bool PIOS_USB_CDC_CTRL_IF_Setup(uint32_t usb_cdc_id, struct usb_setup_req
break;
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
control_line_state = req->wValue;
if (usb_cdc_dev->ctrl_line_cb) {
(usb_cdc_dev->ctrl_line_cb)(usb_cdc_dev->ctrl_line_context,
0xff,
control_line_state);
}
break;
default:
/* Unhandled class request */

View File

@ -1159,6 +1159,17 @@ static const struct pios_usart_cfg pios_usart_rcvrport_cfg = {
},
},
.dtr = {
// FlexIO pin 9
.gpio = GPIOC,
.init = {
.GPIO_Pin = GPIO_Pin_8,
.GPIO_Speed = GPIO_Speed_25MHz,
.GPIO_Mode = GPIO_Mode_OUT,
.GPIO_OType = GPIO_OType_PP,
},
},
.tx = {
// * 7: PC6 = TIM8 CH1, USART6 TX
.gpio = GPIOC,

View File

@ -887,6 +887,9 @@ void PIOS_Board_Init(void)
case HWSETTINGS_RM_RCVRPORT_TELEMETRY:
PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id);
break;
case HWSETTINGS_RM_RCVRPORT_COMBRIDGE:
PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id);
break;
}
#if defined(PIOS_INCLUDE_GCSRCVR)

View File

@ -151,6 +151,12 @@ void ConfigRevoHWWidget::usbVCPPortChanged(int index)
m_ui->cbMain->model()->setData(m_ui->cbMain->model()->index(HwSettings::RM_MAINPORT_COMBRIDGE, 0),
!vcpComBridgeEnabled ? QVariant(0) : QVariant(1 | 32), Qt::UserRole - 1);
if (!vcpComBridgeEnabled && m_ui->cbRcvr->currentIndex() == HwSettings::RM_RCVRPORT_COMBRIDGE) {
m_ui->cbRcvr->setCurrentIndex(HwSettings::RM_RCVRPORT_DISABLED);
}
m_ui->cbRcvr->model()->setData(m_ui->cbRcvr->model()->index(HwSettings::RM_RCVRPORT_COMBRIDGE, 0),
!vcpComBridgeEnabled ? QVariant(0) : QVariant(1 | 32), Qt::UserRole - 1);
// _DEBUGCONSOLE modes are mutual exclusive
if (m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_DEBUGCONSOLE) {
if (m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_DEBUGCONSOLE) {

View File

@ -12,7 +12,7 @@
<field name="RV_TelemetryPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,ComAux,ComBridge" defaultvalue="Telemetry"/>
<field name="RV_GPSPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,ComAux,ComBridge" defaultvalue="GPS"/>
<field name="RM_RcvrPort" units="function" type="enum" elements="1" options="Disabled,PWM,PPM,PPM+PWM,PPM+Telemetry,PPM+Outputs,Outputs,Telemetry" defaultvalue="PWM"/>
<field name="RM_RcvrPort" units="function" type="enum" elements="1" options="Disabled,PWM,PPM,PPM+PWM,PPM+Telemetry,PPM+Outputs,Outputs,Telemetry,ComBridge" defaultvalue="PWM"/>
<field name="RM_MainPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,S.Bus,DSM,DebugConsole,ComBridge,OsdHk" defaultvalue="Disabled"/>
<field name="RM_FlexiPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,I2C,DSM,SRXL,DebugConsole,ComBridge,OsdHk" defaultvalue="Disabled"/>