From 3ff6865b74a183a1c022a6dbd9fa994ca91e7f15 Mon Sep 17 00:00:00 2001 From: AlexGyver Date: Wed, 23 Aug 2023 12:04:46 +0300 Subject: [PATCH] upd --- src/GBUS.h | 74 ++++++++++++++++----------------- src/GBUSmini.cpp | 54 ++++++++++++------------ src/GBUSmini.h | 8 ++-- src/GyverBus.cpp | 22 +++++----- src/GyverBus.h | 41 ++++++++---------- src/softUART.h | 106 +++++++++++++++++++++++------------------------ 6 files changed, 150 insertions(+), 155 deletions(-) diff --git a/src/GBUS.h b/src/GBUS.h index 54ab992..3267e1b 100644 --- a/src/GBUS.h +++ b/src/GBUS.h @@ -9,29 +9,29 @@ /* Коды статусов и ошибок (tick() и getStatus()): - 0 [GBUS_IDLE] - ожидание (холостой режим) - 1 [TRANSMITTING] - передача - 2 [TX_OVERFLOW] - буфер переполнен - 3 [TX_COMPLETE] - передача завершена - 4 [RECEIVING] - приём - 5 [RX_ERROR] - ошибка приёма - 6 [RX_ABORT] - ошибка. Приём прерван - 7 [RX_OVERFLOW] - ошибка. Буфер или пакет переполнен - 8 [RX_ADDRESS_ERROR] - ошибка. Не наш адрес - 9 [RX_CRC_ERROR] - ошибка. Не совпадает CRC - 10 [RX_REQUEST] - успешное получение запроса - 11 [RX_DATA] - успешный приём данных - 12 [RX_ACK] - успешное получение подтверждения + 0 [GBUS_IDLE] - ожидание (холостой режим) + 1 [TRANSMITTING] - передача + 2 [TX_OVERFLOW] - буфер переполнен + 3 [TX_COMPLETE] - передача завершена + 4 [RECEIVING] - приём + 5 [RX_ERROR] - ошибка приёма + 6 [RX_ABORT] - ошибка. Приём прерван + 7 [RX_OVERFLOW] - ошибка. Буфер или пакет переполнен + 8 [RX_ADDRESS_ERROR] - ошибка. Не наш адрес + 9 [RX_CRC_ERROR] - ошибка. Не совпадает CRC + 10 [RX_REQUEST] - успешное получение запроса + 11 [RX_DATA] - успешный приём данных + 12 [RX_ACK] - успешное получение подтверждения */ -/* +/* Инициализация: GBUS объект(обработчик, адрес, размер буфера) - обработчик: адрес объекта-обработчика интерфейса (например &Serial, &mySerial) - адрес: адрес этого устрйоства в сети - размер буфера: размер буфера - Список методов: + Список методов: tick() - отправляет и принимает данные. Вызывать хотя бы каждую миллисекунду. Возвращает коды статусов, тип GBUSstatus (enum) getStatus() - возвращает коды статусов (такие же как tick()), тип GBUSstatus (enum) @@ -40,13 +40,13 @@ readData(дата) - выводит данные из внутреннего буфера в указанную "переменную" (переменные, массивы, структуры) sendRequest(адрес) - отправить "запрос" по адресу получателя - gotRequest() - вернёт true, если на наш адрес пришёл запрос. Сам сбрасывается в false. Адрес отправителя можно узнать в getTXaddress() + gotRequest() - вернёт true, если на наш адрес пришёл запрос. Сам сбрасывается в false. Адрес отправителя можно узнать в getTXaddress() getTXaddress() - возвращает адрес отправителя с последнего успешного получения данных или запроса isBusy() - возвращает true, если линия занята. Возвращает false, если с момента последнего общения по линии прошло GBUS_BUSY_TIMEOUT миллисекунд sendAck(адрес) - отправляет ack (ответ на запрос) по адресу - gotAck() - вернёт true, если на наш адрес пришёл ack (ответ на запрос). Сам сбрасывается в false. Адрес отправителя можно узнать в getTXaddress() + gotAck() - вернёт true, если на наш адрес пришёл ack (ответ на запрос). Сам сбрасывается в false. Адрес отправителя можно узнать в getTXaddress() waitAck(адрес, кол-во попыток, таймаут) - ждёт ответа с указанного адреса. Если не дожидается за таймаут - отправляет ещё реквест И так далее пока не выйдет количество попыток. @@ -68,7 +68,7 @@ ФУНКЦИЯ БЛОКИРУЮЩАЯ Смотри примеры call_response_ack - sendRaw(байтовый массив, размер) - отправит сырые байты (без протокола) по шине. Смотри примеры в папке raw + sendRaw(байтовый массив, размер) - отправит сырые байты (без протокола) по шине. Смотри примеры в папке raw gotRaw() - вернёт true, были приняты какие-то данные (приём завершён успешно). Сам сбрасывается в false. rawSize() - вернёт количество принятых байт (последний успешный приём). Иначе вернёт 0 @@ -85,7 +85,7 @@ // ============================ НАСТРОЙКИ ================================ // таймаут отправки после предыдущей активности на линии, мкс // он же МАКСИМАЛЬНЫЙ таймаут приёма (в процессе работы пересчитывается) -#define GBUS_BUSY_TIMEOUT 50000 +#define GBUS_BUSY_TIMEOUT 50000 // ======================================================================= @@ -152,25 +152,25 @@ class GBUS { // 0: приём идёт // кол-во байт: передача завершена int readBytesAsync(uint8_t* buffer, uint8_t size) { - while (port->available()) { // пока есть данные в буфере сериал - if (!_parseFlag) { // начало приёма - _parseFlag = true; // ключ на старт - _byteCount = 0; // сбросили счетчик - _timeout = GBUS_BUSY_TIMEOUT; // сбросили таймаут + while (port->available()) { // пока есть данные в буфере сериал + if (!_parseFlag) { // начало приёма + _parseFlag = true; // ключ на старт + _byteCount = 0; // сбросили счетчик + _timeout = GBUS_BUSY_TIMEOUT; // сбросили таймаут } buffer[_byteCount++] = port->read();// читаем - if (_byteCount == 2) _timeout = (micros() - _tmr) * 10; // таймаут как время передачи 10 бит - if (_byteCount > size) { // буфер переполнен + if (_byteCount == 2) _timeout = (micros() - _tmr) * 10; // таймаут как время передачи 10 бит + if (_byteCount > size) { // буфер переполнен _parseFlag = false; return -1; } - _tmr = micros(); // сброс таймера (идёт приём) + _tmr = micros(); // сброс таймера (идёт приём) return 0; } // таймаут ожидания приёма if (_parseFlag && micros() - _tmr >= _timeout) { - _parseFlag = false; // приём окончен + _parseFlag = false; // приём окончен return _byteCount; } return -2; @@ -227,22 +227,22 @@ class GBUS { // ждать ответа (блокирующая функция) uint8_t sendRequestAck(uint8_t to, uint8_t tries, int timeout) { sendRequest(to); - while (tick() == GBUS_IDLE); // ждём таймаут - while (tick() != TX_COMPLETE); // ждём отправку + while (tick() == GBUS_IDLE); // ждём таймаут + while (tick() != TX_COMPLETE); // ждём отправку uint8_t thisTry = 0; uint32_t tmr = millis(); while (1) { - tick(); // принимаем или отправляем - if (gotData()) return ACK_DATA; // приняли дату - if (gotAck()) return ACK_ONLY; // приняли ответ - if (millis() - tmr >= timeout) { // таймаут + tick(); // принимаем или отправляем + if (gotData()) return ACK_DATA; // приняли дату + if (gotAck()) return ACK_ONLY; // приняли ответ + if (millis() - tmr >= timeout) { // таймаут tmr = millis(); thisTry++; - if (thisTry >= tries) return ACK_ERROR; // превышено количество попыток - sendRequest(to); // снова шлём запрос + if (thisTry >= tries) return ACK_ERROR; // превышено количество попыток + sendRequest(to); // снова шлём запрос } } - return ACK_ERROR; // не дождались + return ACK_ERROR; // не дождались } diff --git a/src/GBUSmini.cpp b/src/GBUSmini.cpp index 27e2c4f..892a1b5 100644 --- a/src/GBUSmini.cpp +++ b/src/GBUSmini.cpp @@ -13,7 +13,7 @@ uint8_t GBUS_send_request_ack(uint8_t pin, uint8_t to, uint8_t from, uint8_t tri if (thisTry >= tries) return ACK_ERROR; GBUS_send_request(pin, to, from); } - } + } return ACK_ERROR; } @@ -33,25 +33,25 @@ bool GBUS_is_busy(uint8_t pin) { // ********************* ЧТЕНИЕ ************************** // ******************************************************* uint8_t GBUS_read_raw(uint8_t pin, uint8_t* buf, uint8_t size) { - if (!digitalRead(pin)) { // проверяем старт бит (low) - delayMicroseconds(GBUS_BIT_2); // ждём половину времени - if (!digitalRead(pin)) { // если всё ещё старт бит (low) - int8_t bitCount = 0; // счётчик битов - uint8_t byteCount = 0; // счётчик байтов - while (1) { - delayMicroseconds(GBUS_BIT-GBUS_OFFSET_READ); // ждём бит - uint8_t bit = digitalRead(pin); // читаем - if (bitCount < 8) { // передача битов даты - bitWrite(buf[byteCount], bitCount, bit); // пишем в буфер - } else if (bitCount == 8) { // стоп бит (high) - if (!bit) return 0; // ошибка стоп бита. Завершаем - byteCount++; // счётчик собранных байтов - } else if (bitCount == 9) { // старт бит (low) - if (bit) return byteCount; // не дождались старт бита. Конец приёма, возврат количества - if (byteCount >= size) return 0; // буфер переполнен. Завершаем - bitCount = -1; // костыль + if (!digitalRead(pin)) { // проверяем старт бит (low) + delayMicroseconds(GBUS_BIT_2); // ждём половину времени + if (!digitalRead(pin)) { // если всё ещё старт бит (low) + int8_t bitCount = 0; // счётчик битов + uint8_t byteCount = 0; // счётчик байтов + while (1) { + delayMicroseconds(GBUS_BIT-GBUS_OFFSET_READ); // ждём бит + uint8_t bit = digitalRead(pin); // читаем + if (bitCount < 8) { // передача битов даты + bitWrite(buf[byteCount], bitCount, bit); // пишем в буфер + } else if (bitCount == 8) { // стоп бит (high) + if (!bit) return 0; // ошибка стоп бита. Завершаем + byteCount++; // счётчик собранных байтов + } else if (bitCount == 9) { // старт бит (low) + if (bit) return byteCount; // не дождались старт бита. Конец приёма, возврат количества + if (byteCount >= size) return 0; // буфер переполнен. Завершаем + bitCount = -1; // костыль } - bitCount++; // следующий бит + bitCount++; // следующий бит } } } @@ -61,22 +61,22 @@ uint8_t GBUS_read_raw(uint8_t pin, uint8_t* buf, uint8_t size) { // ******************************************************* uint8_t GBUS_read(uint8_t pin, uint8_t addr, uint8_t* buf, uint8_t size) { - uint8_t buf2[size + GBUS_OFFSET]; // буфер на приём - uint8_t bytes = GBUS_read_raw(pin, buf2, (size + GBUS_OFFSET)); // принимаем, получаем количество байт посылки - if (buf2[0] == bytes && (buf2[1] == addr || buf2[1] == 255)) { // если совпало количество байт и адрес + uint8_t buf2[size + GBUS_OFFSET]; // буфер на приём + uint8_t bytes = GBUS_read_raw(pin, buf2, (size + GBUS_OFFSET)); // принимаем, получаем количество байт посылки + if (buf2[0] == bytes && (buf2[1] == addr || buf2[1] == 255)) { // если совпало количество байт и адрес #if (GBUS_CRC == 1) if (GBUS_crc_bytes(buf2, bytes) != 0) return 0; #endif - for (uint8_t i = 0; i < bytes - GBUS_OFFSET; i++) buf[i] = buf2[i + 3]; // переписываем в буфер в скетче - return buf2[2]; // возвращаем адрес + for (uint8_t i = 0; i < bytes - GBUS_OFFSET; i++) buf[i] = buf2[i + 3]; // переписываем в буфер в скетче + return buf2[2]; // возвращаем адрес } - return 0; // иначе возвращаем ошибку + return 0; // иначе возвращаем ошибку } // ******************************************************* // структура буфера: [0, адрес получателя, адрес отправителя, CRC] uint8_t GBUS_read_request(uint8_t pin, uint8_t addr) { - uint8_t buf[GBUS_OFFSET]; + uint8_t buf[GBUS_OFFSET]; if (GBUS_read_raw(pin, buf, GBUS_OFFSET) == GBUS_OFFSET && (buf[1] == addr || buf[1] == 255) #if (GBUS_CRC == 1) @@ -89,7 +89,7 @@ uint8_t GBUS_read_request(uint8_t pin, uint8_t addr) { // ******************************************************* // структура буфера: [1, адрес получателя, адрес отправителя, CRC] uint8_t GBUS_read_ack(uint8_t pin, uint8_t addr) { - uint8_t buf[GBUS_OFFSET]; + uint8_t buf[GBUS_OFFSET]; if (GBUS_read_raw(pin, buf, GBUS_OFFSET) == GBUS_OFFSET && (buf[1] == addr || buf[1] == 255) #if (GBUS_CRC == 1) diff --git a/src/GBUSmini.h b/src/GBUSmini.h index ae57c9b..436a8a5 100644 --- a/src/GBUSmini.h +++ b/src/GBUSmini.h @@ -5,10 +5,10 @@ // ==================== СТАНДАРТНЫЕ НАСТРОЙКИ ====================== // могут быть изменены здесь, либо прямо в скетче при помощи дефайна ПЕРЕД ПОДКЛЮЧЕНИЕМ БИБЛИОТЕКИ // дефайны в скетч соответственно GBUS_SPEED, GBUS_OFFSET_WRITE, GBUS_OFFSET_READ -#define GBUS_DEFAULT_SPEED 400 // скорость (baud) -#define GBUS_DEFAULT_WRITE 8 // коррекция задержки записи, мкс -#define GBUS_DEFAULT_READ 5 // коррекция задержки чтения, мкс -#define GBUSMINI_BUSY_TIMEOUT 50 // таймаут отправки после предыдущей активности на линии, мс +#define GBUS_DEFAULT_SPEED 400 // скорость (baud) +#define GBUS_DEFAULT_WRITE 8 // коррекция задержки записи, мкс +#define GBUS_DEFAULT_READ 5 // коррекция задержки чтения, мкс +#define GBUSMINI_BUSY_TIMEOUT 50 // таймаут отправки после предыдущей активности на линии, мс // ========== ЛЁГКИЕ ФУНКЦИИ ОТПРАВКИ И ЧТЕНИЯ GBUS ========== // По одному проводу diff --git a/src/GyverBus.cpp b/src/GyverBus.cpp index df6d883..1a03176 100644 --- a/src/GyverBus.cpp +++ b/src/GyverBus.cpp @@ -1,22 +1,22 @@ #include "GyverBus.h" uint8_t packGBUScmd(uint8_t* buffer, uint8_t cmd, uint8_t to, uint8_t from) { - buffer[0] = cmd; // команда - buffer[1] = to; // адрес приёмника - buffer[2] = from; // адрес передатчика + buffer[0] = cmd; // команда + buffer[1] = to; // адрес приёмника + buffer[2] = from; // адрес передатчика if (GBUS_CRC) buffer[3] = GBUS_crc_bytes(buffer, 3); return GBUS_OFFSET; } GBUSstatus checkGBUS(uint8_t* buffer, uint8_t bufSize, uint8_t amount, uint8_t addr) { - if (buffer[0] > bufSize) return RX_OVERFLOW; // буфер переполнен - if (amount > GBUS_OFFSET && amount > buffer[0]) return RX_OVERFLOW; // пакет слишком большой - if (buffer[1] != addr && buffer[1] != 255) return RX_ADDRESS_ERROR; // не наш адрес - if (amount < GBUS_OFFSET || (amount > GBUS_OFFSET && amount < buffer[0])) return RX_ABORT; // передача прервана - if (GBUS_CRC) if (GBUS_crc_bytes(buffer, amount) != 0) return RX_CRC_ERROR; // данные повреждены - if (buffer[0] == 0) return RX_REQUEST; // реквест - if (buffer[0] == 1) return RX_ACK; // подтверждение - return RX_DATA; // данные приняты успешно + if (buffer[0] > bufSize) return RX_OVERFLOW; // буфер переполнен + if (amount > GBUS_OFFSET && amount > buffer[0]) return RX_OVERFLOW; // пакет слишком большой + if (buffer[1] != addr && buffer[1] != 255) return RX_ADDRESS_ERROR; // не наш адрес + if (amount < GBUS_OFFSET || (amount > GBUS_OFFSET && amount < buffer[0])) return RX_ABORT; // передача прервана + if (GBUS_CRC) if (GBUS_crc_bytes(buffer, amount) != 0) return RX_CRC_ERROR; // данные повреждены + if (buffer[0] == 0) return RX_REQUEST; // реквест + if (buffer[0] == 1) return RX_ACK; // подтверждение + return RX_DATA; // данные приняты успешно } void GBUS_crc_update(uint8_t &crc, uint8_t data) { diff --git a/src/GyverBus.h b/src/GyverBus.h index 694a8f9..c1b5618 100644 --- a/src/GyverBus.h +++ b/src/GyverBus.h @@ -41,29 +41,29 @@ Библиотека GBUS.h позволяет общаться по протоколу GBUS через любой Stream-объект (Serial, SoftwareSerial, softUART и проч). Основное описание содержится в ней Библиотека GyverBus.h содержит базовые инструменты для упаковки и распаковки данных в байтовые пакеты с адресацией и CRC Библиотека softUART.h - это однопроводной UART, работающий на приём и отправку, причём не блокирующий выполнение кода - Библиотека GBUSmini.h - это набор лёгких БЛОКИРУЮЩИХ функций для общения по одному проводу. Предусмотрено для мелких МК + Библиотека GBUSmini.h - это набор лёгких БЛОКИРУЮЩИХ функций для общения по одному проводу. Предусмотрено для мелких МК */ #ifndef _GyverBus_h #define _GyverBus_h #include // ============== НАСТРОЙКИ ============== -#define GBUS_CRC 1 // 1 - вкл CRC, 0 - выкл (экономит память, но того не стоит) +#define GBUS_CRC 1 // 1 - вкл CRC, 0 - выкл (экономит память, но того не стоит) // СТАТУСЫ (НЕ ТРОГАТЬ) enum GBUSstatus { - GBUS_IDLE, + GBUS_IDLE, TRANSMITTING, - TX_OVERFLOW, - TX_COMPLETE, - RECEIVING, + TX_OVERFLOW, + TX_COMPLETE, + RECEIVING, RX_ERROR, RX_ABORT, RX_OVERFLOW, - RX_ADDRESS_ERROR, + RX_ADDRESS_ERROR, RX_CRC_ERROR, - RX_REQUEST, + RX_REQUEST, RX_DATA, RX_ACK, }; @@ -123,28 +123,23 @@ uint8_t GBUS_crc_bytes(uint8_t *data, uint8_t size); #define ACK_DATA 4 #define GBUS_BROADCAST 255 -// привет разработчикам ядра esp8266. Ничего не потеряли?) -#if defined(ESP8266) -#define min(a,b) ((a)<(b)?(a):(b)) -#endif - template uint8_t packGBUSdata(uint8_t* buffer, uint8_t bufSize, T &data, uint8_t to, uint8_t from) { - buffer[0] = sizeof(T) + GBUS_OFFSET; // размер пакета с учётом служебных - if (buffer[0] > bufSize) return 0; // если переполним буфер - buffer[1] = to; // адрес приёмника - buffer[2] = from; // адрес передатчика - const uint8_t *ptr = (const uint8_t*) &data; // указатель - for (uint16_t i = 0; i < sizeof(T); i++) buffer[i + 3] = *ptr++; // пакуем дату - if (GBUS_CRC) buffer[sizeof(T) + 3] = GBUS_crc_bytes(buffer, sizeof(T) + 3);// crc + buffer[0] = sizeof(T) + GBUS_OFFSET; // размер пакета с учётом служебных + if (buffer[0] > bufSize) return 0; // если переполним буфер + buffer[1] = to; // адрес приёмника + buffer[2] = from; // адрес передатчика + const uint8_t *ptr = (const uint8_t*) &data; // указатель + for (uint16_t i = 0; i < sizeof(T); i++) buffer[i + 3] = *ptr++; // пакуем дату + if (GBUS_CRC) buffer[sizeof(T) + 3] = GBUS_crc_bytes(buffer, sizeof(T) + 3);// crc return buffer[0]; } template bool unpackGBUSdata(uint8_t* buffer, uint8_t bufSize, T &data) { - if (sizeof(T) + GBUS_OFFSET > bufSize) return false; // если данные больше буфера (+ служебная инфа протокола) - uint8_t *ptr = (uint8_t*) &data; - for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i + 3]; // пишем + if (sizeof(T) + GBUS_OFFSET > bufSize) return false; // если данные больше буфера (+ служебная инфа протокола) + uint8_t *ptr = (uint8_t*) &data; + for (uint16_t i = 0; i < sizeof(T); i++) *ptr++ = buffer[i + 3]; // пишем return true; } diff --git a/src/softUART.h b/src/softUART.h index e32a3fc..f4c4f56 100644 --- a/src/softUART.h +++ b/src/softUART.h @@ -6,7 +6,7 @@ // Наследует класс Print, то есть можно отправлять всё что угодно, как через обычный Serial // Улучшенная производительность для AVR Arduino -#define SOFTUART_TX_WAIT 50 // Таймаут ожидания наполнения буфера через write, мкс +#define SOFTUART_TX_WAIT 50 // Таймаут ожидания наполнения буфера через write, мкс /* Интерфейс: UART. start бит 0, stop бит 1. Кодирование даты: HIGH - 0x1, LOW - 0x0 @@ -26,7 +26,7 @@ - скорость: скорость в бодах */ // ============================================================================================= -#define SOFTUART_BUF_SIZE 64 // Стандартный размер буфера на отправку, байт +#define SOFTUART_BUF_SIZE 64 // Стандартный размер буфера на отправку, байт #include // КОНСТАНТЫ @@ -45,14 +45,14 @@ class softUART : public Stream { _pin_reg = portInputRegister(digitalPinToPort(_PIN)); _ddr_reg = portModeRegister(digitalPinToPort(_PIN)); _bit_mask = digitalPinToBitMask(_PIN); - *_ddr_reg &= ~_bit_mask; // INPUT - *_port_reg |= _bit_mask; // HIGH + *_ddr_reg &= ~_bit_mask; // INPUT + *_port_reg |= _bit_mask; // HIGH #else pinMode(_PIN, INPUT_PULLUP); #endif _bitTime = 1000000UL / baud; _bitTime2 = (uint32_t)_bitTime >> 1; - _timeout = _bitTime * 10 * 10; // таймаут как время передачи 10 байт + _timeout = _bitTime * 10 * 10; // таймаут как время передачи 10 байт if (_ROLE == GBUS_TX || _ROLE == GBUS_FULL) buffer = (byte *)malloc(_bufSize); } @@ -67,15 +67,15 @@ class softUART : public Stream { BUS_READING, }; - bool isBusy() { + bool isBusy() { return !(micros() - _tmr > _timeout); } int tick() {return available();} - virtual int available() { - if (_role == GBUS_RX) { // приёмник - if (_ROLE == GBUS_RX || _ROLE == GBUS_FULL) { // компилятор вырежет при выбранной роли + virtual int available() { + if (_role == GBUS_RX) { // приёмник + if (_ROLE == GBUS_RX || _ROLE == GBUS_FULL) { // компилятор вырежет при выбранной роли #if defined(__AVR__) byte bit = (*_pin_reg & _bit_mask); #else @@ -83,7 +83,7 @@ class softUART : public Stream { #endif switch(_busStage) { case BUS_IDLE: - if (!bit) { // старт бит? + if (!bit) { // старт бит? _tmr = micros(); _busStage = BUS_START; } @@ -91,90 +91,90 @@ class softUART : public Stream { case BUS_START: if (micros() - _tmr >= _bitTime2) { - if (!bit) { // да, старт бит - _busStage = BUS_READING; // начинаем приём - _bitCount = 0; - _tmr += _bitTime2; // ждём пол-фрейма - } else { // ошибка - _busStage = BUS_IDLE; - } + if (!bit) { // да, старт бит + _busStage = BUS_READING; // начинаем приём + _bitCount = 0; + _tmr += _bitTime2; // ждём пол-фрейма + } else { // ошибка + _busStage = BUS_IDLE; + } } break; case BUS_READING: - if (micros() - _tmr >= _bitTime) { // таймер - _tmr += _bitTime; // следующий фрейм - if (_bitCount < 8) { // чтение битов даты (0-7) - bitWrite(_thisByte, _bitCount, bit); // пишем в буфер - } else if (_bitCount == 8) { // проверяем стоп бит + if (micros() - _tmr >= _bitTime) { // таймер + _tmr += _bitTime; // следующий фрейм + if (_bitCount < 8) { // чтение битов даты (0-7) + bitWrite(_thisByte, _bitCount, bit); // пишем в буфер + } else if (_bitCount == 8) { // проверяем стоп бит if (!bit) _busStage = BUS_IDLE; // не дождались стоп бита, конец приема - else _readFlag = 1; // стоп бит. Байт принят - } else if (_bitCount == 9) { // проверяем старт бит + else _readFlag = 1; // стоп бит. Байт принят + } else if (_bitCount == 9) { // проверяем старт бит if (bit) _busStage = BUS_IDLE; // не дождались нового старт бита, конец приема - _bitCount = -1; // костыль + _bitCount = -1; // костыль } - _bitCount++; // следующий бит + _bitCount++; // следующий бит } - break; - } + break; + } } - return _readFlag; // вернули 1 если байт собран - } else { // передатчик - if (_ROLE == GBUS_TX || _ROLE == GBUS_FULL) { // компилятор вырежет при выбранной роли + return _readFlag; // вернули 1 если байт собран + } else { // передатчик + if (_ROLE == GBUS_TX || _ROLE == GBUS_FULL) { // компилятор вырежет при выбранной роли switch(_busStage) { case BUS_IDLE: if (_writeStart && micros() - _tmr > SOFTUART_TX_WAIT) { - _writeStart = false; + _writeStart = false; _busStage = BUS_START; } break; case BUS_START: - if (!isBusy()) { // ждём окончания активности на линии + if (!isBusy()) { // ждём окончания активности на линии _busStage = BUS_SENDING; _bitCount = -1; - _byteCount = 0; + _byteCount = 0; _tmr = micros(); } break; case BUS_SENDING: - if (micros() - _tmr >= _bitTime) { - byte bit; - if (_bitCount < 0) bit = 0; // старт бит - else if (_bitCount < 8) { // передача даты + if (micros() - _tmr >= _bitTime) { + byte bit; + if (_bitCount < 0) bit = 0; // старт бит + else if (_bitCount < 8) { // передача даты bit = (buffer[_byteCount] >> _bitCount) & 1; // бит даты } else { - bit = 1; // стоп бит - _byteCount++; // след. байт - _bitCount = -2; // костыль + bit = 1; // стоп бит + _byteCount++; // след. байт + _bitCount = -2; // костыль } // дрыг #if defined(__AVR__) if (bit) { - *_ddr_reg &= ~_bit_mask; // INPUT - *_port_reg |= _bit_mask; // HIGH + *_ddr_reg &= ~_bit_mask; // INPUT + *_port_reg |= _bit_mask; // HIGH } else { - *_ddr_reg |= _bit_mask; // OUTPUT - *_port_reg &= ~_bit_mask; // LOW + *_ddr_reg |= _bit_mask; // OUTPUT + *_port_reg &= ~_bit_mask; // LOW } #else pinMode(_PIN, !bit); digitalWrite(_PIN, bit); #endif _bitCount++; - _tmr += _bitTime; // таймер - if (_byteCount == _txSize) { // передача окончена + _tmr += _bitTime; // таймер + if (_byteCount == _txSize) { // передача окончена _busStage = BUS_IDLE; if (_ROLE == GBUS_FULL) _role = GBUS_RX;// переключение на приёмник - _tmr = micros(); // сброс таймера + _tmr = micros(); // сброс таймера } } break; } } - return 0; // в режиме передатчика возвращаем 0 + return 0; // в режиме передатчика возвращаем 0 } - } + } virtual int read() { _readFlag = 0; @@ -184,7 +184,7 @@ class softUART : public Stream { virtual size_t write(uint8_t byte) { // КВМ (Костыль Вселенских Масштабов) // наполняем буфер по таймеру - if (_ROLE == GBUS_TX || _ROLE == GBUS_FULL) { // компилер вырежет, если ты приёмный + if (_ROLE == GBUS_TX || _ROLE == GBUS_FULL) { // компилер вырежет, если ты приёмный if (!_writeStart) { _writeStart = true; _txSize = 0; @@ -195,7 +195,7 @@ class softUART : public Stream { } } - virtual void flush() {} + virtual void flush() {} int peek(){} private: @@ -206,7 +206,7 @@ class softUART : public Stream { byte _txSize = 0; byte _byteCount = 0; byte _thisByte; - byte _readFlag = 0; + byte _readFlag = 0; uint32_t _tmr; byte _role = GBUS_RX; BUS_stage _busStage = BUS_IDLE;