diff --git a/README.md b/README.md index eeac899..e2576d8 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ void loop() { - v1.2 - улучшение качества связи, оптимизация работы в прерывании - v1.3 - добавлен вывод RSSI - v1.4 - переделан FastIO +- v1.4.1 - убран FastIO, CRC вынесен отдельно ## Баги и обратная связь diff --git a/library.properties b/library.properties index 3f71ba7..797b725 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Gyver433 -version=1.4 +version=1.4.1 author=AlexGyver maintainer=AlexGyver sentence=Simple library for 433 MHz radio diff --git a/src/FastIO_v2.cpp b/src/FastIO_v2.cpp deleted file mode 100644 index 2e1ecdf..0000000 --- a/src/FastIO_v2.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "FastIO_v2.h" - -bool F_fastRead(const uint8_t pin) { -#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) - if (pin < 8) return bitRead(PIND, pin); - else if (pin < 14) return bitRead(PINB, pin - 8); - else if (pin < 20) return bitRead(PINC, pin - 14); - -#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) - return bitRead(PINB, pin); - -#elif defined(AVR) - uint8_t *_pin_reg = portInputRegister(digitalPinToPort(pin)); - uint8_t _bit_mask = digitalPinToBitMask(pin); - return bool(*_pin_reg & _bit_mask); - -#else - return digitalRead(pin); - -#endif - return 0; -} - -void F_fastWrite(const uint8_t pin, bool val) { -#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) - if (pin < 8) bitWrite(PORTD, pin, val); - else if (pin < 14) bitWrite(PORTB, (pin - 8), val); - else if (pin < 20) bitWrite(PORTC, (pin - 14), val); - -#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) - bitWrite(PORTB, pin, val); - -#elif defined(AVR) - uint8_t *_port_reg = portInputRegister(digitalPinToPort(pin)); - uint8_t _bit_mask = digitalPinToBitMask(pin); - _port_reg = portOutputRegister(digitalPinToPort(pin)); - _bit_mask = digitalPinToBitMask(pin); - if (val) *_port_reg |= _bit_mask; // HIGH - else *_port_reg &= ~_bit_mask; // LOW - -#else - digitalWrite(pin, val); - -#endif -} - -uint8_t F_fastShiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { -#if defined(AVR) - volatile uint8_t *_clk_port = portOutputRegister(digitalPinToPort(clockPin)); - volatile uint8_t *_dat_port = portInputRegister(digitalPinToPort(dataPin)); - uint8_t _clk_mask = digitalPinToBitMask(clockPin); - uint8_t _dat_mask = digitalPinToBitMask(dataPin); - uint8_t data = 0; - for (uint8_t i = 0; i < 8; i++) { - *_clk_port |= _clk_mask; - if (bitOrder == MSBFIRST) { - data <<= 1; - if (bool(*_dat_port & _dat_mask)) data |= 1; - } else { - data >>= 1; - if (bool(*_dat_port & _dat_mask)) data |= 1 << 7; - } - *_clk_port &= ~_clk_mask; - } - return data; -#else - return shiftIn(dataPin, clockPin, bitOrder); -#endif -} - -void F_fastShiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t data) { -#if defined(AVR) - volatile uint8_t *_clk_port = portOutputRegister(digitalPinToPort(clockPin)); - volatile uint8_t *_dat_port = portOutputRegister(digitalPinToPort(dataPin)); - uint8_t _clk_mask = digitalPinToBitMask(clockPin); - uint8_t _dat_mask = digitalPinToBitMask(dataPin); - for (uint8_t i = 0; i < 8; i++) { - if (bitOrder == MSBFIRST) { - if (data & (1 << 7)) *_dat_port |= _dat_mask; - else *_dat_port &= ~_dat_mask; - data <<= 1; - } else { - if (data & 1) *_dat_port |= _dat_mask; - else *_dat_port &= ~_dat_mask; - data >>= 1; - } - *_clk_port |= _clk_mask; - *_clk_port &= ~_clk_mask; - } -#else - shiftOut(dataPin, clockPin, bitOrder, data); -#endif -} \ No newline at end of file diff --git a/src/FastIO_v2.h b/src/FastIO_v2.h deleted file mode 100644 index e83265c..0000000 --- a/src/FastIO_v2.h +++ /dev/null @@ -1,13 +0,0 @@ -// Быстрый IO для AVR (для остальных будет digitalxxxxx) -// v1.0 - -#ifndef _FastIO_v2_h -#define _FastIO_v2_h -#include - -bool F_fastRead(const uint8_t pin); // быстрое чтение пина -void F_fastWrite(const uint8_t pin, bool val); // быстрая запись -uint8_t F_fastShiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); // быстрый shiftIn -void F_fastShiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t data); // быстрый shiftOut - -#endif \ No newline at end of file diff --git a/src/G433_crc.cpp b/src/G433_crc.cpp new file mode 100644 index 0000000..68a76ae --- /dev/null +++ b/src/G433_crc.cpp @@ -0,0 +1,41 @@ +#include "G433_crc.h" + +void G433_crc8_byte(uint8_t &crc, uint8_t data) { +#if defined (__AVR__) + // резкий алгоритм для AVR + uint8_t counter; + uint8_t buffer; + asm volatile ( + "EOR %[crc_out], %[data_in] \n\t" + "LDI %[counter], 8 \n\t" + "LDI %[buffer], 0x8C \n\t" + "_loop_start_%=: \n\t" + "LSR %[crc_out] \n\t" + "BRCC _loop_end_%= \n\t" + "EOR %[crc_out], %[buffer] \n\t" + "_loop_end_%=: \n\t" + "DEC %[counter] \n\t" + "BRNE _loop_start_%=" + : [crc_out]"=r" (crc), [counter]"=d" (counter), [buffer]"=d" (buffer) + : [crc_in]"0" (crc), [data_in]"r" (data) + ); +#else + // обычный для всех остальных + uint8_t i = 8; + while (i--) { + crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1); + data >>= 1; + } +#endif +} + +uint8_t G433_crc8(uint8_t *buffer, uint8_t size) { + uint8_t crc = 0; + for (uint8_t i = 0; i < size; i++) G433_crc8_byte(crc, buffer[i]); + return crc; +} +uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size) { + uint8_t crc = 0; + for (uint8_t i = 0; i < size; i++) crc ^= buffer[i]; + return crc; +} \ No newline at end of file diff --git a/src/G433_crc.h b/src/G433_crc.h new file mode 100644 index 0000000..11ceecc --- /dev/null +++ b/src/G433_crc.h @@ -0,0 +1,7 @@ +#ifndef G433_crc_h +#define G433_crc_h +#include +uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8 +uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR +void G433_crc8_byte(uint8_t &crc, uint8_t data); // crc8 один байт +#endif \ No newline at end of file diff --git a/src/Gyver433.h b/src/Gyver433.h index c10cf5e..8e9454c 100644 --- a/src/Gyver433.h +++ b/src/Gyver433.h @@ -20,15 +20,14 @@ v1.2 - улучшение качества связи, оптимизация работы в прерывании v1.3 - добавлен вывод RSSI v1.4 - переделан FastIO + v1.4.1 - убран FastIO, CRC вынесен отдельно */ #ifndef Gyver433_h #define Gyver433_h #include -#include "FastIO_v2.h" +#include "G433_crc.h" -uint8_t G433_crc8(uint8_t *buffer, uint8_t size); // ручной CRC8 -uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR #define TRAINING_TIME_SLOW (500000ul) // время синхронизации для SLOW_MODE // ========================================================================= @@ -76,9 +75,6 @@ uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size); // ручной CRC XOR #define TRAINING_PULSES 50 #endif -// crc8 один байт -void G433_crc8_byte(uint8_t &crc, uint8_t data); - // ============ ПЕРЕДАТЧИК ============ template class Gyver433_TX { @@ -108,28 +104,28 @@ class Gyver433_TX { // отправка сырого набора байтов void write(uint8_t* buf, uint16_t size) { for (uint16_t i = 0; i < TRAINING_PULSES; i++) { - F_fastWrite(TX_PIN, 1); + fastWrite(TX_PIN, 1); G433_DELAY(FRAME_TIME); - F_fastWrite(TX_PIN, 0); + fastWrite(TX_PIN, 0); G433_DELAY(FRAME_TIME); } - F_fastWrite(TX_PIN, 1); // старт + fastWrite(TX_PIN, 1); // старт G433_DELAY(START_PULSE); // ждём - F_fastWrite(TX_PIN, 0); // старт бит + fastWrite(TX_PIN, 0); // старт бит #ifdef G433_MANCHESTER G433_DELAY(HALF_FRAME); // ждём for (uint16_t n = 0; n < size; n++) { uint8_t data = buf[n]; for (uint8_t b = 0; b < 8; b++) { - F_fastWrite(TX_PIN, !(data & 1)); + fastWrite(TX_PIN, !(data & 1)); G433_DELAY(HALF_FRAME); - F_fastWrite(TX_PIN, (data & 1)); + fastWrite(TX_PIN, (data & 1)); G433_DELAY(HALF_FRAME); data >>= 1; } } - F_fastWrite(TX_PIN, 0); // конец передачи + fastWrite(TX_PIN, 0); // конец передачи #else bool flag = 0; for (uint16_t n = 0; n < size; n++) { @@ -137,7 +133,7 @@ class Gyver433_TX { for (uint8_t b = 0; b < 8; b++) { if (data & 1) G433_DELAY(FRAME_TIME); else G433_DELAY(HALF_FRAME); - F_fastWrite(TX_PIN, flag = !flag); + fastWrite(TX_PIN, flag = !flag); data >>= 1; } } @@ -147,7 +143,18 @@ class Gyver433_TX { // доступ к буферу uint8_t buffer[TX_BUF + !!CRC_MODE]; -private: +private: + void fastWrite(const uint8_t pin, bool val) { +#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) + if (pin < 8) bitWrite(PORTD, pin, val); + else if (pin < 14) bitWrite(PORTB, (pin - 8), val); + else if (pin < 20) bitWrite(PORTC, (pin - 14), val); +#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) + bitWrite(PORTB, pin, val); +#else + digitalWrite(pin, val); +#endif + } }; // ============ ПРИЁМНИК ============ @@ -231,8 +238,21 @@ class Gyver433_RX { uint8_t buffer[RX_BUF + !!CRC_MODE]; private: + bool fastRead(const uint8_t pin) { +#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) + if (pin < 8) return bitRead(PIND, pin); + else if (pin < 14) return bitRead(PINB, pin - 8); + else if (pin < 20) return bitRead(PINC, pin - 14); +#elif defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) + return bitRead(PINB, pin); +#else + return digitalRead(pin); +#endif + return 0; + } + bool pinChanged() { - bit = F_fastRead(RX_PIN); + bit = fastRead(RX_PIN); if (bit != prevBit) { prevBit = bit; return 1; @@ -292,44 +312,4 @@ class Gyver433_RX { uint8_t errCount = 0, rcCount = 0, RSSI = 0; }; -// ===== CRC ===== -void G433_crc8_byte(uint8_t &crc, uint8_t data) { -#if defined (__AVR__) - // резкий алгоритм для AVR - uint8_t counter; - uint8_t buffer; - asm volatile ( - "EOR %[crc_out], %[data_in] \n\t" - "LDI %[counter], 8 \n\t" - "LDI %[buffer], 0x8C \n\t" - "_loop_start_%=: \n\t" - "LSR %[crc_out] \n\t" - "BRCC _loop_end_%= \n\t" - "EOR %[crc_out], %[buffer] \n\t" - "_loop_end_%=: \n\t" - "DEC %[counter] \n\t" - "BRNE _loop_start_%=" - : [crc_out]"=r" (crc), [counter]"=d" (counter), [buffer]"=d" (buffer) - : [crc_in]"0" (crc), [data_in]"r" (data) - ); -#else - // обычный для всех остальных - uint8_t i = 8; - while (i--) { - crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1); - data >>= 1; - } -#endif -} - -uint8_t G433_crc8(uint8_t *buffer, uint8_t size) { - uint8_t crc = 0; - for (uint8_t i = 0; i < size; i++) G433_crc8_byte(crc, buffer[i]); - return crc; -} -uint8_t G433_crc_xor(uint8_t *buffer, uint8_t size) { - uint8_t crc = 0; - for (uint8_t i = 0; i < size; i++) crc ^= buffer[i]; - return crc; -} #endif \ No newline at end of file