diff --git a/hardware/pic32/libraries/DEIPcK/examples/TCPEchoClient/TCPEchoClient.ino b/hardware/pic32/libraries/DEIPcK/examples/TCPEchoClient/TCPEchoClient.ino new file mode 100644 index 000000000..e5a49a901 --- /dev/null +++ b/hardware/pic32/libraries/DEIPcK/examples/TCPEchoClient/TCPEchoClient.ino @@ -0,0 +1,236 @@ +/************************************************************************/ +/* */ +/* TCPEchoClient */ +/* */ +/* A chipKIT DEIPcK TCP Client application to */ +/* demonstrate how to use the TcpClient Class. */ +/* This can be used in conjuction with TCPEchoServer */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* */ +/* */ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014 (KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* MX7cK */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the the Internal MAC and SMSC 8720 PHY + +/************************************************************************/ +/* Required library, Do NOT comment out */ +/************************************************************************/ +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +const char * szIPServer = "192.168.1.180"; // server to connect to +unsigned short portServer = 44300; + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + CONNECT, + WRITE, + READ, + CLOSE, + DONE, +} STATE; + +STATE state = CONNECT; +IPSTATUS status; + +unsigned tStart = 0; +unsigned tWait = 5000; + +TCPSocket tcpClient; +byte rgbRead[1024]; +int cbRead = 0; + +// this is for Print.write to print +byte rgbWrite[] = {'*','W','r','o','t','e',' ','f','r','o','m',' ','p','r','i','n','t','.','w','r','i','t','e','*','\n'}; +int cbWrite = sizeof(rgbWrite); + +// this is for tcpClient.writeStream to print +byte rgbWriteStream[] = {'*','W','r','o','t','e',' ','f','r','o','m',' ','t','c','p','C','l','i','e','n','t','.','w','r','i','t','e','S','t','r','e','a','m','*','\n'}; +int cbWriteStream = sizeof(rgbWriteStream); + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * connection to the TCPEchoServer + * Use DHCP to get the IP, mask, and gateway + * by default we connect to port 11000 + * + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("TCPEchoClient 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); + + // use DHCP to get our IP and network addresses + deIPcK.begin(); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and TcpClient class + * which usually is enough time for the Tcp functions to complete on their first call. + * + * This code will write some stings to the server and have the server echo it back + * + * ------------------------------------------------------------ */ +void loop() { + int cbRead = 0; + + switch(state) + { + case CONNECT: + if(deIPcK.tcpConnect(szIPServer, portServer, tcpClient, &status)) + { + state = WRITE; + } + break; + + // write out the strings + case WRITE: + if(tcpClient.isEstablished()) + { + Serial.println("Got Connection"); + + tcpClient.writeStream(rgbWriteStream, cbWriteStream); + + Serial.println("Bytes Read Back:"); + state = READ; + tStart = (unsigned) millis(); + } + break; + + // look for the echo back + case READ: + + // see if we got anything to read + if((cbRead = tcpClient.available()) > 0) + { + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = tcpClient.readStream(rgbRead, cbRead); + + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + } + + // give us some time to get everything echo'ed back + else if( (((unsigned) millis()) - tStart) > tWait ) + { + Serial.println(""); + state = CLOSE; + } + break; + + // done, so close up the tcpClient + case CLOSE: + tcpClient.close(); + Serial.println("Closing TcpClient, Done with sketch."); + state = DONE; + break; + + case DONE: + default: + break; + } + + // keep the stack alive each pass through the loop() + DEIPcK::periodicTasks(); +} \ No newline at end of file diff --git a/hardware/pic32/libraries/DEIPcK/examples/TCPEchoServer/TCPEchoServer.ino b/hardware/pic32/libraries/DEIPcK/examples/TCPEchoServer/TCPEchoServer.ino new file mode 100644 index 000000000..867eeb163 --- /dev/null +++ b/hardware/pic32/libraries/DEIPcK/examples/TCPEchoServer/TCPEchoServer.ino @@ -0,0 +1,321 @@ +/************************************************************************/ +/* */ +/* TCPEchoServer */ +/* */ +/* A chipKIT DEIPcK TCP Server application to */ +/* demonstrate how to use the TcpServer Class. */ +/* This can be used in conjuction with TCPEchoClient */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* */ +/* */ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014(KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* MX7cK */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the the Internal MAC and SMSC 8720 PHY + +/************************************************************************/ +/* Required library, Do NOT comment out */ +/************************************************************************/ +#include +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +IPv4 ipServer = {192,168,1,190}; +unsigned short portServer = 44300; + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + LISTEN, + ISLISTENING, + WAITISLISTENING, + AVAILABLECLIENT, + ACCEPTCLIENT, + READ, + WRITE, + CLOSE, + EXIT, + DONE +} STATE; + +STATE state = LISTEN; + +unsigned tStart = 0; +unsigned tWait = 5000; + +TCPServer tcpServer; +#define cTcpClients 2 +TCPSocket rgTcpClient[cTcpClients]; + +TCPSocket * ptcpClient = NULL; + +IPSTATUS status; + +byte rgbRead[1024]; +int cbRead = 0; +int count = 0; + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * the IP stack for a static IP of ipServer + * No other network addresses are supplied so + * DNS will fail as any name lookup and time servers + * will all fail. But since we are only listening, who cares. + * + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("TCPEchoServer 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); + + // intialize the stack with a static IP + deIPcK.begin(ipServer); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and TcpServer class + * which usually is enough time for the Tcp functions to complete on their first call. + * + * This code listens for a connection, then echos any strings that come in + * After about 5 seconds of inactivity, it will drop the connection. + * + * This is a simple sketch to illistrate a simple TCP Server. + * + * ------------------------------------------------------------ */ +void loop() { + + switch(state) + { + + // say to listen on the port + case LISTEN: + if(deIPcK.tcpStartListening(portServer, tcpServer)) + { + for(int i = 0; i < cTcpClients; i++) + { + tcpServer.addSocket(rgTcpClient[i]); + } + } + state = ISLISTENING; + break; + + case ISLISTENING: + count = tcpServer.isListening(); + Serial.print(count, DEC); + Serial.print(" sockets listening on port: "); + Serial.println(portServer, DEC); + + if(count > 0) + { + state = AVAILABLECLIENT; + } + else + { + state = WAITISLISTENING; + } + break; + + case WAITISLISTENING: + if(tcpServer.isListening() > 0) + { + state = ISLISTENING; + } + break; + + // wait for a connection + case AVAILABLECLIENT: + if((count = tcpServer.availableClients()) > 0) + { + Serial.print("Got "); + Serial.print(count, DEC); + Serial.println(" clients pending"); + state = ACCEPTCLIENT; + } + break; + + // accept the connection + case ACCEPTCLIENT: + + // accept the client + if((ptcpClient = tcpServer.acceptClient()) != NULL && ptcpClient->isConnected()) + { + Serial.println("Got a Connection"); + state = READ; + tStart = (unsigned) millis(); + } + + // this probably won't happen unless the connection is dropped + // if it is, just release our socket and go back to listening + else + { + state = CLOSE; + } + break; + + // wait fot the read, but if too much time elapses (5 seconds) + // we will just close the tcpClient and go back to listening + case READ: + + // see if we got anything to read + if((cbRead = ptcpClient->available()) > 0) + { + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = ptcpClient->readStream(rgbRead, cbRead); + + Serial.print("Got "); + Serial.print(cbRead, DEC); + Serial.println(" bytes"); + + state = WRITE; + } + + // If too much time elapsed between reads, close the connection + else if( (((unsigned) millis()) - tStart) > tWait ) + { + state = CLOSE; + } + break; + + // echo back the string + case WRITE: + if(ptcpClient->isConnected()) + { + Serial.println("Writing: "); + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + Serial.println(""); + + ptcpClient->writeStream(rgbRead, cbRead); + state = READ; + tStart = (unsigned) millis(); + } + + // the connection was closed on us, go back to listening + else + { + Serial.println("Unable to write back."); + state = CLOSE; + } + break; + + // close our tcpClient and go back to listening + case CLOSE: + ptcpClient->close(); + tcpServer.addSocket(*ptcpClient); + Serial.println(""); + state = ISLISTENING; + break; + + // something bad happen, just exit out of the program + case EXIT: + tcpServer.close(); + Serial.println("Something went wrong, sketch is done."); + state = DONE; + break; + + // do nothing in the loop + case DONE: + default: + break; + } + + // every pass through loop(), keep the stack alive + DEIPcK::periodicTasks(); +} diff --git a/hardware/pic32/libraries/DEIPcK/examples/UDPEchoClient/UDPEchoClient.ino b/hardware/pic32/libraries/DEIPcK/examples/UDPEchoClient/UDPEchoClient.ino new file mode 100644 index 000000000..e6bde5cb9 --- /dev/null +++ b/hardware/pic32/libraries/DEIPcK/examples/UDPEchoClient/UDPEchoClient.ino @@ -0,0 +1,260 @@ +/************************************************************************/ +/* */ +/* UDPEchoClient */ +/* */ +/* A chipKIT DEIPcK UDP Client application to */ +/* demonstrate how to use the UdpClient Class. */ +/* This can be used in conjuction with UDPEchoServer */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/24/2014 (KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* MX7cK */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the the Internal MAC and SMSC 8720 PHY + +/************************************************************************/ +/* Required library, Do NOT comment out */ +/************************************************************************/ +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +const char * szIPServer = "192.168.1.180"; +unsigned short portServer = 44400; + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + RESOLVEENDPOINT, + WRITE, + READ, + CLOSE, + DONE, +} STATE; + +STATE state = RESOLVEENDPOINT; + +unsigned tStart = 0; +unsigned tWait = 5000; + +// must have a datagram cache +UDPSocket udpClient; + +// our sketch datagram buffer +byte rgbRead[1024]; +int cbRead = 0; + +IPSTATUS status = ipsSuccess; +IPEndPoint epRemote; + + +// this is for udpClient.writeDatagram to write +byte rgbWriteDatagram[] = {'*','W','r','o','t','e',' ','f','r','o','m',' ','u','d','p','C','l','i','e','n','t','.','w','r','i','t','e','D','a','t','a','g','r','a','m','*','\n'}; +int cbWriteDatagram = sizeof(rgbWriteDatagram); + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * connection to the UDPEchoServer + * Use DHCP to get the IP, mask, and gateway + * by default we connect to port 12000 + * + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("UDPEchoClient 2.0"); + Serial.println("Digilent, Copyright 2013"); + Serial.println(""); + + // use DHCP to get our IP and network addresses + deIPcK.begin(); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and UdpClient class + * which usually is enough time for the Udp functions to complete on their first call. + * + * This code will write a sting to the server and have the server echo it back + * Remember, UDP is unreliable, so the server may not echo back if the datagram is lost + * + * ------------------------------------------------------------ */ +void loop() { + int cbRead = 0; + + switch(state) + { + case RESOLVEENDPOINT: + if(deIPcK.resolveEndPoint(szIPServer, portServer, epRemote, &status)) + { + if(deIPcK.udpSetEndPoint(epRemote, udpClient, portDynamicallyAssign, &status)) + { + state = WRITE; + } + } + + // alway check the status and get out on error + if(IsIPStatusAnError(status)) + { + Serial.print("Unable to resolve endpoint, error: 0x"); + Serial.println(status, HEX); + state = CLOSE; + } + break; + + // write out the strings + case WRITE: + if(deIPcK.isIPReady(&status)) + { + Serial.println("Writing out Datagram"); + + udpClient.writeDatagram(rgbWriteDatagram, cbWriteDatagram); + + Serial.println("Waiting to see if a datagram comes back:"); + state = READ; + tStart = (unsigned) millis(); + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Lost the network, error: 0x"); + Serial.println(status, HEX); + state = CLOSE; + } + break; + + // look for the echo back + case READ: + + // see if we got anything to read + if((cbRead = udpClient.available()) > 0) + { + + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = udpClient.readDatagram(rgbRead, cbRead); + + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + + // give us some more time to wait for stuff to come back + tStart = (unsigned) millis(); + } + + // give us some time to get everything echo'ed back + // or if the datagram is never echoed back + else if( (((unsigned) millis()) - tStart) > tWait ) + { + Serial.println("Done waiting, assuming nothing more is coming"); + Serial.println(""); + state = CLOSE; + } + break; + + // done, so close up the tcpClient + case CLOSE: + udpClient.close(); + Serial.println("Closing udpClient, Done with sketch."); + state = DONE; + break; + + case DONE: + default: + break; + } + + // keep the stack alive each pass through the loop() + DEIPcK::periodicTasks(); +} + diff --git a/hardware/pic32/libraries/DEIPcK/examples/UDPEchoServer/UDPEchoServer.ino b/hardware/pic32/libraries/DEIPcK/examples/UDPEchoServer/UDPEchoServer.ino new file mode 100644 index 000000000..a4fad06ae --- /dev/null +++ b/hardware/pic32/libraries/DEIPcK/examples/UDPEchoServer/UDPEchoServer.ino @@ -0,0 +1,326 @@ +/************************************************************************/ +/* */ +/* UDPEchoServer */ +/* */ +/* A chipKIT DEIPcK UDP Server application to */ +/* demonstrate how to use the udpServer Class. */ +/* This can be used in conjuction with UDPEchoClient */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014 (KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* MX7cK */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the the Internal MAC and SMSC 8720 PHY + +/************************************************************************/ +/* Required library, Do NOT comment out */ +/************************************************************************/ +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +// Internet assigned Static IP +IPv4 ipServer = {192,168,1,190}; +unsigned short portServer = 44400; + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + LISTEN, + ISLISTENING, + AVAILABLECLIENT, + ACCEPTCLIENT, + READ, + WRITE, + CLOSE, + EXIT, + DONE +} STATE; + +STATE state = LISTEN; + +unsigned tStart = 0; +unsigned tWait = 5000; + +// remember to give the UDP client a datagram cache +#define cUDPSockets 3 +static UDPSocket rgUDPClient[cUDPSockets]; +static UDPSocket * pUdpSocket = NULL; +static UDPServer udpServer; + +IPSTATUS status; + +// a read buffer +byte rgbRead[1024]; +int cbRead = 0; +int count = 0; +int i = 0; + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * the IP stack for a static IP of ipServer + * No other network addresses are supplied so + * DNS will fail as any name lookup and time servers + * will all fail. But since we are only listening, who cares. + * + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("UDPEchoServer 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); + + // intialize the stack with a static IP + deIPcK.begin(ipServer); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and UdpServer class + * which usually is enough time for the UDP functions to complete on their first call. + * + * This code listens for a connection, then echos any strings that come in + * After about 5 seconds of inactivity, it will drop the connection. + * + * This is a simple sketch to illistrate a simple UDP Server. + * + * ------------------------------------------------------------ */ +void loop() { + + switch(state) + { + + // say to listen on the port + case LISTEN: + if(deIPcK.udpStartListening(portServer, udpServer, &status)) + { + // add our sockets + for(i=0; i 0) + { + Serial.print(i, DEC); + Serial.print(" Sockets listening on port: "); + Serial.print(portServer, DEC); + Serial.println(""); + state = AVAILABLECLIENT; + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Lost IP connectivity, error: 0x"); + Serial.println(status, HEX); + state = EXIT; + } + break; + + // wait for a connection + case AVAILABLECLIENT: + if((count = udpServer.availableClients()) > 0) + { + Serial.print("Got "); + Serial.print(count, DEC); + Serial.println(" clients pending"); + state = ACCEPTCLIENT; + } + break; + + // accept the connection + case ACCEPTCLIENT: + + // accept the client + if((pUdpSocket = udpServer.acceptClient()) != NULL) + { + Serial.println("Got a Connection"); + state = READ; + tStart = (unsigned) millis(); + } + + // this probably won't happen unless the connection is dropped + // if it is, just release our socket and go back to listening + else + { + state = CLOSE; + } + break; + + // wait fot the read, but if too much time elapses (5 seconds) + // we will just close the udpClient and go back to listening + case READ: + + // see if we got anything to read + if((cbRead = pUdpSocket->available()) > 0) + { + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = pUdpSocket->readDatagram(rgbRead, cbRead); + + Serial.print("Got "); + Serial.print(cbRead, DEC); + Serial.println(" bytes"); + + state = WRITE; + } + + // If too much time elapsed between reads, close the connection + else if( (((unsigned) millis()) - tStart) > tWait ) + { + state = CLOSE; + } + break; + + // echo back the string + case WRITE: + + Serial.println("Writing datagram: "); + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + Serial.println(""); + + pUdpSocket->writeDatagram(rgbRead, cbRead); + state = READ; + tStart = (unsigned) millis(); + break; + + // close our udpClient and go back to listening + case CLOSE: + if(pUdpSocket != NULL) + { + pUdpSocket->close(); + udpServer.addSocket(*pUdpSocket); + } + Serial.println("Closing UdpClient and re-adding it to the server"); + Serial.println(""); + state = ISLISTENING; + break; + + // something bad happen, just exit out of the program + case EXIT: + udpServer.close(); + for(i=0; i +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* 5/14/2014 (KeithV): Created */ +/************************************************************************/ +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* uC32 with a WiFiShield */ +/* WF32 */ +/* WiFIRE */ +/* */ +/************************************************************************/ +/************************************************************************/ +/* */ +/* Network Hardware libraries */ +/* INCLUDE ONLY ONE */ +/* */ +/************************************************************************/ +// You MUST select 1 and ONLY 1 of the following hardware libraries +// they are here so that MPIDE will put the lib path on the compiler include path. +#include // This is for the MRF24WGxx on a pmodWiFi or WiFiShield +//#include // This is for the the Internal MAC and SMSC 8720 PHY + +/************************************************************************/ +/* Network libraries */ +/************************************************************************/ +// The base network library +// this is a required library +// Do not comment out this library +#include + +// ----- COMMENT THIS OUT IF YOU ARE NOT USING WIFI ----- +#include + +//************************************************************************ +//************************************************************************ +//**************** END OF LIBRARY CONFIGURATION ************************** +//************************************************************************ +//************************************************************************ + +#define MRFVERSION + +typedef enum +{ + NONE = 0, + WIFISCAN, + PRINTAPINFO, + ERROR, + STOP, + DONE +} STATE; + +STATE state = WIFISCAN; + +IPSTATUS status = ipsSuccess; +int cNetworks = 0; +int iNetwork = 0; + +void setup() { + + Serial.begin(9600); + + Serial.println("Start of Sketch"); + Serial.println("WiFiScan 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); + + state = WIFISCAN; // Scan WiFi First, verify the WiFi connection + Serial.println("Start WiFi Scan"); + cNetworks = 0; +} + +void loop() +{ + switch(state) + { + case WIFISCAN: + if(deIPcK.wfScan(&cNetworks, &status)) + { + Serial.print("Scan Done, "); + Serial.print(cNetworks, DEC); + Serial.println(" Networks Found"); + state = PRINTAPINFO; + iNetwork = 0; + } + else if(IsIPStatusAnError(status)) + { + Serial.println("Scan Failed"); + Serial.println(""); + state = ERROR; + } + break; + + case PRINTAPINFO: + if(iNetwork < cNetworks) + { + SCANINFO scanInfo; + int j = 0; + + if(deIPcK.getScanInfo(iNetwork, &scanInfo)) + { + Serial.println(""); + Serial.print("Scan info for index: "); + Serial.println(iNetwork, DEC); + + Serial.print("SSID: "); + for(j=0; j> 7, DEC); + Serial.print(" "); + Serial.print((scanInfo.apConfig & 0b01000000) >> 6, DEC); + Serial.print(" "); + Serial.print((scanInfo.apConfig & 0b00100000) >> 5, DEC); + Serial.print(" "); + Serial.print((scanInfo.apConfig & 0b00010000) >> 4, DEC); + Serial.print(" "); + Serial.print((scanInfo.apConfig & 0b00001000) >> 3, DEC); + Serial.print(" "); + Serial.print((scanInfo.apConfig & 0b00000100) >> 2, DEC); + Serial.print(" "); + Serial.print((scanInfo.apConfig & 0b00000010) >> 1, DEC); + Serial.print(" "); + Serial.println((scanInfo.apConfig & 0b00000001), DEC); + + Serial.print("Count of support bit rates: "); + Serial.println(scanInfo.cBasicRates, DEC); + + for( j= 0; j< scanInfo.cBasicRates; j++) + { + uint32_t rate = (scanInfo.basicRateSet[j] & 0x7F) * 500; + Serial.print("\tSupported Rate: "); + Serial.print(rate, DEC); + Serial.println(" kbps"); + } + } + else + { + Serial.print("Unable to get scan info for iNetwork: "); + Serial.println(iNetwork, DEC); + } + + iNetwork++; + } + else + { +// this is MRF24 specific code +// this will not run in all implemenations +#if defined(MRFVERSION) + t_deviceInfo dvInfo; + WF_DeviceInfoGet(&dvInfo); + + Serial.println(""); + Serial.println("Device Info"); + Serial.print("DeviceType: 0x"); + Serial.print((int) dvInfo.deviceType, HEX); + Serial.print(" Rom Version: 0x"); + Serial.print((int) dvInfo.romVersion, HEX); + Serial.print(" Patch Version: 0x"); + Serial.println((int) dvInfo.patchVersion, HEX); +#endif + Serial.println(""); + state = STOP; + } + break; + + case ERROR: + Serial.print("Status value: "); + Serial.println(status, DEC); + state = STOP; + break; + + case STOP: + Serial.println("End of Sketch"); + state = DONE; + break; + + case DONE: + default: + break; + + } + + DEIPcK::periodicTasks(); +} + + diff --git a/hardware/pic32/libraries/DEWFcK/examples/WiFiTCPEchoClient/WiFiTCPEchoClient.ino b/hardware/pic32/libraries/DEWFcK/examples/WiFiTCPEchoClient/WiFiTCPEchoClient.ino new file mode 100644 index 000000000..e51a68c84 --- /dev/null +++ b/hardware/pic32/libraries/DEWFcK/examples/WiFiTCPEchoClient/WiFiTCPEchoClient.ino @@ -0,0 +1,305 @@ +/************************************************************************/ +/* */ +/* TCPEchoClient */ +/* */ +/* A chipKIT DEIPcK TCP Client application to */ +/* demonstrate how to use the TcpClient Class. */ +/* This can be used in conjuction with TCPEchoServer */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* */ +/* */ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014(KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* uC32 with a WiFiShield */ +/* WF32 */ +/* WiFIRE */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the MRF24WGxx on a pmodWiFi or WiFiShield + +/************************************************************************/ +/* Required libraries, Do NOT comment out */ +/************************************************************************/ +#include +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +const char * szIPServer = "192.168.1.180"; // server to connect to +uint16_t portServer = DEIPcK::iPersonalPorts44 + 300; // port 44300 + +// Specify the SSID +const char * szSsid = "chipKIT"; + +// select 1 for the security you want, or none for no security +#define USE_WPA2_PASSPHRASE +//#define USE_WPA2_KEY +//#define USE_WEP40 +//#define USE_WEP104 +//#define USE_WF_CONFIG_H + +// modify the security key to what you have. +#if defined(USE_WPA2_PASSPHRASE) + + const char * szPassPhrase = "Digilent"; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, szPassPhrase, &status) + +#elif defined(USE_WPA2_KEY) + + DEWFcK::WPA2KEY key = { 0x27, 0x2C, 0x89, 0xCC, 0xE9, 0x56, 0x31, 0x1E, + 0x3B, 0xAD, 0x79, 0xF7, 0x1D, 0xC4, 0xB9, 0x05, + 0x7A, 0x34, 0x4C, 0x3E, 0xB5, 0xFA, 0x38, 0xC2, + 0x0F, 0x0A, 0xB0, 0x90, 0xDC, 0x62, 0xAD, 0x58 }; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, key, &status) + +#elif defined(USE_WEP40) + + const int iWEPKey = 0; + DEWFcK::WEP40KEY keySet = { 0xBE, 0xC9, 0x58, 0x06, 0x97, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WEP104) + + const int iWEPKey = 0; + DEWFcK::WEP104KEY keySet = { 0x3E, 0xCD, 0x30, 0xB2, 0x55, 0x2D, 0x3C, 0x50, 0x52, 0x71, 0xE8, 0x83, 0x91, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WF_CONFIG_H) + + #define WiFiConnectMacro() deIPcK.wfConnect(0, &status) + +#else // no security - OPEN + + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, &status) + +#endif + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + CONNECT, + TCPCONNECT, + WRITE, + READ, + CLOSE, + DONE, +} STATE; + +STATE state = CONNECT; + +unsigned tStart = 0; +unsigned tWait = 5000; + +TCPSocket tcpSocket; +byte rgbRead[1024]; +int cbRead = 0; + +// this is for Print.write to print +byte rgbWrite[] = {'*','W','r','o','t','e',' ','f','r','o','m',' ','p','r','i','n','t','.','w','r','i','t','e','*','\n'}; +int cbWrite = sizeof(rgbWrite); + +// this is for tcpSocket.writeStream to print +byte rgbWriteStream[] = {'*','W','r','o','t','e',' ','f','r','o','m',' ','t','c','p','C','l','i','e','n','t','.','w','r','i','t','e','S','t','r','e','a','m','*','\n'}; +int cbWriteStream = sizeof(rgbWriteStream); + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * connection to the TCPEchoServer + * Use DHCP to get the IP, mask, and gateway + * by default we connect to port 44300 + * + * ------------------------------------------------------------ */ +void setup() +{ + Serial.begin(9600); + Serial.println("WiFiTCPEchoClient 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DEIPcK and TcpClient class + * which usually is enough time for the Tcp functions to complete on their first call. + * + * This code will write some stings to the server and have the server echo it back + * + * ------------------------------------------------------------ */ +void loop() { + IPSTATUS status; + int cbRead = 0; + + switch(state) + { + + case CONNECT: + if(WiFiConnectMacro()) + { + Serial.println("WiFi connected"); + deIPcK.begin(); + state = TCPCONNECT; + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Unable to connection, status: "); + Serial.println(status, DEC); + state = CLOSE; + } + break; + + case TCPCONNECT: + if(deIPcK.tcpConnect(szIPServer, portServer, tcpSocket)) + { + Serial.println("Connected to server."); + state = WRITE; + } + break; + + // write out the strings + case WRITE: + if(tcpSocket.isEstablished()) + { + tcpSocket.writeStream(rgbWriteStream, cbWriteStream); + + Serial.println("Bytes Read Back:"); + state = READ; + tStart = (unsigned) millis(); + } + break; + + // look for the echo back + case READ: + + // see if we got anything to read + if((cbRead = tcpSocket.available()) > 0) + { + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = tcpSocket.readStream(rgbRead, cbRead); + + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + } + + // give us some time to get everything echo'ed back + else if( (((unsigned) millis()) - tStart) > tWait ) + { + Serial.println(""); + state = CLOSE; + } + break; + + // done, so close up the tcpSocket + case CLOSE: + tcpSocket.close(); + Serial.println("Closing TcpClient, Done with sketch."); + state = DONE; + break; + + case DONE: + default: + break; + } + + // keep the stack alive each pass through the loop() + DEIPcK::periodicTasks(); +} + diff --git a/hardware/pic32/libraries/DEWFcK/examples/WiFiTCPEchoServer/WiFiTCPEchoServer.ino b/hardware/pic32/libraries/DEWFcK/examples/WiFiTCPEchoServer/WiFiTCPEchoServer.ino new file mode 100644 index 000000000..e380be5de --- /dev/null +++ b/hardware/pic32/libraries/DEWFcK/examples/WiFiTCPEchoServer/WiFiTCPEchoServer.ino @@ -0,0 +1,386 @@ +/************************************************************************/ +/* */ +/* TCPEchoServer */ +/* */ +/* A chipKIT DEWFcK TCP Server application to */ +/* demonstrate how to use the TcpServer Class. */ +/* This can be used in conjuction with TCPEchoClient */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014 (KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* uC32 with a WiFiShield */ +/* WF32 */ +/* WiFIRE */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the MRF24WGxx on a pmodWiFi or WiFiShield + +/************************************************************************/ +/* Required libraries, Do NOT comment out */ +/************************************************************************/ +#include +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +IPv4 ipServer = {192,168,1,190}; +unsigned short portServer = DEIPcK::iPersonalPorts44 + 300; // port 44300 + +// Specify the SSID +const char * szSsid = "chipKIT"; + +// select 1 for the security you want, or none for no security +#define USE_WPA2_PASSPHRASE +//#define USE_WPA2_KEY +//#define USE_WEP40 +//#define USE_WEP104 +//#define USE_WF_CONFIG_H + +// modify the security key to what you have. +#if defined(USE_WPA2_PASSPHRASE) + + const char * szPassPhrase = "Digilent"; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, szPassPhrase, &status) + +#elif defined(USE_WPA2_KEY) + + DEWFcK::WPA2KEY key = { 0x27, 0x2C, 0x89, 0xCC, 0xE9, 0x56, 0x31, 0x1E, + 0x3B, 0xAD, 0x79, 0xF7, 0x1D, 0xC4, 0xB9, 0x05, + 0x7A, 0x34, 0x4C, 0x3E, 0xB5, 0xFA, 0x38, 0xC2, + 0x0F, 0x0A, 0xB0, 0x90, 0xDC, 0x62, 0xAD, 0x58 }; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, key, &status) + +#elif defined(USE_WEP40) + + const int iWEPKey = 0; + DEWFcK::WEP40KEY keySet = { 0xBE, 0xC9, 0x58, 0x06, 0x97, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WEP104) + + const int iWEPKey = 0; + DEWFcK::WEP104KEY keySet = { 0x3E, 0xCD, 0x30, 0xB2, 0x55, 0x2D, 0x3C, 0x50, 0x52, 0x71, 0xE8, 0x83, 0x91, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WF_CONFIG_H) + + #define WiFiConnectMacro() deIPcK.wfConnect(0, &status) + +#else // no security - OPEN + + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, &status) + +#endif + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + CONNECT, + LISTEN, + ISLISTENING, + WAITISLISTENING, + AVAILABLECLIENT, + ACCEPTCLIENT, + READ, + WRITE, + CLOSE, + EXIT, + DONE +} STATE; + +STATE state = CONNECT; + +unsigned tStart = 0; +unsigned tWait = 5000; + +TCPServer tcpServer; +#define cTcpClients 2 +TCPSocket rgTcpClient[cTcpClients]; + +TCPSocket * ptcpClient = NULL; + +byte rgbRead[1024]; +int cbRead = 0; +int count = 0; + +IPSTATUS status; + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * the IP stack for a static IP of ipServer + * No other network addresses are supplied so + * DNS will fail as any name lookup and time servers + * will all fail. But since we are only listening, who cares. + * + * ------------------------------------------------------------ */ +void setup() { + Serial.begin(9600); + Serial.println("WiFiTCPEchoServer 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and TcpServer class + * which usually is enough time for the Tcp functions to complete on their first call. + * + * This code listens for a connection, then echos any strings that come in + * After about 5 seconds of inactivity, it will drop the connection. + * + * This is a simple sketch to illistrate a simple TCP Server. + * + * ------------------------------------------------------------ */ +void loop() { + + switch(state) + { + + case CONNECT: + if(WiFiConnectMacro()) + { + Serial.println("Connection Created"); + deIPcK.begin(ipServer); + state = LISTEN; + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Unable to connection, status: "); + Serial.println(status, DEC); + state = CLOSE; + } + break; + + // say to listen on the port + case LISTEN: + if(deIPcK.tcpStartListening(portServer, tcpServer)) + { + for(int i = 0; i < cTcpClients; i++) + { + tcpServer.addSocket(rgTcpClient[i]); + } + } + state = ISLISTENING; + break; + + case ISLISTENING: + count = tcpServer.isListening(); + Serial.print(count, DEC); + Serial.print(" sockets listening on port: "); + Serial.println(portServer, DEC); + + if(count > 0) + { + state = AVAILABLECLIENT; + } + else + { + state = WAITISLISTENING; + } + break; + + case WAITISLISTENING: + if(tcpServer.isListening() > 0) + { + state = ISLISTENING; + } + break; + + // wait for a connection + case AVAILABLECLIENT: + if((count = tcpServer.availableClients()) > 0) + { + Serial.print("Got "); + Serial.print(count, DEC); + Serial.println(" clients pending"); + state = ACCEPTCLIENT; + } + break; + + // accept the connection + case ACCEPTCLIENT: + + // accept the client + if((ptcpClient = tcpServer.acceptClient()) != NULL && ptcpClient->isConnected()) + { + Serial.println("Got a Connection"); + state = READ; + tStart = (unsigned) millis(); + } + + // this probably won't happen unless the connection is dropped + // if it is, just release our socket and go back to listening + else + { + state = CLOSE; + } + break; + + // wait fot the read, but if too much time elapses (5 seconds) + // we will just close the tcpClient and go back to listening + case READ: + + // see if we got anything to read + if((cbRead = ptcpClient->available()) > 0) + { + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = ptcpClient->readStream(rgbRead, cbRead); + + Serial.print("Got "); + Serial.print(cbRead, DEC); + Serial.println(" bytes"); + + state = WRITE; + } + + // If too much time elapsed between reads, close the connection + else if( (((unsigned) millis()) - tStart) > tWait ) + { + state = CLOSE; + } + break; + + // echo back the string + case WRITE: + if(ptcpClient->isConnected()) + { + Serial.println("Writing: "); + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + Serial.println(""); + + ptcpClient->writeStream(rgbRead, cbRead); + state = READ; + tStart = (unsigned) millis(); + } + + // the connection was closed on us, go back to listening + else + { + Serial.println("Unable to write back."); + state = CLOSE; + } + break; + + // close our tcpClient and go back to listening + case CLOSE: + ptcpClient->close(); + tcpServer.addSocket(*ptcpClient); + Serial.println(""); + state = ISLISTENING; + break; + + // something bad happen, just exit out of the program + case EXIT: + tcpServer.close(); + Serial.println("Something went wrong, sketch is done."); + state = DONE; + break; + + // do nothing in the loop + case DONE: + default: + break; + } + + // every pass through loop(), keep the stack alive + DEIPcK::periodicTasks(); +} diff --git a/hardware/pic32/libraries/DEWFcK/examples/WiFiUDPEchoClient/WiFiUDPEchoClient.ino b/hardware/pic32/libraries/DEWFcK/examples/WiFiUDPEchoClient/WiFiUDPEchoClient.ino new file mode 100644 index 000000000..0537f5bba --- /dev/null +++ b/hardware/pic32/libraries/DEWFcK/examples/WiFiUDPEchoClient/WiFiUDPEchoClient.ino @@ -0,0 +1,328 @@ +/************************************************************************/ +/* */ +/* UDPEchoClient */ +/* */ +/* A chipKIT DEWFcK UDP Client application to */ +/* demonstrate how to use the UdpClient Class. */ +/* This can be used in conjuction with UDPEchoServer */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014(KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* uC32 with a WiFiShield */ +/* WF32 */ +/* WiFIRE */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the MRF24WGxx on a pmodWiFi or WiFiShield + +/************************************************************************/ +/* Required libraries, Do NOT comment out */ +/************************************************************************/ +#include +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +const char * szIPServer = "192.168.1.180"; // server to connect to +uint16_t portServer = DEIPcK::iPersonalPorts44 + 400; // port 44400 + +// Specify the SSID +const char * szSsid = "chipKIT"; + +// select 1 for the security you want, or none for no security +#define USE_WPA2_PASSPHRASE +//#define USE_WPA2_KEY +//#define USE_WEP40 +//#define USE_WEP104 +//#define USE_WF_CONFIG_H + +// modify the security key to what you have. +#if defined(USE_WPA2_PASSPHRASE) + + const char * szPassPhrase = "Digilent"; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, szPassPhrase, &status) + +#elif defined(USE_WPA2_KEY) + + DEWFcK::WPA2KEY key = { 0x27, 0x2C, 0x89, 0xCC, 0xE9, 0x56, 0x31, 0x1E, + 0x3B, 0xAD, 0x79, 0xF7, 0x1D, 0xC4, 0xB9, 0x05, + 0x7A, 0x34, 0x4C, 0x3E, 0xB5, 0xFA, 0x38, 0xC2, + 0x0F, 0x0A, 0xB0, 0x90, 0xDC, 0x62, 0xAD, 0x58 }; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, key, &status) + +#elif defined(USE_WEP40) + + const int iWEPKey = 0; + DEWFcK::WEP40KEY keySet = { 0xBE, 0xC9, 0x58, 0x06, 0x97, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WEP104) + + const int iWEPKey = 0; + DEWFcK::WEP104KEY keySet = { 0x3E, 0xCD, 0x30, 0xB2, 0x55, 0x2D, 0x3C, 0x50, 0x52, 0x71, 0xE8, 0x83, 0x91, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WF_CONFIG_H) + + #define WiFiConnectMacro() deIPcK.wfConnect(0, &status) + +#else // no security - OPEN + + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, &status) + +#endif + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + CONNECT, + RESOLVEENDPOINT, + WRITE, + READ, + CLOSE, + DONE, +} STATE; + +STATE state = CONNECT; + +unsigned tStart = 0; +unsigned tWait = 5000; + +// must have a datagram cache +UDPSocket udpClient; + +// our sketch datagram buffer +byte rgbRead[1024]; +int cbRead = 0; + +IPSTATUS status = ipsSuccess; +IPEndPoint epRemote; + +// this is for udpClient.writeDatagram to write +byte rgbWriteDatagram[] = {'*','W','r','o','t','e',' ','f','r','o','m',' ','u','d','p','C','l','i','e','n','t','.','w','r','i','t','e','D','a','t','a','g','r','a','m','*','\n'}; +int cbWriteDatagram = sizeof(rgbWriteDatagram); + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * connection to the UDPEchoServer + * Use DHCP to get the IP, mask, and gateway + * by default we connect to port 44400 + * + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("UDPEchoClient 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and UdpClient class + * which usually is enough time for the Udp functions to complete on their first call. + * + * This code will write a sting to the server and have the server echo it back + * Remember, UDP is unreliable, so the server may not echo back if the datagram is lost + * + * ------------------------------------------------------------ */ +void loop() { + int cbRead = 0; + + switch(state) + { + + case CONNECT: + if(WiFiConnectMacro()) + { + Serial.println("WiFi connected"); + deIPcK.begin(); + state = RESOLVEENDPOINT; + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Unable to connection, status: "); + Serial.println(status, DEC); + state = CLOSE; + } + break; + + case RESOLVEENDPOINT: + if(deIPcK.resolveEndPoint(szIPServer, portServer, epRemote, &status)) + { + if(deIPcK.udpSetEndPoint(epRemote, udpClient, portDynamicallyAssign, &status)) + { + state = WRITE; + } + } + + // alway check the status and get out on error + if(IsIPStatusAnError(status)) + { + Serial.print("Unable to resolve endpoint, error: 0x"); + Serial.println(status, HEX); + state = CLOSE; + } + break; + + // write out the strings + case WRITE: + if(deIPcK.isIPReady(&status)) + { + Serial.println("Writing out Datagram"); + + udpClient.writeDatagram(rgbWriteDatagram, cbWriteDatagram); + + Serial.println("Waiting to see if a datagram comes back:"); + state = READ; + tStart = (unsigned) millis(); + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Lost the network, error: 0x"); + Serial.println(status, HEX); + state = CLOSE; + } + break; + + // look for the echo back + case READ: + + // see if we got anything to read + if((cbRead = udpClient.available()) > 0) + { + + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = udpClient.readDatagram(rgbRead, cbRead); + + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + + // give us some more time to wait for stuff to come back + tStart = (unsigned) millis(); + } + + // give us some time to get everything echo'ed back + // or if the datagram is never echoed back + else if( (((unsigned) millis()) - tStart) > tWait ) + { + Serial.println("Done waiting, assuming nothing more is coming"); + Serial.println(""); + state = CLOSE; + } + break; + + // done, so close up the tcpClient + case CLOSE: + udpClient.close(); + Serial.println("Closing udpClient, Done with sketch."); + state = DONE; + break; + + case DONE: + default: + break; + } + + // keep the stack alive each pass through the loop() + DEIPcK::periodicTasks(); +} + diff --git a/hardware/pic32/libraries/DEWFcK/examples/WiFiUDPEchoServer/WiFiUDPEchoServer.ino b/hardware/pic32/libraries/DEWFcK/examples/WiFiUDPEchoServer/WiFiUDPEchoServer.ino new file mode 100644 index 000000000..d2de72013 --- /dev/null +++ b/hardware/pic32/libraries/DEWFcK/examples/WiFiUDPEchoServer/WiFiUDPEchoServer.ino @@ -0,0 +1,394 @@ +/************************************************************************/ +/* */ +/* UDPEchoServer */ +/* */ +/* A chipKIT DEWFcK UDP Server application to */ +/* demonstrate how to use the udpServer Class. */ +/* This can be used in conjuction with UDPEchoClient */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2011, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 5/14/2014 (KeithV): Created */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* uC32 with a WiFiShield */ +/* WF32 */ +/* WiFIRE */ +/* */ +/************************************************************************/ + +//****************************************************************************************** +//****************************************************************************************** +//***************************** SET YOUR CONFIGURATION ************************************* +//****************************************************************************************** +//****************************************************************************************** + +/************************************************************************/ +/* */ +/* Include ONLY 1 hardware library that matches */ +/* the network hardware you are using */ +/* */ +/* Refer to the hardware library header file */ +/* for supported boards and hardware configurations */ +/* */ +/************************************************************************/ +#include // This is for the MRF24WGxx on a pmodWiFi or WiFiShield + +/************************************************************************/ +/* Required libraries, Do NOT comment out */ +/************************************************************************/ +#include +#include + +/************************************************************************/ +/* */ +/* SET THESE VALUES FOR YOUR NETWORK */ +/* */ +/************************************************************************/ + +// Internet assigned Static IP +IPv4 ipServer = {192,168,1,190}; + +unsigned short portServer = 44400; + +// Specify the SSID +const char * szSsid = "chipKIT"; + +// select 1 for the security you want, or none for no security +#define USE_WPA2_PASSPHRASE +//#define USE_WPA2_KEY +//#define USE_WEP40 +//#define USE_WEP104 +//#define USE_WF_CONFIG_H + +// modify the security key to what you have. +#if defined(USE_WPA2_PASSPHRASE) + + const char * szPassPhrase = "Digilent"; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, szPassPhrase, &status) + +#elif defined(USE_WPA2_KEY) + + DEWFcK::WPA2KEY key = { 0x27, 0x2C, 0x89, 0xCC, 0xE9, 0x56, 0x31, 0x1E, + 0x3B, 0xAD, 0x79, 0xF7, 0x1D, 0xC4, 0xB9, 0x05, + 0x7A, 0x34, 0x4C, 0x3E, 0xB5, 0xFA, 0x38, 0xC2, + 0x0F, 0x0A, 0xB0, 0x90, 0xDC, 0x62, 0xAD, 0x58 }; + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, key, &status) + +#elif defined(USE_WEP40) + + const int iWEPKey = 0; + DEWFcK::WEP40KEY keySet = { 0xBE, 0xC9, 0x58, 0x06, 0x97, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WEP104) + + const int iWEPKey = 0; + DEWFcK::WEP104KEY keySet = { 0x3E, 0xCD, 0x30, 0xB2, 0x55, 0x2D, 0x3C, 0x50, 0x52, 0x71, 0xE8, 0x83, 0x91, // Key 0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Key 3 + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, keySet, iWEPKey, &status) + +#elif defined(USE_WF_CONFIG_H) + + #define WiFiConnectMacro() deIPcK.wfConnect(0, &status) + +#else // no security - OPEN + + #define WiFiConnectMacro() deIPcK.wfConnect(szSsid, &status) + +#endif + +//****************************************************************************************** +//****************************************************************************************** +//***************************** END OF CONFIGURATION *************************************** +//****************************************************************************************** +//****************************************************************************************** + +typedef enum +{ + NONE = 0, + CONNECT, + LISTEN, + ISLISTENING, + AVAILABLECLIENT, + ACCEPTCLIENT, + READ, + WRITE, + CLOSE, + EXIT, + DONE +} STATE; + +STATE state = CONNECT; + +unsigned tStart = 0; +unsigned tWait = 5000; + +// remember to give the UDP client a datagram cache +#define cUDPSockets 3 +static UDPSocket rgUDPClient[cUDPSockets]; +static UDPSocket * pUdpSocket = NULL; +static UDPServer udpServer; + +IPSTATUS status; + +// a read buffer +byte rgbRead[1024]; +int cbRead = 0; +int count = 0; +int i = 0; + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup function. + * + * Initialize the Serial Monitor, and initializes the + * the IP stack for a static IP of ipServer + * No other network addresses are supplied so + * DNS will fail as any name lookup and time servers + * will all fail. But since we are only listening, who cares. + * + * ------------------------------------------------------------ */ +void setup() { + Serial.begin(9600); + Serial.println("WiFiUDPEchoServer 3.0"); + Serial.println("Digilent, Copyright 2014"); + Serial.println(""); +} + +/*** void loop() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop function. + * + * We are using the default timeout values for the DNETck and UdpServer class + * which usually is enough time for the UDP functions to complete on their first call. + * + * This code listens for a connection, then echos any strings that come in + * After about 5 seconds of inactivity, it will drop the connection. + * + * This is a simple sketch to illistrate a simple UDP Server. + * + * ------------------------------------------------------------ */ +void loop() { + + switch(state) + { + + case CONNECT: + if(WiFiConnectMacro()) + { + Serial.println("Connection Created"); + deIPcK.begin(ipServer); + state = LISTEN; + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Unable to connection, status: "); + Serial.println(status, DEC); + state = CLOSE; + } + break; + + // say to listen on the port + case LISTEN: + if(deIPcK.udpStartListening(portServer, udpServer, &status)) + { + // add our sockets + for(i=0; i 0) + { + Serial.print(i, DEC); + Serial.print(" Sockets listening on port: "); + Serial.print(portServer, DEC); + Serial.println(""); + state = AVAILABLECLIENT; + } + else if(IsIPStatusAnError(status)) + { + Serial.print("Lost IP connectivity, error: 0x"); + Serial.println(status, HEX); + state = EXIT; + } + break; + + // wait for a connection + case AVAILABLECLIENT: + if((count = udpServer.availableClients()) > 0) + { + Serial.print("Got "); + Serial.print(count, DEC); + Serial.println(" clients pending"); + state = ACCEPTCLIENT; + } + break; + + // accept the connection + case ACCEPTCLIENT: + + // accept the client + if((pUdpSocket = udpServer.acceptClient()) != NULL) + { + Serial.println("Got a Connection"); + state = READ; + tStart = (unsigned) millis(); + } + + // this probably won't happen unless the connection is dropped + // if it is, just release our socket and go back to listening + else + { + state = CLOSE; + } + break; + + // wait fot the read, but if too much time elapses (5 seconds) + // we will just close the udpClient and go back to listening + case READ: + + // see if we got anything to read + if((cbRead = pUdpSocket->available()) > 0) + { + cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead); + cbRead = pUdpSocket->readDatagram(rgbRead, cbRead); + + Serial.print("Got "); + Serial.print(cbRead, DEC); + Serial.println(" bytes"); + + state = WRITE; + } + + // If too much time elapsed between reads, close the connection + else if( (((unsigned) millis()) - tStart) > tWait ) + { + state = CLOSE; + } + break; + + // echo back the string + case WRITE: + + Serial.println("Writing datagram: "); + for(int i=0; i < cbRead; i++) + { + Serial.print((char) rgbRead[i]); + } + Serial.println(""); + + pUdpSocket->writeDatagram(rgbRead, cbRead); + state = READ; + tStart = (unsigned) millis(); + break; + + // close our udpClient and go back to listening + case CLOSE: + if(pUdpSocket != NULL) + { + pUdpSocket->close(); + udpServer.addSocket(*pUdpSocket); + } + Serial.println("Closing UdpClient and re-adding it to the server"); + Serial.println(""); + state = ISLISTENING; + break; + + // something bad happen, just exit out of the program + case EXIT: + udpServer.close(); + for(i=0; i + +/* ------------------------------------------------------------ */ +/* Local Type Definitions */ +/* ------------------------------------------------------------ */ + +#define cntBlinkInit 50000 + +/* ------------------------------------------------------------ */ +/* Global Variables */ +/* ------------------------------------------------------------ */ + +int cntBtnBlink; +uint8_t fbLedPmod; +uint8_t fbBtnPmod; +int xcoPmod; +int ycoPmod; +int fLed3; +int fLed4; + +/* Unlike many chipKIT/Arduino libraries, the DSPI library doesn't +** automatically instantiate any interface objects. It is necessary +** to declare an instance of one of the interface objects in the +** sketch. This creates an object to talk to SPI port 0. Similarly, +** declaring a variable of type DSPI1, DSPI2, DSPI3, etc. will create +** an object to talk to DSPI port 1, 2, or 3. +*/ +DSPI0 spi; + +/* ------------------------------------------------------------ */ +/* Local Variables */ +/* ------------------------------------------------------------ */ + + +/* ------------------------------------------------------------ */ +/* Forward Declarations */ +/* ------------------------------------------------------------ */ + + +/* ------------------------------------------------------------ */ +/* Procedure Definitions */ +/* ------------------------------------------------------------ */ +/*** setup +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Initialize the system. +*/ + +void setup() { + DeviceInit(); + AppInit(); +} + +/* ------------------------------------------------------------ */ +/*** loop +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Main application loop. +*/ + +void loop() { + AppTask(); +} + +/* ------------------------------------------------------------ */ +/*** DeviceInit +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform basic board/device level initialization. +*/ + +void DeviceInit() { + /* Set the LED pins to be outputs. Some boards support more + ** than two LEDs. On those boards, also blink the additional + ** LEDs. + */ + pinMode(PIN_LED1, OUTPUT); + pinMode(PIN_LED2, OUTPUT); +#if defined(PIN_LED3) + pinMode(PIN_LED3, OUTPUT); +#endif +#if defined(PIN_LED4) + pinMode(PIN_LED4, OUTPUT); +#endif + /* Initialize the SPI port. + ** Setting the SPI clock speed to 250khz will satisfy the + ** PmodJSTK requirement of having at least 6us of delay between + ** bytes sent. + */ + spi.begin(); + spi.setSpeed(250000); +} + +/* ------------------------------------------------------------ */ +/*** AppInit +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform application level initialization. Call the various +** init functions to initalize the application subsystems. +*/ + +void AppInit() { + /* Init program state variables. + */ + cntBtnBlink = cntBlinkInit; + fbLedPmod = 0x01; + fbBtnPmod = 0; + xcoPmod = 0; + ycoPmod = 0; + /* Start with LED3 on and LED4 off + */ + fLed3 = HIGH; + fLed4 = LOW; +} + +/* ------------------------------------------------------------ */ +/*** AppTask +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform main application functions. This is called once +** each time through the main program loop. +*/ + +void AppTask() { + unsigned int dwBtn; + /* Check the state of button 1 and set LED 1 accordingly + */ + dwBtn = fbBtnPmod & 0x01; + + if (dwBtn == 0) { + digitalWrite(PIN_LED1, LOW); + } else { + digitalWrite(PIN_LED1, HIGH); + } + + /* Check the state of button 2 and set LED 2 accordingly + */ + dwBtn = fbBtnPmod & 0x02; + + if (dwBtn == 0) { + digitalWrite(PIN_LED2, LOW); + } else { + digitalWrite(PIN_LED2, HIGH); + } + + /* Check if it is time to blink LED3 & LED4 and update + ** the joystick. + */ + cntBtnBlink -= 1; + + if (cntBtnBlink == 0) { +#if defined(PIN_LED3) + digitalWrite(PIN_LED3, fLed3); + fLed3 = (fLed3 == HIGH) ? LOW : HIGH; +#endif +#if defined(PIN_LED4) + digitalWrite(PIN_LED4, fLed4); + fLed4 = (fLed4 == HIGH) ? LOW : HIGH; +#endif + /* Toggle the setting for the LEDs on the joystick. + */ + fbLedPmod ^= 0x03; + /* Update the joystick. + */ + ReadJoystick(fbLedPmod, &fbBtnPmod, &xcoPmod, &ycoPmod); + cntBtnBlink = cntBlinkInit; + } +} + +/* ------------------------------------------------------------ */ +/*** ReadJoystick +** +** Parameters: +** fbLed - LED state to set +** pfbBtn - variable to receive button state +** pxco - pointer to var to receive x coordinate +** pyco - pointer to var to receive y coordinate +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Read the current position of the joystick and buttons. +*/ +void ReadJoystick(uint8_t fbLed, uint8_t * pfbBtn, int * pxco, int * pyco) { + uint8_t rgbSnd[5]; + uint8_t rgbRcv[5]; + int ib; + + /* Initialize the transmit buffer. + */ + for (ib = 0; ib < 5; ib++) { + rgbSnd[ib] = 0x50 + ib; + } + + rgbSnd[0] = fbLedPmod + 0x80; //first byte sent sets the LEDs + /* Bring SS low to begin the transaction. + */ + spi.setSelect(LOW); + /* Wait 10us for Pmod to become ready + */ + Delay10us(); + /* Send the data to the Pmod and get the response. + */ + spi.transfer(5, rgbSnd, rgbRcv); + /* Bring SS high to end the transaction. + */ + spi.setSelect(HIGH); + /* Set up the return values. + */ + *pfbBtn = rgbRcv[4] >> 1; + *pxco = (uint16_t)((rgbRcv[1] << 8) + rgbRcv[0]); + *pyco = (uint16_t)((rgbRcv[3] << 8) + rgbRcv[2]); +} + +/* ------------------------------------------------------------ */ +/*** Delay10us +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Delay loop for ~10uS +*/ + +void Delay10us() { + volatile int cnt; + + for (cnt = 0; cnt < 100; cnt++) { + } +} + +/* ------------------------------------------------------------ */ + +/************************************************************************/ + + diff --git a/hardware/pic32/libraries/DSPI/examples/PmodJstkDspiInt/PmodJstkDspiInt.ino b/hardware/pic32/libraries/DSPI/examples/PmodJstkDspiInt/PmodJstkDspiInt.ino new file mode 100644 index 000000000..aa620791d --- /dev/null +++ b/hardware/pic32/libraries/DSPI/examples/PmodJstkDspiInt/PmodJstkDspiInt.ino @@ -0,0 +1,402 @@ +/************************************************************************/ +/* */ +/* PmodJstkDspiInt -- Illustrate Use of DSPI Library with PmodJSTK */ +/* */ +/************************************************************************/ +/* Author: Gene Apperson */ +/* Copyright 2011, Digilent Inc, All rights reserved. */ +/************************************************************************/ +/* + This program 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 +*/ +/************************************************************************/ +/* Module Description: */ +/* */ +/* This example illustrates using the Digilent DSPI library to */ +/* communicate with a Digilent PmodJSTK. */ +/* The PmodJSTK is assumed to be connected to DSPI port 0. This sketch */ +/* illustrates the use of the interrupt driven DSPI data transfer */ +/* functions. */ +/* */ +/* This demo blinks LED3 and LED4 on boards that have four LEDs, and at */ +/* the same time, blinks the two LEDs on the PmodJSTK. It reads the */ +/* state of the two buttons on the PmodJSTK, and turns LED1 and LED2 on */ +/* and off based on the button state. The X and Y joystick position is */ +/* read and placed into global variables, but not used by the demo */ +/* itself. */ +/* */ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 10/27/2011(GeneApperson): Created */ +/* */ +/************************************************************************/ + + +/* ------------------------------------------------------------ */ +/* Include File Definitions */ +/* ------------------------------------------------------------ */ + +/* Pull in the SPI library +*/ +#include + +/* ------------------------------------------------------------ */ +/* Local Type Definitions */ +/* ------------------------------------------------------------ */ + +#define cntBlinkInit 50000 + +/* ------------------------------------------------------------ */ +/* Global Variables */ +/* ------------------------------------------------------------ */ + +int cntBtnBlink; +uint8_t fbLedPmod; +uint8_t fbBtnPmod; +int xcoPmod; +int ycoPmod; +int fLed3; +int fLed4; + +/* Unlike many chipKIT/Arduino libraries, the DSPI library doesn't +** automatically instantiate any interface objects. It is necessary +** to declare an instance of one of the interface objects in the +** sketch. This creates an object to talk to SPI port 0. Similarly, +** declaring a variable of type DSPI1, DSPI2 or DSPI3 will create +** an object to talk to SPI port 1, 2, or 3. +*/ +DSPI0 spi; + +/* These two arrays are used to send and receive data to/from the +** PmodJSTK. They must be statically allocated (i.e. not automatic +** variables inside of a function) as they are accessed at interrupt +** time, and are accessed by more than one function. +*/ +uint8_t rgbSnd[5]; +uint8_t rgbRcv[5]; + +/* This state variable is used to indicate that a PmodJSTK update +** transaction is in progress. +*/ +int fUpdate = false; + +/* ------------------------------------------------------------ */ +/* Local Variables */ +/* ------------------------------------------------------------ */ + + +/* ------------------------------------------------------------ */ +/* Forward Declarations */ +/* ------------------------------------------------------------ */ + + +/* ------------------------------------------------------------ */ +/* Procedure Definitions */ +/* ------------------------------------------------------------ */ +/*** setup +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Initialize the system. +*/ + +void setup() { + DeviceInit(); + AppInit(); +} + +/* ------------------------------------------------------------ */ +/*** loop +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Main application loop. +*/ + +void +loop() { + AppTask(); +} + +/* ------------------------------------------------------------ */ +/*** DeviceInit +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform basic board/device level initialization. +*/ + +void DeviceInit() { + /* Set the LED pins to be outputs. Some boards support more + ** than two LEDs. On those boards, also blink the additional + ** LEDs. + */ + pinMode(PIN_LED1, OUTPUT); + pinMode(PIN_LED2, OUTPUT); +#if defined(PIN_LED3) + pinMode(PIN_LED3, OUTPUT); +#endif +#if defined(PIN_LED4) + pinMode(PIN_LED4, OUTPUT); +#endif + /* Initialize the SPI port. + ** Setting the SPI clock speed to 250khz will satisfy the + ** PmodJSTK requirement of having at least 6us of delay between + ** bytes sent. + */ + spi.begin(); + spi.setSpeed(250000); + spi.enableInterruptTransfer(); +} + +/* ------------------------------------------------------------ */ +/*** AppInit +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform application level initialization. Call the various +** init functions to initalize the application subsystems. +*/ + +void AppInit() { + /* Init program state variables. + */ + cntBtnBlink = cntBlinkInit; + fbLedPmod = 0x01; + fbBtnPmod = 0; + xcoPmod = 0; + ycoPmod = 0; + /* Start with LED3 on and LED4 off + */ + fLed3 = HIGH; + fLed4 = LOW; +} + +/* ------------------------------------------------------------ */ +/*** AppTask +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform main application functions. This is called once +** each time through the main program loop. +*/ + +void AppTask() { + unsigned int dwBtn; + /* Check the state of button 1 and set LED 1 accordingly + */ + dwBtn = fbBtnPmod & 0x01; + + if (dwBtn == 0) { + digitalWrite(PIN_LED1, LOW); + } else { + digitalWrite(PIN_LED1, HIGH); + } + + /* Check the state of button 2 and set LED 2 accordingly + */ + dwBtn = fbBtnPmod & 0x02; + + if (dwBtn == 0) { + digitalWrite(PIN_LED2, LOW); + } else { + digitalWrite(PIN_LED2, HIGH); + } + + /* Check if it is time to blink LED3 & LED4 + */ + cntBtnBlink -= 1; + + if (cntBtnBlink == 0) { +#if defined(PIN_LED3) + digitalWrite(PIN_LED3, fLed3); + fLed3 = (fLed3 == HIGH) ? LOW : HIGH; +#endif +#if defined(PIN_LED4) + digitalWrite(PIN_LED4, fLed4); + fLed4 = (fLed4 == HIGH) ? LOW : HIGH; +#endif + /* Toggle the state for the LEDs on the Pmod. + */ + fbLedPmod ^= 0x03; + /* Start the transaction to update the joystick state. + */ + UpdateJoystick(fbLedPmod); + cntBtnBlink = cntBlinkInit; + } + + /* Check if the transaction with the PmodJSTK has completed + ** and update the local state if so. + */ + if (fUpdate) { + CompleteTransaction(&fbBtnPmod, &xcoPmod, &ycoPmod); + } +} + +/* ------------------------------------------------------------ */ +/*** UpdateJoystick +** +** Parameters: +** fbLed - LED state to set +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** This begins a transaction with the PmodJSTK to update it +** state. This formats a command packet and begins the transmission +** of the packet to the PmodJSTK. +*/ +void UpdateJoystick(uint8_t fbLed) { + /* Init the transmit buffer. This data gets sent to the PmodJSTK + */ + rgbSnd[0] = fbLedPmod + 0x80; + rgbSnd[1] = 1; + rgbSnd[2] = 2; + rgbSnd[3] = 3; + rgbSnd[4] = 4; + /* Bring SS low. This begins all SPI transfer operations + */ + spi.setSelect(LOW); + /* Wait 10us for Pmod to become ready. This is a requirement + ** of the PmodJSTK as we have to make sure that the microcontroller + ** on the board has had time to respond to the SS line coming + ** low. + */ + Delay10us(); + /* Shift the data in/out of the Pmod + */ + spi.intTransfer(5, rgbSnd, rgbRcv); + /* Set the global state variable to indicate that a transaction + ** is in progress. + */ + fUpdate = true; +} + +/* ------------------------------------------------------------ */ +/*** CompleteTransaction +** +** Parameters: +** pfbBtn - variable to receive button state +** pxco - pointer to var to receive x coordinate +** pyco - pointer to var to receive y coordinate +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** This ends the update transaction with the PmodJSTK. +** Once the transfer count has reached zero, all data has +** been sent/received to/from the PmodJSTK and the result +** is in the global array rgbRcv. +*/ +void CompleteTransaction(uint8_t * pfbBtn, int * pxco, int * pyco) { + int ib; + + if (spi.transCount() > 0) { + /* The transaction with the PmodJSTK hasn't completed yet. + */ + return; + } + + /* Bring SS high. This ends the SPI data transfer operation. + */ + spi.setSelect(HIGH); + /* Set up the return values with data received from the PmodJSTK. + ** The array rgbRcv contains the data that was received. + */ + *pfbBtn = rgbRcv[4] >> 1; //get the bits for the two push buttons + *pxco = (uint16_t)((rgbRcv[1] << 8) + rgbRcv[0]); + *pyco = (uint16_t)((rgbRcv[3] << 8) + rgbRcv[2]); + /* Reset the global state variable. + */ + fUpdate = false; +} + +/* ------------------------------------------------------------ */ +/*** Delay10us +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Delay loop for ~10uS +*/ + +void Delay10us() { + volatile int cnt; + + for (cnt = 0; cnt < 100; cnt++) { + } +} + +/* ------------------------------------------------------------ */ + +/************************************************************************/ + + diff --git a/hardware/pic32/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino b/hardware/pic32/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino new file mode 100755 index 000000000..a52f10899 --- /dev/null +++ b/hardware/pic32/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino @@ -0,0 +1,78 @@ +/* + * EEPROM Clear + * + * This sketch will erase the EEPROM memory. An erased + * EEPROM has all of the bytes set to 0xFF (255 decimal). + * + * Description + * Unlike the AVR micrcontrollers used on the Arduino boards, + * the PIC32 microcontrollers used on the chipKIT boards don't + * have internal EEPROM memory. Instead, FLASH memory is used + * to simulate EEPROM. There are two major differences between + * FLASH and EEPROM. 1) EEPROM is byte erasable and rewritable. + * With FLASH an entire page must be erased before any byte can + * be rewritten. 2) FLASH can't be erased and rewritten as many + * times as EEPROM. After a limited number of erase/write + * cycles, the FLASH page will 'wear out', and additional + * writes may not store the correct value. EEPROM can also + * wear out, but it typically takes many more writes to wear + * it out. + * To address these issues, the chipKIT EEPROM library uses a + * page of FLASH memory to simulate EEPROM. + * The FLASH is used as content addressable memory. A 32-bit + * word is used for each simulated EEPROM byte. The word stores + * both the EEPROM address and the byte value. When a write is + * performed, the page is searched for an unused location, when + * one is found, the address/data is written to that word. When + * reading, the page is searched for the address, and then the + * value is returned. If a location is being rewritten, the old + * location is marked as invalid and a new location written as + * described above. + * If there are no unused locations available in the page when a + * write is being attempted, then the page must be erased before + * the value can be written. The contents of the page is copied + * to a memory buffer, the page erased, and then the old values + * plus new value are written back to the FLASH page. This + * method reduces the number of times that the page must be + * erased and rewritten. + * The PIC32 FLASH page size is 4K (4096) bytes, which allows for + * simulation of up to 1K (1024) bytes of EEPROM. + * There is a degenerate case, however, that can lead to rapid + * wearout of the FLASH page being used. If all of the simulated + * EEPROM locations have been written (i.e. all simulated EEPROM + * addresses have been written to), then each additional write + * results in the page being erased and rewritten, eliminating + * the benefit of the wear leveling algorithm being used. + * This library uses two methods to help reduce this problem. + * The first is adding the clear() method. This method erases + * the flash page, erasing all simulated EEPROM. If a sketch has + * been run that uses a large amount of the simulated EEPROM, + * clear() should be used when that EEPROM content is not longer + * needed. This will reduce the number of values in the EEPROM + * that need to be preserved, reducing the number of times that + * the FLASH page will have to be erased and rewritten. The + * second method used to reduce the liklihood of premature FLASH + * wearout is to limit the default EEPROM memory size. By default + * this library implements 512 bytes of simulated EEPROM. This + * reserves at least half of the FLASH page to handle rewrites. + * It is possible to increase the simulated EEPROM size if a + * larger amount is needed. Two new methods have been added to + * accomodate this. getMaxAddress returns the current size of + * the simulated EEPROM. setMaxAddress allows setting it to + * a different size up to 1024. + */ + +#include + +void setup() +{ + // Clear entire eeprom + EEPROM.clear(); + + // turn the LED on when we're done + digitalWrite(13, HIGH); +} + +void loop() +{ +} diff --git a/hardware/pic32/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/hardware/pic32/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino new file mode 100755 index 000000000..3a52c3a83 --- /dev/null +++ b/hardware/pic32/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino @@ -0,0 +1,48 @@ +/* + * EEPROM Read + * + * Reads the value of each byte of the EEPROM and prints it + * to the computer. + * This example code is in the public domain. + * + * Settings: + * + * EEPROM.setMaxAddress(int value) + * This setting will allow a user determine the size + * of the emulated EEPROM. However this setting has + * the potential to prematurely wear out the flash if + * made to large. The largest allowable address is 1023 + * and the default value is 512 + */ + +#include + +// start reading from the first byte (address 0) of the EEPROM +int address = 0; +byte value; + +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + // read a byte from the current address of the EEPROM + value = EEPROM.read(address); + + Serial.print(address); + Serial.print("\t"); + Serial.print(value, DEC); + Serial.println(); + + // advance to the next address of the EEPROM + address = address + 1; + + // there are only 512 bytes of EEPROM, from 0 to 511, so if we're + // on address 512, wrap around to address 0 + if (address == 512) + address = 0; + + delay(100); +} diff --git a/hardware/pic32/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino b/hardware/pic32/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino new file mode 100755 index 000000000..a2cebae16 --- /dev/null +++ b/hardware/pic32/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino @@ -0,0 +1,95 @@ +/* + * EEPROM Write + * + * Stores values read from analog input 0 into the EEPROM. + * These values will stay in the EEPROM when the board is + * turned off and may be retrieved later by another sketch. + * + * Description + * Unlike the AVR micrcontrollers used on the Arduino boards, + * the PIC32 microcontrollers used on the chipKIT boards don't + * have internal EEPROM memory. Instead, FLASH memory is used + * to simulate EEPROM. There are two major differences between + * FLASH and EEPROM. 1) EEPROM is byte erasable and rewritable. + * With FLASH an entire page must be erased before any byte can + * be rewritten. 2) FLASH can't be erased and rewritten as many + * times as EEPROM. After a limited number of erase/write + * cycles, the FLASH page will 'wear out', and additional + * writes may not store the correct value. EEPROM can also + * wear out, but it typically takes many more writes to wear + * it out. + * To address these issues, the chipKIT EEPROM library uses a + * page of FLASH memory to simulate EEPROM. + * The FLASH is used as content addressable memory. A 32-bit + * word is used for each simulated EEPROM byte. The word stores + * both the EEPROM address and the byte value. When a write is + * performed, the page is searched for an unused location, when + * one is found, the address/data is written to that word. When + * reading, the page is searched for the address, and then the + * value is returned. If a location is being rewritten, the old + * location is marked as invalid and a new location written as + * described above. + * If there are no unused locations available in the page when a + * write is being attempted, then the page must be erased before + * the value can be written. The contents of the page is copied + * to a memory buffer, the page erased, and then the old values + * plus new value are written back to the FLASH page. This + * method reduces the number of times that the page must be + * erased and rewritten. + * The PIC32 FLASH page size is 4K (4096) bytes, which allows for + * simulation of up to 1K (1024) bytes of EEPROM. + * There is a degenerate case, however, that can lead to rapid + * wearout of the FLASH page being used. If all of the simulated + * EEPROM locations have been written (i.e. all simulated EEPROM + * addresses have been written to), then each additional write + * results in the page being erased and rewritten, eliminating + * the benefit of the wear leveling algorithm being used. + * This library uses two methods to help reduce this problem. + * The first is adding the clear() method. This method erases + * the flash page, erasing all simulated EEPROM. If a sketch has + * been run that uses a large amount of the simulated EEPROM, + * clear() should be used when that EEPROM content is not longer + * needed. This will reduce the number of values in the EEPROM + * that need to be preserved, reducing the number of times that + * the FLASH page will have to be erased and rewritten. The + * second method used to reduce the liklihood of premature FLASH + * wearout is to limit the default EEPROM memory size. By default + * this library implements 512 bytes of simulated EEPROM. This + * reserves at least half of the FLASH page to handle rewrites. + * It is possible to increase the simulated EEPROM size if a + * larger amount is needed. Two new methods have been added to + * accomodate this. getMaxAddress returns the current size of + * the simulated EEPROM. setMaxAddress allows setting it to + * a different size up to 1024. + */ + +#include + +// the current address in the EEPROM (i.e. which byte +// we're going to write to next) +int addr = 0; + +void setup() +{ +} + +void loop() +{ + // need to divide by 4 because analog inputs range from + // 0 to 1023 and each byte of the EEPROM can only hold a + // value from 0 to 255. + int val = analogRead(0) / 4; + + // write the value to the appropriate byte of the EEPROM. + // these values will remain there when the board is + // turned off. + EEPROM.write(addr, val); + + // advance to the next address. there are 512 bytes in + // the EEPROM, so go back to 0 when we hit 512. + addr = addr + 1; + if (addr == 512) + addr = 0; + + delay(100); +} diff --git a/hardware/pic32/libraries/Ethernet/Dhcp.cpp b/hardware/pic32/libraries/Ethernet/Dhcp.cpp new file mode 100644 index 000000000..50cf6ed95 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/Dhcp.cpp @@ -0,0 +1,480 @@ +// DHCP Library v0.3 - April 25, 2009 +// Author: Jordan Terrell - blog.jordanterrell.com + +#include "utility/w5100.h" + +#include +#include +#include "Dhcp.h" +#include "Arduino.h" +#include "utility/util.h" + +int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +{ + _dhcpLeaseTime=0; + _dhcpT1=0; + _dhcpT2=0; + _lastCheck=0; + _timeout = timeout; + _responseTimeout = responseTimeout; + + // zero out _dhcpMacAddr + memset(_dhcpMacAddr, 0, 6); + reset_DHCP_lease(); + + memcpy((void*)_dhcpMacAddr, (void*)mac, 6); + _dhcp_state = STATE_DHCP_START; + return request_DHCP_lease(); +} + +void DhcpClass::reset_DHCP_lease(){ + // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp + memset(_dhcpLocalIp, 0, 20); +} + +//return:0 on error, 1 if request is sent and response is received +int DhcpClass::request_DHCP_lease(){ + + uint8_t messageType = 0; + + + + // Pick an initial transaction ID + _dhcpTransactionId = random(1UL, 2000UL); + _dhcpInitialTransactionId = _dhcpTransactionId; + + _dhcpUdpSocket.stop(); + if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) + { + // Couldn't get a socket + return 0; + } + + presend_DHCP(); + + int result = 0; + + unsigned long startTime = millis(); + + while(_dhcp_state != STATE_DHCP_LEASED) + { + if(_dhcp_state == STATE_DHCP_START) + { + _dhcpTransactionId++; + + send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000)); + _dhcp_state = STATE_DHCP_DISCOVER; + } + else if(_dhcp_state == STATE_DHCP_REREQUEST){ + _dhcpTransactionId++; + send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000)); + _dhcp_state = STATE_DHCP_REQUEST; + } + else if(_dhcp_state == STATE_DHCP_DISCOVER) + { + uint32_t respId; + messageType = parseDHCPResponse(_responseTimeout, respId); + if(messageType == DHCP_OFFER) + { + // We'll use the transaction ID that the offer came with, + // rather than the one we were up to + _dhcpTransactionId = respId; + send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000)); + _dhcp_state = STATE_DHCP_REQUEST; + } + } + else if(_dhcp_state == STATE_DHCP_REQUEST) + { + uint32_t respId; + messageType = parseDHCPResponse(_responseTimeout, respId); + if(messageType == DHCP_ACK) + { + _dhcp_state = STATE_DHCP_LEASED; + result = 1; + //use default lease time if we didn't get it + if(_dhcpLeaseTime == 0){ + _dhcpLeaseTime = DEFAULT_LEASE; + } + //calculate T1 & T2 if we didn't get it + if(_dhcpT1 == 0){ + //T1 should be 50% of _dhcpLeaseTime + _dhcpT1 = _dhcpLeaseTime >> 1; + } + if(_dhcpT2 == 0){ + //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime + _dhcpT2 = _dhcpT1 << 1; + } + _renewInSec = _dhcpT1; + _rebindInSec = _dhcpT2; + } + else if(messageType == DHCP_NAK) + _dhcp_state = STATE_DHCP_START; + } + + if(messageType == 255) + { + messageType = 0; + _dhcp_state = STATE_DHCP_START; + } + + if(result != 1 && ((millis() - startTime) > _timeout)) + break; + } + + // We're done with the socket now + _dhcpUdpSocket.stop(); + _dhcpTransactionId++; + + return result; +} + +void DhcpClass::presend_DHCP() +{ +} + +void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) +{ + uint8_t buffer[32]; + memset(buffer, 0, 32); + IPAddress dest_addr( 255, 255, 255, 255 ); // Broadcast address + + if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT)) + { + // FIXME Need to return errors + return; + } + + buffer[0] = DHCP_BOOTREQUEST; // op + buffer[1] = DHCP_HTYPE10MB; // htype + buffer[2] = DHCP_HLENETHERNET; // hlen + buffer[3] = DHCP_HOPS; // hops + + // xid + unsigned long xid = htonl(_dhcpTransactionId); + memcpy(buffer + 4, &(xid), 4); + + // 8, 9 - seconds elapsed + buffer[8] = ((secondsElapsed & 0xff00) >> 8); + buffer[9] = (secondsElapsed & 0x00ff); + + // flags + unsigned short flags = htons(DHCP_FLAGSBROADCAST); + memcpy(buffer + 10, &(flags), 2); + + // ciaddr: already zeroed + // yiaddr: already zeroed + // siaddr: already zeroed + // giaddr: already zeroed + + //put data in W5100 transmit buffer + _dhcpUdpSocket.write(buffer, 28); + + memset(buffer, 0, 32); // clear local buffer + + memcpy(buffer, _dhcpMacAddr, 6); // chaddr + + //put data in W5100 transmit buffer + _dhcpUdpSocket.write(buffer, 16); + + memset(buffer, 0, 32); // clear local buffer + + // leave zeroed out for sname && file + // put in W5100 transmit buffer x 6 (192 bytes) + + for(int i = 0; i < 6; i++) { + _dhcpUdpSocket.write(buffer, 32); + } + + // OPT - Magic Cookie + buffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF); + buffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF); + buffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF); + buffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF); + + // OPT - message type + buffer[4] = dhcpMessageType; + buffer[5] = 0x01; + buffer[6] = messageType; //DHCP_REQUEST; + + // OPT - client identifier + buffer[7] = dhcpClientIdentifier; + buffer[8] = 0x07; + buffer[9] = 0x01; + memcpy(buffer + 10, _dhcpMacAddr, 6); + + // OPT - host name + buffer[16] = hostName; + buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address + strcpy((char*)&(buffer[18]), HOST_NAME); + + printByte((char*)&(buffer[24]), _dhcpMacAddr[3]); + printByte((char*)&(buffer[26]), _dhcpMacAddr[4]); + printByte((char*)&(buffer[28]), _dhcpMacAddr[5]); + + //put data in W5100 transmit buffer + _dhcpUdpSocket.write(buffer, 30); + + if(messageType == DHCP_REQUEST) + { + buffer[0] = dhcpRequestedIPaddr; + buffer[1] = 0x04; + buffer[2] = _dhcpLocalIp[0]; + buffer[3] = _dhcpLocalIp[1]; + buffer[4] = _dhcpLocalIp[2]; + buffer[5] = _dhcpLocalIp[3]; + + buffer[6] = dhcpServerIdentifier; + buffer[7] = 0x04; + buffer[8] = _dhcpDhcpServerIp[0]; + buffer[9] = _dhcpDhcpServerIp[1]; + buffer[10] = _dhcpDhcpServerIp[2]; + buffer[11] = _dhcpDhcpServerIp[3]; + + //put data in W5100 transmit buffer + _dhcpUdpSocket.write(buffer, 12); + } + + buffer[0] = dhcpParamRequest; + buffer[1] = 0x06; + buffer[2] = subnetMask; + buffer[3] = routersOnSubnet; + buffer[4] = dns; + buffer[5] = domainName; + buffer[6] = dhcpT1value; + buffer[7] = dhcpT2value; + buffer[8] = endOption; + + //put data in W5100 transmit buffer + _dhcpUdpSocket.write(buffer, 9); + + _dhcpUdpSocket.endPacket(); +} + +uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId) +{ + uint8_t type = 0; + uint8_t opt_len = 0; + + unsigned long startTime = millis(); + + while(_dhcpUdpSocket.parsePacket() <= 0) + { + if((millis() - startTime) > responseTimeout) + { + return 255; + } + delay(50); + } + // start reading in the packet + RIP_MSG_FIXED fixedMsg; + _dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED)); + + if(fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) + { + transactionId = ntohl(fixedMsg.xid); + if(memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 || (transactionId < _dhcpInitialTransactionId) || (transactionId > _dhcpTransactionId)) + { + // Need to read the rest of the packet here regardless + _dhcpUdpSocket.flush(); + return 0; + } + + memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4); + + // Skip to the option part + // Doing this a byte at a time so we don't have to put a big buffer + // on the stack (as we don't have lots of memory lying around) + for (int i =0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++) + { + _dhcpUdpSocket.read(); // we don't care about the returned byte + } + + while (_dhcpUdpSocket.available() > 0) + { + switch (_dhcpUdpSocket.read()) + { + case endOption : + break; + + case padOption : + break; + + case dhcpMessageType : + opt_len = _dhcpUdpSocket.read(); + type = _dhcpUdpSocket.read(); + break; + + case subnetMask : + opt_len = _dhcpUdpSocket.read(); + _dhcpUdpSocket.read(_dhcpSubnetMask, 4); + break; + + case routersOnSubnet : + opt_len = _dhcpUdpSocket.read(); + _dhcpUdpSocket.read(_dhcpGatewayIp, 4); + for (int i = 0; i < opt_len-4; i++) + { + _dhcpUdpSocket.read(); + } + break; + + case dns : + opt_len = _dhcpUdpSocket.read(); + _dhcpUdpSocket.read(_dhcpDnsServerIp, 4); + for (int i = 0; i < opt_len-4; i++) + { + _dhcpUdpSocket.read(); + } + break; + + case dhcpServerIdentifier : + opt_len = _dhcpUdpSocket.read(); + if( *((uint32_t*)_dhcpDhcpServerIp) == 0 || + IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() ) + { + _dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp)); + } + else + { + // Skip over the rest of this option + while (opt_len--) + { + _dhcpUdpSocket.read(); + } + } + break; + + case dhcpT1value : + opt_len = _dhcpUdpSocket.read(); + _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1)); + _dhcpT1 = ntohl(_dhcpT1); + break; + + case dhcpT2value : + opt_len = _dhcpUdpSocket.read(); + _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2)); + _dhcpT2 = ntohl(_dhcpT2); + break; + + case dhcpIPaddrLeaseTime : + opt_len = _dhcpUdpSocket.read(); + _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime)); + _dhcpLeaseTime = ntohl(_dhcpLeaseTime); + _renewInSec = _dhcpLeaseTime; + break; + + default : + opt_len = _dhcpUdpSocket.read(); + // Skip over the rest of this option + while (opt_len--) + { + _dhcpUdpSocket.read(); + } + break; + } + } + } + + // Need to skip to end of the packet regardless here + _dhcpUdpSocket.flush(); + + return type; +} + + +/* + returns: + 0/DHCP_CHECK_NONE: nothing happened + 1/DHCP_CHECK_RENEW_FAIL: renew failed + 2/DHCP_CHECK_RENEW_OK: renew success + 3/DHCP_CHECK_REBIND_FAIL: rebind fail + 4/DHCP_CHECK_REBIND_OK: rebind success +*/ +int DhcpClass::checkLease(){ + //this uses a signed / unsigned trick to deal with millis overflow + unsigned long now = millis(); + signed long snow = (long)now; + int rc=DHCP_CHECK_NONE; + if (_lastCheck != 0){ + signed long factor; + //calc how many ms past the timeout we are + factor = snow - (long)_secTimeout; + //if on or passed the timeout, reduce the counters + if ( factor >= 0 ){ + //next timeout should be now plus 1000 ms minus parts of second in factor + _secTimeout = snow + 1000 - factor % 1000; + //how many seconds late are we, minimum 1 + factor = factor / 1000 +1; + + //reduce the counters by that mouch + //if we can assume that the cycle time (factor) is fairly constant + //and if the remainder is less than cycle time * 2 + //do it early instead of late + if(_renewInSec < factor*2 ) + _renewInSec = 0; + else + _renewInSec -= factor; + + if(_rebindInSec < factor*2 ) + _rebindInSec = 0; + else + _rebindInSec -= factor; + } + + //if we have a lease but should renew, do it + if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){ + _dhcp_state = STATE_DHCP_REREQUEST; + rc = 1 + request_DHCP_lease(); + } + + //if we have a lease or is renewing but should bind, do it + if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){ + //this should basically restart completely + _dhcp_state = STATE_DHCP_START; + reset_DHCP_lease(); + rc = 3 + request_DHCP_lease(); + } + } + else{ + _secTimeout = snow + 1000; + } + + _lastCheck = now; + return rc; +} + +IPAddress DhcpClass::getLocalIp() +{ + return IPAddress(_dhcpLocalIp); +} + +IPAddress DhcpClass::getSubnetMask() +{ + return IPAddress(_dhcpSubnetMask); +} + +IPAddress DhcpClass::getGatewayIp() +{ + return IPAddress(_dhcpGatewayIp); +} + +IPAddress DhcpClass::getDhcpServerIp() +{ + return IPAddress(_dhcpDhcpServerIp); +} + +IPAddress DhcpClass::getDnsServerIp() +{ + return IPAddress(_dhcpDnsServerIp); +} + +void DhcpClass::printByte(char * buf, uint8_t n ) { + char *str = &buf[1]; + buf[0]='0'; + do { + unsigned long m = n; + n /= 16; + char c = m - 16 * n; + *str-- = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); +} diff --git a/hardware/pic32/libraries/Ethernet/Dhcp.h b/hardware/pic32/libraries/Ethernet/Dhcp.h new file mode 100644 index 000000000..6f9c632c7 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/Dhcp.h @@ -0,0 +1,178 @@ +// DHCP Library v0.3 - April 25, 2009 +// Author: Jordan Terrell - blog.jordanterrell.com + +#ifndef Dhcp_h +#define Dhcp_h + +#include "EthernetUdp.h" + +/* DHCP state machine. */ +#define STATE_DHCP_START 0 +#define STATE_DHCP_DISCOVER 1 +#define STATE_DHCP_REQUEST 2 +#define STATE_DHCP_LEASED 3 +#define STATE_DHCP_REREQUEST 4 +#define STATE_DHCP_RELEASE 5 + +#define DHCP_FLAGSBROADCAST 0x8000 + +/* UDP port numbers for DHCP */ +#define DHCP_SERVER_PORT 67 /* from server to client */ +#define DHCP_CLIENT_PORT 68 /* from client to server */ + +/* DHCP message OP code */ +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +/* DHCP message type */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +#define DHCP_HTYPE10MB 1 +#define DHCP_HTYPE100MB 2 + +#define DHCP_HLENETHERNET 6 +#define DHCP_HOPS 0 +#define DHCP_SECS 0 + +#define MAGIC_COOKIE 0x63825363 +#define MAX_DHCP_OPT 16 + +#define HOST_NAME "WIZnet" +#define DEFAULT_LEASE (900) //default lease time in seconds + +#define DHCP_CHECK_NONE (0) +#define DHCP_CHECK_RENEW_FAIL (1) +#define DHCP_CHECK_RENEW_OK (2) +#define DHCP_CHECK_REBIND_FAIL (3) +#define DHCP_CHECK_REBIND_OK (4) + +enum +{ + padOption = 0, + subnetMask = 1, + timerOffset = 2, + routersOnSubnet = 3, + /* timeServer = 4, + nameServer = 5,*/ + dns = 6, + /*logServer = 7, + cookieServer = 8, + lprServer = 9, + impressServer = 10, + resourceLocationServer = 11,*/ + hostName = 12, + /*bootFileSize = 13, + meritDumpFile = 14,*/ + domainName = 15, + /*swapServer = 16, + rootPath = 17, + extentionsPath = 18, + IPforwarding = 19, + nonLocalSourceRouting = 20, + policyFilter = 21, + maxDgramReasmSize = 22, + defaultIPTTL = 23, + pathMTUagingTimeout = 24, + pathMTUplateauTable = 25, + ifMTU = 26, + allSubnetsLocal = 27, + broadcastAddr = 28, + performMaskDiscovery = 29, + maskSupplier = 30, + performRouterDiscovery = 31, + routerSolicitationAddr = 32, + staticRoute = 33, + trailerEncapsulation = 34, + arpCacheTimeout = 35, + ethernetEncapsulation = 36, + tcpDefaultTTL = 37, + tcpKeepaliveInterval = 38, + tcpKeepaliveGarbage = 39, + nisDomainName = 40, + nisServers = 41, + ntpServers = 42, + vendorSpecificInfo = 43, + netBIOSnameServer = 44, + netBIOSdgramDistServer = 45, + netBIOSnodeType = 46, + netBIOSscope = 47, + xFontServer = 48, + xDisplayManager = 49,*/ + dhcpRequestedIPaddr = 50, + dhcpIPaddrLeaseTime = 51, + /*dhcpOptionOverload = 52,*/ + dhcpMessageType = 53, + dhcpServerIdentifier = 54, + dhcpParamRequest = 55, + /*dhcpMsg = 56, + dhcpMaxMsgSize = 57,*/ + dhcpT1value = 58, + dhcpT2value = 59, + /*dhcpClassIdentifier = 60,*/ + dhcpClientIdentifier = 61, + endOption = 255 +}; + +typedef struct _RIP_MSG_FIXED +{ + uint8_t op; + uint8_t htype; + uint8_t hlen; + uint8_t hops; + uint32_t xid; + uint16_t secs; + uint16_t flags; + uint8_t ciaddr[4]; + uint8_t yiaddr[4]; + uint8_t siaddr[4]; + uint8_t giaddr[4]; + uint8_t chaddr[6]; +}RIP_MSG_FIXED; + +class DhcpClass { +private: + uint32_t _dhcpInitialTransactionId; + uint32_t _dhcpTransactionId; + uint8_t _dhcpMacAddr[6]; + uint8_t _dhcpLocalIp[4]; + uint8_t _dhcpSubnetMask[4]; + uint8_t _dhcpGatewayIp[4]; + uint8_t _dhcpDhcpServerIp[4]; + uint8_t _dhcpDnsServerIp[4]; + uint32_t _dhcpLeaseTime; + uint32_t _dhcpT1, _dhcpT2; + signed long _renewInSec; + signed long _rebindInSec; + signed long _lastCheck; + unsigned long _timeout; + unsigned long _responseTimeout; + unsigned long _secTimeout; + uint8_t _dhcp_state; + EthernetUDP _dhcpUdpSocket; + + int request_DHCP_lease(); + void reset_DHCP_lease(); + void presend_DHCP(); + void send_DHCP_MESSAGE(uint8_t, uint16_t); + void printByte(char *, uint8_t); + + uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId); +public: + IPAddress getLocalIp(); + IPAddress getSubnetMask(); + IPAddress getGatewayIp(); + IPAddress getDhcpServerIp(); + IPAddress getDnsServerIp(); + + int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int checkLease(); +}; + +#endif diff --git a/hardware/pic32/libraries/Ethernet/Dns.cpp b/hardware/pic32/libraries/Ethernet/Dns.cpp new file mode 100644 index 000000000..62e36f8a3 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/Dns.cpp @@ -0,0 +1,423 @@ +// Arduino DNS client for WizNet5100-based Ethernet shield +// (c) Copyright 2009-2010 MCQN Ltd. +// Released under Apache License, version 2.0 + +#include "utility/w5100.h" +#include "EthernetUdp.h" +#include "utility/util.h" + +#include "Dns.h" +#include +//#include +#include "Arduino.h" + + +#define SOCKET_NONE 255 +// Various flags and header field values for a DNS message +#define UDP_HEADER_SIZE 8 +#define DNS_HEADER_SIZE 12 +#define TTL_SIZE 4 +#define QUERY_FLAG (0) +#define RESPONSE_FLAG (1<<15) +#define QUERY_RESPONSE_MASK (1<<15) +#define OPCODE_STANDARD_QUERY (0) +#define OPCODE_INVERSE_QUERY (1<<11) +#define OPCODE_STATUS_REQUEST (2<<11) +#define OPCODE_MASK (15<<11) +#define AUTHORITATIVE_FLAG (1<<10) +#define TRUNCATION_FLAG (1<<9) +#define RECURSION_DESIRED_FLAG (1<<8) +#define RECURSION_AVAILABLE_FLAG (1<<7) +#define RESP_NO_ERROR (0) +#define RESP_FORMAT_ERROR (1) +#define RESP_SERVER_FAILURE (2) +#define RESP_NAME_ERROR (3) +#define RESP_NOT_IMPLEMENTED (4) +#define RESP_REFUSED (5) +#define RESP_MASK (15) +#define TYPE_A (0x0001) +#define CLASS_IN (0x0001) +#define LABEL_COMPRESSION_MASK (0xC0) +// Port number that DNS servers listen on +#define DNS_PORT 53 + +// Possible return codes from ProcessResponse +#define SUCCESS 1 +#define TIMED_OUT -1 +#define INVALID_SERVER -2 +#define TRUNCATED -3 +#define INVALID_RESPONSE -4 + +void DNSClient::begin(const IPAddress& aDNSServer) +{ + iDNSServer = aDNSServer; + iRequestId = 0; +} + + +int DNSClient::inet_aton(const char* aIPAddrString, IPAddress& aResult) +{ + // See if we've been given a valid IP address + const char* p =aIPAddrString; + while (*p && + ( (*p == '.') || (*p >= '0') || (*p <= '9') )) + { + p++; + } + + if (*p == '\0') + { + // It's looking promising, we haven't found any invalid characters + p = aIPAddrString; + int segment =0; + int segmentValue =0; + while (*p && (segment < 4)) + { + if (*p == '.') + { + // We've reached the end of a segment + if (segmentValue > 255) + { + // You can't have IP address segments that don't fit in a byte + return 0; + } + else + { + aResult[segment] = (byte)segmentValue; + segment++; + segmentValue = 0; + } + } + else + { + // Next digit + segmentValue = (segmentValue*10)+(*p - '0'); + } + p++; + } + // We've reached the end of address, but there'll still be the last + // segment to deal with + if ((segmentValue > 255) || (segment > 3)) + { + // You can't have IP address segments that don't fit in a byte, + // or more than four segments + return 0; + } + else + { + aResult[segment] = (byte)segmentValue; + return 1; + } + } + else + { + return 0; + } +} + +int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) +{ + int ret =0; + + // See if it's a numeric IP address + if (inet_aton(aHostname, aResult)) + { + // It is, our work here is done + return 1; + } + + // Check we've got a valid DNS server to use + if (iDNSServer == INADDR_NONE) + { + return INVALID_SERVER; + } + + // Find a socket to use + if (iUdp.begin(1024+(millis() & 0xF)) == 1) + { + // Try up to three times + int retries = 0; +// while ((retries < 3) && (ret <= 0)) + { + // Send DNS request + ret = iUdp.beginPacket(iDNSServer, DNS_PORT); + if (ret != 0) + { + // Now output the request data + ret = BuildRequest(aHostname); + if (ret != 0) + { + // And finally send the request + ret = iUdp.endPacket(); + if (ret != 0) + { + // Now wait for a response + int wait_retries = 0; + ret = TIMED_OUT; + while ((wait_retries < 3) && (ret == TIMED_OUT)) + { + ret = ProcessResponse(5000, aResult); + wait_retries++; + } + } + } + } + retries++; + } + + // We're done with the socket now + iUdp.stop(); + } + + return ret; +} + +uint16_t DNSClient::BuildRequest(const char* aName) +{ + // Build header + // 1 1 1 1 1 1 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ID | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | QDCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ANCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | NSCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ARCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // As we only support one request at a time at present, we can simplify + // some of this header + iRequestId = millis(); // generate a random ID + uint16_t twoByteBuffer; + + // FIXME We should also check that there's enough space available to write to, rather + // FIXME than assume there's enough space (as the code does at present) + iUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId)); + + twoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG); + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + + twoByteBuffer = htons(1); // One question record + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + + twoByteBuffer = 0; // Zero answer records + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + // and zero additional records + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + + // Build question + const char* start =aName; + const char* end =start; + uint8_t len; + // Run through the name being requested + while (*end) + { + // Find out how long this section of the name is + end = start; + while (*end && (*end != '.') ) + { + end++; + } + + if (end-start > 0) + { + // Write out the size of this section + len = end-start; + iUdp.write(&len, sizeof(len)); + // And then write out the section + iUdp.write((uint8_t*)start, end-start); + } + start = end+1; + } + + // We've got to the end of the question name, so + // terminate it with a zero-length section + len = 0; + iUdp.write(&len, sizeof(len)); + // Finally the type and class of question + twoByteBuffer = htons(TYPE_A); + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + + twoByteBuffer = htons(CLASS_IN); // Internet class of question + iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); + // Success! Everything buffered okay + return 1; +} + + +uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) +{ + uint32_t startTime = millis(); + + // Wait for a response packet + while(iUdp.parsePacket() <= 0) + { + if((millis() - startTime) > aTimeout) + return TIMED_OUT; + delay(50); + } + + // We've had a reply! + // Read the UDP header + uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header + // Check that it's a response from the right server and the right port + if ( (iDNSServer != iUdp.remoteIP()) || + (iUdp.remotePort() != DNS_PORT) ) + { + // It's not from who we expected + return INVALID_SERVER; + } + + // Read through the rest of the response + if (iUdp.available() < DNS_HEADER_SIZE) + { + return TRUNCATED; + } + iUdp.read(header, DNS_HEADER_SIZE); + + uint16_t header_flags = htons(*((uint16_t*)&header[2])); + // Check that it's a response to this request + if ( ( iRequestId != (*((uint16_t*)&header[0])) ) || + ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) + { + // Mark the entire packet as read + iUdp.flush(); + return INVALID_RESPONSE; + } + // Check for any errors in the response (or in our request) + // although we don't do anything to get round these + if ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) + { + // Mark the entire packet as read + iUdp.flush(); + return -5; //INVALID_RESPONSE; + } + + // And make sure we've got (at least) one answer + uint16_t answerCount = htons(*((uint16_t*)&header[6])); + if (answerCount == 0 ) + { + // Mark the entire packet as read + iUdp.flush(); + return -6; //INVALID_RESPONSE; + } + + // Skip over any questions + for (uint16_t i =0; i < htons(*((uint16_t*)&header[4])); i++) + { + // Skip over the name + uint8_t len; + do + { + iUdp.read(&len, sizeof(len)); + if (len > 0) + { + // Don't need to actually read the data out for the string, just + // advance ptr to beyond it + while(len--) + { + iUdp.read(); // we don't care about the returned byte + } + } + } while (len != 0); + + // Now jump over the type and class + for (int i =0; i < 4; i++) + { + iUdp.read(); // we don't care about the returned byte + } + } + + // Now we're up to the bit we're interested in, the answer + // There might be more than one answer (although we'll just use the first + // type A answer) and some authority and additional resource records but + // we're going to ignore all of them. + + for (uint16_t i =0; i < answerCount; i++) + { + // Skip the name + uint8_t len; + do + { + iUdp.read(&len, sizeof(len)); + if ((len & LABEL_COMPRESSION_MASK) == 0) + { + // It's just a normal label + if (len > 0) + { + // And it's got a length + // Don't need to actually read the data out for the string, + // just advance ptr to beyond it + while(len--) + { + iUdp.read(); // we don't care about the returned byte + } + } + } + else + { + // This is a pointer to a somewhere else in the message for the + // rest of the name. We don't care about the name, and RFC1035 + // says that a name is either a sequence of labels ended with a + // 0 length octet or a pointer or a sequence of labels ending in + // a pointer. Either way, when we get here we're at the end of + // the name + // Skip over the pointer + iUdp.read(); // we don't care about the returned byte + // And set len so that we drop out of the name loop + len = 0; + } + } while (len != 0); + + // Check the type and class + uint16_t answerType; + uint16_t answerClass; + iUdp.read((uint8_t*)&answerType, sizeof(answerType)); + iUdp.read((uint8_t*)&answerClass, sizeof(answerClass)); + + // Ignore the Time-To-Live as we don't do any caching + for (int i =0; i < TTL_SIZE; i++) + { + iUdp.read(); // we don't care about the returned byte + } + + // And read out the length of this answer + // Don't need header_flags anymore, so we can reuse it here + iUdp.read((uint8_t*)&header_flags, sizeof(header_flags)); + + if ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) + { + if (htons(header_flags) != 4) + { + // It's a weird size + // Mark the entire packet as read + iUdp.flush(); + return -9;//INVALID_RESPONSE; + } + iUdp.read(aAddress.raw_address(), 4); + return SUCCESS; + } + else + { + // This isn't an answer type we're after, move onto the next one + for (uint16_t i =0; i < htons(header_flags); i++) + { + iUdp.read(); // we don't care about the returned byte + } + } + } + + // Mark the entire packet as read + iUdp.flush(); + + // If we get here then we haven't found an answer + return -10;//INVALID_RESPONSE; +} + diff --git a/hardware/pic32/libraries/Ethernet/Dns.h b/hardware/pic32/libraries/Ethernet/Dns.h new file mode 100644 index 000000000..c99f5c376 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/Dns.h @@ -0,0 +1,41 @@ +// Arduino DNS client for WizNet5100-based Ethernet shield +// (c) Copyright 2009-2010 MCQN Ltd. +// Released under Apache License, version 2.0 + +#ifndef DNSClient_h +#define DNSClient_h + +#include + +class DNSClient +{ +public: + // ctor + void begin(const IPAddress& aDNSServer); + + /** Convert a numeric IP address string into a four-byte IP address. + @param aIPAddrString IP address to convert + @param aResult IPAddress structure to store the returned IP address + @result 1 if aIPAddrString was successfully converted to an IP address, + else error code + */ + int inet_aton(const char *aIPAddrString, IPAddress& aResult); + + /** Resolve the given hostname to an IP address. + @param aHostname Name to be resolved + @param aResult IPAddress structure to store the returned IP address + @result 1 if aIPAddrString was successfully converted to an IP address, + else error code + */ + int getHostByName(const char* aHostname, IPAddress& aResult); + +protected: + uint16_t BuildRequest(const char* aName); + uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress); + + IPAddress iDNSServer; + uint16_t iRequestId; + EthernetUDP iUdp; +}; + +#endif diff --git a/hardware/pic32/libraries/Ethernet/EthernetClient.cpp b/hardware/pic32/libraries/Ethernet/EthernetClient.cpp new file mode 100644 index 000000000..a592bfdc9 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/EthernetClient.cpp @@ -0,0 +1,168 @@ +#include "utility/w5100.h" +#include "utility/socket.h" + +extern "C" { + #include "string.h" +} + +#include "Arduino.h" + +#include "Ethernet.h" +#include "EthernetClient.h" +#include "EthernetServer.h" +#include "Dns.h" + +uint16_t EthernetClient::_srcport = 49152; //Use IANA recommended ephemeral port range 49152-65535 + +EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) { +} + +EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) { +} + +int EthernetClient::connect(const char* host, uint16_t port) { + // Look up the host first + int ret = 0; + DNSClient dns; + IPAddress remote_addr; + + dns.begin(Ethernet.dnsServerIP()); + ret = dns.getHostByName(host, remote_addr); + if (ret == 1) { + return connect(remote_addr, port); + } else { + return ret; + } +} + +int EthernetClient::connect(IPAddress ip, uint16_t port) { + if (_sock != MAX_SOCK_NUM) + return 0; + + for (int i = 0; i < MAX_SOCK_NUM; i++) { + uint8_t s = socketStatus(i); + if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) { + _sock = i; + break; + } + } + + if (_sock == MAX_SOCK_NUM) + return 0; + + _srcport++; + if (_srcport == 0) _srcport = 49152; //Use IANA recommended ephemeral port range 49152-65535 + socket(_sock, SnMR::TCP, _srcport, 0); + + if (!::connect(_sock, rawIPAddress(ip), port)) { + _sock = MAX_SOCK_NUM; + return 0; + } + + while (status() != SnSR::ESTABLISHED) { + delay(1); + if (status() == SnSR::CLOSED) { + _sock = MAX_SOCK_NUM; + return 0; + } + } + + return 1; +} + +size_t EthernetClient::write(uint8_t b) { + return write(&b, 1); +} + +size_t EthernetClient::write(const uint8_t *buf, size_t size) { + if (_sock == MAX_SOCK_NUM) { + setWriteError(); + return 0; + } + if (!send(_sock, buf, size)) { + setWriteError(); + return 0; + } + return size; +} + +int EthernetClient::available() { + if (_sock != MAX_SOCK_NUM) + return recvAvailable(_sock); + return 0; +} + +int EthernetClient::read() { + uint8_t b; + if ( recv(_sock, &b, 1) > 0 ) + { + // recv worked + return b; + } + else + { + // No data available + return -1; + } +} + +int EthernetClient::read(uint8_t *buf, size_t size) { + return recv(_sock, buf, size); +} + +int EthernetClient::peek() { + uint8_t b; + // Unlike recv, peek doesn't check to see if there's any data available, so we must + if (!available()) + return -1; + ::peek(_sock, &b); + return b; +} + +void EthernetClient::flush() { + ::flush(_sock); +} + +void EthernetClient::stop() { + if (_sock == MAX_SOCK_NUM) + return; + + // attempt to close the connection gracefully (send a FIN to other side) + disconnect(_sock); + unsigned long start = millis(); + + // wait a second for the connection to close + while (status() != SnSR::CLOSED && millis() - start < 1000) + delay(1); + + // if it hasn't closed, close it forcefully + if (status() != SnSR::CLOSED) + close(_sock); + + EthernetClass::_server_port[_sock] = 0; + _sock = MAX_SOCK_NUM; +} + +uint8_t EthernetClient::connected() { + if (_sock == MAX_SOCK_NUM) return 0; + + uint8_t s = status(); + return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT || + (s == SnSR::CLOSE_WAIT && !available())); +} + +uint8_t EthernetClient::status() { + if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED; + return socketStatus(_sock); +} + +// the next function allows us to use the client returned by +// EthernetServer::available() as the condition in an if-statement. + +EthernetClient::operator bool() { + return _sock != MAX_SOCK_NUM; +} + +bool EthernetClient::operator==(const EthernetClient& rhs) { + return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM; +} diff --git a/hardware/pic32/libraries/Ethernet/EthernetClient.h b/hardware/pic32/libraries/Ethernet/EthernetClient.h new file mode 100644 index 000000000..1992db052 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/EthernetClient.h @@ -0,0 +1,39 @@ +#ifndef ethernetclient_h +#define ethernetclient_h +#include "Arduino.h" +#include "Print.h" +#include "Client.h" +#include "IPAddress.h" + +class EthernetClient : public Client { + +public: + EthernetClient(); + EthernetClient(uint8_t sock); + + uint8_t status(); + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char *host, uint16_t port); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual int read(uint8_t *buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool(); + virtual bool operator==(const EthernetClient&); + virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }; + + friend class EthernetServer; + + using Print::write; + +private: + static uint16_t _srcport; + uint8_t _sock; +}; + +#endif diff --git a/hardware/pic32/libraries/Ethernet/EthernetServer.cpp b/hardware/pic32/libraries/Ethernet/EthernetServer.cpp new file mode 100644 index 000000000..6d6ce8c80 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/EthernetServer.cpp @@ -0,0 +1,91 @@ +#include "utility/w5100.h" +#include "utility/socket.h" +extern "C" { +#include "string.h" +} + +#include "Ethernet.h" +#include "EthernetClient.h" +#include "EthernetServer.h" + +EthernetServer::EthernetServer(uint16_t port) +{ + _port = port; +} + +void EthernetServer::begin() +{ + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { + EthernetClient client(sock); + if (client.status() == SnSR::CLOSED) { + socket(sock, SnMR::TCP, _port, 0); + listen(sock); + EthernetClass::_server_port[sock] = _port; + break; + } + } +} + +void EthernetServer::accept() +{ + int listening = 0; + + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { + EthernetClient client(sock); + + if (EthernetClass::_server_port[sock] == _port) { + if (client.status() == SnSR::LISTEN) { + listening = 1; + } + else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) { + client.stop(); + } + } + } + + if (!listening) { + begin(); + } +} + +EthernetClient EthernetServer::available() +{ + accept(); + + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { + EthernetClient client(sock); + if (EthernetClass::_server_port[sock] == _port && + (client.status() == SnSR::ESTABLISHED || + client.status() == SnSR::CLOSE_WAIT)) { + if (client.available()) { + // XXX: don't always pick the lowest numbered socket. + return client; + } + } + } + + return EthernetClient(MAX_SOCK_NUM); +} + +size_t EthernetServer::write(uint8_t b) +{ + return write(&b, 1); +} + +size_t EthernetServer::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + + accept(); + + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { + EthernetClient client(sock); + + if (EthernetClass::_server_port[sock] == _port && + client.status() == SnSR::ESTABLISHED) { + n += client.write(buffer, size); + } + } + + return n; +} diff --git a/hardware/pic32/libraries/Ethernet/EthernetServer.h b/hardware/pic32/libraries/Ethernet/EthernetServer.h new file mode 100644 index 000000000..86ccafe96 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/EthernetServer.h @@ -0,0 +1,22 @@ +#ifndef ethernetserver_h +#define ethernetserver_h + +#include "Server.h" + +class EthernetClient; + +class EthernetServer : +public Server { +private: + uint16_t _port; + void accept(); +public: + EthernetServer(uint16_t); + EthernetClient available(); + virtual void begin(); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + using Print::write; +}; + +#endif diff --git a/hardware/pic32/libraries/Ethernet/EthernetUdp.cpp b/hardware/pic32/libraries/Ethernet/EthernetUdp.cpp new file mode 100644 index 000000000..b5dcb78cc --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/EthernetUdp.cpp @@ -0,0 +1,218 @@ +/* + * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield. + * This version only offers minimal wrapping of socket.c/socket.h + * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/ + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#include "utility/w5100.h" +#include "utility/socket.h" +#include "Ethernet.h" +#include "Udp.h" +#include "Dns.h" + +/* Constructor */ +EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {} + +/* Start EthernetUDP socket, listening at local port PORT */ +uint8_t EthernetUDP::begin(uint16_t port) { + if (_sock != MAX_SOCK_NUM) + return 0; + + for (int i = 0; i < MAX_SOCK_NUM; i++) { + uint8_t s = socketStatus(i); + if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) { + _sock = i; + break; + } + } + + if (_sock == MAX_SOCK_NUM) + return 0; + + _port = port; + _remaining = 0; + socket(_sock, SnMR::UDP, _port, 0); + + return 1; +} + +/* return number of bytes available in the current packet, + will return zero if parsePacket hasn't been called yet */ +int EthernetUDP::available() { + return _remaining; +} + +/* Release any resources being used by this EthernetUDP instance */ +void EthernetUDP::stop() +{ + if (_sock == MAX_SOCK_NUM) + return; + + close(_sock); + + EthernetClass::_server_port[_sock] = 0; + _sock = MAX_SOCK_NUM; +} + +int EthernetUDP::beginPacket(const char *host, uint16_t port) +{ + // Look up the host first + int ret = 0; + DNSClient dns; + IPAddress remote_addr; + + dns.begin(Ethernet.dnsServerIP()); + ret = dns.getHostByName(host, remote_addr); + if (ret == 1) { + return beginPacket(remote_addr, port); + } else { + return ret; + } +} + +int EthernetUDP::beginPacket(IPAddress ip, uint16_t port) +{ + _offset = 0; + return startUDP(_sock, rawIPAddress(ip), port); +} + +int EthernetUDP::endPacket() +{ + return sendUDP(_sock); +} + +size_t EthernetUDP::write(uint8_t byte) +{ + return write(&byte, 1); +} + +size_t EthernetUDP::write(const uint8_t *buffer, size_t size) +{ + uint16_t bytes_written = bufferData(_sock, _offset, buffer, size); + _offset += bytes_written; + return bytes_written; +} + +int EthernetUDP::parsePacket() +{ + // discard any remaining bytes in the last packet + flush(); + + if (recvAvailable(_sock) > 0) + { + //HACK - hand-parse the UDP packet using TCP recv method + uint8_t tmpBuf[8]; + int ret =0; + //read 8 header bytes and get IP and port from it + ret = recv(_sock,tmpBuf,8); + if (ret > 0) + { + _remoteIP = tmpBuf; + _remotePort = tmpBuf[4]; + _remotePort = (_remotePort << 8) + tmpBuf[5]; + _remaining = tmpBuf[6]; + _remaining = (_remaining << 8) + tmpBuf[7]; + + // When we get here, any remaining bytes are the data + ret = _remaining; + } + return ret; + } + // There aren't any packets available + return 0; +} + +int EthernetUDP::read() +{ + uint8_t byte; + + if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0)) + { + // We read things without any problems + _remaining--; + return byte; + } + + // If we get here, there's no data available + return -1; +} + +int EthernetUDP::read(unsigned char* buffer, size_t len) +{ + + if (_remaining > 0) + { + + int got; + + if (_remaining <= len) + { + // data should fit in the buffer + got = recv(_sock, buffer, _remaining); + } + else + { + // too much data for the buffer, + // grab as much as will fit + got = recv(_sock, buffer, len); + } + + if (got > 0) + { + _remaining -= got; + return got; + } + + } + + // If we get here, there's no data available or recv failed + return -1; + +} + +int EthernetUDP::peek() +{ + uint8_t b; + // Unlike recv, peek doesn't check to see if there's any data available, so we must. + // If the user hasn't called parsePacket yet then return nothing otherwise they + // may get the UDP header + if (!_remaining) + return -1; + ::peek(_sock, &b); + return b; +} + +void EthernetUDP::flush() +{ + // could this fail (loop endlessly) if _remaining > 0 and recv in read fails? + // should only occur if recv fails after telling us the data is there, lets + // hope the w5100 always behaves :) + + while (_remaining) + { + read(); + } +} + diff --git a/hardware/pic32/libraries/Ethernet/EthernetUdp.h b/hardware/pic32/libraries/Ethernet/EthernetUdp.h new file mode 100644 index 000000000..8a6b7ab5a --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/EthernetUdp.h @@ -0,0 +1,99 @@ +/* + * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield. + * This version only offers minimal wrapping of socket.c/socket.h + * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/ + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef ethernetudp_h +#define ethernetudp_h + +#include + +#define UDP_TX_PACKET_MAX_SIZE 24 + +class EthernetUDP : public UDP { +private: + uint8_t _sock; // socket ID for Wiz5100 + uint16_t _port; // local port to listen on + IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed + uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed + uint16_t _offset; // offset into the packet being sent + uint16_t _remaining; // remaining bytes of incoming packet yet to be processed + +public: + EthernetUDP(); // Constructor + virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop(); // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port); + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port); + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket(); + // Write a single byte into the packet + virtual size_t write(uint8_t); + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size); + + using Print::write; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket(); + // Number of bytes remaining in the current packet + virtual int available(); + // Read a single byte from the current packet + virtual int read(); + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len); + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); }; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek(); + virtual void flush(); // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() { return _remoteIP; }; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() { return _remotePort; }; +}; + +#endif diff --git a/hardware/pic32/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino b/hardware/pic32/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino new file mode 100644 index 000000000..6fa2787e0 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino @@ -0,0 +1,108 @@ +/* + Advanced Chat Server + + A more advanced server that distributes any incoming messages + to all connected clients but the client the message comes from. + 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. + + 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 + redesigned to make use of operator== 25 Nov 2013 + by Norbert Truchsess + + */ + +#include +#include + +// 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); +IPAddress subnet(255, 255, 0, 0); + + +// telnet defaults to port 23 +EthernetServer server(23); + +EthernetClient clients[4]; + +void setup() { + // initialize the ethernet device + Ethernet.begin(mac, ip, gateway, subnet); + // start listening for clients + server.begin(); + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + Serial.print("Chat server address:"); + Serial.println(Ethernet.localIP()); +} + +void loop() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + + boolean newClient = true; + for (byte i=0;i<4;i++) { + //check whether this client refers to the same socket as one of the existing instances: + if (clients[i]==client) { + newClient = false; + break; + } + } + + if (newClient) { + //check which of the existing clients can be overridden: + for (byte i=0;i<4;i++) { + if (!clients[i] && clients[i]!=client) { + clients[i] = client; + // clead out the input buffer: + client.flush(); + Serial.println("We have a new client"); + client.print("Hello, client number: "); + client.print(i); + client.println(); + break; + } + } + } + + if (client.available() > 0) { + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to all other connected clients: + for (byte i=0;i<4;i++) { + if (clients[i] && (clients[i]!=client)) { + clients[i].write(thisChar); + } + } + // echo the bytes to the server as well: + Serial.write(thisChar); + } + } + for (byte i=0;i<4;i++) { + if (!(clients[i].connected())) { + // client.stop() invalidates the internal socket-descriptor, so next use of == will allways return false; + clients[i].stop(); + } + } +} diff --git a/hardware/pic32/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino b/hardware/pic32/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino new file mode 100644 index 000000000..2c85ddd78 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino @@ -0,0 +1,223 @@ +/* + 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 + CSB: pin 7 + MOSI: pin 11 + MISO: pin 12 + SCK: pin 13 + + created 31 July 2010 + by Tom Igoe + */ + +#include +// the sensor communicates using SPI, so include the library: +#include + + +// assign a MAC address for the ethernet controller. +// fill in your address here: +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 subnet(255, 255, 255, 0); + + +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): +EthernetServer server(80); + + +//Sensor's memory register addresses: +const int PRESSURE = 0x1F; //3 most significant bits of pressure +const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure +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 chipSelectPin = 7; + +float temperature = 0.0; +long pressure = 0; +long lastReadingTime = 0; + +void setup() { + // start the SPI library: + SPI.begin(); + + // start the Ethernet connection and the server: + Ethernet.begin(mac, ip); + server.begin(); + + // initalize the data ready and chip select pins: + pinMode(dataReadyPin, INPUT); + pinMode(chipSelectPin, OUTPUT); + + Serial.begin(9600); + + //Configure SCP1000 for low noise configuration: + writeRegister(0x02, 0x2D); + writeRegister(0x01, 0x03); + writeRegister(0x03, 0x02); + + // give the sensor and Ethernet shield time to set up: + delay(1000); + + //Set the sensor to high resolution mode tp start readings: + writeRegister(0x03, 0x0A); + +} + +void loop() { + // check for a reading no more than once a second. + 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) { + getData(); + // timestamp the last time you got a reading: + lastReadingTime = millis(); + } + } + + // listen for incoming Ethernet connections: + listenForEthernetClients(); +} + + +void getData() { + Serial.println("Getting reading"); + //Read the temperature data + int tempData = readRegister(0x21, 2); + + // convert the temperature to celsius and display it: + temperature = (float)tempData / 20.0; + + //Read the pressure data highest 3 bits: + 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); + //combine the two parts into one 19-bit number: + pressure = ((pressureDataHigh << 16) | pressureDataLow) / 4; + + Serial.print("Temperature: "); + Serial.print(temperature); + Serial.println(" degrees C"); + Serial.print("Pressure: " + String(pressure)); + Serial.println(" Pa"); +} + +void listenForEthernetClients() { + // listen for incoming clients + EthernetClient client = server.available(); + if (client) { + Serial.println("Got a client"); + // an http request ends with a blank line + boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + // if you've gotten to the end of the line (received a newline + // character) and the line is blank, the http request has ended, + // so you can send a reply + if (c == '\n' && currentLineIsBlank) { + // send a standard http response header + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println(); + // print the current readings, in HTML format: + client.print("Temperature: "); + client.print(temperature); + client.print(" degrees C"); + client.println("
"); + client.print("Pressure: " + String(pressure)); + client.print(" Pa"); + client.println("
"); + 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; + } + } + } + // give the web browser time to receive the data + delay(1); + // close the connection: + client.stop(); + } +} + + +//Send a write command to SCP1000 +void writeRegister(byte registerName, byte registerValue) { + // SCP1000 expects the register name in the upper 6 bits + // of the byte: + registerName <<= 2; + // command (read or write) goes in the lower two bits: + registerName |= 0b00000010; //Write command + + // take the chip select low to select the device: + 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); +} + + +//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 + + // SCP1000 expects the register name in the upper 6 bits + // of the byte: + registerName <<= 2; + // command (read or write) goes in the lower two bits: + registerName &= 0b11111100; //Read command + + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + int command = SPI.transfer(registerName); + // send a value of 0 to read the first byte returned: + inByte = SPI.transfer(0x00); + + result = inByte; + // if there's more than one byte returned, + // shift the first byte then get the second byte: + if (numBytes > 1) { + result = inByte << 8; + inByte = SPI.transfer(0x00); + result = result | inByte; + } + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + // return the result: + return(result); +} diff --git a/hardware/pic32/libraries/Ethernet/examples/ChatServer/ChatServer.ino b/hardware/pic32/libraries/Ethernet/examples/ChatServer/ChatServer.ino new file mode 100644 index 000000000..927a60e1b --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/ChatServer/ChatServer.ino @@ -0,0 +1,80 @@ +/* + 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. + + 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 +#include + +// 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); +IPAddress subnet(255, 255, 0, 0); + + +// telnet defaults to port 23 +EthernetServer server(23); +boolean alreadyConnected = false; // whether or not the client was connected previously + +void setup() { + // initialize the ethernet device + Ethernet.begin(mac, ip, gateway, subnet); + // start listening for clients + server.begin(); + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + Serial.print("Chat server address:"); + Serial.println(Ethernet.localIP()); +} + +void loop() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + if (!alreadyConnected) { + // clead out the input buffer: + client.flush(); + Serial.println("We have a new client"); + client.println("Hello, client!"); + alreadyConnected = true; + } + + if (client.available() > 0) { + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to the client: + server.write(thisChar); + // echo the bytes to the server as well: + Serial.write(thisChar); + } + } +} + + + diff --git a/hardware/pic32/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino b/hardware/pic32/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino new file mode 100644 index 000000000..a41b77403 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino @@ -0,0 +1,60 @@ +/* + 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. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 12 April 2011 + modified 9 Apr 2012 + by Tom Igoe + + */ + +#include +#include + +// 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 +}; + +// Initialize the Ethernet client library +// 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: + Serial.begin(9600); + // this check is only needed on the Leonardo: + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // start the Ethernet connection: + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // no point in carrying on, so do nothing forevermore: + for (;;) + ; + } + // print your local IP address: + Serial.print("My IP address: "); + 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.println(); +} + +void loop() { + +} + + diff --git a/hardware/pic32/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino b/hardware/pic32/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino new file mode 100644 index 000000000..73cde4bbb --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino @@ -0,0 +1,88 @@ +/* + 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. + + 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 +#include + +// 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); +IPAddress subnet(255, 255, 0, 0); + +// telnet defaults to port 23 +EthernetServer server(23); +boolean gotAMessage = false; // whether or not you got a message from the client yet + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + // this check is only needed on the Leonardo: + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // start the Ethernet connection: + Serial.println("Trying to get an IP address using DHCP"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // initialize the ethernet device not using DHCP: + Ethernet.begin(mac, ip, gateway, subnet); + } + // print your local IP address: + Serial.print("My IP address: "); + ip = Ethernet.localIP(); + 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.println(); + // start listening for clients + server.begin(); + +} + +void loop() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + if (!gotAMessage) { + Serial.println("We have a new client"); + client.println("Hello, client!"); + gotAMessage = true; + } + + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to the client: + server.write(thisChar); + // echo the bytes to the server as well: + Serial.print(thisChar); + } +} + diff --git a/hardware/pic32/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino b/hardware/pic32/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino new file mode 100644 index 000000000..dcf3e8aa9 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino @@ -0,0 +1,94 @@ +/* + 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 + to test this with. + 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 + 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 +#include + +// 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); + +// Enter the IP address of the server you're connecting to: +IPAddress server(1, 1, 1, 1); + +// Initialize the Ethernet client library +// 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; + +void setup() { + // start the Ethernet connection: + Ethernet.begin(mac, ip); + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // give the Ethernet shield a second to initialize: + delay(1000); + Serial.println("connecting..."); + + // 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"); + } +} + +void loop() +{ + // if there are incoming bytes available + // from the server, read them and print them: + if (client.available()) { + char c = client.read(); + Serial.print(c); + } + + // as long as there are bytes in the serial queue, + // read them and send them out the socket if it's open: + while (Serial.available() > 0) { + char inChar = Serial.read(); + if (client.connected()) { + client.print(inChar); + } + } + + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + // do nothing: + while (true); + } +} + + + + diff --git a/hardware/pic32/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino b/hardware/pic32/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino new file mode 100644 index 000000000..99de7650c --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino @@ -0,0 +1,119 @@ +/* + 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 + and received messages for testing with a computer. + + created 21 Aug 2010 + by Michael Margolis + + This code is in the public domain. + */ + + +#include // needed for Arduino versions later than 0018 +#include +#include // UDP library from: bjoern@cs.stanford.edu 12/30/2008 + + +// 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); + +unsigned int localPort = 8888; // local port to listen on + +// buffers for receiving and sending data +char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, +char ReplyBuffer[] = "acknowledged"; // a string to send back + +// An EthernetUDP instance to let us send and receive packets over UDP +EthernetUDP Udp; + +void setup() { + // start the Ethernet and UDP: + Ethernet.begin(mac, ip); + Udp.begin(localPort); + + Serial.begin(9600); +} + +void loop() { + // if there's data available, read a packet + int packetSize = Udp.parsePacket(); + 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++) + { + Serial.print(remote[i], DEC); + if (i < 3) + { + Serial.print("."); + } + } + Serial.print(", port "); + Serial.println(Udp.remotePort()); + + // read the packet into packetBufffer + Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); + Serial.println("Contents:"); + Serial.println(packetBuffer); + + // send a reply, to the IP address and port that sent us the packet we received + Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); + Udp.write(ReplyBuffer); + Udp.endPacket(); + } + delay(10); +} + + +/* + Processing sketch to run with this example + ===================================================== + + // 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 + } + + 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(); + } + */ + + diff --git a/hardware/pic32/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino b/hardware/pic32/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino new file mode 100644 index 000000000..25c71c402 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino @@ -0,0 +1,142 @@ +/* + + 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, + see http://en.wikipedia.org/wiki/Network_Time_Protocol + + created 4 Sep 2010 + by Michael Margolis + modified 9 Apr 2012 + by Tom Igoe + + This code is in the public domain. + + */ + +#include +#include +#include + +// 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 +}; + +unsigned int localPort = 8888; // local port to listen for UDP packets + +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 + +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() +{ + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // start Ethernet and UDP + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // no point in carrying on, so do nothing forevermore: + for (;;) + ; + } + Udp.begin(localPort); +} + +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() ) { + // We've received a packet, read the data from it + 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]); + // 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; + Serial.print("Seconds since Jan 1 1900 = " ); + 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; + // subtract seventy years: + unsigned long epoch = secsSince1900 - seventyYears; + // print Unix time: + 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(':'); + 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(':'); + 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 + } + // wait ten seconds before asking for the time again + delay(10000); +} + +// 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); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + 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: + Udp.beginPacket(address, 123); //NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} + + + + + + + + + + diff --git a/hardware/pic32/libraries/Ethernet/examples/WebClient/WebClient.ino b/hardware/pic32/libraries/Ethernet/examples/WebClient/WebClient.ino new file mode 100644 index 000000000..9afd40eae --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/WebClient/WebClient.ino @@ -0,0 +1,88 @@ +/* + Web client + + This sketch connects to a website (http://www.google.com) + 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 +#include + +// 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 }; +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) +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); + +// Initialize the Ethernet client library +// 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: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // start the Ethernet connection: + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // no point in carrying on, so do nothing forevermore: + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip); + } + // give the Ethernet shield a second to initialize: + delay(1000); + Serial.println("connecting..."); + + // if you get a connection, report back via serial: + if (client.connect(server, 80)) { + Serial.println("connected"); + // Make a HTTP request: + client.println("GET /search?q=arduino HTTP/1.1"); + 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"); + } +} + +void loop() +{ + // if there are incoming bytes available + // from the server, read them and print them: + if (client.available()) { + char c = client.read(); + Serial.print(c); + } + + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + + // do nothing forevermore: + while (true); + } +} + diff --git a/hardware/pic32/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino b/hardware/pic32/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino new file mode 100644 index 000000000..a0ae8b782 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino @@ -0,0 +1,108 @@ +/* + 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 +#include + +// assign a MAC address for the ethernet controller. +// fill in your address here: +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +// fill in an available IP address on your network here, +// for manual configuration: +IPAddress ip(192, 168, 1, 177); + +// fill in your Domain Name Server address here: +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 +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: + Ethernet.begin(mac, ip, myDns); + // print the Ethernet board/shield's IP address: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); +} + +void loop() { + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) { + char c = client.read(); + Serial.write(c); + } + + // if ten seconds have passed since your last connection, + // then connect again and send data: + if (millis() - lastConnectionTime > postingInterval) { + httpRequest(); + } + +} + +// 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..."); + // send the HTTP PUT request: + client.println("GET /latest.txt HTTP/1.1"); + client.println("Host: www.arduino.cc"); + client.println("User-Agent: arduino-ethernet"); + client.println("Connection: close"); + client.println(); + + // note the time that the connection was made: + lastConnectionTime = millis(); + } + else { + // if you couldn't make a connection: + Serial.println("connection failed"); + } +} + + diff --git a/hardware/pic32/libraries/Ethernet/examples/WebGraph/WebGraph.ino b/hardware/pic32/libraries/Ethernet/examples/WebGraph/WebGraph.ino new file mode 100644 index 000000000..71ec4f3e1 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/WebGraph/WebGraph.ino @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2015, Majenko Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * * Neither the name of Majenko Technologies nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* This small demo illustrates how you can build up graphics using + * SVG which is basically an XML file. The analog inputs 0-5 are + * periodically read and stored in an array of historical readings. + * A web request to the root page ("/") then includes images pointing + * to 6 SVG urls (/graph*.svg) which then produce live graphical + * representations of the stored historical data. + * + * The page should refresh automatically every 5 seconds. + */ + +// Ethernet requires SPI to be included as well. +#include +#include + +// This is the MAC address you want to give the Ethernet shield. +// It should be unique within your network. +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; + +// Give the shield an IP address. It should be unique within the subnet. +IPAddress ip(192, 168, 1, 177); + +// We want a web server to run on port 80. +EthernetServer server(80); + +// This is where we will store our ADC data. +int data[6][200]; + +void setup() { + // Start the Ethernet subsystem up + Ethernet.begin(mac, ip); + // And kick off the server listening for requests. + server.begin(); +} + +// This is a small class that will read the header of a web request +// and store the important information (target host name and page requested). + +class WebRequest { +private: + char *_host; + char *_page; + Client *_client; + char _buffer[100]; + uint8_t _bufptr; +public: + WebRequest(Client &c) : _host(NULL), _page(NULL), _client(&c), _bufptr(0) {} + ~WebRequest() { + if (_host != NULL) { free(_host); } + + if (_page != NULL) { free(_page); } + } + bool process() { + bool _finished = false; + + if (_client->available()) { + int c = _client->read(); + + switch (c) { + case '\r': + break; + + case '\n': + if (strncasecmp("Host: ", _buffer, 6) == 0) { + _host = strdup(_buffer + 6); + } else if (strncasecmp("GET ", _buffer, 4) == 0) { + char *end = strstr(_buffer + 4, " HTTP/"); + + if (end != NULL) { *end = 0; } + + _page = strdup(_buffer + 4); + } else if (strlen(_buffer) == 0) { + _finished = true; + } + + _bufptr = 0; + _buffer[0] = 0; + break; + + default: + if (_bufptr < 99) { + _buffer[_bufptr++] = c; + _buffer[_bufptr] = 0; + } + + break; + } + } + + return _finished; + } + char *getPage() { + return _page; + } + char *getHost() { + return _host; + } +}; + +// This is the heart of the graphics portion. Generate the XML to +// represent the graph data as SVG. +void sendGraph(Client &client, int graphno) { + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: image/svg+xml"); + client.println("Connection: close"); + client.println(); + client.println(""); + client.println(""); + for (int i = 1; i < 200; i++) { + client.print("> 3)); + client.print("\" x2=\""); + client.print(i); + client.print("\" y2=\""); + client.print(127 - (data[graphno][i] >> 3)); + client.println("\" stroke-width=\"1\" />"); + } + client.println(""); + client.println(""); +} + +// If you request a page that doesn't exist you should send back a 403 +void sendNotFound(Client &client) { + client.println("HTTP/1.1 403 NOT FOUND"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); + client.println(); + client.println("Not Found

Not Found

"); +} + +// Process the main index page - include the 6 graph images. +void sendIndex(Client &client) { + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); + client.println("Refresh: 5"); + client.println(); + client.println(""); + client.println(""); + client.println("Sensor Readings"); + client.println("
"); + + for (int i = 0; i < 6; i++) { + client.print(""); + } + + client.println(""); + client.print(""); + + for (int analogChannel = 0; analogChannel < 6; analogChannel++) { + client.print(""); + } + + client.println(""); + client.println("
"); + client.print(i); + client.print("
"); + client.println("
"); +} + +// Our main loop. Read the ADC every 100ms and process any incoming requests. +void loop() { + + // A 100ms ticker. Every 100ms shift the 6 array blocks down one + // entry and read in a new value at the top of the array. + static uint32_t tick = 0; + if (millis() - tick >= 100) { + tick = millis(); + for (int chan = 0; chan < 6; chan++) { + for (int i = 0; i < 199; i++) { + data[chan][i] = data[chan][i+1]; + data[chan][199] = analogRead(chan); + } + } + } + + + // Check to see if there are any pending connections + EthernetClient client = server.available(); + + if (client) { + + // Process the incoming request + WebRequest req(client); + while (client.connected() && !req.process()); + + // Now look to see which page was requested and call the + // right function accordingly. + if (!strcmp(req.getPage(), "/")) { + sendIndex(client); + } else if (!strcmp(req.getPage(), "/index.html")) { + sendIndex(client); + } else if (!strcmp(req.getPage(), "/graph0.svg")) { + sendGraph(client, 0); + } else if (!strcmp(req.getPage(), "/graph1.svg")) { + sendGraph(client, 1); + } else if (!strcmp(req.getPage(), "/graph2.svg")) { + sendGraph(client, 2); + } else if (!strcmp(req.getPage(), "/graph3.svg")) { + sendGraph(client, 3); + } else if (!strcmp(req.getPage(), "/graph4.svg")) { + sendGraph(client, 4); + } else if (!strcmp(req.getPage(), "/graph5.svg")) { + sendGraph(client, 5); + } else { + sendNotFound(client); + } + + // We're done with this connection, so close it down. + client.stop(); + } +} diff --git a/hardware/pic32/libraries/Ethernet/examples/WebServer/WebServer.ino b/hardware/pic32/libraries/Ethernet/examples/WebServer/WebServer.ino new file mode 100644 index 000000000..d0c585d07 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/WebServer/WebServer.ino @@ -0,0 +1,101 @@ +/* + Web Server + + A simple web server that shows the value of the analog input pins. + 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 +#include + +// 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); + +// Initialize the Ethernet server library +// 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: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // start the Ethernet connection and the server: + Ethernet.begin(mac, ip); + server.begin(); + Serial.print("server is at "); + Serial.println(Ethernet.localIP()); +} + + +void loop() { + // listen for incoming clients + EthernetClient client = server.available(); + if (client) { + Serial.println("new client"); + // an http request ends with a blank line + boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + Serial.write(c); + // if you've gotten to the end of the line (received a newline + // character) and the line is blank, the http request has ended, + // so you can send a reply + if (c == '\n' && currentLineIsBlank) { + // send a standard http response header + 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(); + client.println(""); + client.println(""); + // output the value of each analog input pin + for (int analogChannel = 0; analogChannel < 6; analogChannel++) { + int sensorReading = analogRead(analogChannel); + client.print("analog input "); + client.print(analogChannel); + client.print(" is "); + client.print(sensorReading); + client.println("
"); + } + client.println(""); + 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; + } + } + } + // give the web browser time to receive the data + delay(1); + // close the connection: + client.stop(); + Serial.println("client disconnected"); + } +} + diff --git a/hardware/pic32/libraries/Ethernet/examples/XivelyClient/XivelyClient.ino b/hardware/pic32/libraries/Ethernet/examples/XivelyClient/XivelyClient.ino new file mode 100644 index 000000000..23ae72fec --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/XivelyClient/XivelyClient.ino @@ -0,0 +1,163 @@ +/* + Xively sensor client + + This sketch connects an analog sensor to Xively (http://www.xively.com) + using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or + the Adafruit Ethernet shield, either one will work, as long as it's got + a Wiznet Ethernet module on board. + + This example has been updated to use version 2.0 of the Xively.com API. + To make it work, create a feed with a datastream, and give it the ID + sensor1. Or change the code below to match your feed. + + + Circuit: + * Analog sensor attached to analog in 0 + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 15 March 2010 + modified 9 Apr 2012 + by Tom Igoe with input from Usman Haque and Joe Saavedra + +http://arduino.cc/en/Tutorial/XivelyClient + This code is in the public domain. + + */ + +#include +#include + +#define APIKEY "YOUR API KEY GOES HERE" // replace your xively api key here +#define FEEDID 00000 // replace your feed ID +#define USERAGENT "My Project" // user agent is the project name + +// assign a MAC address for the ethernet controller. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +// fill in your address here: +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; + +// fill in an available IP address on your network here, +// for manual configuration: +IPAddress ip(10,0,1,20); +// initialize the library instance: +EthernetClient client; + +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +IPAddress server(216,52,233,122); // numeric IP for api.xively.com +//char server[] = "api.xively.com"; // name address for xively API + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +boolean lastConnected = false; // state of the connection last time through the main loop +const unsigned long postingInterval = 10*1000; //delay between updates to Xively.com + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // start the Ethernet connection: + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // DHCP failed, so use a fixed IP address: + Ethernet.begin(mac, ip); + } +} + +void loop() { + // read the analog sensor: + int sensorReading = analogRead(A0); + + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) { + char c = client.read(); + Serial.print(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)) { + sendData(sensorReading); + } + // 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 sendData(int thisData) { + // if there's a successful connection: + if (client.connect(server, 80)) { + Serial.println("connecting..."); + // send the HTTP PUT request: + client.print("PUT /v2/feeds/"); + client.print(FEEDID); + client.println(".csv HTTP/1.1"); + client.println("Host: api.xively.com"); + client.print("X-XivelyApiKey: "); + client.println(APIKEY); + client.print("User-Agent: "); + client.println(USERAGENT); + client.print("Content-Length: "); + + // calculate the length of the sensor reading in bytes: + // 8 bytes for "sensor1," + number of digits of the data: + int thisLength = 8 + getLength(thisData); + client.println(thisLength); + + // last pieces of the HTTP PUT request: + client.println("Content-Type: text/csv"); + client.println("Connection: close"); + client.println(); + + // here's the actual content of the PUT request: + client.print("sensor1,"); + client.println(thisData); + + } + else { + // if you couldn't make a connection: + Serial.println("connection failed"); + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + } + // note the time that the connection was made or attempted: + lastConnectionTime = millis(); +} + + +// This method calculates the number of digits in the +// sensor reading. Since each digit of the ASCII decimal +// representation is a byte, the number of digits equals +// the number of bytes: + +int getLength(int someValue) { + // there's at least one byte: + int digits = 1; + // continually divide the value by ten, + // adding one to the digit count for each + // time you divide, until you're at 0: + int dividend = someValue /10; + while (dividend > 0) { + dividend = dividend /10; + digits++; + } + // return the number of digits: + return digits; +} + diff --git a/hardware/pic32/libraries/Ethernet/examples/XivelyClientString/XivelyClientString.ino b/hardware/pic32/libraries/Ethernet/examples/XivelyClientString/XivelyClientString.ino new file mode 100644 index 000000000..4df79b706 --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/examples/XivelyClientString/XivelyClientString.ino @@ -0,0 +1,154 @@ +/* + Xively sensor client with Strings + + This sketch connects an analog sensor to Xively (http://www.xively.com) + using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or + the Adafruit Ethernet shield, either one will work, as long as it's got + a Wiznet Ethernet module on board. + + This example has been updated to use version 2.0 of the xively.com API. + To make it work, create a feed with two datastreams, and give them the IDs + sensor1 and sensor2. Or change the code below to match your feed. + + This example uses the String library, which is part of the Arduino core from + version 0019. + + Circuit: + * Analog sensor attached to analog in 0 + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 15 March 2010 + modified 9 Apr 2012 + by Tom Igoe with input from Usman Haque and Joe Saavedra + modified 8 September 2012 + by Scott Fitzgerald + + http://arduino.cc/en/Tutorial/XivelyClientString + This code is in the public domain. + + */ + +#include +#include + + +#define APIKEY "YOUR API KEY GOES HERE" // replace your Xively api key here +#define FEEDID 00000 // replace your feed ID +#define USERAGENT "My Project" // user agent is the project name + + +// assign a MAC address for the ethernet controller. +// fill in your address here: + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; + +// fill in an available IP address on your network here, +// for manual configuration: +IPAddress ip(10,0,1,20); + +// initialize the library instance: +EthernetClient client; + +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +IPAddress server(216,52,233,121); // numeric IP for api.xively.com +//char server[] = "api.xively.com"; // name address for xively API + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +boolean lastConnected = false; // state of the connection last time through the main loop +const unsigned long postingInterval = 10*1000; //delay between updates to xively.com + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + + // give the ethernet module time to boot up: + delay(1000); + // start the Ethernet connection: + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // DHCP failed, so use a fixed IP address: + Ethernet.begin(mac, ip); + } +} + +void loop() { + // read the analog sensor: + int sensorReading = analogRead(A0); + // convert the data to a String to send it: + + String dataString = "sensor1,"; + dataString += sensorReading; + + // you can append multiple readings to this String if your + // xively feed is set up to handle multiple values: + int otherSensorReading = analogRead(A1); + dataString += "\nsensor2,"; + dataString += otherSensorReading; + + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) { + char c = client.read(); + Serial.print(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)) { + sendData(dataString); + } + // 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 sendData(String thisData) { + // if there's a successful connection: + if (client.connect(server, 80)) { + Serial.println("connecting..."); + // send the HTTP PUT request: + client.print("PUT /v2/feeds/"); + client.print(FEEDID); + client.println(".csv HTTP/1.1"); + client.println("Host: api.xively.com"); + client.print("X-xivelyApiKey: "); + client.println(APIKEY); + client.print("User-Agent: "); + client.println(USERAGENT); + client.print("Content-Length: "); + client.println(thisData.length()); + + // last pieces of the HTTP PUT request: + client.println("Content-Type: text/csv"); + client.println("Connection: close"); + client.println(); + + // here's the actual content of the PUT request: + client.println(thisData); + } + else { + // if you couldn't make a connection: + Serial.println("connection failed"); + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + } + // note the time that the connection was made or attempted: + lastConnectionTime = millis(); +} + diff --git a/hardware/pic32/libraries/Ethernet/utility/util.h b/hardware/pic32/libraries/Ethernet/utility/util.h new file mode 100644 index 000000000..33d32a97e --- /dev/null +++ b/hardware/pic32/libraries/Ethernet/utility/util.h @@ -0,0 +1,14 @@ +#ifndef UTIL_H +#define UTIL_H + +#define htons(x) ( ((x)<< 8 & 0xFF00) | \ + ((x)>> 8 & 0x00FF) ) +#define ntohs(x) htons(x) + +#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ + ((x)<< 8 & 0x00FF0000UL) | \ + ((x)>> 8 & 0x0000FF00UL) | \ + ((x)>>24 & 0x000000FFUL) ) +#define ntohl(x) htonl(x) + +#endif diff --git a/hardware/pic32/libraries/HTTPServer/examples/deWebServer/deWebServer.ino b/hardware/pic32/libraries/HTTPServer/examples/deWebServer/deWebServer.ino new file mode 100644 index 000000000..3437d7f8b --- /dev/null +++ b/hardware/pic32/libraries/HTTPServer/examples/deWebServer/deWebServer.ino @@ -0,0 +1,264 @@ +/************************************************************************/ +/* */ +/* WebServer */ +/* */ +/* A Example chipKIT HTTP Server implementation */ +/* This sketch is designed to work with web browser clients */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 6/15/2014(KeithV): Created */ +/************************************************************************/ +/************************************************************************/ +/* */ +/* This HTTP Server Example contains sample content in the content */ +/* subdirectory under the sketch directory. The files in the content */ +/* directory should be copied to the root of your SD card. However, */ +/* you can view the content by opening HomePage.htm page */ +/* with your browser right out of the content subdirectory before */ +/* loading it on the SD card. The sample pages contain */ +/* instructions on how to set up this example and therefore may be */ +/* valuable to read before proceeding. */ +/* */ +/************************************************************************/ + +//************************************************************************ +//************************************************************************ +//************************** READ THIS ********************************* +//************************************************************************ +//*********** !! COPY THIS SKETCH TO YOUR SKETCH DIRECTORY !! *********** +//************************************************************************ +//************************************************************************ +//************** You will not be able to modify the network ************** +//************** parameters as long as this sketch is in a ************** +//************* library subdirectory. Even if you modify in ************** +//************* MPIDE it will not take effect when you build ************ +//************** and you will not be able to connect to ****************** +//************** your router, the connection will timeout **************** +//************************************************************************ +//************************************************************************ + +/************************************************************************/ +/* Supported hardware: */ +/* */ +/* uC32 with a WiFiShield */ +/* WF32 */ +/* WiFIRE */ +/* MX7cK with a pmodSD on JPF */ +/* */ +/* NOTE: you can NOT stack a NetworkShield and a WiFiShield on a Max32 */ +/************************************************************************/ + +//************************************************************************ +//************************************************************************ +//******** SET THESE LIBRARIES FOR YOUR HARDWARE CONFIGURATION ********** +//************************************************************************ +//************************************************************************ + +/************************************************************************/ +/* */ +/* Network Hardware libraries */ +/* INCLUDE ONLY ONE */ +/* */ +/************************************************************************/ +// You MUST select 1 and ONLY 1 of the following hardware libraries +// they are here so that MPIDE will put the lib path on the compiler include path. +#include // This is for the MRF24WGxx on a pmodWiFi or WiFiShield +//#include // This is for the the Internal MAC and SMSC 8720 PHY + +/************************************************************************/ +/* Network libraries */ +/************************************************************************/ +// The base network library +// this is a required library +// Do not comment out this library +#include + +// ----- COMMENT THIS OUT IF YOU ARE NOT USING WIFI ----- +#include + +//************************************************************************ +//************************************************************************ +//**************** END OF LIBRARY CONFIGURATION ************************** +//************************************************************************ +//************************************************************************ + +/************************************************************************/ +/* */ +/* YOU MUST..... */ +/* */ +/* You MUST put HTTPServerConfig.h in your sketch director */ +/* And you MUST configure it with your network parameters */ +/* */ +/* You also MUST load your content onto your SD card and */ +/* the file HomePage.htm MUST exist at the root of the SD */ +/* file structure. Of course you must insert your SD card */ +/* into the SD reader on the chipKIT board */ +/* */ +/* Go do this now.... */ +/* */ +/************************************************************************/ + +/************************************************************************/ +/* Other libraries; Required libraries */ +/************************************************************************/ +// You must have an SD card reader somewhere +// as the HTTP server uses the SD card to hold the HTML pages. +// this is a required library; we must specify this in the .pde for +// MPIDE to include it. +#include + +// and this is the HTTPServer library code. +// this is a required library +#include + +/************************************************************************/ +/* HTTP URL Matching Strings */ +/************************************************************************/ +// These are the HTTP URL match strings for the dynamically created +// HTML rendering functions. +// Make these static const so they get put in flash +static const char szHTMLRestart[] = "GET /Restart "; +static const char szHTMLTerminate[] = "GET /Terminate "; +static const char szHTMLReboot[] = "GET /Reboot "; +static const char szHTMLFavicon[] = "GET /favicon.ico "; +static const char szHTMLGetIO[] = "GET /IOPage.htm "; +static const char szHTMLPostLED[] = "POST /IOPage.htm "; + +// here is our sample/example dynamically created HTML page +GCMD::ACTION ComposeHTMLGetIO(CLIENTINFO * pClientInfo); +GCMD::ACTION ComposeHTMLPostLED(CLIENTINFO * pClientInfo); + +#define CHANGE_HEAP_SIZE(size) __asm__ volatile ("\t.globl _min_heap_size\n\t.equ _min_heap_size, " #size "\n") +CHANGE_HEAP_SIZE(0x200); + +/*** void setup(void) + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino Master Initialization routine + * + * + * ------------------------------------------------------------ */ +void setup(void) +{ + // Must do a Serial.begin because the HTTP Server + // has diagnostic prints in it. + Serial.begin(9600); + Serial.println("WebServer v4.0"); + Serial.println("Copyright 2014, Digilent Inc."); + Serial.println("Written by Keith Vogel"); + Serial.println(); + + // set up the IO pins + for(int i=0; i < HTTPCIO; i++) + { + pinMode(rgReplacePins[i], INPUT); + } + + // set up the LED pins + for(int i=0; i < HTTPCLED; i++) + { + pinMode(rgReplacePins[HTTPCIO + i], OUTPUT); + } + + // add rendering functions for dynamically created web pages + // max of 10 AddHTMLPage() allowed + + // these are the Select picture pages in Post.htm + AddHTMLPage(szHTMLGetIO, ComposeHTMLGetIO); + AddHTMLPage(szHTMLPostLED, ComposeHTMLPostLED); + + // comment this out if you do not want to support + // restarting the network stack from a browser + AddHTMLPage(szHTMLRestart, ComposeHTMLRestartPage); + + // comment this out if you do not want to support + // terminating the server from a browser + AddHTMLPage(szHTMLTerminate, ComposeHTMLTerminatePage); + + // comment this out if you do not want to support + // rebooting (effectively hitting MCLR) the server from a browser + AddHTMLPage(szHTMLReboot, ComposeHTMLRebootPage); + + // This example supports favorite ICONs, + // those are those icon's next to the URL in the address line + // on the browser once the page is displayed. + // To support those icons, have at the root of the SD file direcotory + // an ICON (.ico) file with your ICON in it. The file MUST be named + // favicon.ico. If you do not have an icon, then uncomment the following + // line so the server will tell the browser with an HTTP file not found + // error that we don't have a favoite ICON. + // AddHTMLPage(szHTMLFavicon, ComposeHTTP404Error); + + // Make reading files from the SD card the default compose function + SetDefaultHTMLPage(ComposeHTMLSDPage); + + // Initialize the SD card + SDSetup(); + + // Initialize the HTTP server + ServerSetup(); +} + +/*** void loop(void) + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino Master Loop routine + * + * + * ------------------------------------------------------------ */ +void loop(void) +{ + // process the HTTP Server + ProcessServer(); +} diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino b/hardware/pic32/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino new file mode 100755 index 000000000..27123ad4c --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/Autoscroll/Autoscroll.ino @@ -0,0 +1,73 @@ +/* + LiquidCrystal Library - Autoscroll + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch demonstrates the use of the autoscroll() + and noAutoscroll() functions to make new text scroll or not. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16,2); +} + +void loop() { + // set the cursor to (0,0): + lcd.setCursor(0, 0); + // print from 0 to 9: + for (int thisChar = 0; thisChar < 10; thisChar++) { + lcd.print(thisChar); + delay(500); + } + + // set the cursor to (16,1): + lcd.setCursor(16,1); + // set the display to automatically scroll: + lcd.autoscroll(); + // print from 0 to 9: + for (int thisChar = 0; thisChar < 10; thisChar++) { + lcd.print(thisChar); + delay(500); + } + // turn off automatic scrolling + lcd.noAutoscroll(); + + // clear screen for the next loop: + lcd.clear(); +} + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/Blink/Blink.ino b/hardware/pic32/libraries/LiquidCrystal/examples/Blink/Blink.ino new file mode 100755 index 000000000..72cbf037c --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/Blink/Blink.ino @@ -0,0 +1,63 @@ +/* + LiquidCrystal Library - Blink + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and makes the + cursor block blink. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + + */ + +#include "WProgram.h" + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // Turn off the blinking cursor: + lcd.noBlink(); + delay(3000); + // Turn on the blinking cursor: + lcd.blink(); + delay(3000); +} + + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/Cursor/Cursor.ino b/hardware/pic32/libraries/LiquidCrystal/examples/Cursor/Cursor.ino new file mode 100755 index 000000000..28e2a6a22 --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/Cursor/Cursor.ino @@ -0,0 +1,60 @@ +/* + LiquidCrystal Library - Cursor + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and + uses the cursor() and noCursor() methods to turn + on and off the cursor. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // Turn off the cursor: + lcd.noCursor(); + delay(500); + // Turn on the cursor: + lcd.cursor(); + delay(500); +} + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/Display/Display.ino b/hardware/pic32/libraries/LiquidCrystal/examples/Display/Display.ino new file mode 100755 index 000000000..b000731a4 --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/Display/Display.ino @@ -0,0 +1,60 @@ +/* + LiquidCrystal Library - display() and noDisplay() + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and uses the + display() and noDisplay() functions to turn on and off + the display. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // Turn off the display: + lcd.noDisplay(); + delay(500); + // Turn on the display: + lcd.display(); + delay(500); +} + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.ino b/hardware/pic32/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.ino new file mode 100755 index 000000000..e99957d9a --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/HelloWorld/HelloWorld.ino @@ -0,0 +1,58 @@ +/* + LiquidCrystal Library - Hello World + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD + and shows the time. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); +} + +void loop() { + // set the cursor to column 0, line 1 + // (note: line 1 is the second row, since counting begins with 0): + lcd.setCursor(0, 1); + // print the number of seconds since reset: + lcd.print(millis()/1000); +} + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/Scroll/Scroll.ino b/hardware/pic32/libraries/LiquidCrystal/examples/Scroll/Scroll.ino new file mode 100755 index 000000000..71e5e8cce --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/Scroll/Scroll.ino @@ -0,0 +1,85 @@ +/* + LiquidCrystal Library - scrollDisplayLeft() and scrollDisplayRight() + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints "Hello World!" to the LCD and uses the + scrollDisplayLeft() and scrollDisplayRight() methods to scroll + the text. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // Print a message to the LCD. + lcd.print("hello, world!"); + delay(1000); +} + +void loop() { + // scroll 13 positions (string length) to the left + // to move it offscreen left: + for (int positionCounter = 0; positionCounter < 13; positionCounter++) { + // scroll one position left: + lcd.scrollDisplayLeft(); + // wait a bit: + delay(150); + } + + // scroll 29 positions (string length + display length) to the right + // to move it offscreen right: + for (int positionCounter = 0; positionCounter < 29; positionCounter++) { + // scroll one position right: + lcd.scrollDisplayRight(); + // wait a bit: + delay(150); + } + + // scroll 16 positions (display length + string length) to the left + // to move it back to center: + for (int positionCounter = 0; positionCounter < 16; positionCounter++) { + // scroll one position left: + lcd.scrollDisplayLeft(); + // wait a bit: + delay(150); + } + + // delay at the end of the full loop: + delay(1000); + +} + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino b/hardware/pic32/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino new file mode 100755 index 000000000..9727cee03 --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/SerialDisplay/SerialDisplay.ino @@ -0,0 +1,65 @@ +/* + LiquidCrystal Library - Serial Input + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch displays text sent over the serial port + (e.g. from the Serial Monitor) on an attached LCD. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup(){ + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // initialize the serial communications: + Serial.begin(9600); +} + +void loop() +{ + // when characters arrive over the serial port... + if (Serial.available()) { + // wait a bit for the entire message to arrive + delay(100); + // clear the screen + lcd.clear(); + // read all the available characters + while (Serial.available() > 0) { + // display each character to the LCD + lcd.write(Serial.read()); + } + } +} diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino b/hardware/pic32/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino new file mode 100755 index 000000000..51bab1fb5 --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/TextDirection/TextDirection.ino @@ -0,0 +1,87 @@ + /* + LiquidCrystal Library - TextDirection + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch demonstrates how to use leftToRight() and rightToLeft() + to move the cursor. + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + + */ + +// include the library code: +#include + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +int thisChar = 'a'; + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(16, 2); + // turn on the cursor: + lcd.cursor(); + Serial.begin(9600); +} + +void loop() { + // reverse directions at 'm': + if (thisChar == 'm') { + // go right for the next letter + lcd.rightToLeft(); + } + // reverse again at 's': + if (thisChar == 's') { + // go left for the next letter + lcd.leftToRight(); + } + // reset at 'z': + if (thisChar > 'z') { + // go to (0,0): + lcd.home(); + // start again at 0 + thisChar = 'a'; + } + // print the character + lcd.write(thisChar); + // wait a second: + delay(1000); + // increment the letter: + thisChar++; +} + + + + + + + + diff --git a/hardware/pic32/libraries/LiquidCrystal/examples/setCursor/setCursor.ino b/hardware/pic32/libraries/LiquidCrystal/examples/setCursor/setCursor.ino new file mode 100755 index 000000000..3c4edf3c4 --- /dev/null +++ b/hardware/pic32/libraries/LiquidCrystal/examples/setCursor/setCursor.ino @@ -0,0 +1,71 @@ +/* + LiquidCrystal Library - setCursor + + Demonstrates the use a 16x2 LCD display. The LiquidCrystal + library works with all LCD displays that are compatible with the + Hitachi HD44780 driver. There are many of them out there, and you + can usually tell them by the 16-pin interface. + + This sketch prints to all the positions of the LCD using the + setCursor(0 method: + + The circuit: + * LCD RS pin to digital pin 12 + * LCD Enable pin to digital pin 11 + * LCD D4 pin to digital pin 5 + * LCD D5 pin to digital pin 4 + * LCD D6 pin to digital pin 3 + * LCD D7 pin to digital pin 2 + * LCD R/W pin to ground + * 10K resistor: + * ends to +5V and ground + * wiper to LCD VO pin (pin 3) + + Library originally added 18 Apr 2008 + by David A. Mellis + library modified 5 Jul 2009 + by Limor Fried (http://www.ladyada.net) + example added 9 Jul 2009 + by Tom Igoe + modified 22 Nov 2010 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/LiquidCrystal + */ + +// include the library code: +#include + +// these constants won't change. But you can change the size of +// your LCD using them: +const int numRows = 2; +const int numCols = 16; + +// initialize the library with the numbers of the interface pins +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + +void setup() { + // set up the LCD's number of columns and rows: + lcd.begin(numCols,numRows); +} + +void loop() { + // loop from ASCII 'a' to ASCII 'z': + for (int thisLetter = 'a'; thisLetter <= 'z'; thisLetter++) { + // loop over the columns: + for (int thisCol = 0; thisCol < numRows; thisCol++) { + // loop over the rows: + for (int thisRow = 0; thisRow < numCols; thisRow++) { + // set the cursor position: + lcd.setCursor(thisRow,thisCol); + // print the letter: + lcd.write(thisLetter); + delay(200); + } + } + } +} + + diff --git a/hardware/pic32/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.ino b/hardware/pic32/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.ino new file mode 100644 index 000000000..1d632cadc --- /dev/null +++ b/hardware/pic32/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.ino @@ -0,0 +1,109 @@ +#include + +// OneWire DS18S20, DS18B20, DS1822 Temperature Example +// +// http://www.pjrc.com/teensy/td_libs_OneWire.html +// +// The DallasTemperature library can do all this work for you! +// http://milesburton.com/Dallas_Temperature_Control_Library + +OneWire ds(10); // on pin 10 + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + byte i; + byte present = 0; + byte type_s; + byte data[12]; + byte addr[8]; + float celsius, fahrenheit; + + if ( !ds.search(addr)) { + Serial.println("No more addresses."); + Serial.println(); + ds.reset_search(); + delay(250); + return; + } + + Serial.print("ROM ="); + for( i = 0; i < 8; i++) { + Serial.write(' '); + Serial.print(addr[i], HEX); + } + + if (OneWire::crc8(addr, 7) != addr[7]) { + Serial.println("CRC is not valid!"); + return; + } + Serial.println(); + + // the first ROM byte indicates which chip + switch (addr[0]) { + case 0x10: + Serial.println(" Chip = DS18S20"); // or old DS1820 + type_s = 1; + break; + case 0x28: + Serial.println(" Chip = DS18B20"); + type_s = 0; + break; + case 0x22: + Serial.println(" Chip = DS1822"); + type_s = 0; + break; + default: + Serial.println("Device is not a DS18x20 family device."); + return; + } + + ds.reset(); + ds.select(addr); + ds.write(0x44,1); // start conversion, with parasite power on at the end + + delay(1000); // maybe 750ms is enough, maybe not + // we might do a ds.depower() here, but the reset will take care of it. + + present = ds.reset(); + ds.select(addr); + ds.write(0xBE); // Read Scratchpad + + Serial.print(" Data = "); + Serial.print(present,HEX); + Serial.print(" "); + for ( i = 0; i < 9; i++) { // we need 9 bytes + data[i] = ds.read(); + Serial.print(data[i], HEX); + Serial.print(" "); + } + Serial.print(" CRC="); + Serial.print(OneWire::crc8(data, 8), HEX); + Serial.println(); + + // convert the data to actual temperature + + unsigned int raw = (data[1] << 8) | data[0]; + if (type_s) { + raw = raw << 3; // 9 bit resolution default + if (data[7] == 0x10) { + // count remain gives full 12 bit resolution + raw = (raw & 0xFFF0) + 12 - data[6]; + } + } else { + byte cfg = (data[4] & 0x60); + if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms + else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms + else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms + // default is 12 bit resolution, 750 ms conversion time + } + celsius = (float)raw / 16.0; + fahrenheit = celsius * 1.8 + 32.0; + Serial.print(" Temperature = "); + Serial.print(celsius); + Serial.print(" Celsius, "); + Serial.print(fahrenheit); + Serial.println(" Fahrenheit"); +} diff --git a/hardware/pic32/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.ino b/hardware/pic32/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.ino new file mode 100644 index 000000000..d171f9ba0 --- /dev/null +++ b/hardware/pic32/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.ino @@ -0,0 +1,77 @@ +#include + +/* + * DS2408 8-Channel Addressable Switch + * + * Writte by Glenn Trewitt, glenn at trewitt dot org + * + * Some notes about the DS2408: + * - Unlike most input/output ports, the DS2408 doesn't have mode bits to + * set whether the pins are input or output. If you issue a read command, + * they're inputs. If you write to them, they're outputs. + * - For reading from a switch, you should use 10K pull-up resisters. + */ + +void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0) { + for (uint8_t i = 0; i < count; i++) { + Serial.print(addr[i]>>4, HEX); + Serial.print(addr[i]&0x0f, HEX); + } + if (newline) + Serial.println(); +} + +void ReadAndReport(OneWire* net, uint8_t* addr) { + Serial.print(" Reading DS2408 "); + PrintBytes(addr, 8); + Serial.println(); + + uint8_t buf[13]; // Put everything in the buffer so we can compute CRC easily. + buf[0] = 0xF0; // Read PIO Registers + buf[1] = 0x88; // LSB address + buf[2] = 0x00; // MSB address + net->write_bytes(buf, 3); + net->read_bytes(buf+3, 10); // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16 + net->reset(); + + if (!OneWire::check_crc16(buf, 11, &buf[11])) { + Serial.print("CRC failure in DS2408 at "); + PrintBytes(addr, 8, true); + return; + } + Serial.print(" DS2408 data = "); + // First 3 bytes contain command, register address. + Serial.println(buf[3], BIN); +} + +OneWire net(10); // on pin 10 + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + byte i; + byte present = 0; + byte addr[8]; + + if (!net.search(addr)) { + Serial.print("No more addresses.\n"); + net.reset_search(); + delay(1000); + return; + } + + if (OneWire::crc8(addr, 7) != addr[7]) { + Serial.print("CRC is not valid!\n"); + return; + } + + if (addr[0] != 0x29) { + PrintBytes(addr, 8); + Serial.print(" is not a DS2408.\n"); + return; + } + + ReadAndReport(&net, addr); +} diff --git a/hardware/pic32/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.ino b/hardware/pic32/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.ino new file mode 100644 index 000000000..a85b1c292 --- /dev/null +++ b/hardware/pic32/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.ino @@ -0,0 +1,90 @@ +/* +DS250x add-only programmable memory reader w/SKIP ROM. + + The DS250x is a 512/1024bit add-only PROM(you can add data but cannot change the old one) that's used mainly for device identification purposes + like serial number, mfgr data, unique identifiers, etc. It uses the Maxim 1-wire bus. + + This sketch will use the SKIP ROM function that skips the 1-Wire search phase since we only have one device connected in the bus on digital pin 6. + If more than one device is connected to the bus, it will fail. + Sketch will not verify if device connected is from the DS250x family since the skip rom function effectively skips the family-id byte readout. + thus it is possible to run this sketch with any Maxim OneWire device in which case the command CRC will most likely fail. + Sketch will only read the first page of memory(32bits) starting from the lower address(0000h), if more than 1 device is present, then use the sketch with search functions. + Remember to put a 4.7K pullup resistor between pin 6 and +Vcc + + To change the range or ammount of data to read, simply change the data array size, LSB/MSB addresses and for loop iterations + + This example code is in the public domain and is provided AS-IS. + + Built with Arduino 0022 and PJRC OneWire 2.0 library http://www.pjrc.com/teensy/td_libs_OneWire.html + + created by Guillermo Lovato + march/2011 + + */ + +#include +OneWire ds(6); // OneWire bus on digital pin 6 +void setup() { + Serial.begin (9600); +} + +void loop() { + byte i; // This is for the for loops + boolean present; // device present var + byte data[32]; // container for the data from device + byte leemem[3] = { // array with the commands to initiate a read, DS250x devices expect 3 bytes to start a read: command,LSB&MSB adresses + 0xF0 , 0x00 , 0x00 }; // 0xF0 is the Read Data command, followed by 00h 00h as starting address(the beginning, 0000h) + byte ccrc; // Variable to store the command CRC + byte ccrc_calc; + + present = ds.reset(); // OneWire bus reset, always needed to start operation on the bus, returns a 1/TRUE if there's a device present. + ds.skip(); // Skip ROM search + + if (present == TRUE){ // We only try to read the data if there's a device present + Serial.println("DS250x device present"); + ds.write(leemem[0],1); // Read data command, leave ghost power on + ds.write(leemem[1],1); // LSB starting address, leave ghost power on + ds.write(leemem[2],1); // MSB starting address, leave ghost power on + + ccrc = ds.read(); // DS250x generates a CRC for the command we sent, we assign a read slot and store it's value + ccrc_calc = OneWire::crc8(leemem, 3); // We calculate the CRC of the commands we sent using the library function and store it + + if ( ccrc_calc != ccrc) { // Then we compare it to the value the ds250x calculated, if it fails, we print debug messages and abort + Serial.println("Invalid command CRC!"); + Serial.print("Calculated CRC:"); + Serial.println(ccrc_calc,HEX); // HEX makes it easier to observe and compare + Serial.print("DS250x readback CRC:"); + Serial.println(ccrc,HEX); + return; // Since CRC failed, we abort the rest of the loop and start over + } + Serial.println("Data is: "); // For the printout of the data + for ( i = 0; i < 32; i++) { // Now it's time to read the PROM data itself, each page is 32 bytes so we need 32 read commands + data[i] = ds.read(); // we store each read byte to a different position in the data array + Serial.print(data[i]); // printout in ASCII + Serial.print(" "); // blank space + } + Serial.println(); + delay(5000); // Delay so we don't saturate the serial output + } + else { // Nothing is connected in the bus + Serial.println("Nothing connected"); + delay(3000); + } +} + + + + + + + + + + + + + + + + + diff --git a/hardware/pic32/libraries/SD/examples/CardInfo/CardInfo.ino b/hardware/pic32/libraries/SD/examples/CardInfo/CardInfo.ino new file mode 100755 index 000000000..76ee112af --- /dev/null +++ b/hardware/pic32/libraries/SD/examples/CardInfo/CardInfo.ino @@ -0,0 +1,123 @@ +/* + 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 + + + created 28 Mar 2011 + by Limor Fried + + - Cleaned up all SD examples included with MPIDE for consistency in defining CS pins + revised 24 May 2013 by Jacob Christ + */ + // include the SD library: +#include + +// set up variables using the SD utility library functions: +Sd2Card card; +SdVolume volume; +SdFile root; + +// change this to match your SD shield or module; +// Arduino Ethernet shield: pin 4 +// Adafruit SD shields and modules: pin 10 +// Sparkfun SD shield: pin 8 +// 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. + +// Default SD chip select for Uno and Mega type devices +const int chipSelect_SD_default = 10; // Change 10 to 53 for a Mega + +// chipSelect_SD can be changed if you do not use default CS pin +const int chipSelect_SD = chipSelect_SD_default; + +void setup() +{ + Serial.begin(9600); + Serial.print("\nInitializing SD card..."); + + // Make sure the default chip select pin is set to so that + // shields that have a device that use the default CS pin + // that are connected to the SPI bus do not hold drive bus + pinMode(chipSelect_SD_default, OUTPUT); + digitalWrite(chipSelect_SD_default, HIGH); + + pinMode(chipSelect_SD, OUTPUT); + digitalWrite(chipSelect_SD, HIGH); + + // we'll use the initialization code from the utility libraries + // since we're just testing if the card is working! + if (!card.init(SPI_HALF_SPEED, chipSelect_SD)) { + Serial.println("initialization failed. Things to check:"); + Serial.println("* is a card is inserted?"); + Serial.println("* Is your wiring correct?"); + 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."); + } + + // print the type of card + Serial.print("\nCard type: "); + switch(card.type()) { + case SD_CARD_TYPE_SD1: + Serial.println("SD1"); + break; + case SD_CARD_TYPE_SD2: + Serial.println("SD2"); + break; + case SD_CARD_TYPE_SDHC: + Serial.println("SDHC"); + break; + default: + Serial.println("Unknown"); + } + + // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32 + if (!volume.init(card)) { + Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"); + return; + } + + + // print the type and size of the first FAT-type volume + long volumesize; + 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 + Serial.print("Volume size (bytes): "); + Serial.println(volumesize); + Serial.print("Volume size (Kbytes): "); + volumesize /= 1024; + Serial.println(volumesize); + Serial.print("Volume size (Mbytes): "); + 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) { + +} diff --git a/hardware/pic32/libraries/SD/examples/Datalogger/Datalogger.ino b/hardware/pic32/libraries/SD/examples/Datalogger/Datalogger.ino new file mode 100755 index 000000000..60ba5cc93 --- /dev/null +++ b/hardware/pic32/libraries/SD/examples/Datalogger/Datalogger.ino @@ -0,0 +1,102 @@ +/* + SD card datalogger + + 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: + ** MOSI - pin 11 + ** MISO - pin 12 + ** CLK - pin 13 + ** CS - pin 4 + + created 24 Nov 2010 + updated 2 Dec 2010 + by Tom Igoe + + - Cleaned up all SD examples included with MPIDE for consistency in defining CS pins + revised 24 May 2013 by Jacob Christ + + This example code is in the public domain. + + */ + +#include + +// On the Ethernet Shield, CS is pin 4. Note that even if it's not +// used as the CS pin, the hardware CS pin (10 on most Arduino boards, +// 53 on the Mega) must be left as an output or the SD library +// functions will not work. + +// Default SD chip select for Uno and Mega type devices +const int chipSelect_SD_default = 10; // Change 10 to 53 for a Mega + +// chipSelect_SD can be changed if you do not use default CS pin +const int chipSelect_SD = chipSelect_SD_default; + +void setup() +{ + Serial.begin(9600); + Serial.print("Initializing SD card..."); + + // Make sure the default chip select pin is set to so that + // shields that have a device that use the default CS pin + // that are connected to the SPI bus do not hold drive bus + pinMode(chipSelect_SD_default, OUTPUT); + digitalWrite(chipSelect_SD_default, HIGH); + + pinMode(chipSelect_SD, OUTPUT); + digitalWrite(chipSelect_SD, HIGH); + + + // see if the card is present and can be initialized: + if (!SD.begin(chipSelect_SD)) { + Serial.println("Card failed, or not present"); + // don't do anything more: + return; + } + Serial.println("card initialized."); +} + +void loop() +{ + // make a string for assembling the data to log: + String dataString = ""; + + // read three sensors and append to the string: + for (int analogPin = 0; analogPin < 3; analogPin++) { + int sensor = analogRead(analogPin); + dataString += String(sensor); + if (analogPin < 2) { + dataString += ","; + } + } + + // 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", FILE_WRITE); + + // if the file is available, write to it: + if (dataFile) { + dataFile.println(dataString); + 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"); + } +} + + + + + + + + + + diff --git a/hardware/pic32/libraries/SD/examples/DumpFile/DumpFile.ino b/hardware/pic32/libraries/SD/examples/DumpFile/DumpFile.ino new file mode 100755 index 000000000..c8bfb3723 --- /dev/null +++ b/hardware/pic32/libraries/SD/examples/DumpFile/DumpFile.ino @@ -0,0 +1,78 @@ +/* + 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 + + - Cleaned up all SD examples included with MPIDE for consistency in defining CS pins + revised 24 May 2013 by Jacob Christ + + This example code is in the public domain. + + */ + +#include + +// On the Ethernet Shield, CS is pin 4. Note that even if it's not +// used as the CS pin, the hardware CS pin (10 on most Arduino boards, +// 53 on the Mega) must be left as an output or the SD library +// functions will not work. + +// Default SD chip select for Uno and Mega type devices +const int chipSelect_SD_default = 10; // Change 10 to 53 for a Mega + +// chipSelect_SD can be changed if you do not use default CS pin +const int chipSelect_SD = chipSelect_SD_default; + +void setup() +{ + Serial.begin(9600); + Serial.print("Initializing SD card..."); + + // Make sure the default chip select pin is set to so that + // shields that have a device that use the default CS pin + // that are connected to the SPI bus do not hold drive bus + pinMode(chipSelect_SD_default, OUTPUT); + digitalWrite(chipSelect_SD_default, HIGH); + + pinMode(chipSelect_SD, OUTPUT); + digitalWrite(chipSelect_SD, HIGH); + + // see if the card is present and can be initialized: + if (!SD.begin(chipSelect_SD)) { + Serial.println("Card failed, or not present"); + // don't do anything more: + 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"); + + // if the file is available, write to it: + if (dataFile) { + while (dataFile.available()) { + 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() +{ +} + diff --git a/hardware/pic32/libraries/SD/examples/Files/Files.ino b/hardware/pic32/libraries/SD/examples/Files/Files.ino new file mode 100755 index 000000000..e4d93a949 --- /dev/null +++ b/hardware/pic32/libraries/SD/examples/Files/Files.ino @@ -0,0 +1,96 @@ +/* + SD card basic file example + + 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 + updated 2 Dec 2010 + by Tom Igoe + + - Cleaned up all SD examples included with MPIDE for consistency in defining CS pins + revised 24 May 2013 by Jacob Christ + + This example code is in the public domain. + + */ +#include + +File myFile; + +// 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. + +// Default SD chip select for Uno and Mega type devices +const int chipSelect_SD_default = 10; // Change 10 to 53 for a Mega + +// chipSelect_SD can be changed if you do not use default CS pin +const int chipSelect_SD = chipSelect_SD_default; + +void setup() +{ + Serial.begin(9600); + Serial.print("Initializing SD card..."); + + // Make sure the default chip select pin is set to so that + // shields that have a device that use the default CS pin + // that are connected to the SPI bus do not hold drive bus + pinMode(chipSelect_SD_default, OUTPUT); + digitalWrite(chipSelect_SD_default, HIGH); + + pinMode(chipSelect_SD, OUTPUT); + digitalWrite(chipSelect_SD, HIGH); + + if (!SD.begin(chipSelect_SD)) { + Serial.println("initialization failed!"); + return; + } + Serial.println("initialization done."); + + if (SD.exists("example.txt")) { + Serial.println("example.txt exists."); + } + else { + Serial.println("example.txt doesn't exist."); + } + + // open a new file and immediately close it: + Serial.println("Creating example.txt..."); + myFile = SD.open("example.txt", FILE_WRITE); + myFile.close(); + + // 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."); + } + + // delete the file: + Serial.println("Removing example.txt..."); + SD.remove("example.txt"); + + if (SD.exists("example.txt")){ + Serial.println("example.txt exists."); + } + else { + Serial.println("example.txt doesn't exist."); + } +} + +void loop() +{ + // nothing happens after setup finishes. +} + + + diff --git a/hardware/pic32/libraries/SD/examples/ReadWrite/ReadWrite.ino b/hardware/pic32/libraries/SD/examples/ReadWrite/ReadWrite.ino new file mode 100755 index 000000000..27c810221 --- /dev/null +++ b/hardware/pic32/libraries/SD/examples/ReadWrite/ReadWrite.ino @@ -0,0 +1,97 @@ +/* + SD card read/write + + 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 + updated 2 Dec 2010 + by Tom Igoe + + - Cleaned up all SD examples included with MPIDE for consistency in defining CS pins + revised 24 May 2013 by Jacob Christ + + This example code is in the public domain. + + */ + +#include + +File myFile; + +// 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. + +// Default SD chip select for Uno and Mega type devices +const int chipSelect_SD_default = 10; // Change 10 to 53 for a Mega + +// chipSelect_SD can be changed if you do not use default CS pin +const int chipSelect_SD = chipSelect_SD_default; + +void setup() +{ + Serial.begin(9600); + Serial.print("Initializing SD card..."); + + // Make sure the default chip select pin is set to so that + // shields that have a device that use the default CS pin + // that are connected to the SPI bus do not hold drive bus + pinMode(chipSelect_SD_default, OUTPUT); + digitalWrite(chipSelect_SD_default, HIGH); + + pinMode(chipSelect_SD, OUTPUT); + digitalWrite(chipSelect_SD, HIGH); + + if (!SD.begin(chipSelect_SD)) { + 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: + 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()); + } + // close the file: + myFile.close(); + } else { + // if the file didn't open, print an error: + Serial.println("error opening test.txt"); + } +} + +void loop() +{ + // nothing happens after setup +} + + diff --git a/hardware/pic32/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino b/hardware/pic32/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino new file mode 100644 index 000000000..8104fcbc2 --- /dev/null +++ b/hardware/pic32/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino @@ -0,0 +1,143 @@ +/* + 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 + CSB: pin 7 + MOSI: pin 11 + MISO: pin 12 + SCK: pin 13 + + created 31 July 2010 + modified 14 August 2010 + by Tom Igoe + */ + +// the sensor communicates using SPI, so include the library: +#include + +//Sensor's memory register addresses: +const int PRESSURE = 0x1F; //3 most significant bits of pressure +const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure +const int TEMPERATURE = 0x21; //16 bit temperature reading +const byte READ = 0b11111100; // SCP1000's read command +const byte WRITE = 0b00000010; // SCP1000's write command + +// pins used for the connection with the sensor +// the other you need are controlled by the SPI library): +const int dataReadyPin = 6; +const int chipSelectPin = 7; + +void setup() { + Serial.begin(9600); + + // start the SPI library: + SPI.begin(); + + // initalize the data ready and chip select pins: + pinMode(dataReadyPin, INPUT); + pinMode(chipSelectPin, OUTPUT); + + //Configure SCP1000 for low noise configuration: + writeRegister(0x02, 0x2D); + writeRegister(0x01, 0x03); + writeRegister(0x03, 0x02); + // give the sensor time to set up: + delay(100); +} + +void loop() { + //Select High Resolution Mode + writeRegister(0x03, 0x0A); + + // don't do anything until the data ready pin is high: + if (digitalRead(dataReadyPin) == HIGH) { + //Read the temperature data + int tempData = readRegister(0x21, 2); + + // convert the temperature to celsius and display it: + float realTemp = (float)tempData / 20.0; + Serial.print("Temp[C]="); + Serial.print(realTemp); + + + //Read the pressure data highest 3 bits: + byte pressure_data_high = readRegister(0x1F, 1); + pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 + + //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; + + // display the temperature: + Serial.println("\tPressure [Pa]=" + String(pressure)); + } +} + +//Read from or write to register from the SCP1000: +unsigned int readRegister(byte thisRegister, int bytesToRead ) { + byte inByte = 0; // incoming byte from the SPI + unsigned int result = 0; // result to return + Serial.print(thisRegister, BIN); + Serial.print("\t"); + // SCP1000 expects the register name in the upper 6 bits + // of the byte. So shift the bits left by two bits: + thisRegister = thisRegister << 2; + // now combine the address and the command into one byte + byte dataToSend = thisRegister & READ; + Serial.println(thisRegister, BIN); + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(dataToSend); + // send a value of 0 to read the first byte returned: + result = SPI.transfer(0x00); + // decrement the number of bytes left to read: + bytesToRead--; + // if you still have another byte to read: + if (bytesToRead > 0) { + // shift the first byte left, then get the second byte: + result = result << 8; + inByte = SPI.transfer(0x00); + // combine the byte you just got with the previous one: + result = result | inByte; + // decrement the number of bytes left to read: + bytesToRead--; + } + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + // return the result: + return(result); +} + + +//Sends a write command to SCP1000 + +void writeRegister(byte thisRegister, byte thisValue) { + + // SCP1000 expects the register address in the upper 6 bits + // of the byte. So shift the bits left by two bits: + thisRegister = thisRegister << 2; + // now combine the register address and the command into one byte: + byte dataToSend = thisRegister | WRITE; + + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + + SPI.transfer(dataToSend); //Send register location + SPI.transfer(thisValue); //Send value to record into register + + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); +} + diff --git a/hardware/pic32/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino b/hardware/pic32/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino new file mode 100644 index 000000000..b135a74f4 --- /dev/null +++ b/hardware/pic32/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino @@ -0,0 +1,71 @@ +/* + 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, + one with the channel number (0 - 5) and one with the resistance value for the + channel (0 - 255). + + The circuit: + * All A pins of AD5206 connected to +5V + * All B pins of AD5206 connected to ground + * An LED and a 220-ohm resisor in series connected from each W pin to ground + * 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 + by Tom Igoe + + Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 + +*/ + + +// inslude the SPI library: +#include + + +// set pin 10 as the slave select for the digital pot: +const int slaveSelectPin = 10; + +void setup() { + // set the slaveSelectPin as an output: + pinMode (slaveSelectPin, OUTPUT); + // initialize SPI: + SPI.begin(); +} + +void loop() { + // go through the six channels of the digital pot: + 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); + delay(10); + } + // wait a second at the top: + delay(100); + // change the resistance on this channel from max to min: + for (int level = 0; level < 255; level++) { + digitalPotWrite(channel, 255 - level); + delay(10); + } + } + +} + +void digitalPotWrite(int address, int value) { + // take the SS pin low to select the chip: + 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); +} diff --git a/hardware/pic32/libraries/Servo/examples/Knob/Knob.ino b/hardware/pic32/libraries/Servo/examples/Knob/Knob.ino new file mode 100755 index 000000000..b6eb7cc43 --- /dev/null +++ b/hardware/pic32/libraries/Servo/examples/Knob/Knob.ino @@ -0,0 +1,26 @@ +// Controlling a servo position using a potentiometer (variable resistor) +// by Michal Rinott + +// NOTE: UART will be disabled when servo is attached to pin 0 or 1. + + +#include + + +Servo myservo; // create servo object to control a servo + +int potpin = 0; // analog pin used to connect the potentiometer +int val; // variable to read the value from the analog pin + +void setup() +{ + myservo.attach(9); // attaches the servo on pin 9 to the servo object +} + +void loop() +{ + val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) + val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180) + myservo.write(val); // sets the servo position according to the scaled value + delay(15); // waits for the servo to get there +} diff --git a/hardware/pic32/libraries/Servo/examples/Sweep/Sweep.ino b/hardware/pic32/libraries/Servo/examples/Sweep/Sweep.ino new file mode 100755 index 000000000..d5ef889f1 --- /dev/null +++ b/hardware/pic32/libraries/Servo/examples/Sweep/Sweep.ino @@ -0,0 +1,33 @@ +// Sweep +// by BARRAGAN +// This example code is in the public domain. + +// NOTE: UART will be disabled when servo is attached to pin 0 or 1. + + +#include + +Servo myservo; // create servo object to control a servo + // a maximum of eight servo objects can be created + +int pos = 0; // variable to store the servo position + +void setup() +{ + myservo.attach(9); // attaches the servo on pin 9 to the servo object +} + + +void loop() +{ + for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees + { // in steps of 1 degree + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } + for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees + { + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } +} diff --git a/hardware/pic32/libraries/SoftPWMServo/examples/AllPinsPWM/AllPinsPWM.ino b/hardware/pic32/libraries/SoftPWMServo/examples/AllPinsPWM/AllPinsPWM.ino new file mode 100755 index 000000000..4376b5b62 --- /dev/null +++ b/hardware/pic32/libraries/SoftPWMServo/examples/AllPinsPWM/AllPinsPWM.ino @@ -0,0 +1,47 @@ +/* + ChipKIT MAX32 PWM test - all pins simultainously PWMing + + This sketch fades LEDs up and down on digital pins 0 through 85, all at the same time. + (note, some of these pins are not actually available on the MAX32 board) + This program was written to demonstrate the power of the PIC32 and its ability + to do software PWM on all of its pins. + + The circuit: + * LEDs attached from pins 0 through 85 to ground. + + Written 8/14/22 by Brian Schmalz http://www.schmalzhaus.com + This example code is in the public domain. + Based on AnalogWriteMega example code +*/ + +#include + +// These constants won't change. They're used to give names +// to the pins used: +const int lowestPin = 0; +// Use highestPin = 85 for the Max32 board, and highestPin = 41 for the Uno32 +const int highestPin = 41; + + +void setup() { + // The SoftPWMServo library sets any used pins to be outputs, so that's not needed here +} + +void loop() { + // fade the LED on thisPin from off to brightest: + for (int brightness = 0; brightness < 255; brightness++) { + // iterate over the pins: + for (int thisPin =lowestPin; thisPin <= highestPin; thisPin++) { + SoftPWMServoPWMWrite(thisPin, brightness); + } + delay(10); + } + // fade the LED on thisPin from brithstest to off: + for (int brightness = 255; brightness >= 0; brightness--) { + // iterate over the pins: + for (int thisPin =lowestPin; thisPin <= highestPin; thisPin++) { + SoftPWMServoPWMWrite(thisPin, brightness); + } + delay(10); + } +} diff --git a/hardware/pic32/libraries/SoftPWMServo/examples/AllPinsServo/AllPinsServo.ino b/hardware/pic32/libraries/SoftPWMServo/examples/AllPinsServo/AllPinsServo.ino new file mode 100755 index 000000000..65e6c441a --- /dev/null +++ b/hardware/pic32/libraries/SoftPWMServo/examples/AllPinsServo/AllPinsServo.ino @@ -0,0 +1,44 @@ +/* + ChipKIT MAX32 Servo test - all pins simultainously Servo-ing + + This sketch uses all pins 0 through 85 as RC servo outputs. For each pin, + we go from 1ms to 2ms and then back again, moving all servos back and forth. + + The circuit: + * RC servos attached from pins 0 through 85 to ground. + + Written 8/14/22 by Brian Schmalz http://www.schmalzhaus.com + This example code is in the public domain. + Based on AnalogWriteMega example code +*/ + +#include + +// These constants won't change. They're used to give names +// to the pins used: +const int lowestPin = 0; +// Use highestPin = 85 for the Max32 board, and highestPin = 41 for the Uno32 +const int highestPin = 41; + +void setup() { + // The SoftPWMServo library sets any used pins to be outputs, so that's not needed here +} + +void loop() { + // Go from 1ms to 2ms + for (int pos = 1000; pos < 2000; pos += 10) { + // iterate over the pins: + for (int thisPin =lowestPin; thisPin <= highestPin; thisPin++) { + SoftPWMServoServoWrite(thisPin, pos); + } + delay(25); + } + // And now from 2ms back to 1ms + for (int pos = 2000; pos > 1000; pos -= 10) { + // iterate over the pins: + for (int thisPin =lowestPin; thisPin <= highestPin; thisPin++) { + SoftPWMServoServoWrite(thisPin, pos); + } + delay(25); + } +} diff --git a/hardware/pic32/libraries/SoftPWMServo/examples/ChangeFrameTime/ChangeFrameTime.ino b/hardware/pic32/libraries/SoftPWMServo/examples/ChangeFrameTime/ChangeFrameTime.ino new file mode 100755 index 000000000..9d2ea6048 --- /dev/null +++ b/hardware/pic32/libraries/SoftPWMServo/examples/ChangeFrameTime/ChangeFrameTime.ino @@ -0,0 +1,53 @@ +// Change Frame Time demonstration using SoftPWMServo library +// by Brian Schmalz http://www.schmalzhaus.com +// This example code is in the public domain. + +// Normally, the SoftPWMServo lirbary uses a 2ms 'frame time'. +// The frame time is the time between rising edges of the PWM output. +// To produce RC Servo output, the library executes a normal PWM output +// on a pin (from 0ms to frame time in length) and then waits for +// a certain number of frames to go by (with no output) and then +// sends the pulse again. The number of frames from servo rising +// edge to rising edge can also be set using the SoftPWMServoServoFrames() +// call. + +// So this frame time, normally 2ms, can be made almost arbitrariliy +// small or large. The most interesting use of this functionality would be +// to extend the maximum pulse width so that RC servo output can use +// pulses longer than 2ms. There are many servos that need pulses longer +// than 2ms in order to reach full travel. + +// So if we want to make our frame time 4ms, then we can have pulses that +// range in duration from 0ms to 4ms, which should be enough for any servo. +// We will also want to shorten the ServoFrames value - for example, if we +// set FrameTime to 4ms, and ServoFrames to 5, then there would be 20ms between +// each rising edge of the servo pulses. + +// This little exapmle shows how this is done. + +#include + +int pos = 0; // variable to store the servo position, in microseconds +const int pin = 10; // Choose _any_ pin number on your board + +void setup() +{ + // The Write() calls normally call Init(), but since we're doing some setup + // before we do a Write(), we need to do this Init() call ourselves here. + SoftPWMServoInit(); + + // Set the FrameTime (in 40MHz ticks) to 4ms + SoftPWMServoSetFrameTime(usToTicks(4000)); + + // And set the frames between rising edges to 5 (20ms) + SoftPWMServoSetServoFrames(5); +} + +void loop() +{ + for(pos = 500; pos < 3500; pos += 10) // goes from .5ms to 3.5ms in steps of 10us + { + SoftPWMServoServoWrite(pin, pos); // tell servo to go to position in variable 'pos' + delay(25); // waits 25ms for the servo to reach the position + } +} diff --git a/hardware/pic32/libraries/SoftPWMServo/examples/SimplePWM/SimplePWM.ino b/hardware/pic32/libraries/SoftPWMServo/examples/SimplePWM/SimplePWM.ino new file mode 100755 index 000000000..d24963457 --- /dev/null +++ b/hardware/pic32/libraries/SoftPWMServo/examples/SimplePWM/SimplePWM.ino @@ -0,0 +1,40 @@ +// Simple PWM demonstration using SoftPWMServo library +// by Brian Schmalz http://www.schmalzhaus.com +// This example code is in the public domain. + +// We take 3 pins (could be any at all) and slowly +// ramp them up from 0% to 100%. You could put +// red, green and blue LEDs on these pins and have a neat +// little color fader. + +#include + +// Pick 3 pins, any 3 pins, and use them for our PWM output +const int PinOne = 10; +const int PinTwo = 35; +const int PinThree = 22; + +// Start each pin out at a different PWM value +char PinOneValue = 0; +char PinTwoValue = 100; +char PinThreeValue = 200; + +void setup() +{ +} + +void loop() +{ + // Set each of our three pins as PWM outputs, with their respective values + SoftPWMServoPWMWrite(PinOne, PinOneValue); + SoftPWMServoPWMWrite(PinTwo, PinTwoValue); + SoftPWMServoPWMWrite(PinThree, PinThreeValue); + + // Incriment each PWM value - they will roll over after 255 due to being chars +// PinOneValue++; +// PinTwoValue++; +// PinThreeValue++; + + // Wait just a tad so we don't go too fast. + delay(15); +} diff --git a/hardware/pic32/libraries/SoftPWMServo/examples/SimpleServo/SimpleServo.ino b/hardware/pic32/libraries/SoftPWMServo/examples/SimpleServo/SimpleServo.ino new file mode 100755 index 000000000..06d1b1e4c --- /dev/null +++ b/hardware/pic32/libraries/SoftPWMServo/examples/SimpleServo/SimpleServo.ino @@ -0,0 +1,29 @@ +// Simple Servo demonstration using SoftPWMServo library +// by Brian Schmalz http://www.schmalzhaus.com +// This example code is in the public domain. + +// We take a pin (could be any pin) and use it as a servo +// output. We sweep from 1ms pulse to 2ms pulse to show +// that the servo can be controled. + +// Note that you could easily write a little function to +// convert from 'desired angle in degrees' to 'microseconds' +// so that you could specify a degree value to your servo. + +#include + +int pos = 0; // variable to store the servo position, in microseconds +const int pin = 10; // Choose _any_ pin number on your board + +void setup() +{ +} + +void loop() +{ + for(pos = 1000; pos < 2000; pos += 10) // goes from 1ms to 2ms + { // in steps of 10us + SoftPWMServoServoWrite(pin, pos); // tell servo to go to position in variable 'pos' + delay(25); // waits 25ms for the servo to reach the position + } +} diff --git a/hardware/pic32/libraries/SoftSPI/examples/PmodJstkSoftSPI/PmodJstkSoftSPI.ino b/hardware/pic32/libraries/SoftSPI/examples/PmodJstkSoftSPI/PmodJstkSoftSPI.ino new file mode 100755 index 000000000..a714243b7 --- /dev/null +++ b/hardware/pic32/libraries/SoftSPI/examples/PmodJstkSoftSPI/PmodJstkSoftSPI.ino @@ -0,0 +1,368 @@ +/************************************************************************/ +/* */ +/* PmodJSTKSoftSpi -- Illustrate Use of SoftSPI Library with PmodJSTK */ +/* */ +/************************************************************************/ +/* Author: Gene Apperson */ +/* Copyright 2011, Digilent Inc, All rights reserved. */ +/************************************************************************/ +/* + This program 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 +*/ +/************************************************************************/ +/* Module Description: */ +/* */ +/* This example illustrates using the chipKIT SoftSPI library to */ +/* communicate with a Digilent PmodJSTK. */ +/* */ +/* This demo blinks LED3 and LED4 on boards that have four LEDs, and at */ +/* the same time, blinks the two LEDs on the PmodJSTK. It reads the */ +/* state of the two buttons on the PmodJSTK, and turns LED1 and LED2 on */ +/* and off based on the button state. The X and Y joystick position is */ +/* read and placed into global variables, but not used by the demo */ +/* itself. */ +/* */ +/************************************************************************/ +/* Revision History: */ +/* */ +/* 11/21/2011(GeneApperson): Created */ +/* */ +/************************************************************************/ + + +/* ------------------------------------------------------------ */ +/* Include File Definitions */ +/* ------------------------------------------------------------ */ + +/* Pull in the SoftSPI library +*/ +#include + + +/* ------------------------------------------------------------ */ +/* Local Type Definitions */ +/* ------------------------------------------------------------ */ + +#define cntBlinkInit 50000 + +#define SPI_PORT 1 + +#if (SPI_PORT == 1) + +#define pinSS 24 +#define pinMOSI 25 +#define pinMISO 26 +#define pinSCK 27 + +#elif (SPI_PORT == 2) + +#define pinSS 32 +#define pinMOSI 33 +#define pinMISO 34 +#define pinSCK 35 + +#elif (SPI_PORT == 3) + +#define pinSS 40 +#define pinMOSI 41 +#define pinMISO 42 +#define pinSCK 43 + +#endif + +/* ------------------------------------------------------------ */ +/* Global Variables */ +/* ------------------------------------------------------------ */ + +int cntBtnBlink; +uint8_t fbLedPmod; +uint8_t fbBtnPmod; +int xcoPmod; +int ycoPmod; +int fLed3; +int fLed4; + +/* Unlike many chipKIT/Arduino libraries, the SoftSPI library doesn't +** automatically instantiate any interface objects. It is necessary +** to declare an instance of one of the interface objects in the +** sketch. +*/ +SoftSPI spi; + +/* ------------------------------------------------------------ */ +/* Local Variables */ +/* ------------------------------------------------------------ */ + + +/* ------------------------------------------------------------ */ +/* Forward Declarations */ +/* ------------------------------------------------------------ */ + + +/* ------------------------------------------------------------ */ +/* Procedure Definitions */ +/* ------------------------------------------------------------ */ +/*** setup +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Initialize the system. +*/ + +void setup() { + DeviceInit(); + AppInit(); +} + +/* ------------------------------------------------------------ */ +/*** loop +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Main application loop. +*/ + +void loop() { + AppTask(); +} + +/* ------------------------------------------------------------ */ +/*** DeviceInit +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform basic board/device level initialization. +*/ + +void DeviceInit() { + /* Set the LED pins to be outputs. Some boards support more + ** than two LEDs. On those boards, also blink the additional + ** LEDs. + */ + pinMode(PIN_LED1, OUTPUT); + pinMode(PIN_LED2, OUTPUT); +#if defined(PIN_LED3) + pinMode(PIN_LED3, OUTPUT); +#endif +#if defined(PIN_LED4) + pinMode(PIN_LED4, OUTPUT); +#endif + /* Initialize the SPI port. + ** Note: The pmodJSTK requires a delay of at least 6uS between + ** bytes, so the delay is set to 6uS below. + */ + spi.begin(pinSS, pinMOSI, pinMISO, pinSCK); + spi.setSpeed(250000); + spi.setMode(SSPI_MODE0); + spi.setDirection(SSPI_SHIFT_LEFT); + spi.setDelay(6); +} + +/* ------------------------------------------------------------ */ +/*** AppInit +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform application level initialization. Call the various +** init functions to initalize the application subsystems. +*/ + +void AppInit() { + /* Init program state variables. + */ + cntBtnBlink = cntBlinkInit; + fbLedPmod = 0x01; + fbBtnPmod = 0; + xcoPmod = 0; + ycoPmod = 0; + /* Start with LED3 on and LED4 off + */ + fLed3 = HIGH; + fLed4 = LOW; +} + +/* ------------------------------------------------------------ */ +/*** AppTask +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Perform main application functions. This is called once +** each time through the main program loop. +*/ + +void AppTask() { + unsigned int dwBtn; + /* Check the state of button 1 on the PmodJSTK and set LED 1 + ** accordingly + */ + dwBtn = fbBtnPmod & 0x01; + + if (dwBtn == 0) { + digitalWrite(PIN_LED1, LOW); + } else { + digitalWrite(PIN_LED1, HIGH); + } + + /* Check the state of button 2 and set LED 2 accordingly + */ + dwBtn = fbBtnPmod & 0x02; + + if (dwBtn == 0) { + digitalWrite(PIN_LED2, LOW); + } else { + digitalWrite(PIN_LED2, HIGH); + } + + /* Check if it is time to blink LED3 & LED4 and update + ** the joystick. + */ + cntBtnBlink -= 1; + + if (cntBtnBlink == 0) { +#if defined(PIN_LED3) + digitalWrite(PIN_LED3, fLed3); + fLed3 = (fLed3 == HIGH) ? LOW : HIGH; +#endif +#if defined(PIN_LED4) + digitalWrite(PIN_LED4, fLed4); + fLed4 = (fLed4 == HIGH) ? LOW : HIGH; +#endif + /* Toggle the setting for the LEDs on the joystick. + */ + fbLedPmod ^= 0x03; + /* Update the joystick. + */ + ReadJoystick(fbLedPmod, &fbBtnPmod, &xcoPmod, &ycoPmod); + cntBtnBlink = cntBlinkInit; + } +} + +/* ------------------------------------------------------------ */ +/*** ReadJoystick +** +** Parameters: +** fbLed - LED state to set +** pfbBtn - variable to receive button state +** pxco - pointer to var to receive x coordinate +** pyco - pointer to var to receive y coordinate +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Read the current position of the joystick and buttons. +*/ +void ReadJoystick(uint8_t fbLed, uint8_t * pfbBtn, int * pxco, int * pyco) { + uint8_t rgbSnd[5]; + uint8_t rgbRcv[5]; + int ib; + + /* Initialize the transmit buffer. + */ + for (ib = 0; ib < 5; ib++) { + rgbSnd[ib] = 0x50 + ib; + } + + rgbSnd[0] = fbLedPmod + 0x80; //first byte sent sets the LEDs + /* Bring SS low to begin the transaction. + */ + spi.setSelect(LOW); + /* Wait 10us for Pmod to become ready + */ + Delay10us(); + /* Send the data to the Pmod and get the response. + */ + spi.transfer(5, rgbSnd, rgbRcv); + /* Bring SS high to end the transaction. + */ + spi.setSelect(HIGH); + /* Set up the return values. + */ + *pfbBtn = rgbRcv[4] >> 1; + *pxco = (uint16_t)((rgbRcv[1] << 8) + rgbRcv[0]); + *pyco = (uint16_t)((rgbRcv[3] << 8) + rgbRcv[2]); +} + +/* ------------------------------------------------------------ */ +/*** Delay10us +** +** Parameters: +** none +** +** Return Value: +** none +** +** Errors: +** none +** +** Description: +** Delay loop for ~10uS +*/ + +void Delay10us() { + volatile int cnt; + + for (cnt = 0; cnt < 100; cnt++) { + } +} + +/* ------------------------------------------------------------ */ + +/************************************************************************/ + + diff --git a/hardware/pic32/libraries/Stepper/examples/MotorKnob/MotorKnob.ino b/hardware/pic32/libraries/Stepper/examples/MotorKnob/MotorKnob.ino new file mode 100755 index 000000000..d42818634 --- /dev/null +++ b/hardware/pic32/libraries/Stepper/examples/MotorKnob/MotorKnob.ino @@ -0,0 +1,41 @@ +/* + * MotorKnob + * + * A stepper motor follows the turns of a potentiometer + * (or other sensor) on analog input 0. + * + * http://www.arduino.cc/en/Reference/Stepper + * This example code is in the public domain. + */ + +#include + +// change this to the number of steps on your motor +#define STEPS 100 + +// create an instance of the stepper class, specifying +// the number of steps of the motor and the pins it's +// attached to +Stepper stepper(STEPS, 8, 9, 10, 11); + +// the previous reading from the analog input +int previous = 0; + +void setup() +{ + // set the speed of the motor to 30 RPMs + stepper.setSpeed(30); +} + +void loop() +{ + // get the sensor value + int val = analogRead(0); + + // move a number of steps equal to the change in the + // sensor reading + stepper.step(val - previous); + + // remember the previous value of the sensor + previous = val; +} \ No newline at end of file diff --git a/hardware/pic32/libraries/Stepper/examples/stepper_oneRevolution/stepper_oneRevolution.ino b/hardware/pic32/libraries/Stepper/examples/stepper_oneRevolution/stepper_oneRevolution.ino new file mode 100755 index 000000000..2dbb57d7a --- /dev/null +++ b/hardware/pic32/libraries/Stepper/examples/stepper_oneRevolution/stepper_oneRevolution.ino @@ -0,0 +1,44 @@ + +/* + Stepper Motor Control - one revolution + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + + The motor should revolve one revolution in one direction, then + one revolution in the other direction. + + + Created 11 Mar. 2007 + Modified 30 Nov. 2009 + by Tom Igoe + + */ + +#include + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution + // for your motor + +// initialize the stepper library on pins 8 through 11: +Stepper myStepper(stepsPerRevolution, 8,9,10,11); + +void setup() { + // set the speed at 60 rpm: + myStepper.setSpeed(60); + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // step one revolution in one direction: + Serial.println("clockwise"); + myStepper.step(stepsPerRevolution); + delay(500); + + // step one revolution in the other direction: + Serial.println("counterclockwise"); + myStepper.step(-stepsPerRevolution); + delay(500); +} + diff --git a/hardware/pic32/libraries/Stepper/examples/stepper_oneStepAtATime/stepper_oneStepAtATime.ino b/hardware/pic32/libraries/Stepper/examples/stepper_oneStepAtATime/stepper_oneStepAtATime.ino new file mode 100755 index 000000000..36d32991d --- /dev/null +++ b/hardware/pic32/libraries/Stepper/examples/stepper_oneStepAtATime/stepper_oneStepAtATime.ino @@ -0,0 +1,44 @@ + +/* + Stepper Motor Control - one step at a time + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + + The motor will step one step at a time, very slowly. You can use this to + test that you've got the four wires of your stepper wired to the correct + pins. If wired correctly, all steps should be in the same direction. + + Use this also to count the number of steps per revolution of your motor, + if you don't know it. Then plug that number into the oneRevolution + example to see if you got it right. + + Created 30 Nov. 2009 + by Tom Igoe + + */ + +#include + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution + // for your motor + +// initialize the stepper library on pins 8 through 11: +Stepper myStepper(stepsPerRevolution, 8,9,10,11); + +int stepCount = 0; // number of steps the motor has taken + +void setup() { + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // step one step: + myStepper.step(1); + Serial.print("steps:" ); + Serial.println(stepCount); + stepCount++; + delay(500); +} + diff --git a/hardware/pic32/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino b/hardware/pic32/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino new file mode 100755 index 000000000..dbd0f7f02 --- /dev/null +++ b/hardware/pic32/libraries/Stepper/examples/stepper_speedControl/stepper_speedControl.ino @@ -0,0 +1,49 @@ + +/* + Stepper Motor Control - speed control + + This program drives a unipolar or bipolar stepper motor. + The motor is attached to digital pins 8 - 11 of the Arduino. + A potentiometer is connected to analog input 0. + + The motor will rotate in a clockwise direction. The higher the potentiometer value, + the faster the motor speed. Because setSpeed() sets the delay between steps, + you may notice the motor is less responsive to changes in the sensor value at + low speeds. + + Created 30 Nov. 2009 + Modified 28 Oct 2010 + by Tom Igoe + + */ + +#include + +const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution +// for your motor + + +// initialize the stepper library on pins 8 through 11: +Stepper myStepper(stepsPerRevolution, 8,9,10,11); + +int stepCount = 0; // number of steps the motor has taken + +void setup() { + // initialize the serial port: + Serial.begin(9600); +} + +void loop() { + // read the sensor value: + int sensorReading = analogRead(A0); + // map it to a range from 0 to 100: + int motorSpeed = map(sensorReading, 0, 1023, 0, 100); + // set the motor speed: + if (motorSpeed > 0) { + myStepper.setSpeed(motorSpeed); + // step 1/100 of a revolution: + myStepper.step(stepsPerRevolution/100); + } +} + + diff --git a/hardware/pic32/libraries/Wire/examples/I2CMasterEEPROM/I2CMasterEEPROM.ino b/hardware/pic32/libraries/Wire/examples/I2CMasterEEPROM/I2CMasterEEPROM.ino new file mode 100644 index 000000000..01d753382 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/I2CMasterEEPROM/I2CMasterEEPROM.ino @@ -0,0 +1,355 @@ +/************************************************************************/ +/* */ +/* I2CMasterEEPROM */ +/* */ +/* Example sketch to program and read 24LCxxx EEPROMs */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* 8/4/2014(KeithV): Created */ +/************************************************************************/ + +#include + +//#define I2CADDR 0x50 // on board EEPROM, chipKIT Pro MX4, Network Shield +#define I2CADDR 0x44 // Slave address for the I2CSlaveSimEEPROM sketch + +// create the DTWI object +DTWI0 dtwi0; + +typedef enum { + NONE, + QUERYBUTTONPRESS, + WAITBUTTONPRESS, + WAITBUTTONRELEASE, + BEGINMASTER, + ENDMASTER, + STARTMASTERWRITE, + SAVE, + RESTARTMASTERWRITE, + RESTARTMASTERREAD, + ADDRWRITE, + ADDRREAD, + WRITEDATA, + READDATA, + STOPMASTER, + ERROR, + DONE, +} TWISTATE; + +TWISTATE twiState = NONE; + +// make this 64 bytes which is the size of the page write buffer in the 24LCxxx +// read the documentation carefully, the eeprom can be programmed in 64 byte pages, +// however the pages are 64 byte aligned in the eeprom space. So be starting at an +// address not 64 byte aligned will cause a wrap in the eeprom program address space +// when programmed. In our example we write at address 0x10, write 64 bytes which +// will then wrap back to zero when 0x40 is hit, and the first 16 byes in the eeprom +// are written. When we read back, we read back at address 0x00 and we will see those +// last 16 bytes written starting at location 0 +static const byte rgbDataWrite[] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0x00, + 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0x01, + 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0x02, + 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0x03, + 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0x04, + 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0x05, + 0x16, 0x26, 0x36, 0x46 + }; + + +static uint32_t cbWritten = 0; +static uint32_t cbRead = 0; + +// Read the 24LCxxx Datasheet carefully. ALL WRITES to the EEPROM are 64 byte aligned in the +// address space and will wrap on the 64 byte boundary. By starting at 0x10, only 48 bytes will +// write to the addresses we expect, after 48 bytes, the address will wrap to 0 ans start writing from there +static const byte rgbEEPromAddrWrite[2] = {0x00, 0x10}; // high btye, low byte order. + +// by reading from the 64 byte aligned boundary (of 0) we can see how the bytes after the first 16 bytes +// wrapped around to the begining of the 64 byte aligned locations +static const byte rgbEEPromAddrRead[2] = {0x00, 0x00}; // high btye, low byte order. + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup routine + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("I2CMasterEEPROM v3.0"); + Serial.println("Example sketch to read I2C 24LCxxx EEPROMs"); + Serial.println("Written by: Keith Vogel"); + Serial.println("Copyright Digilent 2014"); + + +// if the WF32, turn on the pullup resistors +#ifdef _BOARD_WF32_ + pinMode(62, OUTPUT); + pinMode(63, OUTPUT); + digitalWrite(62, HIGH); + digitalWrite(63, HIGH); +#endif + +#ifdef PIN_BTN1 + pinMode(PIN_BTN1, INPUT); + twiState = QUERYBUTTONPRESS; +#else + twiState = BEGINMASTER; +#endif +} + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop routine + * ------------------------------------------------------------ */ +void loop() { + + switch(twiState) + { + +#ifdef PIN_BTN1 + case QUERYBUTTONPRESS: + Serial.println("Press BTN to query EEPROM"); + twiState = WAITBUTTONPRESS; + break; + + case WAITBUTTONPRESS: + if(digitalRead(PIN_BTN1) == HIGH) + { + twiState = WAITBUTTONRELEASE; + } + break; + + case WAITBUTTONRELEASE: + if(digitalRead(PIN_BTN1) == LOW) + { + delay(1); // some debounce + twiState = BEGINMASTER; + } + break; +#endif + + case BEGINMASTER: + if(dtwi0.beginMaster()) + { + int i; + twiState = STARTMASTERWRITE; + + // put this print out now, because once I start the master I don't want + // the serial prints to block writing to the I2C bus; it won't hurt, it will + // just put a multi-millisecond delay in while this message prints. + Serial.print("Writing "); + Serial.print((uint32_t) sizeof(rgbDataWrite), DEC); + Serial.print(" bytes to eeprom address: 0x"); + Serial.print((((uint32_t) rgbEEPromAddrWrite[0]) << 8) + rgbEEPromAddrWrite[1], HEX); + + for(i = 0; i < sizeof(rgbDataWrite); i++) + { + if((i % 16) == 0) + { + Serial.println(); + } + Serial.print("0x"); + Serial.print(rgbDataWrite[i], HEX); + Serial.print(" "); + } + Serial.println(); + } + else + { + twiState = ERROR; + } + break; + + case STARTMASTERWRITE: + if(dtwi0.startMasterWrite(I2CADDR)) + { + cbWritten = 0; + twiState = ADDRWRITE; + } + else + { + twiState = ERROR; + } + break; + + case ADDRWRITE: + + if(cbWritten < sizeof(rgbEEPromAddrWrite)) + { + cbWritten += dtwi0.write(&rgbEEPromAddrWrite[cbWritten], sizeof(rgbEEPromAddrWrite) - cbWritten); + } + else + { + twiState = WRITEDATA; + cbWritten = 0; + } + break; + + case WRITEDATA: + + if(cbWritten < sizeof(rgbDataWrite)) + { + cbWritten += dtwi0.write(&rgbDataWrite[cbWritten], sizeof(rgbDataWrite) - cbWritten); + } + else + { + twiState = SAVE; + } + break; + + case SAVE: + if(dtwi0.stopMaster()) + { + twiState = RESTARTMASTERWRITE; + } + break; + + case RESTARTMASTERWRITE: + // this can fail because the EEPROM is busy + if(dtwi0.startMasterWrite(I2CADDR)) + { + cbWritten = 0; + twiState = ADDRREAD; + } + break; + + case ADDRREAD: + + if(cbWritten < sizeof(rgbEEPromAddrRead)) + { + cbWritten += dtwi0.write(&rgbEEPromAddrRead[cbWritten], sizeof(rgbEEPromAddrRead) - cbWritten); + } + else + { + twiState = RESTARTMASTERREAD; + cbWritten = 0; + } + break; + + case RESTARTMASTERREAD: + if(dtwi0.startMasterRead(I2CADDR, sizeof(rgbDataWrite))) + { + cbRead = 0; + twiState = READDATA; + Serial.println("Reading eeprom data back"); + } + break; + + case READDATA: + if(dtwi0.available()) + { + int i = 0; + byte rgb[32]; + uint32_t cbReadThisPass = dtwi0.read(rgb, sizeof(rgb)); + uint32_t readAddr = (((uint32_t) rgbEEPromAddrRead[0]) << 8) + rgbEEPromAddrRead[1] + cbRead; + + Serial.print("eeprom addr 0x"); + Serial.print(readAddr, HEX); + Serial.print(": "); + + cbRead += cbReadThisPass; + + for(i = 0; i < cbReadThisPass; i++) + { + Serial.print("0x"); + Serial.print(rgb[i], HEX); + Serial.print(" "); + } + Serial.println(); + + if(cbRead >= sizeof(rgbDataWrite)) + { + twiState = STOPMASTER; + } + } + break; + + case STOPMASTER: + if(dtwi0.stopMaster()) + { + twiState = ENDMASTER; + } + break; + + case ENDMASTER: + dtwi0.endMaster(); + + // clean out the read / write buffer + dtwi0.abort(); + dtwi0.discard(); + +#ifdef PIN_BTN1 + twiState = QUERYBUTTONPRESS; +#else + Serial.println("Sketch is done"); + twiState = DONE; +#endif + break; + + case ERROR: + Serial.println("Got an error, ending sketch"); +#ifdef PIN_BTN1 + twiState = ENDMASTER; +#else + Serial.println("Sketch is done"); + twiState = DONE; +#endif + break; + + DONE: + default: + break; + } +} diff --git a/hardware/pic32/libraries/Wire/examples/I2CSlaveSimEEPROM/I2CSlaveSimEEPROM.ino b/hardware/pic32/libraries/Wire/examples/I2CSlaveSimEEPROM/I2CSlaveSimEEPROM.ino new file mode 100644 index 000000000..f9b0fd2d0 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/I2CSlaveSimEEPROM/I2CSlaveSimEEPROM.ino @@ -0,0 +1,310 @@ +/************************************************************************/ +/* */ +/* I2CSlaveSimEEPROM.cpp */ +/* */ +/* Example sketch to emulate a 24LCxxx (24LC1) (1K) EEPROM */ +/* */ +/************************************************************************/ +/* Author: Keith Vogel */ +/* Copyright 2014, Digilent Inc. */ +/************************************************************************/ +/* +* +* Copyright (c) 2013-2014, Digilent +* Contact Digilent for the latest version. +* +* This program is free software; distributed under the terms of +* BSD 3-clause license ("Revised BSD License", "New BSD License", or "Modified BSD License") +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names +* of its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/************************************************************************/ +/* Revision History: */ +/* 8/4/2014(KeithV): Created */ +/************************************************************************/ + +#include + +#define I2CADDR 0x44 // slave address + +// how long to be offline while updating the eeprom flash +#define microWAIT 250 + +// create the DTWI object +DTWI0 dtwi0; + +typedef enum { + NONE, + BEGINSLAVE, + WAITMYBUS, + WAITEEPROMADDRESS, + WRITERAM, + READRAM, + PGMFLASH, + DELAYSOME, + ERROR, + ENDSLAVE, + DONE, +} TWISTATE; + +static TWISTATE twiState = NONE; +static uint32_t tStart = 0; + +// The 64 byte eeprom page write buffer +#define WBALIGNMASK 0xFFFFFFC0 +static byte rgbPageWriteBuffer[64]; + +// depending on the eeprom, the size of the eeprom +// is a mult of the page write buffer. The eeprom Digilent use +// on the MX4ck or Network Shield is a 24LC256, a 256K eeprom or +// 4000x the page write buffer. We don't have that much RAM to +// simulate the full 256K, so we are only going to have 1K +// or 16x; so this would be a 24LC1.... if it existed. +#define mRAMvsPageWriteBuff 16 +static byte rgbSimEEProm[mRAMvsPageWriteBuff * sizeof(rgbPageWriteBuffer)]; + +// the RAM address we are writing +static uint16_t ramAddress = 0; +static uint8_t curSession = 0; +static bool fWriteRAM = false; + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino setup routine + * ------------------------------------------------------------ */ +void setup() { + + Serial.begin(9600); + Serial.println("I2CSlaveSimEEPROM v2.0"); + Serial.println("Simulated 24LCxxx EEPROM I2C Slave"); + Serial.println("Written by: Keith Vogel"); + Serial.println("Copyright Digilent 2014"); + +// if the WF32, turn on the pullup resistors +#ifdef _BOARD_WF32_ + pinMode(62, OUTPUT); + pinMode(63, OUTPUT); + digitalWrite(62, HIGH); + digitalWrite(63, HIGH); +#endif + + // flash is originally erased to FFs + memset(rgbSimEEProm, 0xFF, sizeof(rgbSimEEProm)); + + // clean out the read / write buffers + // in the I2C controller + dtwi0.abort(); + dtwi0.discard(); + + twiState = BEGINSLAVE; +} + +/*** void setup() + * + * Parameters: + * None + * + * Return Values: + * None + * + * Description: + * + * Arduino loop routine + * ------------------------------------------------------------ */ +void loop() { + DTWI::I2C_STATUS curStatus = dtwi0.getStatus(); + + switch(twiState) + { + case BEGINSLAVE: + if(dtwi0.beginSlave(I2CADDR)) + { + twiState = WAITMYBUS; + } + else + { + twiState = ENDSLAVE; + } + break; + + case WAITMYBUS: + // about to recieve and address + if(curStatus.fRead) + { + twiState = WAITEEPROMADDRESS; + curSession = curStatus.iSession; + } + + // if we get a write, just spit out data + else if(curStatus.fWrite) + { + twiState = READRAM; + curSession = curStatus.iSession; + } + break; + + case WAITEEPROMADDRESS: + if(dtwi0.available() >= 2) + { + uint32_t iWriteBuffBase; + + dtwi0.read(&((byte *) &ramAddress)[1], 1); + dtwi0.read(&((byte *) &ramAddress)[0], 1); + + // we want to make sure the specified address + // wraps and is in the range of our sim eeprom + ramAddress %= sizeof(rgbSimEEProm); + iWriteBuffBase = ramAddress & WBALIGNMASK; + + // we must preload our page write buffer with + // contents of the eeprom; remember to read the aligned values in + memcpy(rgbPageWriteBuffer, &rgbSimEEProm[iWriteBuffBase], sizeof(rgbPageWriteBuffer)); + + // go to getting the data + fWriteRAM = false; + twiState = WRITERAM; + } + + // if somehow we are not on a read... + // but we are waiting for an address, so this doesn't + // make any sense, go back and wait for a restart + else if(curSession != curStatus.iSession || !curStatus.fMyBus) + { + twiState = ENDSLAVE; + } + break; + + case WRITERAM: + // consume anything we have in the buffer + while(dtwi0.available() > 0) + { + // location of the address is page write buffer aligned + // within the eeprom + uint32_t iPageWriteBuff = ramAddress % sizeof(rgbPageWriteBuffer); + uint32_t cbRead = min(sizeof(rgbPageWriteBuffer) - iPageWriteBuff, dtwi0.available()); + + // read the data into the write page buffer + dtwi0.read(&rgbPageWriteBuffer[iPageWriteBuff], cbRead); + + // update the ramAddress based on the page write buffer address wrapping + ramAddress = (ramAddress & WBALIGNMASK) + ((iPageWriteBuff + cbRead) % sizeof(rgbPageWriteBuffer)); + + fWriteRAM = true; + } + + // as soon as we lose the bus, shutdown the controller + // this will give us time to read the rest of the data and + // write sim eeprom + if(!curStatus.fBusInUse && fWriteRAM) + { + // we want to immediately turn OFF the controller + // we do not want to respond to new address requests + dtwi0.endSlave(true); + twiState = PGMFLASH; + } + + // if I lost the session, don't write the eeprom + // just go back and look for another command + else if(!curStatus.fMyBus || curStatus.iSession != curSession) + { + twiState = WAITMYBUS; + } + + break; + + case READRAM: + if(dtwi0.transmitting() < 10) + { + dtwi0.write(&rgbSimEEProm[ramAddress++], 1); + ramAddress %= sizeof(rgbSimEEProm); + } + else if(!curStatus.fMyBus || curStatus.iSession != curSession) + { + // clean out the write buffer + twiState = ENDSLAVE; + } + break; + + case PGMFLASH: + // we must write back our page write buffer to + // simulated eeprom + memcpy(&rgbSimEEProm[(ramAddress & WBALIGNMASK)], rgbPageWriteBuffer, sizeof(rgbPageWriteBuffer)); + + // clean out the read / write buffer + dtwi0.abort(); + dtwi0.discard(); + + // now simulate flash write time + tStart = micros(); + twiState = DELAYSOME; + break; + + case DELAYSOME: + // the 24LCxxxx will be knocked off line as a slave + // while it updates the eeprom from the write buffer + // a real 24LCxxxx will be off line for many millisec + // but as an emulations, we just want to be off line + // long enough to show we went off line, so our emulation + // is much shorter. + if( micros() - tStart >= microWAIT) + { + // start over, wait for another slave command + twiState = BEGINSLAVE; + } + break; + + case ENDSLAVE: + // forcefully end the slave + dtwi0.endSlave(true); + + // clean the buffers up + dtwi0.abort(); + dtwi0.discard(); + + // start over, wait for another slave command + twiState = BEGINSLAVE; + break; + + case ERROR: + // forcefully end the slave + dtwi0.endSlave(true); + tStart = micros(); + + Serial.println("Got an error, ending sketch"); + twiState = DELAYSOME; + break; + + DONE: + default: + break; + } +} diff --git a/hardware/pic32/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino b/hardware/pic32/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino new file mode 100644 index 000000000..4bb4b83e8 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino @@ -0,0 +1,87 @@ +// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder +// by Nicholas Zambetti +// and James Tichenor + +// Demonstrates use of the Wire library reading data from the +// Devantech Utrasonic Rangers SFR08 and SFR10 + +// Created 29 April 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) + Serial.begin(9600); // start serial communication at 9600bps +} + +int reading = 0; + +void loop() +{ + // step 1: instruct sensor to read echoes + Wire.beginTransmission(112); // transmit to device #112 (0x70) + // the address specified in the datasheet is 224 (0xE0) + // but i2c adressing uses the high 7 bits so it's 112 + Wire.send(0x00); // sets register pointer to the command register (0x00) + Wire.send(0x50); // command sensor to measure in "inches" (0x50) + // use 0x51 for centimeters + // use 0x52 for ping microseconds + Wire.endTransmission(); // stop transmitting + + // step 2: wait for readings to happen + delay(70); // datasheet suggests at least 65 milliseconds + + // step 3: instruct sensor to return a particular echo reading + Wire.beginTransmission(112); // transmit to device #112 + Wire.send(0x02); // sets register pointer to echo #1 register (0x02) + Wire.endTransmission(); // stop transmitting + + // step 4: request reading from sensor + Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 + + // step 5: receive reading from sensor + if(2 <= Wire.available()) // if two bytes were received + { + reading = Wire.receive(); // receive high byte (overwrites previous reading) + reading = reading << 8; // shift high byte to be high 8 bits + reading |= Wire.receive(); // receive low byte as lower 8 bits + Serial.println(reading); // print the reading + } + + delay(250); // wait a bit since people have to read the output :) +} + + +/* + +// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) +// usage: changeAddress(0x70, 0xE6); + +void changeAddress(byte oldAddress, byte newAddress) +{ + Wire.beginTransmission(oldAddress); + Wire.send(0x00); + Wire.send(0xA0); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.send(0x00); + Wire.send(0xAA); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.send(0x00); + Wire.send(0xA5); + Wire.endTransmission(); + + Wire.beginTransmission(oldAddress); + Wire.send(0x00); + Wire.send(newAddress); + Wire.endTransmission(); +} + +*/ diff --git a/hardware/pic32/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino b/hardware/pic32/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino new file mode 100644 index 000000000..00a15cc3e --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino @@ -0,0 +1,39 @@ +// I2C Digital Potentiometer +// by Nicholas Zambetti +// and Shawn Bonkowski + +// Demonstrates use of the Wire library +// Controls AD5171 digital potentiometer via I2C/TWI + +// Created 31 March 2006 + +// This example code is in the public domain. + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte val = 0; + +void loop() +{ + Wire.beginTransmission(44); // transmit to device #44 (0x2c) + // device address is specified in datasheet + Wire.send(0x00); // sends instruction byte + Wire.send(val); // sends potentiometer value byte + Wire.endTransmission(); // stop transmitting + + val++; // increment value + if(val == 64) // if reached 64th position (max) + { + val = 0; // start over from lowest value + } + delay(500); +} + diff --git a/hardware/pic32/libraries/Wire/examples/master_reader/master_reader.ino b/hardware/pic32/libraries/Wire/examples/master_reader/master_reader.ino new file mode 100644 index 000000000..267f8c9a2 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/master_reader/master_reader.ino @@ -0,0 +1,32 @@ +// Wire Master Reader +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Reads data from an I2C/TWI slave device +// Refer to the "Wire Slave Sender" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) + Serial.begin(9600); // start serial for output +} + +void loop() +{ + Wire.requestFrom(20, 6); // request 6 bytes from slave device #20 + + while(Wire.available()) // slave may send less than requested + { + char c = Wire.receive(); // receive a byte as character + Serial.print(c); // print the character + } + + delay(500); +} diff --git a/hardware/pic32/libraries/Wire/examples/master_writer/master_writer.ino b/hardware/pic32/libraries/Wire/examples/master_writer/master_writer.ino new file mode 100644 index 000000000..f0dfbd379 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/master_writer/master_writer.ino @@ -0,0 +1,31 @@ +// Wire Master Writer +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Writes data to an I2C/TWI slave device +// Refer to the "Wire Slave Receiver" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(); // join i2c bus (address optional for master) +} + +byte x = 0; + +void loop() +{ + Wire.beginTransmission(40); // transmit to device #40 + Wire.send("x is "); // sends five bytes + Wire.send(x); // sends one byte + Wire.endTransmission(); // stop transmitting + + x++; + delay(500); +} diff --git a/hardware/pic32/libraries/Wire/examples/slave_receiver/slave_receiver.ino b/hardware/pic32/libraries/Wire/examples/slave_receiver/slave_receiver.ino new file mode 100644 index 000000000..896ad4842 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/slave_receiver/slave_receiver.ino @@ -0,0 +1,41 @@ +// Wire Slave Receiver +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Receives data as an I2C/TWI slave device +// Refer to the "Wire Master Writer" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(40); // join i2c bus with address #40 + Wire.onReceive(receiveEvent); // register event + Serial.begin(9600); // start serial for output +} + +void loop() +{ + delay(100); +} + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +void receiveEvent(int howMany) +{ + if(Wire.available() >= 6) + { + while(1 < Wire.available()) // loop through all but the last + { + char c = Wire.receive(); // receive byte as a character + Serial.print(c); // print the character + } + int x = Wire.receive(); // receive byte as an integer + Serial.println(x); // print the integer + } +} diff --git a/hardware/pic32/libraries/Wire/examples/slave_sender/slave_sender.ino b/hardware/pic32/libraries/Wire/examples/slave_sender/slave_sender.ino new file mode 100644 index 000000000..6f7d64ca7 --- /dev/null +++ b/hardware/pic32/libraries/Wire/examples/slave_sender/slave_sender.ino @@ -0,0 +1,32 @@ +// Wire Slave Sender +// by Nicholas Zambetti + +// Demonstrates use of the Wire library +// Sends data as an I2C/TWI slave device +// Refer to the "Wire Master Reader" example for use with this + +// Created 29 March 2006 + +// This example code is in the public domain. + + +#include + +void setup() +{ + Wire.begin(20); // join i2c bus with address #20 + Wire.onRequest(requestEvent); // register event +} + +void loop() +{ + delay(100); +} + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() +{ + Wire.send("hello "); // respond with message of 6 bytes + // as expected by master +}