MultiGen isr

This commit is contained in:
DashyFox 2024-02-06 17:14:59 +03:00
parent 02410cc78c
commit e0fbc8502d
3 changed files with 148 additions and 60 deletions

View File

@ -3,12 +3,18 @@
IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) {
ir_out = pin; ir_out = pin;
pinMode(ir_out, OUTPUT);
addrSelf = addr; addrSelf = addr;
decoder = decPair; decoder = decPair;
carrierTune = tune; carrierTune = tune;
halfPeriod = (carrierPeriod / 2) - carrierTune; halfPeriod = (carrierPeriod / 2) - carrierTune;
dataBitCounter = 0 - preambFronts;
signal = noSignal;
}; };
IR_Encoder::~IR_Encoder() {}; IR_Encoder::~IR_Encoder() {};
void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) {
@ -102,34 +108,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) { void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) {
/*tmp*/bool LOW_FIRST = false;/*tmp*/ digitalToggle(9); digitalToggle(9);
isSending = true;
if (decoder != nullptr) { decoder->isPairSending = isSending; }
cli();
// toggleCounter = bitTakts*2 - 1;
#define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1)
// #define preambToggle (3*2-1)
toggleCounter = preambToggle;
preambBitCounter = preambPulse;
dataBitCounter = 0;
syncBitCounter = 0;
if (decoder != nullptr) { decoder->isPairSending = true; } signal = preamb;
isSending = true;
state = HIGH;
sei();
}
bool prev = 1;
bool next;
send_EMPTY(preambPulse); // преамбула void IR_Encoder::isr() {
for (uint16_t byteNum = 0; byteNum < len; byteNum++) { if (!isSending) return;
sendByte(ptr[byteNum], &prev, LOW_FIRST);
if (byteNum < len - 1) { ir_out_virtual = !ir_out_virtual && state;
next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000);
} else {
next = 0; if (!toggleCounter) {
state = !state;
switch (signal) {
case noSignal:
return;
break;
case preamb:
toggleCounter = preambToggle;
if (!state) { // Низкий уровень - конец периода генерации
preambBitCounter--;
if (!preambBitCounter) { // Конец преамбулы, переход на следующий этап
isSending = false;
}
}
break;
case data:
signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2
break;
case sync:
signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2
break;
default:
return;
break;
} }
addSync(&prev, &next);
}
if (decoder != nullptr) { decoder->isPairSending = false; } } else { toggleCounter--; }
}
void old() {///////////////////////////////////////////////////////
// void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) {
// /*tmp*/bool LOW_FIRST = false;/*tmp*/
// if (decoder != nullptr) { decoder->isPairSending = true; }
// bool prev = 1;
// bool next;
// send_EMPTY(preambPulse); // преамбула
// for (uint16_t byteNum = 0; byteNum < len; byteNum++) {
// sendByte(ptr[byteNum], &prev, LOW_FIRST);
// if (byteNum < len - 1) {
// next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000);
// } else {
// next = 0;
// }
// addSync(&prev, &next);
// }
// if (decoder != nullptr) { decoder->isPairSending = false; }
// }
} }
void IR_Encoder::sendByte(uint8_t byte, bool* prev, bool LOW_FIRST) { void IR_Encoder::sendByte(uint8_t byte, bool* prev, bool LOW_FIRST) {
uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000; uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000;
for (uint8_t bitShift = 8; bitShift; bitShift--) { for (uint8_t bitShift = 8; bitShift; bitShift--) {
digitalWrite(9, HIGH);
digitalWrite(9, LOW);
byte& mask ? send_HIGH(prev) : send_LOW(); byte& mask ? send_HIGH(prev) : send_LOW();
*prev = byte & mask; *prev = byte & mask;
LOW_FIRST ? mask <<= 1 : mask >>= 1; LOW_FIRST ? mask <<= 1 : mask >>= 1;
digitalWrite(9, HIGH);
digitalWrite(9, LOW);
} }
} }
@ -152,39 +229,29 @@ void IR_Encoder::addSync(bool* prev, bool* next) {
} }
void IR_Encoder::send_HIGH(bool prevBite = 1) { void IR_Encoder::send_HIGH(bool prevBite = 1) {
if (prevBite) {
meanderBlock(bitPauseTakts * 2, halfPeriod, LOW); // if (/* prevBite */1) {
meanderBlock(bitActiveTakts, halfPeriod, HIGH); // meanderBlock(bitPauseTakts * 2, halfPeriod, LOW);
} else { // более короткий HIGH после нуля // meanderBlock(bitActiveTakts, halfPeriod, HIGH);
meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW); // } else { // более короткий HIGH после нуля
meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH); // meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW);
} // meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH);
// }
} }
void IR_Encoder::send_LOW() { void IR_Encoder::send_LOW() {
meanderBlock(bitPauseTakts, halfPeriod, LOW); // meanderBlock(bitPauseTakts, halfPeriod, LOW);
meanderBlock(bitActiveTakts, halfPeriod, LOW); // meanderBlock(bitActiveTakts, halfPeriod, LOW);
meanderBlock(bitPauseTakts, halfPeriod, HIGH); // meanderBlock(bitPauseTakts, halfPeriod, HIGH);
} }
void IR_Encoder::send_EMPTY(uint8_t count) { void IR_Encoder::send_EMPTY(uint8_t count) {
for (size_t i = 0; i < count * 2; i++) { // for (size_t i = 0; i < count * 2; i++) {
meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, prevPreambBit); // meanderBlock((bitPauseTakts * 2 + bitActiveTakts), halfPeriod, prevPreambBit);
prevPreambBit = !prevPreambBit; // prevPreambBit = !prevPreambBit;
} // }
// meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, 0); //TODO: Отодвинуть преамбулу
} }
void IR_Encoder::meanderBlock(uint16_t count, uint16_t _period, bool high = true) {
for (uint16_t i = 0; i < count << 1; i++) {
if ((i & 1)) { // Если чётное
//PORTC &= ~(1 << 3); // LOW
digitalWrite(ir_out, high ? LOW : LOW);
} else { // Если не четное
//PORTC |= 1 << 3; // HIGH
digitalWrite(ir_out, high ? HIGH : LOW);
}
delayMicroseconds(_period);
}
}

View File

@ -6,22 +6,16 @@
class IR_Decoder; class IR_Decoder;
class IR_Encoder : IR_FOX { class IR_Encoder : IR_FOX {
friend IR_Decoder; friend IR_Decoder;
friend void isr(IR_Encoder& e);
public: public:
/// @brief Вывод передатчика
uint8_t ir_out;
/// @brief Адрес передатчика uint8_t ir_out; /// @brief Вывод передатчика
uint16_t addrSelf; uint16_t addrSelf; /// @brief Адрес передатчика
private: private:
/// @brief предыдущий бит преамбулы uint8_t carrierTune; /// @brief Подстройка несущей частоты
bool prevPreambBit = true; uint8_t halfPeriod; /// @brief полупериод несущей частоты
/// @brief Подстройка несущей частоты
uint8_t carrierTune;
/// @brief полупериод несущей частоты
uint8_t halfPeriod;
public: public:
/// @brief Класс передатчика /// @brief Класс передатчика
@ -35,23 +29,50 @@ public:
void sendData(uint16_t addrTo, T& data, bool needAccept = false); void sendData(uint16_t addrTo, T& data, bool needAccept = false);
void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false);
void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0);
void rawSend(uint8_t* ptr, uint8_t len);
void isr();
~IR_Encoder(); ~IR_Encoder();
volatile bool ir_out_virtual;
private: private:
IR_Decoder* decoder; IR_Decoder* decoder;
void meanderBlock(uint16_t count, uint16_t _period, bool isNoPause = true); void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType);
void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST); void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST);
void addSync(bool* prev, bool* next); void addSync(bool* prev, bool* next);
void send_HIGH(bool = 1); void send_HIGH(bool = 1);
void send_LOW(); void send_LOW();
void send_EMPTY(uint8_t count); void send_EMPTY(uint8_t count);
void rawSend(uint8_t* ptr, uint8_t len);
void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); enum SignalPart : uint8_t {
noSignal = 0,
preamb = 1,
data = 2, // 2 должен инвертироваться в sync
sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data
};
volatile bool isSending = false;
// volatile bool genState = HIGH;
volatile bool state; /// @brief Текущий уровень генерации
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;
// uint8_t bitSequence[2];
// volatile uint32_t toggle_counter;
SignalPart signal;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T> template<typename T>

View File

@ -106,10 +106,10 @@ typedef uint16_t crc_t;
#define carrierPeriod (1000000U/carrierFrec) // период несущей в us #define carrierPeriod (1000000U/carrierFrec) // период несущей в us
// В процессе работы значения будут отклонятся в соответствии с предыдущим битом // В процессе работы значения будут отклонятся в соответствии с предыдущим битом
#define bitActiveTakts 25U // длительность единицы в тактах #define bitActiveTakts 25U // длительность высокого уровня в тактах
#define bitPauseTakts 6U // длительность нуля в тактах #define bitPauseTakts 6U // длительность низкого уровня в тактах
#define bitTakts (bitActiveTakts+bitPauseTakts*2U) // Общая длительность бита в тактах #define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах
#define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита
#define tolerance 300U #define tolerance 300U