fix longPacket sync_bit

This commit is contained in:
2026-04-13 14:42:50 +03:00
parent f8daa68381
commit 57f79b35c7
3 changed files with 153 additions and 3 deletions

View File

@ -1,5 +1,5 @@
{ {
"board": "STMicroelectronics:stm32:GenF4", "board": "STMicroelectronics:stm32:GenG4",
"port": "COM17", "port": "COM17",
"prebuild": "if exist bin rd /s /q bin" "prebuild": "if exist bin rd /s /q bin"
} }

View File

@ -187,8 +187,8 @@ bool isReciveRaw;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации
uint16_t i_dataBuffer; // Счётчик буфера данных uint16_t i_dataBuffer; // Счётчик буфера данных
uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData uint16_t nextControlBit = bitPerByte; // Метка для смены флага isData; uint16_t нужен для длинных кадров (>24 байт total)
uint8_t i_syncBit; // Счётчик битов синхронизации uint8_t i_syncBit; // Счётчик битов синхронизации
uint8_t err_syncBit; // Счётчик ошибок синхронизации uint8_t err_syncBit; // Счётчик ошибок синхронизации

View File

@ -0,0 +1,150 @@
/*
* Тест длинной полезной нагрузки IR (0x5E + строка, как ответ версии в Car).
* Передача через DMA + TIM17 — как в машинке (Car/src/IR/IR.cpp, BoardTest/IR_DMA).
* Авто-режим: чередование total длины кадра 24/25 байт.
*/
#include "IR_Decoder.h"
#include "IR_Encoder.h"
#include "TimerStatic.h"
/** 1 — TX через DMA (STM32G4). */
#ifndef LONGDATA_USE_DMA
#define LONGDATA_USE_DMA 0
#endif
#if LONGDATA_USE_DMA
#include <IrDmaTxStm32.h>
#endif
static constexpr uint16_t kIrDeviceAddr = 0;
static constexpr uint8_t kCmdVersion = 0x5E;
static constexpr uint32_t kSerialBaud = 115200;
static constexpr uint32_t kSendPeriodMs = 500;
static constexpr uint8_t kMaxPayload = bytePerPack;
static constexpr uint8_t kMaxParamBytes = kMaxPayload - 1;
static IR_Encoder enc(PIN_IR_ENC_FORWARD, kIrDeviceAddr, nullptr);
static HardwareTimer irTimer(TIM17);
#if LONGDATA_USE_DMA
namespace {
constexpr size_t kIrDmaStreams = 1;
constexpr uint16_t kIrDmaTxWordCount = 4096U;
constexpr size_t kIrDmaTxMaxGateRuns = 1024U;
static uint32_t s_irDmaWords[kIrDmaTxWordCount];
static IR_Encoder::IR_TxGateRun s_irGateRuns[kIrDmaTxMaxGateRuns];
} // namespace
static IrDmaTxStm32<kIrDmaStreams> dmaBackend;
static bool txBusy(void * /*ctx*/) { return dmaBackend.busy(); }
static bool txStart(void * /*ctx*/, IR_Encoder *e, const uint8_t *packet, uint8_t len) {
return dmaBackend.start(e, packet, len);
}
#endif
static char s_paramAscii[kMaxParamBytes + 1];
static uint8_t s_irPayload[kMaxPayload];
static uint8_t s_irPayloadLen = 0;
static uint32_t s_lastSendMs = 0;
static bool s_sendLongerFrame = false;
// 24 байта total: msg(1)+addr(2)+addr(2)+data(17)+crc(2), где data=0x5E + 16 ASCII.
static const char kPayload16[] = "Car_v4.3.9_[12MH";
// 25 байт total: как выше, но data=0x5E + 17 ASCII.
static const char kPayload17[] = "Car_v4.3.9_[12MHz]_G491";
static void rebuildIrPayload() {
s_irPayload[0] = kCmdVersion;
size_t n = 0;
while (n < sizeof(s_paramAscii) && s_paramAscii[n]) {
++n;
}
const size_t copyLen = (n > kMaxParamBytes) ? kMaxParamBytes : n;
memcpy(s_irPayload + 1, s_paramAscii, copyLen);
s_irPayloadLen = static_cast<uint8_t>(1 + copyLen);
}
static void setAlternatingPayload() {
const char* src = s_sendLongerFrame ? kPayload17 : kPayload16;
strncpy(s_paramAscii, src, kMaxParamBytes);
s_paramAscii[kMaxParamBytes] = '\0';
s_sendLongerFrame = !s_sendLongerFrame;
}
static void sendVersionPacket() {
rebuildIrPayload();
const IR_SendResult r = enc.sendData(IR_Broadcast, s_irPayload, s_irPayloadLen);
Serial.print(F("TX 0x5E + "));
Serial.print((unsigned)(s_irPayloadLen - 1));
Serial.print(F(" B, ok="));
Serial.print(r.success ? F("1") : F("0"));
Serial.print(F(", t="));
Serial.print(r.sendTimeMs);
Serial.println(F(" ms"));
}
void setup() {
Serial.begin(kSerialBaud);
strncpy(s_paramAscii, kPayload16, kMaxParamBytes);
s_paramAscii[kMaxParamBytes] = '\0';
rebuildIrPayload();
#if LONGDATA_USE_DMA
IR_Encoder::beginClockOnly(&irTimer);
IrDmaTxStm32<kIrDmaStreams>::Config cfg;
cfg.timer = &irTimer;
cfg.streamCount = kIrDmaStreams;
cfg.streams[0].instance = DMA1_Channel1;
cfg.streams[0].irq = DMA1_Channel1_IRQn;
cfg.streams[0].dmamuxRequest = DMA_REQUEST_TIM17_UP;
cfg.streams[0].enc = &enc;
cfg.streams[0].dmaWords = s_irDmaWords;
cfg.streams[0].dmaWordCount = kIrDmaTxWordCount;
cfg.streams[0].gateRuns = s_irGateRuns;
cfg.streams[0].maxGateRuns = kIrDmaTxMaxGateRuns;
if (!dmaBackend.begin(cfg)) {
Serial.println(F("[IR_DMA] init FAILED"));
return;
}
IR_Encoder::setExternalTxBackend(txStart, txBusy, nullptr);
#elif LONGDATA_LEGACY_ISR
IR_Encoder::begin(&irTimer, 1, TIM17_IRQn, 0);
#else
IR_Encoder::begin(&irTimer, 1, TIM17_IRQn, 0);
#endif
enc.enable();
#if LONGDATA_USE_DMA
Serial.println(F("longData: DMA TX alternating 24/25 bytes"));
#elif LONGDATA_LEGACY_ISR
Serial.println(F("longData: legacy ISR TX (pre-unified FSM) 24/25 bytes"));
#else
Serial.println(F("longData: ISR TX (unified FSM) alternating 24/25 bytes"));
#endif
Serial.print(F("Auto-period ms = "));
Serial.println((unsigned long)kSendPeriodMs);
}
void loop() {
#if LONGDATA_USE_DMA
IR_Encoder::tick();
#endif
const uint32_t now = millis();
if (now - s_lastSendMs >= kSendPeriodMs) {
s_lastSendMs = now;
setAlternatingPayload();
sendVersionPacket();
}
}
#if LONGDATA_USE_DMA && defined(STM32G4xx)
extern "C" void DMA1_Channel1_IRQHandler(void) {
if (auto *p = IrDmaTxStm32<kIrDmaStreams>::instance()) {
p->irqForStream(0);
}
}
#endif