Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Tools/AP_Periph/networking_passthru.cpp
Views: 1798
/*1This program is free software: you can redistribute it and/or modify2it under the terms of the GNU General Public License as published by3the Free Software Foundation, either version 3 of the License, or4(at your option) any later version.56This program is distributed in the hope that it will be useful,7but WITHOUT ANY WARRANTY; without even the implied warranty of8MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9GNU General Public License for more details.1011You should have received a copy of the GNU General Public License12along with this program. If not, see <http://www.gnu.org/licenses/>.13*/1415#include "AP_Periph.h"1617#if defined(HAL_PERIPH_ENABLE_NETWORKING) && HAL_PERIPH_NETWORK_NUM_PASSTHRU > 01819#include <AP_SerialManager/AP_SerialManager.h>2021const AP_Param::GroupInfo Networking_Periph::Passthru::var_info[] = {22// @Param: ENABLE23// @DisplayName: Enable Passthrough24// @Description: Enable Passthrough of any UART, Network, or CAN ports to any UART, Network, or CAN ports.25// @Values: 0:Disabled, 1:Enabled26// @RebootRequired: True27// @User: Advanced28AP_GROUPINFO_FLAGS("ENABLE", 1, Networking_Periph::Passthru, enabled, 0, AP_PARAM_FLAG_ENABLE),2930// @Param: EP131// @DisplayName: Endpoint 132// @Description: Passthrough Endpoint 1. This can be a serial port UART, a Network port, or a CAN port. The selected port will route to Endport 2.33// @Values: -1:Disabled, 0:Serial0(usually USB), 1:Serial1, 2:Serial2, 3:Serial3, 4:Serial4, 5:Serial5, 6:Serial6, 7:Serial7, 8:Serial8, 9:Serial9, 21:Network Port1, 22:Network Port2, 23:Network Port3, 24:Network Port4, 25:Network Port5, 26:Network Port6, 27:Network Port7, 28:Network Port8, 29:Network Port9, 41:CAN1 Port1, 42:CAN1 Port2, 43:CAN1 Port3, 44:CAN1 Port4, 45:CAN1 Port5, 46:CAN1 Port6, 47:CAN1 Port7, 48:CAN1 Port8, 49:CAN1 Port9, 51:CAN2 Port1, 52:CAN2 Port2, 53:CAN2 Port3, 54:CAN2 Port4, 55:CAN2 Port5, 56:CAN2 Port6, 57:CAN2 Port7, 58:CAN2 Port8, 59:CAN2 Port934// @RebootRequired: True35// @User: Advanced36AP_GROUPINFO("EP1", 2, Networking_Periph::Passthru, ep1, -1),3738// @Param: EP239// @DisplayName: Endpoint 240// @Description: Passthrough Endpoint 2. This can be a serial port UART, a Network port, or a CAN port. The selected port will route to Endport 1.41// @CopyFieldsFrom: NET_PASS1_EP142AP_GROUPINFO("EP2", 3, Networking_Periph::Passthru, ep2, -1),4344// @Param: BAUD145// @DisplayName: Endpoint 1 Baud Rate46// @Description: The baud rate used for Endpoint 1. Only applies to serial ports.47// @CopyFieldsFrom: SERIAL1_BAUD48AP_GROUPINFO("BAUD1", 4, Networking_Periph::Passthru, baud1, 115200),4950// @Param: BAUD251// @DisplayName: Endpoint 2 Baud Rate52// @Description: The baud rate used for Endpoint 2. Only applies to serial ports.53// @CopyFieldsFrom: SERIAL1_BAUD54AP_GROUPINFO("BAUD2", 5, Networking_Periph::Passthru, baud2, 115200),5556// @Param: OPT157// @DisplayName: Serial Port Options EP158// @Description: Control over UART options for Endpoint 1. Only applies to serial ports.59// @CopyFieldsFrom: SERIAL1_OPTIONS60AP_GROUPINFO("OPT1", 6, Networking_Periph::Passthru, options1, 0),6162// @Param: OPT263// @DisplayName: Serial Port Options EP264// @Description: Control over UART options for Endpoint 2. Only applies to serial ports.65// @CopyFieldsFrom: SERIAL1_OPTIONS66AP_GROUPINFO("OPT2", 7, Networking_Periph::Passthru, options2, 0),6768AP_GROUPEND69};7071void Networking_Periph::Passthru::init()72{73if (enabled == 0) {74// Feature is disabled75return;76}7778if (port1 != nullptr || port2 != nullptr) {79// The ports have already been initialized, nothing to do.80return;81}8283if (ep1 <= -1 || ep2 <= -1 || ep1 == ep2) {84// end points are not set or are the same. Can't route to self85return;86}8788port1 = AP::serialmanager().get_serial_by_id(ep1);89port2 = AP::serialmanager().get_serial_by_id(ep2);9091if (port1 != nullptr && port2 != nullptr) {92port1->set_options(options1);93port1->begin(baud1);9495port2->set_options(options2);96port2->begin(baud2);97}98}99100void Networking_Periph::Passthru::update()101{102if (enabled == 0 || port1 == nullptr || port2 == nullptr) {103return;104}105106// Fastest possible connection is 3Mbps serial port, which is roughly 300KB/s payload and we service this at <= 1kHz107// Raising this any higher just causes excess stack usage which never gets used.108uint8_t buf[300];109110// read from port1, and write to port2111auto avail = port1->available();112if (avail > 0) {113auto space = port2->txspace();114const uint32_t n = MIN(space, sizeof(buf));115const auto nbytes = port1->read(buf, n);116if (nbytes > 0) {117port2->write(buf, nbytes);118}119}120121// read from port2, and write to port1122avail = port2->available();123if (avail > 0) {124auto space = port1->txspace();125const uint32_t n = MIN(space, sizeof(buf));126const auto nbytes = port2->read(buf, n);127if (nbytes > 0) {128port1->write(buf, nbytes);129}130}131}132133#endif // defined(HAL_PERIPH_ENABLE_NETWORKING) && HAL_PERIPH_NETWORK_NUM_PASSTHRU > 0134135136137