mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-19 09:42:11 +03:00
Merge 1.6.1 into esp8266
* commit 'b8b2869753d488bfd203615637e1de3912589a92': (68 commits) Updated revisions.txt Fixed wrong path in successful message arduino-core: restored debug info in class files Fixed NPE in case of missing boardData Added missing translations Added windows drivers Added warning for uncertified boards Update revision.txt update revisions.txt SoftwareSerial: match bool API with HardwareSerial Fix to save as to parent folder is needed by all OSs, not just Mac Update revision.txt MacOSX: previous better IDE was missing some pieces. Added MacOSX: better IDE Updated revisions.txt NEW button now behaves as clicking File -> New menu entry. Fixes #2685 Windows: bundled JRE updated to 8u31 build.xml now uses unzip target Added .getParentFile() to saveas for mac. This prevents saving into the sketch itself Compound edits weren't part of the undo/redo dance An undoable action marks the sketh as modified ...
This commit is contained in:
@ -11,6 +11,13 @@ yun.vid.0=0x2341
|
||||
yun.pid.0=0x0041
|
||||
yun.vid.1=0x2341
|
||||
yun.pid.1=0x8041
|
||||
yun.vid.2=0x2A03
|
||||
yun.pid.2=0x0041
|
||||
yun.vid.3=0x2A03
|
||||
yun.pid.3=0x8041
|
||||
|
||||
yun.vid.0x2A03.warning=Uncertified
|
||||
|
||||
yun.upload.tool=avrdude
|
||||
yun.upload.protocol=avr109
|
||||
yun.upload.maximum_size=28672
|
||||
@ -46,6 +53,10 @@ uno.vid.0=0x2341
|
||||
uno.pid.0=0x0043
|
||||
uno.vid.1=0x2341
|
||||
uno.pid.1=0x0001
|
||||
uno.vid.2=0x2A03
|
||||
uno.pid.2=0x0043
|
||||
|
||||
uno.vid.0x2A03.warning=Uncertified
|
||||
|
||||
uno.upload.tool=avrdude
|
||||
uno.upload.protocol=arduino
|
||||
@ -166,6 +177,12 @@ mega.vid.0=0x2341
|
||||
mega.pid.0=0x0010
|
||||
mega.vid.1=0x2341
|
||||
mega.pid.1=0x0042
|
||||
mega.vid.2=0x2A03
|
||||
mega.pid.2=0x0010
|
||||
mega.vid.3=0x2A03
|
||||
mega.pid.3=0x0042
|
||||
|
||||
mega.vid.0x2A03.warning=Uncertified
|
||||
|
||||
mega.upload.tool=avrdude
|
||||
mega.upload.maximum_data_size=8192
|
||||
@ -219,6 +236,12 @@ megaADK.vid.0=0x2341
|
||||
megaADK.pid.0=0x003f
|
||||
megaADK.vid.1=0x2341
|
||||
megaADK.pid.1=0x0044
|
||||
megaADK.vid.2=0x2A03
|
||||
megaADK.pid.2=0x003f
|
||||
megaADK.vid.3=0x2A03
|
||||
megaADK.pid.3=0x0044
|
||||
|
||||
megaADK.vid.0x2A03.warning=Uncertified
|
||||
|
||||
megaADK.upload.tool=avrdude
|
||||
megaADK.upload.protocol=wiring
|
||||
@ -247,6 +270,13 @@ leonardo.vid.0=0x2341
|
||||
leonardo.pid.0=0x0036
|
||||
leonardo.vid.1=0x2341
|
||||
leonardo.pid.1=0x8036
|
||||
leonardo.vid.2=0x2A03
|
||||
leonardo.pid.2=0x0036
|
||||
leonardo.vid.3=0x2A03
|
||||
leonardo.pid.3=0x8036
|
||||
|
||||
leonardo.vid.0x2A03.warning=Uncertified
|
||||
|
||||
leonardo.upload.tool=avrdude
|
||||
leonardo.upload.protocol=avr109
|
||||
leonardo.upload.maximum_size=28672
|
||||
@ -277,6 +307,17 @@ leonardo.build.extra_flags={build.usb_flags}
|
||||
##############################################################
|
||||
|
||||
micro.name=Arduino Micro
|
||||
micro.vid.0=0x2341
|
||||
micro.pid.0=0x0037
|
||||
micro.vid.1=0x2341
|
||||
micro.pid.1=0x8037
|
||||
micro.vid.2=0x2A03
|
||||
micro.pid.2=0x0037
|
||||
micro.vid.3=0x2A03
|
||||
micro.pid.3=0x8037
|
||||
|
||||
micro.vid.0x2A03.warning=Uncertified
|
||||
|
||||
micro.upload.tool=avrdude
|
||||
micro.upload.protocol=avr109
|
||||
micro.upload.maximum_size=28672
|
||||
@ -308,9 +349,16 @@ micro.build.extra_flags={build.usb_flags}
|
||||
|
||||
esplora.name=Arduino Esplora
|
||||
esplora.vid.0=0x2341
|
||||
esplora.pid.0=0x003c
|
||||
esplora.pid.0=0x003C
|
||||
esplora.vid.1=0x2341
|
||||
esplora.pid.1=0x803c
|
||||
esplora.pid.1=0x803C
|
||||
esplora.vid.2=0x2A03
|
||||
esplora.pid.2=0x003C
|
||||
esplora.vid.3=0x2A03
|
||||
esplora.pid.3=0x803C
|
||||
|
||||
esplora.vid.0x2A03.warning=Uncertified
|
||||
|
||||
esplora.upload.tool=avrdude
|
||||
esplora.upload.protocol=avr109
|
||||
esplora.upload.maximum_size=28672
|
||||
@ -477,6 +525,10 @@ bt.menu.cpu.atmega168.build.mcu=atmega168
|
||||
##############################################################
|
||||
|
||||
LilyPadUSB.name=LilyPad Arduino USB
|
||||
LilyPadUSB.vid.0=0x1B4F
|
||||
LilyPadUSB.pid.0=0x9207
|
||||
LilyPadUSB.vid.1=0x1B4F
|
||||
LilyPadUSB.pid.1=0x9208
|
||||
|
||||
LilyPadUSB.upload.tool=avrdude
|
||||
LilyPadUSB.upload.protocol=avr109
|
||||
@ -678,6 +730,17 @@ atmegang.menu.cpu.atmega8.build.mcu=atmega8
|
||||
##############################################################
|
||||
|
||||
robotControl.name=Arduino Robot Control
|
||||
robotControl.vid.0=0x2341
|
||||
robotControl.pid.0=0x0038
|
||||
robotControl.vid.1=0x2341
|
||||
robotControl.pid.1=0x8038
|
||||
robotControl.vid.2=0x2A03
|
||||
robotControl.pid.2=0x0038
|
||||
robotControl.vid.3=0x2A03
|
||||
robotControl.pid.3=0x8038
|
||||
|
||||
robotControl.vid.0x2A03.warning=Uncertified
|
||||
|
||||
robotControl.upload.tool=avrdude
|
||||
robotControl.upload.protocol=avr109
|
||||
robotControl.upload.maximum_size=28672
|
||||
@ -708,6 +771,17 @@ robotControl.build.extra_flags={build.usb_flags}
|
||||
##############################################################
|
||||
|
||||
robotMotor.name=Arduino Robot Motor
|
||||
robotMotor.vid.0=0x2341
|
||||
robotMotor.pid.0=0x0039
|
||||
robotMotor.vid.1=0x2341
|
||||
robotMotor.pid.1=0x8039
|
||||
robotMotor.vid.2=0x2A03
|
||||
robotMotor.pid.2=0x0039
|
||||
robotMotor.vid.3=0x2A03
|
||||
robotMotor.pid.3=0x8039
|
||||
|
||||
robotMotor.vid.0x2A03.warning=Uncertified
|
||||
|
||||
robotMotor.upload.tool=avrdude
|
||||
robotMotor.upload.protocol=avr109
|
||||
robotMotor.upload.maximum_size=28672
|
||||
|
@ -42,92 +42,7 @@ http://arduiniana.org.
|
||||
#include <avr/pgmspace.h>
|
||||
#include <Arduino.h>
|
||||
#include <SoftwareSerial.h>
|
||||
//
|
||||
// Lookup table
|
||||
//
|
||||
typedef struct _DELAY_TABLE
|
||||
{
|
||||
long baud;
|
||||
unsigned short rx_delay_centering;
|
||||
unsigned short rx_delay_intrabit;
|
||||
unsigned short rx_delay_stopbit;
|
||||
unsigned short tx_delay;
|
||||
} DELAY_TABLE;
|
||||
|
||||
#if F_CPU == 16000000
|
||||
|
||||
static const DELAY_TABLE PROGMEM table[] =
|
||||
{
|
||||
// baud rxcenter rxintra rxstop tx
|
||||
{ 115200, 1, 17, 17, 12, },
|
||||
{ 57600, 10, 37, 37, 33, },
|
||||
{ 38400, 25, 57, 57, 54, },
|
||||
{ 31250, 31, 70, 70, 68, },
|
||||
{ 28800, 34, 77, 77, 74, },
|
||||
{ 19200, 54, 117, 117, 114, },
|
||||
{ 14400, 74, 156, 156, 153, },
|
||||
{ 9600, 114, 236, 236, 233, },
|
||||
{ 4800, 233, 474, 474, 471, },
|
||||
{ 2400, 471, 950, 950, 947, },
|
||||
{ 1200, 947, 1902, 1902, 1899, },
|
||||
{ 600, 1902, 3804, 3804, 3800, },
|
||||
{ 300, 3804, 7617, 7617, 7614, },
|
||||
};
|
||||
|
||||
const int XMIT_START_ADJUSTMENT = 5;
|
||||
|
||||
#elif F_CPU == 8000000
|
||||
|
||||
static const DELAY_TABLE table[] PROGMEM =
|
||||
{
|
||||
// baud rxcenter rxintra rxstop tx
|
||||
{ 115200, 1, 5, 5, 3, },
|
||||
{ 57600, 1, 15, 15, 13, },
|
||||
{ 38400, 2, 25, 26, 23, },
|
||||
{ 31250, 7, 32, 33, 29, },
|
||||
{ 28800, 11, 35, 35, 32, },
|
||||
{ 19200, 20, 55, 55, 52, },
|
||||
{ 14400, 30, 75, 75, 72, },
|
||||
{ 9600, 50, 114, 114, 112, },
|
||||
{ 4800, 110, 233, 233, 230, },
|
||||
{ 2400, 229, 472, 472, 469, },
|
||||
{ 1200, 467, 948, 948, 945, },
|
||||
{ 600, 948, 1895, 1895, 1890, },
|
||||
{ 300, 1895, 3805, 3805, 3802, },
|
||||
};
|
||||
|
||||
const int XMIT_START_ADJUSTMENT = 4;
|
||||
|
||||
#elif F_CPU == 20000000
|
||||
|
||||
// 20MHz support courtesy of the good people at macegr.com.
|
||||
// Thanks, Garrett!
|
||||
|
||||
static const DELAY_TABLE PROGMEM table[] =
|
||||
{
|
||||
// baud rxcenter rxintra rxstop tx
|
||||
{ 115200, 3, 21, 21, 18, },
|
||||
{ 57600, 20, 43, 43, 41, },
|
||||
{ 38400, 37, 73, 73, 70, },
|
||||
{ 31250, 45, 89, 89, 88, },
|
||||
{ 28800, 46, 98, 98, 95, },
|
||||
{ 19200, 71, 148, 148, 145, },
|
||||
{ 14400, 96, 197, 197, 194, },
|
||||
{ 9600, 146, 297, 297, 294, },
|
||||
{ 4800, 296, 595, 595, 592, },
|
||||
{ 2400, 592, 1189, 1189, 1186, },
|
||||
{ 1200, 1187, 2379, 2379, 2376, },
|
||||
{ 600, 2379, 4759, 4759, 4755, },
|
||||
{ 300, 4759, 9523, 9523, 9520, },
|
||||
};
|
||||
|
||||
const int XMIT_START_ADJUSTMENT = 6;
|
||||
|
||||
#else
|
||||
|
||||
#error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
|
||||
|
||||
#endif
|
||||
#include <util/delay_basic.h>
|
||||
|
||||
//
|
||||
// Statics
|
||||
@ -162,36 +77,44 @@ inline void DebugPulse(uint8_t pin, uint8_t count)
|
||||
|
||||
/* static */
|
||||
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
|
||||
uint8_t tmp=0;
|
||||
|
||||
asm volatile("sbiw %0, 0x01 \n\t"
|
||||
"ldi %1, 0xFF \n\t"
|
||||
"cpi %A0, 0xFF \n\t"
|
||||
"cpc %B0, %1 \n\t"
|
||||
"brne .-10 \n\t"
|
||||
: "+r" (delay), "+a" (tmp)
|
||||
: "0" (delay)
|
||||
);
|
||||
_delay_loop_2(delay);
|
||||
}
|
||||
|
||||
// This function sets the current object as the "listening"
|
||||
// one and returns true if it replaces another
|
||||
bool SoftwareSerial::listen()
|
||||
{
|
||||
if (!_rx_delay_stopbit)
|
||||
return false;
|
||||
|
||||
if (active_object != this)
|
||||
{
|
||||
if (active_object)
|
||||
active_object->stopListening();
|
||||
|
||||
_buffer_overflow = false;
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
_receive_buffer_head = _receive_buffer_tail = 0;
|
||||
active_object = this;
|
||||
SREG = oldSREG;
|
||||
|
||||
setRxIntMsk(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stop listening. Returns true if we were actually listening.
|
||||
bool SoftwareSerial::stopListening()
|
||||
{
|
||||
if (active_object == this)
|
||||
{
|
||||
setRxIntMsk(false);
|
||||
active_object = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// The receive routine called by the interrupt handler
|
||||
//
|
||||
@ -220,43 +143,49 @@ void SoftwareSerial::recv()
|
||||
// so interrupt is probably not for us
|
||||
if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
|
||||
{
|
||||
// Disable further interrupts during reception, this prevents
|
||||
// triggering another interrupt directly after we return, which can
|
||||
// cause problems at higher baudrates.
|
||||
setRxIntMsk(false);
|
||||
|
||||
// Wait approximately 1/2 of a bit width to "center" the sample
|
||||
tunedDelay(_rx_delay_centering);
|
||||
DebugPulse(_DEBUG_PIN2, 1);
|
||||
|
||||
// Read each of the 8 bits
|
||||
for (uint8_t i=0x1; i; i <<= 1)
|
||||
for (uint8_t i=8; i > 0; --i)
|
||||
{
|
||||
tunedDelay(_rx_delay_intrabit);
|
||||
d >>= 1;
|
||||
DebugPulse(_DEBUG_PIN2, 1);
|
||||
uint8_t noti = ~i;
|
||||
if (rx_pin_read())
|
||||
d |= i;
|
||||
else // else clause added to ensure function timing is ~balanced
|
||||
d &= noti;
|
||||
d |= 0x80;
|
||||
}
|
||||
|
||||
// skip the stop bit
|
||||
tunedDelay(_rx_delay_stopbit);
|
||||
DebugPulse(_DEBUG_PIN2, 1);
|
||||
|
||||
if (_inverse_logic)
|
||||
d = ~d;
|
||||
|
||||
// if buffer full, set the overflow flag and return
|
||||
if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
|
||||
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
|
||||
if (next != _receive_buffer_head)
|
||||
{
|
||||
// save new data in buffer: tail points to where byte goes
|
||||
_receive_buffer[_receive_buffer_tail] = d; // save new byte
|
||||
_receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
|
||||
_receive_buffer_tail = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if _DEBUG // for scope: pulse pin as overflow indictator
|
||||
DebugPulse(_DEBUG_PIN1, 1);
|
||||
#endif
|
||||
_buffer_overflow = true;
|
||||
}
|
||||
|
||||
// skip the stop bit
|
||||
tunedDelay(_rx_delay_stopbit);
|
||||
DebugPulse(_DEBUG_PIN1, 1);
|
||||
|
||||
// Re-enable interrupts when we're sure to be inside the stop bit
|
||||
setRxIntMsk(true);
|
||||
|
||||
}
|
||||
|
||||
#if GCC_VERSION < 40302
|
||||
@ -275,14 +204,6 @@ void SoftwareSerial::recv()
|
||||
#endif
|
||||
}
|
||||
|
||||
void SoftwareSerial::tx_pin_write(uint8_t pin_state)
|
||||
{
|
||||
if (pin_state == LOW)
|
||||
*_transmitPortRegister &= ~_transmitBitMask;
|
||||
else
|
||||
*_transmitPortRegister |= _transmitBitMask;
|
||||
}
|
||||
|
||||
uint8_t SoftwareSerial::rx_pin_read()
|
||||
{
|
||||
return *_receivePortRegister & _receiveBitMask;
|
||||
@ -309,24 +230,15 @@ ISR(PCINT0_vect)
|
||||
#endif
|
||||
|
||||
#if defined(PCINT1_vect)
|
||||
ISR(PCINT1_vect)
|
||||
{
|
||||
SoftwareSerial::handle_interrupt();
|
||||
}
|
||||
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
|
||||
#endif
|
||||
|
||||
#if defined(PCINT2_vect)
|
||||
ISR(PCINT2_vect)
|
||||
{
|
||||
SoftwareSerial::handle_interrupt();
|
||||
}
|
||||
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
|
||||
#endif
|
||||
|
||||
#if defined(PCINT3_vect)
|
||||
ISR(PCINT3_vect)
|
||||
{
|
||||
SoftwareSerial::handle_interrupt();
|
||||
}
|
||||
ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
|
||||
#endif
|
||||
|
||||
//
|
||||
@ -354,8 +266,12 @@ SoftwareSerial::~SoftwareSerial()
|
||||
|
||||
void SoftwareSerial::setTX(uint8_t tx)
|
||||
{
|
||||
pinMode(tx, OUTPUT);
|
||||
// First write, then set output. If we do this the other way around,
|
||||
// the pin would be output low for a short while before switching to
|
||||
// output hihg. Now, it is input with pullup for a short while, which
|
||||
// is fine. With inverse logic, either order is fine.
|
||||
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
|
||||
pinMode(tx, OUTPUT);
|
||||
_transmitBitMask = digitalPinToBitMask(tx);
|
||||
uint8_t port = digitalPinToPort(tx);
|
||||
_transmitPortRegister = portOutputRegister(port);
|
||||
@ -372,6 +288,13 @@ void SoftwareSerial::setRX(uint8_t rx)
|
||||
_receivePortRegister = portInputRegister(port);
|
||||
}
|
||||
|
||||
uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) {
|
||||
if (num > sub)
|
||||
return num - sub;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
@ -380,27 +303,64 @@ void SoftwareSerial::begin(long speed)
|
||||
{
|
||||
_rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
|
||||
|
||||
for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
|
||||
{
|
||||
long baud = pgm_read_dword(&table[i].baud);
|
||||
if (baud == speed)
|
||||
{
|
||||
_rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
|
||||
_rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
|
||||
_rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
|
||||
_tx_delay = pgm_read_word(&table[i].tx_delay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Precalculate the various delays, in number of 4-cycle delays
|
||||
uint16_t bit_delay = (F_CPU / speed) / 4;
|
||||
|
||||
// 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit,
|
||||
// 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits,
|
||||
// 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit
|
||||
// These are all close enough to just use 15 cycles, since the inter-bit
|
||||
// timings are the most critical (deviations stack 8 times)
|
||||
_tx_delay = subtract_cap(bit_delay, 15 / 4);
|
||||
|
||||
// Only setup rx when we have a valid PCINT for this pin
|
||||
if (digitalPinToPCICR(_receivePin)) {
|
||||
#if GCC_VERSION > 40800
|
||||
// Timings counted from gcc 4.8.2 output. This works up to 115200 on
|
||||
// 16Mhz and 57600 on 8Mhz.
|
||||
//
|
||||
// When the start bit occurs, there are 3 or 4 cycles before the
|
||||
// interrupt flag is set, 4 cycles before the PC is set to the right
|
||||
// interrupt vector address and the old PC is pushed on the stack,
|
||||
// and then 75 cycles of instructions (including the RJMP in the
|
||||
// ISR vector table) until the first delay. After the delay, there
|
||||
// are 17 more cycles until the pin value is read (excluding the
|
||||
// delay in the loop).
|
||||
// We want to have a total delay of 1.5 bit time. Inside the loop,
|
||||
// we already wait for 1 bit time - 23 cycles, so here we wait for
|
||||
// 0.5 bit time - (71 + 18 - 22) cycles.
|
||||
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
|
||||
|
||||
// There are 23 cycles in each loop iteration (excluding the delay)
|
||||
_rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
|
||||
|
||||
// There are 37 cycles from the last bit read to the start of
|
||||
// stopbit delay and 11 cycles from the delay until the interrupt
|
||||
// mask is enabled again (which _must_ happen during the stopbit).
|
||||
// This delay aims at 3/4 of a bit time, meaning the end of the
|
||||
// delay will be at 1/4th of the stopbit. This allows some extra
|
||||
// time for ISR cleanup, which makes 115200 baud at 16Mhz work more
|
||||
// reliably
|
||||
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
|
||||
#else // Timings counted from gcc 4.3.2 output
|
||||
// Note that this code is a _lot_ slower, mostly due to bad register
|
||||
// allocation choices of gcc. This works up to 57600 on 16Mhz and
|
||||
// 38400 on 8Mhz.
|
||||
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4);
|
||||
_rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4);
|
||||
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4);
|
||||
#endif
|
||||
|
||||
|
||||
// Enable the PCINT for the entire port here, but never disable it
|
||||
// (others might also need it, so we disable the interrupt by using
|
||||
// the per-pin PCMSK register).
|
||||
*digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
|
||||
// Precalculate the pcint mask register and value, so setRxIntMask
|
||||
// can be used inside the ISR without costing too much time.
|
||||
_pcint_maskreg = digitalPinToPCMSK(_receivePin);
|
||||
_pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin));
|
||||
|
||||
// Set up RX interrupts, but only if we have a valid RX baud rate
|
||||
if (_rx_delay_stopbit)
|
||||
{
|
||||
if (digitalPinToPCICR(_receivePin))
|
||||
{
|
||||
*digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
|
||||
*digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
|
||||
}
|
||||
tunedDelay(_tx_delay); // if we were low this establishes the end
|
||||
}
|
||||
|
||||
@ -412,10 +372,17 @@ void SoftwareSerial::begin(long speed)
|
||||
listen();
|
||||
}
|
||||
|
||||
void SoftwareSerial::setRxIntMsk(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
*_pcint_maskreg |= _pcint_maskvalue;
|
||||
else
|
||||
*_pcint_maskreg &= ~_pcint_maskvalue;
|
||||
}
|
||||
|
||||
void SoftwareSerial::end()
|
||||
{
|
||||
if (digitalPinToPCMSK(_receivePin))
|
||||
*digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
|
||||
stopListening();
|
||||
}
|
||||
|
||||
|
||||
@ -450,42 +417,47 @@ size_t SoftwareSerial::write(uint8_t b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// By declaring these as local variables, the compiler will put them
|
||||
// in registers _before_ disabling interrupts and entering the
|
||||
// critical timing sections below, which makes it a lot easier to
|
||||
// verify the cycle timings
|
||||
volatile uint8_t *reg = _transmitPortRegister;
|
||||
uint8_t reg_mask = _transmitBitMask;
|
||||
uint8_t inv_mask = ~_transmitBitMask;
|
||||
uint8_t oldSREG = SREG;
|
||||
bool inv = _inverse_logic;
|
||||
uint16_t delay = _tx_delay;
|
||||
|
||||
if (inv)
|
||||
b = ~b;
|
||||
|
||||
cli(); // turn off interrupts for a clean txmit
|
||||
|
||||
// Write the start bit
|
||||
tx_pin_write(_inverse_logic ? HIGH : LOW);
|
||||
tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
|
||||
if (inv)
|
||||
*reg |= reg_mask;
|
||||
else
|
||||
*reg &= inv_mask;
|
||||
|
||||
tunedDelay(delay);
|
||||
|
||||
// Write each of the 8 bits
|
||||
if (_inverse_logic)
|
||||
for (uint8_t i = 8; i > 0; --i)
|
||||
{
|
||||
for (byte mask = 0x01; mask; mask <<= 1)
|
||||
{
|
||||
if (b & mask) // choose bit
|
||||
tx_pin_write(LOW); // send 1
|
||||
else
|
||||
tx_pin_write(HIGH); // send 0
|
||||
|
||||
tunedDelay(_tx_delay);
|
||||
}
|
||||
if (b & 1) // choose bit
|
||||
*reg |= reg_mask; // send 1
|
||||
else
|
||||
*reg &= inv_mask; // send 0
|
||||
|
||||
tx_pin_write(LOW); // restore pin to natural state
|
||||
tunedDelay(delay);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
// restore pin to natural state
|
||||
if (inv)
|
||||
*reg &= inv_mask;
|
||||
else
|
||||
{
|
||||
for (byte mask = 0x01; mask; mask <<= 1)
|
||||
{
|
||||
if (b & mask) // choose bit
|
||||
tx_pin_write(HIGH); // send 1
|
||||
else
|
||||
tx_pin_write(LOW); // send 0
|
||||
|
||||
tunedDelay(_tx_delay);
|
||||
}
|
||||
|
||||
tx_pin_write(HIGH); // restore pin to natural state
|
||||
}
|
||||
*reg |= reg_mask;
|
||||
|
||||
SREG = oldSREG; // turn interrupts back on
|
||||
tunedDelay(_tx_delay);
|
||||
|
@ -53,7 +53,10 @@ private:
|
||||
volatile uint8_t *_receivePortRegister;
|
||||
uint8_t _transmitBitMask;
|
||||
volatile uint8_t *_transmitPortRegister;
|
||||
volatile uint8_t *_pcint_maskreg;
|
||||
uint8_t _pcint_maskvalue;
|
||||
|
||||
// Expressed as 4-cycle delays (must never be 0!)
|
||||
uint16_t _rx_delay_centering;
|
||||
uint16_t _rx_delay_intrabit;
|
||||
uint16_t _rx_delay_stopbit;
|
||||
@ -69,11 +72,15 @@ private:
|
||||
static SoftwareSerial *active_object;
|
||||
|
||||
// private methods
|
||||
void recv();
|
||||
void recv() __attribute__((__always_inline__));
|
||||
uint8_t rx_pin_read();
|
||||
void tx_pin_write(uint8_t pin_state);
|
||||
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__));
|
||||
|
||||
// Return num - sub, or 1 if the result would be < 1
|
||||
static uint16_t subtract_cap(uint16_t num, uint16_t sub);
|
||||
|
||||
// private static method for timing
|
||||
static inline void tunedDelay(uint16_t delay);
|
||||
@ -86,18 +93,20 @@ public:
|
||||
bool listen();
|
||||
void end();
|
||||
bool isListening() { return this == active_object; }
|
||||
bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
|
||||
bool stopListening();
|
||||
bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; }
|
||||
int peek();
|
||||
|
||||
virtual size_t write(uint8_t byte);
|
||||
virtual int read();
|
||||
virtual int available();
|
||||
virtual void flush();
|
||||
operator bool() { return true; }
|
||||
|
||||
using Print::write;
|
||||
|
||||
// public only for easy access by interrupt handlers
|
||||
static inline void handle_interrupt();
|
||||
static inline void handle_interrupt() __attribute__((__always_inline__));
|
||||
};
|
||||
|
||||
// Arduino 0012 workaround
|
||||
|
@ -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.0
|
||||
version=1.6.1
|
||||
|
||||
# AVR compile variables
|
||||
# ---------------------
|
||||
@ -61,10 +61,8 @@ recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compil
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
|
||||
|
||||
## Create eeprom
|
||||
## Create output files (.eep and .hex)
|
||||
recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"
|
||||
|
||||
## Create hex
|
||||
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
|
||||
|
||||
## Compute size
|
||||
@ -100,5 +98,5 @@ tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verb
|
||||
# USB Default Flags
|
||||
# Default blank usb manufacturer will be filled it at compile time
|
||||
# - from numeric vendor ID, set to Unknown otherwise
|
||||
build.usb_manufacturer=
|
||||
build.usb_manufacturer="Unknown"
|
||||
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
|
||||
|
@ -2,6 +2,9 @@
|
||||
arduino_due_x_dbg.name=Arduino Due (Programming Port)
|
||||
arduino_due_x_dbg.vid.0=0x2341
|
||||
arduino_due_x_dbg.pid.0=0x003d
|
||||
arduino_due_x_dbg.vid.1=0x2A03
|
||||
arduino_due_x_dbg.pid.1=0x003d
|
||||
arduino_due_x_dbg.vid.0x2A03.warning=Uncertified
|
||||
arduino_due_x_dbg.upload.tool=bossac
|
||||
arduino_due_x_dbg.upload.protocol=sam-ba
|
||||
arduino_due_x_dbg.upload.maximum_size=524288
|
||||
@ -23,6 +26,9 @@ arduino_due_x_dbg.build.pid=0x003e
|
||||
arduino_due_x.name=Arduino Due (Native USB Port)
|
||||
arduino_due_x.vid.0=0x2341
|
||||
arduino_due_x.pid.0=0x003e
|
||||
arduino_due_x.vid.1=0x2A03
|
||||
arduino_due_x.pid.1=0x003e
|
||||
arduino_due_x.vid.0x2A03.warning=Uncertified
|
||||
arduino_due_x.upload.tool=bossac
|
||||
arduino_due_x.upload.protocol=sam-ba
|
||||
arduino_due_x.upload.maximum_size=524288
|
||||
|
@ -5,7 +5,7 @@
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=Arduino ARM (32-bits) Boards
|
||||
version=1.6.0
|
||||
version=1.6.1
|
||||
|
||||
# SAM3 compile variables
|
||||
# ----------------------
|
||||
@ -65,11 +65,8 @@ recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compil
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls_sam3.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -lm -gcc
|
||||
|
||||
## Create eeprom
|
||||
recipe.objcopy.eep.pattern=
|
||||
|
||||
## Create hex
|
||||
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
|
||||
## Create output (.bin file)
|
||||
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
|
||||
|
||||
## Compute size
|
||||
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
|
||||
|
Reference in New Issue
Block a user