Browse files

Fully working base code

  • Loading branch information...
1 parent 0ac23aa commit 91a0bf7b15d0d96a6100d91b2f7d978d95b01e01 @brandenhall committed Apr 4, 2012
Showing with 179 additions and 327 deletions.
  1. +2 −4 LICENSE.txt
  2. +6 −220 README.txt
  3. +2 −14 TODO.txt
  4. +1 −7 src/SC16IS750/SC16IS750Device.cpp
  5. +74 −6 src/WiFly/WiFlyClient.cpp
  6. +34 −27 src/WiFly/WiFlyClient.h
  7. +49 −42 src/WiFly/WiFlyDevice.cpp
  8. +5 −6 src/WiFly/WiFlyDevice.h
  9. +6 −1 src/WiFly/WiFlyServer.cpp
View
6 LICENSE.txt
@@ -4,12 +4,10 @@ Electronics and is licensed under the LGPL.
Examples based on the original examples from the official Arduino
Ethernet library are licensed under the same terms as the originals.
-'ParsedStream.h' contains a ringbuffer implementation based on one
-originally found in the Arduino 'HardwareSerial' implementation.
-
TODO: Handle license stuff better.
AUTHORS
+ * Branden Hall (Major re-write and simplification)
* Chris Taylor (Original autoconnect sketch and tutorial)
- * Philip J. Lindsay (Conversion to library)
+ * Philip J. Lindsay (Conversion to library)
View
226 README.txt
@@ -1,12 +1,7 @@
-Note:
-Just about ALL of this is out of date now...
+== WiFly Arduino Library ==
-== SparkFun WiFly Shield Library : alpha 1 release ==
-
-This is a library for the Arduino-compatible WiFly Shield available from
-SparkFun Electronics:
-
- <http://sparkfun.com/products/9954>
+This is a library for working with the WiFly GSX and EZX devices from
+Roving Networks with Arduino 1.0 and above.
The goal with this library is to make it--as much as possible--a "drop
in" replacement for the official Arduino Ethernet library
@@ -21,217 +16,8 @@ separate breakout board:
<http://www.sparkfun.com/products/9981>
-
= Usage =
-This is how you connect to a WPA wireless network with a passphrase
-and use DHCP to obtain an IP address and DNS configuration:
-
-----
-#include "WiFly.h"
-
-void setup() {
-
- WiFly.begin();
-
- if (!WiFly.join("ssid", "passphrase")) {
- // Handle the failure
- }
-
- // Rejoice in your connection
-}
----
-
-If the network you want to connect to has no passphrase you can use this form:
-
----
- if (!WiFly.join("ssid")) {
- // Handle the failure
- }
----
-
-If the network you want to connect to is using WEP use this form:
-
----
- if (!WiFly.join("NETWORK", "00112233445566778899AABBCC", WEP_MODE)) {
- // Handle the failure
- }
----
-
-Note the description of the WEP key from the WiFly user guide:
-
- * Key must be EXACTLY 26 ASCII characters representing 13 bytes.
-
- * In HEX format, hex digits > 9 can be either upper or lower case.
-
- * "The Wifly GSX only supports “open” key mode, 128 bit keys for WEP."
-
-Whatever connection method you use, once you have joined you can use
-the Client and Server classes (re-implemented for the WiFly) mostly as
-normal.
-
-You can supply a domain name rather than an IP address for client
-connections:
-
- Client client("google.com", 80);
-
-You can also retrieve the current IP address with:
-
- Serial.println(WiFly.ip());
-
-This release of the library comes with three examples:
-
- * WiFly_Autoconnect_Terminal: reimplementation from tutorial
- * WiFly_WebClient: Ethernet WebClient demo with small WiFly changes
- * WiFly_WebServer: Ethernet WebServer demo with small WiFly changes
-
-For each example you will need to modify the file "Credentials.h" to
-supply your network's name (SSID) and passphrase.
-
-There are also some troubleshooting tools:
-
- * SpiUartTerminal: enter command mode and send commands manually
- * HardwareFactoryReset: hardware factory reset a WiFly module
-
-
-= Configuration =
-
-Different revisions of the WiFly shield support different features. If
-you are using an older revision of the shield you will need to modify
-the value of 'SHIELD_REVISION' in the file 'Configuration.h' to
-indicate which revision of the WiFly shield you are using. See the
-documentation in the file for further detail.
-
-The value defaults to the most recent revision sold at the time of
-code release.
-
-
-= Arduino Mega support =
-
-This library supports using the WiFly Shield with the Arduino Mega if
-four jumper wires are added. The following connections are required:
-
- * Mega pin 53 to shield pin 10
- * Mega pin 51 to shield pin 11
- * Mega pin 50 to shield pin 12
- * Mega pin 52 to shield pin 13
-
-In addition, code on the Mega must not use pins 10, 11, 12, or 13.
-
-
-= Known Issues =
-
-This is an alpha release--this means it's non-feature complete and may
-not be entirely reliable. It has been tested with the shipped examples and
-works in most cases.
-
-There are some known issues:
-
- * Connections to WEP networks have not really been tested--please try
- it out and provide feedback. At the moment adhoc networks of any
- type are not supported--the module supports them, the library just
- hasn't been modified to recognise the different way the module
- responds when connecting.
-
- * Incomplete documentation.
-
- * Only tested with WiFly firmware version 2.18--earlier or later
- versions may or may not have issues. 2.20 has also been tested.
-
- * Only DHCP is supported--you can't specify an IP address and DNS
- configuration directly.
-
- * There are some situations (exact cause unknown but often it seems
- to be after initial programming) where the WiFly will fail to
- respond to requests. You may need to power-cycle the Arduino or try
- refreshing the page in your browser if it's acting as a server.
-
- * There's a limit to how quickly you can refresh a page when acting
- as a server--this is because the library doesn't handle dropped
- connections well at present. You can generally tell from the lights
- on the unit if it's busy. (This is particularly obvious when a
- using a web browser (rather than something like 'wget') because
- after the page is loaded the browser makes an immediate request for
- the favicon. Once every five seconds or so should be fine depending
- on how big the page is.
-
- * None of the non-ethernet capabilities of the WiFly are yet exposed
- e.g. network scans, signal strength information etc.
-
- * The code isn't very robust for error states--in general it will
- hang rather than return useful information.
-
- * We only have a 9600 baud connection between the Arduino and WiFly
- it should in theory be possible to be much faster.
-
- * Passphrases or SSIDs that contain spaces or dollar signs ($) will
- probably not work.
-
-
-= License & Authors =
-
-See LICENSE.TXT
-
-
-= Feedback =
-
-Please email <spark@sparkfun.com> or leave a comment on the SparkFun forums:
-
- <http://forum.sparkfun.com/>
-
-
-= Changelog =
-
-+ alpha 2 -- 17 December 2010 -- "Azalea Galaxy"
-
- * NOTE: New configuration location! You now need to modify the value
- of 'SHIELD_REVISION' in the file 'Configuration.h' to
- indicate what revision of the WiFly shield you are
- using. See the documentation in the file for further
- detail. The value defaults to the most recent revision sold
- at the time of the code release.
-
- * Added support for joining Open networks (i.e. without a passphrase or key).
-
- * Added (untested) WEP network support.
-
- * Modified software reboot to hopefully work more reliably.
-
- * Added support for hardware reset which should be more reliable than
- software reboot on board revisions that support it (currently only the
- most recent revision).
-
- * Modified command mode entry method to hopefully work more
- reliably. Includes use of guard time as originally inspired by
- World Mood Light.
-
- * Added 'SpiUartTerminal' troubleshooting tool.
-
- * Added 'HardwareFactoryReset' tool to help with troubleshooting.
-
- * Added support for further board revision feature support configuration.
-
- * Added some debugging support.
-
-
-+ alpha 1 -- 31 August 2010 -- "August Gratitude"
-
- * Change default crystal speed to match new 14MHz crystal used.
- NOTE: People using the older 12MHz crystal will need to change
- "USE_14_MHZ_CRYSTAL" in SpiUart.cpp to 'false'.
-
- * Added ability to set baud rate at runtime in SpiUart class.
- (Note: This ability to change the baudrate has not yet been propagated
- to the WiFly class.)
-
- * Renamed Spi.h to _Spi.h in order to avoid clashes with the other
- library by the same name as the IDE might (and has) mistakenly
- included ours instead of the the other one which results in
- confusing error messages.
-
- * Changed the case of the 'examples' directory so it gets displayed
- in the IDE correctly.
-
-
-+ alpha 0 -- 19 May 2010 -- "Awfully Gorgeous"
- * Initial release
+This version of the library provides a simple wrapper to the WiFly
+device. As such, it's important to read and understand the WiFly
+command set.
View
16 TODO.txt
@@ -1,18 +1,6 @@
-* Add mention of port 80 default issue.
+* Detail flow control issue
-* Add mention of configuration change/save for flow control
-
-* Add baud rate control.
-
-* Consider future support for firmware 2.20 which has better debug level control--including suppressing DHCP messages?
+* Make setup example
* Improve documentation.
-
-* Special case version 2.19 firmware with passphrase length bug?
-
-* Reimplement release script. Including handling credentials issue.
-
-* Support WEP out of the box.
-
-* Handle connecting to adhoc networks.
View
8 src/SC16IS750/SC16IS750Device.cpp
@@ -182,14 +182,8 @@ int SC16IS750Device::read() {
if (!available()) {
return -1;
}
-
- // int i = readRegister(RHR);
- // Serial.print((char) i);
-
- // return i;
-
- return readRegister(RHR);
+ return readRegister(RHR);;
}
View
80 src/WiFly/WiFlyClient.cpp
@@ -4,6 +4,8 @@
WiFlyClient::WiFlyClient() : _WiFly (WiFly) {
connections = 0;
+ closeCmd = "*CLOS*";
+ closeBufferIndex = closeBufferSize = 0;
}
// handle connect from server class
@@ -22,7 +24,7 @@ int WiFlyClient::connect(const char* host, uint16_t port) {
char cmdbuf[len];
cmd.toCharArray(cmdbuf, len);
- connections = _WiFly.sendCommand(cmdbuf, "*OPEN*", 10000, false);
+ connections = _WiFly.sendCommand(cmdbuf, "*OPEN*", 10000);
return connections;
}
@@ -43,7 +45,7 @@ int WiFlyClient::connect(IPAddress ip, uint16_t port) {
char cmdbuf[len];
cmd.toCharArray(cmdbuf, len);
- connections = _WiFly.sendCommand(cmdbuf, "*OPEN*", 10000, false);
+ connections = _WiFly.sendCommand(cmdbuf, "*OPEN*", 10000);
return connections;
}
@@ -69,7 +71,7 @@ int WiFlyClient::read() {
return -1;
}
- return _WiFly.uart->read();
+ return bufferedRead();
}
int WiFlyClient::read(uint8_t *buf, size_t size) {
@@ -81,7 +83,7 @@ int WiFlyClient::read(uint8_t *buf, size_t size) {
}
for (uint8_t i=0; i<size; ++i) {
- value = _WiFly.uart->read();
+ value = bufferedRead();
if (value > -1) {
buf[count] = value;
@@ -95,6 +97,70 @@ int WiFlyClient::read(uint8_t *buf, size_t size) {
return count;
}
+int WiFlyClient::bufferedRead() {
+ int value;
+
+ if (closeBufferSize > 0) {
+ value = closeBuffer[closeBufferIndex];
+
+ ++closeBufferIndex;
+ if (closeBufferIndex == closeBufferSize) {
+ closeBufferIndex = closeBufferSize = 0;
+ }
+
+ } else {
+ value = _WiFly.uart->read();
+
+ while (value != -1 && closeBufferSize < sizeof(closeCmd) && closeCmd[closeBufferSize] == (char)value) {
+ closeBuffer[closeBufferSize] = value;
+
+ while (!_WiFly.uart->available()) {
+ delay(1);
+ }
+
+ value = _WiFly.uart->read();
+ ++closeBufferSize;
+ }
+
+ // found close, kill connection
+ if (closeBufferSize == sizeof(closeCmd)) {
+ Serial.println("GOT CLOSE!");
+ Serial.println((char)closeBuffer[0]);
+ Serial.println((char)closeBuffer[1]);
+ Serial.println((char)closeBuffer[2]);
+ Serial.println((char)closeBuffer[3]);
+ Serial.println((char)closeBuffer[4]);
+ Serial.println((char)closeBuffer[5]);
+ Serial.println((char)closeBuffer[6]);
+
+ connections = 0;
+ closeBufferSize = 0;
+ closeBufferIndex = 0;
+
+ _WiFly.uart->flush();
+
+ delay(20);
+
+ while (_WiFly.uart->available()) {
+ _WiFly.uart->read();
+ }
+
+ _WiFly.serverConnected = false;
+
+ value = -1;
+
+ // otherwise read from the buffer
+ } else {
+ if (closeBufferSize > 0) {
+ value = closeBuffer[0];
+ closeBufferIndex = 1;
+ }
+ }
+ }
+
+ return value;
+}
+
int WiFlyClient::peek() {
if (connections < 1) {
return -1;
@@ -113,9 +179,11 @@ void WiFlyClient::flush() {
void WiFlyClient::stop() {
_WiFly.sendCommand(F("close"), _WiFly.firmwareVersion);
- reset();
+ connections = 0;
- _WiFly.uart->flush();
+ while (_WiFly.uart->available()) {
+ _WiFly.uart->read();
+ }
_WiFly.serverConnected = false;
}
View
61 src/WiFly/WiFlyClient.h
@@ -7,33 +7,40 @@
class WiFlyClient : public Client {
-public:
- WiFlyClient();
-
- int connect();
-
- virtual int connect(IPAddress ip, uint16_t port);
- virtual int connect(const char *host, uint16_t port);
- virtual size_t write(uint8_t);
- virtual size_t write(const uint8_t *buf, size_t size);
- virtual int available();
- virtual int read();
- virtual int read(uint8_t *buf, size_t size);
- virtual int peek();
- virtual void flush();
- virtual void stop();
- virtual uint8_t connected();
- virtual operator bool();
-
- void reset();
-
-// friend class WiFlyServer;
-
- using Print::write;
-
-private:
- WiFlyDevice& _WiFly;
- uint8_t connections;
+ public:
+ WiFlyClient();
+
+ int connect();
+
+ virtual int connect(IPAddress ip, uint16_t port);
+ virtual int connect(const char *host, uint16_t port);
+ virtual size_t write(uint8_t);
+ virtual size_t write(const uint8_t *buf, size_t size);
+ virtual int available();
+ virtual int read();
+ virtual int read(uint8_t *buf, size_t size);
+ virtual int peek();
+ virtual void flush();
+ virtual void stop();
+ virtual uint8_t connected();
+ virtual operator bool();
+
+ void reset();
+
+ // friend class WiFlyServer;
+
+ using Print::write;
+
+ private:
+ int bufferedRead();
+
+ WiFlyDevice& _WiFly;
+ uint8_t connections;
+
+ const char* closeCmd;
+ int closeBuffer[7];
+ int closeBufferSize;
+ int closeBufferIndex;
};
#endif
View
91 src/WiFly/WiFlyDevice.cpp
@@ -24,7 +24,9 @@ void WiFlyDevice::begin() {
delay(250);
};
- fullVersion = getCommandResponse("ver");
+ uart->flush();
+
+ fullVersion = getCommandResponse(F("ver"));
while (fullVersion[index] != ',') {
++index;
@@ -35,6 +37,9 @@ void WiFlyDevice::begin() {
fullVersion = "<" + fullVersion + ">";
fullVersion.toCharArray(firmwareVersion, index - 7);
+
+ uart->flush();
+
}
void WiFlyDevice::sendBareCommand(const __FlashStringHelper* command) {
@@ -66,41 +71,40 @@ String WiFlyDevice::getCommandResponse(const __FlashStringHelper* command) {
// wait for response
while (!uart->available()) {
- delay(10);
+ delay(5);
}
while (uart->available()) {
- response += (char)uart->read();
- delay(1);
+ while (uart->available()) {
+ response += (char)uart->read();
+ }
+ delay(20);
}
+ exitCommandMode();
+
return response;
}
boolean WiFlyDevice::sendCommand(const __FlashStringHelper* command) {
- return sendCommand(command, "AOK", 2000, true);
+ return sendCommand(command, "AOK", 2000);
}
boolean WiFlyDevice::sendCommand(const __FlashStringHelper* command, char* response) {
- return sendCommand(command, response, 2000, true);
+ return sendCommand(command, response, 2000);
}
boolean WiFlyDevice::sendCommand(const __FlashStringHelper* command, char* response, int timeout) {
- return sendCommand(command, response, timeout, true);
-}
-
-boolean WiFlyDevice::sendCommand(const __FlashStringHelper* command, char* response, int timeout, boolean exit) {
boolean result;
sendBareCommand(command);
+ uart->flush();
+
// wait until the WiFly responds
result = waitForResponse(response, timeout);
- if (exit) {
- uart->flush();
- exitCommandMode();
- }
+ exitCommandMode();
return result;
}
@@ -112,9 +116,9 @@ void WiFlyDevice::sendBareCommand(char* command) {
enterCommandMode();
- uart->flush();
uart->print(command);
uart->write(13);
+ uart->flush();
uart->find("\n");
}
@@ -126,12 +130,14 @@ String WiFlyDevice::getCommandResponse(char* command) {
// wait for response
while (!uart->available()) {
- delay(10);
+ delay(5);
}
while (uart->available()) {
- response += (char)uart->read();
- delay(1);
+ while (uart->available()) {
+ response += (char)uart->read();
+ }
+ delay(20);
}
return response;
@@ -146,25 +152,33 @@ boolean WiFlyDevice::sendCommand(char* command, char* response) {
}
boolean WiFlyDevice::sendCommand(char* command, char* response, int timeout) {
- return sendCommand(command, response, timeout, true);
-}
-
-boolean WiFlyDevice::sendCommand(char* command, char* response, int timeout, boolean exit) {
boolean result;
sendBareCommand(command);
// wait until the WiFly responds
result = waitForResponse(response, timeout);
- if (exit) {
- uart->flush();
- exitCommandMode();
- }
+ uart->flush();
+ exitCommandMode();
return result;
}
+boolean WiFlyDevice::waitForResponse(char* response) {
+ waitForResponse(response, 2000);
+}
+
+boolean WiFlyDevice::waitForResponse(char* response, int timeout) {
+ uart->setTimeout(timeout);
+
+ while (!uart->available()) {
+ delay(10);
+ }
+
+ return uart->find(response);
+}
+
IPAddress WiFlyDevice::localIP() {
String result = getCommandResponse(F("get ip"));
int start;
@@ -234,7 +248,7 @@ boolean WiFlyDevice::reboot() {
// wait a bit until we have data coming in
while (!uart->available()) {
- delay(10);
+ delay(5);
}
uart->flush();
@@ -255,7 +269,7 @@ void WiFlyDevice::enterCommandMode(){
// wait a bit until we have data coming in
while (!uart->available()) {
- delay(10);
+ delay(5);
}
// make sure we're in command mode
@@ -276,24 +290,11 @@ void WiFlyDevice::exitCommandMode() {
uart->print("exit");
uart->write(13);
uart->find("EXIT");
- uart->flush();
+ clear();
commandModeFlag = false;
}
-boolean WiFlyDevice::waitForResponse(char* response) {
- waitForResponse(response, 2000);
-}
-
-boolean WiFlyDevice::waitForResponse(char* response, int timeout) {
- uart->setTimeout(timeout);
-
- while (!uart->available()) {
- delay(10);
- }
-
- return uart->find(response);
-}
IPAddress WiFlyDevice::stringToIPAddress(String str) {
int max = str.length() + 1;
@@ -310,4 +311,10 @@ IPAddress WiFlyDevice::stringToIPAddress(String str) {
ip[3] = atoi(strtok_r(NULL, ".", &i));
return ip;
+}
+
+void WiFlyDevice::clear() {
+ while (uart->available()) {
+ uart->read();
+ }
}
View
11 src/WiFly/WiFlyDevice.h
@@ -19,18 +19,13 @@ class WiFlyDevice {
boolean sendCommand(const __FlashStringHelper* command);
boolean sendCommand(const __FlashStringHelper* command, char* response);
boolean sendCommand(const __FlashStringHelper* command, char* response, int timeout);
- boolean sendCommand(const __FlashStringHelper* command, char* response, int timeout, boolean exit);
void sendBareCommand(char* command);
String getCommandResponse(char* command);
boolean sendCommand(char* command);
boolean sendCommand(char* command, char* response);
- boolean sendCommand(char* command, char* response, int timeout);
- boolean sendCommand(char* command, char* response, int timeout, boolean exit);
-
- void enterCommandMode();
- void exitCommandMode();
+ boolean sendCommand(char* command, char* response, int timeout);
boolean waitForResponse(char* response);
boolean waitForResponse(char* response, int timeout);
@@ -51,6 +46,10 @@ class WiFlyDevice {
private:
boolean commandModeFlag;
+
+ void enterCommandMode();
+ void exitCommandMode();
+ void clear();
};
#endif
View
7 src/WiFly/WiFlyServer.cpp
@@ -26,12 +26,17 @@ WiFlyClient WiFlyServer::available() {
activeClient.reset();
if (WiFly.uart->available() >= strlen(TOKEN_MATCH_OPEN)) {
- if (WiFly.waitForResponse(TOKEN_MATCH_OPEN, 1)) {
+ Serial.println("Got text, lookine for *OPEN*...");
+
+ if (WiFly.waitForResponse(TOKEN_MATCH_OPEN, 2000)) {
+
+ Serial.println("Found *OPEN*!");
WiFly.serverConnected = true;
activeClient.connect();
} else {
+ Serial.println("Didn't find *OPEN*!");
WiFly.uart->flush();
}
}

0 comments on commit 91a0bf7

Please sign in to comment.