Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / flight / modules / ComUsbBridge / ComUsbBridge.c
blobfdc9a014409acc5722fa6edeef7eae5ad2270a8a
1 /**
2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
4 * @{
5 * @addtogroup ComUsbBridgeModule Com Port to USB VCP Bridge Module
6 * @brief Bridge Com and USB VCP ports
7 * @{
9 * @file ComUsbBridge.c
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
11 * @brief Bridges selected Com Port to the USB VCP emulated serial port
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 // ****************
33 #include <openpilot.h>
35 #include "taskinfo.h"
37 #include <stdbool.h>
39 #include <pios_board_io.h>
41 // ****************
42 // Private functions
44 static void com2UsbBridgeTask(void *parameters);
45 static void usb2ComBridgeTask(void *parameters);
46 static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state);
47 static void usb2ComBridgeSetBaudRate(uint32_t com_id, uint32_t baud);
50 // ****************
51 // Private constants
53 #define U2C_STACK_SIZE_BYTES 260
54 #define C2U_STACK_SIZE_BYTES 316
56 #define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
58 #define BRIDGE_BUF_LEN 10
60 // ****************
61 // Private variables
63 static xTaskHandle com2UsbBridgeTaskHandle;
64 static xTaskHandle usb2ComBridgeTaskHandle;
66 static uint8_t *com2usb_buf;
67 static uint8_t *usb2com_buf;
69 static uint32_t usart_port;
70 static uint32_t vcp_port;
72 static bool bridge_enabled = false;
74 /**
75 * Initialise the module
76 * \return -1 if initialisation failed
77 * \return 0 on success
80 static int32_t comUsbBridgeStart(void)
82 if (bridge_enabled) {
83 // Start tasks
84 xTaskCreate(com2UsbBridgeTask, "Com2UsbBridge", C2U_STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &com2UsbBridgeTaskHandle);
85 PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_COM2USBBRIDGE, com2UsbBridgeTaskHandle);
86 xTaskCreate(usb2ComBridgeTask, "Usb2ComBridge", U2C_STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &usb2ComBridgeTaskHandle);
87 PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_USB2COMBRIDGE, usb2ComBridgeTaskHandle);
88 return 0;
91 return -1;
93 /**
94 * Initialise the module
95 * \return -1 if initialisation failed
96 * \return 0 on success
98 static int32_t comUsbBridgeInitialize(void)
100 // TODO: Get from settings object
101 usart_port = PIOS_COM_BRIDGE;
102 vcp_port = PIOS_COM_VCP;
104 // Register the call back handler for USB control line changes to simply
105 // pass these onto any handler registered on the USART
106 if (vcp_port) {
107 PIOS_COM_RegisterCtrlLineCallback(vcp_port,
108 usb2ComBridgeSetCtrlLine,
109 usart_port);
110 PIOS_COM_RegisterBaudRateCallback(vcp_port,
111 usb2ComBridgeSetBaudRate,
112 usart_port);
115 #ifdef MODULE_COMUSBBRIDGE_BUILTIN
116 bridge_enabled = true;
117 #else
119 if (usart_port && vcp_port) {
120 bridge_enabled = true;
121 } else {
122 bridge_enabled = false;
124 #endif
126 if (bridge_enabled) {
127 com2usb_buf = pios_malloc(BRIDGE_BUF_LEN);
128 PIOS_Assert(com2usb_buf);
129 usb2com_buf = pios_malloc(BRIDGE_BUF_LEN);
130 PIOS_Assert(usb2com_buf);
133 return 0;
135 MODULE_INITCALL(comUsbBridgeInitialize, comUsbBridgeStart);
138 * Main task. It does not return.
141 static void com2UsbBridgeTask(__attribute__((unused)) void *parameters)
143 /* Handle usart -> vcp direction */
144 volatile uint32_t tx_errors = 0;
146 while (1) {
147 uint32_t rx_bytes;
149 rx_bytes = PIOS_COM_ReceiveBuffer(usart_port, com2usb_buf, BRIDGE_BUF_LEN, 500);
150 if (rx_bytes > 0) {
151 /* Bytes available to transfer */
152 if (PIOS_COM_SendBuffer(vcp_port, com2usb_buf, rx_bytes) != (int32_t)rx_bytes) {
153 /* Error on transmit */
154 tx_errors++;
160 static void usb2ComBridgeTask(__attribute__((unused)) void *parameters)
162 /* Handle vcp -> usart direction */
163 volatile uint32_t tx_errors = 0;
165 while (1) {
166 uint32_t rx_bytes;
168 rx_bytes = PIOS_COM_ReceiveBuffer(vcp_port, usb2com_buf, BRIDGE_BUF_LEN, 500);
169 if (rx_bytes > 0) {
170 /* Bytes available to transfer */
171 if (PIOS_COM_SendBuffer(usart_port, usb2com_buf, rx_bytes) != (int32_t)rx_bytes) {
172 /* Error on transmit */
173 tx_errors++;
179 /* This routine is registered with the USB driver and will be called in the
180 * event of a control line state change. It will then call down to the USART
181 * driver to drive the required control line state.
183 static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state)
185 PIOS_COM_SetCtrlLine(com_id, mask, state);
188 static void usb2ComBridgeSetBaudRate(uint32_t com_id, uint32_t baud)
190 PIOS_COM_ChangeBaud(com_id, baud);