Прошивка получает две роли, выбираемые compile-time env; общий код собирается в оба env, специфичный — через build_src_filter, без мёртвого кода неактивной роли. Роль публикуется в USB product string (CART-TX/CART-RX), по которой ПК находит нужный порт. - app_tx.cpp: как раньше формирует SBUS на локальный провод и дополнительно шлёт те же ch[16] по USB кадром CONTROL; отвечает на HELLO кадром IDENT. Старый проводной функционал не изменён. - app_rx.cpp: принимает CONTROL по USB и гонит SBUS на провод строго каждые 50 мс из последнего состояния. FAILSAFE: нет свежего CONTROL дольше 150 мс -> нейтраль с флагом failsafe (срабатывает и при обрыве USB/зависании ПК); сетевой флаг failsafe транслируется в бит SBUS. - platformio.ini: env cart_tx/cart_rx, макросы роли и USB_PRODUCT_STRING. - удалён монолитный main.cpp (логика разнесена по модулям). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
60 lines
1.6 KiB
C++
60 lines
1.6 KiB
C++
// Роль TX: к STM подключён пульт. Как и раньше, формирует SBUS на локальный
|
|
// провод (старый функционал не изменён), и ДОПОЛНИТЕЛЬНО шлёт те же значения
|
|
// каналов по USB на ПК кадром CONTROL. Отвечает на HELLO кадром IDENT.
|
|
#ifdef CART_ROLE_TX
|
|
#include <Arduino.h>
|
|
#include "sbus.h"
|
|
#include "stick.h"
|
|
#include "usb_link.h"
|
|
#include "device_id.h"
|
|
|
|
static void replyIdent() {
|
|
LinkIdent id;
|
|
id.role = ROLE_TX;
|
|
id.proto_ver = LINK_VERSION;
|
|
id.fw_ver = CART_FW_VERSION;
|
|
cartReadUid(id.uid);
|
|
usbSendIdent(&id);
|
|
}
|
|
|
|
void setup() {
|
|
usbLinkInit();
|
|
stickInit();
|
|
sbusUartInit();
|
|
}
|
|
|
|
void loop() {
|
|
// обслуживаем входящие кадры (ждём только HELLO от ПК)
|
|
LinkRxEvent ev;
|
|
do {
|
|
usbLinkPoll(&ev);
|
|
if (ev.type == LINK_HELLO)
|
|
replyIdent();
|
|
} while (ev.type != 0);
|
|
|
|
static uint32_t next = 0;
|
|
static uint32_t seq = 0;
|
|
uint32_t now = millis();
|
|
if (now < next)
|
|
return;
|
|
next = now + FRAME_PERIOD_MS;
|
|
|
|
uint16_t ch[16];
|
|
float fwd, right;
|
|
stickComputeChannels(ch, &fwd, &right);
|
|
|
|
// 1) локальный провод к драйверу — как раньше
|
|
uint8_t frame[25];
|
|
sbusPack(frame, ch);
|
|
sbusSendFrame(frame);
|
|
|
|
// 2) те же каналы по USB на ПК
|
|
LinkControl c;
|
|
c.seq = seq++;
|
|
c.t_ms = now;
|
|
c.flags = 0;
|
|
memcpy(c.ch, ch, sizeof(c.ch));
|
|
usbSendControl(&c);
|
|
}
|
|
#endif // CART_ROLE_TX
|