signal generator

This commit is contained in:
DashyFox 2024-02-08 17:18:33 +03:00
parent 8d5b2f6e3c
commit b272b6031c
5 changed files with 82 additions and 42 deletions

View File

@ -8,7 +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 = new uint8_t[bufferDataSize] { 0 };
dataBuffer = new uint8_t[dataByteSizeMax] { 0 };
prevRise = prevFall = prevPrevFall = prevPrevRise = 0;
start_RX();
}
@ -255,7 +255,7 @@ void IR_Decoder::start_RX() {
resetAvaliable();
isBufferOverflow = false;
memset(dataBuffer, 0x00, bufferDataSize);
memset(dataBuffer, 0x00, dataByteSizeMax);
bufBitPos = 0;
isData = true;
@ -266,7 +266,7 @@ void IR_Decoder::start_RX() {
}
void IR_Decoder::writeToBuffer(bool bit) {
if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения
if (i_dataBuffer >= dataByteSizeMax * 8 - 1) {// проверка переполнения
//TODO: Буффер переполнен!
isBufferOverflow = true;
}

View File

@ -197,7 +197,6 @@ private:
volatile bool isPreamb = false; // флаг начальной последовости
bool HIGH_FIRST = true; //TODO: порядок приходящих битов
const uint8_t bufferDataSize = dataByteSizeMax; // + crc
////////////////////////////////////////////////////////////////////////
void noFunc();
volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов

View File

@ -1,7 +1,12 @@
#include "IR_Encoder.h"
#include "IR_Decoder.h"
#define LoopOut 12
#define ISR_Out 10
#define TestOut 13
IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) {
sendBuffer = new uint8_t[dataByteSizeMax] { 0 };
ir_out = pin;
pinMode(ir_out, OUTPUT);
addrSelf = addr;
@ -16,6 +21,7 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder*
IR_Encoder::~IR_Encoder() {
delete [] bitHigh;
delete [] bitLow;
delete [] sendBuffer;
};
void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) {
@ -109,74 +115,105 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t
}
void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) {
cli();
digitalToggle(9); digitalToggle(9);
memset(sendBuffer, 0x00, dataByteSizeMax);
memcpy(sendBuffer, ptr, len);
sendLen = len;
// *sendBuffer = 0b10010011;
isSending = true;
cli();
if (decoder != nullptr) { decoder->isPairSending = isSending; }
// #define preambToggle 2*2-1 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
toggleCounter = preambToggle; // Первая генерация для первого signal
preambBitCounter;
dataBitCounter = 3/* len * 8 */;
syncBitCounter = syncBits;
dataBitCounter = bitPerByte - 1;
dataByteCounter = 0;
preambFrontCounter = preambPulse * 2 - 1; // -1 за счёт генерации уже на этапе сразу после инициализации
dataFrontCounter = bitPerByte * 2;
syncFrontCounter;
dataSequenceCounter = bitPerByte * 2;
syncSequenceCounter = syncBits * 2;
signal = preamb;
isSending = true;
state = HIGH;
currentBit = bitHigh;
currentBitSequence = bitHigh;
sei();
}
void IR_Encoder::isr() {
if (!isSending) return;
ir_out_virtual = !ir_out_virtual && state;
if (toggleCounter == 0) {
if (toggleCounter) {
toggleCounter--;
} else {
IsrStart:
switch (signal) {
case noSignal:
// сброс счетчиков
// ...
isSending = false;
return;
break;
case preamb:
if (preambFrontCounter == 0) { // Конец преамбулы, переход на следующий signal
if (preambFrontCounter) {
preambFrontCounter--;
toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal
} else {// Конец преамбулы, переход на следующий signal
signal = data;
state = !LOW; // Инверсное состояние первой генерации следующего signal
goto IsrStart; // Применение новых параметров в этй же итерации прерывания
} else {
preambFrontCounter--;
toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal
}
break;
case data:
if (dataFrontCounter == 0) { // Конец преамбулы, переход на следующий signal
signal = noSignal;
// state = HIGH;
isSending = false;
} else {
toggleCounter = currentBit[!state];
dataFrontCounter--;
if (dataSequenceCounter) {
if (!(dataSequenceCounter & 1U)) { // если чётный - смена бита
currentBitSequence = ((sendBuffer[dataByteCounter] >> dataBitCounter) & 1U) ? bitHigh : bitLow; // определение текущего бита
dataBitCounter--;
}
toggleCounter = currentBitSequence[!state];
dataSequenceCounter--;
} else { // Конец data, переход на следующий signal
syncLastBit = !((sendBuffer[dataByteCounter]) & 1U);
dataByteCounter++;
dataBitCounter = bitPerByte - 1;
dataSequenceCounter = bitPerByte * 2;
signal = sync;
goto IsrStart; // Применение новых параметров в этй же итерации прерывания
}
// signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2
break;
case sync:
// signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2
if (syncSequenceCounter) {
if (!(syncSequenceCounter & 1U)) { // если чётный - смена бита
if (syncSequenceCounter == 2) { // Если последний бит
currentBitSequence = ((sendBuffer[dataByteCounter]) & 0b10000000) ? bitLow : bitHigh;
} else {
currentBitSequence = syncLastBit ? bitLow : bitHigh; // определение текущего бита
syncLastBit = !syncLastBit;
}
}
toggleCounter = currentBitSequence[!state];
syncSequenceCounter--;
} else { // Конец sync, переход на следующий signal
signal = data;
syncSequenceCounter = syncBits * 2;
if (dataByteCounter >= sendLen) { // определение конца данных
signal = noSignal;
}
goto IsrStart; // Применение новых параметров в этй же итерации прерывания
}
break;
default:
@ -185,9 +222,7 @@ void IR_Encoder::isr() {
}
state = !state;
} else { toggleCounter--; }
}
}

View File

@ -46,23 +46,27 @@ private:
enum SignalPart : uint8_t {
noSignal = 0,
preamb = 1,
data = 2, // 2 должен инвертироваться в sync
sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data
data = 2,
sync = 3
};
uint8_t sendLen;
uint8_t* sendBuffer; /// @brief Буффер данных для отправки
volatile bool isSending = false;
// volatile bool genState = HIGH;
volatile bool state; /// @brief Текущий уровень генерации
volatile uint8_t dataByteCounter;
volatile uint8_t toggleCounter; /// @brief Счётчик переключений
volatile uint8_t preambBitCounter;
volatile uint8_t dataBitCounter;
volatile uint8_t syncBitCounter;
volatile uint8_t preambFrontCounter;
volatile uint8_t dataFrontCounter;
volatile uint8_t syncFrontCounter;
volatile uint8_t dataSequenceCounter;
volatile uint8_t syncSequenceCounter;
volatile bool syncLastBit;
struct BitSequence {
uint8_t low;
@ -76,7 +80,7 @@ private:
(bitPauseTakts + bitActiveTakts) * 2 - 1,
(bitPauseTakts) * 2 - 1
};
uint8_t* currentBit;
uint8_t* currentBitSequence = bitLow;
// uint8_t bitSequence[2];

View File

@ -96,8 +96,8 @@ typedef uint16_t crc_t;
#define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes)
// размер msg в битах // размер короткой посылки в битах
#define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах
#define bufferBitSizeMax (dataBitSize) // Размер буффера в битах
// #define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах
// #define bufferBitSizeMax (dataBitSize) // Размер буффера в битах
//const auto x = bufferBitSizeMax;
#define preambFronts (preambPulse*2) // количество фронтов преамбулы
@ -113,6 +113,8 @@ typedef uint16_t crc_t;
#define bitTime (bitTakts*carrierPeriod) // Общая длительность бита
#define tolerance 300U
#define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1)
class IR_FOX {
private: