aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino
diff options
context:
space:
mode:
Diffstat (limited to 'cores/arduino')
-rw-r--r--cores/arduino/HardwareSerial.cpp10
-rw-r--r--cores/arduino/HardwareSerial.h21
-rwxr-xr-xcores/arduino/Print.cpp5
-rwxr-xr-xcores/arduino/Print.h5
-rw-r--r--cores/arduino/USBAPI.h1
-rw-r--r--cores/arduino/WInterrupts.c36
-rw-r--r--cores/arduino/WString.h2
-rwxr-xr-xcores/arduino/wiring_private.h2
8 files changed, 72 insertions, 10 deletions
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index 1ae90c3..e512421 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -350,6 +350,8 @@ try_again:
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
+ transmitting = false;
+
sbi(*_ucsrb, _rxen);
sbi(*_ucsrb, _txen);
sbi(*_ucsrb, _rxcie);
@@ -446,8 +448,9 @@ int HardwareSerial::read(void)
void HardwareSerial::flush()
{
- while (_tx_buffer->head != _tx_buffer->tail)
- ;
+ // UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY && SENT
+ while (transmitting && ! (*_ucsra & _BV(TXC0)));
+ transmitting = false;
}
size_t HardwareSerial::write(uint8_t c)
@@ -464,6 +467,9 @@ size_t HardwareSerial::write(uint8_t c)
_tx_buffer->head = i;
sbi(*_ucsrb, _udrie);
+ // clear the TXC bit -- "can be cleared by writing a one to its bit location"
+ transmitting = true;
+ sbi(*_ucsra, TXC0);
return 1;
}
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index 07445a0..8f00d15 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -45,6 +45,7 @@ class HardwareSerial : public Stream
uint8_t _rxcie;
uint8_t _udrie;
uint8_t _u2x;
+ bool transmitting;
public:
HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
@@ -59,6 +60,10 @@ class HardwareSerial : public Stream
virtual int read(void);
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); }
+ inline size_t write(unsigned int n) { return write((uint8_t)n); }
+ inline size_t write(int n) { return write((uint8_t)n); }
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool();
};
@@ -129,6 +134,22 @@ class HardwareSerial : public Stream
extern HardwareSerial Serial3;
#endif
+/*
+ * on ATmega8, the uart and its bits are not numbered, so there is no "TXC0"
+ * definition. It is slightly cleaner to define this here instead of having
+ * conditional code in the cpp module.
+ */
+#if !defined(TXC0)
+#if defined(TXC)
+#define TXC0 TXC
+#elif defined(TXC1)
+// Some devices have uart1 but no uart0
+#define TXC0 TXC1
+#else
+#error TXC0 not definable in HardwareSerial.h
+#endif
+#endif
+
extern void serialEventRun(void) __attribute__((weak));
#endif
diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp
index e541a6c..53961ec 100755
--- a/cores/arduino/Print.cpp
+++ b/cores/arduino/Print.cpp
@@ -226,6 +226,11 @@ size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
+ if (isnan(number)) return print("nan");
+ if (isinf(number)) return print("inf");
+ if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
+ if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
+
// Handle negative numbers
if (number < 0.0)
{
diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h
index 1af6b72..dc76150 100755
--- a/cores/arduino/Print.h
+++ b/cores/arduino/Print.h
@@ -46,7 +46,10 @@ class Print
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0;
- size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
+ size_t write(const char *str) {
+ if (str == NULL) return 0;
+ return write((const uint8_t *)str, strlen(str));
+ }
virtual size_t write(const uint8_t *buffer, size_t size);
size_t print(const __FlashStringHelper *);
diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index d5abdb6..eb2e593 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -39,6 +39,7 @@ public:
virtual int read(void);
virtual void flush(void);
virtual size_t write(uint8_t);
+ using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool();
};
extern Serial_ Serial;
diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c
index 8f3ec84..62efc9c 100644
--- a/cores/arduino/WInterrupts.c
+++ b/cores/arduino/WInterrupts.c
@@ -59,6 +59,14 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
EIMSK |= (1<<INT1);
break;
+ case 2:
+ EICRA = (EICRA & ~((1<<ISC20) | (1<<ISC21))) | (mode << ISC20);
+ EIMSK |= (1<<INT2);
+ break;
+ case 3:
+ EICRA = (EICRA & ~((1<<ISC30) | (1<<ISC31))) | (mode << ISC30);
+ EIMSK |= (1<<INT3);
+ break;
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
case 2:
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
@@ -147,12 +155,18 @@ void detachInterrupt(uint8_t interruptNum) {
// ATmega8. There, INT0 is 6 and INT1 is 7.)
switch (interruptNum) {
#if defined(__AVR_ATmega32U4__)
- case 0:
- EIMSK &= ~(1<<INT0);
- break;
- case 1:
- EIMSK &= ~(1<<INT1);
- break;
+ case 0:
+ EIMSK &= ~(1<<INT0);
+ break;
+ case 1:
+ EIMSK &= ~(1<<INT1);
+ break;
+ case 2:
+ EIMSK &= ~(1<<INT2);
+ break;
+ case 3:
+ EIMSK &= ~(1<<INT3);
+ break;
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
case 2:
EIMSK &= ~(1 << INT0);
@@ -226,6 +240,16 @@ SIGNAL(INT1_vect) {
intFunc[EXTERNAL_INT_1]();
}
+SIGNAL(INT2_vect) {
+ if(intFunc[EXTERNAL_INT_2])
+ intFunc[EXTERNAL_INT_2]();
+}
+
+SIGNAL(INT3_vect) {
+ if(intFunc[EXTERNAL_INT_3])
+ intFunc[EXTERNAL_INT_3]();
+}
+
#elif defined(EICRA) && defined(EICRB)
SIGNAL(INT0_vect) {
diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h
index d76d2a3..947325e 100644
--- a/cores/arduino/WString.h
+++ b/cores/arduino/WString.h
@@ -35,7 +35,7 @@
// -std=c++0x
class __FlashStringHelper;
-#define F(string_literal) (reinterpret_cast<__FlashStringHelper *>(PSTR(string_literal)))
+#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
diff --git a/cores/arduino/wiring_private.h b/cores/arduino/wiring_private.h
index f0ceb0c..026ce1a 100755
--- a/cores/arduino/wiring_private.h
+++ b/cores/arduino/wiring_private.h
@@ -56,6 +56,8 @@ extern "C"{
#define EXTERNAL_NUM_INTERRUPTS 8
#elif defined(__AVR_ATmega1284P__)
#define EXTERNAL_NUM_INTERRUPTS 3
+#elif defined(__AVR_ATmega32U4__)
+#define EXTERNAL_NUM_INTERRUPTS 4
#else
#define EXTERNAL_NUM_INTERRUPTS 2
#endif