@@ -46,75 +46,38 @@ using namespace time_literals;
46
46
47
47
DShotTelemetry::~DShotTelemetry ()
48
48
{
49
- deinit ();
49
+ _uart. close ();
50
50
}
51
51
52
- int DShotTelemetry::init (const char *uart_device , bool swap_rxtx)
52
+ int DShotTelemetry::init (const char *port , bool swap_rxtx)
53
53
{
54
- int ret = OK;
55
- deinit ();
56
- _uart_fd = ::open (uart_device, O_RDONLY | O_NOCTTY);
57
-
58
- if (_uart_fd < 0 ) {
59
- PX4_ERR (" failed to open serial port: %s err: %d" , uart_device, errno);
60
- return -errno;
54
+ if (!_uart.setPort (port)) {
55
+ PX4_ERR (" Error configuring port %s" , port);
56
+ return PX4_ERROR;
61
57
}
62
58
63
- ret = setBaudrate (DSHOT_TELEMETRY_UART_BAUDRATE);
64
-
65
- if (ret) {
66
- PX4_ERR (" failed to set baurate: %s err: %d" , uart_device, ret);
67
- return ret;
59
+ if (!_uart.setBaudrate (DSHOT_TELEMETRY_UART_BAUDRATE)) {
60
+ PX4_ERR (" Error setting baudrate on %s" , port);
61
+ return PX4_ERROR;
68
62
}
69
63
70
64
if (swap_rxtx) {
71
- // Swap RX/TX pins if the device supports it
72
- ret = ioctl (_uart_fd, TIOCSSWAP, SER_SWAP_ENABLED);
73
-
74
- // For other devices we can still place RX on TX pin via half-duplex single-wire mode
75
- if (ret) { ret = ioctl (_uart_fd, TIOCSSINGLEWIRE, SER_SINGLEWIRE_ENABLED); }
76
-
77
- if (ret) {
78
- PX4_ERR (" failed to swap rx/tx pins: %s err: %d" , uart_device, ret);
79
- return ret;
65
+ if (!_uart.setSwapRxTxMode ()) {
66
+ PX4_ERR (" Error swapping TX/RX" );
67
+ return PX4_ERROR;
80
68
}
81
69
}
82
70
83
- _num_timeouts = 0 ;
84
- _num_successful_responses = 0 ;
85
- _current_motor_index_request = -1 ;
86
-
87
- return ret;
88
- }
89
-
90
- void DShotTelemetry::deinit ()
91
- {
92
- if (_uart_fd >= 0 ) {
93
- close (_uart_fd);
94
- _uart_fd = -1 ;
71
+ if (! _uart.open ()) {
72
+ PX4_ERR (" Error opening %s" , port);
73
+ return PX4_ERROR;
95
74
}
96
- }
97
75
98
- int DShotTelemetry::redirectOutput (OutputBuffer &buffer)
99
- {
100
- if (expectingData ()) {
101
- // Error: cannot override while we already expect data
102
- return -EBUSY;
103
- }
104
-
105
- _current_motor_index_request = buffer.motor_index ;
106
- _current_request_start = hrt_absolute_time ();
107
- _redirect_output = &buffer;
108
- _redirect_output->buf_pos = 0 ;
109
- return 0 ;
76
+ return PX4_OK;
110
77
}
111
78
112
79
int DShotTelemetry::update (int num_motors)
113
80
{
114
- if (_uart_fd < 0 ) {
115
- return -1 ;
116
- }
117
-
118
81
if (_current_motor_index_request == -1 ) {
119
82
// nothing in progress, start a request
120
83
_current_motor_index_request = 0 ;
@@ -124,10 +87,9 @@ int DShotTelemetry::update(int num_motors)
124
87
}
125
88
126
89
// read from the uart. This must be non-blocking, so check first if there is data available
127
- int bytes_available = 0 ;
128
- int ret = ioctl (_uart_fd, FIONREAD, (unsigned long )&bytes_available);
90
+ int bytes_available = _uart.bytesAvailable ();
129
91
130
- if (ret != 0 || bytes_available <= 0 ) {
92
+ if (bytes_available <= 0 ) {
131
93
// no data available. Check for a timeout
132
94
const hrt_abstime now = hrt_absolute_time ();
133
95
@@ -149,13 +111,12 @@ int DShotTelemetry::update(int num_motors)
149
111
return -1 ;
150
112
}
151
113
152
- const int buf_length = ESC_FRAME_SIZE;
153
- uint8_t buf[buf_length] ;
114
+ uint8_t buf[ ESC_FRAME_SIZE] ;
115
+ int bytes = _uart. read ( buf, sizeof (buf)) ;
154
116
155
- int num_read = read (_uart_fd, buf, buf_length);
156
- ret = -1 ;
117
+ int ret = -1 ;
157
118
158
- for (int i = 0 ; i < num_read && ret == -1 ; ++i) {
119
+ for (int i = 0 ; i < bytes && ret == -1 ; ++i) {
159
120
if (_redirect_output) {
160
121
_redirect_output->buffer [_redirect_output->buf_pos ++] = buf[i];
161
122
@@ -223,30 +184,27 @@ void DShotTelemetry::printStatus() const
223
184
PX4_INFO (" Number of CRC errors: %i" , _num_checksum_errors);
224
185
}
225
186
226
- uint8_t DShotTelemetry::updateCrc8 ( uint8_t crc , uint8_t crc_seed )
187
+ uint8_t DShotTelemetry::crc8 ( const uint8_t *buf , uint8_t len )
227
188
{
228
- uint8_t crc_u = crc ^ crc_seed;
189
+ auto update_crc8 = [](uint8_t crc, uint8_t crc_seed) {
190
+ uint8_t crc_u = crc ^ crc_seed;
229
191
230
- for (int i = 0 ; i < 8 ; ++i) {
231
- crc_u = (crc_u & 0x80 ) ? 0x7 ^ (crc_u << 1 ) : (crc_u << 1 );
232
- }
233
-
234
- return crc_u;
235
- }
192
+ for (int i = 0 ; i < 8 ; ++i) {
193
+ crc_u = (crc_u & 0x80 ) ? 0x7 ^ (crc_u << 1 ) : (crc_u << 1 );
194
+ }
236
195
196
+ return crc_u;
197
+ };
237
198
238
- uint8_t DShotTelemetry::crc8 (const uint8_t *buf, uint8_t len)
239
- {
240
199
uint8_t crc = 0 ;
241
200
242
201
for (int i = 0 ; i < len; ++i) {
243
- crc = updateCrc8 (buf[i], crc);
202
+ crc = update_crc8 (buf[i], crc);
244
203
}
245
204
246
205
return crc;
247
206
}
248
207
249
-
250
208
void DShotTelemetry::requestNextMotor (int num_motors)
251
209
{
252
210
_current_motor_index_request = (_current_motor_index_request + 1 ) % num_motors;
@@ -418,83 +376,4 @@ void DShotTelemetry::decodeAndPrintEscInfoPacket(const OutputBuffer &buffer)
418
376
PX4_INFO (" LED %d: %s" , i, setting ? (setting == 255 ? " unsupported" : " on" ) : " off" );
419
377
}
420
378
}
421
-
422
-
423
- }
424
-
425
- int DShotTelemetry::setBaudrate (unsigned baud)
426
- {
427
- int speed;
428
-
429
- switch (baud) {
430
- case 9600 : speed = B9600; break ;
431
-
432
- case 19200 : speed = B19200; break ;
433
-
434
- case 38400 : speed = B38400; break ;
435
-
436
- case 57600 : speed = B57600; break ;
437
-
438
- case 115200 : speed = B115200; break ;
439
-
440
- case 230400 : speed = B230400; break ;
441
-
442
- default :
443
- return -EINVAL;
444
- }
445
-
446
- struct termios uart_config;
447
-
448
- int termios_state;
449
-
450
- /* fill the struct for the new configuration */
451
- tcgetattr (_uart_fd, &uart_config);
452
-
453
- //
454
- // Input flags - Turn off input processing
455
- //
456
- // convert break to null byte, no CR to NL translation,
457
- // no NL to CR translation, don't mark parity errors or breaks
458
- // no input parity check, don't strip high bit off,
459
- // no XON/XOFF software flow control
460
- //
461
- uart_config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
462
- INLCR | PARMRK | INPCK | ISTRIP | IXON);
463
- //
464
- // Output flags - Turn off output processing
465
- //
466
- // no CR to NL translation, no NL to CR-NL translation,
467
- // no NL to CR translation, no column 0 CR suppression,
468
- // no Ctrl-D suppression, no fill characters, no case mapping,
469
- // no local output processing
470
- //
471
- // config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
472
- // ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
473
- uart_config.c_oflag = 0 ;
474
-
475
- //
476
- // No line processing
477
- //
478
- // echo off, echo newline off, canonical mode off,
479
- // extended input processing off, signal chars off
480
- //
481
- uart_config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
482
-
483
- /* no parity, one stop bit, disable flow control */
484
- uart_config.c_cflag &= ~(CSTOPB | PARENB | CRTSCTS);
485
-
486
- /* set baud rate */
487
- if ((termios_state = cfsetispeed (&uart_config, speed)) < 0 ) {
488
- return -errno;
489
- }
490
-
491
- if ((termios_state = cfsetospeed (&uart_config, speed)) < 0 ) {
492
- return -errno;
493
- }
494
-
495
- if ((termios_state = tcsetattr (_uart_fd, TCSANOW, &uart_config)) < 0 ) {
496
- return -errno;
497
- }
498
-
499
- return 0 ;
500
379
}
0 commit comments