mirror of
https://github.com/arduino/Arduino.git
synced 2024-12-01 12:24:14 +01:00
Merge pull request #2365 from cmaglie/ide-1.0.x-spi-transaction
[IDE 1.0.x (backport from 1.5.x)] SPI Transactions
This commit is contained in:
commit
1be99c3a1d
@ -2,12 +2,16 @@
|
||||
ARDUINO 1.0.7
|
||||
|
||||
[libraries]
|
||||
* Backported GSM from IDE 1.5.x
|
||||
* EthernetClien: use IANA recommended ephemeral port range, 49152-65535 (Jack Christensen, cifer-lee)
|
||||
* Backported SPI Transaction API from IDE 1.5.x (Paul Stoffregen)
|
||||
* Backported GSM from IDE 1.5.x: fix build regression
|
||||
* Backported Ethernet from IDE 1.5.x
|
||||
* Backported SD from IDE 1.5.x
|
||||
* Backported SPI from IDE 1.5.x
|
||||
* EthernetClient: use IANA recommended ephemeral port range, 49152-65535 (Jack Christensen, cifer-lee)
|
||||
|
||||
[core]
|
||||
* Fixed missing NOT_AN_INTERRUPT constant in digitalPinToInterrupt() macro
|
||||
* Fixed regression in HardwareSerial::available() introduced with https://github.com/arduino/Arduino/pull/2057
|
||||
* Fixed performance regression in HardwareSerial::available() introduced with https://github.com/arduino/Arduino/pull/2057
|
||||
|
||||
ARDUINO 1.0.6 - 2014.09.16
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
void yield(void);
|
||||
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
|
||||
|
31
hardware/arduino/cores/arduino/hooks.c
Normal file
31
hardware/arduino/cores/arduino/hooks.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Empty yield() hook.
|
||||
*
|
||||
* This function is intended to be used by library writers to build
|
||||
* libraries or sketches that supports cooperative threads.
|
||||
*
|
||||
* Its defined as a weak symbol and it can be redefined to implement a
|
||||
* real cooperative scheduler.
|
||||
*/
|
||||
static void __empty() {
|
||||
// Empty
|
||||
}
|
||||
void yield(void) __attribute__ ((weak, alias("__empty")));
|
@ -111,6 +111,7 @@ void delay(unsigned long ms)
|
||||
uint16_t start = (uint16_t)micros();
|
||||
|
||||
while (ms > 0) {
|
||||
yield();
|
||||
if (((uint16_t)micros() - start) >= 1000) {
|
||||
ms--;
|
||||
start += 1000;
|
||||
|
4
libraries/Ethernet/Dhcp.cpp
Executable file → Normal file
4
libraries/Ethernet/Dhcp.cpp
Executable file → Normal file
@ -1,13 +1,13 @@
|
||||
// DHCP Library v0.3 - April 25, 2009
|
||||
// Author: Jordan Terrell - blog.jordanterrell.com
|
||||
|
||||
#include "w5100.h"
|
||||
#include "utility/w5100.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "Dhcp.h"
|
||||
#include "Arduino.h"
|
||||
#include "util.h"
|
||||
#include "utility/util.h"
|
||||
|
||||
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
|
||||
{
|
||||
|
0
libraries/Ethernet/Dhcp.h
Executable file → Normal file
0
libraries/Ethernet/Dhcp.h
Executable file → Normal file
@ -2,9 +2,9 @@
|
||||
// (c) Copyright 2009-2010 MCQN Ltd.
|
||||
// Released under Apache License, version 2.0
|
||||
|
||||
#include "w5100.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "EthernetUdp.h"
|
||||
#include "util.h"
|
||||
#include "utility/util.h"
|
||||
|
||||
#include "Dns.h"
|
||||
#include <string.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "w5100.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "Ethernet.h"
|
||||
#include "Dhcp.h"
|
||||
|
||||
@ -16,8 +16,10 @@ int EthernetClass::begin(uint8_t *mac_address)
|
||||
|
||||
// Initialise the basic info
|
||||
W5100.init();
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac_address);
|
||||
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
|
||||
SPI.endTransaction();
|
||||
|
||||
// Now try to get our config info from a DHCP server
|
||||
int ret = _dhcp->beginWithDHCP(mac_address);
|
||||
@ -25,9 +27,11 @@ int EthernetClass::begin(uint8_t *mac_address)
|
||||
{
|
||||
// We've successfully found a DHCP server and got our configuration info, so set things
|
||||
// accordingly
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
}
|
||||
|
||||
@ -61,10 +65,12 @@ void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dn
|
||||
void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
W5100.init();
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setMACAddress(mac);
|
||||
W5100.setIPAddress(local_ip._address);
|
||||
W5100.setGatewayIp(gateway._address);
|
||||
W5100.setSubnetMask(subnet._address);
|
||||
W5100.setIPAddress(local_ip.raw_address());
|
||||
W5100.setGatewayIp(gateway.raw_address());
|
||||
W5100.setSubnetMask(subnet.raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = dns_server;
|
||||
}
|
||||
|
||||
@ -80,9 +86,11 @@ int EthernetClass::maintain(){
|
||||
case DHCP_CHECK_RENEW_OK:
|
||||
case DHCP_CHECK_REBIND_OK:
|
||||
//we might have got a new IP.
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
|
||||
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
|
||||
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
|
||||
SPI.endTransaction();
|
||||
_dnsServerAddress = _dhcp->getDnsServerIp();
|
||||
break;
|
||||
default:
|
||||
@ -96,21 +104,27 @@ int EthernetClass::maintain(){
|
||||
IPAddress EthernetClass::localIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getIPAddress(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::subnetMask()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getSubnetMask(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPAddress EthernetClass::gatewayIP()
|
||||
{
|
||||
IPAddress ret;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.getGatewayIp(ret.raw_address());
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "utility/socket.h"
|
||||
|
||||
extern "C" {
|
||||
#include "string.h"
|
||||
@ -40,7 +40,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < MAX_SOCK_NUM; i++) {
|
||||
uint8_t s = W5100.readSnSR(i);
|
||||
uint8_t s = socketStatus(i);
|
||||
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
|
||||
_sock = i;
|
||||
break;
|
||||
@ -88,7 +88,7 @@ size_t EthernetClient::write(const uint8_t *buf, size_t size) {
|
||||
|
||||
int EthernetClient::available() {
|
||||
if (_sock != MAX_SOCK_NUM)
|
||||
return W5100.getRXReceivedSize(_sock);
|
||||
return recvAvailable(_sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -120,8 +120,7 @@ int EthernetClient::peek() {
|
||||
}
|
||||
|
||||
void EthernetClient::flush() {
|
||||
while (available())
|
||||
read();
|
||||
::flush(_sock);
|
||||
}
|
||||
|
||||
void EthernetClient::stop() {
|
||||
@ -154,7 +153,7 @@ uint8_t EthernetClient::connected() {
|
||||
|
||||
uint8_t EthernetClient::status() {
|
||||
if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
|
||||
return W5100.readSnSR(_sock);
|
||||
return socketStatus(_sock);
|
||||
}
|
||||
|
||||
// the next function allows us to use the client returned by
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "utility/socket.h"
|
||||
extern "C" {
|
||||
#include "string.h"
|
||||
}
|
||||
|
@ -26,8 +26,8 @@
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "utility/socket.h"
|
||||
#include "Ethernet.h"
|
||||
#include "Udp.h"
|
||||
#include "Dns.h"
|
||||
@ -41,7 +41,7 @@ uint8_t EthernetUDP::begin(uint16_t port) {
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < MAX_SOCK_NUM; i++) {
|
||||
uint8_t s = W5100.readSnSR(i);
|
||||
uint8_t s = socketStatus(i);
|
||||
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
|
||||
_sock = i;
|
||||
break;
|
||||
@ -120,7 +120,7 @@ int EthernetUDP::parsePacket()
|
||||
// discard any remaining bytes in the last packet
|
||||
flush();
|
||||
|
||||
if (W5100.getRXReceivedSize(_sock) > 0)
|
||||
if (recvAvailable(_sock) > 0)
|
||||
{
|
||||
//HACK - hand-parse the UDP packet using TCP recv method
|
||||
uint8_t tmpBuf[8];
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*
|
||||
SCP1000 Barometric Pressure Sensor Display
|
||||
|
||||
|
||||
Serves the output of a Barometric Pressure Sensor as a web page.
|
||||
Uses the SPI library. For details on the sensor, see:
|
||||
http://www.sparkfun.com/commerce/product_info.php?products_id=8161
|
||||
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
|
||||
|
||||
|
||||
This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
|
||||
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
|
||||
|
||||
|
||||
Circuit:
|
||||
SCP1000 sensor attached to pins 6,7, and 11 - 13:
|
||||
DRDY: pin 6
|
||||
@ -16,7 +16,7 @@
|
||||
MOSI: pin 11
|
||||
MISO: pin 12
|
||||
SCK: pin 13
|
||||
|
||||
|
||||
created 31 July 2010
|
||||
by Tom Igoe
|
||||
*/
|
||||
@ -28,16 +28,17 @@
|
||||
|
||||
// assign a MAC address for the ethernet controller.
|
||||
// fill in your address here:
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
|
||||
};
|
||||
// assign an IP address for the controller:
|
||||
IPAddress ip(192,168,1,20);
|
||||
IPAddress gateway(192,168,1,1);
|
||||
IPAddress ip(192, 168, 1, 20);
|
||||
IPAddress gateway(192, 168, 1, 1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
|
||||
// Initialize the Ethernet server library
|
||||
// with the IP address and port you want to use
|
||||
// with the IP address and port you want to use
|
||||
// (port 80 is default for HTTP):
|
||||
EthernetServer server(80);
|
||||
|
||||
@ -49,7 +50,7 @@ const int TEMPERATURE = 0x21; //16 bit temperature reading
|
||||
|
||||
// pins used for the connection with the sensor
|
||||
// the others you need are controlled by the SPI library):
|
||||
const int dataReadyPin = 6;
|
||||
const int dataReadyPin = 6;
|
||||
const int chipSelectPin = 7;
|
||||
|
||||
float temperature = 0.0;
|
||||
@ -83,9 +84,9 @@ void setup() {
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop() {
|
||||
// check for a reading no more than once a second.
|
||||
if (millis() - lastReadingTime > 1000){
|
||||
if (millis() - lastReadingTime > 1000) {
|
||||
// if there's a reading ready, read it:
|
||||
// don't do anything until the data ready pin is high:
|
||||
if (digitalRead(dataReadyPin) == HIGH) {
|
||||
@ -109,13 +110,13 @@ void getData() {
|
||||
temperature = (float)tempData / 20.0;
|
||||
|
||||
//Read the pressure data highest 3 bits:
|
||||
byte pressureDataHigh = readRegister(0x1F, 1);
|
||||
byte pressureDataHigh = readRegister(0x1F, 1);
|
||||
pressureDataHigh &= 0b00000111; //you only needs bits 2 to 0
|
||||
|
||||
//Read the pressure data lower 16 bits:
|
||||
unsigned int pressureDataLow = readRegister(0x20, 2);
|
||||
unsigned int pressureDataLow = readRegister(0x20, 2);
|
||||
//combine the two parts into one 19-bit number:
|
||||
pressure = ((pressureDataHigh << 16) | pressureDataLow)/4;
|
||||
pressure = ((pressureDataHigh << 16) | pressureDataLow) / 4;
|
||||
|
||||
Serial.print("Temperature: ");
|
||||
Serial.print(temperature);
|
||||
@ -149,13 +150,13 @@ void listenForEthernetClients() {
|
||||
client.println("<br />");
|
||||
client.print("Pressure: " + String(pressure));
|
||||
client.print(" Pa");
|
||||
client.println("<br />");
|
||||
client.println("<br />");
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
// you're starting a new line
|
||||
currentLineIsBlank = true;
|
||||
}
|
||||
}
|
||||
else if (c != '\r') {
|
||||
// you've gotten a character on the current line
|
||||
currentLineIsBlank = false;
|
||||
@ -167,7 +168,7 @@ void listenForEthernetClients() {
|
||||
// close the connection:
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Send a write command to SCP1000
|
||||
@ -179,20 +180,20 @@ void writeRegister(byte registerName, byte registerValue) {
|
||||
registerName |= 0b00000010; //Write command
|
||||
|
||||
// take the chip select low to select the device:
|
||||
digitalWrite(chipSelectPin, LOW);
|
||||
digitalWrite(chipSelectPin, LOW);
|
||||
|
||||
SPI.transfer(registerName); //Send register location
|
||||
SPI.transfer(registerValue); //Send value to record into register
|
||||
|
||||
// take the chip select high to de-select:
|
||||
digitalWrite(chipSelectPin, HIGH);
|
||||
digitalWrite(chipSelectPin, HIGH);
|
||||
}
|
||||
|
||||
|
||||
//Read register from the SCP1000:
|
||||
unsigned int readRegister(byte registerName, int numBytes) {
|
||||
byte inByte = 0; // incoming from the SPI read
|
||||
unsigned int result = 0; // result to return
|
||||
unsigned int result = 0; // result to return
|
||||
|
||||
// SCP1000 expects the register name in the upper 6 bits
|
||||
// of the byte:
|
||||
@ -201,22 +202,22 @@ unsigned int readRegister(byte registerName, int numBytes) {
|
||||
registerName &= 0b11111100; //Read command
|
||||
|
||||
// take the chip select low to select the device:
|
||||
digitalWrite(chipSelectPin, LOW);
|
||||
digitalWrite(chipSelectPin, LOW);
|
||||
// send the device the register you want to read:
|
||||
int command = SPI.transfer(registerName);
|
||||
int command = SPI.transfer(registerName);
|
||||
// send a value of 0 to read the first byte returned:
|
||||
inByte = SPI.transfer(0x00);
|
||||
|
||||
inByte = SPI.transfer(0x00);
|
||||
|
||||
result = inByte;
|
||||
// if there's more than one byte returned,
|
||||
// if there's more than one byte returned,
|
||||
// shift the first byte then get the second byte:
|
||||
if (numBytes > 1){
|
||||
if (numBytes > 1) {
|
||||
result = inByte << 8;
|
||||
inByte = SPI.transfer(0x00);
|
||||
result = result |inByte;
|
||||
inByte = SPI.transfer(0x00);
|
||||
result = result | inByte;
|
||||
}
|
||||
// take the chip select high to de-select:
|
||||
digitalWrite(chipSelectPin, HIGH);
|
||||
digitalWrite(chipSelectPin, HIGH);
|
||||
// return the result:
|
||||
return(result);
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
Chat Server
|
||||
|
||||
|
||||
A simple server that distributes any incoming messages to all
|
||||
connected clients. To use telnet to your device's IP address and type.
|
||||
You can see the client's input in the serial monitor as well.
|
||||
Using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
Using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
* Analog inputs attached to pins A0 through A5 (optional)
|
||||
|
||||
|
||||
created 18 Dec 2009
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -23,10 +23,11 @@
|
||||
// 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 };
|
||||
IPAddress ip(192,168,1, 177);
|
||||
IPAddress gateway(192,168,1, 1);
|
||||
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);
|
||||
|
||||
|
||||
@ -39,9 +40,9 @@ void setup() {
|
||||
Ethernet.begin(mac, ip, gateway, subnet);
|
||||
// start listening for clients
|
||||
server.begin();
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -58,11 +59,11 @@ void loop() {
|
||||
if (client) {
|
||||
if (!alreadyConnected) {
|
||||
// clead out the input buffer:
|
||||
client.flush();
|
||||
client.flush();
|
||||
Serial.println("We have a new client");
|
||||
client.println("Hello, client!");
|
||||
client.println("Hello, client!");
|
||||
alreadyConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (client.available() > 0) {
|
||||
// read the bytes incoming from the client:
|
||||
|
@ -1,17 +1,17 @@
|
||||
/*
|
||||
DHCP-based IP printer
|
||||
|
||||
|
||||
This sketch uses the DHCP extensions to the Ethernet library
|
||||
to get an IP address via DHCP and print the address obtained.
|
||||
using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
|
||||
created 12 April 2011
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -19,19 +19,20 @@
|
||||
|
||||
// Enter a MAC address for your controller below.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
byte mac[] = {
|
||||
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
|
||||
byte mac[] = {
|
||||
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
|
||||
};
|
||||
|
||||
// Initialize the Ethernet client library
|
||||
// with the IP address and port of the server
|
||||
// with the IP address and port of the server
|
||||
// that you want to connect to (port 80 is default for HTTP):
|
||||
EthernetClient client;
|
||||
|
||||
void setup() {
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
// this check is only needed on the Leonardo:
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -39,7 +40,7 @@ void setup() {
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
for(;;)
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
// print your local IP address:
|
||||
@ -47,7 +48,7 @@ void setup() {
|
||||
for (byte thisByte = 0; thisByte < 4; thisByte++) {
|
||||
// print the value of each byte of the IP address:
|
||||
Serial.print(Ethernet.localIP()[thisByte], DEC);
|
||||
Serial.print(".");
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
DHCP Chat Server
|
||||
|
||||
|
||||
A simple server that distributes any incoming messages to all
|
||||
connected clients. To use telnet to your device's IP address and type.
|
||||
You can see the client's input in the serial monitor as well.
|
||||
Using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
Using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
THis version attempts to get an IP address using DHCP
|
||||
|
||||
|
||||
Circuit:
|
||||
* 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
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -24,10 +24,11 @@
|
||||
// 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[] = {
|
||||
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
|
||||
IPAddress ip(192,168,1, 177);
|
||||
IPAddress gateway(192,168,1, 1);
|
||||
byte mac[] = {
|
||||
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
|
||||
};
|
||||
IPAddress ip(192, 168, 1, 177);
|
||||
IPAddress gateway(192, 168, 1, 1);
|
||||
IPAddress subnet(255, 255, 0, 0);
|
||||
|
||||
// telnet defaults to port 23
|
||||
@ -38,7 +39,7 @@ void setup() {
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
// this check is only needed on the Leonardo:
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -56,12 +57,12 @@ void setup() {
|
||||
for (byte thisByte = 0; thisByte < 4; thisByte++) {
|
||||
// print the value of each byte of the IP address:
|
||||
Serial.print(ip[thisByte], DEC);
|
||||
Serial.print(".");
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
// start listening for clients
|
||||
server.begin();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@ -72,7 +73,7 @@ void loop() {
|
||||
if (client) {
|
||||
if (!gotAMessage) {
|
||||
Serial.println("We have a new client");
|
||||
client.println("Hello, client!");
|
||||
client.println("Hello, client!");
|
||||
gotAMessage = true;
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Telnet client
|
||||
|
||||
|
||||
This sketch connects to a a telnet server (http://www.google.com)
|
||||
using an Arduino Wiznet Ethernet shield. You'll need a telnet server
|
||||
using an Arduino Wiznet Ethernet shield. You'll need a telnet server
|
||||
to test this with.
|
||||
Processing's ChatServer example (part of the network library) works well,
|
||||
Processing's ChatServer example (part of the network library) works well,
|
||||
running on port 10002. It can be found as part of the examples
|
||||
in the Processing application, available at
|
||||
in the Processing application, available at
|
||||
http://processing.org/
|
||||
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
|
||||
created 14 Sep 2010
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -23,15 +23,16 @@
|
||||
|
||||
// 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 };
|
||||
IPAddress ip(192,168,1,177);
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
|
||||
};
|
||||
IPAddress ip(192, 168, 1, 177);
|
||||
|
||||
// Enter the IP address of the server you're connecting to:
|
||||
IPAddress server(1,1,1,1);
|
||||
IPAddress server(1, 1, 1, 1);
|
||||
|
||||
// Initialize the Ethernet client library
|
||||
// with the IP address and port of the server
|
||||
// with the IP address and port of the server
|
||||
// that you want to connect to (port 23 is default for telnet;
|
||||
// if you're using Processing's ChatServer, use port 10002):
|
||||
EthernetClient client;
|
||||
@ -39,9 +40,9 @@ EthernetClient client;
|
||||
void setup() {
|
||||
// start the Ethernet connection:
|
||||
Ethernet.begin(mac, ip);
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ void setup() {
|
||||
// if you get a connection, report back via serial:
|
||||
if (client.connect(server, 10002)) {
|
||||
Serial.println("connected");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if you didn't get a connection to the server:
|
||||
Serial.println("connection failed");
|
||||
@ -62,7 +63,7 @@ void setup() {
|
||||
|
||||
void loop()
|
||||
{
|
||||
// if there are incoming bytes available
|
||||
// if there are incoming bytes available
|
||||
// from the server, read them and print them:
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
@ -74,7 +75,7 @@ void loop()
|
||||
while (Serial.available() > 0) {
|
||||
char inChar = Serial.read();
|
||||
if (client.connected()) {
|
||||
client.print(inChar);
|
||||
client.print(inChar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +85,7 @@ void loop()
|
||||
Serial.println("disconnecting.");
|
||||
client.stop();
|
||||
// do nothing:
|
||||
while(true);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,13 @@
|
||||
UDPSendReceive.pde:
|
||||
This sketch receives UDP message strings, prints them to the serial port
|
||||
and sends an "acknowledge" string back to the sender
|
||||
|
||||
A Processing sketch is included at the end of file that can be used to send
|
||||
|
||||
A Processing sketch is included at the end of file that can be used to send
|
||||
and received messages for testing with a computer.
|
||||
|
||||
|
||||
created 21 Aug 2010
|
||||
by Michael Margolis
|
||||
|
||||
|
||||
This code is in the public domain.
|
||||
*/
|
||||
|
||||
@ -20,8 +20,9 @@
|
||||
|
||||
// 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);
|
||||
|
||||
unsigned int localPort = 8888; // local port to listen on
|
||||
@ -35,7 +36,7 @@ EthernetUDP Udp;
|
||||
|
||||
void setup() {
|
||||
// start the Ethernet and UDP:
|
||||
Ethernet.begin(mac,ip);
|
||||
Ethernet.begin(mac, ip);
|
||||
Udp.begin(localPort);
|
||||
|
||||
Serial.begin(9600);
|
||||
@ -44,13 +45,13 @@ void setup() {
|
||||
void loop() {
|
||||
// if there's data available, read a packet
|
||||
int packetSize = Udp.parsePacket();
|
||||
if(packetSize)
|
||||
if (packetSize)
|
||||
{
|
||||
Serial.print("Received packet of size ");
|
||||
Serial.println(packetSize);
|
||||
Serial.print("From ");
|
||||
IPAddress remote = Udp.remoteIP();
|
||||
for (int i =0; i < 4; i++)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Serial.print(remote[i], DEC);
|
||||
if (i < 3)
|
||||
@ -62,7 +63,7 @@ void loop() {
|
||||
Serial.println(Udp.remotePort());
|
||||
|
||||
// read the packet into packetBufffer
|
||||
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
|
||||
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
|
||||
Serial.println("Contents:");
|
||||
Serial.println(packetBuffer);
|
||||
|
||||
@ -78,40 +79,40 @@ void loop() {
|
||||
/*
|
||||
Processing sketch to run with this example
|
||||
=====================================================
|
||||
|
||||
// Processing UDP example to send and receive string data from Arduino
|
||||
|
||||
// Processing UDP example to send and receive string data from Arduino
|
||||
// press any key to send the "Hello Arduino" message
|
||||
|
||||
|
||||
|
||||
|
||||
import hypermedia.net.*;
|
||||
|
||||
|
||||
UDP udp; // define the UDP object
|
||||
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000
|
||||
//udp.log( true ); // <-- printout the connection activity
|
||||
udp.listen( true ); // and wait for incoming message
|
||||
udp.listen( true ); // and wait for incoming message
|
||||
}
|
||||
|
||||
|
||||
void draw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
String ip = "192.168.1.177"; // the remote IP address
|
||||
int port = 8888; // the destination port
|
||||
|
||||
|
||||
udp.send("Hello World", ip, port ); // the message to send
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void receive( byte[] data ) { // <-- default handler
|
||||
//void receive( byte[] data, String ip, int port ) { // <-- extended handler
|
||||
|
||||
for(int i=0; i < data.length; i++)
|
||||
print(char(data[i]));
|
||||
println();
|
||||
|
||||
for(int i=0; i < data.length; i++)
|
||||
print(char(data[i]));
|
||||
println();
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -1,55 +1,47 @@
|
||||
/*
|
||||
|
||||
Udp NTP Client
|
||||
|
||||
|
||||
Get the time from a Network Time Protocol (NTP) time server
|
||||
Demonstrates use of UDP sendPacket and ReceivePacket
|
||||
For more on NTP time servers and the messages needed to communicate with them,
|
||||
Demonstrates use of UDP sendPacket and ReceivePacket
|
||||
For more on NTP time servers and the messages needed to communicate with them,
|
||||
see http://en.wikipedia.org/wiki/Network_Time_Protocol
|
||||
|
||||
Warning: NTP Servers are subject to temporary failure or IP address change.
|
||||
Plese check
|
||||
|
||||
http://tf.nist.gov/tf-cgi/servers.cgi
|
||||
|
||||
if the time server used in the example didn't work.
|
||||
|
||||
created 4 Sep 2010
|
||||
created 4 Sep 2010
|
||||
by Michael Margolis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
This code is in the public domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
#include <EthernetUdp.h>
|
||||
|
||||
// Enter a MAC address for your controller below.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
|
||||
};
|
||||
|
||||
unsigned int localPort = 8888; // local port to listen for UDP packets
|
||||
unsigned int localPort = 8888; // local port to listen for UDP packets
|
||||
|
||||
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server
|
||||
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server
|
||||
// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
|
||||
char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server
|
||||
|
||||
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
|
||||
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
|
||||
|
||||
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
|
||||
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
|
||||
|
||||
// A UDP instance to let us send and receive packets over UDP
|
||||
EthernetUDP Udp;
|
||||
|
||||
void setup()
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -58,7 +50,7 @@ void setup()
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
for(;;)
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
Udp.begin(localPort);
|
||||
@ -68,58 +60,58 @@ void loop()
|
||||
{
|
||||
sendNTPpacket(timeServer); // send an NTP packet to a time server
|
||||
|
||||
// wait to see if a reply is available
|
||||
delay(1000);
|
||||
if ( Udp.parsePacket() ) {
|
||||
// wait to see if a reply is available
|
||||
delay(1000);
|
||||
if ( Udp.parsePacket() ) {
|
||||
// We've received a packet, read the data from it
|
||||
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
|
||||
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
|
||||
|
||||
//the timestamp starts at byte 40 of the received packet and is four bytes,
|
||||
// or two words, long. First, esxtract the two words:
|
||||
|
||||
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
|
||||
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
|
||||
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
|
||||
// combine the four bytes (two words) into a long integer
|
||||
// this is NTP time (seconds since Jan 1 1900):
|
||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||
Serial.print("Seconds since Jan 1 1900 = " );
|
||||
Serial.println(secsSince1900);
|
||||
Serial.println(secsSince1900);
|
||||
|
||||
// now convert NTP time into everyday time:
|
||||
Serial.print("Unix time = ");
|
||||
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
|
||||
const unsigned long seventyYears = 2208988800UL;
|
||||
const unsigned long seventyYears = 2208988800UL;
|
||||
// subtract seventy years:
|
||||
unsigned long epoch = secsSince1900 - seventyYears;
|
||||
unsigned long epoch = secsSince1900 - seventyYears;
|
||||
// print Unix time:
|
||||
Serial.println(epoch);
|
||||
Serial.println(epoch);
|
||||
|
||||
|
||||
// print the hour, minute and second:
|
||||
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
|
||||
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
|
||||
Serial.print(':');
|
||||
Serial.print(':');
|
||||
if ( ((epoch % 3600) / 60) < 10 ) {
|
||||
// In the first 10 minutes of each hour, we'll want a leading '0'
|
||||
Serial.print('0');
|
||||
}
|
||||
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
|
||||
Serial.print(':');
|
||||
Serial.print(':');
|
||||
if ( (epoch % 60) < 10 ) {
|
||||
// In the first 10 seconds of each minute, we'll want a leading '0'
|
||||
Serial.print('0');
|
||||
}
|
||||
Serial.println(epoch %60); // print the second
|
||||
Serial.println(epoch % 60); // print the second
|
||||
}
|
||||
// wait ten seconds before asking for the time again
|
||||
delay(10000);
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
// send an NTP request to the time server at the given address
|
||||
unsigned long sendNTPpacket(IPAddress& address)
|
||||
// send an NTP request to the time server at the given address
|
||||
unsigned long sendNTPpacket(char* address)
|
||||
{
|
||||
// set all bytes in the buffer to 0
|
||||
memset(packetBuffer, 0, NTP_PACKET_SIZE);
|
||||
memset(packetBuffer, 0, NTP_PACKET_SIZE);
|
||||
// Initialize values needed to form NTP request
|
||||
// (see URL above for details on the packets)
|
||||
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||
@ -127,16 +119,16 @@ unsigned long sendNTPpacket(IPAddress& address)
|
||||
packetBuffer[2] = 6; // Polling Interval
|
||||
packetBuffer[3] = 0xEC; // Peer Clock Precision
|
||||
// 8 bytes of zero for Root Delay & Root Dispersion
|
||||
packetBuffer[12] = 49;
|
||||
packetBuffer[12] = 49;
|
||||
packetBuffer[13] = 0x4E;
|
||||
packetBuffer[14] = 49;
|
||||
packetBuffer[15] = 52;
|
||||
|
||||
// all NTP fields have been given values, now
|
||||
// you can send a packet requesting a timestamp:
|
||||
// you can send a packet requesting a timestamp:
|
||||
Udp.beginPacket(address, 123); //NTP requests are to port 123
|
||||
Udp.write(packetBuffer,NTP_PACKET_SIZE);
|
||||
Udp.endPacket();
|
||||
Udp.write(packetBuffer, NTP_PACKET_SIZE);
|
||||
Udp.endPacket();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
/*
|
||||
Web client
|
||||
|
||||
|
||||
This sketch connects to a website (http://www.google.com)
|
||||
using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
|
||||
created 18 Dec 2009
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe, based on work by Adrian McEwen
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -26,17 +26,17 @@ byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
||||
char server[] = "www.google.com"; // name address for Google (using DNS)
|
||||
|
||||
// Set the static IP address to use if the DHCP fails to assign
|
||||
IPAddress ip(192,168,0,177);
|
||||
IPAddress ip(192, 168, 0, 177);
|
||||
|
||||
// Initialize the Ethernet client library
|
||||
// with the IP address and port of the server
|
||||
// with the IP address and port of the server
|
||||
// that you want to connect to (port 80 is default for HTTP):
|
||||
EthernetClient client;
|
||||
|
||||
void setup() {
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ void setup() {
|
||||
client.println("Host: www.google.com");
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// kf you didn't get a connection to the server:
|
||||
Serial.println("connection failed");
|
||||
@ -68,7 +68,7 @@ void setup() {
|
||||
|
||||
void loop()
|
||||
{
|
||||
// if there are incoming bytes available
|
||||
// if there are incoming bytes available
|
||||
// from the server, read them and print them:
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
@ -82,7 +82,7 @@ void loop()
|
||||
client.stop();
|
||||
|
||||
// do nothing forevermore:
|
||||
while(true);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,25 @@
|
||||
/*
|
||||
Repeating Web client
|
||||
|
||||
|
||||
This sketch connects to a a web server and makes a request
|
||||
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 uses DNS, by assigning the Ethernet client with a MAC address,
|
||||
IP address, and DNS address.
|
||||
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
|
||||
|
||||
created 19 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
modified 21 Jan 2014
|
||||
by Federico Vanzati
|
||||
|
||||
http://arduino.cc/en/Tutorial/WebClientRepeating
|
||||
This code is in the public domain.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -25,27 +27,33 @@
|
||||
|
||||
// assign a MAC address for the ethernet controller.
|
||||
// fill in your address here:
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
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,0,20);
|
||||
IPAddress ip(192, 168, 1, 177);
|
||||
|
||||
// fill in your Domain Name Server address here:
|
||||
IPAddress myDns(1,1,1,1);
|
||||
IPAddress myDns(1, 1, 1, 1);
|
||||
|
||||
// initialize the library instance:
|
||||
EthernetClient client;
|
||||
|
||||
char server[] = "www.arduino.cc";
|
||||
//IPAddress server(64,131,82,241);
|
||||
|
||||
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 = 60*1000; // delay between updates, in milliseconds
|
||||
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
|
||||
const unsigned long postingInterval = 10L * 1000L; // delay between updates, in milliseconds
|
||||
// the "L" is needed to use long type numbers
|
||||
|
||||
void setup() {
|
||||
// start serial port:
|
||||
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 using a fixed IP address and DNS server:
|
||||
@ -61,29 +69,23 @@ void loop() {
|
||||
// purposes only:
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
Serial.print(c);
|
||||
Serial.write(c);
|
||||
}
|
||||
|
||||
// if there's no net connection, but there was one last time
|
||||
// through the loop, then stop the client:
|
||||
if (!client.connected() && lastConnected) {
|
||||
Serial.println();
|
||||
Serial.println("disconnecting.");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
// if you're not connected, and ten seconds have passed since
|
||||
// your last connection, then connect again and send data:
|
||||
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
|
||||
// if ten seconds have passed since your last connection,
|
||||
// then connect again and send data:
|
||||
if (millis() - lastConnectionTime > postingInterval) {
|
||||
httpRequest();
|
||||
}
|
||||
// store the state of the connection for next time through
|
||||
// the loop:
|
||||
lastConnected = client.connected();
|
||||
|
||||
}
|
||||
|
||||
// this method makes a HTTP connection to the server:
|
||||
void httpRequest() {
|
||||
// close any connection before send a new request.
|
||||
// This will free the socket on the WiFi shield
|
||||
client.stop();
|
||||
|
||||
// if there's a successful connection:
|
||||
if (client.connect(server, 80)) {
|
||||
Serial.println("connecting...");
|
||||
@ -96,15 +98,11 @@ void httpRequest() {
|
||||
|
||||
// note the time that the connection was made:
|
||||
lastConnectionTime = millis();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if you couldn't make a connection:
|
||||
Serial.println("connection failed");
|
||||
Serial.println("disconnecting.");
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
Web Server
|
||||
|
||||
|
||||
A simple web server that shows the value of the analog input pins.
|
||||
using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
using an Arduino Wiznet Ethernet shield.
|
||||
|
||||
Circuit:
|
||||
* Ethernet shield attached to pins 10, 11, 12, 13
|
||||
* Analog inputs attached to pins A0 through A5 (optional)
|
||||
|
||||
|
||||
created 18 Dec 2009
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
@ -20,19 +20,20 @@
|
||||
|
||||
// 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 };
|
||||
IPAddress ip(192,168,1,177);
|
||||
byte mac[] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
|
||||
};
|
||||
IPAddress ip(192, 168, 1, 177);
|
||||
|
||||
// Initialize the Ethernet server library
|
||||
// with the IP address and port you want to use
|
||||
// with the IP address and port you want to use
|
||||
// (port 80 is default for HTTP):
|
||||
EthernetServer server(80);
|
||||
|
||||
void setup() {
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -64,7 +65,7 @@ void loop() {
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Content-Type: text/html");
|
||||
client.println("Connection: close"); // the connection will be closed after completion of the response
|
||||
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
|
||||
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
|
||||
client.println();
|
||||
client.println("<!DOCTYPE HTML>");
|
||||
client.println("<html>");
|
||||
@ -75,7 +76,7 @@ void loop() {
|
||||
client.print(analogChannel);
|
||||
client.print(" is ");
|
||||
client.print(sensorReading);
|
||||
client.println("<br />");
|
||||
client.println("<br />");
|
||||
}
|
||||
client.println("</html>");
|
||||
break;
|
||||
@ -83,7 +84,7 @@ void loop() {
|
||||
if (c == '\n') {
|
||||
// you're starting a new line
|
||||
currentLineIsBlank = true;
|
||||
}
|
||||
}
|
||||
else if (c != '\r') {
|
||||
// you've gotten a character on the current line
|
||||
currentLineIsBlank = false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
#include "utility/w5100.h"
|
||||
#include "utility/socket.h"
|
||||
|
||||
static uint16_t local_port;
|
||||
|
||||
@ -12,6 +12,7 @@ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
|
||||
if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE))
|
||||
{
|
||||
close(s);
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.writeSnMR(s, protocol | flag);
|
||||
if (port != 0) {
|
||||
W5100.writeSnPORT(s, port);
|
||||
@ -22,7 +23,7 @@ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
|
||||
}
|
||||
|
||||
W5100.execCmdSn(s, Sock_OPEN);
|
||||
|
||||
SPI.endTransaction();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -30,13 +31,24 @@ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
|
||||
}
|
||||
|
||||
|
||||
uint8_t socketStatus(SOCKET s)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
uint8_t status = W5100.readSnSR(s);
|
||||
SPI.endTransaction();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function close the socket and parameter is "s" which represent the socket number
|
||||
*/
|
||||
void close(SOCKET s)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.execCmdSn(s, Sock_CLOSE);
|
||||
W5100.writeSnIR(s, 0xFF);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
|
||||
@ -46,9 +58,13 @@ void close(SOCKET s)
|
||||
*/
|
||||
uint8_t listen(SOCKET s)
|
||||
{
|
||||
if (W5100.readSnSR(s) != SnSR::INIT)
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
if (W5100.readSnSR(s) != SnSR::INIT) {
|
||||
SPI.endTransaction();
|
||||
return 0;
|
||||
}
|
||||
W5100.execCmdSn(s, Sock_LISTEN);
|
||||
SPI.endTransaction();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -70,9 +86,11 @@ uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
|
||||
return 0;
|
||||
|
||||
// set destination IP
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.writeSnDIPR(s, addr);
|
||||
W5100.writeSnDPORT(s, port);
|
||||
W5100.execCmdSn(s, Sock_CONNECT);
|
||||
SPI.endTransaction();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -85,7 +103,9 @@ uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
|
||||
*/
|
||||
void disconnect(SOCKET s)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.execCmdSn(s, Sock_DISCON);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
|
||||
@ -107,17 +127,21 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
// if freebuf is available, start.
|
||||
do
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
freesize = W5100.getTXFreeSize(s);
|
||||
status = W5100.readSnSR(s);
|
||||
SPI.endTransaction();
|
||||
if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
while (freesize < ret);
|
||||
|
||||
// copy data
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.send_data_processing(s, (uint8_t *)buf, ret);
|
||||
W5100.execCmdSn(s, Sock_SEND);
|
||||
|
||||
@ -127,12 +151,17 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
/* m2008.01 [bj] : reduce code */
|
||||
if ( W5100.readSnSR(s) == SnSR::CLOSED )
|
||||
{
|
||||
SPI.endTransaction();
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
SPI.endTransaction();
|
||||
yield();
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
}
|
||||
/* +2008.01 bj */
|
||||
W5100.writeSnIR(s, SnIR::SEND_OK);
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -146,6 +175,7 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
|
||||
{
|
||||
// Check how much data is available
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
int16_t ret = W5100.getRXReceivedSize(s);
|
||||
if ( ret == 0 )
|
||||
{
|
||||
@ -172,6 +202,16 @@ int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
|
||||
W5100.recv_data_processing(s, buf, ret);
|
||||
W5100.execCmdSn(s, Sock_RECV);
|
||||
}
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int16_t recvAvailable(SOCKET s)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
int16_t ret = W5100.getRXReceivedSize(s);
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -183,8 +223,9 @@ int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
|
||||
*/
|
||||
uint16_t peek(SOCKET s, uint8_t *buf)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.recv_data_processing(s, buf, 1, 1);
|
||||
|
||||
SPI.endTransaction();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -213,6 +254,7 @@ uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint1
|
||||
}
|
||||
else
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.writeSnDIPR(s, addr);
|
||||
W5100.writeSnDPORT(s, port);
|
||||
|
||||
@ -227,12 +269,17 @@ uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint1
|
||||
{
|
||||
/* +2008.01 [bj]: clear interrupt */
|
||||
W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
|
||||
SPI.endTransaction();
|
||||
return 0;
|
||||
}
|
||||
SPI.endTransaction();
|
||||
yield();
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
}
|
||||
|
||||
/* +2008.01 bj */
|
||||
W5100.writeSnIR(s, SnIR::SEND_OK);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -252,11 +299,12 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
|
||||
|
||||
if ( len > 0 )
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
ptr = W5100.readSnRX_RD(s);
|
||||
switch (W5100.readSnMR(s) & 0x07)
|
||||
{
|
||||
case SnMR::UDP :
|
||||
W5100.read_data(s, (uint8_t *)ptr, head, 0x08);
|
||||
W5100.read_data(s, ptr, head, 0x08);
|
||||
ptr += 8;
|
||||
// read peer's IP address, port number.
|
||||
addr[0] = head[0];
|
||||
@ -268,14 +316,14 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
|
||||
data_len = head[6];
|
||||
data_len = (data_len << 8) + head[7];
|
||||
|
||||
W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy.
|
||||
W5100.read_data(s, ptr, buf, data_len); // data copy.
|
||||
ptr += data_len;
|
||||
|
||||
W5100.writeSnRX_RD(s, ptr);
|
||||
break;
|
||||
|
||||
case SnMR::IPRAW :
|
||||
W5100.read_data(s, (uint8_t *)ptr, head, 0x06);
|
||||
W5100.read_data(s, ptr, head, 0x06);
|
||||
ptr += 6;
|
||||
|
||||
addr[0] = head[0];
|
||||
@ -285,19 +333,19 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
|
||||
data_len = head[4];
|
||||
data_len = (data_len << 8) + head[5];
|
||||
|
||||
W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy.
|
||||
W5100.read_data(s, ptr, buf, data_len); // data copy.
|
||||
ptr += data_len;
|
||||
|
||||
W5100.writeSnRX_RD(s, ptr);
|
||||
break;
|
||||
|
||||
case SnMR::MACRAW:
|
||||
W5100.read_data(s,(uint8_t*)ptr,head,2);
|
||||
W5100.read_data(s, ptr, head, 2);
|
||||
ptr+=2;
|
||||
data_len = head[0];
|
||||
data_len = (data_len<<8) + head[1] - 2;
|
||||
|
||||
W5100.read_data(s,(uint8_t*) ptr,buf,data_len);
|
||||
W5100.read_data(s, ptr, buf, data_len);
|
||||
ptr += data_len;
|
||||
W5100.writeSnRX_RD(s, ptr);
|
||||
break;
|
||||
@ -306,14 +354,20 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
|
||||
break;
|
||||
}
|
||||
W5100.execCmdSn(s, Sock_RECV);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
return data_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for buffered transmission to complete.
|
||||
*/
|
||||
void flush(SOCKET s) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
{
|
||||
uint8_t status=0;
|
||||
uint16_t ret=0;
|
||||
|
||||
if (len > W5100.SSIZE)
|
||||
@ -324,28 +378,34 @@ uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.send_data_processing(s, (uint8_t *)buf, ret);
|
||||
W5100.execCmdSn(s, Sock_SEND);
|
||||
|
||||
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
|
||||
{
|
||||
status = W5100.readSnSR(s);
|
||||
if (W5100.readSnIR(s) & SnIR::TIMEOUT)
|
||||
{
|
||||
/* in case of igmp, if send fails, then socket closed */
|
||||
/* if you want change, remove this code. */
|
||||
SPI.endTransaction();
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
SPI.endTransaction();
|
||||
yield();
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
}
|
||||
|
||||
W5100.writeSnIR(s, SnIR::SEND_OK);
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
|
||||
{
|
||||
uint16_t ret =0;
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
if (len > W5100.getTXFreeSize(s))
|
||||
{
|
||||
ret = W5100.getTXFreeSize(s); // check size not to exceed MAX size.
|
||||
@ -355,6 +415,7 @@ uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
|
||||
ret = len;
|
||||
}
|
||||
W5100.send_data_processing_offset(s, offset, buf, ret);
|
||||
SPI.endTransaction();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -370,14 +431,17 @@ int startUDP(SOCKET s, uint8_t* addr, uint16_t port)
|
||||
}
|
||||
else
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.writeSnDIPR(s, addr);
|
||||
W5100.writeSnDPORT(s, port);
|
||||
SPI.endTransaction();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int sendUDP(SOCKET s)
|
||||
{
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
W5100.execCmdSn(s, Sock_SEND);
|
||||
|
||||
/* +2008.01 bj */
|
||||
@ -387,12 +451,17 @@ int sendUDP(SOCKET s)
|
||||
{
|
||||
/* +2008.01 [bj]: clear interrupt */
|
||||
W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT));
|
||||
SPI.endTransaction();
|
||||
return 0;
|
||||
}
|
||||
SPI.endTransaction();
|
||||
yield();
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
}
|
||||
|
||||
/* +2008.01 bj */
|
||||
W5100.writeSnIR(s, SnIR::SEND_OK);
|
||||
SPI.endTransaction();
|
||||
|
||||
/* Sent ok */
|
||||
return 1;
|
||||
|
5
libraries/Ethernet/utility/socket.h
Executable file → Normal file
5
libraries/Ethernet/utility/socket.h
Executable file → Normal file
@ -1,18 +1,21 @@
|
||||
#ifndef _SOCKET_H_
|
||||
#define _SOCKET_H_
|
||||
|
||||
#include "w5100.h"
|
||||
#include "utility/w5100.h"
|
||||
|
||||
extern uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag); // Opens a socket(TCP or UDP or IP_RAW mode)
|
||||
extern uint8_t socketStatus(SOCKET s);
|
||||
extern void close(SOCKET s); // Close socket
|
||||
extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TCP connection (Active connection)
|
||||
extern void disconnect(SOCKET s); // disconnect the connection
|
||||
extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection)
|
||||
extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP)
|
||||
extern int16_t recv(SOCKET s, uint8_t * buf, int16_t len); // Receive data (TCP)
|
||||
extern int16_t recvAvailable(SOCKET s);
|
||||
extern uint16_t peek(SOCKET s, uint8_t *buf);
|
||||
extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW)
|
||||
extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW)
|
||||
extern void flush(SOCKET s); // Wait for transmission to complete
|
||||
|
||||
extern uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
|
||||
#define htons(x) ( ((x)<< 8 & 0xFF00) | \
|
||||
((x)>> 8 & 0x00FF) )
|
||||
#define ntohs(x) htons(x)
|
||||
|
||||
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
@ -9,9 +9,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "w5100.h"
|
||||
#include "utility/w5100.h"
|
||||
|
||||
// W5100 controller instance
|
||||
W5100Class W5100;
|
||||
@ -29,10 +28,11 @@ void W5100Class::init(void)
|
||||
|
||||
SPI.begin();
|
||||
initSS();
|
||||
|
||||
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
|
||||
writeMR(1<<RST);
|
||||
writeTMSR(0x55);
|
||||
writeRMSR(0x55);
|
||||
SPI.endTransaction();
|
||||
|
||||
for (int i=0; i<MAX_SOCK_NUM; i++) {
|
||||
SBASE[i] = TXBUF_BASE + SSIZE * i;
|
||||
@ -98,7 +98,7 @@ void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin
|
||||
{
|
||||
uint16_t ptr;
|
||||
ptr = readSnRX_RD(s);
|
||||
read_data(s, (uint8_t *)ptr, data, len);
|
||||
read_data(s, ptr, data, len);
|
||||
if (!peek)
|
||||
{
|
||||
ptr += len;
|
||||
@ -106,13 +106,13 @@ void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin
|
||||
}
|
||||
}
|
||||
|
||||
void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
|
||||
void W5100Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len)
|
||||
{
|
||||
uint16_t size;
|
||||
uint16_t src_mask;
|
||||
uint16_t src_ptr;
|
||||
|
||||
src_mask = (uint16_t)src & RMASK;
|
||||
src_mask = src & RMASK;
|
||||
src_ptr = RBASE[s] + src_mask;
|
||||
|
||||
if( (src_mask + len) > RSIZE )
|
||||
|
6
libraries/Ethernet/utility/w5100.h
Executable file → Normal file
6
libraries/Ethernet/utility/w5100.h
Executable file → Normal file
@ -10,9 +10,10 @@
|
||||
#ifndef W5100_H_INCLUDED
|
||||
#define W5100_H_INCLUDED
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define SPI_ETHERNET_SETTINGS SPISettings(4000000, MSBFIRST, SPI_MODE0)
|
||||
|
||||
#define MAX_SOCK_NUM 4
|
||||
|
||||
typedef uint8_t SOCKET;
|
||||
@ -138,7 +139,7 @@ public:
|
||||
* the data from Receive buffer. Here also take care of the condition while it exceed
|
||||
* the Rx memory uper-bound of socket.
|
||||
*/
|
||||
void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len);
|
||||
void read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief This function is being called by send() and sendto() function also.
|
||||
@ -340,7 +341,6 @@ private:
|
||||
inline static void setSS() { PORTB &= ~_BV(2); };
|
||||
inline static void resetSS() { PORTB |= _BV(2); };
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern W5100Class W5100;
|
||||
|
@ -550,9 +550,9 @@ boolean SDClass::mkdir(char *filepath) {
|
||||
boolean SDClass::rmdir(char *filepath) {
|
||||
/*
|
||||
|
||||
Makes a single directory or a heirarchy of directories.
|
||||
Remove a single directory or a heirarchy of directories.
|
||||
|
||||
A rough equivalent to `mkdir -p`.
|
||||
A rough equivalent to `rm -rf`.
|
||||
|
||||
*/
|
||||
return walkPath(filepath, root, callback_rmdir);
|
||||
|
@ -1,25 +1,26 @@
|
||||
/*
|
||||
SD card test
|
||||
|
||||
SD card test
|
||||
|
||||
This example shows how use the utility libraries on which the'
|
||||
SD library is based in order to get info about your SD card.
|
||||
Very useful for testing a card when you're not sure whether its working or not.
|
||||
|
||||
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
|
||||
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
|
||||
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
|
||||
** CS - depends on your SD card shield or module.
|
||||
** CS - depends on your SD card shield or module.
|
||||
Pin 4 used here for consistency with other Arduino examples
|
||||
|
||||
|
||||
|
||||
created 28 Mar 2011
|
||||
by Limor Fried
|
||||
by Limor Fried
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
*/
|
||||
// include the SD library:
|
||||
// include the SD library:
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
// set up variables using the SD utility library functions:
|
||||
@ -31,22 +32,22 @@ SdFile root;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
const int chipSelect = 4;
|
||||
const int chipSelect = 4;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
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
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT); // change this to 53 on a mega
|
||||
|
||||
|
||||
@ -59,12 +60,12 @@ void setup()
|
||||
Serial.println("* did you change the chipSelect pin to match your shield or module?");
|
||||
return;
|
||||
} else {
|
||||
Serial.println("Wiring is correct and a card is present.");
|
||||
Serial.println("Wiring is correct and a card is present.");
|
||||
}
|
||||
|
||||
// print the type of card
|
||||
Serial.print("\nCard type: ");
|
||||
switch(card.type()) {
|
||||
switch (card.type()) {
|
||||
case SD_CARD_TYPE_SD1:
|
||||
Serial.println("SD1");
|
||||
break;
|
||||
@ -90,7 +91,7 @@ void setup()
|
||||
Serial.print("\nVolume type is FAT");
|
||||
Serial.println(volume.fatType(), DEC);
|
||||
Serial.println();
|
||||
|
||||
|
||||
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
|
||||
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
|
||||
volumesize *= 512; // SD card blocks are always 512 bytes
|
||||
@ -103,15 +104,15 @@ void setup()
|
||||
volumesize /= 1024;
|
||||
Serial.println(volumesize);
|
||||
|
||||
|
||||
|
||||
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
|
||||
root.openRoot(volume);
|
||||
|
||||
|
||||
// list all files in the card with date and size
|
||||
root.ls(LS_R | LS_DATE | LS_SIZE);
|
||||
}
|
||||
|
||||
|
||||
void loop(void) {
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
SD card datalogger
|
||||
|
||||
This example shows how to log data from three analog sensors
|
||||
|
||||
This example shows how to log data from three analog sensors
|
||||
to an SD card using the SD library.
|
||||
|
||||
|
||||
The circuit:
|
||||
* analog sensors on analog ins 0, 1, and 2
|
||||
* SD card attached to SPI bus as follows:
|
||||
@ -11,15 +11,16 @@
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
|
||||
created 24 Nov 2010
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
|
||||
@ -30,9 +31,9 @@ const int chipSelect = 4;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -41,7 +42,7 @@ void setup()
|
||||
// make sure that the default chip select pin is set to
|
||||
// output, even if you don't use it:
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
|
||||
// see if the card is present and can be initialized:
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("Card failed, or not present");
|
||||
@ -61,7 +62,7 @@ void loop()
|
||||
int sensor = analogRead(analogPin);
|
||||
dataString += String(sensor);
|
||||
if (analogPin < 2) {
|
||||
dataString += ",";
|
||||
dataString += ",";
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,11 +76,11 @@ void loop()
|
||||
dataFile.close();
|
||||
// print to the serial port too:
|
||||
Serial.println(dataString);
|
||||
}
|
||||
}
|
||||
// if the file isn't open, pop up an error:
|
||||
else {
|
||||
Serial.println("error opening datalog.txt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,25 +1,26 @@
|
||||
/*
|
||||
SD card file dump
|
||||
|
||||
|
||||
This example shows how to read a file from the SD card using the
|
||||
SD library and send it over the serial port.
|
||||
|
||||
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** 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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
|
||||
@ -30,9 +31,9 @@ const int chipSelect = 4;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
@ -41,7 +42,7 @@ void setup()
|
||||
// make sure that the default chip select pin is set to
|
||||
// output, even if you don't use it:
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
|
||||
// see if the card is present and can be initialized:
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("Card failed, or not present");
|
||||
@ -49,7 +50,7 @@ void setup()
|
||||
return;
|
||||
}
|
||||
Serial.println("card initialized.");
|
||||
|
||||
|
||||
// open the file. note that only one file can be open at a time,
|
||||
// so you have to close this one before opening another.
|
||||
File dataFile = SD.open("datalog.txt");
|
||||
@ -60,11 +61,11 @@ void setup()
|
||||
Serial.write(dataFile.read());
|
||||
}
|
||||
dataFile.close();
|
||||
}
|
||||
}
|
||||
// if the file isn't open, pop up an error:
|
||||
else {
|
||||
Serial.println("error opening datalog.txt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
@ -1,40 +1,41 @@
|
||||
/*
|
||||
SD card basic file example
|
||||
|
||||
This example shows how to create and destroy an SD card file
|
||||
|
||||
This example shows how to create and destroy an SD card file
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
|
||||
created Nov 2010
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
|
||||
*/
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
File myFile;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
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
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
if (!SD.begin(4)) {
|
||||
@ -55,23 +56,23 @@ void setup()
|
||||
myFile = SD.open("example.txt", FILE_WRITE);
|
||||
myFile.close();
|
||||
|
||||
// Check to see if the file exists:
|
||||
// Check to see if the file exists:
|
||||
if (SD.exists("example.txt")) {
|
||||
Serial.println("example.txt exists.");
|
||||
}
|
||||
else {
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
}
|
||||
|
||||
// delete the file:
|
||||
Serial.println("Removing example.txt...");
|
||||
SD.remove("example.txt");
|
||||
|
||||
if (SD.exists("example.txt")){
|
||||
if (SD.exists("example.txt")) {
|
||||
Serial.println("example.txt exists.");
|
||||
}
|
||||
else {
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,85 +1,86 @@
|
||||
/*
|
||||
SD card read/write
|
||||
|
||||
This example shows how to read and write data to and from an SD card file
|
||||
|
||||
This example shows how to read and write data to and from an SD card file
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
|
||||
created Nov 2010
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
File myFile;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
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
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
if (!SD.begin(4)) {
|
||||
Serial.println("initialization failed!");
|
||||
return;
|
||||
}
|
||||
Serial.println("initialization done.");
|
||||
|
||||
|
||||
// open the file. note that only one file can be open at a time,
|
||||
// so you have to close this one before opening another.
|
||||
myFile = SD.open("test.txt", FILE_WRITE);
|
||||
|
||||
|
||||
// if the file opened okay, write to it:
|
||||
if (myFile) {
|
||||
Serial.print("Writing to test.txt...");
|
||||
myFile.println("testing 1, 2, 3.");
|
||||
// close the file:
|
||||
// close the file:
|
||||
myFile.close();
|
||||
Serial.println("done.");
|
||||
} else {
|
||||
// if the file didn't open, print an error:
|
||||
Serial.println("error opening test.txt");
|
||||
}
|
||||
|
||||
|
||||
// re-open the file for reading:
|
||||
myFile = SD.open("test.txt");
|
||||
if (myFile) {
|
||||
Serial.println("test.txt:");
|
||||
|
||||
|
||||
// read from the file until there's nothing else in it:
|
||||
while (myFile.available()) {
|
||||
Serial.write(myFile.read());
|
||||
Serial.write(myFile.read());
|
||||
}
|
||||
// close the file:
|
||||
myFile.close();
|
||||
} else {
|
||||
// if the file didn't open, print an error:
|
||||
// if the file didn't open, print an error:
|
||||
Serial.println("error opening test.txt");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// nothing happens after setup
|
||||
// nothing happens after setup
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
|
||||
created Nov 2010
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
@ -19,8 +19,9 @@
|
||||
by Scott Fitzgerald
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
|
||||
*/
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
File root;
|
||||
@ -29,15 +30,15 @@ void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
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
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
if (!SD.begin(4)) {
|
||||
@ -47,9 +48,9 @@ void setup()
|
||||
Serial.println("initialization done.");
|
||||
|
||||
root = SD.open("/");
|
||||
|
||||
|
||||
printDirectory(root, 0);
|
||||
|
||||
|
||||
Serial.println("done!");
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ struct partitionTable {
|
||||
uint32_t firstSector;
|
||||
/** Length of the partition, in blocks. */
|
||||
uint32_t totalSectors;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
/** Type name for partitionTable */
|
||||
typedef struct partitionTable part_t;
|
||||
//------------------------------------------------------------------------------
|
||||
@ -114,7 +114,7 @@ struct masterBootRecord {
|
||||
uint8_t mbrSig0;
|
||||
/** Second MBR signature byte. Must be 0XAA */
|
||||
uint8_t mbrSig1;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
/** Type name for masterBootRecord */
|
||||
typedef struct masterBootRecord mbr_t;
|
||||
//------------------------------------------------------------------------------
|
||||
@ -236,7 +236,7 @@ struct biosParmBlock {
|
||||
* should always set all of the bytes of this field to 0.
|
||||
*/
|
||||
uint8_t fat32Reserved[12];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
/** Type name for biosParmBlock */
|
||||
typedef struct biosParmBlock bpb_t;
|
||||
//------------------------------------------------------------------------------
|
||||
@ -271,7 +271,7 @@ struct fat32BootSector {
|
||||
uint8_t bootSectorSig0;
|
||||
/** must be 0XAA */
|
||||
uint8_t bootSectorSig1;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
//------------------------------------------------------------------------------
|
||||
// End Of Chain values for FAT entries
|
||||
/** FAT16 end of chain value used by Microsoft. */
|
||||
@ -366,7 +366,7 @@ struct directoryEntry {
|
||||
uint16_t firstClusterLow;
|
||||
/** 32-bit unsigned holding this file's size in bytes. */
|
||||
uint32_t fileSize;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
//------------------------------------------------------------------------------
|
||||
// Definitions for directory entries
|
||||
//
|
||||
|
@ -17,20 +17,34 @@
|
||||
* along with the Arduino Sd2Card Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define USE_SPI_LIB
|
||||
#include <Arduino.h>
|
||||
#include "Sd2Card.h"
|
||||
//------------------------------------------------------------------------------
|
||||
#ifndef SOFTWARE_SPI
|
||||
#ifdef USE_SPI_LIB
|
||||
#include <SPI.h>
|
||||
static SPISettings settings;
|
||||
#endif
|
||||
// functions for hardware SPI
|
||||
/** Send a byte to the card */
|
||||
static void spiSend(uint8_t b) {
|
||||
#ifndef USE_SPI_LIB
|
||||
SPDR = b;
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
#else
|
||||
SPI.transfer(b);
|
||||
#endif
|
||||
}
|
||||
/** Receive a byte from the card */
|
||||
static uint8_t spiRec(void) {
|
||||
#ifndef USE_SPI_LIB
|
||||
spiSend(0XFF);
|
||||
return SPDR;
|
||||
#else
|
||||
return SPI.transfer(0xFF);
|
||||
#endif
|
||||
}
|
||||
#else // SOFTWARE_SPI
|
||||
//------------------------------------------------------------------------------
|
||||
@ -112,7 +126,8 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
|
||||
spiSend(crc);
|
||||
|
||||
// wait for response
|
||||
for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);
|
||||
for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++)
|
||||
;
|
||||
return status_;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
@ -142,11 +157,25 @@ uint32_t Sd2Card::cardSize(void) {
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
static uint8_t chip_select_asserted = 0;
|
||||
|
||||
void Sd2Card::chipSelectHigh(void) {
|
||||
digitalWrite(chipSelectPin_, HIGH);
|
||||
#ifdef USE_SPI_LIB
|
||||
if (chip_select_asserted) {
|
||||
chip_select_asserted = 0;
|
||||
SPI.endTransaction();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void Sd2Card::chipSelectLow(void) {
|
||||
#ifdef USE_SPI_LIB
|
||||
if (!chip_select_asserted) {
|
||||
chip_select_asserted = 1;
|
||||
SPI.beginTransaction(settings);
|
||||
}
|
||||
#endif
|
||||
digitalWrite(chipSelectPin_, LOW);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
@ -219,12 +248,15 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
||||
|
||||
// set pin modes
|
||||
pinMode(chipSelectPin_, OUTPUT);
|
||||
chipSelectHigh();
|
||||
digitalWrite(chipSelectPin_, HIGH);
|
||||
#ifndef USE_SPI_LIB
|
||||
pinMode(SPI_MISO_PIN, INPUT);
|
||||
pinMode(SPI_MOSI_PIN, OUTPUT);
|
||||
pinMode(SPI_SCK_PIN, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifndef SOFTWARE_SPI
|
||||
#ifndef USE_SPI_LIB
|
||||
// SS must be in output mode even it is not chip select
|
||||
pinMode(SS_PIN, OUTPUT);
|
||||
digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
|
||||
@ -232,10 +264,20 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
||||
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
|
||||
// clear double speed
|
||||
SPSR &= ~(1 << SPI2X);
|
||||
#endif // SOFTWARE_SPI
|
||||
#else // USE_SPI_LIB
|
||||
SPI.begin();
|
||||
settings = SPISettings(250000, MSBFIRST, SPI_MODE0);
|
||||
#endif // USE_SPI_LIB
|
||||
#endif // SOFTWARE_SPI
|
||||
|
||||
// must supply min of 74 clock cycles with CS high.
|
||||
#ifdef USE_SPI_LIB
|
||||
SPI.beginTransaction(settings);
|
||||
#endif
|
||||
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
|
||||
#ifdef USE_SPI_LIB
|
||||
SPI.endTransaction();
|
||||
#endif
|
||||
|
||||
chipSelectLow();
|
||||
|
||||
@ -360,18 +402,21 @@ uint8_t Sd2Card::readData(uint32_t block,
|
||||
|
||||
// skip data before offset
|
||||
for (;offset_ < offset; offset_++) {
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
SPDR = 0XFF;
|
||||
}
|
||||
// transfer data
|
||||
n = count - 1;
|
||||
for (uint16_t i = 0; i < n; i++) {
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
dst[i] = SPDR;
|
||||
SPDR = 0XFF;
|
||||
}
|
||||
// wait for last byte
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
dst[n] = SPDR;
|
||||
|
||||
#else // OPTIMIZE_HARDWARE_SPI
|
||||
@ -406,11 +451,13 @@ void Sd2Card::readEnd(void) {
|
||||
// optimize skip for hardware
|
||||
SPDR = 0XFF;
|
||||
while (offset_++ < 513) {
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
SPDR = 0XFF;
|
||||
}
|
||||
// wait for last crc byte
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
#else // OPTIMIZE_HARDWARE_SPI
|
||||
while (offset_++ < 514) spiRec();
|
||||
#endif // OPTIMIZE_HARDWARE_SPI
|
||||
@ -456,6 +503,7 @@ uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
|
||||
error(SD_CARD_ERROR_SCK_RATE);
|
||||
return false;
|
||||
}
|
||||
#ifndef USE_SPI_LIB
|
||||
// see avr processor datasheet for SPI register bit definitions
|
||||
if ((sckRateID & 1) || sckRateID == 6) {
|
||||
SPSR &= ~(1 << SPI2X);
|
||||
@ -465,6 +513,17 @@ uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
|
||||
SPCR &= ~((1 <<SPR1) | (1 << SPR0));
|
||||
SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
|
||||
| (sckRateID & 2 ? (1 << SPR0) : 0);
|
||||
#else // USE_SPI_LIB
|
||||
switch (sckRateID) {
|
||||
case 0: settings = SPISettings(25000000, MSBFIRST, SPI_MODE0); break;
|
||||
case 1: settings = SPISettings(4000000, MSBFIRST, SPI_MODE0); break;
|
||||
case 2: settings = SPISettings(2000000, MSBFIRST, SPI_MODE0); break;
|
||||
case 3: settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); break;
|
||||
case 4: settings = SPISettings(500000, MSBFIRST, SPI_MODE0); break;
|
||||
case 5: settings = SPISettings(250000, MSBFIRST, SPI_MODE0); break;
|
||||
default: settings = SPISettings(125000, MSBFIRST, SPI_MODE0);
|
||||
}
|
||||
#endif // USE_SPI_LIB
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
@ -561,14 +620,17 @@ uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
|
||||
|
||||
// send two byte per iteration
|
||||
for (uint16_t i = 0; i < 512; i += 2) {
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
SPDR = src[i];
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
SPDR = src[i+1];
|
||||
}
|
||||
|
||||
// wait for last data byte
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
while (!(SPSR & (1 << SPIF)))
|
||||
;
|
||||
|
||||
#else // OPTIMIZE_HARDWARE_SPI
|
||||
spiSend(token);
|
||||
|
@ -31,6 +31,11 @@ uint8_t const SPI_FULL_SPEED = 0;
|
||||
uint8_t const SPI_HALF_SPEED = 1;
|
||||
/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */
|
||||
uint8_t const SPI_QUARTER_SPEED = 2;
|
||||
/**
|
||||
* USE_SPI_LIB: if set, use the SPI library bundled with Arduino IDE, otherwise
|
||||
* run with a standalone driver for AVR.
|
||||
*/
|
||||
#define USE_SPI_LIB
|
||||
/**
|
||||
* Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos.
|
||||
* Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
|
||||
@ -66,7 +71,9 @@ uint8_t const SPI_MISO_PIN = MISO_PIN;
|
||||
/** SPI Clock pin */
|
||||
uint8_t const SPI_SCK_PIN = SCK_PIN;
|
||||
/** optimize loops for hardware SPI */
|
||||
#ifndef USE_SPI_LIB
|
||||
#define OPTIMIZE_HARDWARE_SPI
|
||||
#endif
|
||||
|
||||
#else // SOFTWARE_SPI
|
||||
// define software SPI pins so Mega can use unmodified GPS Shield
|
||||
|
@ -17,6 +17,22 @@
|
||||
* along with the Arduino SdFat Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#if defined(__arm__) // Arduino Due Board follows
|
||||
|
||||
#ifndef Sd2PinMap_h
|
||||
#define Sd2PinMap_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
uint8_t const SS_PIN = SS;
|
||||
uint8_t const MOSI_PIN = MOSI;
|
||||
uint8_t const MISO_PIN = MISO;
|
||||
uint8_t const SCK_PIN = SCK;
|
||||
|
||||
#endif // Sd2PinMap_h
|
||||
|
||||
#elif defined(__AVR__) // Other AVR based Boards follows
|
||||
|
||||
// Warning this file was generated by a program.
|
||||
#ifndef Sd2PinMap_h
|
||||
#define Sd2PinMap_h
|
||||
@ -350,3 +366,7 @@ static inline __attribute__((always_inline))
|
||||
}
|
||||
}
|
||||
#endif // Sd2PinMap_h
|
||||
|
||||
#else
|
||||
#error Architecture or board not supported.
|
||||
#endif
|
||||
|
@ -23,7 +23,9 @@
|
||||
* \file
|
||||
* SdFile and SdVolume classes
|
||||
*/
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#include "Sd2Card.h"
|
||||
#include "FatStructs.h"
|
||||
#include "Print.h"
|
||||
@ -286,8 +288,10 @@ class SdFile : public Print {
|
||||
size_t write(uint8_t b);
|
||||
size_t write(const void* buf, uint16_t nbyte);
|
||||
size_t write(const char* str);
|
||||
#ifdef __AVR__
|
||||
void write_P(PGM_P str);
|
||||
void writeln_P(PGM_P str);
|
||||
#endif
|
||||
//------------------------------------------------------------------------------
|
||||
#if ALLOW_DEPRECATED_FUNCTIONS
|
||||
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
||||
|
@ -24,12 +24,14 @@
|
||||
* Useful utility functions.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
/** Store and print a string in flash memory.*/
|
||||
#define PgmPrint(x) SerialPrint_P(PSTR(x))
|
||||
/** Store and print a string in flash memory followed by a CR/LF.*/
|
||||
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))
|
||||
/** Defined so doxygen works for function definitions. */
|
||||
#endif
|
||||
#define NOINLINE __attribute__((noinline,unused))
|
||||
#define UNUSEDOK __attribute__((unused))
|
||||
//------------------------------------------------------------------------------
|
||||
@ -49,6 +51,7 @@ static UNUSEDOK int FreeRam(void) {
|
||||
}
|
||||
return free_memory;
|
||||
}
|
||||
#ifdef __AVR__
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* %Print a string in flash memory to the serial port.
|
||||
@ -68,4 +71,5 @@ static NOINLINE void SerialPrintln_P(PGM_P str) {
|
||||
SerialPrint_P(str);
|
||||
Serial.println();
|
||||
}
|
||||
#endif // __AVR__
|
||||
#endif // #define SdFatUtil_h
|
||||
|
@ -17,8 +17,10 @@
|
||||
* along with the Arduino SdFat Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <SdFat.h>
|
||||
#include "SdFat.h"
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#include <Arduino.h>
|
||||
//------------------------------------------------------------------------------
|
||||
// callback function for date/time
|
||||
@ -256,9 +258,15 @@ uint8_t SdFile::make83Name(const char* str, uint8_t* name) {
|
||||
i = 8; // place for extension
|
||||
} else {
|
||||
// illegal FAT characters
|
||||
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
||||
uint8_t b;
|
||||
#if defined(__AVR__)
|
||||
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
||||
while ((b = pgm_read_byte(p++))) if (b == c) return false;
|
||||
#elif defined(__arm__)
|
||||
const uint8_t valid[] = "|<>^+=?/[];,*\"\\";
|
||||
const uint8_t *p = valid;
|
||||
while ((b = *p++)) if (b == c) return false;
|
||||
#endif
|
||||
// check size and only allow ASCII printable characters
|
||||
if (i > n || c < 0X21 || c > 0X7E)return false;
|
||||
// only upper case allowed in 8.3 names - convert lower to upper
|
||||
@ -1232,6 +1240,7 @@ size_t SdFile::write(uint8_t b) {
|
||||
size_t SdFile::write(const char* str) {
|
||||
return write(str, strlen(str));
|
||||
}
|
||||
#ifdef __AVR__
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Write a PROGMEM string to a file.
|
||||
@ -1251,3 +1260,4 @@ void SdFile::writeln_P(PGM_P str) {
|
||||
write_P(str);
|
||||
println();
|
||||
}
|
||||
#endif
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with the Arduino SdFat Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <SdFat.h>
|
||||
#include "SdFat.h"
|
||||
//------------------------------------------------------------------------------
|
||||
// raw block cache
|
||||
// init cacheBlockNumber_to invalid SD block number
|
||||
|
@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
|
||||
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
||||
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
|
||||
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
|
||||
* SPI Master library for arduino.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
@ -8,59 +11,183 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "pins_arduino.h"
|
||||
#include "SPI.h"
|
||||
|
||||
SPIClass SPI;
|
||||
|
||||
void SPIClass::begin() {
|
||||
uint8_t SPIClass::initialized = 0;
|
||||
uint8_t SPIClass::interruptMode = 0;
|
||||
uint8_t SPIClass::interruptMask = 0;
|
||||
uint8_t SPIClass::interruptSave = 0;
|
||||
#ifdef SPI_TRANSACTION_MISMATCH_LED
|
||||
uint8_t SPIClass::inTransactionFlag = 0;
|
||||
#endif
|
||||
|
||||
// Set SS to high so a connected chip will be "deselected" by default
|
||||
digitalWrite(SS, HIGH);
|
||||
void SPIClass::begin()
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
|
||||
if (!initialized) {
|
||||
// Set SS to high so a connected chip will be "deselected" by default
|
||||
digitalWrite(SS, HIGH);
|
||||
|
||||
// When the SS pin is set as OUTPUT, it can be used as
|
||||
// a general purpose output port (it doesn't influence
|
||||
// SPI operations).
|
||||
pinMode(SS, OUTPUT);
|
||||
// When the SS pin is set as OUTPUT, it can be used as
|
||||
// a general purpose output port (it doesn't influence
|
||||
// SPI operations).
|
||||
pinMode(SS, OUTPUT);
|
||||
|
||||
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
|
||||
// automatically switches to Slave, so the data direction of
|
||||
// the SS pin MUST be kept as OUTPUT.
|
||||
SPCR |= _BV(MSTR);
|
||||
SPCR |= _BV(SPE);
|
||||
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
|
||||
// automatically switches to Slave, so the data direction of
|
||||
// the SS pin MUST be kept as OUTPUT.
|
||||
SPCR |= _BV(MSTR);
|
||||
SPCR |= _BV(SPE);
|
||||
|
||||
// Set direction register for SCK and MOSI pin.
|
||||
// MISO pin automatically overrides to INPUT.
|
||||
// By doing this AFTER enabling SPI, we avoid accidentally
|
||||
// clocking in a single bit since the lines go directly
|
||||
// from "input" to SPI control.
|
||||
// http://code.google.com/p/arduino/issues/detail?id=888
|
||||
pinMode(SCK, OUTPUT);
|
||||
pinMode(MOSI, OUTPUT);
|
||||
// Set direction register for SCK and MOSI pin.
|
||||
// MISO pin automatically overrides to INPUT.
|
||||
// By doing this AFTER enabling SPI, we avoid accidentally
|
||||
// clocking in a single bit since the lines go directly
|
||||
// from "input" to SPI control.
|
||||
// http://code.google.com/p/arduino/issues/detail?id=888
|
||||
pinMode(SCK, OUTPUT);
|
||||
pinMode(MOSI, OUTPUT);
|
||||
}
|
||||
initialized++; // reference count
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
|
||||
void SPIClass::end() {
|
||||
SPCR &= ~_BV(SPE);
|
||||
}
|
||||
|
||||
void SPIClass::setBitOrder(uint8_t bitOrder)
|
||||
{
|
||||
if(bitOrder == LSBFIRST) {
|
||||
SPCR |= _BV(DORD);
|
||||
} else {
|
||||
SPCR &= ~(_BV(DORD));
|
||||
uint8_t sreg = SREG;
|
||||
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
|
||||
// Decrease the reference counter
|
||||
if (initialized)
|
||||
initialized--;
|
||||
// If there are no more references disable SPI
|
||||
if (!initialized) {
|
||||
SPCR &= ~_BV(SPE);
|
||||
interruptMode = 0;
|
||||
#ifdef SPI_TRANSACTION_MISMATCH_LED
|
||||
inTransactionFlag = 0;
|
||||
#endif
|
||||
}
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
void SPIClass::setDataMode(uint8_t mode)
|
||||
// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
#define SPI_INT0_MASK (1<<INT0)
|
||||
#define SPI_INT1_MASK (1<<INT1)
|
||||
#define SPI_INT2_MASK (1<<INT2)
|
||||
#define SPI_INT3_MASK (1<<INT3)
|
||||
#define SPI_INT4_MASK (1<<INT6)
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
#define SPI_INT0_MASK (1<<INT0)
|
||||
#define SPI_INT1_MASK (1<<INT1)
|
||||
#define SPI_INT2_MASK (1<<INT2)
|
||||
#define SPI_INT3_MASK (1<<INT3)
|
||||
#define SPI_INT4_MASK (1<<INT4)
|
||||
#define SPI_INT5_MASK (1<<INT5)
|
||||
#define SPI_INT6_MASK (1<<INT6)
|
||||
#define SPI_INT7_MASK (1<<INT7)
|
||||
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
||||
#define SPI_INT0_MASK (1<<INT4)
|
||||
#define SPI_INT1_MASK (1<<INT5)
|
||||
#define SPI_INT2_MASK (1<<INT0)
|
||||
#define SPI_INT3_MASK (1<<INT1)
|
||||
#define SPI_INT4_MASK (1<<INT2)
|
||||
#define SPI_INT5_MASK (1<<INT3)
|
||||
#define SPI_INT6_MASK (1<<INT6)
|
||||
#define SPI_INT7_MASK (1<<INT7)
|
||||
#else
|
||||
#ifdef INT0
|
||||
#define SPI_INT0_MASK (1<<INT0)
|
||||
#endif
|
||||
#ifdef INT1
|
||||
#define SPI_INT1_MASK (1<<INT1)
|
||||
#endif
|
||||
#ifdef INT2
|
||||
#define SPI_INT2_MASK (1<<INT2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void SPIClass::usingInterrupt(uint8_t interruptNumber)
|
||||
{
|
||||
SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
|
||||
uint8_t mask = 0;
|
||||
uint8_t sreg = SREG;
|
||||
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
|
||||
switch (interruptNumber) {
|
||||
#ifdef SPI_INT0_MASK
|
||||
case 0: mask = SPI_INT0_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT1_MASK
|
||||
case 1: mask = SPI_INT1_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT2_MASK
|
||||
case 2: mask = SPI_INT2_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT3_MASK
|
||||
case 3: mask = SPI_INT3_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT4_MASK
|
||||
case 4: mask = SPI_INT4_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT5_MASK
|
||||
case 5: mask = SPI_INT5_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT6_MASK
|
||||
case 6: mask = SPI_INT6_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT7_MASK
|
||||
case 7: mask = SPI_INT7_MASK; break;
|
||||
#endif
|
||||
default:
|
||||
interruptMode = 2;
|
||||
break;
|
||||
}
|
||||
interruptMask |= mask;
|
||||
if (!interruptMode)
|
||||
interruptMode = 1;
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
void SPIClass::setClockDivider(uint8_t rate)
|
||||
void SPIClass::notUsingInterrupt(uint8_t interruptNumber)
|
||||
{
|
||||
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
|
||||
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
|
||||
// Once in mode 2 we can't go back to 0 without a proper reference count
|
||||
if (interruptMode == 2)
|
||||
return;
|
||||
uint8_t mask = 0;
|
||||
uint8_t sreg = SREG;
|
||||
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
|
||||
switch (interruptNumber) {
|
||||
#ifdef SPI_INT0_MASK
|
||||
case 0: mask = SPI_INT0_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT1_MASK
|
||||
case 1: mask = SPI_INT1_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT2_MASK
|
||||
case 2: mask = SPI_INT2_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT3_MASK
|
||||
case 3: mask = SPI_INT3_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT4_MASK
|
||||
case 4: mask = SPI_INT4_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT5_MASK
|
||||
case 5: mask = SPI_INT5_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT6_MASK
|
||||
case 6: mask = SPI_INT6_MASK; break;
|
||||
#endif
|
||||
#ifdef SPI_INT7_MASK
|
||||
case 7: mask = SPI_INT7_MASK; break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
// this case can't be reached
|
||||
}
|
||||
interruptMask &= ~mask;
|
||||
if (!interruptMask)
|
||||
interruptMode = 0;
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
|
||||
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
||||
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
|
||||
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
|
||||
* SPI Master library for arduino.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
@ -11,9 +14,34 @@
|
||||
#ifndef _SPI_H_INCLUDED
|
||||
#define _SPI_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Arduino.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
|
||||
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
|
||||
#define SPI_HAS_TRANSACTION 1
|
||||
|
||||
// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method
|
||||
#define SPI_HAS_NOTUSINGINTERRUPT 1
|
||||
|
||||
// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.
|
||||
// This way when there is a bug fix you can check this define to alert users
|
||||
// of your code if it uses better version of this library.
|
||||
// This also implies everything that SPI_HAS_TRANSACTION as documented above is
|
||||
// available too.
|
||||
#define SPI_ATOMIC_VERSION 1
|
||||
|
||||
// Uncomment this line to add detection of mismatched begin/end transactions.
|
||||
// A mismatch occurs if other libraries fail to use SPI.endTransaction() for
|
||||
// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn
|
||||
// on if any mismatch is ever detected.
|
||||
//#define SPI_TRANSACTION_MISMATCH_LED 5
|
||||
|
||||
#ifndef LSBFIRST
|
||||
#define LSBFIRST 0
|
||||
#endif
|
||||
#ifndef MSBFIRST
|
||||
#define MSBFIRST 1
|
||||
#endif
|
||||
|
||||
#define SPI_CLOCK_DIV4 0x00
|
||||
#define SPI_CLOCK_DIV16 0x01
|
||||
@ -22,7 +50,6 @@
|
||||
#define SPI_CLOCK_DIV2 0x04
|
||||
#define SPI_CLOCK_DIV8 0x05
|
||||
#define SPI_CLOCK_DIV32 0x06
|
||||
//#define SPI_CLOCK_DIV64 0x07
|
||||
|
||||
#define SPI_MODE0 0x00
|
||||
#define SPI_MODE1 0x04
|
||||
@ -33,38 +60,265 @@
|
||||
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
|
||||
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
|
||||
|
||||
// define SPI_AVR_EIMSK for AVR boards with external interrupt pins
|
||||
#if defined(EIMSK)
|
||||
#define SPI_AVR_EIMSK EIMSK
|
||||
#elif defined(GICR)
|
||||
#define SPI_AVR_EIMSK GICR
|
||||
#elif defined(GIMSK)
|
||||
#define SPI_AVR_EIMSK GIMSK
|
||||
#endif
|
||||
|
||||
class SPISettings {
|
||||
public:
|
||||
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
|
||||
if (__builtin_constant_p(clock)) {
|
||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
||||
} else {
|
||||
init_MightInline(clock, bitOrder, dataMode);
|
||||
}
|
||||
}
|
||||
SPISettings() {
|
||||
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
|
||||
}
|
||||
private:
|
||||
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
|
||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
||||
}
|
||||
void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
|
||||
__attribute__((__always_inline__)) {
|
||||
// Clock settings are defined as follows. Note that this shows SPI2X
|
||||
// inverted, so the bits form increasing numbers. Also note that
|
||||
// fosc/64 appears twice
|
||||
// SPR1 SPR0 ~SPI2X Freq
|
||||
// 0 0 0 fosc/2
|
||||
// 0 0 1 fosc/4
|
||||
// 0 1 0 fosc/8
|
||||
// 0 1 1 fosc/16
|
||||
// 1 0 0 fosc/32
|
||||
// 1 0 1 fosc/64
|
||||
// 1 1 0 fosc/64
|
||||
// 1 1 1 fosc/128
|
||||
|
||||
// We find the fastest clock that is less than or equal to the
|
||||
// given clock rate. The clock divider that results in clock_setting
|
||||
// is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
|
||||
// slowest (128 == 2 ^^ 7, so clock_div = 6).
|
||||
uint8_t clockDiv;
|
||||
|
||||
// When the clock is known at compiletime, use this if-then-else
|
||||
// cascade, which the compiler knows how to completely optimize
|
||||
// away. When clock is not known, use a loop instead, which generates
|
||||
// shorter code.
|
||||
if (__builtin_constant_p(clock)) {
|
||||
if (clock >= F_CPU / 2) {
|
||||
clockDiv = 0;
|
||||
} else if (clock >= F_CPU / 4) {
|
||||
clockDiv = 1;
|
||||
} else if (clock >= F_CPU / 8) {
|
||||
clockDiv = 2;
|
||||
} else if (clock >= F_CPU / 16) {
|
||||
clockDiv = 3;
|
||||
} else if (clock >= F_CPU / 32) {
|
||||
clockDiv = 4;
|
||||
} else if (clock >= F_CPU / 64) {
|
||||
clockDiv = 5;
|
||||
} else {
|
||||
clockDiv = 6;
|
||||
}
|
||||
} else {
|
||||
uint32_t clockSetting = F_CPU / 2;
|
||||
clockDiv = 0;
|
||||
while (clockDiv < 6 && clock < clockSetting) {
|
||||
clockSetting /= 2;
|
||||
clockDiv++;
|
||||
}
|
||||
}
|
||||
|
||||
// Compensate for the duplicate fosc/64
|
||||
if (clockDiv == 6)
|
||||
clockDiv = 7;
|
||||
|
||||
// Invert the SPI2X bit
|
||||
clockDiv ^= 0x1;
|
||||
|
||||
// Pack into the SPISettings class
|
||||
spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
|
||||
(dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
|
||||
spsr = clockDiv & SPI_2XCLOCK_MASK;
|
||||
}
|
||||
uint8_t spcr;
|
||||
uint8_t spsr;
|
||||
friend class SPIClass;
|
||||
};
|
||||
|
||||
|
||||
class SPIClass {
|
||||
public:
|
||||
inline static byte transfer(byte _data);
|
||||
// Initialize the SPI library
|
||||
static void begin();
|
||||
|
||||
// SPI Configuration methods
|
||||
// If SPI is used from within an interrupt, this function registers
|
||||
// that interrupt with the SPI library, so beginTransaction() can
|
||||
// prevent conflicts. The input interruptNumber is the number used
|
||||
// with attachInterrupt. If SPI is used from a different interrupt
|
||||
// (eg, a timer), interruptNumber should be 255.
|
||||
static void usingInterrupt(uint8_t interruptNumber);
|
||||
// And this does the opposite.
|
||||
static void notUsingInterrupt(uint8_t interruptNumber);
|
||||
// Note: the usingInterrupt and notUsingInterrupt functions should
|
||||
// not to be called from ISR context or inside a transaction.
|
||||
// For details see:
|
||||
// https://github.com/arduino/Arduino/pull/2381
|
||||
// https://github.com/arduino/Arduino/pull/2449
|
||||
|
||||
inline static void attachInterrupt();
|
||||
inline static void detachInterrupt(); // Default
|
||||
// Before using SPI.transfer() or asserting chip select pins,
|
||||
// this function is used to gain exclusive access to the SPI bus
|
||||
// and configure the correct settings.
|
||||
inline static void beginTransaction(SPISettings settings) {
|
||||
if (interruptMode > 0) {
|
||||
uint8_t sreg = SREG;
|
||||
noInterrupts();
|
||||
|
||||
static void begin(); // Default
|
||||
#ifdef SPI_AVR_EIMSK
|
||||
if (interruptMode == 1) {
|
||||
interruptSave = SPI_AVR_EIMSK;
|
||||
SPI_AVR_EIMSK &= ~interruptMask;
|
||||
SREG = sreg;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
interruptSave = sreg;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SPI_TRANSACTION_MISMATCH_LED
|
||||
if (inTransactionFlag) {
|
||||
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
|
||||
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
|
||||
}
|
||||
inTransactionFlag = 1;
|
||||
#endif
|
||||
|
||||
SPCR = settings.spcr;
|
||||
SPSR = settings.spsr;
|
||||
}
|
||||
|
||||
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
|
||||
inline static uint8_t transfer(uint8_t data) {
|
||||
SPDR = data;
|
||||
/*
|
||||
* The following NOP introduces a small delay that can prevent the wait
|
||||
* loop form iterating when running at the maximum speed. This gives
|
||||
* about 10% more speed, even if it seems counter-intuitive. At lower
|
||||
* speeds it is unnoticed.
|
||||
*/
|
||||
asm volatile("nop");
|
||||
while (!(SPSR & _BV(SPIF))) ; // wait
|
||||
return SPDR;
|
||||
}
|
||||
inline static uint16_t transfer16(uint16_t data) {
|
||||
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
|
||||
in.val = data;
|
||||
if (!(SPCR & _BV(DORD))) {
|
||||
SPDR = in.msb;
|
||||
asm volatile("nop"); // See transfer(uint8_t) function
|
||||
while (!(SPSR & _BV(SPIF))) ;
|
||||
out.msb = SPDR;
|
||||
SPDR = in.lsb;
|
||||
asm volatile("nop");
|
||||
while (!(SPSR & _BV(SPIF))) ;
|
||||
out.lsb = SPDR;
|
||||
} else {
|
||||
SPDR = in.lsb;
|
||||
asm volatile("nop");
|
||||
while (!(SPSR & _BV(SPIF))) ;
|
||||
out.lsb = SPDR;
|
||||
SPDR = in.msb;
|
||||
asm volatile("nop");
|
||||
while (!(SPSR & _BV(SPIF))) ;
|
||||
out.msb = SPDR;
|
||||
}
|
||||
return out.val;
|
||||
}
|
||||
inline static void transfer(void *buf, size_t count) {
|
||||
if (count == 0) return;
|
||||
uint8_t *p = (uint8_t *)buf;
|
||||
SPDR = *p;
|
||||
while (--count > 0) {
|
||||
uint8_t out = *(p + 1);
|
||||
while (!(SPSR & _BV(SPIF))) ;
|
||||
uint8_t in = SPDR;
|
||||
SPDR = out;
|
||||
*p++ = in;
|
||||
}
|
||||
while (!(SPSR & _BV(SPIF))) ;
|
||||
*p = SPDR;
|
||||
}
|
||||
// After performing a group of transfers and releasing the chip select
|
||||
// signal, this function allows others to access the SPI bus
|
||||
inline static void endTransaction(void) {
|
||||
#ifdef SPI_TRANSACTION_MISMATCH_LED
|
||||
if (!inTransactionFlag) {
|
||||
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
|
||||
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
|
||||
}
|
||||
inTransactionFlag = 0;
|
||||
#endif
|
||||
|
||||
if (interruptMode > 0) {
|
||||
#ifdef SPI_AVR_EIMSK
|
||||
uint8_t sreg = SREG;
|
||||
#endif
|
||||
noInterrupts();
|
||||
#ifdef SPI_AVR_EIMSK
|
||||
if (interruptMode == 1) {
|
||||
SPI_AVR_EIMSK = interruptSave;
|
||||
SREG = sreg;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
SREG = interruptSave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the SPI bus
|
||||
static void end();
|
||||
|
||||
static void setBitOrder(uint8_t);
|
||||
static void setDataMode(uint8_t);
|
||||
static void setClockDivider(uint8_t);
|
||||
// This function is deprecated. New applications should use
|
||||
// beginTransaction() to configure SPI settings.
|
||||
inline static void setBitOrder(uint8_t bitOrder) {
|
||||
if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
|
||||
else SPCR &= ~(_BV(DORD));
|
||||
}
|
||||
// This function is deprecated. New applications should use
|
||||
// beginTransaction() to configure SPI settings.
|
||||
inline static void setDataMode(uint8_t dataMode) {
|
||||
SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
|
||||
}
|
||||
// This function is deprecated. New applications should use
|
||||
// beginTransaction() to configure SPI settings.
|
||||
inline static void setClockDivider(uint8_t clockDiv) {
|
||||
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
|
||||
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
|
||||
}
|
||||
// These undocumented functions should not be used. SPI.transfer()
|
||||
// polls the hardware flag which is automatically cleared as the
|
||||
// AVR responds to SPI's interrupt
|
||||
inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
|
||||
inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
|
||||
|
||||
private:
|
||||
static uint8_t initialized;
|
||||
static uint8_t interruptMode; // 0=none, 1=mask, 2=global
|
||||
static uint8_t interruptMask; // which interrupts to mask
|
||||
static uint8_t interruptSave; // temp storage, to restore state
|
||||
#ifdef SPI_TRANSACTION_MISMATCH_LED
|
||||
static uint8_t inTransactionFlag;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern SPIClass SPI;
|
||||
|
||||
byte SPIClass::transfer(byte _data) {
|
||||
SPDR = _data;
|
||||
while (!(SPSR & _BV(SPIF)))
|
||||
;
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
void SPIClass::attachInterrupt() {
|
||||
SPCR |= _BV(SPIE);
|
||||
}
|
||||
|
||||
void SPIClass::detachInterrupt() {
|
||||
SPCR &= ~_BV(SPIE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*
|
||||
SCP1000 Barometric Pressure Sensor Display
|
||||
|
||||
|
||||
Shows the output of a Barometric Pressure Sensor on a
|
||||
Uses the SPI library. For details on the sensor, see:
|
||||
http://www.sparkfun.com/commerce/product_info.php?products_id=8161
|
||||
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
|
||||
|
||||
|
||||
This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
|
||||
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
|
||||
|
||||
|
||||
Circuit:
|
||||
SCP1000 sensor attached to pins 6, 7, 10 - 13:
|
||||
DRDY: pin 6
|
||||
@ -16,7 +16,7 @@
|
||||
MOSI: pin 11
|
||||
MISO: pin 12
|
||||
SCK: pin 13
|
||||
|
||||
|
||||
created 31 July 2010
|
||||
modified 14 August 2010
|
||||
by Tom Igoe
|
||||
@ -77,7 +77,7 @@ void loop() {
|
||||
//Read the pressure data lower 16 bits:
|
||||
unsigned int pressure_data_low = readRegister(0x20, 2);
|
||||
//combine the two parts into one 19-bit number:
|
||||
long pressure = ((pressure_data_high << 16) | pressure_data_low)/4;
|
||||
long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
|
||||
|
||||
// display the temperature:
|
||||
Serial.println("\tPressure [Pa]=" + String(pressure));
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
Digital Pot Control
|
||||
|
||||
|
||||
This example controls an Analog Devices AD5206 digital potentiometer.
|
||||
The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
|
||||
A - connect this to voltage
|
||||
W - this is the pot's wiper, which changes when you set it
|
||||
B - connect this to ground.
|
||||
|
||||
The AD5206 is SPI-compatible,and to command it, you send two bytes,
|
||||
|
||||
The AD5206 is SPI-compatible,and to command it, you send two bytes,
|
||||
one with the channel number (0 - 5) and one with the resistance value for the
|
||||
channel (0 - 255).
|
||||
|
||||
channel (0 - 255).
|
||||
|
||||
The circuit:
|
||||
* All A pins of AD5206 connected to +5V
|
||||
* All B pins of AD5206 connected to ground
|
||||
@ -18,12 +18,12 @@
|
||||
* CS - to digital pin 10 (SS pin)
|
||||
* SDI - to digital pin 11 (MOSI pin)
|
||||
* CLK - to digital pin 13 (SCK pin)
|
||||
|
||||
created 10 Aug 2010
|
||||
|
||||
created 10 Aug 2010
|
||||
by Tom Igoe
|
||||
|
||||
|
||||
Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -38,12 +38,12 @@ void setup() {
|
||||
// set the slaveSelectPin as an output:
|
||||
pinMode (slaveSelectPin, OUTPUT);
|
||||
// initialize SPI:
|
||||
SPI.begin();
|
||||
SPI.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// go through the six channels of the digital pot:
|
||||
for (int channel = 0; channel < 6; channel++) {
|
||||
for (int channel = 0; channel < 6; channel++) {
|
||||
// change the resistance on this channel from min to max:
|
||||
for (int level = 0; level < 255; level++) {
|
||||
digitalPotWrite(channel, level);
|
||||
@ -62,10 +62,10 @@ void loop() {
|
||||
|
||||
void digitalPotWrite(int address, int value) {
|
||||
// take the SS pin low to select the chip:
|
||||
digitalWrite(slaveSelectPin,LOW);
|
||||
digitalWrite(slaveSelectPin, LOW);
|
||||
// send in the address and value via SPI:
|
||||
SPI.transfer(address);
|
||||
SPI.transfer(value);
|
||||
// take the SS pin high to de-select the chip:
|
||||
digitalWrite(slaveSelectPin,HIGH);
|
||||
digitalWrite(slaveSelectPin, HIGH);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user