From c58fcf5554827113680ee16559c36ed21e0ec0e0 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sun, 11 Dec 2011 19:56:50 -0500 Subject: fixed TIMER4 use on Leonardo ATMEGA32U4 has major differences in TIMER4 registers compared to ATMEGA1280 and 2560. turnOffPWM, analogWrite, and initialize routines had wrong registers, bit names, etc. --- cores/arduino/wiring.c | 11 ++++++++++- cores/arduino/wiring_analog.c | 24 ++++++++++++++++-------- cores/arduino/wiring_digital.c | 22 +++++++++++++++++++--- 3 files changed, 45 insertions(+), 12 deletions(-) mode change 100755 => 100644 cores/arduino/wiring.c mode change 100755 => 100644 cores/arduino/wiring_digital.c (limited to 'cores') diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c old mode 100755 new mode 100644 index e7f7cde..9c264d0 --- a/cores/arduino/wiring.c +++ b/cores/arduino/wiring.c @@ -278,12 +278,21 @@ void init() sbi(TCCR3B, CS30); sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode #endif - + +#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ + sbi(TCCR4A, COM4A1); // clear channel A on output compare match + sbi(TCCR4C, COM4D1); // clear channel D on output compare match + sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 + sbi(TCCR4B, CS41); + sbi(TCCR4B, CS40); + sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode +#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ #if defined(TCCR4B) && defined(CS41) && defined(WGM40) sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 sbi(TCCR4B, CS40); sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode #endif +#endif /* end timer4 block for ATMEGA1280/2560 and similar */ #if defined(TCCR5B) && defined(CS51) && defined(WGM50) sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 902b153..db6cb7e 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -204,14 +204,18 @@ void analogWrite(uint8_t pin, int val) break; #endif - #if defined(TCCR4A) && defined(COM4A1) + #if defined(TCCR4A) case TIMER4A: - // connect pwm to pin on timer 4, channel A + //connect pwm to pin on timer 4, channel A + #if defined(PWM4A) /* ATMEGA32U4 and related */ + sbi(TCCR4A, PWM4A); + #elif defined(COM4A1) /* ATMEGA1280/2560 and related */ sbi(TCCR4A, COM4A1); - OCR4A = val; // set pwm duty + #endif + OCR4A = val; // set pwm duty break; #endif - + #if defined(TCCR4A) && defined(COM4B1) case TIMER4B: // connect pwm to pin on timer 4, channel B @@ -228,14 +232,17 @@ void analogWrite(uint8_t pin, int val) break; #endif - #if defined(TCCR4A) && defined(COM4D1) - case TIMER4D: + #if defined(TCCR4C) + case TIMER4D: // connect pwm to pin on timer 4, channel D - sbi(TCCR4A, COM4D1); - OCR4D = val; // set pwm duty + #if defined(PWM4D) /* ATMEGA32U4 and related */ + sbi(TCCR4C, PWM4D); + #endif + OCR4D = val; // set pwm duty break; #endif + #if defined(TCCR5A) && defined(COM5A1) case TIMER5A: // connect pwm to pin on timer 5, channel A @@ -270,3 +277,4 @@ void analogWrite(uint8_t pin, int val) } } } + diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c old mode 100755 new mode 100644 index 97ef134..112defc --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -105,15 +105,31 @@ static void turnOffPWM(uint8_t timer) case TIMER3C: cbi(TCCR3A, COM3C1); break; #endif - #if defined(TCCR4A) && defined(COM4A1) - case TIMER4A: cbi(TCCR4A, COM4A1); break; - #endif + #if defined(TCCR4A) + case TIMER4A: + #if defined(PWM4A) + cbi(TCCR4A, PWM4A); + #elif defined(COM4A1) + cbi(TCCR4A, COM4A1); + #endif + break; + #endif + #if defined(TCCR4A) && defined(COM4B1) case TIMER4B: cbi(TCCR4A, COM4B1); break; #endif #if defined(TCCR4A) && defined(COM4C1) case TIMER4C: cbi(TCCR4A, COM4C1); break; #endif + + #if defined(TCCR4C) + case TIMER4D: + #if defined(PWM4D) + cbi(TCCR4C, PWM4D); + #endif + break; + #endif + #if defined(TCCR5A) case TIMER5A: cbi(TCCR5A, COM5A1); break; case TIMER5B: cbi(TCCR5A, COM5B1); break; -- cgit v1.2.3-18-g5258 From 177641003c53844ad73584553a9d44f2da4648e2 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sun, 18 Dec 2011 14:18:38 -0500 Subject: fixed digitalWrite on timer 4 pins (D6 and D13) --- cores/arduino/wiring.c | 4 ++++ cores/arduino/wiring_analog.c | 8 +------- cores/arduino/wiring_digital.c | 24 ++++++------------------ 3 files changed, 11 insertions(+), 25 deletions(-) (limited to 'cores') diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c index 9c264d0..fb447eb 100644 --- a/cores/arduino/wiring.c +++ b/cores/arduino/wiring.c @@ -281,11 +281,15 @@ void init() #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ sbi(TCCR4A, COM4A1); // clear channel A on output compare match + cbi(TCCR4A, COM4A0); sbi(TCCR4C, COM4D1); // clear channel D on output compare match + cbi(TCCR4C, COM4D0); sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 sbi(TCCR4B, CS41); sbi(TCCR4B, CS40); sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode + sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A + sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ #if defined(TCCR4B) && defined(CS41) && defined(WGM40) sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index db6cb7e..8a6fef3 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -207,11 +207,7 @@ void analogWrite(uint8_t pin, int val) #if defined(TCCR4A) case TIMER4A: //connect pwm to pin on timer 4, channel A - #if defined(PWM4A) /* ATMEGA32U4 and related */ - sbi(TCCR4A, PWM4A); - #elif defined(COM4A1) /* ATMEGA1280/2560 and related */ sbi(TCCR4A, COM4A1); - #endif OCR4A = val; // set pwm duty break; #endif @@ -235,9 +231,7 @@ void analogWrite(uint8_t pin, int val) #if defined(TCCR4C) case TIMER4D: // connect pwm to pin on timer 4, channel D - #if defined(PWM4D) /* ATMEGA32U4 and related */ - sbi(TCCR4C, PWM4D); - #endif + sbi(TCCR4C, COM4D1); OCR4D = val; // set pwm duty break; #endif diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index 112defc..75f850e 100644 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -105,29 +105,17 @@ static void turnOffPWM(uint8_t timer) case TIMER3C: cbi(TCCR3A, COM3C1); break; #endif - #if defined(TCCR4A) - case TIMER4A: - #if defined(PWM4A) - cbi(TCCR4A, PWM4A); - #elif defined(COM4A1) - cbi(TCCR4A, COM4A1); - #endif - break; - #endif - + #if defined(TCCR4A) && defined(COM4A1) + case TIMER4A: cbi(TCCR4A, COM4A1); break; + #endif #if defined(TCCR4A) && defined(COM4B1) case TIMER4B: cbi(TCCR4A, COM4B1); break; #endif #if defined(TCCR4A) && defined(COM4C1) case TIMER4C: cbi(TCCR4A, COM4C1); break; - #endif - - #if defined(TCCR4C) - case TIMER4D: - #if defined(PWM4D) - cbi(TCCR4C, PWM4D); - #endif - break; + #endif + #if defined(TCCR4C) && defined(COM4D1) + case TIMER4D: cbi(TCCR4C, COM4D1); break; #endif #if defined(TCCR5A) -- cgit v1.2.3-18-g5258 From 58fc0d17cc2d7c5dfb4ce268b7e43d35eebac342 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sun, 18 Dec 2011 17:52:35 -0500 Subject: added asynchronous buffering of received CDC characters This fixes the issue Federico reported where bytes written by host but not read by sketch would cause serial connection to lock up. Ring buffer implementation is based on HardwareSerial.cpp. Adds public accept() method to CDC. --- cores/arduino/CDC.cpp | 67 ++++++++++++++++++++++++++++++++++++----------- cores/arduino/USBAPI.h | 3 +++ cores/arduino/USBCore.cpp | 2 ++ 3 files changed, 56 insertions(+), 16 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 14a0eae..8605ce3 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -30,6 +30,25 @@ void Reboot() asm volatile("jmp 0x7800"); // jump to bootloader - DiskLoader takes up last 2 kB } +// 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. +#if (RAMEND < 1000) +#define SERIAL_BUFFER_SIZE 16 +#else +#define SERIAL_BUFFER_SIZE 64 +#endif + +struct ring_buffer +{ + unsigned char buffer[SERIAL_BUFFER_SIZE]; + volatile int head; + volatile int tail; +}; + +ring_buffer cdc_rx_buffer = { { 0 }, 0, 0}; + typedef struct { u32 dwDTERate; @@ -111,33 +130,49 @@ void Serial_::end(void) { } +void Serial_::accept(void) +{ + ring_buffer *buffer = &cdc_rx_buffer; + int c = USB_Recv(CDC_RX); + int i = (unsigned int)(buffer->head+1) % SERIAL_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 != buffer->tail) { + buffer->buffer[buffer->head] = c; + buffer->head = i; + } +} + int Serial_::available(void) { - u8 avail = USB_Available(CDC_RX); - if (_serialPeek != -1) - avail++; - return avail; + ring_buffer *buffer = &cdc_rx_buffer; + return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE; } -// peek is nasty int Serial_::peek(void) { - if (_serialPeek == -1) - _serialPeek = read(); - return _serialPeek; + ring_buffer *buffer = &cdc_rx_buffer; + if (buffer->head == buffer->tail) { + return -1; + } else { + return buffer->buffer[buffer->tail]; + } } int Serial_::read(void) { - int c; - if (_serialPeek != -1) - { - c = _serialPeek; - _serialPeek = -1; + ring_buffer *buffer = &cdc_rx_buffer; + // if the head isn't ahead of the tail, we don't have any characters + if (buffer->head == buffer->tail) { + return -1; } else { - c = USB_Recv(CDC_RX); - } - return c; + unsigned char c = buffer->buffer[buffer->tail]; + buffer->tail = (unsigned int)(buffer->tail + 1) % SERIAL_BUFFER_SIZE; + return c; + } } void Serial_::flush(void) diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 26a2032..1772c3c 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -27,11 +27,14 @@ extern USB_ USB; class Serial_ : public Stream { +private: + ring_buffer *_cdc_rx_buffer; public: void begin(uint16_t baud_count); void end(void); virtual int available(void); + virtual void accept(void); virtual int peek(void); virtual int read(void); virtual void flush(void); diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 398bc73..7924078 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -599,6 +599,8 @@ ISR(USB_GEN_vect) { #ifdef CDC_ENABLED USB_Flush(CDC_TX); // Send a tx frame if found + while (USB_Available(CDC_RX)) // Handle received bytes (if any) + Serial.accept(); #endif // check whether the one-shot period has elapsed. if so, turn off the LED -- cgit v1.2.3-18-g5258 From 6dc00061df81b4750208996bb7dd0ec76f8f901f Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 19 Dec 2011 15:40:12 -0500 Subject: fixed attachInterrupt() on Leonardo had to define a separate block for the 32U4 since it looks like a Mega-series board based on a simple register trick. Only two useable HW interrupts though, compared to the Megas' 8, and numbering differs. --- cores/arduino/WInterrupts.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) mode change 100755 => 100644 cores/arduino/WInterrupts.c (limited to 'cores') diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c old mode 100755 new mode 100644 index 1449cfb..2ec72a5 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.c @@ -47,7 +47,19 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { // Enable the interrupt. switch (interruptNum) { -#if defined(EICRA) && defined(EICRB) && defined(EIMSK) +#if defined(__AVR_ATmega32U4__) + // I hate doing this, but the register assignment differs between the 1280/2560 + // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't + // even present on the 32U4 this is the only way to distinguish between them. + case 0: + EICRA = (EICRA & ~((1< Date: Tue, 20 Dec 2011 17:00:19 -0500 Subject: changed Keyboard write() method to type(). Made write() an alias for type() to allow subclassing by Stream. --- cores/arduino/HID.cpp | 5 +++++ cores/arduino/USBAPI.h | 1 + 2 files changed, 6 insertions(+) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index 8ed1566..d69522f 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -407,6 +407,11 @@ const uint8_t _asciimap[128] = uint8_t USBPutChar(uint8_t c); size_t Keyboard_::write(uint8_t c) +{ + type(c); +} + +size_t Keyboard_::type(uint8_t c) { // Keydown { diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 1772c3c..326fd6c 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -105,6 +105,7 @@ private: public: Keyboard_(); virtual size_t write(uint8_t); + virtual size_t type(uint8_t); }; extern Keyboard_ Keyboard; -- cgit v1.2.3-18-g5258 From e405a6eb6099a71959c664cab8ca8241634c6b91 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 20 Dec 2011 17:08:07 -0500 Subject: Revert "changed Keyboard write() method to type(). Made write() an alias for type() to allow subclassing by Stream." This reverts commit de1d5fc0cb82874c0dcb766c5fb27ab36c5cb32c. --- cores/arduino/HID.cpp | 5 ----- cores/arduino/USBAPI.h | 1 - 2 files changed, 6 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index d69522f..8ed1566 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -407,11 +407,6 @@ const uint8_t _asciimap[128] = uint8_t USBPutChar(uint8_t c); size_t Keyboard_::write(uint8_t c) -{ - type(c); -} - -size_t Keyboard_::type(uint8_t c) { // Keydown { diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 326fd6c..1772c3c 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -105,7 +105,6 @@ private: public: Keyboard_(); virtual size_t write(uint8_t); - virtual size_t type(uint8_t); }; extern Keyboard_ Keyboard; -- cgit v1.2.3-18-g5258 From 4e9fb924b2ea4c1373edc09408db2ac0c402e68c Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 20 Dec 2011 17:09:44 -0500 Subject: changed Keyboard write() method to type(). Made write() an alias for type() to allow subclassing by Stream. --- cores/arduino/HID.cpp | 3 ++- cores/arduino/USBAPI.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index 8ed1566..e6fb5f7 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -406,7 +406,8 @@ const uint8_t _asciimap[128] = }; uint8_t USBPutChar(uint8_t c); -size_t Keyboard_::write(uint8_t c) + +size_t Keyboard_::type(uint8_t c) { // Keydown { diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 1772c3c..6a0b989 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -104,7 +104,8 @@ private: void setKeyMap(KeyMap* keyMap); public: Keyboard_(); - virtual size_t write(uint8_t); + virtual size_t write(uint8_t c) {type(c);}; + virtual size_t type(uint8_t c); }; extern Keyboard_ Keyboard; -- cgit v1.2.3-18-g5258 From 3f429a9c61ae953d24f3d19ff1f6d9b332d29b9c Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Mon, 2 Jan 2012 12:38:23 -0500 Subject: Fixing static is not at beginning of declaration warnings (maniacbug). --- cores/arduino/WInterrupts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c index 1449cfb..4f035eb 100755 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.c @@ -32,7 +32,7 @@ #include "wiring_private.h" -volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; +static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; // volatile static voidFuncPtr twiIntFunc; void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { -- cgit v1.2.3-18-g5258 From 95b51c7728619fb9a718e15d13d99cb371905ad9 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Mon, 2 Jan 2012 12:57:23 -0500 Subject: Fixing warnings (unsigned comparisons to 0). (maniacbug) --- cores/arduino/WString.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp index 3e81331..c6839fc 100644 --- a/cores/arduino/WString.cpp +++ b/cores/arduino/WString.cpp @@ -500,7 +500,7 @@ int String::lastIndexOf( char theChar ) const int String::lastIndexOf(char ch, unsigned int fromIndex) const { - if (fromIndex >= len || fromIndex < 0) return -1; + if (fromIndex >= len) return -1; char tempchar = buffer[fromIndex + 1]; buffer[fromIndex + 1] = '\0'; char* temp = strrchr( buffer, ch ); @@ -516,7 +516,7 @@ int String::lastIndexOf(const String &s2) const int String::lastIndexOf(const String &s2, unsigned int fromIndex) const { - if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1; + if (s2.len == 0 || len == 0 || s2.len > len) return -1; if (fromIndex >= len) fromIndex = len - 1; int found = -1; for (char *p = buffer; p <= buffer + fromIndex; p++) { -- cgit v1.2.3-18-g5258 From 3b962be2730265dd27220b801fc9bceb92220977 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Mon, 2 Jan 2012 13:49:59 -0500 Subject: Fixing findUntil() problem with repeated initial characters. (Jeffery.zksun) http://code.google.com/p/arduino/issues/detail?id=768 --- cores/arduino/Stream.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'cores') diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp index 5fad8dd..3d5b905 100644 --- a/cores/arduino/Stream.cpp +++ b/cores/arduino/Stream.cpp @@ -99,25 +99,27 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t size_t index = 0; // maximum target string length is 64k bytes! size_t termIndex = 0; int c; - + if( *target == 0) - return true; // return true if target is a null string + return true; // return true if target is a null string while( (c = timedRead()) > 0){ + + if(c != target[index]) + index = 0; // reset index if any char does not match + if( c == target[index]){ - //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); + //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); if(++index >= targetLen){ // return true if all chars in the target match return true; } } - else{ - index = 0; // reset index if any char does not match - } + if(termLen > 0 && c == terminator[termIndex]){ - if(++termIndex >= termLen) - return false; // return false if terminate string found before target string + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string } else - termIndex = 0; + termIndex = 0; } return false; } -- cgit v1.2.3-18-g5258 From 6c00397e22021762851511a0a9b6f914db81deca Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Mon, 2 Jan 2012 14:20:28 -0500 Subject: Adding INPUT_PULLUP option pinMode(). (Paul Stoffregen). This also changes pinMode(pin, INPUT); to explicitly disable the pull-up resistor, even if it was previously set. http://code.google.com/p/arduino/issues/detail?id=246 --- cores/arduino/Arduino.h | 1 + cores/arduino/wiring_digital.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index bfec943..830c995 100755 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -20,6 +20,7 @@ extern "C"{ #define INPUT 0x0 #define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 #define true 0x1 #define false 0x0 diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index 97ef134..584a28a 100755 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -32,17 +32,25 @@ void pinMode(uint8_t pin, uint8_t mode) { uint8_t bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); - volatile uint8_t *reg; + volatile uint8_t *reg, *out; if (port == NOT_A_PIN) return; // JWS: can I let the optimizer do this? reg = portModeRegister(port); + out = portOutputRegister(port); if (mode == INPUT) { uint8_t oldSREG = SREG; cli(); *reg &= ~bit; + *out &= ~bit; + SREG = oldSREG; + } else if (mode == INPUT_PULLUP) { + uint8_t oldSREG = SREG; + cli(); + *reg &= ~bit; + *out |= bit; SREG = oldSREG; } else { uint8_t oldSREG = SREG; -- cgit v1.2.3-18-g5258 From 45d3b102956c74f837eb0297af45939ca46b09a0 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 24 Jan 2012 18:04:10 -0500 Subject: Caterina now cleanly hands off operation to the sketch had to remove TIMER1 operation from bootloader - was interfering with normal sketch operation --- cores/arduino/CDC.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 8605ce3..eb1b2c5 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -27,7 +27,10 @@ void Reboot() { USB.detach(); cli(); - asm volatile("jmp 0x7800"); // jump to bootloader - DiskLoader takes up last 2 kB + + // Reset the microcontroller to run the bootloader + wdt_enable(WDTO_250MS); + for (;;); } // Define constants and variables for buffering incoming serial data. We're -- cgit v1.2.3-18-g5258 From e1438efb3a6d538ae3fd0e2037ec2b112aa1c563 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 3 Feb 2012 17:24:29 -0500 Subject: Making head and tail unsigned to avoid division in serial ISR. http://code.google.com/p/arduino/issues/detail?id=776 --- cores/arduino/HardwareSerial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 1b1fa71..9985b78 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -46,8 +46,8 @@ struct ring_buffer { unsigned char buffer[SERIAL_BUFFER_SIZE]; - volatile int head; - volatile int tail; + volatile unsigned int head; + volatile unsigned int tail; }; #if defined(USBCON) -- cgit v1.2.3-18-g5258 From d7b0507e8a226a639f000fd1c6e7de70117c7c84 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Fri, 3 Feb 2012 21:42:46 -0500 Subject: fixed starting Leonardo bootloader from sketch AvrdudeUploader class opens and closes Leonardo port at the magic baudrate before starting avrdude; reduced reset timeout from 250 ms to 15 ms --- cores/arduino/CDC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index eb1b2c5..6dd1cbe 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -29,7 +29,7 @@ void Reboot() cli(); // Reset the microcontroller to run the bootloader - wdt_enable(WDTO_250MS); + wdt_enable(WDTO_15MS); for (;;); } -- cgit v1.2.3-18-g5258 From 35bbf80ba955bee9e432d4b2e11d479979599568 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Wed, 8 Feb 2012 01:16:56 -0500 Subject: adjusting descriptors - trying to prevent sketch and bootloader from grabbing different COM numbers on Windows --- cores/arduino/USBDesc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h index 549ed9e..7e4b4ba 100644 --- a/cores/arduino/USBDesc.h +++ b/cores/arduino/USBDesc.h @@ -60,7 +60,7 @@ #define IMANUFACTURER 1 #define IPRODUCT 2 -#define USB_PID_LEONARDO 0x0034 +#define USB_PID_LEONARDO 0x3003 #define USB_PID_MICRO 0x0035 #define USB_VID 0x2341 // arduino LLC vid #define USB_PID ARDUINO_MODEL_USB_PID -- cgit v1.2.3-18-g5258 From a7afdf40baf0598a97dbfeaf7d9bfcce93df74fd Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sun, 12 Feb 2012 19:52:03 -0500 Subject: prog_char -> char PROGMEM in Print.cpp http://code.google.com/p/arduino/issues/detail?id=795 --- cores/arduino/Print.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index ff9b154..e541a6c 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -41,7 +41,7 @@ size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::print(const __FlashStringHelper *ifsh) { - const prog_char *p = (const prog_char *)ifsh; + const char PROGMEM *p = (const char PROGMEM *)ifsh; size_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); -- cgit v1.2.3-18-g5258 From ac3aca0acf45f459c2c55e8e0894621aaaa4b4dd Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 13 Feb 2012 00:10:16 -0500 Subject: changed Leonardo bootloader and sketch PID values again (now 0x0701 for bootloader, 0x0801 for sketch) --- cores/arduino/USBDesc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h index 7e4b4ba..5cd90ad 100644 --- a/cores/arduino/USBDesc.h +++ b/cores/arduino/USBDesc.h @@ -60,7 +60,7 @@ #define IMANUFACTURER 1 #define IPRODUCT 2 -#define USB_PID_LEONARDO 0x3003 +#define USB_PID_LEONARDO 0x0801 #define USB_PID_MICRO 0x0035 #define USB_VID 0x2341 // arduino LLC vid #define USB_PID ARDUINO_MODEL_USB_PID -- cgit v1.2.3-18-g5258 From 924e5a48465cf8a9ba3af38e6cf4c2e1a2c0733c Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 13 Feb 2012 00:56:06 -0500 Subject: Leonardo auto-reset-and-upload changes for Windows (explanation below) On Windows COM port changes when board switched between bootloader and sketch. No way to prevent this so now Windows users have to select the upload port separate from the comm port. Also, handling of reset into bootloader was broken on Windows. Would occasionally leave the original COM port completely unusable. Changed the way this reset is initiated. Finally, had to add upload.disable.flushing=true flag to boards.txt so IDE wouldn't try to flush the original COM port after it disappeared. --- cores/arduino/CDC.cpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 6dd1cbe..deda5c0 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -23,20 +23,6 @@ #if defined(USBCON) #ifdef CDC_ENABLED -void Reboot() -{ - USB.detach(); - cli(); - - // Reset the microcontroller to run the bootloader - wdt_enable(WDTO_15MS); - for (;;); -} - -// 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. #if (RAMEND < 1000) #define SERIAL_BUFFER_SIZE 16 #else @@ -114,9 +100,14 @@ bool WEAK CDC_Setup(Setup& setup) if (CDC_SET_CONTROL_LINE_STATE == r) { - if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) // auto-reset is triggered when the port, already open at 1200 bps, is closed - Reboot(); _usbLineInfo.lineState = setup.wValueL; + // auto-reset into the bootloader is triggered when the port, already + // open at 1200 bps, is closed. this is the signal to start the watchdog + // with a relatively long period so it can finish housekeeping tasks + // like servicing endpoints before the sketch ends + if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) { + wdt_enable(WDTO_2S); + } return true; } } -- cgit v1.2.3-18-g5258 From 79481252081da0bdc4501cf039c060efcdf85c95 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 14 Feb 2012 12:17:30 -0500 Subject: Leonardo now checks whether bootloader should be run after a WDT event. Before the sketch initiates an auto-reset for upload it pokes a magic word into a specific RAM address. On starting the bootloader checks this address. If it finds the magic word it knows the bootloader code should run. If not it jumps straight back to sketch. Test in a sketch by adding to setup(): wdt_enable(WDTO_2S); Sketch should upload, start, run for two seconds, WDT, and sketch should restart (not bootloader). Had to cut out unused descriptor code to make the bootloader still fit in 4k. --- cores/arduino/CDC.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index deda5c0..0fa06bc 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -105,7 +105,8 @@ bool WEAK CDC_Setup(Setup& setup) // open at 1200 bps, is closed. this is the signal to start the watchdog // with a relatively long period so it can finish housekeeping tasks // like servicing endpoints before the sketch ends - if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) { + if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) { + *(uint16_t *)0x0A00 = 0x7777; wdt_enable(WDTO_2S); } return true; -- cgit v1.2.3-18-g5258 From 0138ee9b0167da66a9fb16602e57dc11bf02a563 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Wed, 22 Feb 2012 22:33:44 -0500 Subject: shortened the watchdog period for resetting Leonardo from 2 s to 250 ms. Reset into bootloader is much snappier. --- cores/arduino/CDC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 0fa06bc..7f33a6e 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -107,7 +107,7 @@ bool WEAK CDC_Setup(Setup& setup) // like servicing endpoints before the sketch ends if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) { *(uint16_t *)0x0A00 = 0x7777; - wdt_enable(WDTO_2S); + wdt_enable(WDTO_250MS); } return true; } -- cgit v1.2.3-18-g5258 From 73066a4ca24699820580f15520bf07d3f34068a2 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 27 Feb 2012 17:41:38 +0100 Subject: Autoreset 1200 bps fix. --- cores/arduino/CDC.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 7f33a6e..6d3929e 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -101,13 +101,26 @@ bool WEAK CDC_Setup(Setup& setup) if (CDC_SET_CONTROL_LINE_STATE == r) { _usbLineInfo.lineState = setup.wValueL; + // auto-reset into the bootloader is triggered when the port, already // open at 1200 bps, is closed. this is the signal to start the watchdog // with a relatively long period so it can finish housekeeping tasks // like servicing endpoints before the sketch ends - if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) { + + // We check DTR state to determine if host port is open (bit 0 of lineState). + // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX); + if ((_usbLineInfo.lineState & 0x01) == 0 && _usbLineInfo.dwDTERate == 1200) { *(uint16_t *)0x0A00 = 0x7777; wdt_enable(WDTO_250MS); + } else { + // Most OSs do some intermediate steps when configuring ports and DTR can + // twiggle more than once before stabilizing. + // To avoid spurious resets we set the watchdog to 250ms and eventually + // cancel if DTR goes back high. + + wdt_disable(); + wdt_reset(); + *(uint16_t *)0x0A00 = 0x0; } return true; } @@ -202,4 +215,4 @@ size_t Serial_::write(uint8_t c) Serial_ Serial; #endif -#endif /* if defined(USBCON) */ \ No newline at end of file +#endif /* if defined(USBCON) */ -- cgit v1.2.3-18-g5258 From c8ca7f96366d53b139ded479bcc690332eb8382d Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Thu, 1 Mar 2012 08:51:16 -0500 Subject: changed auto-reset logic for Leonardo. only do WDT manipulation if the port is opened at 1200 bps. (Dave Mellis) --- cores/arduino/CDC.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 6d3929e..94faf2e 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -106,21 +106,22 @@ bool WEAK CDC_Setup(Setup& setup) // open at 1200 bps, is closed. this is the signal to start the watchdog // with a relatively long period so it can finish housekeeping tasks // like servicing endpoints before the sketch ends - - // We check DTR state to determine if host port is open (bit 0 of lineState). - // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX); - if ((_usbLineInfo.lineState & 0x01) == 0 && _usbLineInfo.dwDTERate == 1200) { - *(uint16_t *)0x0A00 = 0x7777; - wdt_enable(WDTO_250MS); - } else { - // Most OSs do some intermediate steps when configuring ports and DTR can - // twiggle more than once before stabilizing. - // To avoid spurious resets we set the watchdog to 250ms and eventually - // cancel if DTR goes back high. - - wdt_disable(); - wdt_reset(); - *(uint16_t *)0x0A00 = 0x0; + if (1200 == _usbLineInfo.dwDTERate) { + // We check DTR state to determine if host port is open (bit 0 of lineState). + // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX); + if ((_usbLineInfo.lineState & 0x01) == 0) { + *(uint16_t *)0x0A00 = 0x7777; + wdt_enable(WDTO_250MS); + } else { + // Most OSs do some intermediate steps when configuring ports and DTR can + // twiggle more than once before stabilizing. + // To avoid spurious resets we set the watchdog to 250ms and eventually + // cancel if DTR goes back high. + + wdt_disable(); + wdt_reset(); + *(uint16_t *)0x0A00 = 0x0; + } } return true; } -- cgit v1.2.3-18-g5258 From 4fade7007fbe2049f4f7a3867c9f9a76f8c06db1 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 2 Mar 2012 18:58:53 -0500 Subject: Small changes for the ATmega1284. http://code.google.com/p/arduino/issues/detail?id=736 --- cores/arduino/WInterrupts.c | 2 -- cores/arduino/wiring_analog.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c index 4f035eb..3b9fe08 100755 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.c @@ -121,8 +121,6 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK) MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); GIMSK |= (1 << INT2); - #else - #warning attachInterrupt may need some more work for this cpu (case 1) #endif break; #endif diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 902b153..a8bc817 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -45,6 +45,8 @@ int analogRead(uint8_t pin) if (pin >= 54) pin -= 54; // allow for channel or pin numbers #elif defined(__AVR_ATmega32U4__) if (pin >= 18) pin -= 18; // allow for channel or pin numbers +#elif defined(__AVR_ATmega1284__) + if (pin >= 24) pin -= 24; // allow for channel or pin numbers #else if (pin >= 14) pin -= 14; // allow for channel or pin numbers #endif -- cgit v1.2.3-18-g5258 From 8f5869009ccddad8698969ff2ebe204d7b574b37 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sat, 3 Mar 2012 13:26:57 -0500 Subject: fixed minor compilation warnings for Leonardo --- cores/arduino/HID.cpp | 3 +-- cores/arduino/USBAPI.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index e6fb5f7..b60b3c0 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -144,7 +144,6 @@ u8 _hid_protocol = 1; u8 _hid_idle = 1; #define WEAK __attribute__ ((weak)) -#define WEAK int WEAK HID_GetInterface(u8* interfaceNum) { @@ -245,7 +244,7 @@ void Mouse_::release(uint8_t b) bool Mouse_::isPressed(uint8_t b) { - if (b & _buttons > 0) + if ((b & _buttons) > 0) return true; return false; } diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 6a0b989..3c97ff1 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -104,7 +104,7 @@ private: void setKeyMap(KeyMap* keyMap); public: Keyboard_(); - virtual size_t write(uint8_t c) {type(c);}; + virtual size_t write(uint8_t c) {return type(c);}; virtual size_t type(uint8_t c); }; extern Keyboard_ Keyboard; -- cgit v1.2.3-18-g5258 From fbea67532a03cbcb35c47209f902797c80c499f7 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sat, 3 Mar 2012 22:54:45 -0500 Subject: added Keyboard methods press(), release(), and releaseAll() Changes mean that a single, persistent key report must be used so keys can be added or removed. Also reimplemented type() using the new methods. --- cores/arduino/HID.cpp | 98 +++++++++++++++++++++++++++++++++++--------------- cores/arduino/USBAPI.h | 8 +++-- 2 files changed, 76 insertions(+), 30 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index b60b3c0..9904993 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -253,7 +253,7 @@ bool Mouse_::isPressed(uint8_t b) //================================================================================ // Keyboard -Keyboard_::Keyboard_() : _keyMap(0) +Keyboard_::Keyboard_() : _keyMap(0) { } @@ -406,38 +406,80 @@ const uint8_t _asciimap[128] = uint8_t USBPutChar(uint8_t c); -size_t Keyboard_::type(uint8_t c) +size_t Keyboard_::press(uint8_t k) { - // Keydown - { - KeyReport keys = {0}; - if (_keyMap) - _keyMap->charToKey(c,&keys); - else - { - if (c >= 128) { - setWriteError(); - return 0; - } - c = pgm_read_byte(_asciimap + c); - if (!c) { - setWriteError(); - return 0; - } - if (c & 0x80) - { - keys.modifiers |= KEY_MODIFIER_LEFT_SHIFT; - c &= 0x7F; + uint8_t i; + k = pgm_read_byte(_asciimap + k); + if (!k) { + setWriteError(); + return 0; + } + if (k & 0x80) { + _keyReport.modifiers |= KEY_MODIFIER_LEFT_SHIFT; + k &= 0x7F; + } + if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && + _keyReport.keys[2] != k && _keyReport.keys[3] != k && + _keyReport.keys[4] != k && _keyReport.keys[5] != k) { + + for (i=0; i<6; i++) { + if (_keyReport.keys[i] == 0x00) { + _keyReport.keys[i] = k; + break; } - keys.keys[0] = c; } - sendReport(&keys); + if (i == 6) { + setWriteError(); + return 0; + } } - // Keyup - { - KeyReport keys = {0}; - sendReport(&keys); + sendReport(&_keyReport); + return 1; +} + +size_t Keyboard_::release(uint8_t k) +{ + uint8_t i; + k = pgm_read_byte(_asciimap + k); + if (!k) { + return 0; } + if (k & 0x80) { + _keyReport.modifiers |= KEY_MODIFIER_LEFT_SHIFT; + k &= 0x7F; + } + for (i=0; i<6; i++) { + if (_keyReport.keys[i] == k) { + _keyReport.keys[i] = 0x00; + break; + } + } + if (i == 6) { + return 0; + } + sendReport(&_keyReport); + return 1; +} + +void Keyboard_::releaseAll(void) +{ + _keyReport.keys[0] = 0; + _keyReport.keys[1] = 0; + _keyReport.keys[2] = 0; + _keyReport.keys[3] = 0; + _keyReport.keys[4] = 0; + _keyReport.keys[5] = 0; + _keyReport.modifiers = 0; + sendReport(&_keyReport); +} + +size_t Keyboard_::type(uint8_t c) +{ + releaseAll(); + // Keydown + press(c); + // Keyup + releaseAll(); return 1; } diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 3c97ff1..6615fa8 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -100,12 +100,16 @@ class Keyboard_ : public Print { private: KeyMap* _keyMap; + KeyReport _keyReport; void sendReport(KeyReport* keys); void setKeyMap(KeyMap* keyMap); public: Keyboard_(); - virtual size_t write(uint8_t c) {return type(c);}; - virtual size_t type(uint8_t c); + virtual size_t write(uint8_t k) {return type(k);}; + virtual size_t type(uint8_t k); + virtual size_t press(uint8_t k); + virtual size_t release(uint8_t k); + virtual void releaseAll(void); }; extern Keyboard_ Keyboard; -- cgit v1.2.3-18-g5258 From 54fb0bf3f54a37d4dd9370d5f545a52b54ad1775 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sat, 3 Mar 2012 23:06:44 -0500 Subject: Removed support for key mapping in Keyboard. Was no longer being used and would be damn near impossible to support with the new scheme for handling modifiers and non-printing keyboard characters. --- cores/arduino/HID.cpp | 7 +------ cores/arduino/USBAPI.h | 11 ----------- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index 9904993..b508f10 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -253,7 +253,7 @@ bool Mouse_::isPressed(uint8_t b) //================================================================================ // Keyboard -Keyboard_::Keyboard_() : _keyMap(0) +Keyboard_::Keyboard_() { } @@ -262,11 +262,6 @@ void Keyboard_::sendReport(KeyReport* keys) HID_SendReport(2,keys,sizeof(KeyReport)); } -void Keyboard_::setKeyMap(KeyMap* keyMap) -{ - _keyMap = keyMap; -} - extern const uint8_t _asciimap[128] PROGMEM; diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 6615fa8..3f71856 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -87,22 +87,11 @@ typedef struct uint8_t keys[6]; } KeyReport; -// Map a character into a key report -// Called from Print to map text to keycodes -class KeyMap -{ -public: - virtual void charToKey(int c, KeyReport* keyReport) = 0; -}; - -// class Keyboard_ : public Print { private: - KeyMap* _keyMap; KeyReport _keyReport; void sendReport(KeyReport* keys); - void setKeyMap(KeyMap* keyMap); public: Keyboard_(); virtual size_t write(uint8_t k) {return type(k);}; -- cgit v1.2.3-18-g5258 From 15660068717c4721c60c9caefc1a8eaff702cc24 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sat, 3 Mar 2012 23:37:39 -0500 Subject: Added Keyboard support for all modifier and all common non-printing keys. --- cores/arduino/HID.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++-------- cores/arduino/USBAPI.h | 44 +++++++++++++++++++++++++++++++-------- 2 files changed, 83 insertions(+), 17 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index b508f10..378a157 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -401,18 +401,32 @@ const uint8_t _asciimap[128] = uint8_t USBPutChar(uint8_t c); +// press() adds the specified key (printing, non-printing, or modifier) +// to the persistent key report and sends the report. Because of the way +// USB HID works, the host acts like the key remains pressed until we +// call release(), releaseAll(), or otherwise clear the report and resend. size_t Keyboard_::press(uint8_t k) { uint8_t i; - k = pgm_read_byte(_asciimap + k); - if (!k) { - setWriteError(); - return 0; - } - if (k & 0x80) { - _keyReport.modifiers |= KEY_MODIFIER_LEFT_SHIFT; - k &= 0x7F; + if (k >= 136) { // it's a non-printing key (not a modifier) + k = k - 136; + } else if (k >= 128) { // it's a modifier key + _keyReport.modifiers |= (1<<(k-128)); + k = 0; + } else { // it's a printing key + k = pgm_read_byte(_asciimap + k); + if (!k) { + setWriteError(); + return 0; + } + if (k & 0x80) { + _keyReport.modifiers |= 0x02; // the left shift modifier + k &= 0x7F; + } } + + // Add k to the key report only if it's not already present + // and if there is an empty slot. if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && _keyReport.keys[2] != k && _keyReport.keys[3] != k && _keyReport.keys[4] != k && _keyReport.keys[5] != k) { @@ -432,17 +446,40 @@ size_t Keyboard_::press(uint8_t k) return 1; } +// release() takes the specified key out of the persistent key report and +// sends the report. This tells the OS the key is no longer pressed and that +// it shouldn't be repeated any more. size_t Keyboard_::release(uint8_t k) { + /* uint8_t i; k = pgm_read_byte(_asciimap + k); if (!k) { return 0; } if (k & 0x80) { - _keyReport.modifiers |= KEY_MODIFIER_LEFT_SHIFT; + _keyReport.modifiers |= 0x02; // the left shift modifier k &= 0x7F; } + */ + uint8_t i; + if (k >= 136) { // it's a non-printing key (not a modifier) + k = k - 136; + } else if (k >= 128) { // it's a modifier key + _keyReport.modifiers &= ~(1<<(k-128)); + k = 0; + } else { // it's a printing key + k = pgm_read_byte(_asciimap + k); + if (!k) { + return 0; + } + if (k & 0x80) { + _keyReport.modifiers &= ~(0x02); // the left shift modifier + k &= 0x7F; + } + } + + // Test the key report to see if k is present. Clear it if it exists. for (i=0; i<6; i++) { if (_keyReport.keys[i] == k) { _keyReport.keys[i] = 0x00; @@ -468,6 +505,7 @@ void Keyboard_::releaseAll(void) sendReport(&_keyReport); } +// type() does a press and release of the specified key. size_t Keyboard_::type(uint8_t c) { releaseAll(); diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 3f71856..05f7318 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -70,14 +70,42 @@ extern Mouse_ Mouse; //================================================================================ // Keyboard -#define KEY_MODIFIER_LEFT_CTRL 0x01 -#define KEY_MODIFIER_LEFT_SHIFT 0x02 -#define KEY_MODIFIER_LEFT_ALT 0x04 -#define KEY_MODIFIER_LEFT_GUI 0x08 -#define KEY_MODIFIER_RIGHT_CTRL 0x010 -#define KEY_MODIFIER_RIGHT_SHIFT 0x020 -#define KEY_MODIFIER_RIGHT_ALT 0x040 -#define KEY_MODIFIER_RIGHT_GUI 0x080 +#define KEY_LEFT_CTRL 0x80 +#define KEY_LEFT_SHIFT 0x81 +#define KEY_LEFT_ALT 0x82 +#define KEY_LEFT_GUI 0x83 +#define KEY_RIGHT_CTRL 0x84 +#define KEY_RIGHT_SHIFT 0x85 +#define KEY_RIGHT_ALT 0x86 +#define KEY_RIGHT_GUI 0x87 + +#define KEY_UP_ARROW 0xDA +#define KEY_DOWN_ARROW 0xD9 +#define KEY_LEFT_ARROW 0xD8 +#define KEY_RIGHT_ARROW 0xD7 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD // Low level key report: up to 6 keys and shift, ctrl etc at once typedef struct -- cgit v1.2.3-18-g5258 From b407337677f8b6964a69939e0fb5a371dfb0d3e4 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 7 Mar 2012 16:21:04 +0100 Subject: Fix for some strange behaviours during board reset --- cores/arduino/USBCore.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 7924078..c360d26 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -637,6 +637,12 @@ void USB_::attach() PLLCSR = 0x12; // Need 16 MHz xtal while (!(PLLCSR & (1< Date: Wed, 14 Mar 2012 18:17:22 -0400 Subject: reduced delay before starting the Leonardo bootloader Since we use a magic RAM flag to signal to the bootloader there's a risk of the sketch overwriting the magic RAM location before the bootloader starts. By reducing the watchdog timeout we reduce the chance of this happening. --- cores/arduino/CDC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 94faf2e..7206aa6 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -111,7 +111,7 @@ bool WEAK CDC_Setup(Setup& setup) // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX); if ((_usbLineInfo.lineState & 0x01) == 0) { *(uint16_t *)0x0A00 = 0x7777; - wdt_enable(WDTO_250MS); + wdt_enable(WDTO_120MS); } else { // Most OSs do some intermediate steps when configuring ports and DTR can // twiggle more than once before stabilizing. -- cgit v1.2.3-18-g5258 From 9c040a8a2bcc7ec8d128df05479b2e741fe192c2 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 26 Mar 2012 16:02:40 -0400 Subject: added stub methods for begin() and end() to Mouse and Keyboard --- cores/arduino/HID.cpp | 20 ++++++++++++++++++-- cores/arduino/USBAPI.h | 8 ++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index 378a157..e7ee249 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -201,7 +201,15 @@ bool WEAK HID_Setup(Setup& setup) //================================================================================ // Mouse -Mouse_::Mouse_() : _buttons(0) +Mouse_::Mouse_(void) : _buttons(0) +{ +} + +void Mouse_::begin(void) +{ +} + +void Mouse_::end(void) { } @@ -253,7 +261,15 @@ bool Mouse_::isPressed(uint8_t b) //================================================================================ // Keyboard -Keyboard_::Keyboard_() +Keyboard_::Keyboard_(void) +{ +} + +void Keyboard_::begin(void) +{ +} + +void Keyboard_::end(void) { } diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 05f7318..c8948c1 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -57,7 +57,9 @@ private: uint8_t _buttons; void buttons(uint8_t b); public: - Mouse_(); + Mouse_(void); + void begin(void); + void end(void); void click(uint8_t b = MOUSE_LEFT); void move(signed char x, signed char y, signed char wheel = 0); void press(uint8_t b = MOUSE_LEFT); // press LEFT by default @@ -121,7 +123,9 @@ private: KeyReport _keyReport; void sendReport(KeyReport* keys); public: - Keyboard_(); + Keyboard_(void); + void begin(void); + void end(void); virtual size_t write(uint8_t k) {return type(k);}; virtual size_t type(uint8_t k); virtual size_t press(uint8_t k); -- cgit v1.2.3-18-g5258 From f646c9186d33b26adeaada088e9549417463cdab Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 26 Mar 2012 17:00:16 -0400 Subject: Keyboard.type() now just presses and releases the key indicated - doesn't releaseAll() --- cores/arduino/HID.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index e7ee249..b0ef6e3 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -523,13 +523,10 @@ void Keyboard_::releaseAll(void) // type() does a press and release of the specified key. size_t Keyboard_::type(uint8_t c) -{ - releaseAll(); - // Keydown - press(c); - // Keyup - releaseAll(); - return 1; +{ + uint8_t p = press(c); // Keydown + uint8_t r = release(c); // Keyup + return (p&r); } #endif -- cgit v1.2.3-18-g5258 From 58c36f76d51d1fe4859140acf5c9c056b4204da5 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 26 Mar 2012 17:28:02 -0400 Subject: added methods to Keyboard to handle multiple simultaneous key presses or releases (up to six each) --- cores/arduino/HID.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++------ cores/arduino/USBAPI.h | 15 ++++++++ 2 files changed, 96 insertions(+), 11 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index b0ef6e3..b556223 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -467,17 +467,6 @@ size_t Keyboard_::press(uint8_t k) // it shouldn't be repeated any more. size_t Keyboard_::release(uint8_t k) { - /* - uint8_t i; - k = pgm_read_byte(_asciimap + k); - if (!k) { - return 0; - } - if (k & 0x80) { - _keyReport.modifiers |= 0x02; // the left shift modifier - k &= 0x7F; - } - */ uint8_t i; if (k >= 136) { // it's a non-printing key (not a modifier) k = k - 136; @@ -509,6 +498,87 @@ size_t Keyboard_::release(uint8_t k) return 1; } +size_t Keyboard_::press(uint8_t k[], uint8_t len) { + uint8_t i; + uint8_t result = 0; + for (i=0; i Date: Wed, 28 Mar 2012 18:35:26 -0400 Subject: eliminated Keyboard.type() - unnecessary duplication of Keyboard.write() (David Mellis). Also edit KeyboardReprogram example which was the only example using type() --- cores/arduino/HID.cpp | 3 +-- cores/arduino/USBAPI.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index b556223..dfcbd9d 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -591,8 +591,7 @@ void Keyboard_::releaseAll(void) sendReport(&_keyReport); } -// type() does a press and release of the specified key. -size_t Keyboard_::type(uint8_t c) +size_t Keyboard_::write(uint8_t c) { uint8_t p = press(c); // Keydown uint8_t r = release(c); // Keyup diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index e83089a..ee35af9 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -126,8 +126,7 @@ public: Keyboard_(void); void begin(void); void end(void); - virtual size_t write(uint8_t k) {return type(k);}; - virtual size_t type(uint8_t k); + virtual size_t write(uint8_t k); virtual size_t press(uint8_t k); virtual size_t release(uint8_t k); -- cgit v1.2.3-18-g5258 From 83feb140138d1c7900619ac2a733885e192987a8 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Wed, 28 Mar 2012 18:46:10 -0400 Subject: removed horrible multi-key Keyboard.press() and Keyboard.release() methods Saves 924 bytes of Flash --- cores/arduino/HID.cpp | 81 -------------------------------------------------- cores/arduino/USBAPI.h | 15 ---------- 2 files changed, 96 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index dfcbd9d..cdf49bd 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -498,87 +498,6 @@ size_t Keyboard_::release(uint8_t k) return 1; } -size_t Keyboard_::press(uint8_t k[], uint8_t len) { - uint8_t i; - uint8_t result = 0; - for (i=0; i Date: Wed, 28 Mar 2012 19:46:32 -0400 Subject: fixed logic error in Keyboard.release() - now removes every occurrence of a key if it's present more than once --- cores/arduino/HID.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index cdf49bd..ac63608 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -435,7 +435,7 @@ size_t Keyboard_::press(uint8_t k) setWriteError(); return 0; } - if (k & 0x80) { + if (k & 0x80) { // it's a capital letter or other character reached with shift _keyReport.modifiers |= 0x02; // the left shift modifier k &= 0x7F; } @@ -478,22 +478,20 @@ size_t Keyboard_::release(uint8_t k) if (!k) { return 0; } - if (k & 0x80) { + if (k & 0x80) { // it's a capital letter or other character reached with shift _keyReport.modifiers &= ~(0x02); // the left shift modifier k &= 0x7F; } } // Test the key report to see if k is present. Clear it if it exists. + // Check all positions in case the key is present more than once (which it shouldn't be) for (i=0; i<6; i++) { - if (_keyReport.keys[i] == k) { + if (0 != k && _keyReport.keys[i] == k) { _keyReport.keys[i] = 0x00; - break; } } - if (i == 6) { - return 0; - } + sendReport(&_keyReport); return 1; } @@ -514,7 +512,7 @@ size_t Keyboard_::write(uint8_t c) { uint8_t p = press(c); // Keydown uint8_t r = release(c); // Keyup - return (p&r); + return (p); // just return the result of press() since release() almost always returns 1 } #endif -- cgit v1.2.3-18-g5258 From a984b581a8ad093b55ec9f2d4677afdd77bf4705 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Sun, 1 Apr 2012 12:54:35 -0400 Subject: added Boolean operators to HardwareSerial and CDC to test whether the port is ready to send data. Mostly useful for Leonardo - simple way to test whether the port is actually opened by an application and ready to receive data. For Serial objects attached to real UARTs always returns true. --- cores/arduino/CDC.cpp | 6 ++++++ cores/arduino/HardwareSerial.cpp | 4 ++++ cores/arduino/HardwareSerial.h | 1 + cores/arduino/USBAPI.h | 1 + 4 files changed, 12 insertions(+) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 7206aa6..1275304 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -213,6 +213,12 @@ size_t Serial_::write(uint8_t c) return 0; } +Serial_::operator bool() { + if (_usbLineInfo.lineState > 0) + return true; + return false; +} + Serial_ Serial; #endif diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 9985b78..f40ddee 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -398,6 +398,10 @@ size_t HardwareSerial::write(uint8_t c) return 1; } +HardwareSerial::operator bool() { + return true; +} + // Preinstantiate Objects ////////////////////////////////////////////////////// #if defined(UBRRH) && defined(UBRRL) diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 176abe1..bf4924c 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -57,6 +57,7 @@ class HardwareSerial : public Stream 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(); }; #if defined(UBRRH) || defined(UBRR0H) diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 5169e65..f66cb16 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); + operator bool(); }; extern Serial_ Serial; -- cgit v1.2.3-18-g5258 From dd55096901b163b315948e0ddee3706464b3ec26 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 3 Apr 2012 10:52:38 -0400 Subject: added a short delay and comment to boolean operator in CDC Delay fixes problem where the port has been configured but not quite opened. Federico found that 10 ms was the minimum time needed to avoid problems. --- cores/arduino/CDC.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 1275304..c1e646d 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -213,10 +213,19 @@ size_t Serial_::write(uint8_t c) return 0; } +// This operator is a convenient way for a sketch to check whether the +// port has actually been configured and opened by the host (as opposed +// to just being connected to the host). It can be used, for example, in +// setup() before printing to ensure that an application on the host is +// actually ready to receive and display the data. +// We add a short delay before returning to fix a bug observed by Federico +// where the port is configured (lineState != 0) but not quite opened. Serial_::operator bool() { - if (_usbLineInfo.lineState > 0) - return true; - return false; + bool result = false; + if (_usbLineInfo.lineState > 0) + result = true; + delay(10); + return result; } Serial_ Serial; -- cgit v1.2.3-18-g5258 From 02c5849501294f2965051c41e1236899a55f7bfc Mon Sep 17 00:00:00 2001 From: Federico Vanzati Date: Fri, 6 Apr 2012 17:36:09 +0200 Subject: Revert "added a short delay and comment to boolean operator in CDC" This reverts commit ade4893f585e3e94fa6cf683620e1d12afc88ecd. --- cores/arduino/CDC.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index c1e646d..1275304 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -213,19 +213,10 @@ size_t Serial_::write(uint8_t c) return 0; } -// This operator is a convenient way for a sketch to check whether the -// port has actually been configured and opened by the host (as opposed -// to just being connected to the host). It can be used, for example, in -// setup() before printing to ensure that an application on the host is -// actually ready to receive and display the data. -// We add a short delay before returning to fix a bug observed by Federico -// where the port is configured (lineState != 0) but not quite opened. Serial_::operator bool() { - bool result = false; - if (_usbLineInfo.lineState > 0) - result = true; - delay(10); - return result; + if (_usbLineInfo.lineState > 0) + return true; + return false; } Serial_ Serial; -- cgit v1.2.3-18-g5258 From ee611dc194fad72d2db9a901208577857365778f Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Fri, 6 Apr 2012 21:23:17 -0400 Subject: Revert "Revert "added a short delay and comment to boolean operator in CDC"" This reverts commit 200eefb4e2ac7796c5c901e8fd9369c85ec544c5. --- cores/arduino/CDC.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index 1275304..c1e646d 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -213,10 +213,19 @@ size_t Serial_::write(uint8_t c) return 0; } +// This operator is a convenient way for a sketch to check whether the +// port has actually been configured and opened by the host (as opposed +// to just being connected to the host). It can be used, for example, in +// setup() before printing to ensure that an application on the host is +// actually ready to receive and display the data. +// We add a short delay before returning to fix a bug observed by Federico +// where the port is configured (lineState != 0) but not quite opened. Serial_::operator bool() { - if (_usbLineInfo.lineState > 0) - return true; - return false; + bool result = false; + if (_usbLineInfo.lineState > 0) + result = true; + delay(10); + return result; } Serial_ Serial; -- cgit v1.2.3-18-g5258 From ec83f55b626f3b9b5da4a0782b8fa81ca72a8933 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 9 Apr 2012 08:06:35 -0400 Subject: sketch USB VID and PID values are passed in from boards.txt at compile time now. changed sketch PIDs to final values. also uncommented Micro section in boards.txt --- cores/arduino/USBCore.cpp | 4 ++-- cores/arduino/USBDesc.h | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'cores') diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index c360d26..d1aeace 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -51,9 +51,9 @@ const u16 STRING_LANGUAGE[2] = { const u16 STRING_IPRODUCT[17] = { (3<<8) | (2+2*16), -#if USB_PID == USB_PID_LEONARDO +#if USB_PID == 0x8034 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o' -#elif USB_PID == USB_PID_MICRO +#elif USB_PID == 0x8035 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' ' #endif }; diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h index 5cd90ad..900713e 100644 --- a/cores/arduino/USBDesc.h +++ b/cores/arduino/USBDesc.h @@ -60,8 +60,4 @@ #define IMANUFACTURER 1 #define IPRODUCT 2 -#define USB_PID_LEONARDO 0x0801 -#define USB_PID_MICRO 0x0035 -#define USB_VID 0x2341 // arduino LLC vid -#define USB_PID ARDUINO_MODEL_USB_PID -- cgit v1.2.3-18-g5258 From e2e0260094c762fddf4669b7a957914405ae9f19 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Mon, 9 Apr 2012 10:12:14 -0400 Subject: Micro I hardly knew ye --- cores/arduino/USBCore.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index d1aeace..34c4372 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -53,14 +53,18 @@ const u16 STRING_IPRODUCT[17] = { (3<<8) | (2+2*16), #if USB_PID == 0x8034 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o' -#elif USB_PID == 0x8035 - 'A','r','d','u','i','n','o',' ','M','i','c','r','o',' ',' ',' ' +#else + 'U','S','B',' ','I','O',' ','B','O','A','R','D',' ',' ',' ',' ' #endif }; const u16 STRING_IMANUFACTURER[12] = { (3<<8) | (2+2*11), +#if USB_VID == 0x2341 'A','r','d','u','i','n','o',' ','L','L','C' +#else + 'U','n','k','n','o','w','n',' ',' ',' ',' ' +#endif }; #ifdef CDC_ENABLED -- cgit v1.2.3-18-g5258 From 49f7fb00fd7578fe5ecd78d60165fc2570aec1e2 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Wed, 11 Apr 2012 23:19:05 -0400 Subject: fixed logic bug in Caterina that could stop the bootloader from entering self-programming mode --- cores/arduino/CDC.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'cores') diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index c1e646d..1ee3a48 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -108,9 +108,8 @@ bool WEAK CDC_Setup(Setup& setup) // like servicing endpoints before the sketch ends if (1200 == _usbLineInfo.dwDTERate) { // We check DTR state to determine if host port is open (bit 0 of lineState). - // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX); if ((_usbLineInfo.lineState & 0x01) == 0) { - *(uint16_t *)0x0A00 = 0x7777; + *(uint16_t *)0x0800 = 0x7777; wdt_enable(WDTO_120MS); } else { // Most OSs do some intermediate steps when configuring ports and DTR can @@ -120,7 +119,7 @@ bool WEAK CDC_Setup(Setup& setup) wdt_disable(); wdt_reset(); - *(uint16_t *)0x0A00 = 0x0; + *(uint16_t *)0x0800 = 0x0; } } return true; -- cgit v1.2.3-18-g5258 From 56ddc4637de1b8b0e21840519ed0b94966395ff5 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Thu, 19 Apr 2012 15:46:32 -0400 Subject: bugfix for boards with a timer 4 but no channel D compilation failed for Mega because the COM4D1 and OCR4D registers are defined for 32U4 but not for Mega --- cores/arduino/wiring_analog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 40a3363..c06cad4 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -230,7 +230,7 @@ void analogWrite(uint8_t pin, int val) break; #endif - #if defined(TCCR4C) + #if defined(TCCR4C) && defined(COM4D1) case TIMER4D: // connect pwm to pin on timer 4, channel D sbi(TCCR4C, COM4D1); -- cgit v1.2.3-18-g5258 From 6ae1a1723561266767ed1ba39ae61c35ea263162 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Thu, 19 Apr 2012 15:52:16 -0400 Subject: bugfix for configuring PWM on D6 and D13 too early. (thanks to Limor Fried) was starting PWM on these pins too soon - in init() instead of when analogWrite() was called. as a result doing output on port registers directly failed. --- cores/arduino/wiring.c | 4 ---- cores/arduino/wiring_analog.c | 6 ++++++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'cores') diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c index fb447eb..ac8bb6f 100644 --- a/cores/arduino/wiring.c +++ b/cores/arduino/wiring.c @@ -280,10 +280,6 @@ void init() #endif #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ - sbi(TCCR4A, COM4A1); // clear channel A on output compare match - cbi(TCCR4A, COM4A0); - sbi(TCCR4C, COM4D1); // clear channel D on output compare match - cbi(TCCR4C, COM4D0); sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 sbi(TCCR4B, CS41); sbi(TCCR4B, CS40); diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index c06cad4..0e9881f 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -210,6 +210,9 @@ void analogWrite(uint8_t pin, int val) case TIMER4A: //connect pwm to pin on timer 4, channel A sbi(TCCR4A, COM4A1); + #if defined(COM4A0) // only used on 32U4 + cbi(TCCR4A, COM4A0); + #endif OCR4A = val; // set pwm duty break; #endif @@ -234,6 +237,9 @@ void analogWrite(uint8_t pin, int val) case TIMER4D: // connect pwm to pin on timer 4, channel D sbi(TCCR4C, COM4D1); + #if defined(COM4D0) // only used on 32U4 + cbi(TCCR4C, COM4D0); + #endif OCR4D = val; // set pwm duty break; #endif -- cgit v1.2.3-18-g5258 From d755d0035d4e3a816c127fd8207722bfe6629eee Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Wed, 25 Apr 2012 15:56:18 -0400 Subject: changed PID values for Leonardo bootloader and sketch done to avoid driver problems for users who installed the pre-release bootloader and driver --- cores/arduino/USBCore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cores') diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 34c4372..9e89fd6 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -51,10 +51,10 @@ const u16 STRING_LANGUAGE[2] = { const u16 STRING_IPRODUCT[17] = { (3<<8) | (2+2*16), -#if USB_PID == 0x8034 +#if USB_PID == 0x8036 'A','r','d','u','i','n','o',' ','L','e','o','n','a','r','d','o' #else - 'U','S','B',' ','I','O',' ','B','O','A','R','D',' ',' ',' ',' ' + 'U','S','B',' ','I','O',' ','B','o','a','r','d',' ',' ',' ',' ' #endif }; -- cgit v1.2.3-18-g5258 From 757a77ab67edb9831fe11fe95c80cb08a695e4a1 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 1 May 2012 11:18:15 -0400 Subject: renamed Leonardo USB_ class to USBDevice_ to be unambiguous. renamed "USB" object to "USBDevice" to prevent conflict with USB Host library (thanks Massimo) --- cores/arduino/USBAPI.h | 6 +++--- cores/arduino/USBCore.cpp | 12 ++++++------ cores/arduino/main.cpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) mode change 100755 => 100644 cores/arduino/main.cpp (limited to 'cores') diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index f66cb16..1c21845 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -9,17 +9,17 @@ //================================================================================ // USB -class USB_ +class USBDevice_ { public: - USB_(); + USBDevice_(); bool configured(); void attach(); void detach(); // Serial port goes down too... void poll(); }; -extern USB_ USB; +extern USBDevice_ USBDevice; //================================================================================ //================================================================================ diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 9e89fd6..6766be6 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -627,13 +627,13 @@ u8 USBConnected() //======================================================================= //======================================================================= -USB_ USB; +USBDevice_ USBDevice; -USB_::USB_() +USBDevice_::USBDevice_() { } -void USB_::attach() +void USBDevice_::attach() { _usbConfiguration = 0; UHWCON = 0x01; // power internal reg @@ -654,18 +654,18 @@ void USB_::attach() TX_RX_LED_INIT; } -void USB_::detach() +void USBDevice_::detach() { } // Check for interrupts // TODO: VBUS detection -bool USB_::configured() +bool USBDevice_::configured() { return _usbConfiguration; } -void USB_::poll() +void USBDevice_::poll() { } diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp old mode 100755 new mode 100644 index 34450f4..3d4e079 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -5,7 +5,7 @@ int main(void) init(); #if defined(USBCON) - USB.attach(); + USBDevice.attach(); #endif setup(); -- cgit v1.2.3-18-g5258 From efa75937723c2b868ddb7cec93a0a3bf6fa01959 Mon Sep 17 00:00:00 2001 From: Zach Eveland Date: Tue, 15 May 2012 15:48:51 -0400 Subject: Mouse.isPressed() now checks only for left button by default if no argument is given now checks left button by default to be consistent with press() and release() (thanks, David Mellis) --- cores/arduino/USBAPI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 1c21845..d5abdb6 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -65,7 +65,7 @@ public: void move(signed char x, signed char y, signed char wheel = 0); void press(uint8_t b = MOUSE_LEFT); // press LEFT by default void release(uint8_t b = MOUSE_LEFT); // release LEFT by default - bool isPressed(uint8_t b = MOUSE_ALL); // check all buttons by default + bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default }; extern Mouse_ Mouse; -- cgit v1.2.3-18-g5258 From b495294aa32ca838180af57efdb1f04727487d55 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Wed, 16 May 2012 15:39:34 -0400 Subject: Adding readString() and readStringUntil() to Stream (Adrian McEwen). This isn't necessarily a particularly efficient implementation (it allocates memory one character at a time and so may lead to fragmentation) but it seems to work. http://code.google.com/p/arduino/issues/detail?id=454 --- cores/arduino/Stream.cpp | 24 ++++++++++++++++++++++++ cores/arduino/Stream.h | 2 ++ 2 files changed, 26 insertions(+) (limited to 'cores') diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp index 3d5b905..aafb7fc 100644 --- a/cores/arduino/Stream.cpp +++ b/cores/arduino/Stream.cpp @@ -244,3 +244,27 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) return index; // return number of characters, not including null terminator } +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h index 13f11be..58bbf75 100644 --- a/cores/arduino/Stream.h +++ b/cores/arduino/Stream.h @@ -82,6 +82,8 @@ class Stream : public Print // returns the number of characters placed in the buffer (0 means no valid data found) // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); protected: long parseInt(char skipChar); // as above but the given skipChar is ignored -- cgit v1.2.3-18-g5258 From 4ed0bd2bd562ad815e62e0a2dbb34d854d2c6929 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sat, 2 Jun 2012 20:08:46 +0200 Subject: Added support for interrupt on INT2 and INT3 on the Leonardo --- cores/arduino/WInterrupts.c | 36 ++++++++++++++++++++++++++++++------ cores/arduino/wiring_private.h | 2 ++ 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'cores') 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< Date: Sun, 3 Jun 2012 07:48:32 -0400 Subject: Check for NULL pointer in Print.write(). Otherwise, trying to print(NULL) or write(NULL) could print a random character. http://code.google.com/p/arduino/issues/detail?id=941 --- cores/arduino/Print.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'cores') 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 *); -- cgit v1.2.3-18-g5258 From 3436ca97cbccd9068c79bf201cb367de60789f37 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Mon, 4 Jun 2012 23:30:41 -0400 Subject: Printing NaN values as "nan" in printFloat(). http://code.google.com/p/arduino/issues/detail?id=946 --- cores/arduino/Print.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'cores') diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index e541a6c..98969f5 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -226,6 +226,8 @@ size_t Print::printFloat(double number, uint8_t digits) { size_t n = 0; + if (isnan(number)) return print("nan"); + // Handle negative numbers if (number < 0.0) { -- cgit v1.2.3-18-g5258 From 29ff4f779a37019c5218145cb15b036b51fc5e25 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Thu, 14 Jun 2012 15:53:27 +0100 Subject: Adding write(str) and write(buf, size) for USB CDC. So that they work on the Leonardo. http://code.google.com/p/arduino/issues/detail?id=958 --- cores/arduino/USBAPI.h | 1 + 1 file changed, 1 insertion(+) (limited to 'cores') 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; -- cgit v1.2.3-18-g5258 From 2ef2f9d5c78ad4a1d265b7386e13c41d41ba410a Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sat, 23 Jun 2012 10:37:35 -0500 Subject: Print "inf" for infinite floating point numbers (using isinf()). http://code.google.com/p/arduino/issues/detail?id=961 --- cores/arduino/Print.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'cores') diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 98969f5..711251c 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -227,6 +227,7 @@ 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"); // Handle negative numbers if (number < 0.0) -- cgit v1.2.3-18-g5258