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) {
rawBuffer = new uint8_t[bufferRawSize] { 0 };
dataBuffer = rawBuffer;
prevRise = prevFall = prevPrevFall = prevPrevRise = 0;
start_RX();
}
@ -17,13 +18,59 @@ IR_Decoder::~IR_Decoder() {
}
void IR_Decoder::writeToBuffer(bool bit) {
if (!isBufferOverflow && !isPreamb) {
if (HIGH_FIRST) {
rawBuffer[(bufBitPos >> 3)] |= bit << (7 - (bufBitPos & ~(~0 << 3)));
}/* else {
rawBuffer[(bufBitPos >> 3)] |= bit << (bufBitPos & ~(~0 << 3));
} */
if (isBufferOverflow || isPreamb) return;
// Переключение флага, data или syncBit
if (bufBitPos == nextControlBit) {
nextControlBit += (isData ? syncBits : bitPerByte);
isData = !isData;
Serial.print(" ");
}
Serial.print(bit);
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);
#endif
@ -79,11 +126,9 @@ void IR_Decoder::writeToBuffer(bool bit) {
default:
break;
}
}
}/**/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; }
bufBitPos++;
}
}
uint8_t* IR_Decoder::getDataBuffer(bool reset = false) {
@ -149,10 +194,20 @@ bool IR_Decoder::crcCheck(uint8_t len) {
}
void IR_Decoder::start_RX() {
// Serial.println();
// Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN));
// Serial.println();
resetAvaliable();
isBufferOverflow = false;
memset(rawBuffer, 0x00, bufferRawSize);
bufBitPos = 0;
isData = true;
i_dataBuffer = 0;
nextControlBit = bitPerByte;
i_syncBit = 0;
}
void IR_Decoder::resetAvaliable() {
@ -308,14 +363,14 @@ void IR_Decoder::tick() {
void IR_Decoder::isr() { // в прерывании вызываем isr()
if (isPairSending) return;
frontBuffer[currentFrontBufferWriteIndex].next = nullptr;
frontBuffer[currentFrontBufferWriteIndex].dir = (PIND >> isrPin) & 1;
frontBuffer[currentFrontBufferWriteIndex].time = micros();
subBuffer[currentSubBufferIndex].next = nullptr;
subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1;
subBuffer[currentSubBufferIndex].time = micros();
if (firstUnHandledFront == nullptr) {
firstUnHandledFront = &frontBuffer[currentFrontBufferWriteIndex]; // Если нет необработанных данных - добавляем их
firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их
} else {
if (firstUnHandledFront == &frontBuffer[currentFrontBufferWriteIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его
if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его
firstUnHandledFront = firstUnHandledFront->next;
Serial.println();
Serial.println("ERROR");
@ -324,14 +379,14 @@ void IR_Decoder::isr() { // в прерывании вызываем isr()
}
if (lastFront == nullptr) {
lastFront = &frontBuffer[currentFrontBufferWriteIndex];
lastFront = &subBuffer[currentSubBufferIndex];
} else {
lastFront->next = &frontBuffer[currentFrontBufferWriteIndex];
lastFront = &frontBuffer[currentFrontBufferWriteIndex];
lastFront->next = &subBuffer[currentSubBufferIndex];
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 IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1
#define subBuffer 5 //Буфер для складирования фронтов, пока их не обработают
#define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают
class IR_Encoder;
class IR_Decoder : private IR_FOX {
@ -200,12 +200,14 @@ private:
const uint8_t bufferDataSize = dataByteSizeMax; // + crc
////////////////////////////////////////////////////////////////////////
void noFunc();
volatile uint8_t currentFrontBufferWriteIndex;
volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов
// Структура для хранения времени и направления фронта/спада
struct FrontStorage {
volatile uint32_t time;
volatile bool dir;
volatile FrontStorage* next;
volatile uint32_t time; // Время
volatile bool dir; // Направление (true = ↑; false = ↓)
volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец
// Операторо присвоения
FrontStorage& operator= (FrontStorage& val) {
this->next = val.next;
this->time = val.time;
@ -214,9 +216,9 @@ private:
return *this;
}
};
volatile FrontStorage* lastFront = nullptr;
volatile FrontStorage* firstUnHandledFront = nullptr;
volatile FrontStorage frontBuffer[subBuffer];
volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада
volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада
volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов
////////////////////////////////////////////////////////////////////////
uint8_t* rawBuffer = nullptr;
uint8_t* dataBuffer = nullptr;
@ -229,9 +231,14 @@ private:
private:
uint8_t* getDataBuffer(bool reset = false);
bool crcCheck(uint8_t len);
inline void writeToBuffer(bool);
inline void start_RX();
////////////////////////////////////////////////////////////////////////
bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации
uint16_t i_dataBuffer; // Счётчик буфера данных
uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData
uint8_t i_syncBit; // Счётчик битов синхронизации
void writeToBuffer(bool);
////////////////////////////////////////////////////////////////////////
void start_RX();
void resetAvaliable();
uint16_t ceil_div(uint16_t, uint16_t);