aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino
diff options
context:
space:
mode:
Diffstat (limited to 'cores/arduino')
-rw-r--r--cores/arduino/HardwareSerial.cpp105
-rw-r--r--cores/arduino/HardwareSerial0.cpp54
-rw-r--r--cores/arduino/HardwareSerial1.cpp54
-rw-r--r--cores/arduino/HardwareSerial2.cpp54
-rw-r--r--cores/arduino/HardwareSerial3.cpp54
5 files changed, 229 insertions, 92 deletions
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index 4318a1e..d7f1fca 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -84,105 +84,46 @@
#error "Not all bit positions for UART3 are the same as for UART0"
#endif
+// 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));
- void serialEvent() {}
-#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 the first UART"
-#endif
- {
- Serial._rx_complete_irq();
- }
+ bool Serial0_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL1)
void serialEvent1() __attribute__((weak));
- void serialEvent1() {}
- ISR(USART1_RX_vect)
- {
- Serial1._rx_complete_irq();
- }
+ bool Serial1_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL2)
void serialEvent2() __attribute__((weak));
- void serialEvent2() {}
- ISR(USART2_RX_vect)
- {
- Serial2._rx_complete_irq();
- }
+ bool Serial2_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL3)
void serialEvent3() __attribute__((weak));
- void serialEvent3() {}
- ISR(USART3_RX_vect)
- {
- Serial3._rx_complete_irq();
- }
+ bool Serial3_available() __attribute__((weak));
#endif
void serialEventRun(void)
{
#if defined(HAVE_HWSERIAL0)
- if (Serial.available()) serialEvent();
+ if (Serial0_available && serialEvent && Serial0_available()) serialEvent();
#endif
#if defined(HAVE_HWSERIAL1)
- if (Serial1.available()) serialEvent1();
+ if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1();
#endif
#if defined(HAVE_HWSERIAL2)
- if (Serial2.available()) serialEvent2();
+ if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2();
#endif
#if defined(HAVE_HWSERIAL3)
- if (Serial3.available()) serialEvent3();
-#endif
-}
-
-
-#if defined(HAVE_HWSERIAL0)
-#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 the first UART"
-#endif
-{
- Serial._tx_udr_empty_irq();
-}
+ if (Serial3_available && serialEvent2 && Serial3_available()) serialEvent3();
#endif
-
-#if defined(HAVE_HWSERIAL1)
-ISR(USART1_UDRE_vect)
-{
- Serial1._tx_udr_empty_irq();
}
-#endif
-
-#if defined(HAVE_HWSERIAL2)
-ISR(USART2_UDRE_vect)
-{
- Serial2._tx_udr_empty_irq();
-}
-#endif
-
-#if defined(HAVE_HWSERIAL3)
-ISR(USART3_UDRE_vect)
-{
- Serial3._tx_udr_empty_irq();
-}
-#endif
-
// Actual interrupt handlers //////////////////////////////////////////////////////////////
@@ -371,25 +312,5 @@ size_t HardwareSerial::write(uint8_t c)
return 1;
}
-// Preinstantiate Objects //////////////////////////////////////////////////////
-
-#if defined(HAVE_HWSERIAL0)
-#if defined(UBRRH) && defined(UBRRL)
- HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
-#else
- HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
-#endif
-#endif
-
-#if defined(HAVE_HWSERIAL1)
- HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1);
-#endif
-#if defined(HAVE_HWSERIAL2)
- HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2);
-#endif
-#if defined(HAVE_HWSERIAL3)
- HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3);
-#endif
#endif // whole file
-
diff --git a/cores/arduino/HardwareSerial0.cpp b/cores/arduino/HardwareSerial0.cpp
new file mode 100644
index 0000000..dd4d806
--- /dev/null
+++ b/cores/arduino/HardwareSerial0.cpp
@@ -0,0 +1,54 @@
+#include "Arduino.h"
+#include "HardwareSerial.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 the first UART"
+#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 the first UART"
+#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/cores/arduino/HardwareSerial1.cpp b/cores/arduino/HardwareSerial1.cpp
new file mode 100644
index 0000000..c04263e
--- /dev/null
+++ b/cores/arduino/HardwareSerial1.cpp
@@ -0,0 +1,54 @@
+#include "Arduino.h"
+#include "HardwareSerial.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_HWSERIAL1)
+
+#if defined(USART_RX_vect)
+ ISR(USART_RX_vect)
+#elif defined(USART1_RX_vect)
+ ISR(USART1_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 the first UART"
+#endif
+ {
+ Serial1._rx_complete_irq();
+ }
+
+#if defined(UART1_UDRE_vect)
+ISR(UART1_UDRE_vect)
+#elif defined(UART_UDRE_vect)
+ISR(UART_UDRE_vect)
+#elif defined(USART1_UDRE_vect)
+ISR(USART1_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 the first UART"
+#endif
+{
+ Serial1._tx_udr_empty_irq();
+}
+
+#if defined(UBRRH) && defined(UBRRL)
+ HardwareSerial Serial1(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
+#else
+ HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1);
+#endif
+
+// Function that can be weakly referenced by serialEventRun to prevent
+// pulling in this file if it's not otherwise used.
+bool Serial1_available() {
+ return Serial1.available();
+}
+
+#endif // HAVE_HWSERIAL1
diff --git a/cores/arduino/HardwareSerial2.cpp b/cores/arduino/HardwareSerial2.cpp
new file mode 100644
index 0000000..2c448f9
--- /dev/null
+++ b/cores/arduino/HardwareSerial2.cpp
@@ -0,0 +1,54 @@
+#include "Arduino.h"
+#include "HardwareSerial.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_HWSERIAL2)
+
+#if defined(USART_RX_vect)
+ ISR(USART_RX_vect)
+#elif defined(USART2_RX_vect)
+ ISR(USART2_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 the first UART"
+#endif
+ {
+ Serial2._rx_complete_irq();
+ }
+
+#if defined(UART2_UDRE_vect)
+ISR(UART2_UDRE_vect)
+#elif defined(UART_UDRE_vect)
+ISR(UART_UDRE_vect)
+#elif defined(USART2_UDRE_vect)
+ISR(USART2_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 the first UART"
+#endif
+{
+ Serial2._tx_udr_empty_irq();
+}
+
+#if defined(UBRRH) && defined(UBRRL)
+ HardwareSerial Serial2(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
+#else
+ HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2);
+#endif
+
+// Function that can be weakly referenced by serialEventRun to prevent
+// pulling in this file if it's not otherwise used.
+bool Serial2_available() {
+ return Serial2.available();
+}
+
+#endif // HAVE_HWSERIAL2
diff --git a/cores/arduino/HardwareSerial3.cpp b/cores/arduino/HardwareSerial3.cpp
new file mode 100644
index 0000000..012839d
--- /dev/null
+++ b/cores/arduino/HardwareSerial3.cpp
@@ -0,0 +1,54 @@
+#include "Arduino.h"
+#include "HardwareSerial.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_HWSERIAL3)
+
+#if defined(USART_RX_vect)
+ ISR(USART_RX_vect)
+#elif defined(USART3_RX_vect)
+ ISR(USART3_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 the first UART"
+#endif
+ {
+ Serial3._rx_complete_irq();
+ }
+
+#if defined(UART3_UDRE_vect)
+ISR(UART3_UDRE_vect)
+#elif defined(UART_UDRE_vect)
+ISR(UART_UDRE_vect)
+#elif defined(USART3_UDRE_vect)
+ISR(USART3_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 the first UART"
+#endif
+{
+ Serial3._tx_udr_empty_irq();
+}
+
+#if defined(UBRRH) && defined(UBRRL)
+ HardwareSerial Serial3(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
+#else
+ HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3);
+#endif
+
+// Function that can be weakly referenced by serialEventRun to prevent
+// pulling in this file if it's not otherwise used.
+bool Serial3_available() {
+ return Serial3.available();
+}
+
+#endif // HAVE_HWSERIAL3