aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cores/arduino/PluggableUSB.cpp9
-rw-r--r--cores/arduino/PluggableUSB.h2
-rw-r--r--cores/arduino/Stream.cpp66
-rw-r--r--cores/arduino/Stream.h42
-rw-r--r--cores/arduino/USBAPI.h1
-rw-r--r--cores/arduino/USBCore.cpp42
-rw-r--r--cores/arduino/USBDesc.h8
-rw-r--r--cores/arduino/wiring.c4
-rw-r--r--libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino4
-rw-r--r--libraries/HID/HID.cpp26
-rw-r--r--libraries/HID/HID.h8
-rw-r--r--libraries/SoftwareSerial/SoftwareSerial.cpp14
-rw-r--r--libraries/SoftwareSerial/SoftwareSerial.h5
-rw-r--r--libraries/Wire/keywords.txt2
-rw-r--r--libraries/Wire/utility/twi.c12
-rw-r--r--platform.txt4
-rw-r--r--variants/ethernet/pins_arduino.h2
-rw-r--r--variants/gemma/pins_arduino.h6
-rw-r--r--variants/leonardo/pins_arduino.h16
19 files changed, 181 insertions, 92 deletions
diff --git a/cores/arduino/PluggableUSB.cpp b/cores/arduino/PluggableUSB.cpp
index 7a6351d..c489d9f 100644
--- a/cores/arduino/PluggableUSB.cpp
+++ b/cores/arduino/PluggableUSB.cpp
@@ -50,6 +50,15 @@ int PluggableUSB_::getDescriptor(USBSetup& setup)
return 0;
}
+void PluggableUSB_::getShortName(char *iSerialNum)
+{
+ PluggableUSBModule* node;
+ for (node = rootNode; node; node = node->next) {
+ iSerialNum += node->getShortName(iSerialNum);
+ }
+ *iSerialNum = 0;
+}
+
bool PluggableUSB_::setup(USBSetup& setup)
{
PluggableUSBModule* node;
diff --git a/cores/arduino/PluggableUSB.h b/cores/arduino/PluggableUSB.h
index 3df9bff..507f0df 100644
--- a/cores/arduino/PluggableUSB.h
+++ b/cores/arduino/PluggableUSB.h
@@ -35,6 +35,7 @@ protected:
virtual bool setup(USBSetup& setup) = 0;
virtual int getInterface(uint8_t* interfaceCount) = 0;
virtual int getDescriptor(USBSetup& setup) = 0;
+ virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
uint8_t pluggedInterface;
uint8_t pluggedEndpoint;
@@ -55,6 +56,7 @@ public:
int getInterface(uint8_t* interfaceCount);
int getDescriptor(USBSetup& setup);
bool setup(USBSetup& setup);
+ void getShortName(char *iSerialNum);
private:
uint8_t lastIf;
diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp
index b31942f..f665465 100644
--- a/cores/arduino/Stream.cpp
+++ b/cores/arduino/Stream.cpp
@@ -26,7 +26,6 @@
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
-#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
// private method to read stream with timeout
int Stream::timedRead()
@@ -54,14 +53,30 @@ int Stream::timedPeek()
// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
-int Stream::peekNextDigit()
+int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
{
int c;
while (1) {
c = timedPeek();
- if (c < 0) return c; // timeout
- if (c == '-') return c;
- if (c >= '0' && c <= '9') return c;
+
+ if( c < 0 ||
+ c == '-' ||
+ (c >= '0' && c <= '9') ||
+ (detectDecimal && c == '.')) return c;
+
+ switch( lookahead ){
+ case SKIP_NONE: return -1; // Fail code.
+ case SKIP_WHITESPACE:
+ switch( c ){
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n': break;
+ default: return -1; // Fail code.
+ }
+ case SKIP_ALL:
+ break;
+ }
read(); // discard non-numeric
}
}
@@ -107,31 +122,25 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t
}
}
-
// returns the first valid (long) integer value from the current position.
-// initial characters that are not digits (or the minus sign) are skipped
-// function is terminated by the first character that is not a digit.
-long Stream::parseInt()
-{
- return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
-}
-
-// as above but a given skipChar is ignored
-// this allows format characters (typically commas) in values to be ignored
-long Stream::parseInt(char skipChar)
+// lookahead determines how parseInt looks ahead in the stream.
+// See LookaheadMode enumeration at the top of the file.
+// Lookahead is terminated by the first character that is not a valid part of an integer.
+// Once parsing commences, 'ignore' will be skipped in the stream.
+long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
long value = 0;
int c;
- c = peekNextDigit();
+ c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
- if(c == skipChar)
- ; // ignore this charactor
+ if(c == ignore)
+ ; // ignore this character
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
@@ -139,36 +148,29 @@ long Stream::parseInt(char skipChar)
read(); // consume the character we got with peek
c = timedPeek();
}
- while( (c >= '0' && c <= '9') || c == skipChar );
+ while( (c >= '0' && c <= '9') || c == ignore );
if(isNegative)
value = -value;
return value;
}
-
// as parseInt but returns a floating point value
-float Stream::parseFloat()
+float Stream::parseFloat(LookaheadMode lookahead, char ignore)
{
- return parseFloat(NO_SKIP_CHAR);
-}
-
-// as above but the given skipChar is ignored
-// this allows format characters (typically commas) in values to be ignored
-float Stream::parseFloat(char skipChar){
bool isNegative = false;
bool isFraction = false;
long value = 0;
- char c;
+ int c;
float fraction = 1.0;
- c = peekNextDigit();
+ c = peekNextDigit(lookahead, true);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
- if(c == skipChar)
+ if(c == ignore)
; // ignore
else if(c == '-')
isNegative = true;
@@ -182,7 +184,7 @@ float Stream::parseFloat(char skipChar){
read(); // consume the character we got with peek
c = timedPeek();
}
- while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
+ while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
if(isNegative)
value = -value;
diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h
index 15f6761..db71bb6 100644
--- a/cores/arduino/Stream.h
+++ b/cores/arduino/Stream.h
@@ -28,13 +28,24 @@
// compatability macros for testing
/*
#define getInt() parseInt()
-#define getInt(skipChar) parseInt(skipchar)
+#define getInt(ignore) parseInt(ignore)
#define getFloat() parseFloat()
-#define getFloat(skipChar) parseFloat(skipChar)
+#define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
+// This enumeration provides the lookahead options for parseInt(), parseFloat()
+// The rules set out here are used until either the first valid character is found
+// or a time out occurs due to lack of input.
+enum LookaheadMode{
+ SKIP_ALL, // All invalid characters are ignored.
+ SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
+ SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
+};
+
+#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
+
class Stream : public Print
{
protected:
@@ -42,7 +53,7 @@ class Stream : public Print
unsigned long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout
int timedPeek(); // private method to peek stream with timeout
- int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
+ int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0;
@@ -72,12 +83,15 @@ class Stream : public Print
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
+ long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
+ // returns the first valid (long) integer value from the current position.
+ // lookahead determines how parseInt looks ahead in the stream.
+ // See LookaheadMode enumeration at the top of the file.
+ // Lookahead is terminated by the first character that is not a valid part of an integer.
+ // Once parsing commences, 'ignore' will be skipped in the stream.
- long parseInt(); // returns the first valid (long) integer value from the current position.
- // initial characters that are not digits (or the minus sign) are skipped
- // integer is terminated by the first character that is not a digit.
-
- float parseFloat(); // float version of parseInt
+ float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
+ // float version of parseInt
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
@@ -94,11 +108,11 @@ class Stream : public Print
String readStringUntil(char terminator);
protected:
- long parseInt(char skipChar); // as above but the given skipChar is ignored
- // as above but the given skipChar is ignored
- // this allows format characters (typically commas) in values to be ignored
-
- float parseFloat(char skipChar); // as above but the given skipChar is ignored
+ long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
+ float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
+ // These overload exists for compatibility with any class that has derived
+ // Stream and used parseFloat/Int with a custom ignore character. To keep
+ // the public API simple, these overload remains protected.
struct MultiTarget {
const char *str; // string you're searching for
@@ -111,5 +125,5 @@ class Stream : public Print
int findMulti(struct MultiTarget *targets, int tCount);
};
-
+#undef NO_IGNORE_CHAR
#endif
diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h
index f22ab6a..358444e 100644
--- a/cores/arduino/USBAPI.h
+++ b/cores/arduino/USBAPI.h
@@ -193,6 +193,7 @@ bool CDC_Setup(USBSetup& setup);
int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len);
+int USB_RecvControlLong(void* d, int len);
uint8_t USB_Available(uint8_t ep);
uint8_t USB_SendSpace(uint8_t ep);
diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp
index f67bfea..62b90ed 100644
--- a/cores/arduino/USBCore.cpp
+++ b/cores/arduino/USBCore.cpp
@@ -18,6 +18,7 @@
#include "USBAPI.h"
#include "PluggableUSB.h"
+#include <stdlib.h>
#if defined(USBCON)
@@ -69,10 +70,10 @@ const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER;
// DEVICE DESCRIPTOR
const DeviceDescriptor USB_DeviceDescriptor =
- D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
+ D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1);
const DeviceDescriptor USB_DeviceDescriptorB =
- D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
+ D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1);
//==================================================================
//==================================================================
@@ -409,11 +410,12 @@ int USB_SendControl(u8 flags, const void* d, int len)
// Send a USB descriptor string. The string is stored in PROGMEM as a
// plain ASCII string but is sent out as UTF-16 with the correct 2-byte
// prefix
-static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) {
+static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len, uint8_t flags) {
SendControl(2 + string_len * 2);
SendControl(3);
+ bool pgm = flags & TRANSFER_PGM;
for(u8 i = 0; i < string_len; i++) {
- bool r = SendControl(pgm_read_byte(&string_P[i]));
+ bool r = SendControl(pgm ? pgm_read_byte(&string_P[i]) : string_P[i]);
r &= SendControl(0); // high byte
if(!r) {
return false;
@@ -423,13 +425,24 @@ static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len) {
}
// Does not timeout or cross fifo boundaries
-// Will only work for transfers <= 64 bytes
-// TODO
int USB_RecvControl(void* d, int len)
{
- WaitOUT();
- Recv((u8*)d,len);
- ClearOUT();
+ auto length = len;
+ while(length)
+ {
+ // Dont receive more than the USB Control EP has to offer
+ // Use fixed 64 because control EP always have 64 bytes even on 16u2.
+ auto recvLength = length;
+ if(recvLength > 64){
+ recvLength = 64;
+ }
+
+ // Write data to fit to the end (not the beginning) of the array
+ WaitOUT();
+ Recv((u8*)d + len - length, recvLength);
+ ClearOUT();
+ length -= recvLength;
+ }
return len;
}
@@ -495,10 +508,17 @@ bool SendDescriptor(USBSetup& setup)
desc_addr = (const u8*)&STRING_LANGUAGE;
}
else if (setup.wValueL == IPRODUCT) {
- return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT));
+ return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM);
}
else if (setup.wValueL == IMANUFACTURER) {
- return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER));
+ return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER), TRANSFER_PGM);
+ }
+ else if (setup.wValueL == ISERIAL) {
+#ifdef PLUGGABLE_USB_ENABLED
+ char name[ISERIAL_MAX_LEN];
+ PluggableUSB().getShortName(name);
+ return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0);
+#endif
}
else
return false;
diff --git a/cores/arduino/USBDesc.h b/cores/arduino/USBDesc.h
index 4b9cf66..c0dce07 100644
--- a/cores/arduino/USBDesc.h
+++ b/cores/arduino/USBDesc.h
@@ -24,6 +24,8 @@
#define USB_ENDPOINTS 5 // AtMegaxxU2
#endif
+#define ISERIAL_MAX_LEN 20
+
#define CDC_INTERFACE_COUNT 2
#define CDC_ENPOINT_COUNT 3
@@ -39,6 +41,6 @@
#define CDC_RX CDC_ENDPOINT_OUT
#define CDC_TX CDC_ENDPOINT_IN
-#define IMANUFACTURER 1
-#define IPRODUCT 2
-
+#define IMANUFACTURER 1
+#define IPRODUCT 2
+#define ISERIAL 3 \ No newline at end of file
diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c
index 1c3e5a5..b956f78 100644
--- a/cores/arduino/wiring.c
+++ b/cores/arduino/wiring.c
@@ -105,11 +105,11 @@ unsigned long micros() {
void delay(unsigned long ms)
{
- uint16_t start = (uint16_t)micros();
+ uint32_t start = micros();
while (ms > 0) {
yield();
- if (((uint16_t)micros() - start) >= 1000) {
+ while ( ms > 0 && (micros() - start) >= 1000) {
ms--;
start += 1000;
}
diff --git a/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino
index 73d64a7..8b5121c 100644
--- a/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino
+++ b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino
@@ -11,7 +11,9 @@
#include <EEPROM.h>
void setup() {
-
+ // initialize the LED pin as an output.
+ pinMode(13, OUTPUT);
+
/***
Iterate through each byte of the EEPROM storage.
diff --git a/libraries/HID/HID.cpp b/libraries/HID/HID.cpp
index 411529e..21ede26 100644
--- a/libraries/HID/HID.cpp
+++ b/libraries/HID/HID.cpp
@@ -54,9 +54,24 @@ int HID_::getDescriptor(USBSetup& setup)
return -1;
total += res;
}
+
+ // Reset the protocol on reenumeration. Normally the host should not assume the state of the protocol
+ // due to the USB specs, but Windows and Linux just assumes its in report mode.
+ protocol = HID_REPORT_PROTOCOL;
+
return total;
}
+uint8_t HID_::getShortName(char *name)
+{
+ name[0] = 'H';
+ name[1] = 'I';
+ name[2] = 'D';
+ name[3] = 'A' + (descriptorSize & 0x0F);
+ name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
+ return 5;
+}
+
void HID_::AppendDescriptor(HIDSubDescriptor *node)
{
if (!rootNode) {
@@ -71,10 +86,13 @@ void HID_::AppendDescriptor(HIDSubDescriptor *node)
descriptorSize += node->length;
}
-void HID_::SendReport(uint8_t id, const void* data, int len)
+int HID_::SendReport(uint8_t id, const void* data, int len)
{
- USB_Send(pluggedEndpoint, &id, 1);
- USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, len);
+ auto ret = USB_Send(pluggedEndpoint, &id, 1);
+ if (ret < 0) return ret;
+ auto ret2 = USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, len);
+ if (ret2 < 0) return ret2;
+ return ret + ret2;
}
bool HID_::setup(USBSetup& setup)
@@ -130,7 +148,7 @@ bool HID_::setup(USBSetup& setup)
HID_::HID_(void) : PluggableUSBModule(1, 1, epType),
rootNode(NULL), descriptorSize(0),
- protocol(1), idle(1)
+ protocol(HID_REPORT_PROTOCOL), idle(1)
{
epType[0] = EP_TYPE_INTERRUPT_IN;
PluggableUSB().plug(this);
diff --git a/libraries/HID/HID.h b/libraries/HID/HID.h
index ba08da7..93c4bd5 100644
--- a/libraries/HID/HID.h
+++ b/libraries/HID/HID.h
@@ -54,6 +54,11 @@
#define HID_BOOT_PROTOCOL 0
#define HID_REPORT_PROTOCOL 1
+// HID Request Type HID1.11 Page 51 7.2.1 Get_Report Request
+#define HID_REPORT_TYPE_INPUT 1
+#define HID_REPORT_TYPE_OUTPUT 2
+#define HID_REPORT_TYPE_FEATURE 3
+
typedef struct
{
uint8_t len; // 9
@@ -88,7 +93,7 @@ class HID_ : public PluggableUSBModule
public:
HID_(void);
int begin(void);
- void SendReport(uint8_t id, const void* data, int len);
+ int SendReport(uint8_t id, const void* data, int len);
void AppendDescriptor(HIDSubDescriptor* node);
protected:
@@ -96,6 +101,7 @@ protected:
int getInterface(uint8_t* interfaceCount);
int getDescriptor(USBSetup& setup);
bool setup(USBSetup& setup);
+ uint8_t getShortName(char* name);
private:
uint8_t epType[1];
diff --git a/libraries/SoftwareSerial/SoftwareSerial.cpp b/libraries/SoftwareSerial/SoftwareSerial.cpp
index 527f3f9..0a16ff7 100644
--- a/libraries/SoftwareSerial/SoftwareSerial.cpp
+++ b/libraries/SoftwareSerial/SoftwareSerial.cpp
@@ -57,9 +57,9 @@ volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
//
// This function generates a brief pulse
// for debugging or measuring on an oscilloscope.
+#if _DEBUG
inline void DebugPulse(uint8_t pin, uint8_t count)
{
-#if _DEBUG
volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
uint8_t val = *pport;
@@ -68,8 +68,10 @@ inline void DebugPulse(uint8_t pin, uint8_t count)
*pport = val | digitalPinToBitMask(pin);
*pport = val;
}
-#endif
}
+#else
+inline void DebugPulse(uint8_t, uint8_t) {}
+#endif
//
// Private methods
@@ -467,13 +469,7 @@ size_t SoftwareSerial::write(uint8_t b)
void SoftwareSerial::flush()
{
- if (!isListening())
- return;
-
- uint8_t oldSREG = SREG;
- cli();
- _receive_buffer_head = _receive_buffer_tail = 0;
- SREG = oldSREG;
+ // There is no tx buffering, simply return
}
int SoftwareSerial::peek()
diff --git a/libraries/SoftwareSerial/SoftwareSerial.h b/libraries/SoftwareSerial/SoftwareSerial.h
index 274f3df..622e2a5 100644
--- a/libraries/SoftwareSerial/SoftwareSerial.h
+++ b/libraries/SoftwareSerial/SoftwareSerial.h
@@ -72,12 +72,11 @@ private:
static SoftwareSerial *active_object;
// private methods
- void recv() __attribute__((__always_inline__));
+ inline void recv() __attribute__((__always_inline__));
uint8_t rx_pin_read();
- void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__));
void setTX(uint8_t transmitPin);
void setRX(uint8_t receivePin);
- void setRxIntMsk(bool enable) __attribute__((__always_inline__));
+ inline void setRxIntMsk(bool enable) __attribute__((__always_inline__));
// Return num - sub, or 1 if the result would be < 1
static uint16_t subtract_cap(uint16_t num, uint16_t sub);
diff --git a/libraries/Wire/keywords.txt b/libraries/Wire/keywords.txt
index ff31475..5e3d2b1 100644
--- a/libraries/Wire/keywords.txt
+++ b/libraries/Wire/keywords.txt
@@ -15,8 +15,6 @@ setClock KEYWORD2
beginTransmission KEYWORD2
endTransmission KEYWORD2
requestFrom KEYWORD2
-send KEYWORD2
-receive KEYWORD2
onReceive KEYWORD2
onRequest KEYWORD2
diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c
index b436e69..2af0597 100644
--- a/libraries/Wire/utility/twi.c
+++ b/libraries/Wire/utility/twi.c
@@ -167,7 +167,9 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen
// up. Also, don't enable the START interrupt. There may be one pending from the
// repeated start that we sent outselves, and that would really confuse things.
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
- TWDR = twi_slarw;
+ do {
+ TWDR = twi_slarw;
+ } while(TWCR & _BV(TWWC));
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
}
else
@@ -247,7 +249,9 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
// up. Also, don't enable the START interrupt. There may be one pending from the
// repeated start that we sent outselves, and that would really confuse things.
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
- TWDR = twi_slarw;
+ do {
+ TWDR = twi_slarw;
+ } while(TWCR & _BV(TWWC));
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
}
else
@@ -476,6 +480,8 @@ ISR(TWI_vect)
}
break;
case TW_SR_STOP: // stop or repeated start condition received
+ // ack future responses and leave slave receiver state
+ twi_releaseBus();
// put a null char after data if there's room
if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
twi_rxBuffer[twi_rxBufferIndex] = '\0';
@@ -484,8 +490,6 @@ ISR(TWI_vect)
twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
// since we submit rx buffer to "wire" library, we can reset it
twi_rxBufferIndex = 0;
- // ack future responses and leave slave receiver state
- twi_releaseBus();
break;
case TW_SR_DATA_NACK: // data received, returned nack
case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
diff --git a/platform.txt b/platform.txt
index b541c16..d7c9b0b 100644
--- a/platform.txt
+++ b/platform.txt
@@ -6,7 +6,7 @@
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
name=Arduino AVR Boards
-version=1.6.8
+version=1.6.9
# AVR compile variables
# ---------------------
@@ -86,7 +86,7 @@ preproc.includes.flags=-w -x c++ -M -MG -MP
recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}"
preproc.macros.flags=-w -x c++ -E -CC
-recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}"
+recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}"
# AVR Uploader/Programmers tools
# ------------------------------
diff --git a/variants/ethernet/pins_arduino.h b/variants/ethernet/pins_arduino.h
index f6773a0..a11ecfc 100644
--- a/variants/ethernet/pins_arduino.h
+++ b/variants/ethernet/pins_arduino.h
@@ -58,6 +58,8 @@ static const uint8_t A7 = 21;
#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))
+#define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))
+
#ifdef ARDUINO_MAIN
// On the Arduino board, digital pins are also used
diff --git a/variants/gemma/pins_arduino.h b/variants/gemma/pins_arduino.h
index 3150b6a..b6aed39 100644
--- a/variants/gemma/pins_arduino.h
+++ b/variants/gemma/pins_arduino.h
@@ -42,7 +42,9 @@
// GND 4| |5 PB0 (D 0) pwm0
// +----+
-#define LED_BUILTIN 1
+#define NUM_DIGITAL_PINS 3
+#define NUM_ANALOG_INPUTS 1
+#define LED_BUILTIN 1
static const uint8_t A0 = 6;
static const uint8_t A1 = 7;
@@ -54,6 +56,8 @@ static const uint8_t A3 = 9;
#define digitalPinToPCMSK(p) ( ((p) <= 4) ? (&PCMSK) : ((uint8_t *)0) )
#define digitalPinToPCMSKbit(p) ( (p) )
+#define digitalPinToInterrupt(p) ((p) == 2 ? 0 : NOT_AN_INTERRUPT)
+
#define analogPinToChannel(p) ( (p) < 6 ? (p) : (p) - 6 )
#define TCCR1A GTCCR
diff --git a/variants/leonardo/pins_arduino.h b/variants/leonardo/pins_arduino.h
index 89b8806..6027223 100644
--- a/variants/leonardo/pins_arduino.h
+++ b/variants/leonardo/pins_arduino.h
@@ -88,7 +88,7 @@
#undef OCR2_6
#undef OCR2_7
-#define NUM_DIGITAL_PINS 30
+#define NUM_DIGITAL_PINS 31
#define NUM_ANALOG_INPUTS 12
#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0)
@@ -100,6 +100,8 @@
static const uint8_t SDA = 2;
static const uint8_t SCL = 3;
#define LED_BUILTIN 13
+#define LED_BUILTIN_RX 17
+#define LED_BUILTIN_TX 30
// Map SPI port to 'new' pins D14..D17
static const uint8_t SS = 17;
@@ -131,6 +133,8 @@ static const uint8_t A11 = 29; // D12
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
+#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13)
+
#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))
#ifdef ARDUINO_MAIN
@@ -171,8 +175,8 @@ extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
// MOSI D16 PB2 MOSI,PCINT2
// SS D17 PB0 RXLED,SS/PCINT0
//
-// TXLED PD5
-// RXLED PB0
+// TXLED D30 PD5 XCK1
+// RXLED D17 PB0
// HWB PE2 HWB
// these arrays map port names (e.g. port B) to the
@@ -243,6 +247,7 @@ const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PB, // D27 / D9 - A9 - PB5
PB, // D28 / D10 - A10 - PB6
PD, // D29 / D12 - A11 - PD6
+ PD, // D30 / TX Led - PD5
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
@@ -280,6 +285,7 @@ const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
_BV(5), // D27 / D9 - A9 - PB5
_BV(6), // D28 / D10 - A10 - PB6
_BV(6), // D29 / D12 - A11 - PD6
+ _BV(5), // D30 / TX Led - PD5
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
@@ -317,6 +323,7 @@ const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
+ NOT_ON_TIMER,
};
const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
@@ -356,4 +363,7 @@ const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1
+// Alias SerialUSB to Serial
+#define SerialUSB SERIAL_PORT_USBVIRTUAL
+
#endif /* Pins_Arduino_h */