mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
222 lines
6.5 KiB
C
222 lines
6.5 KiB
C
/**
|
|
******************************************************************************
|
|
* @addtogroup OpenPilotModules OpenPilot Modules
|
|
* @{
|
|
* @addtogroup ComUsbBridgeModule Com Port to USB VCP Bridge Module
|
|
* @brief Bridge Com and USB VCP ports
|
|
* @{
|
|
*
|
|
* @file ComUsbBridge.c
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
|
|
* @brief Bridges selected Com Port to the USB VCP emulated serial port
|
|
* @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 <openpilot.h>
|
|
|
|
#include "hwsettings.h"
|
|
#include "taskinfo.h"
|
|
|
|
#include <stdbool.h>
|
|
|
|
// ****************
|
|
// Private functions
|
|
|
|
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
|
|
|
|
#define U2C_STACK_SIZE_BYTES 260
|
|
#define C2U_STACK_SIZE_BYTES 316
|
|
|
|
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
|
|
|
#define BRIDGE_BUF_LEN 10
|
|
|
|
// ****************
|
|
// Private variables
|
|
|
|
static xTaskHandle com2UsbBridgeTaskHandle;
|
|
static xTaskHandle usb2ComBridgeTaskHandle;
|
|
|
|
static uint8_t *com2usb_buf;
|
|
static uint8_t *usb2com_buf;
|
|
|
|
static uint32_t usart_port;
|
|
static uint32_t vcp_port;
|
|
|
|
static bool bridge_enabled = false;
|
|
|
|
/**
|
|
* Initialise the module
|
|
* \return -1 if initialisation failed
|
|
* \return 0 on success
|
|
*/
|
|
|
|
static int32_t comUsbBridgeStart(void)
|
|
{
|
|
if (bridge_enabled) {
|
|
// Start tasks
|
|
xTaskCreate(com2UsbBridgeTask, "Com2UsbBridge", C2U_STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &com2UsbBridgeTaskHandle);
|
|
PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_COM2USBBRIDGE, com2UsbBridgeTaskHandle);
|
|
xTaskCreate(usb2ComBridgeTask, "Usb2ComBridge", U2C_STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &usb2ComBridgeTaskHandle);
|
|
PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_USB2COMBRIDGE, usb2ComBridgeTaskHandle);
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
/**
|
|
* Initialise the module
|
|
* \return -1 if initialisation failed
|
|
* \return 0 on success
|
|
*/
|
|
static int32_t comUsbBridgeInitialize(void)
|
|
{
|
|
// TODO: Get from settings object
|
|
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;
|
|
#else
|
|
HwSettingsInitialize();
|
|
HwSettingsOptionalModulesData optionalModules;
|
|
|
|
HwSettingsOptionalModulesGet(&optionalModules);
|
|
|
|
if (usart_port && vcp_port) {
|
|
bridge_enabled = true;
|
|
} else {
|
|
bridge_enabled = false;
|
|
}
|
|
#endif
|
|
|
|
if (bridge_enabled) {
|
|
com2usb_buf = pios_malloc(BRIDGE_BUF_LEN);
|
|
PIOS_Assert(com2usb_buf);
|
|
usb2com_buf = pios_malloc(BRIDGE_BUF_LEN);
|
|
PIOS_Assert(usb2com_buf);
|
|
HwSettingsConnectCallback(&updateSettings);
|
|
updateSettings(0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
MODULE_INITCALL(comUsbBridgeInitialize, comUsbBridgeStart);
|
|
|
|
/**
|
|
* Main task. It does not return.
|
|
*/
|
|
|
|
static void com2UsbBridgeTask(__attribute__((unused)) void *parameters)
|
|
{
|
|
/* Handle usart -> vcp direction */
|
|
volatile uint32_t tx_errors = 0;
|
|
|
|
while (1) {
|
|
uint32_t rx_bytes;
|
|
|
|
rx_bytes = PIOS_COM_ReceiveBuffer(usart_port, com2usb_buf, BRIDGE_BUF_LEN, 500);
|
|
if (rx_bytes > 0) {
|
|
/* Bytes available to transfer */
|
|
if (PIOS_COM_SendBuffer(vcp_port, com2usb_buf, rx_bytes) != (int32_t)rx_bytes) {
|
|
/* Error on transmit */
|
|
tx_errors++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void usb2ComBridgeTask(__attribute__((unused)) void *parameters)
|
|
{
|
|
/* Handle vcp -> usart direction */
|
|
volatile uint32_t tx_errors = 0;
|
|
|
|
while (1) {
|
|
uint32_t rx_bytes;
|
|
|
|
rx_bytes = PIOS_COM_ReceiveBuffer(vcp_port, usb2com_buf, BRIDGE_BUF_LEN, 500);
|
|
if (rx_bytes > 0) {
|
|
/* Bytes available to transfer */
|
|
if (PIOS_COM_SendBuffer(usart_port, usb2com_buf, rx_bytes) != (int32_t)rx_bytes) {
|
|
/* Error on transmit */
|
|
tx_errors++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 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)
|
|
{
|
|
if (usart_port) {
|
|
// Retrieve settings
|
|
uint8_t speed;
|
|
HwSettingsComUsbBridgeSpeedGet(&speed);
|
|
|
|
// Set port speed
|
|
switch (speed) {
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_2400:
|
|
PIOS_COM_ChangeBaud(usart_port, 2400);
|
|
break;
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_4800:
|
|
PIOS_COM_ChangeBaud(usart_port, 4800);
|
|
break;
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_9600:
|
|
PIOS_COM_ChangeBaud(usart_port, 9600);
|
|
break;
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_19200:
|
|
PIOS_COM_ChangeBaud(usart_port, 19200);
|
|
break;
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_38400:
|
|
PIOS_COM_ChangeBaud(usart_port, 38400);
|
|
break;
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_57600:
|
|
PIOS_COM_ChangeBaud(usart_port, 57600);
|
|
break;
|
|
case HWSETTINGS_COMUSBBRIDGESPEED_115200:
|
|
PIOS_COM_ChangeBaud(usart_port, 115200);
|
|
break;
|
|
}
|
|
}
|
|
}
|