From 7f071ec949befcc71c7ab747dfdc0d81da3a1b9f Mon Sep 17 00:00:00 2001 From: NekoNekoNyan Date: Thu, 29 Aug 2019 20:52:55 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20variants,?= =?UTF-8?q?=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D1=8D=D1=82=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83?= =?UTF-8?q?=D0=B5=D1=82=D1=81=D1=8F=20build.extra=5Fflags.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GyverCore/boards.txt | 4 ++-- GyverCore/cores/arduino/time_init.cpp | 1 - GyverCore/variants/nomillis/timeControl.h | 0 GyverCore/variants/yesmillis/timeControl.h | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 GyverCore/variants/nomillis/timeControl.h delete mode 100644 GyverCore/variants/yesmillis/timeControl.h diff --git a/GyverCore/boards.txt b/GyverCore/boards.txt index 4056100..077ab55 100644 --- a/GyverCore/boards.txt +++ b/GyverCore/boards.txt @@ -22,10 +22,10 @@ nano.build.core=arduino ## timer0 OVF ON/OFF ## -------------------------- nano.menu.timers.yes_millis=with millis -nano.menu.timers.yes_millis.build.variant=yesmillis +nano.menu.timers.yes_millis.build.extra_flags=-DMILLIS_TMRS nano.menu.timers.no_millis=without millis -nano.menu.timers.no_millis.build.variant=nomillis +nano.menu.timers.no_millis.build.extra_flags= ## Clock ## -------------------------- diff --git a/GyverCore/cores/arduino/time_init.cpp b/GyverCore/cores/arduino/time_init.cpp index 644ba4a..0a0a667 100644 --- a/GyverCore/cores/arduino/time_init.cpp +++ b/GyverCore/cores/arduino/time_init.cpp @@ -1,5 +1,4 @@ #include "Arduino.h" -#include "timeControl.h" /* функции времени и инициализация таймеров , АЦП*/ /* #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) // 1024 на 16 МГц / 2048 на 8 МГц diff --git a/GyverCore/variants/nomillis/timeControl.h b/GyverCore/variants/nomillis/timeControl.h deleted file mode 100644 index e69de29..0000000 diff --git a/GyverCore/variants/yesmillis/timeControl.h b/GyverCore/variants/yesmillis/timeControl.h deleted file mode 100644 index 4ba6fcf..0000000 --- a/GyverCore/variants/yesmillis/timeControl.h +++ /dev/null @@ -1 +0,0 @@ -#define MILLIS_TMRS \ No newline at end of file From 73a96106105a8a244e6e193aa6dc8995204928e6 Mon Sep 17 00:00:00 2001 From: NekoNekoNyan Date: Thu, 29 Aug 2019 21:06:46 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=20delay/delayMicroseconds=20=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=B8=20=D0=B8=D0=B7=20avrlibc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GyverCore/cores/arduino/Arduino.h | 8 ++++++-- GyverCore/cores/arduino/time_init.cpp | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/GyverCore/cores/arduino/Arduino.h b/GyverCore/cores/arduino/Arduino.h index 217c58b..3277f3c 100644 --- a/GyverCore/cores/arduino/Arduino.h +++ b/GyverCore/cores/arduino/Arduino.h @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C"{ @@ -121,8 +122,11 @@ void analogWrite(uint8_t pin, int val); unsigned long millis(void); unsigned long micros(void); -void delay(unsigned long); -void delayMicroseconds(unsigned int us); + +/* Эти функции доступны по умолчанию и не исмользуют millis или прерывания */ +#define delay(x) (_delay_ms((x))) +#define delayMicroseconds(x) (_delay_us((x))) + unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); diff --git a/GyverCore/cores/arduino/time_init.cpp b/GyverCore/cores/arduino/time_init.cpp index 0a0a667..c195b0d 100644 --- a/GyverCore/cores/arduino/time_init.cpp +++ b/GyverCore/cores/arduino/time_init.cpp @@ -59,6 +59,7 @@ unsigned long micros() { // return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); // default } +/* void delay(unsigned long ms) { uint32_t start = micros(); // запомнили время старта @@ -90,6 +91,7 @@ void delayMicroseconds(unsigned int us) // работает на счете ти ); // return = 4 cycles } +*/ void init() // функция инициализации { From 712442fa00646906ce1014947fc5b15394f2f23b Mon Sep 17 00:00:00 2001 From: NekoNekoNyan Date: Thu, 29 Aug 2019 21:49:19 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=D0=BB=20HardwareSerial.cpp=20=D0=BA=D0=B0=D0=BA=20=D0=B2?= =?UTF-8?q?=20uart.cpp,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B9=20uart*=20=D0=B2?= =?UTF-8?q?=20Serial.*=20uart.cpp/uart.h=20=D0=BF=D0=BE-=D1=85=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D1=88=D0=B5=D0=BC=D1=83=20=D0=BD=D0=B0=D0=B4=D0=BE=20?= =?UTF-8?q?=D0=B1=D1=8B=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D1=82=D1=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GyverCore/cores/arduino/HardwareSerial.cpp | 272 +++--------------- GyverCore/cores/arduino/HardwareSerial.h | 81 +----- GyverCore/cores/arduino/HardwareSerial0.cpp | 80 ------ .../cores/arduino/HardwareSerial_private.h | 102 ------- GyverCore/cores/arduino/uart.cpp | 64 +---- GyverCore/cores/arduino/uart.h | 16 +- 6 files changed, 58 insertions(+), 557 deletions(-) delete mode 100644 GyverCore/cores/arduino/HardwareSerial0.cpp delete mode 100644 GyverCore/cores/arduino/HardwareSerial_private.h diff --git a/GyverCore/cores/arduino/HardwareSerial.cpp b/GyverCore/cores/arduino/HardwareSerial.cpp index 053cfd4..c68a17a 100644 --- a/GyverCore/cores/arduino/HardwareSerial.cpp +++ b/GyverCore/cores/arduino/HardwareSerial.cpp @@ -28,255 +28,69 @@ #include #include - #include "HardwareSerial.h" -#include "HardwareSerial_private.h" - -// this next line disables the entire HardwareSerial.cpp, -// this is so I can support Attiny series and any other chip without a uart -#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) - -// SerialEvent functions are weak, so when the user doesn't define them, -// the linker just sets their address to 0 (which is checked below). -// The Serialx_available is just a wrapper around Serialx.available(), -// but we can refer to it weakly so we don't pull in the entire -// HardwareSerial instance if the user doesn't also refer to it. -#if defined(HAVE_HWSERIAL0) - void serialEvent() __attribute__((weak)); - bool Serial0_available() __attribute__((weak)); -#endif - -#if defined(HAVE_HWSERIAL1) - void serialEvent1() __attribute__((weak)); - bool Serial1_available() __attribute__((weak)); -#endif -#if defined(HAVE_HWSERIAL2) - void serialEvent2() __attribute__((weak)); - bool Serial2_available() __attribute__((weak)); -#endif +static volatile rx_buffer_index_t buffer_head; +static volatile rx_buffer_index_t buffer_tail; +static volatile char buffer[SERIAL_RX_BUFFER_SIZE]; -#if defined(HAVE_HWSERIAL3) - void serialEvent3() __attribute__((weak)); - bool Serial3_available() __attribute__((weak)); -#endif - -void serialEventRun(void) -{ -#if defined(HAVE_HWSERIAL0) - if (Serial0_available && serialEvent && Serial0_available()) serialEvent(); -#endif -#if defined(HAVE_HWSERIAL1) - if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1(); -#endif -#if defined(HAVE_HWSERIAL2) - if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2(); -#endif -#if defined(HAVE_HWSERIAL3) - if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3(); -#endif +HardwareSerial Serial {}; +void serialEvent() __attribute__((weak)); +void serialEventRun(void){ + if (serialEvent && Serial.available()) serialEvent(); } -// macro to guard critical sections when needed for large TX buffer sizes -#if (SERIAL_TX_BUFFER_SIZE>256) -#define TX_BUFFER_ATOMIC ATOMIC_BLOCK(ATOMIC_RESTORESTATE) -#else -#define TX_BUFFER_ATOMIC -#endif - -// Actual interrupt handlers ////////////////////////////////////////////////////////////// - -void HardwareSerial::_tx_udr_empty_irq(void) -{ - // If interrupts are enabled, there must be more data in the output - // buffer. Send the next byte - unsigned char c = _tx_buffer[_tx_buffer_tail]; - _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE; - - *_udr = c; - - // clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written. Other r/w bits are preserved, and zeroes - // written to the rest. - -#ifdef MPCM0 - *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0); -#else - *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0))); -#endif - - if (_tx_buffer_head == _tx_buffer_tail) { - // Buffer empty, so disable interrupts - cbi(*_ucsrb, UDRIE0); - } +ISR(USART_RX_vect) { + if (bit_is_set(UCSR0A, UPE0)) + UDR0; // Не сохранять новые данные если parity error + else { + unsigned char c = UDR0; + rx_buffer_index_t i = (unsigned int)(buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; + + // Не сохранять новые данные если нет места + if (i != buffer_tail) { + buffer[buffer_head] = c; + buffer_head = i; + } + } } -// Public Methods ////////////////////////////////////////////////////////////// -void HardwareSerial::begin(unsigned long baud, byte config) -{ - // Try u2x mode first - uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2; - *_ucsra = 1 << U2X0; +void HardwareSerial::begin(unsigned long baud, byte config) { + uint16_t speed = ((F_CPU / 8) / baud) - 1; // расчет baudrate + buffer_head = buffer_tail = 0; - // hardcoded exception for 57600 for compatibility with the bootloader - // shipped with the Duemilanove and previous boards and the firmware - // on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot - // be > 4095, so switch back to non-u2x mode if the baud rate is too - // low. - if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095)) - { - *_ucsra = 0; - baud_setting = (F_CPU / 8 / baud - 1) / 2; - } - - // assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register) - *_ubrrh = baud_setting >> 8; - *_ubrrl = baud_setting; - - _written = false; - - //set the data bits, parity, and stop bits -#if defined(__AVR_ATmega8__) - config |= 0x80; // select UCSRC register (shared with UBRRH) -#endif - *_ucsrc = config; - - sbi(*_ucsrb, RXEN0); - sbi(*_ucsrb, TXEN0); - sbi(*_ucsrb, RXCIE0); - cbi(*_ucsrb, UDRIE0); + UBRR0H = speed >> 8; + UBRR0L = speed; + UCSR0A = (1 << U2X0); // вкл удвоенную скорость + UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0); // вкл uart + UCSR0C = config; } -void HardwareSerial::end() -{ - // wait for transmission of outgoing data - flush(); - - cbi(*_ucsrb, RXEN0); - cbi(*_ucsrb, TXEN0); - cbi(*_ucsrb, RXCIE0); - cbi(*_ucsrb, UDRIE0); - - // clear any received data - _rx_buffer_head = _rx_buffer_tail; +void HardwareSerial::end() { + UCSR0B = 0; } -int HardwareSerial::available(void) -{ - return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE; +int HardwareSerial::available(void) { + return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + buffer_head - buffer_tail)) % SERIAL_RX_BUFFER_SIZE; } -int HardwareSerial::peek(void) -{ - if (_rx_buffer_head == _rx_buffer_tail) { - return -1; - } else { - return _rx_buffer[_rx_buffer_tail]; - } +int HardwareSerial::peek(void) { + return buffer_head != buffer_tail? buffer[buffer_tail]: -1; } -int HardwareSerial::read(void) -{ - // if the head isn't ahead of the tail, we don't have any characters - if (_rx_buffer_head == _rx_buffer_tail) { - return -1; - } else { - unsigned char c = _rx_buffer[_rx_buffer_tail]; - _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE; +int HardwareSerial::read(void) { + if (buffer_head == buffer_tail) + return -1; + + unsigned char c = buffer[buffer_tail]; + buffer_tail = (rx_buffer_index_t)(buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE; return c; - } -} - -int HardwareSerial::availableForWrite(void) -{ - tx_buffer_index_t head; - tx_buffer_index_t tail; - - TX_BUFFER_ATOMIC { - head = _tx_buffer_head; - tail = _tx_buffer_tail; - } - if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail; - return tail - head - 1; } -void HardwareSerial::flush() -{ - // If we have never written a byte, no need to flush. This special - // case is needed since there is no way to force the TXC (transmit - // complete) bit to 1 during initialization - if (!_written) - return; - - while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) { - if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0)) - // Interrupts are globally disabled, but the DR empty - // interrupt should be enabled, so poll the DR empty flag to - // prevent deadlock - if (bit_is_set(*_ucsra, UDRE0)) - _tx_udr_empty_irq(); - } - // If we get here, nothing is queued anymore (DRIE is disabled) and - // the hardware finished tranmission (TXC is set). -} - -size_t HardwareSerial::write(uint8_t c) -{ - _written = true; - // If the buffer and the data register is empty, just write the byte - // to the data register and be done. This shortcut helps - // significantly improve the effective datarate at high (> - // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown. - if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) { - // If TXC is cleared before writing UDR and the previous byte - // completes before writing to UDR, TXC will be set but a byte - // is still being transmitted causing flush() to return too soon. - // So writing UDR must happen first. - // Writing UDR and clearing TC must be done atomically, otherwise - // interrupts might delay the TXC clear so the byte written to UDR - // is transmitted (setting TXC) before clearing TXC. Then TXC will - // be cleared when no bytes are left, causing flush() to hang - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - *_udr = c; -#ifdef MPCM0 - *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0); -#else - *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0))); -#endif - } +size_t HardwareSerial::write(uint8_t c) { + loop_until_bit_is_set(UCSR0A, UDRE0); + UDR0 = c; return 1; - } - tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE; - - // If the output buffer is full, there's nothing for it other than to - // wait for the interrupt handler to empty it a bit - while (i == _tx_buffer_tail) { - if (bit_is_clear(SREG, SREG_I)) { - // Interrupts are disabled, so we'll have to poll the data - // register empty flag ourselves. If it is set, pretend an - // interrupt has happened and call the handler to free up - // space for us. - if(bit_is_set(*_ucsra, UDRE0)) - _tx_udr_empty_irq(); - } else { - // nop, the interrupt handler will free up space for us - } - } - - _tx_buffer[_tx_buffer_head] = c; - - // make atomic to prevent execution of ISR between setting the - // head pointer and setting the interrupt flag resulting in buffer - // retransmission - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - _tx_buffer_head = i; - sbi(*_ucsrb, UDRIE0); - } - - return 1; } - -#endif // whole file diff --git a/GyverCore/cores/arduino/HardwareSerial.h b/GyverCore/cores/arduino/HardwareSerial.h index 17000c2..002bce2 100644 --- a/GyverCore/cores/arduino/HardwareSerial.h +++ b/GyverCore/cores/arduino/HardwareSerial.h @@ -28,41 +28,15 @@ #include "Stream.h" -// Define constants and variables for buffering incoming serial data. We're -// using a ring buffer (I think), in which head is the index of the location -// to which to write the next incoming character and tail is the index of the -// location from which to read. -// NOTE: a "power of 2" buffer size is reccomended to dramatically -// optimize all the modulo operations for ring buffers. -// WARNING: When buffer sizes are increased to > 256, the buffer index -// variables are automatically increased in size, but the extra -// atomicity guards needed for that are not implemented. This will -// often work, but occasionally a race condition can occur that makes -// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405 #if !defined(SERIAL_TX_BUFFER_SIZE) -#if ((RAMEND - RAMSTART) < 1023) -#define SERIAL_TX_BUFFER_SIZE 16 -#else #define SERIAL_TX_BUFFER_SIZE 64 #endif -#endif #if !defined(SERIAL_RX_BUFFER_SIZE) -#if ((RAMEND - RAMSTART) < 1023) -#define SERIAL_RX_BUFFER_SIZE 16 -#else #define SERIAL_RX_BUFFER_SIZE 64 #endif -#endif -#if (SERIAL_TX_BUFFER_SIZE>256) -typedef uint16_t tx_buffer_index_t; -#else + typedef uint8_t tx_buffer_index_t; -#endif -#if (SERIAL_RX_BUFFER_SIZE>256) -typedef uint16_t rx_buffer_index_t; -#else typedef uint8_t rx_buffer_index_t; -#endif // Define config for Serial.begin(baud, config); #define SERIAL_5N1 0x00 @@ -90,42 +64,15 @@ typedef uint8_t rx_buffer_index_t; #define SERIAL_7O2 0x3C #define SERIAL_8O2 0x3E -class HardwareSerial : public Stream -{ - protected: - volatile uint8_t * const _ubrrh; - volatile uint8_t * const _ubrrl; - volatile uint8_t * const _ucsra; - volatile uint8_t * const _ucsrb; - volatile uint8_t * const _ucsrc; - volatile uint8_t * const _udr; - // Has any byte been written to the UART since begin() - bool _written; - - volatile rx_buffer_index_t _rx_buffer_head; - volatile rx_buffer_index_t _rx_buffer_tail; - volatile tx_buffer_index_t _tx_buffer_head; - volatile tx_buffer_index_t _tx_buffer_tail; - - // Don't put any members after these buffers, since only the first - // 32 bytes of this struct can be accessed quickly using the ldd - // instruction. - unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; - unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; - +class HardwareSerial : public Stream { public: - inline HardwareSerial( - volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, - volatile uint8_t *ucsra, volatile uint8_t *ucsrb, - volatile uint8_t *ucsrc, volatile uint8_t *udr); - void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } - void begin(unsigned long, uint8_t); + void begin(unsigned long baud = 9600, uint8_t config = SERIAL_8N1); void end(); virtual int available(void); virtual int peek(void); virtual int read(void); - virtual int availableForWrite(void); - virtual void flush(void); + virtual int availableForWrite(void) { return 1; } + virtual void flush(void) {} virtual size_t write(uint8_t); inline size_t write(unsigned long n) { return write((uint8_t)n); } inline size_t write(long n) { return write((uint8_t)n); } @@ -139,23 +86,7 @@ class HardwareSerial : public Stream void _tx_udr_empty_irq(void); }; -#if defined(UBRRH) || defined(UBRR0H) - extern HardwareSerial Serial; - #define HAVE_HWSERIAL0 -#endif -#if defined(UBRR1H) - extern HardwareSerial Serial1; - #define HAVE_HWSERIAL1 -#endif -#if defined(UBRR2H) - extern HardwareSerial Serial2; - #define HAVE_HWSERIAL2 -#endif -#if defined(UBRR3H) - extern HardwareSerial Serial3; - #define HAVE_HWSERIAL3 -#endif - +extern HardwareSerial Serial; extern void serialEventRun(void) __attribute__((weak)); #endif diff --git a/GyverCore/cores/arduino/HardwareSerial0.cpp b/GyverCore/cores/arduino/HardwareSerial0.cpp deleted file mode 100644 index 0d2882f..0000000 --- a/GyverCore/cores/arduino/HardwareSerial0.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - HardwareSerial0.cpp - Hardware serial library for Wiring - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 23 November 2006 by David A. Mellis - Modified 28 September 2010 by Mark Sproul - Modified 14 August 2012 by Alarus - Modified 3 December 2013 by Matthijs Kooijman -*/ - -#include "Arduino.h" -#include "HardwareSerial.h" -#include "HardwareSerial_private.h" - -// Each HardwareSerial is defined in its own file, sine the linker pulls -// in the entire file when any element inside is used. --gc-sections can -// additionally cause unused symbols to be dropped, but ISRs have the -// "used" attribute so are never dropped and they keep the -// HardwareSerial instance in as well. Putting each instance in its own -// file prevents the linker from pulling in any unused instances in the -// first place. - -#if defined(HAVE_HWSERIAL0) - -#if defined(USART_RX_vect) - ISR(USART_RX_vect) -#elif defined(USART0_RX_vect) - ISR(USART0_RX_vect) -#elif defined(USART_RXC_vect) - ISR(USART_RXC_vect) // ATmega8 -#else - #error "Don't know what the Data Received vector is called for Serial" -#endif - { - Serial._rx_complete_irq(); - } - -#if defined(UART0_UDRE_vect) -ISR(UART0_UDRE_vect) -#elif defined(UART_UDRE_vect) -ISR(UART_UDRE_vect) -#elif defined(USART0_UDRE_vect) -ISR(USART0_UDRE_vect) -#elif defined(USART_UDRE_vect) -ISR(USART_UDRE_vect) -#else - #error "Don't know what the Data Register Empty vector is called for Serial" -#endif -{ - Serial._tx_udr_empty_irq(); - -} - -#if defined(UBRRH) && defined(UBRRL) - HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR); -#else - HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0); -#endif - -// Function that can be weakly referenced by serialEventRun to prevent -// pulling in this file if it's not otherwise used. -bool Serial0_available() { - return Serial.available(); -} - -#endif // HAVE_HWSERIAL0 diff --git a/GyverCore/cores/arduino/HardwareSerial_private.h b/GyverCore/cores/arduino/HardwareSerial_private.h deleted file mode 100644 index b8cf7e8..0000000 --- a/GyverCore/cores/arduino/HardwareSerial_private.h +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include "Arduino.h" - -// this next line disables the entire HardwareSerial.cpp, -// this is so I can support Attiny series and any other chip without a uart -#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) - -// Ensure that the various bit positions we use are available with a 0 -// postfix, so we can always use the values for UART0 for all UARTs. The -// alternative, passing the various values for each UART to the -// HardwareSerial constructor also works, but makes the code bigger and -// slower. -#if !defined(TXC0) -#if defined(TXC) -// Some chips like ATmega8 don't have UPE, only PE. The other bits are -// named as expected. -#if !defined(UPE) && defined(PE) -#define UPE PE -#endif -// On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc. -#define TXC0 TXC -#define RXEN0 RXEN -#define TXEN0 TXEN -#define RXCIE0 RXCIE -#define UDRIE0 UDRIE -#define U2X0 U2X -#define UPE0 UPE -#define UDRE0 UDRE -#elif defined(TXC1) -// Some devices have uart1 but no uart0 -#define TXC0 TXC1 -#define RXEN0 RXEN1 -#define TXEN0 TXEN1 -#define RXCIE0 RXCIE1 -#define UDRIE0 UDRIE1 -#define U2X0 U2X1 -#define UPE0 UPE1 -#define UDRE0 UDRE1 -#else -#error No UART found in HardwareSerial.cpp -#endif -#endif // !defined TXC0 - -// Check at compiletime that it is really ok to use the bit positions of -// UART0 for the other UARTs as well, in case these values ever get -// changed for future hardware. -#if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \ - UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \ - UDRE1 != UDRE0) -#error "Not all bit positions for UART1 are the same as for UART0" -#endif -#if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \ - UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \ - UDRE2 != UDRE0) -#error "Not all bit positions for UART2 are the same as for UART0" -#endif -#if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \ - UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \ - UDRE3 != UDRE0) -#error "Not all bit positions for UART3 are the same as for UART0" -#endif - -// Constructors //////////////////////////////////////////////////////////////// - -HardwareSerial::HardwareSerial( - volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, - volatile uint8_t *ucsra, volatile uint8_t *ucsrb, - volatile uint8_t *ucsrc, volatile uint8_t *udr) : - _ubrrh(ubrrh), _ubrrl(ubrrl), - _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc), - _udr(udr), - _rx_buffer_head(0), _rx_buffer_tail(0), - _tx_buffer_head(0), _tx_buffer_tail(0) -{ -} - -// Actual interrupt handlers ////////////////////////////////////////////////////////////// - -void HardwareSerial::_rx_complete_irq(void) -{ - if (bit_is_clear(*_ucsra, UPE0)) { - // No Parity error, read byte and store it in the buffer if there is - // room - unsigned char c = *_udr; - rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; - - // if we should be storing the received character into the location - // just before the tail (meaning that the head would advance to the - // current location of the tail), we're about to overflow the buffer - // and so we don't write the character or advance the head. - if (i != _rx_buffer_tail) { - _rx_buffer[_rx_buffer_head] = c; - _rx_buffer_head = i; - } - } else { - // Parity error, read byte but discard it - *_udr; - }; -} - -#endif // whole file diff --git a/GyverCore/cores/arduino/uart.cpp b/GyverCore/cores/arduino/uart.cpp index 4293621..590cf22 100644 --- a/GyverCore/cores/arduino/uart.cpp +++ b/GyverCore/cores/arduino/uart.cpp @@ -1,58 +1,6 @@ -#include "uart.h" +#include "Arduino.h" /* Реализация облегченного Serial от AlexGyver & Egor 'Nich1con' Zaharov*/ -// ===== INIT ===== -void uartBegin(uint32_t baudrate){ // инициализация uart - uint16_t speed = ((F_CPU / 8) / baudrate) - 1; // расчет baudrate - UBRR0H = highByte(speed); // установка baudrate - UBRR0L = lowByte(speed); - UCSR0A = (1 << U2X0); // вкл удвоенную скорость - UCSR0B = ((1< -void uartBegin(void); -void uartBegin(uint32_t baudrate); -void uartEnd(); - -boolean uartAvailable(); -char uartRead(); -char uartPeek(); -void uartClear(); +#define uartBegin Serial.begin +#define uartEnd Serial.end +#define uartAvailable Serial.available +#define uartRead Serial.read +#define uartPeek Serial.peek +#define uartWrite Serial.write +#define uartClear() do{}while(0) void uartSetTimeout(int timeout); int32_t uartParseInt(); @@ -21,7 +20,6 @@ float uartParseFloat(); String uartReadString(); boolean uartParsePacket(int *intArray); -void uartWrite(byte data); void uartPrintln(void); void uartPrint(int8_t data);