aboutsummaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'libraries')
-rw-r--r--libraries/EEPROM/examples/eeprom_read/eeprom_read.ino4
-rwxr-xr-xlibraries/Ethernet/Dhcp.cpp158
-rwxr-xr-xlibraries/Ethernet/Dhcp.h19
-rw-r--r--libraries/Ethernet/Ethernet.cpp38
-rw-r--r--libraries/Ethernet/Ethernet.h3
-rw-r--r--libraries/Ethernet/EthernetClient.cpp2
-rw-r--r--libraries/Ethernet/EthernetUdp.cpp73
-rw-r--r--libraries/Ethernet/EthernetUdp.h1
-rw-r--r--libraries/Ethernet/examples/ChatServer/ChatServer.ino44
-rw-r--r--libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino8
-rw-r--r--libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino9
-rw-r--r--libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino9
-rw-r--r--libraries/Ethernet/examples/PachubeClient/PachubeClient.ino83
-rw-r--r--libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino87
-rw-r--r--libraries/Ethernet/examples/TelnetClient/TelnetClient.ino8
-rw-r--r--libraries/Ethernet/examples/TwitterClient/TwitterClient.ino21
-rw-r--r--libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino7
-rw-r--r--libraries/Ethernet/examples/WebClient/WebClient.ino7
-rw-r--r--libraries/Ethernet/examples/WebServer/WebServer.ino37
-rwxr-xr-xlibraries/Ethernet/utility/w5100.h6
-rw-r--r--libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino3
-rw-r--r--libraries/LiquidCrystal/examples/Blink/Blink.ino2
-rw-r--r--libraries/LiquidCrystal/examples/Cursor/Cursor.ino3
-rw-r--r--libraries/LiquidCrystal/examples/Display/Display.ino3
-rw-r--r--libraries/LiquidCrystal/examples/Scroll/Scroll.ino3
-rw-r--r--libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino2
-rw-r--r--libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino3
-rw-r--r--libraries/LiquidCrystal/examples/setCursor/setCursor.ino3
-rw-r--r--libraries/SD/examples/CardInfo/CardInfo.ino8
-rw-r--r--libraries/SD/examples/Datalogger/Datalogger.ino8
-rw-r--r--libraries/SD/examples/DumpFile/DumpFile.ino9
-rw-r--r--libraries/SD/examples/Files/Files.ino8
-rw-r--r--libraries/SD/examples/ReadWrite/ReadWrite.ino8
-rw-r--r--libraries/SD/examples/listfiles/listfiles.ino8
-rw-r--r--libraries/SD/utility/SdFatUtil.h2
-rwxr-xr-xlibraries/Servo/Servo.cpp4
-rw-r--r--libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino26
-rw-r--r--libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino7
-rw-r--r--libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino5
-rwxr-xr-xlibraries/Wire/Wire.cpp43
-rwxr-xr-xlibraries/Wire/Wire.h5
-rw-r--r--libraries/Wire/utility/twi.c75
-rwxr-xr-xlibraries/Wire/utility/twi.h4
43 files changed, 687 insertions, 179 deletions
diff --git a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
index 88e3488..0709b2d 100644
--- a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
+++ b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
@@ -14,7 +14,11 @@ byte value;
void setup()
{
+ // initialize serial and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
}
void loop()
diff --git a/libraries/Ethernet/Dhcp.cpp b/libraries/Ethernet/Dhcp.cpp
index 62bbfeb..e4d27f7 100755
--- a/libraries/Ethernet/Dhcp.cpp
+++ b/libraries/Ethernet/Dhcp.cpp
@@ -11,13 +11,33 @@
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
{
- uint8_t dhcp_state = STATE_DHCP_START;
- uint8_t messageType = 0;
-
- // zero out _dhcpMacAddr, _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
- memset(_dhcpMacAddr, 0, 26);
+ _dhcpLeaseTime=0;
+ _dhcpT1=0;
+ _dhcpT2=0;
+ _lastCheck=0;
+ _timeout = timeout;
+ _responseTimeout = responseTimeout;
+
+ // zero out _dhcpMacAddr
+ memset(_dhcpMacAddr, 0, 6);
+ reset_DHCP_lease();
memcpy((void*)_dhcpMacAddr, (void*)mac, 6);
+ _dhcp_state = STATE_DHCP_START;
+ return request_DHCP_lease();
+}
+
+void DhcpClass::reset_DHCP_lease(){
+ // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
+ memset(_dhcpLocalIp, 0, 20);
+}
+
+//return:0 on error, 1 if request is sent and response is received
+int DhcpClass::request_DHCP_lease(){
+
+ uint8_t messageType = 0;
+
+
// Pick an initial transaction ID
_dhcpTransactionId = random(1UL, 2000UL);
@@ -35,55 +55,75 @@ int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long
unsigned long startTime = millis();
- while(dhcp_state != STATE_DHCP_LEASED)
+ while(_dhcp_state != STATE_DHCP_LEASED)
{
- if(dhcp_state == STATE_DHCP_START)
+ if(_dhcp_state == STATE_DHCP_START)
{
_dhcpTransactionId++;
send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
- dhcp_state = STATE_DHCP_DISCOVER;
+ _dhcp_state = STATE_DHCP_DISCOVER;
+ }
+ else if(_dhcp_state == STATE_DHCP_REREQUEST){
+ _dhcpTransactionId++;
+ send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
+ _dhcp_state = STATE_DHCP_REQUEST;
}
- else if(dhcp_state == STATE_DHCP_DISCOVER)
+ else if(_dhcp_state == STATE_DHCP_DISCOVER)
{
uint32_t respId;
- messageType = parseDHCPResponse(responseTimeout, respId);
+ messageType = parseDHCPResponse(_responseTimeout, respId);
if(messageType == DHCP_OFFER)
{
// We'll use the transaction ID that the offer came with,
// rather than the one we were up to
_dhcpTransactionId = respId;
send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
- dhcp_state = STATE_DHCP_REQUEST;
+ _dhcp_state = STATE_DHCP_REQUEST;
}
}
- else if(dhcp_state == STATE_DHCP_REQUEST)
+ else if(_dhcp_state == STATE_DHCP_REQUEST)
{
uint32_t respId;
- messageType = parseDHCPResponse(responseTimeout, respId);
+ messageType = parseDHCPResponse(_responseTimeout, respId);
if(messageType == DHCP_ACK)
{
- dhcp_state = STATE_DHCP_LEASED;
+ _dhcp_state = STATE_DHCP_LEASED;
result = 1;
+ //use default lease time if we didn't get it
+ if(_dhcpLeaseTime == 0){
+ _dhcpLeaseTime = DEFAULT_LEASE;
+ }
+ //calculate T1 & T2 if we didn't get it
+ if(_dhcpT1 == 0){
+ //T1 should be 50% of _dhcpLeaseTime
+ _dhcpT1 = _dhcpLeaseTime >> 1;
+ }
+ if(_dhcpT2 == 0){
+ //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
+ _dhcpT2 = _dhcpT1 << 1;
+ }
+ _renewInSec = _dhcpT1;
+ _rebindInSec = _dhcpT2;
}
else if(messageType == DHCP_NAK)
- dhcp_state = STATE_DHCP_START;
+ _dhcp_state = STATE_DHCP_START;
}
if(messageType == 255)
{
messageType = 0;
- dhcp_state = STATE_DHCP_START;
+ _dhcp_state = STATE_DHCP_START;
}
- if(result != 1 && ((millis() - startTime) > timeout))
+ if(result != 1 && ((millis() - startTime) > _timeout))
break;
}
// We're done with the socket now
_dhcpUdpSocket.stop();
_dhcpTransactionId++;
-
+
return result;
}
@@ -302,8 +342,26 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
}
}
break;
-
+
+ case dhcpT1value :
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));
+ _dhcpT1 = ntohl(_dhcpT1);
+ break;
+
+ case dhcpT2value :
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));
+ _dhcpT2 = ntohl(_dhcpT2);
+ break;
+
case dhcpIPaddrLeaseTime :
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
+ _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
+ _renewInSec = _dhcpLeaseTime;
+ break;
+
default :
opt_len = _dhcpUdpSocket.read();
// Skip over the rest of this option
@@ -322,6 +380,68 @@ uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& tr
return type;
}
+
+/*
+ returns:
+ 0/DHCP_CHECK_NONE: nothing happened
+ 1/DHCP_CHECK_RENEW_FAIL: renew failed
+ 2/DHCP_CHECK_RENEW_OK: renew success
+ 3/DHCP_CHECK_REBIND_FAIL: rebind fail
+ 4/DHCP_CHECK_REBIND_OK: rebind success
+*/
+int DhcpClass::checkLease(){
+ //this uses a signed / unsigned trick to deal with millis overflow
+ unsigned long now = millis();
+ signed long snow = (long)now;
+ int rc=DHCP_CHECK_NONE;
+ if (_lastCheck != 0){
+ signed long factor;
+ //calc how many ms past the timeout we are
+ factor = snow - (long)_secTimeout;
+ //if on or passed the timeout, reduce the counters
+ if ( factor >= 0 ){
+ //next timeout should be now plus 1000 ms minus parts of second in factor
+ _secTimeout = snow + 1000 - factor % 1000;
+ //how many seconds late are we, minimum 1
+ factor = factor / 1000 +1;
+
+ //reduce the counters by that mouch
+ //if we can assume that the cycle time (factor) is fairly constant
+ //and if the remainder is less than cycle time * 2
+ //do it early instead of late
+ if(_renewInSec < factor*2 )
+ _renewInSec = 0;
+ else
+ _renewInSec -= factor;
+
+ if(_rebindInSec < factor*2 )
+ _rebindInSec = 0;
+ else
+ _rebindInSec -= factor;
+ }
+
+ //if we have a lease but should renew, do it
+ if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
+ _dhcp_state = STATE_DHCP_REREQUEST;
+ rc = 1 + request_DHCP_lease();
+ }
+
+ //if we have a lease or is renewing but should bind, do it
+ if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
+ //this should basically restart completely
+ _dhcp_state = STATE_DHCP_START;
+ reset_DHCP_lease();
+ rc = 3 + request_DHCP_lease();
+ }
+ }
+ else{
+ _secTimeout = snow + 1000;
+ }
+
+ _lastCheck = now;
+ return rc;
+}
+
IPAddress DhcpClass::getLocalIp()
{
return IPAddress(_dhcpLocalIp);
diff --git a/libraries/Ethernet/Dhcp.h b/libraries/Ethernet/Dhcp.h
index 149876d..4a47936 100755
--- a/libraries/Ethernet/Dhcp.h
+++ b/libraries/Ethernet/Dhcp.h
@@ -45,6 +45,13 @@
#define MAX_DHCP_OPT 16
#define HOST_NAME "WIZnet"
+#define DEFAULT_LEASE (900) //default lease time in seconds
+
+#define DHCP_CHECK_NONE (0)
+#define DHCP_CHECK_RENEW_FAIL (1)
+#define DHCP_CHECK_RENEW_OK (2)
+#define DHCP_CHECK_REBIND_FAIL (3)
+#define DHCP_CHECK_REBIND_OK (4)
enum
{
@@ -139,8 +146,19 @@ private:
uint8_t _dhcpGatewayIp[4];
uint8_t _dhcpDhcpServerIp[4];
uint8_t _dhcpDnsServerIp[4];
+ uint32_t _dhcpLeaseTime;
+ uint32_t _dhcpT1, _dhcpT2;
+ signed long _renewInSec;
+ signed long _rebindInSec;
+ signed long _lastCheck;
+ unsigned long _timeout;
+ unsigned long _responseTimeout;
+ unsigned long _secTimeout;
+ uint8_t _dhcp_state;
EthernetUDP _dhcpUdpSocket;
+ int request_DHCP_lease();
+ void reset_DHCP_lease();
void presend_DHCP();
void send_DHCP_MESSAGE(uint8_t, uint16_t);
void printByte(char *, uint8_t);
@@ -154,6 +172,7 @@ public:
IPAddress getDnsServerIp();
int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);
+ int checkLease();
};
#endif
diff --git a/libraries/Ethernet/Ethernet.cpp b/libraries/Ethernet/Ethernet.cpp
index c298f3d..5d28f71 100644
--- a/libraries/Ethernet/Ethernet.cpp
+++ b/libraries/Ethernet/Ethernet.cpp
@@ -10,7 +10,8 @@ uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
int EthernetClass::begin(uint8_t *mac_address)
{
- DhcpClass dhcp;
+ _dhcp = new DhcpClass();
+
// Initialise the basic info
W5100.init();
@@ -18,15 +19,15 @@ int EthernetClass::begin(uint8_t *mac_address)
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
// Now try to get our config info from a DHCP server
- int ret = dhcp.beginWithDHCP(mac_address);
+ int ret = _dhcp->beginWithDHCP(mac_address);
if(ret == 1)
{
// We've successfully found a DHCP server and got our configuration info, so set things
// accordingly
- W5100.setIPAddress(dhcp.getLocalIp().raw_address());
- W5100.setGatewayIp(dhcp.getGatewayIp().raw_address());
- W5100.setSubnetMask(dhcp.getSubnetMask().raw_address());
- _dnsServerAddress = dhcp.getDnsServerIp();
+ W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
+ W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
+ W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
+ _dnsServerAddress = _dhcp->getDnsServerIp();
}
return ret;
@@ -66,6 +67,31 @@ void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server
_dnsServerAddress = dns_server;
}
+int EthernetClass::maintain(){
+ int rc = DHCP_CHECK_NONE;
+ if(_dhcp != NULL){
+ //we have a pointer to dhcp, use it
+ rc = _dhcp->checkLease();
+ switch ( rc ){
+ case DHCP_CHECK_NONE:
+ //nothing done
+ break;
+ case DHCP_CHECK_RENEW_OK:
+ case DHCP_CHECK_REBIND_OK:
+ //we might have got a new IP.
+ W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
+ W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
+ W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
+ _dnsServerAddress = _dhcp->getDnsServerIp();
+ break;
+ default:
+ //this is actually a error, it will retry though
+ break;
+ }
+ }
+ return rc;
+}
+
IPAddress EthernetClass::localIP()
{
IPAddress ret;
diff --git a/libraries/Ethernet/Ethernet.h b/libraries/Ethernet/Ethernet.h
index c916dda..2a07ff3 100644
--- a/libraries/Ethernet/Ethernet.h
+++ b/libraries/Ethernet/Ethernet.h
@@ -6,12 +6,14 @@
#include "IPAddress.h"
#include "EthernetClient.h"
#include "EthernetServer.h"
+#include "Dhcp.h"
#define MAX_SOCK_NUM 4
class EthernetClass {
private:
IPAddress _dnsServerAddress;
+ DhcpClass* _dhcp;
public:
static uint8_t _state[MAX_SOCK_NUM];
static uint16_t _server_port[MAX_SOCK_NUM];
@@ -23,6 +25,7 @@ public:
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
+ int maintain();
IPAddress localIP();
IPAddress subnetMask();
diff --git a/libraries/Ethernet/EthernetClient.cpp b/libraries/Ethernet/EthernetClient.cpp
index a77a62b..9885efb 100644
--- a/libraries/Ethernet/EthernetClient.cpp
+++ b/libraries/Ethernet/EthernetClient.cpp
@@ -41,7 +41,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i);
- if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
+ if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
_sock = i;
break;
}
diff --git a/libraries/Ethernet/EthernetUdp.cpp b/libraries/Ethernet/EthernetUdp.cpp
index 9c752fc..3760052 100644
--- a/libraries/Ethernet/EthernetUdp.cpp
+++ b/libraries/Ethernet/EthernetUdp.cpp
@@ -52,15 +52,16 @@ uint8_t EthernetUDP::begin(uint16_t port) {
return 0;
_port = port;
+ _remaining = 0;
socket(_sock, SnMR::UDP, _port, 0);
return 1;
}
-/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
- * returned value includes 8 byte UDP header!*/
+/* return number of bytes available in the current packet,
+ will return zero if parsePacket hasn't been called yet */
int EthernetUDP::available() {
- return W5100.getRXReceivedSize(_sock);
+ return _remaining;
}
/* Release any resources being used by this EthernetUDP instance */
@@ -116,11 +117,14 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
int EthernetUDP::parsePacket()
{
- if (available() > 0)
+ // discard any remaining bytes in the last packet
+ flush();
+
+ if (W5100.getRXReceivedSize(_sock) > 0)
{
//HACK - hand-parse the UDP packet using TCP recv method
uint8_t tmpBuf[8];
- int ret =0;
+ int ret =0;
//read 8 header bytes and get IP and port from it
ret = recv(_sock,tmpBuf,8);
if (ret > 0)
@@ -128,8 +132,11 @@ int EthernetUDP::parsePacket()
_remoteIP = tmpBuf;
_remotePort = tmpBuf[4];
_remotePort = (_remotePort << 8) + tmpBuf[5];
+ _remaining = tmpBuf[6];
+ _remaining = (_remaining << 8) + tmpBuf[7];
+
// When we get here, any remaining bytes are the data
- ret = available();
+ ret = _remaining;
}
return ret;
}
@@ -140,34 +147,58 @@ int EthernetUDP::parsePacket()
int EthernetUDP::read()
{
uint8_t byte;
- if (recv(_sock, &byte, 1) > 0)
+
+ if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
{
// We read things without any problems
+ _remaining--;
return byte;
}
+
// If we get here, there's no data available
return -1;
}
int EthernetUDP::read(unsigned char* buffer, size_t len)
{
- /* In the readPacket that copes with truncating packets, the buffer was
- filled with this code. Not sure why it loops round reading out a byte
- at a time.
- int i;
- for(i=0;i<(int)bufLen;i++) {
- recv(_sock,tmpBuf,1);
- buf[i]=tmpBuf[0];
+
+ if (_remaining > 0)
+ {
+
+ int got;
+
+ if (_remaining <= len)
+ {
+ // data should fit in the buffer
+ got = recv(_sock, buffer, _remaining);
+ }
+ else
+ {
+ // too much data for the buffer,
+ // grab as much as will fit
+ got = recv(_sock, buffer, len);
+ }
+
+ if (got > 0)
+ {
+ _remaining -= got;
+ return got;
+ }
+
}
- */
- return recv(_sock, buffer, len);
+
+ // If we get here, there's no data available or recv failed
+ return -1;
+
}
int EthernetUDP::peek()
{
uint8_t b;
- // Unlike recv, peek doesn't check to see if there's any data available, so we must
- if (!available())
+ // Unlike recv, peek doesn't check to see if there's any data available, so we must.
+ // If the user hasn't called parsePacket yet then return nothing otherwise they
+ // may get the UDP header
+ if (!_remaining)
return -1;
::peek(_sock, &b);
return b;
@@ -175,7 +206,11 @@ int EthernetUDP::peek()
void EthernetUDP::flush()
{
- while (available())
+ // could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
+ // should only occur if recv fails after telling us the data is there, lets
+ // hope the w5100 always behaves :)
+
+ while (_remaining)
{
read();
}
diff --git a/libraries/Ethernet/EthernetUdp.h b/libraries/Ethernet/EthernetUdp.h
index 9a2b653..8a6b7ab 100644
--- a/libraries/Ethernet/EthernetUdp.h
+++ b/libraries/Ethernet/EthernetUdp.h
@@ -48,6 +48,7 @@ private:
IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
uint16_t _offset; // offset into the packet being sent
+ uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
public:
EthernetUDP(); // Constructor
diff --git a/libraries/Ethernet/examples/ChatServer/ChatServer.ino b/libraries/Ethernet/examples/ChatServer/ChatServer.ino
index 9f819fd..d50e5a6 100644
--- a/libraries/Ethernet/examples/ChatServer/ChatServer.ino
+++ b/libraries/Ethernet/examples/ChatServer/ChatServer.ino
@@ -12,7 +12,7 @@
created 18 Dec 2009
by David A. Mellis
- modified 10 August 2010
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -23,41 +23,57 @@
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
-byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte mac[] = {
+ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 177);
IPAddress gateway(192,168,1, 1);
IPAddress subnet(255, 255, 0, 0);
+
// telnet defaults to port 23
EthernetServer server(23);
-boolean gotAMessage = false; // whether or not you got a message from the client yet
+boolean alreadyConnected = false; // whether or not the client was connected previously
void setup() {
// initialize the ethernet device
Ethernet.begin(mac, ip, gateway, subnet);
// start listening for clients
server.begin();
- // open the serial port
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
+ Serial.print("Chat server address:");
+ Serial.println(Ethernet.localIP());
}
void loop() {
// wait for a new client:
EthernetClient client = server.available();
-
+
// when the client sends the first byte, say hello:
if (client) {
- if (!gotAMessage) {
+ if (!alreadyConnected) {
+ // clead out the input buffer:
+ client.flush();
Serial.println("We have a new client");
client.println("Hello, client!");
- gotAMessage = true;
+ alreadyConnected = true;
+ }
+
+ if (client.available() > 0) {
+ // read the bytes incoming from the client:
+ char thisChar = client.read();
+ // echo the bytes back to the client:
+ server.write(thisChar);
+ // echo the bytes to the server as well:
+ Serial.write(thisChar);
}
-
- // read the bytes incoming from the client:
- char thisChar = client.read();
- // echo the bytes back to the client:
- server.write(thisChar);
- // echo the bytes to the server as well:
- Serial.print(thisChar);
}
}
+
+
+
diff --git a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino
index 630dd17..5eaaf24 100644
--- a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino
+++ b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino
@@ -9,6 +9,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 12 April 2011
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -27,8 +28,13 @@ byte mac[] = {
EthernetClient client;
void setup() {
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ // this check is only needed on the Leonardo:
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
diff --git a/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino
index 5082054..09cbd43 100644
--- a/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino
+++ b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino
@@ -12,6 +12,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 21 May 2011
+ modified 9 Apr 2012
by Tom Igoe
Based on ChatServer example by David A. Mellis
@@ -34,8 +35,14 @@ EthernetServer server(23);
boolean gotAMessage = false; // whether or not you got a message from the client yet
void setup() {
- // open the serial port
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ // this check is only needed on the Leonardo:
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// start the Ethernet connection:
Serial.println("Trying to get an IP address using DHCP");
if (Ethernet.begin(mac) == 0) {
diff --git a/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino b/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino
index 5c7a53a..c14abf4 100644
--- a/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino
+++ b/libraries/Ethernet/examples/DnsWebClient/DnsWebClient.ino
@@ -9,7 +9,7 @@
created 18 Dec 2009
by David A. Mellis
- modified 12 April 2011
+ modified 9 Apr 2012
by Tom Igoe, based on work by Adrian McEwen
*/
@@ -28,8 +28,13 @@ char serverName[] = "www.google.com";
EthernetClient client;
void setup() {
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
diff --git a/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino b/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino
index a169443..dfd2d40 100644
--- a/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino
+++ b/libraries/Ethernet/examples/PachubeClient/PachubeClient.ino
@@ -6,15 +6,20 @@
the Adafruit Ethernet shield, either one will work, as long as it's got
a Wiznet Ethernet module on board.
+ This example has been updated to use version 2.0 of the Pachube.com API.
+ To make it work, create a feed with a datastream, and give it the ID
+ sensor1. Or change the code below to match your feed.
+
+
Circuit:
* Analog sensor attached to analog in 0
* Ethernet shield attached to pins 10, 11, 12, 13
created 15 March 2010
- updated 26 Oct 2011
- by Tom Igoe
+ modified 9 Apr 2012
+ by Tom Igoe with input from Usman Haque and Joe Saavedra
- http://www.tigoe.net/pcomp/code/category/arduinowiring/873
+http://arduino.cc/en/Tutorial/PachubeClient
This code is in the public domain.
*/
@@ -22,6 +27,10 @@
#include <SPI.h>
#include <Ethernet.h>
+#define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here
+#define FEEDID 00000 // replace your feed ID
+#define USERAGENT "My Project" // user agent is the project name
+
// assign a MAC address for the ethernet controller.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// fill in your address here:
@@ -34,26 +43,27 @@ IPAddress ip(10,0,1,20);
// initialize the library instance:
EthernetClient client;
-long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
-boolean lastConnected = false; // state of the connection last time through the main loop
-const int postingInterval = 10000; //delay between updates to Pachube.com
+// if you don't want to use DNS (and reduce your sketch size)
+// use the numeric IP instead of the name for the server:
+IPAddress server(216,52,233,122); // numeric IP for api.pachube.com
+//char server[] = "api.pachube.com"; // name address for pachube API
+
+unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
+boolean lastConnected = false; // state of the connection last time through the main loop
+const unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com
void setup() {
- // start serial port:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
- // start the Ethernet connection:
- if (Ethernet.begin(mac) == 0) {
- Serial.println("Failed to configure Ethernet using DHCP");
- // no point in carrying on, so do nothing forevermore:
- for(;;)
- ;
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
}
- // give the ethernet module time to boot up:
- delay(1000);
- // start the Ethernet connection:
+
+
+ // start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
- // Configure manually:
+ // DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}
@@ -91,34 +101,43 @@ void loop() {
// this method makes a HTTP connection to the server:
void sendData(int thisData) {
// if there's a successful connection:
- if (client.connect("www.pachube.com", 80)) {
+ if (client.connect(server, 80)) {
Serial.println("connecting...");
- // send the HTTP PUT request.
- // fill in your feed address here:
- client.print("PUT /api/YOUR_FEED_HERE.csv HTTP/1.1\n");
- client.print("Host: www.pachube.com\n");
- // fill in your Pachube API key here:
- client.print("X-PachubeApiKey: YOUR_KEY_HERE\n");
+ // send the HTTP PUT request:
+ client.print("PUT /v2/feeds/");
+ client.print(FEEDID);
+ client.println(".csv HTTP/1.1");
+ client.println("Host: api.pachube.com");
+ client.print("X-PachubeApiKey: ");
+ client.println(APIKEY);
+ client.print("User-Agent: ");
+ client.println(USERAGENT);
client.print("Content-Length: ");
// calculate the length of the sensor reading in bytes:
- int thisLength = getLength(thisData);
- client.println(thisLength, DEC);
+ // 8 bytes for "sensor1," + number of digits of the data:
+ int thisLength = 8 + getLength(thisData);
+ client.println(thisLength);
// last pieces of the HTTP PUT request:
- client.print("Content-Type: text/csv\n");
- client.println("Connection: close\n");
+ client.println("Content-Type: text/csv");
+ client.println("Connection: close");
+ client.println();
// here's the actual content of the PUT request:
- client.println(thisData, DEC);
-
- // note the time that the connection was made:
- lastConnectionTime = millis();
+ client.print("sensor1,");
+ client.println(thisData);
+
}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
}
+ // note the time that the connection was made or attempted:
+ lastConnectionTime = millis();
}
diff --git a/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino b/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
index 4a03100..2a96e9f 100644
--- a/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
+++ b/libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
@@ -1,11 +1,15 @@
/*
- Pachube sensor client with Strings
+ Cosm sensor client with Strings
- This sketch connects an analog sensor to Pachube (http://www.pachube.com)
+ This sketch connects an analog sensor to Cosm (http://www.cosm.com)
using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or
the Adafruit Ethernet shield, either one will work, as long as it's got
a Wiznet Ethernet module on board.
+ This example has been updated to use version 2.0 of the Cosm.com API.
+ To make it work, create a feed with two datastreams, and give them the IDs
+ sensor1 and sensor2. Or change the code below to match your feed.
+
This example uses the String library, which is part of the Arduino core from
version 0019.
@@ -14,9 +18,10 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 15 March 2010
- updated 26 Oct 2011
- by Tom Igoe
+ modified 9 Apr 2012
+ by Tom Igoe with input from Usman Haque and Joe Saavedra
+ http://arduino.cc/en/Tutorial/CosmClientString
This code is in the public domain.
*/
@@ -24,10 +29,17 @@
#include <SPI.h>
#include <Ethernet.h>
+
+/#define APIKEY "YOUR API KEY GOES HERE" // replace your Cosm api key here
+#define FEEDID 00000 // replace your feed ID
+#define USERAGENT "My Project" // user agent is the project name
+
+
// assign a MAC address for the ethernet controller.
// fill in your address here:
-byte mac[] = {
+ byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
+
// fill in an available IP address on your network here,
// for manual configuration:
IPAddress ip(10,0,1,20);
@@ -35,19 +47,29 @@ IPAddress ip(10,0,1,20);
// initialize the library instance:
EthernetClient client;
-long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
-boolean lastConnected = false; // state of the connection last time through the main loop
-const int postingInterval = 10000; //delay between updates to Pachube.com
+// if you don't want to use DNS (and reduce your sketch size)
+// use the numeric IP instead of the name for the server:
+IPAddress server(216,52,233,121); // numeric IP for api.cosm.com
+//char server[] = "api.cosm.com"; // name address for Cosm API
+
+unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
+boolean lastConnected = false; // state of the connection last time through the main loop
+const unsigned long postingInterval = 10*1000; //delay between updates to Cosm.com
void setup() {
- // start serial port:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// give the ethernet module time to boot up:
delay(1000);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
- // Configure manually:
+ // DHCP failed, so use a fixed IP address:
Ethernet.begin(mac, ip);
}
}
@@ -56,13 +78,15 @@ void loop() {
// read the analog sensor:
int sensorReading = analogRead(A0);
// convert the data to a String to send it:
- String dataString = String(sensorReading);
+
+ String dataString = "sensor1,";
+ dataString += sensorReading;
// you can append multiple readings to this String if your
- // pachube feed is set up to handle multiple values:
+ // Cosm feed is set up to handle multiple values:
int otherSensorReading = analogRead(A1);
- dataString += ",";
- dataString += String(otherSensorReading);
+ dataString += "\nsensor2,";
+ dataString += otherSensorReading;
// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
@@ -81,7 +105,7 @@ void loop() {
}
// if you're not connected, and ten seconds have passed since
- // your last connection, then connect again and send data:
+ // your last connection, then connect again and send data:
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
sendData(dataString);
}
@@ -93,29 +117,36 @@ void loop() {
// this method makes a HTTP connection to the server:
void sendData(String thisData) {
// if there's a successful connection:
- if (client.connect("www.pachube.com", 80)) {
+ if (client.connect(server, 80)) {
Serial.println("connecting...");
- // send the HTTP PUT request.
- // fill in your feed address here:
- client.print("PUT /api/YOUR_FEED_HERE.csv HTTP/1.1\n");
- client.print("Host: www.pachube.com\n");
- // fill in your Pachube API key here:
- client.print("X-PachubeApiKey: YOUR_KEY_HERE\n");
+ // send the HTTP PUT request:
+ client.print("PUT /v2/feeds/");
+ client.print(FEEDID);
+ client.println(".csv HTTP/1.1");
+ client.println("Host: api.cosm.com");
+ client.print("X-CosmApiKey: ");
+ client.println(APIKEY);
+ client.print("User-Agent: ");
+ client.println(USERAGENT);
client.print("Content-Length: ");
- client.println(thisData.length(), DEC);
+ client.println(thisData.length());
// last pieces of the HTTP PUT request:
- client.print("Content-Type: text/csv\n");
- client.println("Connection: close\n");
+ client.println("Content-Type: text/csv");
+ client.println("Connection: close");
+ client.println();
// here's the actual content of the PUT request:
client.println(thisData);
-
- // note the time that the connection was made:
- lastConnectionTime = millis();
}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
+ Serial.println();
+ Serial.println("disconnecting.");
+ client.stop();
}
+ // note the time that the connection was made or attempted:
+ lastConnectionTime = millis();
}
+
diff --git a/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino
index 5cf1ad8..3457125 100644
--- a/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino
+++ b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino
@@ -13,6 +13,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 14 Sep 2010
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -38,8 +39,13 @@ EthernetClient client;
void setup() {
// start the Ethernet connection:
Ethernet.begin(mac, ip);
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
diff --git a/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino b/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino
index f113e17..3587d72 100644
--- a/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino
+++ b/libraries/Ethernet/examples/TwitterClient/TwitterClient.ino
@@ -14,9 +14,10 @@
version 0019.
Circuit:
- * Ethernet shield attached to pins 10, 11, 12, 13
+ * Ethernet shield attached to pins 10, 11, 12, 13
created 21 May 2011
+ modified 9 Apr 2012
by Tom Igoe
This code is in the public domain.
@@ -35,12 +36,12 @@ IPAddress ip(192,168,1,20);
// initialize the library instance:
EthernetClient client;
-const int requestInterval = 60000; // delay between requests
+const unsigned long requestInterval = 60000; // delay between requests
char serverName[] = "api.twitter.com"; // twitter URL
boolean requested; // whether you've made a request since connecting
-long lastAttemptTime = 0; // last time you connected to the server, in milliseconds
+unsigned long lastAttemptTime = 0; // last time you connected to the server, in milliseconds
String currentLine = ""; // string to hold the text from server
String tweet = ""; // string to hold the tweet
@@ -51,13 +52,22 @@ void setup() {
currentLine.reserve(256);
tweet.reserve(150);
-// initialize serial:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// attempt a DHCP connection:
+ Serial.println("Attempting to get an IP address using DHCP:");
if (!Ethernet.begin(mac)) {
// if DHCP fails, start with a hard-coded address:
+ Serial.println("failed to get an IP address using DHCP, trying manually");
Ethernet.begin(mac, ip);
}
+ Serial.print("My address:");
+ Serial.println(Ethernet.localIP());
// connect to Twitter:
connectToServer();
}
@@ -114,7 +124,7 @@ void connectToServer() {
Serial.println("connecting to server...");
if (client.connect(serverName, 80)) {
Serial.println("making HTTP request...");
- // make HTTP GET request to twitter:
+ // make HTTP GET request to twitter:
client.println("GET /1/statuses/user_timeline.xml?screen_name=arduino&count=1 HTTP/1.1");
client.println("HOST: api.twitter.com");
client.println();
@@ -122,3 +132,4 @@ void connectToServer() {
// note the time of this connect attempt:
lastAttemptTime = millis();
}
+
diff --git a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino
index b4e24b8..93ffe39 100644
--- a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino
+++ b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino
@@ -9,7 +9,7 @@
created 4 Sep 2010
by Michael Margolis
- modified 17 Sep 2010
+ modified 9 Apr 2012
by Tom Igoe
This code is in the public domain.
@@ -38,7 +38,12 @@ EthernetUDP Udp;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
diff --git a/libraries/Ethernet/examples/WebClient/WebClient.ino b/libraries/Ethernet/examples/WebClient/WebClient.ino
index 1806854..5d5d7f2 100644
--- a/libraries/Ethernet/examples/WebClient/WebClient.ino
+++ b/libraries/Ethernet/examples/WebClient/WebClient.ino
@@ -8,6 +8,7 @@
* Ethernet shield attached to pins 10, 11, 12, 13
created 18 Dec 2009
+ modified 9 Apr 2012
by David A. Mellis
*/
@@ -26,8 +27,12 @@ IPAddress server(173,194,33,104); // Google
EthernetClient client;
void setup() {
- // start the serial library:
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
diff --git a/libraries/Ethernet/examples/WebServer/WebServer.ino b/libraries/Ethernet/examples/WebServer/WebServer.ino
index 6837f83..ce8dbb1 100644
--- a/libraries/Ethernet/examples/WebServer/WebServer.ino
+++ b/libraries/Ethernet/examples/WebServer/WebServer.ino
@@ -10,7 +10,7 @@
created 18 Dec 2009
by David A. Mellis
- modified 4 Sep 2010
+ modified 9 Apr 2012
by Tom Igoe
*/
@@ -20,7 +20,8 @@
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
-byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+byte mac[] = {
+ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 177);
// Initialize the Ethernet server library
@@ -28,23 +29,33 @@ IPAddress ip(192,168,1, 177);
// (port 80 is default for HTTP):
EthernetServer server(80);
-void setup()
-{
+void setup() {
+ // Open serial communications and wait for port to open:
+ Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
+ Serial.print("server is at ");
+ Serial.println(Ethernet.localIP());
}
-void loop()
-{
+
+void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
+ Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
+ Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
@@ -52,16 +63,22 @@ void loop()
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
+ client.println("Connnection: close");
client.println();
-
+ client.println("<!DOCTYPE HTML>");
+ client.println("<html>");
+ // add a meta refresh tag, so the browser pulls again every 5 seconds:
+ client.println("<meta http-equiv=\"refresh\" content=\"5\">");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
+ int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
- client.print(analogRead(analogChannel));
- client.println("<br />");
+ client.print(sensorReading);
+ client.println("<br />");
}
+ client.println("</html>");
break;
}
if (c == '\n') {
@@ -78,5 +95,7 @@ void loop()
delay(1);
// close the connection:
client.stop();
+ Serial.println("client disonnected");
}
}
+
diff --git a/libraries/Ethernet/utility/w5100.h b/libraries/Ethernet/utility/w5100.h
index 153aedb..8dccd9f 100755
--- a/libraries/Ethernet/utility/w5100.h
+++ b/libraries/Ethernet/utility/w5100.h
@@ -327,7 +327,11 @@ private:
inline static void initSS() { DDRB |= _BV(4); };
inline static void setSS() { PORTB &= ~_BV(4); };
inline static void resetSS() { PORTB |= _BV(4); };
-#elif defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
+#elif defined(__AVR_ATmega32U4__)
+ inline static void initSS() { DDRB |= _BV(6); };
+ inline static void setSS() { PORTB &= ~_BV(6); };
+ inline static void resetSS() { PORTB |= _BV(6); };
+#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
inline static void initSS() { DDRB |= _BV(0); };
inline static void setSS() { PORTB &= ~_BV(0); };
inline static void resetSS() { PORTB |= _BV(0); };
diff --git a/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino b/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
index 27123ad..1127d8f 100644
--- a/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
+++ b/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino
@@ -32,7 +32,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalAutoscroll
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/Blink/Blink.ino b/libraries/LiquidCrystal/examples/Blink/Blink.ino
index e410424..9667b5d 100644
--- a/libraries/LiquidCrystal/examples/Blink/Blink.ino
+++ b/libraries/LiquidCrystal/examples/Blink/Blink.ino
@@ -32,7 +32,7 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalBlink
*/
diff --git a/libraries/LiquidCrystal/examples/Cursor/Cursor.ino b/libraries/LiquidCrystal/examples/Cursor/Cursor.ino
index 28e2a6a..05862a4 100644
--- a/libraries/LiquidCrystal/examples/Cursor/Cursor.ino
+++ b/libraries/LiquidCrystal/examples/Cursor/Cursor.ino
@@ -33,7 +33,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalCursor
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/Display/Display.ino b/libraries/LiquidCrystal/examples/Display/Display.ino
index b000731..a85effb 100644
--- a/libraries/LiquidCrystal/examples/Display/Display.ino
+++ b/libraries/LiquidCrystal/examples/Display/Display.ino
@@ -33,7 +33,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/Scroll/Scroll.ino b/libraries/LiquidCrystal/examples/Scroll/Scroll.ino
index 71e5e8c..0d6d8dc 100644
--- a/libraries/LiquidCrystal/examples/Scroll/Scroll.ino
+++ b/libraries/LiquidCrystal/examples/Scroll/Scroll.ino
@@ -33,7 +33,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalScroll
+
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
index 9727cee..a6f8f40 100644
--- a/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
+++ b/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino
@@ -32,7 +32,7 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalSerial
*/
// include the library code:
diff --git a/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino b/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino
index 51bab1f..cabd8ea 100644
--- a/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino
+++ b/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino
@@ -32,7 +32,7 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalTextDirection
*/
@@ -49,7 +49,6 @@ void setup() {
lcd.begin(16, 2);
// turn on the cursor:
lcd.cursor();
- Serial.begin(9600);
}
void loop() {
diff --git a/libraries/LiquidCrystal/examples/setCursor/setCursor.ino b/libraries/LiquidCrystal/examples/setCursor/setCursor.ino
index 3c4edf3..e45c491 100644
--- a/libraries/LiquidCrystal/examples/setCursor/setCursor.ino
+++ b/libraries/LiquidCrystal/examples/setCursor/setCursor.ino
@@ -32,7 +32,8 @@
This example code is in the public domain.
- http://www.arduino.cc/en/Tutorial/LiquidCrystal
+ http://arduino.cc/en/Tutorial/LiquidCrystalSetCursor
+
*/
// include the library code:
diff --git a/libraries/SD/examples/CardInfo/CardInfo.ino b/libraries/SD/examples/CardInfo/CardInfo.ino
index fb2f6c3..0c2dfc5 100644
--- a/libraries/SD/examples/CardInfo/CardInfo.ino
+++ b/libraries/SD/examples/CardInfo/CardInfo.ino
@@ -16,7 +16,7 @@
created 28 Mar 2011
by Limor Fried
- modified 16 Mar 2011
+ modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
@@ -35,7 +35,13 @@ const int chipSelect = 4;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("\nInitializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/examples/Datalogger/Datalogger.ino b/libraries/SD/examples/Datalogger/Datalogger.ino
index 73d81af..a7f85ee 100644
--- a/libraries/SD/examples/Datalogger/Datalogger.ino
+++ b/libraries/SD/examples/Datalogger/Datalogger.ino
@@ -13,7 +13,7 @@
** CS - pin 4
created 24 Nov 2010
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -30,7 +30,13 @@ const int chipSelect = 4;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
diff --git a/libraries/SD/examples/DumpFile/DumpFile.ino b/libraries/SD/examples/DumpFile/DumpFile.ino
index 961717f..d83089a 100644
--- a/libraries/SD/examples/DumpFile/DumpFile.ino
+++ b/libraries/SD/examples/DumpFile/DumpFile.ino
@@ -12,6 +12,9 @@
** CS - pin 4
created 22 December 2010
+ by Limor Fried
+ modified 9 Apr 2012
+ by Tom Igoe
This example code is in the public domain.
@@ -27,7 +30,13 @@ const int chipSelect = 4;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
diff --git a/libraries/SD/examples/Files/Files.ino b/libraries/SD/examples/Files/Files.ino
index 5ed9fea..a15b862 100644
--- a/libraries/SD/examples/Files/Files.ino
+++ b/libraries/SD/examples/Files/Files.ino
@@ -11,7 +11,7 @@
created Nov 2010
by David A. Mellis
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -23,7 +23,13 @@ File myFile;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/examples/ReadWrite/ReadWrite.ino b/libraries/SD/examples/ReadWrite/ReadWrite.ino
index 9957218..5805fc8 100644
--- a/libraries/SD/examples/ReadWrite/ReadWrite.ino
+++ b/libraries/SD/examples/ReadWrite/ReadWrite.ino
@@ -11,7 +11,7 @@
created Nov 2010
by David A. Mellis
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -24,7 +24,13 @@ File myFile;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/examples/listfiles/listfiles.ino b/libraries/SD/examples/listfiles/listfiles.ino
index b2435a2..876c3f8 100644
--- a/libraries/SD/examples/listfiles/listfiles.ino
+++ b/libraries/SD/examples/listfiles/listfiles.ino
@@ -11,7 +11,7 @@
created Nov 2010
by David A. Mellis
- updated 2 Dec 2010
+ modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
@@ -23,7 +23,13 @@ File root;
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
diff --git a/libraries/SD/utility/SdFatUtil.h b/libraries/SD/utility/SdFatUtil.h
index 283fcb2..7d6b410 100644
--- a/libraries/SD/utility/SdFatUtil.h
+++ b/libraries/SD/utility/SdFatUtil.h
@@ -56,7 +56,7 @@ static UNUSEDOK int FreeRam(void) {
* \param[in] str Pointer to string stored in flash memory.
*/
static NOINLINE void SerialPrint_P(PGM_P str) {
- for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c);
+ for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.write(c);
}
//------------------------------------------------------------------------------
/**
diff --git a/libraries/Servo/Servo.cpp b/libraries/Servo/Servo.cpp
index acac29a..a716433 100755
--- a/libraries/Servo/Servo.cpp
+++ b/libraries/Servo/Servo.cpp
@@ -89,7 +89,7 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
}
else {
// finished all channels so wait for the refresh period to expire before starting over
- if( (unsigned)*TCNTn < (usToTicks(REFRESH_INTERVAL) + 4) ) // allow a few ticks to ensure the next OCR1A not missed
+ if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
else
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
@@ -298,7 +298,7 @@ void Servo::writeMicroseconds(int value)
{
// calculate and store the values for the given channel
byte channel = this->servoIndex;
- if( (channel >= 0) && (channel < MAX_SERVOS) ) // ensure channel is valid
+ if( (channel < MAX_SERVOS) ) // ensure channel is valid
{
if( value < SERVO_MIN() ) // ensure pulse width is valid
value = SERVO_MIN();
diff --git a/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino b/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino
index 1f535bd..69bcc01 100644
--- a/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino
+++ b/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino
@@ -1,10 +1,34 @@
+/*
+ Software serial multple serial test
+
+ Receives from the hardware serial, sends to software serial.
+ Receives from software serial, sends to hardware serial.
+
+ The circuit:
+ * RX is digital pin 2 (connect to TX of other device)
+ * TX is digital pin 3 (connect to RX of other device)
+
+ created back in the mists of time
+ modified 9 Apr 2012
+ by Tom Igoe
+ based on Mikal Hart's example
+
+ This example code is in the public domain.
+
+ */
#include <SoftwareSerial.h>
-SoftwareSerial mySerial(2, 3);
+SoftwareSerial mySerial(2, 3); // RX, TX
void setup()
{
+ // Open serial communications and wait for port to open:
Serial.begin(57600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
+
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
diff --git a/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino b/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino
index e870c6f..d9f8f45 100644
--- a/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino
+++ b/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino
@@ -17,6 +17,7 @@
* Second serial device's TX attached to digital pin 4, RX to pin 5
created 18 Apr. 2011
+ modified 9 Apr 2012
by Tom Igoe
based on Mikal Hart's twoPortRXExample
@@ -33,8 +34,12 @@ SoftwareSerial portTwo(4, 5);
void setup()
{
- // Start the hardware serial port
+ // Open serial communications and wait for port to open:
Serial.begin(9600);
+ while (!Serial) {
+ ; // wait for serial port to connect. Needed for Leonardo only
+ }
+
// Start each software serial port
portOne.begin(9600);
diff --git a/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino b/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino
index dbd0f7f..1a67a55 100644
--- a/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino
+++ b/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino
@@ -26,11 +26,10 @@ const int stepsPerRevolution = 200; // change this to fit the number of steps p
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8,9,10,11);
-int stepCount = 0; // number of steps the motor has taken
+int stepCount = 0; // number of steps the motor has taken
void setup() {
- // initialize the serial port:
- Serial.begin(9600);
+ // nothing to do inside the setup
}
void loop() {
diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp
index d83f478..4e7a17c 100755
--- a/libraries/Wire/Wire.cpp
+++ b/libraries/Wire/Wire.cpp
@@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
extern "C" {
@@ -73,14 +75,14 @@ void TwoWire::begin(int address)
begin((uint8_t)address);
}
-uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
+uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
// clamp to buffer length
if(quantity > BUFFER_LENGTH){
quantity = BUFFER_LENGTH;
}
// perform blocking read into buffer
- uint8_t read = twi_readFrom(address, rxBuffer, quantity);
+ uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = read;
@@ -88,9 +90,19 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
return read;
}
+uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
+{
+ return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
+}
+
uint8_t TwoWire::requestFrom(int address, int quantity)
{
- return requestFrom((uint8_t)address, (uint8_t)quantity);
+ return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
+}
+
+uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
+{
+ return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
}
void TwoWire::beginTransmission(uint8_t address)
@@ -109,10 +121,23 @@ void TwoWire::beginTransmission(int address)
beginTransmission((uint8_t)address);
}
-uint8_t TwoWire::endTransmission(void)
+//
+// Originally, 'endTransmission' was an f(void) function.
+// It has been modified to take one parameter indicating
+// whether or not a STOP should be performed on the bus.
+// Calling endTransmission(false) allows a sketch to
+// perform a repeated start.
+//
+// WARNING: Nothing in the library keeps track of whether
+// the bus tenure has been properly ended with a STOP. It
+// is very possible to leave the bus in a hung state if
+// no call to endTransmission(true) is made. Some I2C
+// devices will behave oddly if they do not see a STOP.
+//
+uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
// transmit buffer (blocking)
- int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
+ int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
@@ -121,6 +146,14 @@ uint8_t TwoWire::endTransmission(void)
return ret;
}
+// This provides backwards compatibility with the original
+// definition, and expected behaviour, of endTransmission
+//
+uint8_t TwoWire::endTransmission(void)
+{
+ return endTransmission(true);
+}
+
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h
index 9ea4afd..a93d0f5 100755
--- a/libraries/Wire/Wire.h
+++ b/libraries/Wire/Wire.h
@@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
#ifndef TwoWire_h
@@ -50,8 +52,11 @@ class TwoWire : public Stream
void beginTransmission(uint8_t);
void beginTransmission(int);
uint8_t endTransmission(void);
+ uint8_t endTransmission(uint8_t);
uint8_t requestFrom(uint8_t, uint8_t);
+ uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
uint8_t requestFrom(int, int);
+ uint8_t requestFrom(int, int, int);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *, size_t);
virtual int available(void);
diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c
index d80114b..6b2db3c 100644
--- a/libraries/Wire/utility/twi.c
+++ b/libraries/Wire/utility/twi.c
@@ -15,6 +15,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
*/
#include <math.h>
@@ -37,14 +39,16 @@
#include "twi.h"
static volatile uint8_t twi_state;
-static uint8_t twi_slarw;
+static volatile uint8_t twi_slarw;
+static volatile uint8_t twi_sendStop; // should the transaction end with a stop
+static volatile uint8_t twi_inRepStart; // in the middle of a repeated start
static void (*twi_onSlaveTransmit)(void);
static void (*twi_onSlaveReceive)(uint8_t*, int);
static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_masterBufferIndex;
-static uint8_t twi_masterBufferLength;
+static volatile uint8_t twi_masterBufferLength;
static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
static volatile uint8_t twi_txBufferIndex;
@@ -65,6 +69,8 @@ void twi_init(void)
{
// initialize state
twi_state = TWI_READY;
+ twi_sendStop = true; // default value
+ twi_inRepStart = false;
// activate internal pullups for twi.
digitalWrite(SDA, 1);
@@ -103,9 +109,10 @@ void twi_setAddress(uint8_t address)
* Input address: 7bit i2c device address
* data: pointer to byte array
* length: number of bytes to read into array
+ * sendStop: Boolean indicating whether to send a stop at the end
* Output number of bytes read
*/
-uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
+uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
{
uint8_t i;
@@ -119,6 +126,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
continue;
}
twi_state = TWI_MRX;
+ twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
@@ -135,8 +143,20 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
twi_slarw = TW_READ;
twi_slarw |= address << 1;
- // send start condition
- TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+ if (true == twi_inRepStart) {
+ // if we're in the repeated start state, then we've already sent the start,
+ // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
+ // We need to remove ourselves from the repeated start state before we enable interrupts,
+ // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
+ // 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;
+ TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
+ }
+ else
+ // send start condition
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
// wait for read operation to complete
while(TWI_MRX == twi_state){
@@ -162,13 +182,14 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
* data: pointer to byte array
* length: number of bytes in array
* wait: boolean indicating to wait for write or not
+ * sendStop: boolean indicating whether or not to send a stop at the end
* Output 0 .. success
* 1 .. length to long for buffer
* 2 .. address send, NACK received
* 3 .. data send, NACK received
* 4 .. other twi error (lost bus arbitration, bus error, ..)
*/
-uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
+uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
{
uint8_t i;
@@ -182,6 +203,7 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
continue;
}
twi_state = TWI_MTX;
+ twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
@@ -198,8 +220,23 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait
twi_slarw = TW_WRITE;
twi_slarw |= address << 1;
- // send start condition
- TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+ // if we're in a repeated start, then we've already sent the START
+ // in the ISR. Don't do it again.
+ //
+ if (true == twi_inRepStart) {
+ // if we're in the repeated start state, then we've already sent the start,
+ // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
+ // We need to remove ourselves from the repeated start state before we enable interrupts,
+ // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
+ // 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;
+ TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
+ }
+ else
+ // send start condition
+ TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
// wait for write operation to complete
while(wait && (TWI_MTX == twi_state)){
@@ -343,7 +380,16 @@ SIGNAL(TWI_vect)
TWDR = twi_masterBuffer[twi_masterBufferIndex++];
twi_reply(1);
}else{
- twi_stop();
+ if (twi_sendStop)
+ twi_stop();
+ else {
+ twi_inRepStart = true; // we're gonna send the START
+ // don't enable the interrupt. We'll generate the start, but we
+ // avoid handling the interrupt until we're in the next transaction,
+ // at the point where we would normally issue the start.
+ TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
+ twi_state = TWI_READY;
+ }
}
break;
case TW_MT_SLA_NACK: // address sent, nack received
@@ -374,6 +420,17 @@ SIGNAL(TWI_vect)
case TW_MR_DATA_NACK: // data received, nack sent
// put final byte into buffer
twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
+ if (twi_sendStop)
+ twi_stop();
+ else {
+ twi_inRepStart = true; // we're gonna send the START
+ // don't enable the interrupt. We'll generate the start, but we
+ // avoid handling the interrupt until we're in the next transaction,
+ // at the point where we would normally issue the start.
+ TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
+ twi_state = TWI_READY;
+ }
+ break;
case TW_MR_SLA_NACK: // address sent, nack received
twi_stop();
break;
diff --git a/libraries/Wire/utility/twi.h b/libraries/Wire/utility/twi.h
index 831b928..6526593 100755
--- a/libraries/Wire/utility/twi.h
+++ b/libraries/Wire/utility/twi.h
@@ -40,8 +40,8 @@
void twi_init(void);
void twi_setAddress(uint8_t);
- uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
- uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
+ uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
+ uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
uint8_t twi_transmit(const uint8_t*, uint8_t);
void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
void twi_attachSlaveTxEvent( void (*)(void) );