mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
200 lines
5.2 KiB
C
200 lines
5.2 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 <stdbool.h>
|
|
|
|
// ****************
|
|
// Private functions
|
|
|
|
static void com2UsbBridgeTask(void *parameters);
|
|
static void usb2ComBridgeTask(void *parameters);
|
|
static void updateSettings();
|
|
|
|
// ****************
|
|
// Private constants
|
|
|
|
#define STACK_SIZE_BYTES 280
|
|
#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, (signed char *)"Com2UsbBridge", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &com2UsbBridgeTaskHandle);
|
|
TaskMonitorAdd(TASKINFO_RUNNING_COM2USBBRIDGE, com2UsbBridgeTaskHandle);
|
|
xTaskCreate(usb2ComBridgeTask, (signed char *)"Usb2ComBridge", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &usb2ComBridgeTaskHandle);
|
|
TaskMonitorAdd(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;
|
|
|
|
#ifdef MODULE_COMUSBBRIDGE_BUILTIN
|
|
bridge_enabled = true;
|
|
#else
|
|
HwSettingsInitialize();
|
|
uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM];
|
|
|
|
HwSettingsOptionalModulesGet(optionalModules);
|
|
|
|
if (usart_port && vcp_port &&
|
|
(optionalModules[HWSETTINGS_OPTIONALMODULES_COMUSBBRIDGE] == HWSETTINGS_OPTIONALMODULES_ENABLED))
|
|
bridge_enabled = true;
|
|
else
|
|
bridge_enabled = false;
|
|
#endif
|
|
|
|
if (bridge_enabled) {
|
|
com2usb_buf = pvPortMalloc(BRIDGE_BUF_LEN);
|
|
PIOS_Assert(com2usb_buf);
|
|
usb2com_buf = pvPortMalloc(BRIDGE_BUF_LEN);
|
|
PIOS_Assert(usb2com_buf);
|
|
|
|
updateSettings();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
MODULE_INITCALL(comUsbBridgeInitialize, comUsbBridgeStart)
|
|
|
|
/**
|
|
* Main task. It does not return.
|
|
*/
|
|
|
|
static void com2UsbBridgeTask(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) != rx_bytes) {
|
|
/* Error on transmit */
|
|
tx_errors++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void usb2ComBridgeTask(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) != rx_bytes) {
|
|
/* Error on transmit */
|
|
tx_errors++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void updateSettings()
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|