mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-05-04 07:10:16 +00:00
196 lines
13 KiB
C++
196 lines
13 KiB
C++
#pragma once
|
||
#include <Arduino.h>
|
||
|
||
#define IRDEBUG_INFO
|
||
/*//////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
Для работы в паре положить декодер в энкодер
|
||
|
||
*/// Адресация с 1 до 65 499
|
||
#define IR_Broadcast 65000 // 65 500 ~ 65 535 - широковещательные пакеты (всем), возможно разделить на 35 типов
|
||
/*
|
||
Адрес 0 запрещен и зарезервирован под NULL, либо тесты
|
||
IR_MSG_ACCEPT с адреса 0 воспринимается всеми устройствами
|
||
|
||
|
||
Адресное пространство:
|
||
|
||
Излучатели контрольных точек: 1000 ~ 1999
|
||
Излучатели без обратной связиЖ 2000 ~ 2999
|
||
Излучатели светофоров: 3000 ~ 3999
|
||
|
||
|
||
|
||
/```````````````````````````````````````````````` data pack `````````````````````````````````````````````\
|
||
|
||
{``````````} [````````````````````````] [````````````````````] [````````````````````````] [``````````````]
|
||
{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]
|
||
{..........} [........................] [....................] [........................] [..............]
|
||
|
||
{ aka size } [addr_from_H][addr_from_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]
|
||
| 0 1 2 3 4 5 | |
|
||
\____________________________________________________________________________________________/ |
|
||
| |
|
||
\____________________________________________________________________________________________________/
|
||
|
||
msg type:
|
||
// __________
|
||
// | 01234567 |
|
||
// ----------
|
||
// | xxx..... | = тип сообщения
|
||
// | ...xxxxx | = длина (максимум 31 бита)
|
||
// ---------- */
|
||
#define IR_MSG_BACK 0U // | 000...... | = Задний сигнал машинки
|
||
#define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение
|
||
#define IR_MSG_REQUEST 2U // | 010..... | = запрос
|
||
#define IR_MSG_ 3U // | 011..... | = ??
|
||
#define IR_MSG_BACK_TO 4U // | 100..... | = Задний сигнал машинки c адресацией
|
||
#define IR_MSG_ 5U // | 101..... | = ??
|
||
#define IR_MSG_DATA_NOACCEPT 6U // | 110..... | = данные, не требующие подтверждения
|
||
#define IR_MSG_DATA_ACCEPT 7U // | 111..... | = данные требующие подтверждения
|
||
/* // ----------
|
||
|
||
/```````````````````` подтверждение ```````````````````\ /``````````````````````````````````````` запрос ``````````````````````````````````\
|
||
|
||
{``````````} [````````````````````````] [``````````````] {``````````} [````````````````````````] [````````````````````````] [``````````````]
|
||
{ msg type } [ addr_from uint16_t ] [ CRC Bytes ] { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ]
|
||
{..........} [........................] [..............] {..........} [........................] [........................] [..............]
|
||
|
||
{ 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]
|
||
| 0 1 2 3 4 | 0 1 2 3 4 5 6
|
||
\__________________________________________/ | \_____________________________________________________________________/ |
|
||
| | | |
|
||
\__________________________________________________/ \_____________________________________________________________________________/
|
||
|
||
|
||
|
||
/`````````````````````` Задний сигнал машинки без адресации ``````````````````````\ В (IR_MASK_MSG_INFO & 15U) содержится количество байт
|
||
сквозных команд, максимум 15
|
||
{``````````} [````````````````````````] [````````````````````````] [``````````````] Если полезных байт информации нет, отправляется один
|
||
{ msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ] байт нулей
|
||
{..........} [........................] [........................] [..............]
|
||
|
||
{ 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]
|
||
| 0 1 2 3 | |
|
||
\_____________________________________________________________________/ |
|
||
| |
|
||
\_____________________________________________________________________________/
|
||
|
||
|
||
|
||
/```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\
|
||
|
||
{``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]
|
||
{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]
|
||
{..........} [........................] [........................] [........................] [..............]
|
||
|
||
{ 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]
|
||
| 0 1 2 3 4 5 | |
|
||
\________________________________________________________________________________________________/ |
|
||
| |
|
||
\________________________________________________________________________________________________________/
|
||
|
||
*/
|
||
|
||
#define IR_MASK_MSG_TYPE 0b00000111
|
||
#define IR_MASK_MSG_INFO 0b00011111
|
||
|
||
/*
|
||
/////////////////////////////////////////////////////////////////////////////////////*/
|
||
typedef uint16_t crc_t;
|
||
|
||
#define bytePerPack 16 // колличество байтов в пакете
|
||
#ifndef freeFrec
|
||
#define freeFrec true
|
||
#endif
|
||
#define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают (передатчик)
|
||
|
||
#define preambPulse 3
|
||
|
||
#define disablePairDec false // Отключать парный приёмник, возможны баги, используйте setBlindDecoders()
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
#define bitPerByte 8U // Колличество бит в байте
|
||
#define addrBytes 2
|
||
#define msgBytes 1
|
||
#define crcBytes 2
|
||
#define poly1 0x31
|
||
#define poly2 0x8C
|
||
#define syncBits 3U // количество битов синхронизации
|
||
|
||
#define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes)
|
||
|
||
#define preambFronts (preambPulse*2) // количество фронтов преамбулы (Приём)
|
||
#define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) // колличество переключений преамбулы (Передача)
|
||
|
||
#define carrierFrec 38000U // частота несущей (Приём/Передача)
|
||
#define carrierPeriod (1000000U/carrierFrec) // период несущей в us (Приём)
|
||
|
||
// В процессе работы значения будут отклонятся в соответствии с предыдущим битом
|
||
#define bitActiveTakts 25U // длительность высокого уровня в тактах
|
||
#define bitPauseTakts 6U // длительность низкого уровня в тактах
|
||
|
||
#define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах
|
||
#define bitTime (bitTakts*carrierPeriod) // Общая длительность бита
|
||
#define tolerance 300U
|
||
|
||
class IR_FOX {
|
||
public:
|
||
struct PackOffsets {
|
||
uint8_t msgOffset;
|
||
uint8_t addrFromOffset;
|
||
uint8_t addrToOffset;
|
||
uint8_t dataOffset;
|
||
uint8_t crcOffset;
|
||
};
|
||
|
||
struct ErrorsStruct {
|
||
uint8_t lowSignal;
|
||
uint8_t highSignal;
|
||
uint8_t other;
|
||
|
||
void reset() {
|
||
lowSignal = 0;
|
||
highSignal = 0;
|
||
other = 0;
|
||
}
|
||
uint16_t all() { return lowSignal + highSignal + other; }
|
||
|
||
};
|
||
|
||
struct PackInfo {
|
||
uint8_t* ptr;
|
||
uint8_t packSize;
|
||
uint16_t crc;
|
||
ErrorsStruct err;
|
||
uint16_t rTime;
|
||
};
|
||
|
||
protected:
|
||
ErrorsStruct errors;
|
||
|
||
void checkaddressRuleApply(uint16_t address, uint16_t id, bool &flag) {
|
||
flag = false;
|
||
flag |= id == 0;
|
||
flag |= address == id;
|
||
flag |= address >= IR_Broadcast;
|
||
}
|
||
|
||
uint8_t crc8(uint8_t* data, uint8_t start, uint8_t end, uint8_t poly) { //TODO: сделать возможность межбайтовой проверки
|
||
uint8_t crc = 0xff;
|
||
size_t i, j;
|
||
for (i = start; i < end; i++) {
|
||
crc ^= data[i];
|
||
for (j = 0; j < 8; j++) {
|
||
if ((crc & 0x80) != 0)
|
||
crc = (uint8_t)((crc << 1) ^ poly);
|
||
else
|
||
crc <<= 1;
|
||
}
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
};
|