Line data Source code
1 : /*
2 : Please contribute your ideas! See https://ardupilot.club/dev for details
3 :
4 : This program is free software: you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation, either version 3 of the License, or
7 : (at your option) any later version.
8 :
9 : This program is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with this program. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 : /*
18 : SerialManager allows defining the protocol and baud rates for the available
19 : serial ports and provides helper functions so objects (like a gimbal) can
20 : find which serial port they should use
21 : */
22 :
23 : #include "AP_SerialManager_config.h"
24 :
25 : #if AP_SERIALMANAGER_ENABLED
26 :
27 : #include <AP_HAL/AP_HAL.h>
28 : #include <AP_Math/AP_Math.h>
29 : #include <AP_RCProtocol/AP_RCProtocol.h>
30 : #include <AP_MSP/AP_MSP.h>
31 : #include <AP_InertialSensor/AP_InertialSensor.h>
32 : #include "AP_SerialManager.h"
33 : #include <GCS_MAVLink/GCS.h>
34 :
35 : extern const AP_HAL::HAL& hal;
36 :
37 : #ifndef DEFAULT_SERIAL0_PROTOCOL
38 : #define DEFAULT_SERIAL0_PROTOCOL SerialProtocol_MAVLink2
39 : #endif
40 : #ifndef DEFAULT_SERIAL0_BAUD
41 : #define DEFAULT_SERIAL0_BAUD AP_SERIALMANAGER_CONSOLE_BAUD
42 : #endif
43 : #ifdef HAL_SERIAL0_PROTOCOL
44 : #error "Please use DEFAULT_SERIAL0_PROTOCOL"
45 : #endif
46 :
47 : #ifndef DEFAULT_SERIAL1_PROTOCOL
48 : #define DEFAULT_SERIAL1_PROTOCOL SerialProtocol_MAVLink2
49 : #endif
50 : #ifndef DEFAULT_SERIAL1_BAUD
51 : #define DEFAULT_SERIAL1_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
52 : #endif
53 : #ifndef DEFAULT_SERIAL1_OPTIONS
54 : #define DEFAULT_SERIAL1_OPTIONS 0
55 : #endif
56 : #ifdef HAL_SERIAL1_PROTOCOL
57 : #error "Please use DEFAULT_SERIAL1_PROTOCOL"
58 : #endif
59 :
60 : #ifndef DEFAULT_SERIAL2_PROTOCOL
61 : #define DEFAULT_SERIAL2_PROTOCOL SerialProtocol_MAVLink2
62 : #endif
63 : #ifndef DEFAULT_SERIAL2_BAUD
64 : #define DEFAULT_SERIAL2_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
65 : #endif
66 : #ifndef DEFAULT_SERIAL2_OPTIONS
67 : #define DEFAULT_SERIAL2_OPTIONS 0
68 : #endif
69 : #ifdef HAL_SERIAL2_PROTOCOL
70 : #error "Please use DEFAULT_SERIAL2_PROTOCOL"
71 : #endif
72 :
73 : #ifndef DEFAULT_SERIAL3_PROTOCOL
74 : #define DEFAULT_SERIAL3_PROTOCOL SerialProtocol_GPS
75 : #endif
76 : #ifndef DEFAULT_SERIAL3_BAUD
77 : #define DEFAULT_SERIAL3_BAUD AP_SERIALMANAGER_GPS_BAUD/1000
78 : #endif
79 : #ifndef DEFAULT_SERIAL3_OPTIONS
80 : #define DEFAULT_SERIAL3_OPTIONS 0
81 : #endif
82 : #ifdef HAL_SERIAL3_PROTOCOL
83 : #error "Please use DEFAULT_SERIAL3_PROTOCOL"
84 : #endif
85 :
86 : #ifndef DEFAULT_SERIAL4_PROTOCOL
87 : #define DEFAULT_SERIAL4_PROTOCOL SerialProtocol_GPS
88 : #endif
89 : #ifndef DEFAULT_SERIAL4_BAUD
90 : #define DEFAULT_SERIAL4_BAUD AP_SERIALMANAGER_GPS_BAUD/1000
91 : #endif
92 : #ifndef DEFAULT_SERIAL4_OPTIONS
93 : #define DEFAULT_SERIAL4_OPTIONS 0
94 : #endif
95 : #ifdef HAL_SERIAL4_PROTOCOL
96 : #error "Please use DEFAULT_SERIAL4_PROTOCOL"
97 : #endif
98 :
99 : #ifndef DEFAULT_SERIAL5_PROTOCOL
100 : #define DEFAULT_SERIAL5_PROTOCOL SerialProtocol_None
101 : #endif
102 : #ifndef DEFAULT_SERIAL5_BAUD
103 : #define DEFAULT_SERIAL5_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
104 : #endif
105 : #ifndef DEFAULT_SERIAL5_OPTIONS
106 : #define DEFAULT_SERIAL5_OPTIONS 0
107 : #endif
108 : #ifdef HAL_SERIAL5_PROTOCOL
109 : #error "Please use DEFAULT_SERIAL5_PROTOCOL"
110 : #endif
111 :
112 : #ifndef DEFAULT_SERIAL6_PROTOCOL
113 : #define DEFAULT_SERIAL6_PROTOCOL SerialProtocol_None
114 : #endif
115 : #ifndef DEFAULT_SERIAL6_BAUD
116 : #define DEFAULT_SERIAL6_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
117 : #endif
118 : #ifndef DEFAULT_SERIAL6_OPTIONS
119 : #define DEFAULT_SERIAL6_OPTIONS 0
120 : #endif
121 : #ifdef HAL_SERIAL6_PROTOCOL
122 : #error "Please use DEFAULT_SERIAL6_PROTOCOL"
123 : #endif
124 :
125 : #ifndef DEFAULT_SERIAL7_PROTOCOL
126 : #define DEFAULT_SERIAL7_PROTOCOL SerialProtocol_None
127 : #endif
128 : #ifndef DEFAULT_SERIAL7_BAUD
129 : #define DEFAULT_SERIAL7_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
130 : #endif
131 : #ifndef DEFAULT_SERIAL7_OPTIONS
132 : #define DEFAULT_SERIAL7_OPTIONS 0
133 : #endif
134 : #ifdef HAL_SERIAL7_PROTOCOL
135 : #error "Please use DEFAULT_SERIAL7_PROTOCOL"
136 : #endif
137 :
138 : #ifndef DEFAULT_SERIAL8_PROTOCOL
139 : #define DEFAULT_SERIAL8_PROTOCOL SerialProtocol_None
140 : #endif
141 : #ifndef DEFAULT_SERIAL8_BAUD
142 : #define DEFAULT_SERIAL8_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
143 : #endif
144 : #ifndef DEFAULT_SERIAL8_OPTIONS
145 : #define DEFAULT_SERIAL8_OPTIONS 0
146 : #endif
147 : #ifdef HAL_SERIAL8_PROTOCOL
148 : #error "Please use DEFAULT_SERIAL8_PROTOCOL"
149 : #endif
150 :
151 : #ifndef DEFAULT_SERIAL9_PROTOCOL
152 : #define DEFAULT_SERIAL9_PROTOCOL SerialProtocol_None
153 : #endif
154 : #ifndef DEFAULT_SERIAL9_BAUD
155 : #define DEFAULT_SERIAL9_BAUD AP_SERIALMANAGER_MAVLINK_BAUD/1000
156 : #endif
157 : #ifndef DEFAULT_SERIAL9_OPTIONS
158 : #define DEFAULT_SERIAL9_OPTIONS 0
159 : #endif
160 : #ifdef HAL_SERIAL9_PROTOCOL
161 : #error "Please use DEFAULT_SERIAL9_PROTOCOL"
162 : #endif
163 :
164 : const AP_Param::GroupInfo AP_SerialManager::var_info[] = {
165 : #if HAL_HAVE_SERIAL0_PARAMS
166 : // @Param: 0_BAUD
167 : // @DisplayName: Serial0 baud rate
168 : // @Description: The baud rate used on the USB console. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
169 : // @Values: 1:1200,2:2400,4:4800,9:9600,19:19200,38:38400,57:57600,111:111100,115:115200,230:230400,256:256000,460:460800,500:500000,921:921600,1500:1.5MBaud,2000:2MBaud,12500000:12.5MBaud
170 : // @Range: 1 20000000
171 : // @User: Standard
172 : AP_GROUPINFO("0_BAUD", 0, AP_SerialManager, state[0].baud, DEFAULT_SERIAL0_BAUD/1000),
173 :
174 : // @Param: 0_PROTOCOL
175 : // @DisplayName: Console protocol selection
176 : // @Description: Control what protocol to use on the console.
177 : // @Values: 1:MAVLink1, 2:MAVLink2
178 : // @User: Standard
179 : // @RebootRequired: True
180 : AP_GROUPINFO("0_PROTOCOL", 11, AP_SerialManager, state[0].protocol, SerialProtocol_MAVLink2),
181 : #endif
182 :
183 : #if HAL_HAVE_SERIAL1_PARAMS
184 : // @Param: 1_PROTOCOL
185 : // @DisplayName: Telem1 protocol selection
186 : // @Description: Control what protocol to use on the Telem1 port. Note that the Frsky options require external converter hardware. See the wiki for details.
187 : // @SortValues: AlphabeticalZeroAtTop
188 : // @Values: -1:None, 1:MAVLink1, 2:MAVLink2, 3:Frsky D, 4:Frsky SPort, 5:GPS, 7:Alexmos Gimbal Serial, 8:Gimbal, 9:Rangefinder, 10:FrSky SPort Passthrough (OpenTX), 11:Lidar360, 13:Beacon, 14:Volz servo out, 15:SBus servo out, 16:ESC Telemetry, 17:Devo Telemetry, 18:OpticalFlow, 19:RobotisServo, 20:NMEA Output, 21:WindVane, 22:SLCAN, 23:RCIN, 24:EFI Serial, 25:LTM, 26:RunCam, 27:HottTelem, 28:Scripting, 29:Crossfire VTX, 30:Generator, 31:Winch, 32:MSP, 33:DJI FPV, 34:AirSpeed, 35:ADSB, 36:AHRS, 37:SmartAudio, 38:FETtecOneWire, 39:Torqeedo, 40:AIS, 41:CoDevESC, 42:DisplayPort, 43:MAVLink High Latency, 44:IRC Tramp, 45:DDS XRCE, 46:IMUDATA, 48:PPP, 49:i-BUS Telemetry, 50: IOMCU
189 : // @User: Standard
190 : // @RebootRequired: True
191 : AP_GROUPINFO("1_PROTOCOL", 1, AP_SerialManager, state[1].protocol, DEFAULT_SERIAL1_PROTOCOL),
192 :
193 : // @Param: 1_BAUD
194 : // @DisplayName: Telem1 Baud Rate
195 : // @Description: The baud rate used on the Telem1 port. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
196 : // @Values: 1:1200,2:2400,4:4800,9:9600,19:19200,38:38400,57:57600,111:111100,115:115200,230:230400,256:256000,460:460800,500:500000,921:921600,1500:1.5MBaud,2000:2MBaud,12500000:12.5MBaud
197 : // @Range: 1 20000000
198 : // @User: Standard
199 : AP_GROUPINFO("1_BAUD", 2, AP_SerialManager, state[1].baud, DEFAULT_SERIAL1_BAUD),
200 : #endif
201 :
202 : #if HAL_HAVE_SERIAL2_PARAMS
203 : // @Param: 2_PROTOCOL
204 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
205 : // @DisplayName: Telemetry 2 protocol selection
206 : // @Description: Control what protocol to use on the Telem2 port. Note that the Frsky options require external converter hardware. See the wiki for details.
207 : AP_GROUPINFO("2_PROTOCOL", 3, AP_SerialManager, state[2].protocol, DEFAULT_SERIAL2_PROTOCOL),
208 :
209 : // @Param: 2_BAUD
210 : // @CopyFieldsFrom: SERIAL1_BAUD
211 : // @DisplayName: Telemetry 2 Baud Rate
212 : // @Description: The baud rate of the Telem2 port. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
213 : AP_GROUPINFO("2_BAUD", 4, AP_SerialManager, state[2].baud, DEFAULT_SERIAL2_BAUD),
214 : #endif
215 :
216 : #if HAL_HAVE_SERIAL3_PARAMS
217 : // @Param: 3_PROTOCOL
218 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
219 : // @DisplayName: Serial 3 (GPS) protocol selection
220 : // @Description: Control what protocol Serial 3 (GPS) should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
221 : AP_GROUPINFO("3_PROTOCOL", 5, AP_SerialManager, state[3].protocol, DEFAULT_SERIAL3_PROTOCOL),
222 :
223 : // @Param: 3_BAUD
224 : // @CopyFieldsFrom: SERIAL1_BAUD
225 : // @DisplayName: Serial 3 (GPS) Baud Rate
226 : // @Description: The baud rate used for the Serial 3 (GPS). Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
227 : AP_GROUPINFO("3_BAUD", 6, AP_SerialManager, state[3].baud, DEFAULT_SERIAL3_BAUD),
228 : #endif
229 :
230 : #if HAL_HAVE_SERIAL4_PARAMS
231 : // @Param: 4_PROTOCOL
232 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
233 : // @DisplayName: Serial4 protocol selection
234 : // @Description: Control what protocol Serial4 port should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
235 : AP_GROUPINFO("4_PROTOCOL", 7, AP_SerialManager, state[4].protocol, DEFAULT_SERIAL4_PROTOCOL),
236 :
237 : // @Param: 4_BAUD
238 : // @CopyFieldsFrom: SERIAL1_BAUD
239 : // @DisplayName: Serial 4 Baud Rate
240 : // @Description: The baud rate used for Serial4. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
241 : AP_GROUPINFO("4_BAUD", 8, AP_SerialManager, state[4].baud, DEFAULT_SERIAL4_BAUD),
242 : #endif
243 :
244 : #if HAL_HAVE_SERIAL5_PARAMS
245 : // @Param: 5_PROTOCOL
246 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
247 : // @DisplayName: Serial5 protocol selection
248 : // @Description: Control what protocol Serial5 port should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
249 : AP_GROUPINFO("5_PROTOCOL", 9, AP_SerialManager, state[5].protocol, DEFAULT_SERIAL5_PROTOCOL),
250 :
251 : // @Param: 5_BAUD
252 : // @CopyFieldsFrom: SERIAL1_BAUD
253 : // @DisplayName: Serial 5 Baud Rate
254 : // @Description: The baud rate used for Serial5. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
255 : AP_GROUPINFO("5_BAUD", 10, AP_SerialManager, state[5].baud, DEFAULT_SERIAL5_BAUD),
256 : #endif
257 :
258 : // index 11 used by 0_PROTOCOL
259 :
260 : #if HAL_HAVE_SERIAL6_PARAMS
261 : // @Param: 6_PROTOCOL
262 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
263 : // @DisplayName: Serial6 protocol selection
264 : // @Description: Control what protocol Serial6 port should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
265 : AP_GROUPINFO("6_PROTOCOL", 12, AP_SerialManager, state[6].protocol, DEFAULT_SERIAL6_PROTOCOL),
266 :
267 : // @Param: 6_BAUD
268 : // @CopyFieldsFrom: SERIAL1_BAUD
269 : // @DisplayName: Serial 6 Baud Rate
270 : // @Description: The baud rate used for Serial6. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
271 : AP_GROUPINFO("6_BAUD", 13, AP_SerialManager, state[6].baud, DEFAULT_SERIAL6_BAUD),
272 : #endif
273 :
274 : #if HAL_HAVE_SERIAL1_PARAMS
275 : // @Param: 1_OPTIONS
276 : // @DisplayName: Telem1 options
277 : // @Description: Control over UART options. The InvertRX option controls invert of the receive pin. The InvertTX option controls invert of the transmit pin. The HalfDuplex option controls half-duplex (onewire) mode, where both transmit and receive is done on the transmit wire. The Swap option allows the RX and TX pins to be swapped on STM32F7 based boards. NOTE that two bits have moved from this parameter into MAVn_OPTIONS!
278 : // @Bitmask: 0:InvertRX, 1:InvertTX, 2:HalfDuplex, 3:SwapTXRX, 4: RX_PullDown, 5: RX_PullUp, 6: TX_PullDown, 7: TX_PullUp, 8: RX_NoDMA, 9: TX_NoDMA, 10: Don't forward mavlink to/from (moved to MAVn_OPTIONS >4.7), 11: DisableFIFO, 12: Ignore Streamrate (moved to MAVn_OPTIONS >4.7)
279 : // @User: Advanced
280 : // @RebootRequired: True
281 : AP_GROUPINFO("1_OPTIONS", 14, AP_SerialManager, state[1].options, DEFAULT_SERIAL1_OPTIONS),
282 : #endif
283 :
284 : #if HAL_HAVE_SERIAL2_PARAMS
285 : // @Param: 2_OPTIONS
286 : // @CopyFieldsFrom: SERIAL1_OPTIONS
287 : // @DisplayName: Telem2 options
288 : AP_GROUPINFO("2_OPTIONS", 15, AP_SerialManager, state[2].options, DEFAULT_SERIAL2_OPTIONS),
289 : #endif
290 :
291 : #if HAL_HAVE_SERIAL3_PARAMS
292 : // @Param: 3_OPTIONS
293 : // @CopyFieldsFrom: SERIAL1_OPTIONS
294 : // @DisplayName: Serial3 options
295 : AP_GROUPINFO("3_OPTIONS", 16, AP_SerialManager, state[3].options, DEFAULT_SERIAL3_OPTIONS),
296 : #endif
297 :
298 : #if HAL_HAVE_SERIAL4_PARAMS
299 : // @Param: 4_OPTIONS
300 : // @CopyFieldsFrom: SERIAL1_OPTIONS
301 : // @DisplayName: Serial4 options
302 : AP_GROUPINFO("4_OPTIONS", 17, AP_SerialManager, state[4].options, DEFAULT_SERIAL4_OPTIONS),
303 : #endif
304 :
305 : #if HAL_HAVE_SERIAL5_PARAMS
306 : // @Param: 5_OPTIONS
307 : // @CopyFieldsFrom: SERIAL1_OPTIONS
308 : // @DisplayName: Serial5 options
309 : AP_GROUPINFO("5_OPTIONS", 18, AP_SerialManager, state[5].options, DEFAULT_SERIAL5_OPTIONS),
310 : #endif
311 :
312 : #if HAL_HAVE_SERIAL6_PARAMS
313 : // @Param: 6_OPTIONS
314 : // @CopyFieldsFrom: SERIAL1_OPTIONS
315 : // @DisplayName: Serial6 options
316 : AP_GROUPINFO("6_OPTIONS", 19, AP_SerialManager, state[6].options, DEFAULT_SERIAL6_OPTIONS),
317 : #endif
318 :
319 : // @Param: _PASS1
320 : // @DisplayName: Serial passthru first port
321 : // @Description: This sets one side of pass-through between two serial ports. Once both sides are set then all data received on either port will be passed to the other port
322 : // @Values: -1:Disabled,0:Serial0,1:Serial1,2:Serial2,3:Serial3,4:Serial4,5:Serial5,6:Serial6
323 : // @User: Advanced
324 : AP_GROUPINFO("_PASS1", 20, AP_SerialManager, passthru_port1, 0),
325 :
326 : // @Param: _PASS2
327 : // @DisplayName: Serial passthru second port
328 : // @Description: This sets one side of pass-through between two serial ports. Once both sides are set then all data received on either port will be passed to the other port. This parameter is normally reset to -1 on reboot, disabling passthrough. If SERIAL_PASSTIMO is set to -1 then it is not reset on reboot.
329 : // @Values: -1:Disabled,0:Serial0,1:Serial1,2:Serial2,3:Serial3,4:Serial4,5:Serial5,6:Serial6
330 : // @User: Advanced
331 : AP_GROUPINFO("_PASS2", 21, AP_SerialManager, passthru_port2, -1),
332 :
333 : // @Param: _PASSTIMO
334 : // @DisplayName: Serial passthru timeout
335 : // @Description: This sets a timeout for serial pass-through in seconds. When the pass-through is enabled by setting the SERIAL_PASS1 and SERIAL_PASS2 parameters then it remains in effect until no data comes from the first port for SERIAL_PASSTIMO seconds. This allows the port to revent to its normal usage (such as MAVLink connection to a GCS) when it is no longer needed. A value of 0 means no timeout. A value of -1 means no timeout and the SERIAL_PASS2 parameter is not reset on reboot.
336 : // @Range: -1 120
337 : // @Units: s
338 : // @User: Advanced
339 : AP_GROUPINFO("_PASSTIMO", 22, AP_SerialManager, passthru_timeout, 15),
340 :
341 : #if HAL_HAVE_SERIAL7_PARAMS
342 : // @Param: 7_PROTOCOL
343 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
344 : // @DisplayName: Serial7 protocol selection
345 : // @Description: Control what protocol Serial7 port should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
346 : AP_GROUPINFO("7_PROTOCOL", 23, AP_SerialManager, state[7].protocol, DEFAULT_SERIAL7_PROTOCOL),
347 :
348 : // @Param: 7_BAUD
349 : // @CopyFieldsFrom: SERIAL1_BAUD
350 : // @DisplayName: Serial 7 Baud Rate
351 : // @Description: The baud rate used for Serial7. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
352 : AP_GROUPINFO("7_BAUD", 24, AP_SerialManager, state[7].baud, DEFAULT_SERIAL7_BAUD),
353 :
354 : // @Param: 7_OPTIONS
355 : // @CopyFieldsFrom: SERIAL1_OPTIONS
356 : // @DisplayName: Serial7 options
357 : AP_GROUPINFO("7_OPTIONS", 25, AP_SerialManager, state[7].options, 0),
358 : #endif
359 :
360 : #if HAL_HAVE_SERIAL8_PARAMS
361 : // @Param: 8_PROTOCOL
362 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
363 : // @DisplayName: Serial8 protocol selection
364 : // @Description: Control what protocol Serial8 port should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
365 : AP_GROUPINFO("8_PROTOCOL", 26, AP_SerialManager, state[8].protocol, DEFAULT_SERIAL8_PROTOCOL),
366 :
367 : // @Param: 8_BAUD
368 : // @CopyFieldsFrom: SERIAL1_BAUD
369 : // @DisplayName: Serial 8 Baud Rate
370 : // @Description: The baud rate used for Serial8. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
371 : AP_GROUPINFO("8_BAUD", 27, AP_SerialManager, state[8].baud, DEFAULT_SERIAL8_BAUD),
372 :
373 : // @Param: 8_OPTIONS
374 : // @CopyFieldsFrom: SERIAL1_OPTIONS
375 : // @DisplayName: Serial8 options
376 : AP_GROUPINFO("8_OPTIONS", 28, AP_SerialManager, state[8].options, 0),
377 : #endif
378 :
379 : #if HAL_HAVE_SERIAL9_PARAMS
380 : // @Param: 9_PROTOCOL
381 : // @CopyFieldsFrom: SERIAL1_PROTOCOL
382 : // @DisplayName: Serial9 protocol selection
383 : // @Description: Control what protocol Serial9 port should be used for. Note that the Frsky options require external converter hardware. See the wiki for details.
384 : AP_GROUPINFO("9_PROTOCOL", 29, AP_SerialManager, state[9].protocol, DEFAULT_SERIAL9_PROTOCOL),
385 :
386 : // @Param: 9_BAUD
387 : // @CopyFieldsFrom: SERIAL1_BAUD
388 : // @DisplayName: Serial 9 Baud Rate
389 : // @Description: The baud rate used for Serial8. Most stm32-based boards can support rates of up to 1500. If you setup a rate you cannot support and then can't connect to your board you should load a firmware from a different vehicle type. That will reset all your parameters to defaults.
390 : AP_GROUPINFO("9_BAUD", 30, AP_SerialManager, state[9].baud, DEFAULT_SERIAL9_BAUD),
391 :
392 : // @Param: 9_OPTIONS
393 : // @CopyFieldsFrom: SERIAL1_OPTIONS
394 : // @DisplayName: Serial9 options
395 : AP_GROUPINFO("9_OPTIONS", 31, AP_SerialManager, state[9].options, DEFAULT_SERIAL9_OPTIONS),
396 : #endif
397 :
398 : AP_GROUPEND
399 : };
400 :
401 : // singleton instance
402 : AP_SerialManager *AP_SerialManager::_singleton;
403 :
404 : // Constructor
405 23078 : AP_SerialManager::AP_SerialManager()
406 : {
407 2098 : _singleton = this;
408 : // setup parameter defaults
409 2098 : AP_Param::setup_object_defaults(this, var_info);
410 2098 : }
411 :
412 : // init_console - initialise console at default baud rate
413 4188 : void AP_SerialManager::init_console()
414 : {
415 : // initialise console immediately at default size and baud
416 : #if SERIALMANAGER_NUM_PORTS > 0
417 4188 : if (!init_console_done) {
418 2094 : init_console_done = true;
419 2094 : hal.serial(0)->begin(DEFAULT_SERIAL0_BAUD,
420 : AP_SERIALMANAGER_CONSOLE_BUFSIZE_RX,
421 : AP_SERIALMANAGER_CONSOLE_BUFSIZE_TX);
422 : }
423 : #endif
424 4188 : }
425 :
426 : // init - // init - initialise serial ports
427 2094 : void AP_SerialManager::init()
428 : {
429 2094 : convert_parameters();
430 :
431 : // reset passthru port2 on boot if timeout is not -1
432 2094 : if (passthru_timeout != -1) {
433 2094 : passthru_port2.set_and_save_ifchanged(-1);
434 : }
435 :
436 : #ifdef HAL_OTG1_CONFIG
437 : /*
438 : prevent users from changing USB protocol to other than
439 : MAVLink. This fixes an issue where users trying to get SLCAN
440 : change SERIAL0_PROTOCOL to 22 and find they can no longer connect
441 : */
442 : if (state[0].protocol != SerialProtocol_MAVLink &&
443 : state[0].protocol != SerialProtocol_MAVLink2) {
444 : state[0].protocol.set(SerialProtocol_MAVLink2);
445 : }
446 : #endif
447 :
448 2094 : init_console();
449 :
450 : // initialise serial ports
451 16752 : for (uint8_t i=1; i<SERIALMANAGER_NUM_PORTS; i++) {
452 14658 : auto *uart = hal.serial(i);
453 :
454 14658 : state[i].idx = i;
455 :
456 14658 : if (uart != nullptr) {
457 14658 : set_options(i);
458 14658 : switch (state[i].protocol) {
459 6164 : case SerialProtocol_None:
460 : #if HAL_GCS_ENABLED
461 : // disable RX and TX pins in case they are shared
462 : // with another peripheral (eg. RCIN pin). We
463 : // don't do this if GCS is not enabled as in that
464 : // case we don't have serialmanager parameters and
465 : // this would prevent AP_Periph from using a GPS
466 6164 : uart->disable_rxtx();
467 : #endif
468 6164 : break;
469 4234 : case SerialProtocol_Console:
470 : case SerialProtocol_MAVLink:
471 : case SerialProtocol_MAVLink2:
472 : case SerialProtocol_MAVLinkHL:
473 4234 : uart->begin(state[i].baudrate(),
474 : AP_SERIALMANAGER_MAVLINK_BUFSIZE_RX,
475 : AP_SERIALMANAGER_MAVLINK_BUFSIZE_TX);
476 4234 : break;
477 1 : case SerialProtocol_FrSky_D:
478 : // Note baudrate is hardcoded to 9600
479 1 : state[i].baud.set_and_default(AP_SERIALMANAGER_FRSKY_D_BAUD/1000); // update baud param in case user looks at it
480 : // begin is handled by AP_Frsky_telem library
481 1 : break;
482 4 : case SerialProtocol_FrSky_SPort:
483 : case SerialProtocol_FrSky_SPort_Passthrough:
484 : // Note baudrate is hardcoded to 57600
485 4 : state[i].baud.set_and_default(AP_SERIALMANAGER_FRSKY_SPORT_BAUD/1000); // update baud param in case user looks at it
486 : // begin is handled by AP_Frsky_telem library
487 4 : break;
488 4112 : case SerialProtocol_GPS:
489 : case SerialProtocol_GPS2:
490 4112 : uart->begin(state[i].baudrate(),
491 : AP_SERIALMANAGER_GPS_BUFSIZE_RX,
492 : AP_SERIALMANAGER_GPS_BUFSIZE_TX);
493 4112 : break;
494 0 : case SerialProtocol_AlexMos:
495 : // Note baudrate is hardcoded to 115200
496 0 : state[i].baud.set_and_default(AP_SERIALMANAGER_ALEXMOS_BAUD / 1000); // update baud param in case user looks at it
497 0 : uart->begin(AP_SERIALMANAGER_ALEXMOS_BAUD,
498 : AP_SERIALMANAGER_ALEXMOS_BUFSIZE_RX,
499 : AP_SERIALMANAGER_ALEXMOS_BUFSIZE_TX);
500 0 : break;
501 3 : case SerialProtocol_Gimbal:
502 : // Note baudrate is hardcoded to 115200
503 3 : state[i].baud.set_and_default(AP_SERIALMANAGER_GIMBAL_BAUD / 1000); // update baud param in case user looks at it
504 3 : uart->begin(state[i].baudrate(),
505 : AP_SERIALMANAGER_GIMBAL_BUFSIZE_RX,
506 : AP_SERIALMANAGER_GIMBAL_BUFSIZE_TX);
507 3 : break;
508 0 : case SerialProtocol_Aerotenna_USD1:
509 0 : state[i].protocol.set_and_save(SerialProtocol_Rangefinder);
510 0 : break;
511 0 : case SerialProtocol_Sbus1:
512 : // initialised within library
513 0 : break;
514 0 : case SerialProtocol_ESCTelemetry:
515 : // ESC telemetry protocol from BLHeli32 ESCs. Note that baudrate is hardcoded to 115200
516 0 : state[i].baud.set_and_default(115200 / 1000);
517 0 : uart->begin(state[i].baudrate(), 30, 30);
518 0 : uart->set_flow_control(AP_HAL::UARTDriver::FLOW_CONTROL_DISABLE);
519 0 : break;
520 :
521 0 : case SerialProtocol_Robotis:
522 0 : uart->begin(state[i].baudrate(),
523 : AP_SERIALMANAGER_ROBOTIS_BUFSIZE_RX,
524 : AP_SERIALMANAGER_ROBOTIS_BUFSIZE_TX);
525 0 : uart->set_unbuffered_writes(true);
526 0 : uart->set_flow_control(AP_HAL::UARTDriver::FLOW_CONTROL_DISABLE);
527 0 : break;
528 :
529 0 : case SerialProtocol_SLCAN:
530 0 : uart->begin(state[i].baudrate(),
531 : AP_SERIALMANAGER_SLCAN_BUFSIZE_RX,
532 : AP_SERIALMANAGER_SLCAN_BUFSIZE_TX);
533 0 : break;
534 :
535 : #if AP_RCPROTOCOL_ENABLED
536 1 : case SerialProtocol_RCIN:
537 1 : if (!AP::RC().has_uart()) {
538 1 : AP::RC().add_uart(uart);
539 : } else {
540 0 : GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "SERIAL%u_PROTOCOL: duplicate RCIN not permitted", i);
541 : }
542 :
543 1 : break;
544 : #endif
545 :
546 2 : case SerialProtocol_EFI:
547 2 : state[i].baud.set_default(AP_SERIALMANAGER_EFI_MS_BAUD);
548 2 : uart->begin(state[i].baudrate(),
549 : AP_SERIALMANAGER_EFI_MS_BUFSIZE_RX,
550 : AP_SERIALMANAGER_EFI_MS_BUFSIZE_TX);
551 2 : uart->set_flow_control(AP_HAL::UARTDriver::FLOW_CONTROL_DISABLE);
552 2 : break;
553 :
554 6 : case SerialProtocol_Generator:
555 6 : break;
556 : #if HAL_MSP_ENABLED
557 6 : case SerialProtocol_MSP:
558 : case SerialProtocol_DJI_FPV:
559 : case SerialProtocol_MSP_DisplayPort:
560 : // baudrate defaults to 115200
561 6 : state[i].baud.set_default(AP_SERIALMANAGER_MSP_BAUD/1000);
562 6 : uart->begin(state[i].baudrate(),
563 : AP_SERIALMANAGER_MSP_BUFSIZE_RX,
564 : AP_SERIALMANAGER_MSP_BUFSIZE_TX);
565 6 : uart->set_flow_control(AP_HAL::UARTDriver::FLOW_CONTROL_DISABLE);
566 : // Note init is handled by AP_MSP
567 6 : break;
568 : #endif
569 :
570 : #if AP_SERIALMANAGER_IMUOUT_ENABLED
571 0 : case SerialProtocol_IMUOUT:
572 0 : uart->begin(state[i].baudrate(),
573 : AP_SERIALMANAGER_IMUOUT_BUFSIZE_RX,
574 : AP_SERIALMANAGER_IMUOUT_BUFSIZE_TX);
575 0 : AP::ins().set_imu_out_uart(uart);
576 0 : uart->set_unbuffered_writes(true);
577 0 : break;
578 : #endif
579 : #if AP_NETWORKING_BACKEND_PPP
580 : case SerialProtocol_PPP:
581 : break;
582 : #endif
583 0 : case SerialProtocol_IOMCU:
584 : // nothing to do, AP_IOMCU handles this
585 0 : break;
586 125 : default:
587 125 : uart->begin(state[i].baudrate());
588 : }
589 : }
590 : }
591 2094 : }
592 :
593 2094 : void AP_SerialManager::convert_parameters()
594 : {
595 : // PARAMETER_CONVERSION - Added: Jun-2025 for ArduPilot-4.7
596 23034 : for (auto &_state : state) {
597 20940 : _state.options.convert_parameter_width(AP_PARAM_INT16);
598 : }
599 2094 : }
600 :
601 41691263 : const AP_SerialManager::UARTState *AP_SerialManager::find_protocol_instance(enum SerialProtocol protocol, uint8_t instance) const
602 : {
603 41691263 : uint8_t found_instance = 0;
604 :
605 : // search for matching protocol
606 375121766 : for(uint8_t i=0; i<SERIALMANAGER_NUM_PORTS; i++) {
607 333445537 : if (protocol_match(protocol, (enum SerialProtocol)state[i].protocol.get())) {
608 34433 : if (found_instance == instance) {
609 15034 : return &state[i];
610 : }
611 19399 : found_instance++;
612 : }
613 : }
614 :
615 : #if AP_SERIALMANAGER_REGISTER_ENABLED
616 41801305 : for (auto p = registered_ports; p; p = p->next) {
617 125102 : if (protocol_match(protocol, (enum SerialProtocol)p->state.protocol.get())) {
618 66 : if (found_instance == instance) {
619 26 : return &p->state;
620 : }
621 40 : found_instance++;
622 : }
623 : }
624 : #endif
625 :
626 : // if we got this far we did not find the uart
627 41676203 : return nullptr;
628 : }
629 :
630 : // find_serial - searches available serial ports for the first instance that allows the given protocol
631 : // instance should be zero if searching for the first instance, 1 for the second, etc
632 : // returns uart on success, nullptr if a serial port cannot be found
633 41539853 : AP_HAL::UARTDriver *AP_SerialManager::find_serial(enum SerialProtocol protocol, uint8_t instance) const
634 : {
635 41539853 : const struct UARTState *_state = find_protocol_instance(protocol, instance);
636 41539853 : if (_state == nullptr) {
637 41531328 : return nullptr;
638 : }
639 8525 : const uint8_t serial_idx = _state->idx;
640 :
641 : // set options before any user does begin()
642 8525 : AP_HAL::UARTDriver *port = hal.serial(serial_idx);
643 :
644 : #if AP_SERIALMANAGER_REGISTER_ENABLED
645 8525 : if (port == nullptr) {
646 : // look for a registered port
647 28 : for (auto p = registered_ports; p; p = p->next) {
648 28 : if (p->state.idx == serial_idx) {
649 14 : port = p;
650 14 : break;
651 : }
652 : }
653 : }
654 : #endif
655 :
656 8525 : if (port) {
657 8525 : port->set_options(_state->options);
658 : }
659 8525 : return port;
660 : }
661 :
662 : // have_serial - return true if we have the given serial protocol configured
663 144910 : bool AP_SerialManager::have_serial(enum SerialProtocol protocol, uint8_t instance) const
664 : {
665 144910 : return find_protocol_instance(protocol, instance) != nullptr;
666 : }
667 :
668 : // find_baudrate - searches available serial ports for the first instance that allows the given protocol
669 : // instance should be zero if searching for the first instance, 1 for the second, etc
670 : // returns baudrate on success, 0 if a serial port cannot be found
671 95 : uint32_t AP_SerialManager::find_baudrate(enum SerialProtocol protocol, uint8_t instance) const
672 : {
673 95 : const struct UARTState *_state = find_protocol_instance(protocol, instance);
674 95 : if (_state == nullptr) {
675 0 : return 0;
676 : }
677 95 : return _state->baudrate();
678 : }
679 :
680 3 : void AP_SerialManager::set_and_default_baud(enum SerialProtocol protocol, uint8_t instance, uint32_t _baud)
681 : {
682 3 : const struct UARTState *_state = find_protocol_instance(protocol, instance);
683 3 : if (_state == nullptr) {
684 0 : return;
685 : }
686 3 : state->baud.set_and_default(_baud);
687 : }
688 :
689 : // find_portnum - find port number (SERIALn index) for a protocol and instance, -1 for not found
690 62 : int8_t AP_SerialManager::find_portnum(enum SerialProtocol protocol, uint8_t instance) const
691 : {
692 62 : const struct UARTState *_state = find_protocol_instance(protocol, instance);
693 62 : if (_state == nullptr) {
694 0 : return -1;
695 : }
696 62 : return int8_t(_state->idx);
697 : }
698 :
699 : // get_serial_by_id - gets serial by serial id
700 0 : AP_HAL::UARTDriver *AP_SerialManager::get_serial_by_id(uint8_t id)
701 : {
702 0 : if (id < SERIALMANAGER_NUM_PORTS) {
703 0 : return hal.serial(id);
704 : }
705 : #if AP_SERIALMANAGER_REGISTER_ENABLED
706 0 : for (auto p = registered_ports; p; p = p->next) {
707 0 : if (p->state.idx == id) {
708 0 : return (AP_HAL::UARTDriver *)p;
709 : }
710 : }
711 : #endif
712 0 : return nullptr;
713 : }
714 :
715 : /*
716 : get a UARTState by index
717 : */
718 0 : const AP_SerialManager::UARTState *AP_SerialManager::get_state_by_id(uint8_t id) const
719 : {
720 0 : if (id < SERIALMANAGER_NUM_PORTS) {
721 0 : return &state[id];
722 : }
723 : #if AP_SERIALMANAGER_REGISTER_ENABLED
724 0 : for (auto p = registered_ports; p; p = p->next) {
725 0 : if (p->state.idx == id) {
726 0 : return &p->state;
727 : }
728 : }
729 : #endif
730 0 : return nullptr;
731 : }
732 :
733 : /*
734 : * map from a 16 bit EEPROM baud rate to a real baud rate. For
735 : * stm32-based boards we can do 1.5MBit, although 921600 is more
736 : * reliable.
737 : */
738 14919 : uint32_t AP_SerialManager::map_baudrate(int32_t rate)
739 : {
740 14919 : if (rate <= 0) {
741 10 : rate = 57;
742 : }
743 14919 : switch (rate) {
744 0 : case 1: return 1200;
745 0 : case 2: return 2400;
746 0 : case 4: return 4800;
747 0 : case 9: return 9600;
748 0 : case 19: return 19200;
749 6 : case 38: return 38400;
750 8515 : case 57: return 57600;
751 0 : case 100: return 100000;
752 0 : case 111: return 111100;
753 2127 : case 115: return 115200;
754 4133 : case 230: return 230400;
755 0 : case 256: return 256000;
756 0 : case 460: return 460800;
757 0 : case 500: return 500000;
758 0 : case 921: return 921600;
759 0 : case 1500: return 1500000;
760 0 : case 2000: return 2000000;
761 : }
762 :
763 138 : if (rate > 2000) {
764 : // assume it is a direct baudrate. This allows for users to
765 : // set an exact baudrate as long as it is over 2000 baud
766 138 : return (uint32_t)rate;
767 : }
768 :
769 : // otherwise allow any other kbaud rate
770 0 : return rate*1000;
771 : }
772 :
773 : // protocol_match - returns true if the protocols match
774 333570639 : bool AP_SerialManager::protocol_match(enum SerialProtocol protocol1, enum SerialProtocol protocol2) const
775 : {
776 : // check for obvious match
777 333570639 : if (protocol1 == protocol2) {
778 2498 : return true;
779 : }
780 :
781 : // mavlink match
782 333568141 : if (((protocol1 == SerialProtocol_MAVLink) || (protocol1 == SerialProtocol_MAVLink2) || (protocol1 == SerialProtocol_MAVLinkHL)) &&
783 42669 : ((protocol2 == SerialProtocol_MAVLink) || (protocol2 == SerialProtocol_MAVLink2) || (protocol2 == SerialProtocol_MAVLinkHL))) {
784 32001 : return true;
785 : }
786 :
787 : // gps match
788 333536140 : if (((protocol1 == SerialProtocol_GPS) || (protocol1 == SerialProtocol_GPS2)) &&
789 6126 : ((protocol2 == SerialProtocol_GPS) || (protocol2 == SerialProtocol_GPS2))) {
790 0 : return true;
791 : }
792 :
793 333536140 : return false;
794 : }
795 :
796 : // setup any special options
797 14658 : void AP_SerialManager::set_options(uint16_t i)
798 : {
799 14658 : struct UARTState &opt = state[i];
800 : // pass through to HAL
801 14658 : if (!hal.serial(i)->set_options(opt.options)) {
802 0 : DEV_PRINTF("Unable to setup options for Serial%u\n", i);
803 : }
804 14658 : }
805 :
806 : // get the passthru ports if enabled
807 41931458 : bool AP_SerialManager::get_passthru(AP_HAL::UARTDriver *&port1, AP_HAL::UARTDriver *&port2, uint8_t &timeout_s,
808 : uint32_t &baud1, uint32_t &baud2)
809 : {
810 41931458 : if (passthru_port2 < 0 ||
811 0 : passthru_port1 < 0) {
812 41931458 : return false;
813 : }
814 0 : port1 = get_serial_by_id(passthru_port1);
815 0 : port2 = get_serial_by_id(passthru_port2);
816 0 : if (port1 == nullptr || port2 == nullptr) {
817 0 : return false;
818 : }
819 0 : const auto *state1 = get_state_by_id(passthru_port1);
820 0 : const auto *state2 = get_state_by_id(passthru_port2);
821 0 : if (!state1 || !state2) {
822 0 : return false;
823 : }
824 0 : baud1 = state1->baudrate();
825 0 : baud2 = state2->baudrate();
826 0 : timeout_s = MAX(passthru_timeout, 0);
827 0 : return true;
828 : }
829 :
830 : // disable passthru by settings SERIAL_PASS2 to -1
831 0 : void AP_SerialManager::disable_passthru(void)
832 : {
833 0 : passthru_port2.set_and_notify(-1);
834 0 : }
835 :
836 : // accessor for AP_Periph to set baudrate and type
837 0 : void AP_SerialManager::set_protocol_and_baud(uint8_t sernum, enum SerialProtocol protocol, uint32_t baudrate)
838 : {
839 0 : if (sernum < SERIALMANAGER_NUM_PORTS) {
840 0 : state[sernum].protocol.set_and_default(protocol);
841 0 : state[sernum].baud.set_and_default(baudrate);
842 : }
843 0 : }
844 140684 : bool AP_SerialManager::pre_arm_checks(char *failure_msg, const uint8_t failure_msg_len)
845 : {
846 : // PARAMETER_CONVERSION - Added: Jun-2025 for ArduPilot-4.7
847 : // ArduPilot 4.7 pre-arm fails if either bit is set when conversion should have nuked them
848 : // ArduPilot 4.8 pre-arm fails if either bit is set when conversion should have nuked them
849 : // ArduPilot 4.9 pre-arm fails if either bit is set when conversion should have nuked them
850 : // ArduPilot 4.9++ removes the pre-arm failure
851 1547524 : for (uint8_t i=0; i<ARRAY_SIZE(state); i++) {
852 1406840 : const auto &_state = state[i];
853 1406840 : if (_state.options & AP_HAL::UARTDriver::Option::OPTION_MAVLINK_NO_FORWARD_old) {
854 0 : hal.util->snprintf(failure_msg, failure_msg_len, "SERIAL%u_OPTIONS bit 10 ('no forward mavlink') must not be set; use MAVn_OPTIONS bit 1 instead", unsigned(i));
855 0 : return false;
856 : }
857 1406840 : if (_state.options & AP_HAL::UARTDriver::Option::OPTION_NOSTREAMOVERRIDE_old) {
858 0 : hal.util->snprintf(failure_msg, failure_msg_len, "SERIAL%u_OPTIONS bit 12 ('no stream overrides') must not be set; use MAVn_OPTIONS bit 2 instead", unsigned(i));
859 0 : return false;
860 : }
861 : }
862 140684 : return true;
863 : }
864 :
865 : #if AP_SERIALMANAGER_REGISTER_ENABLED
866 : /*
867 : register an external network port. It is up to the caller to use a unique id field
868 : using AP_SERIALMANAGER_NET_PORT_1 as the base id for NET_P1_*
869 : */
870 16 : void AP_SerialManager::register_port(RegisteredPort *port)
871 : {
872 16 : const auto idx = port->state.idx;
873 16 : WITH_SEMAPHORE(port_sem);
874 : /*
875 : maintain the list in ID order
876 : */
877 16 : if (registered_ports == nullptr ||
878 10 : registered_ports->state.idx >= idx) {
879 6 : port->next = registered_ports;
880 6 : registered_ports = port;
881 6 : return;
882 : }
883 17 : for (auto p = registered_ports; p; p = p->next) {
884 17 : if (p->next == nullptr || p->next->state.idx >= idx) {
885 10 : port->next = p->next;
886 10 : p->next = port;
887 10 : break;
888 : }
889 : }
890 16 : }
891 :
892 : #if HAL_LOGGING_ENABLED && HAL_UART_STATS_ENABLED
893 : // Log UART message for each registered serial port
894 149217 : void AP_SerialManager::registered_ports_log()
895 : {
896 : // Calculate time since last call
897 149217 : const uint32_t now_ms = AP_HAL::millis();
898 149217 : const uint32_t dt_ms = now_ms - registered_ports_last_log_ms;
899 149217 : registered_ports_last_log_ms = now_ms;
900 :
901 149217 : WITH_SEMAPHORE(port_sem);
902 :
903 : // Loop over ports
904 149546 : for (auto p = registered_ports; p; p = p->next) {
905 329 : p->log_stats(p->state.idx, p->state.stats, dt_ms);
906 : }
907 149217 : }
908 : #endif
909 :
910 : #endif // AP_SERIALMANAGER_REGISTER_ENABLED
911 :
912 : // Return a device id for this port
913 6340 : uint32_t AP_SerialManager::UARTState::get_device_id() const
914 : {
915 : #if AP_SERIALMANAGER_REGISTER_ENABLED
916 6340 : if (idx >= AP_SERIALMANAGER_SCR_PORT_1) {
917 : // Scripting port
918 0 : return AP_HAL::Device::make_bus_id(
919 : AP_HAL::Device::BUS_TYPE_SERIAL,
920 : 0,
921 0 : idx - AP_SERIALMANAGER_SCR_PORT_1,
922 : uint8_t(DeviceType::SCRIPTING)
923 0 : );
924 : }
925 :
926 6340 : if (idx >= AP_SERIALMANAGER_CAN_D2_PORT_1) {
927 : // CAN D2 port
928 0 : return AP_HAL::Device::make_bus_id(
929 : AP_HAL::Device::BUS_TYPE_SERIAL,
930 : 1,
931 0 : idx - AP_SERIALMANAGER_CAN_D2_PORT_1,
932 : uint8_t(DeviceType::CANBUS)
933 0 : );
934 : }
935 :
936 6340 : if (idx >= AP_SERIALMANAGER_CAN_D1_PORT_1) {
937 : // CAN D1 port
938 2 : return AP_HAL::Device::make_bus_id(
939 : AP_HAL::Device::BUS_TYPE_SERIAL,
940 : 0,
941 2 : idx - AP_SERIALMANAGER_CAN_D1_PORT_1,
942 : uint8_t(DeviceType::CANBUS)
943 2 : );
944 : }
945 :
946 6338 : if (idx >= AP_SERIALMANAGER_NET_PORT_1) {
947 : // Networking port
948 10 : return AP_HAL::Device::make_bus_id(
949 : AP_HAL::Device::BUS_TYPE_SERIAL,
950 : 0,
951 10 : idx - AP_SERIALMANAGER_NET_PORT_1,
952 : uint8_t(DeviceType::NETWORKING)
953 10 : );
954 : }
955 : #endif // AP_SERIALMANAGER_REGISTER_ENABLED
956 :
957 : // Standard port
958 6328 : return AP_HAL::Device::make_bus_id(
959 : AP_HAL::Device::BUS_TYPE_SERIAL,
960 : 0,
961 6328 : idx,
962 : uint8_t(DeviceType::UART)
963 6328 : );
964 : }
965 :
966 : namespace AP {
967 :
968 83740977 : AP_SerialManager &serialmanager()
969 : {
970 83740977 : return *AP_SerialManager::get_singleton();
971 : }
972 :
973 : }
974 :
975 : #endif // AP_SERIALMANAGER_ENABLED
|