mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-05-04 07:10:16 +00:00
fix extra zero, docs and debag
This commit is contained in:
parent
56c207b058
commit
d629b24864
203
IR_Decoder.cpp
203
IR_Decoder.cpp
@ -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,73 +18,117 @@ 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));
|
||||
} */
|
||||
Serial.print(bit);
|
||||
#ifdef IRDEBUG
|
||||
bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1);
|
||||
#endif
|
||||
if (isBufferOverflow || isPreamb) return;
|
||||
|
||||
if (isBufferOverflow) { //TODO: Буффер переполнен!
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//const auto testval = bufferBitSizeMax;
|
||||
if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) {
|
||||
switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) {
|
||||
case IR_MSG_ACCEPT:
|
||||
if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) {
|
||||
const uint8_t dataSize = msgBytes + addrBytes;
|
||||
isRawAvaliable = true;
|
||||
isMsgAvaliable = crcCheck(dataSize);
|
||||
if (isMsgAvaliable && checkAddr(1, 2)) {
|
||||
gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
gotAccept._isAvaliable = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IR_MSG_REQUEST:
|
||||
if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) {
|
||||
const uint8_t dataSize = msgBytes + addrBytes + addrBytes;
|
||||
isRawAvaliable = true;
|
||||
isMsgAvaliable = (crcCheck(dataSize));
|
||||
if (isMsgAvaliable && checkAddr(3, 4)) {
|
||||
gotRequest._isAvaliable = true;
|
||||
gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IR_MSG_DATA_ACCEPT:
|
||||
case IR_MSG_DATA_NOACCEPT:
|
||||
if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) {
|
||||
const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO);
|
||||
isRawAvaliable = true;
|
||||
isMsgAvaliable = crcCheck(dataSize);
|
||||
if (isMsgAvaliable && checkAddr(3, 4)) {
|
||||
gotData._isAvaliable = true;
|
||||
gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
} else {
|
||||
gotRawData._isAvaliable = true;
|
||||
gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; }
|
||||
bufBitPos++;
|
||||
// Переключение флага, 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
|
||||
|
||||
if (isBufferOverflow) { //TODO: Буффер переполнен!
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//const auto testval = bufferBitSizeMax;
|
||||
if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) {
|
||||
switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) {
|
||||
case IR_MSG_ACCEPT:
|
||||
if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) {
|
||||
const uint8_t dataSize = msgBytes + addrBytes;
|
||||
isRawAvaliable = true;
|
||||
isMsgAvaliable = crcCheck(dataSize);
|
||||
if (isMsgAvaliable && checkAddr(1, 2)) {
|
||||
gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
gotAccept._isAvaliable = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IR_MSG_REQUEST:
|
||||
if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) {
|
||||
const uint8_t dataSize = msgBytes + addrBytes + addrBytes;
|
||||
isRawAvaliable = true;
|
||||
isMsgAvaliable = (crcCheck(dataSize));
|
||||
if (isMsgAvaliable && checkAddr(3, 4)) {
|
||||
gotRequest._isAvaliable = true;
|
||||
gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case IR_MSG_DATA_ACCEPT:
|
||||
case IR_MSG_DATA_NOACCEPT:
|
||||
if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) {
|
||||
const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO);
|
||||
isRawAvaliable = true;
|
||||
isMsgAvaliable = crcCheck(dataSize);
|
||||
if (isMsgAvaliable && checkAddr(3, 4)) {
|
||||
gotData._isAvaliable = true;
|
||||
gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
} else {
|
||||
gotRawData._isAvaliable = true;
|
||||
gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}/**/
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
|
||||
|
31
IR_Decoder.h
31
IR_Decoder.h
@ -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,13 +200,15 @@ 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) {
|
||||
// Операторо присвоения
|
||||
FrontStorage& operator= (FrontStorage& val) {
|
||||
this->next = val.next;
|
||||
this->time = val.time;
|
||||
this->dir = val.dir;
|
||||
@ -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);
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
case 2:
|
||||
for (size_t i = 0; i < s * 8; i++) {
|
||||
if (i == control) {
|
||||
str += " ";
|
||||
str += " ";
|
||||
control += bitPerByte;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user