mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-09-18 19:13:58 +00:00
B2 (HIGH): IR_Decoder::_tick — encoder->sendAccept() без null-check; у Car decoder создан с encoder==nullptr → HardFault при приёме IR_MSG_DATA_ACCEPT. Добавлен guard. B4 (MEDIUM): acceptSendTimer/isWaitingAcceptSend/addrAcceptSendTo/acceptCustomByte не инициализировались → мусор мог спонтанно дёрнуть sendAccept. Дефолты в .h. B3 (HIGH): writeToBuffer — '>' вместо '>=' → при i_dataBuffer==dataByteSizeMax*8 (304) запись dataBuffer[38] за границей 38-байтового массива (packSize==0 runaway). Валидные кадры закрываются при <=248, не затронуты. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
73 lines
2.9 KiB
C++
73 lines
2.9 KiB
C++
#pragma once
|
||
#include "IR_DecoderRaw.h"
|
||
#include "PacketTypes.h"
|
||
#include "IR_Encoder.h"
|
||
|
||
class IR_Decoder : public IR_DecoderRaw
|
||
{
|
||
private:
|
||
// static std::list<IR_Decoder *> dec_list;
|
||
static std::list<IR_Decoder*>& get_dec_list();
|
||
void _tick();
|
||
|
||
uint32_t acceptSendTimer = 0;
|
||
bool isWaitingAcceptSend = false; // B4: без инициализации мусор мог дёрнуть sendAccept при старте
|
||
uint16_t addrAcceptSendTo = 0;
|
||
|
||
uint16_t acceptDelay = IR_ResponseDelay;
|
||
uint8_t acceptCustomByte = 0;
|
||
|
||
bool extiEnabled_ = false;
|
||
bool rxExtiPreemptConfigured_ = false;
|
||
uint32_t rxExtiPreemptValue_ = 0;
|
||
|
||
public:
|
||
PacketTypes::Data gotData;
|
||
PacketTypes::DataBack gotBackData;
|
||
PacketTypes::Accept gotAccept;
|
||
PacketTypes::Request gotRequest;
|
||
PacketTypes::BasePack gotRaw;
|
||
|
||
// IR_Decoder();
|
||
/** @param enableOnConstruct true — вызвать enable() из конструктора; false — отложенный enable() (NVIC и т.д.), tick — tickThis() / tick(). */
|
||
IR_Decoder(const uint8_t pin, uint16_t addr = 0, IR_Encoder *encPair = nullptr, bool enableOnConstruct = true);
|
||
|
||
std::function<void()> operator()();
|
||
|
||
/**
|
||
* Arduino STM32: после attachInterrupt ядро выставляет свой приоритет EXTI.
|
||
* Если вызывали setReceiveExtiPreemptPriority(), здесь он применяется поверх (обычно нужен выше срочности, чем DMA ИК-TX).
|
||
* На других платформах поведение без изменений.
|
||
*/
|
||
void enable();
|
||
void disable();
|
||
|
||
#if defined(ARDUINO_ARCH_STM32) && !defined(HAL_EXTI_MODULE_DISABLED)
|
||
/**
|
||
* Задать preempt-приоритет NVIC для EXTI линии этого пина (тот же смысл, что второй аргумент CMSIS NVIC_SetPriority).
|
||
* Вызывайте до или после enable(); при активном приёме применяется сразу.
|
||
* При использовании DMA на передачу ИК preempt приёма должен быть меньше, чем у DMA TX (выше срочность прерывания).
|
||
*/
|
||
void setReceiveExtiPreemptPriority(uint32_t preempt);
|
||
#endif
|
||
|
||
bool isReceive(uint8_t type);
|
||
|
||
~IR_Decoder();
|
||
|
||
/** Обойти все экземпляры из внутреннего списка и вызвать tick у каждого. */
|
||
static void tick();
|
||
|
||
/** Tick только этого декодера (без обхода списка). Не комбинируйте с static tick() для того же экземпляра. */
|
||
void tickThis() { _tick(); }
|
||
|
||
inline void setAcceptDelay(uint16_t acceptDelay)
|
||
{
|
||
this->acceptDelay = acceptDelay;
|
||
}
|
||
inline uint16_t getAcceptDelay()
|
||
{
|
||
return this->acceptDelay;
|
||
}
|
||
};
|