mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-04-28 03:08:08 +00:00
fix longPacket sync_bit
This commit is contained in:
2
.vscode/arduino.json
vendored
2
.vscode/arduino.json
vendored
@ -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"
|
||||||
}
|
}
|
||||||
@ -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; // Счётчик ошибок синхронизации
|
||||||
|
|
||||||
|
|||||||
150
test_examples/longData/longData.ino
Normal file
150
test_examples/longData/longData.ino
Normal 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
|
||||||
Reference in New Issue
Block a user