Skip to content

Commit 3786e33

Browse files
committed
Pre-merge upstream Arduino
2 parents 324023a + 9a8976c commit 3786e33

File tree

30 files changed

+619
-225
lines changed

30 files changed

+619
-225
lines changed

cores/arduino/Arduino.h

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern "C"{
2020

2121
#define INPUT 0x0
2222
#define OUTPUT 0x1
23+
#define INPUT_PULLUP 0x2
2324

2425
#define true 0x1
2526
#define false 0x0

cores/arduino/HardwareSerial.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
struct ring_buffer
4747
{
4848
unsigned char buffer[SERIAL_BUFFER_SIZE];
49-
volatile int head;
50-
volatile int tail;
49+
volatile unsigned int head;
50+
volatile unsigned int tail;
5151
};
5252

5353
#if defined(USBCON)

cores/arduino/Print.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ size_t Print::write(const uint8_t *buffer, size_t size)
4141

4242
size_t Print::print(const __FlashStringHelper *ifsh)
4343
{
44-
const prog_char *p = (const prog_char *)ifsh;
44+
const char PROGMEM *p = (const char PROGMEM *)ifsh;
4545
size_t n = 0;
4646
while (1) {
4747
unsigned char c = pgm_read_byte(p++);

cores/arduino/Stream.cpp

+11-9
Original file line numberDiff line numberDiff line change
@@ -99,25 +99,27 @@ bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t
9999
size_t index = 0; // maximum target string length is 64k bytes!
100100
size_t termIndex = 0;
101101
int c;
102-
102+
103103
if( *target == 0)
104-
return true; // return true if target is a null string
104+
return true; // return true if target is a null string
105105
while( (c = timedRead()) > 0){
106+
107+
if(c != target[index])
108+
index = 0; // reset index if any char does not match
109+
106110
if( c == target[index]){
107-
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
111+
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
108112
if(++index >= targetLen){ // return true if all chars in the target match
109113
return true;
110114
}
111115
}
112-
else{
113-
index = 0; // reset index if any char does not match
114-
}
116+
115117
if(termLen > 0 && c == terminator[termIndex]){
116-
if(++termIndex >= termLen)
117-
return false; // return false if terminate string found before target string
118+
if(++termIndex >= termLen)
119+
return false; // return false if terminate string found before target string
118120
}
119121
else
120-
termIndex = 0;
122+
termIndex = 0;
121123
}
122124
return false;
123125
}

cores/arduino/WInterrupts.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
#include "wiring_private.h"
3434

35-
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
35+
static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
3636
// volatile static voidFuncPtr twiIntFunc;
3737

3838
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
@@ -121,8 +121,6 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
121121
#elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK)
122122
MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
123123
GIMSK |= (1 << INT2);
124-
#else
125-
#warning attachInterrupt may need some more work for this cpu (case 1)
126124
#endif
127125
break;
128126
#endif

cores/arduino/WString.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ int String::lastIndexOf( char theChar ) const
500500

501501
int String::lastIndexOf(char ch, unsigned int fromIndex) const
502502
{
503-
if (fromIndex >= len || fromIndex < 0) return -1;
503+
if (fromIndex >= len) return -1;
504504
char tempchar = buffer[fromIndex + 1];
505505
buffer[fromIndex + 1] = '\0';
506506
char* temp = strrchr( buffer, ch );
@@ -516,7 +516,7 @@ int String::lastIndexOf(const String &s2) const
516516

517517
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
518518
{
519-
if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
519+
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
520520
if (fromIndex >= len) fromIndex = len - 1;
521521
int found = -1;
522522
for (char *p = buffer; p <= buffer + fromIndex; p++) {

cores/arduino/wiring_analog.c

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ int analogRead(uint8_t pin)
4545
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
4646
#elif defined(__AVR_ATmega32U4__)
4747
if (pin >= 18) pin -= 18; // allow for channel or pin numbers
48+
#elif defined(__AVR_ATmega1284__)
49+
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
4850
#else
4951
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
5052
#endif

cores/arduino/wiring_digital.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,25 @@ void pinMode(uint8_t pin, uint8_t mode)
3232
{
3333
uint8_t bit = digitalPinToBitMask(pin);
3434
uint8_t port = digitalPinToPort(pin);
35-
volatile uint8_t *reg;
35+
volatile uint8_t *reg, *out;
3636

3737
if (port == NOT_A_PIN) return;
3838

3939
// JWS: can I let the optimizer do this?
4040
reg = portModeRegister(port);
41+
out = portOutputRegister(port);
4142

4243
if (mode == INPUT) {
4344
uint8_t oldSREG = SREG;
4445
cli();
4546
*reg &= ~bit;
47+
*out &= ~bit;
48+
SREG = oldSREG;
49+
} else if (mode == INPUT_PULLUP) {
50+
uint8_t oldSREG = SREG;
51+
cli();
52+
*reg &= ~bit;
53+
*out |= bit;
4654
SREG = oldSREG;
4755
} else {
4856
uint8_t oldSREG = SREG;

libraries/Ethernet/Dhcp.cpp

+139-19
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,33 @@
1111

1212
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
1313
{
14-
uint8_t dhcp_state = STATE_DHCP_START;
15-
uint8_t messageType = 0;
16-
17-
// zero out _dhcpMacAddr, _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
18-
memset(_dhcpMacAddr, 0, 26);
14+
_dhcpLeaseTime=0;
15+
_dhcpT1=0;
16+
_dhcpT2=0;
17+
_lastCheck=0;
18+
_timeout = timeout;
19+
_responseTimeout = responseTimeout;
20+
21+
// zero out _dhcpMacAddr
22+
memset(_dhcpMacAddr, 0, 6);
23+
reset_DHCP_lease();
1924

2025
memcpy((void*)_dhcpMacAddr, (void*)mac, 6);
26+
_dhcp_state = STATE_DHCP_START;
27+
return request_DHCP_lease();
28+
}
29+
30+
void DhcpClass::reset_DHCP_lease(){
31+
// zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
32+
memset(_dhcpLocalIp, 0, 20);
33+
}
34+
35+
//return:0 on error, 1 if request is sent and response is received
36+
int DhcpClass::request_DHCP_lease(){
37+
38+
uint8_t messageType = 0;
39+
40+
2141

2242
// Pick an initial transaction ID
2343
_dhcpTransactionId = random(1UL, 2000UL);
@@ -35,55 +55,75 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long
3555

3656
unsigned long startTime = millis();
3757

38-
while(dhcp_state != STATE_DHCP_LEASED)
58+
while(_dhcp_state != STATE_DHCP_LEASED)
3959
{
40-
if(dhcp_state == STATE_DHCP_START)
60+
if(_dhcp_state == STATE_DHCP_START)
4161
{
4262
_dhcpTransactionId++;
4363

4464
send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
45-
dhcp_state = STATE_DHCP_DISCOVER;
65+
_dhcp_state = STATE_DHCP_DISCOVER;
66+
}
67+
else if(_dhcp_state == STATE_DHCP_REREQUEST){
68+
_dhcpTransactionId++;
69+
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
70+
_dhcp_state = STATE_DHCP_REQUEST;
4671
}
47-
else if(dhcp_state == STATE_DHCP_DISCOVER)
72+
else if(_dhcp_state == STATE_DHCP_DISCOVER)
4873
{
4974
uint32_t respId;
50-
messageType = parseDHCPResponse(responseTimeout, respId);
75+
messageType = parseDHCPResponse(_responseTimeout, respId);
5176
if(messageType == DHCP_OFFER)
5277
{
5378
// We'll use the transaction ID that the offer came with,
5479
// rather than the one we were up to
5580
_dhcpTransactionId = respId;
5681
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
57-
dhcp_state = STATE_DHCP_REQUEST;
82+
_dhcp_state = STATE_DHCP_REQUEST;
5883
}
5984
}
60-
else if(dhcp_state == STATE_DHCP_REQUEST)
85+
else if(_dhcp_state == STATE_DHCP_REQUEST)
6186
{
6287
uint32_t respId;
63-
messageType = parseDHCPResponse(responseTimeout, respId);
88+
messageType = parseDHCPResponse(_responseTimeout, respId);
6489
if(messageType == DHCP_ACK)
6590
{
66-
dhcp_state = STATE_DHCP_LEASED;
91+
_dhcp_state = STATE_DHCP_LEASED;
6792
result = 1;
93+
//use default lease time if we didn't get it
94+
if(_dhcpLeaseTime == 0){
95+
_dhcpLeaseTime = DEFAULT_LEASE;
96+
}
97+
//calculate T1 & T2 if we didn't get it
98+
if(_dhcpT1 == 0){
99+
//T1 should be 50% of _dhcpLeaseTime
100+
_dhcpT1 = _dhcpLeaseTime >> 1;
101+
}
102+
if(_dhcpT2 == 0){
103+
//T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
104+
_dhcpT2 = _dhcpT1 << 1;
105+
}
106+
_renewInSec = _dhcpT1;
107+
_rebindInSec = _dhcpT2;
68108
}
69109
else if(messageType == DHCP_NAK)
70-
dhcp_state = STATE_DHCP_START;
110+
_dhcp_state = STATE_DHCP_START;
71111
}
72112

73113
if(messageType == 255)
74114
{
75115
messageType = 0;
76-
dhcp_state = STATE_DHCP_START;
116+
_dhcp_state = STATE_DHCP_START;
77117
}
78118

79-
if(result != 1 && ((millis() - startTime) > timeout))
119+
if(result != 1 && ((millis() - startTime) > _timeout))
80120
break;
81121
}
82122

83123
// We're done with the socket now
84124
_dhcpUdpSocket.stop();
85125
_dhcpTransactionId++;
86-
126+
87127
return result;
88128
}
89129

@@ -302,8 +342,26 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
302342
}
303343
}
304344
break;
305-
345+
346+
case dhcpT1value :
347+
opt_len = _dhcpUdpSocket.read();
348+
_dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));
349+
_dhcpT1 = ntohl(_dhcpT1);
350+
break;
351+
352+
case dhcpT2value :
353+
opt_len = _dhcpUdpSocket.read();
354+
_dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));
355+
_dhcpT2 = ntohl(_dhcpT2);
356+
break;
357+
306358
case dhcpIPaddrLeaseTime :
359+
opt_len = _dhcpUdpSocket.read();
360+
_dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
361+
_dhcpLeaseTime = ntohl(_dhcpLeaseTime);
362+
_renewInSec = _dhcpLeaseTime;
363+
break;
364+
307365
default :
308366
opt_len = _dhcpUdpSocket.read();
309367
// Skip over the rest of this option
@@ -322,6 +380,68 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
322380
return type;
323381
}
324382

383+
384+
/*
385+
returns:
386+
0/DHCP_CHECK_NONE: nothing happened
387+
1/DHCP_CHECK_RENEW_FAIL: renew failed
388+
2/DHCP_CHECK_RENEW_OK: renew success
389+
3/DHCP_CHECK_REBIND_FAIL: rebind fail
390+
4/DHCP_CHECK_REBIND_OK: rebind success
391+
*/
392+
int DhcpClass::checkLease(){
393+
//this uses a signed / unsigned trick to deal with millis overflow
394+
unsigned long now = millis();
395+
signed long snow = (long)now;
396+
int rc=DHCP_CHECK_NONE;
397+
if (_lastCheck != 0){
398+
signed long factor;
399+
//calc how many ms past the timeout we are
400+
factor = snow - (long)_secTimeout;
401+
//if on or passed the timeout, reduce the counters
402+
if ( factor >= 0 ){
403+
//next timeout should be now plus 1000 ms minus parts of second in factor
404+
_secTimeout = snow + 1000 - factor % 1000;
405+
//how many seconds late are we, minimum 1
406+
factor = factor / 1000 +1;
407+
408+
//reduce the counters by that mouch
409+
//if we can assume that the cycle time (factor) is fairly constant
410+
//and if the remainder is less than cycle time * 2
411+
//do it early instead of late
412+
if(_renewInSec < factor*2 )
413+
_renewInSec = 0;
414+
else
415+
_renewInSec -= factor;
416+
417+
if(_rebindInSec < factor*2 )
418+
_rebindInSec = 0;
419+
else
420+
_rebindInSec -= factor;
421+
}
422+
423+
//if we have a lease but should renew, do it
424+
if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
425+
_dhcp_state = STATE_DHCP_REREQUEST;
426+
rc = 1 + request_DHCP_lease();
427+
}
428+
429+
//if we have a lease or is renewing but should bind, do it
430+
if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
431+
//this should basically restart completely
432+
_dhcp_state = STATE_DHCP_START;
433+
reset_DHCP_lease();
434+
rc = 3 + request_DHCP_lease();
435+
}
436+
}
437+
else{
438+
_secTimeout = snow + 1000;
439+
}
440+
441+
_lastCheck = now;
442+
return rc;
443+
}
444+
325445
IPAddress DhcpClass::getLocalIp()
326446
{
327447
return IPAddress(_dhcpLocalIp);

0 commit comments

Comments
 (0)