fix extra zero, docs and debag

This commit is contained in:
DashyFox 2024-01-24 16:13:03 +03:00
parent 56c207b058
commit d629b24864
3 changed files with 149 additions and 87 deletions

View File

@ -8,6 +8,7 @@
IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) { IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) {
rawBuffer = new uint8_t[bufferRawSize] { 0 }; rawBuffer = new uint8_t[bufferRawSize] { 0 };
dataBuffer = rawBuffer;
prevRise = prevFall = prevPrevFall = prevPrevRise = 0; prevRise = prevFall = prevPrevFall = prevPrevRise = 0;
start_RX(); start_RX();
} }
@ -17,21 +18,67 @@ IR_Decoder::~IR_Decoder() {
} }
void IR_Decoder::writeToBuffer(bool bit) { void IR_Decoder::writeToBuffer(bool bit) {
if (!isBufferOverflow && !isPreamb) { if (isBufferOverflow || isPreamb) return;
if (HIGH_FIRST) {
rawBuffer[(bufBitPos >> 3)] |= bit << (7 - (bufBitPos & ~(~0 << 3))); // Переключение флага, data или syncBit
}/* else { if (bufBitPos == nextControlBit) {
rawBuffer[(bufBitPos >> 3)] |= bit << (bufBitPos & ~(~0 << 3)); nextControlBit += (isData ? syncBits : bitPerByte);
} */ isData = !isData;
Serial.print(" ");
}
Serial.print(bit); Serial.print(bit);
#ifdef IRDEBUG
if (isData) { // Запись битов в dataBuffer
dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer%8);
i_dataBuffer++;
bufBitPos++;
i_syncBit = 0;
} else { // Проверка контрольных sync битов
if (i_syncBit == 0) { // Первый бит синхронизации
if (bit != dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))) {
bufBitPos++;
} else {
errorCounter++;
Serial.print("E");
// Serial.print("bit: ");Serial.println(bit);
// Serial.print("dataBuffer: ");Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3))));
}
} else { // Последующие биты синхронизации
bufBitPos++;
}
i_syncBit++;
}
// if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; }
/*
#ifdef IRDEBUG
bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1);
#endif #endif
if (isBufferOverflow) { //TODO: Буффер переполнен! if (isBufferOverflow) { //TODO: Буффер переполнен!
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//const auto testval = bufferBitSizeMax; //const auto testval = bufferBitSizeMax;
if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) {
switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) {
@ -79,11 +126,9 @@ void IR_Decoder::writeToBuffer(bool bit) {
default: default:
break; break;
} }
} }/**/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; }
bufBitPos++;
}
} }
uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { uint8_t* IR_Decoder::getDataBuffer(bool reset = false) {
@ -149,10 +194,20 @@ bool IR_Decoder::crcCheck(uint8_t len) {
} }
void IR_Decoder::start_RX() { void IR_Decoder::start_RX() {
// Serial.println();
// Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN));
// Serial.println();
resetAvaliable(); resetAvaliable();
isBufferOverflow = false; isBufferOverflow = false;
memset(rawBuffer, 0x00, bufferRawSize); memset(rawBuffer, 0x00, bufferRawSize);
bufBitPos = 0; bufBitPos = 0;
isData = true;
i_dataBuffer = 0;
nextControlBit = bitPerByte;
i_syncBit = 0;
} }
void IR_Decoder::resetAvaliable() { void IR_Decoder::resetAvaliable() {
@ -308,14 +363,14 @@ void IR_Decoder::tick() {
void IR_Decoder::isr() { // в прерывании вызываем isr() void IR_Decoder::isr() { // в прерывании вызываем isr()
if (isPairSending) return; if (isPairSending) return;
frontBuffer[currentFrontBufferWriteIndex].next = nullptr; subBuffer[currentSubBufferIndex].next = nullptr;
frontBuffer[currentFrontBufferWriteIndex].dir = (PIND >> isrPin) & 1; subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1;
frontBuffer[currentFrontBufferWriteIndex].time = micros(); subBuffer[currentSubBufferIndex].time = micros();
if (firstUnHandledFront == nullptr) { if (firstUnHandledFront == nullptr) {
firstUnHandledFront = &frontBuffer[currentFrontBufferWriteIndex]; // Если нет необработанных данных - добавляем их firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их
} else { } else {
if (firstUnHandledFront == &frontBuffer[currentFrontBufferWriteIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его
firstUnHandledFront = firstUnHandledFront->next; firstUnHandledFront = firstUnHandledFront->next;
Serial.println(); Serial.println();
Serial.println("ERROR"); Serial.println("ERROR");
@ -324,14 +379,14 @@ void IR_Decoder::isr() { // в прерывании вызываем isr()
} }
if (lastFront == nullptr) { if (lastFront == nullptr) {
lastFront = &frontBuffer[currentFrontBufferWriteIndex]; lastFront = &subBuffer[currentSubBufferIndex];
} else { } else {
lastFront->next = &frontBuffer[currentFrontBufferWriteIndex]; lastFront->next = &subBuffer[currentSubBufferIndex];
lastFront = &frontBuffer[currentFrontBufferWriteIndex]; lastFront = &subBuffer[currentSubBufferIndex];
} }
currentFrontBufferWriteIndex == (subBuffer - 1) ? currentFrontBufferWriteIndex = 0 : currentFrontBufferWriteIndex++; currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++;
} }

View File

@ -21,7 +21,7 @@
#define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax)
#define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 #define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1
#define subBuffer 5 //Буфер для складирования фронтов, пока их не обработают #define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают
class IR_Encoder; class IR_Encoder;
class IR_Decoder : private IR_FOX { class IR_Decoder : private IR_FOX {
@ -200,12 +200,14 @@ private:
const uint8_t bufferDataSize = dataByteSizeMax; // + crc const uint8_t bufferDataSize = dataByteSizeMax; // + crc
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
void noFunc(); void noFunc();
volatile uint8_t currentFrontBufferWriteIndex; volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов
// Структура для хранения времени и направления фронта/спада
struct FrontStorage { struct FrontStorage {
volatile uint32_t time; volatile uint32_t time; // Время
volatile bool dir; volatile bool dir; // Направление (true = ↑; false = ↓)
volatile FrontStorage* next; volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец
// Операторо присвоения
FrontStorage& operator= (FrontStorage& val) { FrontStorage& operator= (FrontStorage& val) {
this->next = val.next; this->next = val.next;
this->time = val.time; this->time = val.time;
@ -214,9 +216,9 @@ private:
return *this; return *this;
} }
}; };
volatile FrontStorage* lastFront = nullptr; volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада
volatile FrontStorage* firstUnHandledFront = nullptr; volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада
volatile FrontStorage frontBuffer[subBuffer]; volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
uint8_t* rawBuffer = nullptr; uint8_t* rawBuffer = nullptr;
uint8_t* dataBuffer = nullptr; uint8_t* dataBuffer = nullptr;
@ -229,9 +231,14 @@ private:
private: private:
uint8_t* getDataBuffer(bool reset = false); uint8_t* getDataBuffer(bool reset = false);
bool crcCheck(uint8_t len); bool crcCheck(uint8_t len);
////////////////////////////////////////////////////////////////////////
inline void writeToBuffer(bool); bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации
inline void start_RX(); uint16_t i_dataBuffer; // Счётчик буфера данных
uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData
uint8_t i_syncBit; // Счётчик битов синхронизации
void writeToBuffer(bool);
////////////////////////////////////////////////////////////////////////
void start_RX();
void resetAvaliable(); void resetAvaliable();
uint16_t ceil_div(uint16_t, uint16_t); uint16_t ceil_div(uint16_t, uint16_t);