1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-30 19:52:13 +01:00

Adding SPI library and revising Ethernet library (Christian Maglie).

This commit is contained in:
David A. Mellis 2010-08-02 18:59:44 +00:00
parent 78e093b482
commit e24b135755
24 changed files with 1429 additions and 2524 deletions

View File

@ -1,81 +1,77 @@
extern "C" {
#include "types.h"
#include "w5100.h"
#include "socket.h"
extern "C" {
#include "string.h"
}
#include "WProgram.h"
#include "Ethernet.h"
#include "Client.h"
#include "Server.h"
#include "ethernet.h"
#include "client.h"
#include "server.h"
uint16_t Client::_srcport = 0;
uint16_t Client::_srcport = 1024;
Client::Client(uint8_t sock) {
_sock = sock;
Client::Client() : _connected(false) {
}
Client::Client(uint8_t *ip, uint16_t port) {
_ip = ip;
_port = port;
_sock = 255;
Client::Client(uint8_t sock) : _connected(true), _sock(sock) {
}
Client::Client(uint8_t *ip, uint16_t port) : _ip(ip), _port(port), _connected(false) {
}
uint8_t Client::connect() {
if (_sock != 255)
if (_connected)
return 0;
for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = getSn_SR(i);
if (s == SOCK_CLOSED || s == SOCK_FIN_WAIT) {
int i;
for (i=0; i<MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i);
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
_sock = i;
break;
}
}
if (_sock == 255)
if (i == MAX_SOCK_NUM)
return 0;
_srcport++;
if (_srcport + 1024 == 0) _srcport = 0;
socket(_sock, Sn_MR_TCP, _srcport + 1024, 0);
if (_srcport == 0) _srcport = 1024;
socket(_sock, SnMR::TCP, _srcport, 0);
if (!::connect(_sock, _ip, _port)) {
_sock = 255;
if (!::connect(_sock, _ip, _port))
return 0;
}
while (status() != SOCK_ESTABLISHED) {
while (status() != SnSR::ESTABLISHED) {
delay(1);
if (status() == SOCK_CLOSED) {
_sock = 255;
if (status() == SnSR::CLOSED)
return 0;
}
}
_connected = true;
return 1;
}
void Client::write(uint8_t b) {
if (_sock != 255)
if (_connected)
send(_sock, &b, 1);
}
void Client::write(const char *str) {
if (_sock != 255)
if (_connected)
send(_sock, (const uint8_t *)str, strlen(str));
}
void Client::write(const uint8_t *buf, size_t size) {
if (_sock != 255)
if (_connected)
send(_sock, buf, size);
}
int Client::available() {
if (_sock != 255)
return getSn_RX_RSR(_sock);
if (_connected)
return W5100.getRXReceivedSize(_sock);
return 0;
}
@ -93,7 +89,7 @@ void Client::flush() {
}
void Client::stop() {
if (_sock == 255)
if (!_connected)
return;
// attempt to close the connection gracefully (send a FIN to other side)
@ -101,33 +97,25 @@ void Client::stop() {
unsigned long start = millis();
// wait a second for the connection to close
while (status() != SOCK_CLOSED && millis() - start < 1000)
while (status() != SnSR::CLOSED && millis() - start < 1000)
delay(1);
// if it hasn't closed, close it forcefully
if (status() != SOCK_CLOSED)
if (status() != SnSR::CLOSED)
close(_sock);
EthernetClass::_server_port[_sock] = 0;
_sock = 255;
_connected = false;
}
uint8_t Client::connected() {
if (_sock == 255) {
return 0;
} else {
uint8_t s = status();
return !(s == SOCK_LISTEN || s == SOCK_CLOSED || s == SOCK_FIN_WAIT ||
(s == SOCK_CLOSE_WAIT && !available()));
}
return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
(s == SnSR::CLOSE_WAIT && !available()));
}
uint8_t Client::status() {
if (_sock == 255) {
return SOCK_CLOSED;
} else {
return getSn_SR(_sock);
}
return W5100.readSnSR(_sock);
}
// the next three functions are a hack so we can compare the client returned
@ -136,13 +124,13 @@ uint8_t Client::status() {
// library.
uint8_t Client::operator==(int p) {
return _sock == 255;
return !_connected;
}
uint8_t Client::operator!=(int p) {
return _sock != 255;
return _connected;
}
Client::operator bool() {
return _sock != 255;
return _connected;
}

View File

@ -1,17 +1,15 @@
#ifndef Client_h
#define Client_h
#ifndef client_h
#define client_h
#include "Print.h"
class Client : public Print {
private:
static uint16_t _srcport;
uint8_t _sock;
uint8_t *_ip;
uint16_t _port;
public:
Client();
Client(uint8_t);
Client(uint8_t *, uint16_t);
uint8_t status();
uint8_t connect();
virtual void write(uint8_t);
@ -25,7 +23,15 @@ public:
uint8_t operator==(int);
uint8_t operator!=(int);
operator bool();
friend class Server;
private:
static uint16_t _srcport;
bool _connected;
uint8_t _sock;
uint8_t *_ip;
uint16_t _port;
};
#endif

View File

@ -1,13 +1,11 @@
extern "C" {
#include "types.h"
#include "w5100.h"
}
#include "Ethernet.h"
#include "ethernet.h"
// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, 0, 0, 0 };
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 };
uint8_t EthernetClass::_state[MAX_SOCK_NUM] = {
0, 0, 0, 0 };
uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
0, 0, 0, 0 };
void EthernetClass::begin(uint8_t *mac, uint8_t *ip)
{
@ -21,18 +19,18 @@ void EthernetClass::begin(uint8_t *mac, uint8_t *ip)
void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway)
{
uint8_t subnet[] = { 255, 255, 255, 0 };
uint8_t subnet[] = {
255, 255, 255, 0 };
begin(mac, ip, gateway, subnet);
}
void EthernetClass::begin(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
{
iinchip_init();
sysinit(0x55, 0x55);
setSHAR(mac);
setSIPR(ip);
setGAR(gateway);
setSUBR(subnet);
W5100.init();
W5100.setMACAddress(mac);
W5100.setIPAddress(ip);
W5100.setGatewayIp(gateway);
W5100.setSubnetMask(subnet);
}
EthernetClass Ethernet;

View File

@ -1,9 +1,12 @@
#ifndef Ethernet_h
#define Ethernet_h
#ifndef ethernet_h
#define ethernet_h
#include <inttypes.h>
#include "Client.h"
#include "Server.h"
//#include "w5100.h"
#include "client.h"
#include "server.h"
#define MAX_SOCK_NUM 4
class EthernetClass {
private:

View File

@ -1,13 +1,12 @@
extern "C" {
#include "types.h"
#include "w5100.h"
#include "socket.h"
extern "C" {
#include "string.h"
}
#include "Ethernet.h"
#include "Client.h"
#include "Server.h"
#include "ethernet.h"
#include "client.h"
#include "server.h"
Server::Server(uint16_t port)
{
@ -18,8 +17,8 @@ void Server::begin()
{
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
Client client(sock);
if (client.status() == SOCK_CLOSED) {
socket(sock, Sn_MR_TCP, _port, 0);
if (client.status() == SnSR::CLOSED) {
socket(sock, SnMR::TCP, _port, 0);
listen(sock);
EthernetClass::_server_port[sock] = _port;
break;
@ -35,9 +34,10 @@ void Server::accept()
Client client(sock);
if (EthernetClass::_server_port[sock] == _port) {
if (client.status() == SOCK_LISTEN) {
if (client.status() == SnSR::LISTEN) {
listening = 1;
} else if (client.status() == SOCK_CLOSE_WAIT && !client.available()) {
}
else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
client.stop();
}
}
@ -55,7 +55,7 @@ Client Server::available()
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
Client client(sock);
if (EthernetClass::_server_port[sock] == _port &&
client.status() == SOCK_ESTABLISHED) {
client.status() == SnSR::ESTABLISHED) {
if (client.available()) {
// XXX: don't always pick the lowest numbered socket.
return client;
@ -63,7 +63,7 @@ Client Server::available()
}
}
return Client(255);
return Client();
}
void Server::write(uint8_t b)
@ -84,7 +84,7 @@ void Server::write(const uint8_t *buffer, size_t size)
Client client(sock);
if (EthernetClass::_server_port[sock] == _port &&
client.status() == SOCK_ESTABLISHED) {
client.status() == SnSR::ESTABLISHED) {
client.write(buffer, size);
}
}

View File

@ -1,15 +1,12 @@
#ifndef Server_h
#define Server_h
extern "C" {
#include "utility/types.h"
}
#ifndef server_h
#define server_h
#include "Print.h"
class Client;
class Server : public Print {
class Server :
public Print {
private:
uint16_t _port;
void accept();

129
libraries/Ethernet/Udp.cpp Normal file
View File

@ -0,0 +1,129 @@
/*
* 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 "w5100.h"
#include "socket.h"
#include "ethernet.h"
#include "udp.h"
/* Start UDP socket, listening at local port PORT */
void UdpClass::begin(uint16_t port) {
_port = port;
_sock = 0; //TODO: should not be hardcoded
socket(_sock, SnMR::UDP, _port, 0);
}
/* Send packet contained in buf of length len to peer at specified ip, and port */
/* Use this function to transmit binary data that might contain 0x00 bytes*/
/* This function returns sent data size for success else -1. */
uint16_t UdpClass::sendPacket(uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
return sendto(_sock,(const uint8_t *)buf,len,ip,port);
}
/* Send zero-terminated string str as packet to peer at specified ip, and port */
/* This function returns sent data size for success else -1. */
uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
// compute strlen
const char *s;
for(s = str; *s; ++s);
uint16_t len = (s-str);
// send packet
return sendto(_sock,(const uint8_t *)str,len,ip,port);
}
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
* returned value includes 8 byte UDP header!*/
int UdpClass::available() {
return W5100.getRXReceivedSize(_sock);
}
/* Read a received packet into buffer buf (which is of maximum length len); */
/* store calling ip and port as well. Call available() to make sure data is ready first. */
/* NOTE: I don't believe len is ever checked in implementation of recvfrom(),*/
/* so it's easy to overflow buffer. so we check and truncate. */
/* returns number of bytes read, or negative number of bytes we would have needed if we truncated */
int UdpClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
int packetLen = available()-8; //skip UDP header;
if(packetLen < 0 ) return 0; // no real data here
if(packetLen > (int)bufLen) {
//packet is too large - truncate
//HACK - hand-parse the UDP packet using TCP recv method
uint8_t tmpBuf[8];
int i;
//read 8 header bytes and get IP and port from it
recv(_sock,tmpBuf,8);
ip[0] = tmpBuf[0];
ip[1] = tmpBuf[1];
ip[2] = tmpBuf[2];
ip[3] = tmpBuf[3];
*port = tmpBuf[4];
*port = (*port << 8) + tmpBuf[5];
//now copy first (bufLen) bytes into buf
for(i=0;i<(int)bufLen;i++) {
recv(_sock,tmpBuf,1);
buf[i]=tmpBuf[0];
}
//and just read the rest byte by byte and throw it away
while(available()) {
recv(_sock,tmpBuf,1);
}
return (-1*packetLen);
//ALTERNATIVE: requires stdlib - takes a bunch of space
/*//create new buffer and read everything into it
uint8_t * tmpBuf = (uint8_t *)malloc(packetLen);
recvfrom(_sock,tmpBuf,packetLen,ip,port);
if(!tmpBuf) return 0; //couldn't allocate
// copy first bufLen bytes
for(unsigned int i=0; i<bufLen; i++) {
buf[i]=tmpBuf[i];
}
//free temp buffer
free(tmpBuf);
*/
}
return recvfrom(_sock,buf,bufLen,ip,port);
}
/* Read a received packet, throw away peer's ip and port. See note above. */
int UdpClass::readPacket(uint8_t * buf, uint16_t len) {
uint8_t ip[4];
uint16_t port[1];
return recvfrom(_sock,buf,len,ip,port);
}
/* Create one global object */
UdpClass Udp;

60
libraries/Ethernet/Udp.h Normal file
View File

@ -0,0 +1,60 @@
/*
* 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 udp_h
#define udp_h
#define UDP_TX_PACKET_MAX_SIZE 24
class UdpClass {
private:
uint8_t _sock; // socket ID for Wiz5100
uint16_t _port; // local port to listen on
public:
void begin(uint16_t); // initialize, start listening on specified port
int available(); // has data been received?
// C-style buffer-oriented functions
uint16_t sendPacket(uint8_t *, uint16_t, uint8_t *, uint16_t); //send a packet to specified peer
uint16_t sendPacket(const char[], uint8_t *, uint16_t); //send a string as a packet to specified peer
int readPacket(uint8_t *, uint16_t); // read a received packet
int readPacket(uint8_t *, uint16_t, uint8_t *, uint16_t *); // read a received packet, also return sender's ip and port
};
extern UdpClass Udp;
#endif

View File

@ -17,6 +17,7 @@
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.

View File

@ -19,7 +19,7 @@
*/
// include the Ethernet library
#include <SPI.h>
#include <Ethernet.h>
// assign a MAC address for the ethernet controller.

View File

@ -19,7 +19,7 @@
*/
// include the Ethernet library
#include <SPI.h>
#include <Ethernet.h>
// pin that the pushButton is connected to:

View File

@ -11,6 +11,8 @@
by David A. Mellis
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.

View File

@ -13,7 +13,7 @@
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.

View File

@ -1,558 +0,0 @@
/*
*
@file socket.c
@brief setting chip register for socket
last update : 2008. Jan
*
*/
#include "types.h"
#include "w5100.h"
#include "socket.h"
static uint16 local_port;
/**
@brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
@return 1 for sucess else 0.
*/
uint8 socket(
SOCKET s, /**< for socket number */
uint8 protocol, /**< for socket protocol */
uint16 port, /**< the source port for the socket */
uint8 flag /**< the option for the socket */
)
{
uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
printf("socket()\r\n");
#endif
if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
{
close(s);
IINCHIP_WRITE(Sn_MR(s),protocol | flag);
if (port != 0) {
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
} else {
local_port++; // if don't set the source port, set local_port number.
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
}
IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
ret = 1;
}
else
{
ret = 0;
}
#ifdef __DEF_IINCHIP_DBG__
printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
#endif
return ret;
}
/**
@brief This function close the socket and parameter is "s" which represent the socket number
*/
void close(SOCKET s)
{
#ifdef __DEF_IINCHIP_DBG__
printf("close()\r\n");
#endif
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
/* +2008.01 [hwkim]: clear interrupt */
#ifdef __DEF_IINCHIP_INT__
/* m2008.01 [bj] : all clear */
putISR(s, 0x00);
#else
/* m2008.01 [bj] : all clear */
IINCHIP_WRITE(Sn_IR(s), 0xFF);
#endif
}
/**
@brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
@return 1 for success else 0.
*/
uint8 listen(
SOCKET s /**< the socket number */
)
{
uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
printf("listen()\r\n");
#endif
if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
{
IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
ret = 1;
}
else
{
ret = 0;
#ifdef __DEF_IINCHIP_DBG__
printf("Fail[invalid ip,port]\r\n");
#endif
}
return ret;
}
/**
@brief This function established the connection for the channel in Active (client) mode.
This function waits for the untill the connection is established.
@return 1 for success else 0.
*/
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
printf("connect()\r\n");
#endif
if
(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00)
)
{
ret = 0;
#ifdef __DEF_IINCHIP_DBG__
printf("Fail[invalid ip,port]\r\n");
#endif
}
else
{
ret = 1;
// set destination IP
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
/* m2008.01 [bj] : wait for completion */
while ( IINCHIP_READ(Sn_CR(s)) ) ;
}
return ret;
}
/**
@brief This function used for disconnect the socket and parameter is "s" which represent the socket number
@return 1 for success else 0.
*/
void disconnect(SOCKET s)
{
#ifdef __DEF_IINCHIP_DBG__
printf("disconnect()\r\n");
#endif
IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
}
/**
@brief This function used to send the data in TCP mode
@return 1 for success else 0.
*/
uint16 send(
SOCKET s, /**< the socket index */
const uint8 * buf, /**< a pointer to data */
uint16 len /**< the data size to be send */
)
{
uint8 status=0;
uint16 ret=0;
uint16 freesize=0;
#ifdef __DEF_IINCHIP_DBG__
printf("send()\r\n");
#endif
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
// if freebuf is available, start.
do
{
freesize = getSn_TX_FSR(s);
status = IINCHIP_READ(Sn_SR(s));
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
{
ret = 0;
break;
}
#ifdef __DEF_IINCHIP_DBG__
printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
#endif
} while (freesize < ret);
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
/* +2008.01 bj */
#ifdef __DEF_IINCHIP_INT__
while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
#else
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
#endif
{
/* m2008.01 [bj] : reduce code */
if ( IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED )
{
#ifdef __DEF_IINCHIP_DBG__
printf("SOCK_CLOSED.\r\n");
#endif
close(s);
return 0;
}
}
/* +2008.01 bj */
#ifdef __DEF_IINCHIP_INT__
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
#else
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
#endif
return ret;
}
/**
@brief This function is an application I/F function which is used to receive the data in TCP mode.
It continues to wait for data as much as the application wants to receive.
@return received data size for success else -1.
*/
uint16 recv(
SOCKET s, /**< socket index */
uint8 * buf, /**< a pointer to copy the data to be received */
uint16 len /**< the data size to be read */
)
{
uint16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
printf("recv()\r\n");
#endif
if ( len > 0 )
{
recv_data_processing(s, buf, len);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
ret = len;
}
return ret;
}
/**
@brief This function is an application I/F function which is used to send the data for other then TCP mode.
Unlike TCP transmission, The peer's destination address and the port is needed.
@return This function return send data size for success else -1.
*/
uint16 sendto(
SOCKET s, /**< socket index */
const uint8 * buf, /**< a pointer to the data */
uint16 len, /**< the data size to send */
uint8 * addr, /**< the peer's Destination IP address */
uint16 port /**< the peer's destination port number */
)
{
// uint8 status=0;
// uint8 isr=0;
uint16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
printf("sendto()\r\n");
#endif
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
if
(
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
((port == 0x00)) ||(ret == 0)
)
{
/* +2008.01 [bj] : added return value */
ret = 0;
#ifdef __DEF_IINCHIP_DBG__
printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
printf("Fail[invalid ip,port]\r\n");
#endif
}
else
{
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
/* +2008.01 bj */
#ifdef __DEF_IINCHIP_INT__
while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
#else
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
#endif
{
#ifdef __DEF_IINCHIP_INT__
if (getISR(s) & Sn_IR_TIMEOUT)
#else
if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
#endif
{
#ifdef __DEF_IINCHIP_DBG__
printf("send fail.\r\n");
#endif
/* +2008.01 [bj]: clear interrupt */
#ifdef __DEF_IINCHIP_INT__
putISR(s, getISR(s) & ~(Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
#else
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
#endif
return 0;
}
}
/* +2008.01 bj */
#ifdef __DEF_IINCHIP_INT__
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
#else
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
#endif
}
return ret;
}
/**
@brief This function is an application I/F function which is used to receive the data in other then
TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
@return This function return received data size for success else -1.
*/
uint16 recvfrom(
SOCKET s, /**< the socket number */
uint8 * buf, /**< a pointer to copy the data to be received */
uint16 len, /**< the data size to read */
uint8 * addr, /**< a pointer to store the peer's IP address */
uint16 *port /**< a pointer to store the peer's port number. */
)
{
uint8 head[8];
uint16 data_len=0;
uint16 ptr=0;
#ifdef __DEF_IINCHIP_DBG__
printf("recvfrom()\r\n");
#endif
if ( len > 0 )
{
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
#ifdef __DEF_IINCHIP_DBG__
printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
#endif
switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
{
case Sn_MR_UDP :
read_data(s, (uint8 *)ptr, head, 0x08);
ptr += 8;
// read peer's IP address, port number.
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
data_len = head[6];
data_len = (data_len << 8) + head[7];
#ifdef __DEF_IINCHIP_DBG__
printf("UDP msg arrived\r\n");
printf("source Port : %d\r\n", *port);
printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
#endif
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
case Sn_MR_IPRAW :
read_data(s, (uint8 *)ptr, head, 0x06);
ptr += 6;
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
data_len = head[4];
data_len = (data_len << 8) + head[5];
#ifdef __DEF_IINCHIP_DBG__
printf("IP RAW msg arrived\r\n");
printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
#endif
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
case Sn_MR_MACRAW :
read_data(s,(uint8*)ptr,head,2);
ptr+=2;
data_len = head[0];
data_len = (data_len<<8) + head[1] - 2;
read_data(s,(uint8*) ptr,buf,data_len);
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
#ifdef __DEF_IINCHIP_DGB__
printf("MAC RAW msg arrived\r\n");
printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
printf("src mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
printf("type =%.2X%.2X\r\n",buf[12],buf[13]);
#endif
break;
default :
break;
}
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
}
#ifdef __DEF_IINCHIP_DBG__
printf("recvfrom() end ..\r\n");
#endif
return data_len;
}
uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len)
{
uint8 status=0;
// uint8 isr=0;
uint16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
printf("igmpsend()\r\n");
#endif
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
if (ret == 0)
{
;
#ifdef __DEF_IINCHIP_DBG__
printf("%d Fail[%d]\r\n",len);
#endif
}
else
{
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
/* +2008.01 bj */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
/* +2008.01 bj */
#ifdef __DEF_IINCHIP_INT__
while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
#else
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
#endif
{
status = IINCHIP_READ(Sn_SR(s));
#ifdef __DEF_IINCHIP_INT__
if (getISR(s) & Sn_IR_TIMEOUT)
#else
if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
#endif
{
#ifdef __DEF_IINCHIP_DBG__
printf("igmpsend fail.\r\n");
#endif
/* in case of igmp, if send fails, then socket closed */
/* if you want change, remove this code. */
close(s);
/* ----- */
return 0;
}
}
/* +2008.01 bj */
#ifdef __DEF_IINCHIP_INT__
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
#else
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
#endif
}
return ret;
}

View File

@ -0,0 +1,314 @@
#include "w5100.h"
#include "socket.h"
static uint16_t local_port;
/**
* @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
* @return 1 for success else 0.
*/
uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
{
uint8_t ret;
if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE))
{
close(s);
W5100.writeSnMR(s, protocol | flag);
if (port != 0) {
W5100.writeSnPORT(s, port);
}
else {
local_port++; // if don't set the source port, set local_port number.
W5100.writeSnPORT(s, local_port);
}
W5100.execCmdSn(s, Sock_OPEN);
return 1;
}
return 0;
}
/**
* @brief This function close the socket and parameter is "s" which represent the socket number
*/
void close(SOCKET s)
{
W5100.execCmdSn(s, Sock_CLOSE);
W5100.writeSnIR(s, 0xFF);
}
/**
* @brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
* @return 1 for success else 0.
*/
uint8_t listen(SOCKET s)
{
if (W5100.readSnSR(s) != SnSR::INIT)
return 0;
W5100.execCmdSn(s, Sock_LISTEN);
return 1;
}
/**
* @brief This function established the connection for the channel in Active (client) mode.
* This function waits for the untill the connection is established.
*
* @return 1 for success else 0.
*/
uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
{
if
(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00)
)
return 0;
// set destination IP
W5100.writeSnDIPR(s, addr);
W5100.writeSnDPORT(s, port);
W5100.execCmdSn(s, Sock_CONNECT);
return 1;
}
/**
* @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
* @return 1 for success else 0.
*/
void disconnect(SOCKET s)
{
W5100.execCmdSn(s, Sock_DISCON);
}
/**
* @brief This function used to send the data in TCP mode
* @return 1 for success else 0.
*/
uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
{
uint8_t status=0;
uint16_t ret=0;
uint16_t freesize=0;
if (len > W5100.SSIZE)
ret = W5100.SSIZE; // check size not to exceed MAX size.
else
ret = len;
// if freebuf is available, start.
do
{
freesize = W5100.getTXFreeSize(s);
status = W5100.readSnSR(s);
if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
{
ret = 0;
break;
}
}
while (freesize < ret);
// copy data
W5100.send_data_processing(s, (uint8_t *)buf, ret);
W5100.execCmdSn(s, Sock_SEND);
/* +2008.01 bj */
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
{
/* m2008.01 [bj] : reduce code */
if ( W5100.readSnSR(s) == SnSR::CLOSED )
{
close(s);
return 0;
}
}
/* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK);
return ret;
}
/**
* @brief This function is an application I/F function which is used to receive the data in TCP mode.
* It continues to wait for data as much as the application wants to receive.
*
* @return received data size for success else -1.
*/
uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len)
{
uint16_t ret=0;
if ( len > 0 )
{
W5100.recv_data_processing(s, buf, len);
W5100.execCmdSn(s, Sock_RECV);
ret = len;
}
return ret;
}
/**
* @brief This function is an application I/F function which is used to send the data for other then TCP mode.
* Unlike TCP transmission, The peer's destination address and the port is needed.
*
* @return This function return send data size for success else -1.
*/
uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
{
uint16_t ret=0;
if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size.
else ret = len;
if
(
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
((port == 0x00)) ||(ret == 0)
)
{
/* +2008.01 [bj] : added return value */
ret = 0;
}
else
{
W5100.writeSnDIPR(s, addr);
W5100.writeSnDPORT(s, port);
// copy data
W5100.send_data_processing(s, (uint8_t *)buf, ret);
W5100.execCmdSn(s, Sock_SEND);
/* +2008.01 bj */
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
{
if (W5100.readSnIR(s) & SnIR::TIMEOUT)
{
/* +2008.01 [bj]: clear interrupt */
W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
return 0;
}
}
/* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK);
}
return ret;
}
/**
* @brief This function is an application I/F function which is used to receive the data in other then
* TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
*
* @return This function return received data size for success else -1.
*/
uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port)
{
uint8_t head[8];
uint16_t data_len=0;
uint16_t ptr=0;
if ( len > 0 )
{
ptr = W5100.readSnRX_RD(s);
switch (W5100.readSnMR(s) & 0x07)
{
case SnMR::UDP :
W5100.read_data(s, (uint8_t *)ptr, head, 0x08);
ptr += 8;
// read peer's IP address, port number.
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
data_len = head[6];
data_len = (data_len << 8) + head[7];
W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy.
ptr += data_len;
W5100.writeSnRX_RD(s, ptr);
break;
case SnMR::IPRAW :
W5100.read_data(s, (uint8_t *)ptr, head, 0x06);
ptr += 6;
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
data_len = head[4];
data_len = (data_len << 8) + head[5];
W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy.
ptr += data_len;
W5100.writeSnRX_RD(s, ptr);
break;
case SnMR::MACRAW:
W5100.read_data(s,(uint8_t*)ptr,head,2);
ptr+=2;
data_len = head[0];
data_len = (data_len<<8) + head[1] - 2;
W5100.read_data(s,(uint8_t*) ptr,buf,data_len);
ptr += data_len;
W5100.writeSnRX_RD(s, ptr);
break;
default :
break;
}
W5100.execCmdSn(s, Sock_RECV);
}
return data_len;
}
uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
{
uint8_t status=0;
uint16_t ret=0;
if (len > W5100.SSIZE)
ret = W5100.SSIZE; // check size not to exceed MAX size.
else
ret = len;
if (ret == 0)
return 0;
W5100.send_data_processing(s, (uint8_t *)buf, ret);
W5100.execCmdSn(s, Sock_SEND);
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
{
status = W5100.readSnSR(s);
if (W5100.readSnIR(s) & SnIR::TIMEOUT)
{
/* in case of igmp, if send fails, then socket closed */
/* if you want change, remove this code. */
close(s);
return 0;
}
}
W5100.writeSnIR(s, SnIR::SEND_OK);
return ret;
}

View File

@ -1,23 +1,19 @@
/*
*
@file socket.h
@brief define function of socket API
*
*/
#ifndef _SOCKET_H_
#define _SOCKET_H_
extern uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag); // Opens a socket(TCP or UDP or IP_RAW mode)
extern void close(SOCKET s); // Close socket
extern uint8 connect(SOCKET s, uint8 * addr, uint16 port); // Establish TCP connection (Active connection)
extern void disconnect(SOCKET s); // disconnect the connection
extern uint8 listen(SOCKET s); // Establish TCP connection (Passive connection)
extern uint16 send(SOCKET s, const uint8 * buf, uint16 len); // Send data (TCP)
extern uint16 recv(SOCKET s, uint8 * buf, uint16 len); // Receive data (TCP)
extern uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port); // Send data (UDP/IP RAW)
extern uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port); // Receive data (UDP/IP RAW)
#include "w5100.h"
extern uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag); // Opens a socket(TCP or UDP or IP_RAW mode)
extern void close(SOCKET s); // Close socket
extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TCP connection (Active connection)
extern void disconnect(SOCKET s); // disconnect the connection
extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection)
extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP)
extern uint16_t recv(SOCKET s, uint8_t * buf, uint16_t len); // Receive data (TCP)
extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW)
extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW)
extern uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);
extern uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len);
#endif
/* _SOCKET_H_ */

View File

@ -1,58 +0,0 @@
//-----------------------------------------------------------------------------
//AVR Mega168 SPI HAL
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define SPI0_SS_BIT BIT2
#define SPI0_SS_DDR DDRB
#define SPI0_SS_PORT PORTB
#define SPI0_SCLK_BIT BIT5
#define SPI0_SCLK_DDR DDRB
#define SPI0_SCLK_PORT PORTB
#define SPI0_MOSI_BIT BIT3
#define SPI0_MOSI_DDR DDRB
#define SPI0_MOSI_PORT PORTB
#define SPI0_MISO_BIT BIT4
#define SPI0_MISO_DDR DDRB
#define SPI0_MISO_PORT PORTB
#define SPI0_WaitForReceive()
#define SPI0_RxData() (SPDR)
#define SPI0_TxData(Data) (SPDR = Data)
#define SPI0_WaitForSend() while( (SPSR & 0x80)==0x00 )
#define SPI0_SendByte(Data) SPI0_TxData(Data);SPI0_WaitForSend()
#define SPI0_RecvBute() SPI0_RxData()
// PB4(MISO), PB3(MOSI), PB5(SCK), PB2(/SS) // CS=1, waiting for SPI start // SPI mode 0, 4MHz
#define SPI0_Init() DDRB |= SPI0_SS_BIT|SPI0_SCLK_BIT|SPI0_MOSI_BIT;\
PORTB |= SPI0_SS_BIT; PORTB &= ~(SPI0_SCLK_BIT|SPI0_MOSI_BIT);\
SPCR = 0x50
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//IInChip SPI HAL
#define IINCHIP_SpiInit SPI0_Init
#define IINCHIP_SpiSendData SPI0_SendByte
#define IINCHIP_SpiRecvData SPI0_RxData
#define IINCHIP_CS_BIT BIT2
#define IINCHIP_CS_DDR DDRB
#define IINCHIP_CS_PORT PORTB
#define IINCHIP_CSInit() (IINCHIP_CS_DDR |= IINCHIP_CS_BIT)
#define IINCHIP_CSon() (IINCHIP_CS_PORT |= IINCHIP_CS_BIT)
#define IINCHIP_CSoff() (IINCHIP_CS_PORT &= ~IINCHIP_CS_BIT)
//-----------------------------------------------------------------------------

View File

@ -1,165 +0,0 @@
/*
*
@file type.h
*
*/
#ifndef _TYPE_H_
#define _TYPE_H_
/***************************************************
* attribute for mcu ( types, ... )
***************************************************/
//#include "mcu_define.h"
#define __MCU_AVR__ 1
#define __MCU_TYPE__ __MCU_AVR__
//---- Refer "Rom File Maker Manual Vx.x.pdf"
#include <avr/pgmspace.h>
#define _ENDIAN_LITTLE_ 0 /**< This must be defined if system is little-endian alignment */
#define _ENDIAN_BIG_ 1
#define SYSTEM_ENDIAN _ENDIAN_LITTLE_
#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
#define CLK_CPU F_CPU /**< 8Mhz(for serial) */
/* ## __DEF_IINCHIP_xxx__ : define option for iinchip driver *****************/
//#define __DEF_IINCHIP_DBG__ /* involve debug code in driver (socket.c) */
//#define __DEF_IINCHIP_INT__ /**< involve interrupt service routine (socket.c) */
//#define __DEF_IINCHIP_PPP__ /* involve pppoe routine (socket.c) */
/* If it is defined, the source files(md5.h,md5.c) must be included in your project.
Otherwize, the source files must be removed in your project. */
#define __DEF_IINCHIP_DIRECT_MODE__ 1
#define __DEF_IINCHIP_INDIRECT_MODE__ 2
#define __DEF_IINCHIP_SPI_MODE__ 3
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__ /*Enable SPI_mode*/
/**
@brief __DEF_IINCHIP_MAP_xxx__ : define memory map for iinchip
*/
#define __DEF_IINCHIP_MAP_BASE__ 0x8000
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
#define COMMON_BASE __DEF_IINCHIP_MAP_BASE__
#else
#define COMMON_BASE 0x0000
#endif
#define __DEF_IINCHIP_MAP_TXBUF__ (COMMON_BASE + 0x4000) /* Internal Tx buffer address of the iinchip */
#define __DEF_IINCHIP_MAP_RXBUF__ (COMMON_BASE + 0x6000) /* Internal Rx buffer address of the iinchip */
#if (__MCU_TYPE__ == __MCU_AVR__)
#ifdef __DEF_IINCHIP_INT__
// iinchip use external interrupt 4
#define IINCHIP_ISR_DISABLE() (EIMSK &= ~(0x10))
#define IINCHIP_ISR_ENABLE() (EIMSK |= 0x10)
#define IINCHIP_ISR_GET(X) (X = EIMSK)
#define IINCHIP_ISR_SET(X) (EIMSK = X)
#else
#define IINCHIP_ISR_DISABLE()
#define IINCHIP_ISR_ENABLE()
#define IINCHIP_ISR_GET(X)
#define IINCHIP_ISR_SET(X)
#endif
#else
#error "unknown MCU type"
#endif
#ifndef NULL
#define NULL ((void *) 0)
#endif
//typedef enum { false, true } bool;
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
/**
* The 8-bit signed data type.
*/
typedef char int8;
/**
* The volatile 8-bit signed data type.
*/
typedef volatile char vint8;
/**
* The 8-bit unsigned data type.
*/
typedef unsigned char uint8;
/**
* The volatile 8-bit unsigned data type.
*/
typedef volatile unsigned char vuint8;
/**
* The 16-bit signed data type.
*/
typedef int int16;
/**
* The volatile 16-bit signed data type.
*/
typedef volatile int vint16;
/**
* The 16-bit unsigned data type.
*/
typedef unsigned int uint16;
/**
* The volatile 16-bit unsigned data type.
*/
typedef volatile unsigned int vuint16;
/**
* The 32-bit signed data type.
*/
typedef long int32;
/**
* The volatile 32-bit signed data type.
*/
typedef volatile long vint32;
/**
* The 32-bit unsigned data type.
*/
typedef unsigned long uint32;
/**
* The volatile 32-bit unsigned data type.
*/
typedef volatile unsigned long vuint32;
/* bsd */
typedef uint8 u_char; /**< 8-bit value */
typedef uint8 SOCKET;
typedef uint16 u_short; /**< 16-bit value */
typedef uint16 u_int; /**< 16-bit value */
typedef uint32 u_long; /**< 32-bit value */
typedef union _un_l2cval {
u_long lVal;
u_char cVal[4];
}un_l2cval;
typedef union _un_i2cval {
u_int iVal;
u_char cVal[2];
}un_i2cval;
/** global define */
#define FW_VERSION 0x01010000 /* System F/W Version : 1.1.0.0 */
#define HW_VERSION 0x01000000
#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF+TX_RX_MAX_BUF_SIZE)
#define UART_DEVICE_CNT 1 /**< UART device number */
/* #define SUPPORT_UART_ONE */
#endif /* _TYPE_H_ */

View File

@ -1,1302 +0,0 @@
/*
* (c)COPYRIGHT
* ALL RIGHT RESERVED
*
* FileName : w5100.c
* Revision History :
* ---------- ------- ------------------------------------------------
* Date version Description
* ---------- ------- ------------------------------------------------
* 01/25/2007 1.1 Bug is Fixed in the Indirect Mode
* : Memory mapping error
* ---------- ------- ------------------------------------------------
* 01/08/2008 1.2 Modification of Socket Command Part
* : Check if the appropriately performed after writing Sn_CR
*
* Modification of SPI Part
* : SPI code changed by adding 'spi.h'.
* : Change control type for SPI port from byte to bit.
* ---------- ------- ------------------------------------------------
* 01/15/2008 1.3 Bug is Fixed in the pppinit() fuction.
* : do not clear interrupt value, so fixed.
*
* Modification of ISR
* : Do not exit ISR, if there is interrupt.
* ---------- ------- ------------------------------------------------
* 03/21/2008 1.4 Modification of SetMR() function
* : Use IINCHIP_WRITE() function in Direct or SPI mode.
* ---------- ------- ------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
// #include <avr/io.h>
#include "types.h"
#include "socket.h"
#include "w5100.h"
#ifdef __DEF_IINCHIP_PPP__
#include "md5.h"
#endif
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
#include "spi.h" //+2007113[jhpark]
#endif
static uint8 I_STATUS[MAX_SOCK_NUM];
static uint16 SMASK[MAX_SOCK_NUM]; /**< Variable for Tx buffer MASK in each channel */
static uint16 RMASK[MAX_SOCK_NUM]; /**< Variable for Rx buffer MASK in each channel */
static uint16 SSIZE[MAX_SOCK_NUM]; /**< Max Tx buffer size by each channel */
static uint16 RSIZE[MAX_SOCK_NUM]; /**< Max Rx buffer size by each channel */
static uint16 SBUFBASEADDRESS[MAX_SOCK_NUM]; /**< Tx buffer base address by each channel */
static uint16 RBUFBASEADDRESS[MAX_SOCK_NUM]; /**< Rx buffer base address by each channel */
uint8 getISR(uint8 s)
{
return I_STATUS[s];
}
void putISR(uint8 s, uint8 val)
{
I_STATUS[s] = val;
}
uint16 getIINCHIP_RxMAX(uint8 s)
{
return RSIZE[s];
}
uint16 getIINCHIP_TxMAX(uint8 s)
{
return SSIZE[s];
}
uint16 getIINCHIP_RxMASK(uint8 s)
{
return RMASK[s];
}
uint16 getIINCHIP_TxMASK(uint8 s)
{
return SMASK[s];
}
uint16 getIINCHIP_RxBASE(uint8 s)
{
return RBUFBASEADDRESS[s];
}
uint16 getIINCHIP_TxBASE(uint8 s)
{
return SBUFBASEADDRESS[s];
}
/**
@brief This function writes the data into W5100 registers.
*/
uint8 IINCHIP_WRITE(uint16 addr,uint8 data)
{
// DIRECT MODE I/F
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
*((vuint8*)(addr)) = data;
IINCHIP_ISR_ENABLE();
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__) /* INDIRECT MODE I/F */
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
*((vuint8*)IDM_DR) = data;
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
IINCHIP_ISR_DISABLE();
IINCHIP_SpiInit();
//SPI MODE I/F
IINCHIP_CSoff(); // CS=0, SPI start
IINCHIP_SpiSendData(0xF0);
IINCHIP_SpiSendData((addr & 0xFF00) >> 8);
IINCHIP_SpiSendData(addr & 0x00FF);
IINCHIP_SpiSendData(data);
IINCHIP_CSon();
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return 1;
}
/**
@brief This function reads the value from W5100 registers.
*/
uint8 IINCHIP_READ(uint16 addr)
{
uint8 data;
// DIRECT MODE I/F
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
data = *((vuint8*)(addr));
IINCHIP_ISR_ENABLE();
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
data = *((vuint8*)IDM_DR);
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
IINCHIP_ISR_DISABLE();
IINCHIP_SpiInit();
IINCHIP_CSoff(); // CS=0, SPI start
IINCHIP_SpiSendData(0x0F);
IINCHIP_SpiSendData((addr & 0xFF00) >> 8);
IINCHIP_SpiSendData(addr & 0x00FF);
IINCHIP_SpiSendData(0);
data = IINCHIP_SpiRecvData();
IINCHIP_CSon(); // SPI end
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return data;
}
/**
@brief This function writes into W5100 memory(Buffer)
*/
uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
memcpy((uint8 *)addr, buf, len);
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
uint16 idx = 0;
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
for (idx = 0; idx < len ; idx++) *((vuint8*)IDM_DR) = buf[idx];
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
uint16 idx = 0;
IINCHIP_ISR_DISABLE();
IINCHIP_SpiInit();
//SPI MODE I/F
for(idx=0;idx<len;idx++)
{
IINCHIP_CSoff(); // CS=0, SPI start
IINCHIP_SpiSendData(0xF0);
IINCHIP_SpiSendData(((addr+idx) & 0xFF00) >> 8);
IINCHIP_SpiSendData((addr+idx) & 0x00FF);
IINCHIP_SpiSendData(buf[idx]);
IINCHIP_CSon(); // CS=0, SPI end
}
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return len;
}
/**
@brief This function reads into W5100 memory(Buffer)
*/
uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
memcpy(buf, (uint8 *)addr, len);
IINCHIP_ISR_ENABLE();
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
uint16 idx = 0;
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
for (idx = 0; idx < len ; idx++) buf[idx] = *((vuint8*)IDM_DR);
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
uint16 idx = 0;
IINCHIP_ISR_DISABLE();
IINCHIP_SpiInit();
for (idx=0; idx<len; idx++)
{
IINCHIP_CSoff(); // CS=0, SPI start
IINCHIP_SpiSendData(0x0F);
IINCHIP_SpiSendData(((addr+idx) & 0xFF00) >> 8);
IINCHIP_SpiSendData((addr+idx) & 0x00FF);
IINCHIP_SpiSendData(0);
buf[idx] = IINCHIP_SpiRecvData();
IINCHIP_CSon(); // CS=0, SPI end
}
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return len;
}
/**
@brief Socket interrupt routine
*/
#ifdef __DEF_IINCHIP_INT__
ISR(INT4_vect)
{
uint8 int_val;
IINCHIP_ISR_DISABLE();
int_val = IINCHIP_READ(IR);
/* +200801[bj] process all of interupt */
do {
/*---*/
if (int_val & IR_CONFLICT)
{
printf("IP conflict : %.2x\r\n", int_val);
}
if (int_val & IR_UNREACH)
{
printf("INT Port Unreachable : %.2x\r\n", int_val);
printf("UIPR0 : %d.%d.%d.%d\r\n", IINCHIP_READ(UIPR0), IINCHIP_READ(UIPR0+1), IINCHIP_READ(UIPR0+2), IINCHIP_READ(UIPR0+3));
printf("UPORT0 : %.2x %.2x\r\n", IINCHIP_READ(UPORT0), IINCHIP_READ(UPORT0+1));
}
/* +200801[bj] interrupt clear */
IINCHIP_WRITE(IR, 0xf0);
/*---*/
if (int_val & IR_SOCK(0))
{
/* +-200801[bj] save interrupt value*/
I_STATUS[0] |= IINCHIP_READ(Sn_IR(0)); // can be come to over two times.
IINCHIP_WRITE(Sn_IR(0), I_STATUS[0]);
/*---*/
}
if (int_val & IR_SOCK(1))
{
/* +-200801[bj] save interrupt value*/
I_STATUS[1] |= IINCHIP_READ(Sn_IR(1));
IINCHIP_WRITE(Sn_IR(1), I_STATUS[1]);
/*---*/
}
if (int_val & IR_SOCK(2))
{
/* +-200801[bj] save interrupt value*/
I_STATUS[2] |= IINCHIP_READ(Sn_IR(2));
IINCHIP_WRITE(Sn_IR(2), I_STATUS[2]);
/*---*/
}
if (int_val & IR_SOCK(3))
{
/* +-200801[bj] save interrupt value*/
I_STATUS[3] |= IINCHIP_READ(Sn_IR(3));
IINCHIP_WRITE(Sn_IR(3), I_STATUS[3]);
/*---*/
}
/* +-200801[bj] re-read interrupt value*/
int_val = IINCHIP_READ(IR);
/* +200801[bj] if exist, contiue to process */
} while (int_val != 0x00);
/*---*/
IINCHIP_ISR_ENABLE();
}
#endif
/**
@brief This function is for resetting of the iinchip. Initializes the iinchip to work in whether DIRECT or INDIRECT mode
*/
void iinchip_init(void)
{
setMR( MR_RST );
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
setMR( MR_IND | MR_AI );
#ifdef __DEF_IINCHIP_DBG__
printf("MR value is %d \r\n",IINCHIP_READ(MR));
#endif
#endif
}
/**
@brief This function set the transmit & receive buffer size as per the channels is used
Note for TMSR and RMSR bits are as follows\n
bit 1-0 : memory size of channel #0 \n
bit 3-2 : memory size of channel #1 \n
bit 5-4 : memory size of channel #2 \n
bit 7-6 : memory size of channel #3 \n\n
Maximum memory size for Tx, Rx in the W5100 is 8K Bytes,\n
In the range of 8KBytes, the memory size could be allocated dynamically by each channel.\n
Be attentive to sum of memory size shouldn't exceed 8Kbytes\n
and to data transmission and receiption from non-allocated channel may cause some problems.\n
If the 8KBytes memory is already assigned to centain channel, \n
other 3 channels couldn't be used, for there's no available memory.\n
If two 4KBytes memory are assigned to two each channels, \n
other 2 channels couldn't be used, for there's no available memory.\n
*/
void sysinit(
uint8 tx_size, /**< tx_size Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */
uint8 rx_size /**< rx_size Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */
)
{
int16 i;
int16 ssum,rsum;
#ifdef __DEF_IINCHIP_DBG__
printf("sysinit()\r\n");
#endif
ssum = 0;
rsum = 0;
IINCHIP_WRITE(TMSR,tx_size); /* Set Tx memory size for each channel */
IINCHIP_WRITE(RMSR,rx_size); /* Set Rx memory size for each channel */
SBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_TXBUF__); /* Set base address of Tx memory for channel #0 */
RBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_RXBUF__); /* Set base address of Rx memory for channel #0 */
#ifdef __DEF_IINCHIP_DBG__
printf("Channel : SEND MEM SIZE : RECV MEM SIZE\r\n");
#endif
for (i = 0 ; i < MAX_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel
{
SSIZE[i] = (int16)(0);
RSIZE[i] = (int16)(0);
if (ssum < 8192)
{
switch((tx_size >> i*2) & 0x03) // Set Tx memory size
{
case 0:
SSIZE[i] = (int16)(1024);
SMASK[i] = (uint16)(0x03FF);
break;
case 1:
SSIZE[i] = (int16)(2048);
SMASK[i] = (uint16)(0x07FF);
break;
case 2:
SSIZE[i] = (int16)(4096);
SMASK[i] = (uint16)(0x0FFF);
break;
case 3:
SSIZE[i] = (int16)(8192);
SMASK[i] = (uint16)(0x1FFF);
break;
}
}
if (rsum < 8192)
{
switch((rx_size >> i*2) & 0x03) // Set Rx memory size
{
case 0:
RSIZE[i] = (int16)(1024);
RMASK[i] = (uint16)(0x03FF);
break;
case 1:
RSIZE[i] = (int16)(2048);
RMASK[i] = (uint16)(0x07FF);
break;
case 2:
RSIZE[i] = (int16)(4096);
RMASK[i] = (uint16)(0x0FFF);
break;
case 3:
RSIZE[i] = (int16)(8192);
RMASK[i] = (uint16)(0x1FFF);
break;
}
}
ssum += SSIZE[i];
rsum += RSIZE[i];
if (i != 0) // Sets base address of Tx and Rx memory for channel #1,#2,#3
{
SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1];
RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1];
}
#ifdef __DEF_IINCHIP_DBG__
printf("%d : %.4x : %.4x : %.4x : %.4x\r\n", i, (uint16)SBUFBASEADDRESS[i], (uint16)RBUFBASEADDRESS[i], SSIZE[i], RSIZE[i]);
#endif
}
}
void setMR(uint8 val)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
*((volatile uint8*)(MR)) = val;
#else
/* DIRECT ACCESS */
IINCHIP_WRITE(MR,val);
#endif
}
/**
@brief This function sets up gateway IP address.
*/
void setGAR(
uint8 * addr /**< a pointer to a 4 -byte array responsible to set the Gateway IP address. */
)
{
IINCHIP_WRITE((GAR0 + 0),addr[0]);
IINCHIP_WRITE((GAR0 + 1),addr[1]);
IINCHIP_WRITE((GAR0 + 2),addr[2]);
IINCHIP_WRITE((GAR0 + 3),addr[3]);
}
void getGWIP(uint8 * addr)
{
addr[0] = IINCHIP_READ((GAR0 + 0));
addr[1] = IINCHIP_READ((GAR0 + 1));
addr[2] = IINCHIP_READ((GAR0 + 2));
addr[3] = IINCHIP_READ((GAR0 + 3));
}
/**
@brief It sets up SubnetMask address
*/
void setSUBR(
uint8 * addr /**< a pointer to a 4 -byte array responsible to set the SubnetMask address */
)
{
IINCHIP_WRITE((SUBR0 + 0),addr[0]);
IINCHIP_WRITE((SUBR0 + 1),addr[1]);
IINCHIP_WRITE((SUBR0 + 2),addr[2]);
IINCHIP_WRITE((SUBR0 + 3),addr[3]);
}
/**
@brief This function sets up MAC address.
*/
void setSHAR(
uint8 * addr /**< a pointer to a 6 -byte array responsible to set the MAC address. */
)
{
IINCHIP_WRITE((SHAR0 + 0),addr[0]);
IINCHIP_WRITE((SHAR0 + 1),addr[1]);
IINCHIP_WRITE((SHAR0 + 2),addr[2]);
IINCHIP_WRITE((SHAR0 + 3),addr[3]);
IINCHIP_WRITE((SHAR0 + 4),addr[4]);
IINCHIP_WRITE((SHAR0 + 5),addr[5]);
}
/**
@brief This function sets up Source IP address.
*/
void setSIPR(
uint8 * addr /**< a pointer to a 4 -byte array responsible to set the Source IP address. */
)
{
IINCHIP_WRITE((SIPR0 + 0),addr[0]);
IINCHIP_WRITE((SIPR0 + 1),addr[1]);
IINCHIP_WRITE((SIPR0 + 2),addr[2]);
IINCHIP_WRITE((SIPR0 + 3),addr[3]);
}
/**
@brief This function gets Interrupt register in common register.
*/
uint8 getIR( void )
{
return IINCHIP_READ(IR);
}
/**
@brief This function sets up Retransmission time.
If there is no response from the peer or delay in response then retransmission
will be there as per RTR (Retry Time-value Register)setting
*/
void setRTR(uint16 timeout)
{
IINCHIP_WRITE(RTR0,(uint8)((timeout & 0xff00) >> 8));
IINCHIP_WRITE((RTR0 + 1),(uint8)(timeout & 0x00ff));
}
/**
@brief This function set the number of Retransmission.
If there is no response from the peer or delay in response then recorded time
as per RTR & RCR register seeting then time out will occur.
*/
void setRCR(uint8 retry)
{
IINCHIP_WRITE(RCR,retry);
}
/**
@brief This function set the interrupt mask Enable/Disable appropriate Interrupt. ('1' : interrupt enable)
If any bit in IMR is set as '0' then there is not interrupt signal though the bit is
set in IR register.
*/
void setIMR(uint8 mask)
{
IINCHIP_WRITE(IMR,mask); // must be setted 0x10.
}
/**
@brief These below functions are used to get the Gateway, SubnetMask
and Source Hardware Address (MAC Address) and Source IP address
*/
void getGAR(uint8 * addr)
{
addr[0] = IINCHIP_READ(GAR0);
addr[1] = IINCHIP_READ(GAR0+1);
addr[2] = IINCHIP_READ(GAR0+2);
addr[3] = IINCHIP_READ(GAR0+3);
}
void getSUBR(uint8 * addr)
{
addr[0] = IINCHIP_READ(SUBR0);
addr[1] = IINCHIP_READ(SUBR0+1);
addr[2] = IINCHIP_READ(SUBR0+2);
addr[3] = IINCHIP_READ(SUBR0+3);
}
void getSHAR(uint8 * addr)
{
addr[0] = IINCHIP_READ(SHAR0);
addr[1] = IINCHIP_READ(SHAR0+1);
addr[2] = IINCHIP_READ(SHAR0+2);
addr[3] = IINCHIP_READ(SHAR0+3);
addr[4] = IINCHIP_READ(SHAR0+4);
addr[5] = IINCHIP_READ(SHAR0+5);
}
void getSIPR(uint8 * addr)
{
addr[0] = IINCHIP_READ(SIPR0);
addr[1] = IINCHIP_READ(SIPR0+1);
addr[2] = IINCHIP_READ(SIPR0+2);
addr[3] = IINCHIP_READ(SIPR0+3);
}
/**
@brief These below functions are used to get the Destination Hardware Address (MAC Address), Destination IP address and Destination Port.
*/
void getSn_DHAR(SOCKET s, uint8 * addr)
{
addr[0] = IINCHIP_READ(Sn_DHAR0(s));
addr[1] = IINCHIP_READ(Sn_DHAR0(s)+1);
addr[2] = IINCHIP_READ(Sn_DHAR0(s)+2);
addr[3] = IINCHIP_READ(Sn_DHAR0(s)+3);
addr[4] = IINCHIP_READ(Sn_DHAR0(s)+4);
addr[5] = IINCHIP_READ(Sn_DHAR0(s)+5);
}
void setSn_DHAR(SOCKET s, uint8 * addr)
{
IINCHIP_WRITE((Sn_DHAR0(s) + 0),addr[0]);
IINCHIP_WRITE((Sn_DHAR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DHAR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DHAR0(s) + 3),addr[3]);
IINCHIP_WRITE((Sn_DHAR0(s) + 4),addr[4]);
IINCHIP_WRITE((Sn_DHAR0(s) + 5),addr[5]);
}
void getSn_DIPR(SOCKET s, uint8 * addr)
{
addr[0] = IINCHIP_READ(Sn_DIPR0(s));
addr[1] = IINCHIP_READ(Sn_DIPR0(s)+1);
addr[2] = IINCHIP_READ(Sn_DIPR0(s)+2);
addr[3] = IINCHIP_READ(Sn_DIPR0(s)+3);
}
void setSn_DIPR(SOCKET s, uint8 * addr)
{
IINCHIP_WRITE((Sn_DIPR0(s) + 0),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
}
void getSn_DPORT(SOCKET s, uint8 * addr)
{
addr[0] = IINCHIP_READ(Sn_DPORT0(s));
addr[1] = IINCHIP_READ(Sn_DPORT0(s)+1);
}
void setSn_DPORT(SOCKET s, uint8 * addr)
{
IINCHIP_WRITE((Sn_DPORT0(s) + 0),addr[0]);
IINCHIP_WRITE((Sn_DPORT0(s) + 1),addr[1]);
}
/**
@brief This sets the maximum segment size of TCP in Active Mode), while in Passive Mode this is set by peer
*/
void setSn_MSS(SOCKET s, uint16 Sn_MSSR0)
{
IINCHIP_WRITE(Sn_MSSR0(s),(uint8)((Sn_MSSR0 & 0xff00) >> 8));
IINCHIP_WRITE((Sn_MSSR0(s) + 1),(uint8)(Sn_MSSR0 & 0x00ff));
}
void setSn_TTL(SOCKET s, uint8 ttl)
{
IINCHIP_WRITE(Sn_TTL(s), ttl);
}
/**
@brief These below function is used to setup the Protocol Field of IP Header when
executing the IP Layer RAW mode.
*/
void setSn_PROTO(SOCKET s, uint8 proto)
{
IINCHIP_WRITE(Sn_PROTO(s),proto);
}
/**
@brief get socket interrupt status
These below functions are used to read the Interrupt & Soket Status register
*/
uint8 getSn_IR(SOCKET s)
{
return IINCHIP_READ(Sn_IR(s));
}
/**
@brief get socket status
*/
uint8 getSn_SR(SOCKET s)
{
return IINCHIP_READ(Sn_SR(s));
}
/**
@brief get socket TX free buf size
This gives free buffer size of transmit buffer. This is the data size that user can transmit.
User shuold check this value first and control the size of transmitting data
*/
uint16 getSn_TX_FSR(SOCKET s)
{
uint16 val=0,val1=0;
do
{
val1 = IINCHIP_READ(Sn_TX_FSR0(s));
val1 = (val1 << 8) + IINCHIP_READ(Sn_TX_FSR0(s) + 1);
if (val1 != 0)
{
val = IINCHIP_READ(Sn_TX_FSR0(s));
val = (val << 8) + IINCHIP_READ(Sn_TX_FSR0(s) + 1);
}
} while (val != val1);
return val;
}
/**
@brief get socket RX recv buf size
This gives size of received data in receive buffer.
*/
uint16 getSn_RX_RSR(SOCKET s)
{
uint16 val=0,val1=0;
do
{
val1 = IINCHIP_READ(Sn_RX_RSR0(s));
val1 = (val1 << 8) + IINCHIP_READ(Sn_RX_RSR0(s) + 1);
if(val1 != 0)
{
val = IINCHIP_READ(Sn_RX_RSR0(s));
val = (val << 8) + IINCHIP_READ(Sn_RX_RSR0(s) + 1);
}
} while (val != val1);
return val;
}
/**
@brief This function is being called by send() and sendto() function also.
This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
register. User should read upper byte first and lower byte later to get proper value.
*/
void send_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr;
ptr = IINCHIP_READ(Sn_TX_WR0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR0(s) + 1);
write_data(s, data, (uint8 *)(ptr), len);
ptr += len;
IINCHIP_WRITE(Sn_TX_WR0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_TX_WR0(s) + 1),(uint8)(ptr & 0x00ff));
}
/**
@brief This function is being called by recv() also.
This function read the Rx read pointer register
and after copy the data from receive buffer update the Rx write pointer register.
User should read upper byte first and lower byte later to get proper value.
*/
void recv_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr;
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
#ifdef __DEF_IINCHIP_DBG__
printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
#endif
read_data(s, (uint8 *)ptr, data, len); // read data
ptr += len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
}
/**
@brief for copy the data form application buffer to Transmite buffer of the chip.
This function is being used for copy the data form application buffer to Transmite
buffer of the chip. It calculate the actual physical address where one has to write
the data in transmite buffer. Here also take care of the condition while it exceed
the Tx memory uper-bound of socket.
*/
void write_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len)
{
uint16 size;
uint16 dst_mask;
uint8 * dst_ptr;
dst_mask = (uint16)dst & getIINCHIP_TxMASK(s);
dst_ptr = (uint8 *)(getIINCHIP_TxBASE(s) + dst_mask);
if (dst_mask + len > getIINCHIP_TxMAX(s))
{
size = getIINCHIP_TxMAX(s) - dst_mask;
wiz_write_buf((uint16)dst_ptr, (uint8*)src, size);
src += size;
size = len - size;
dst_ptr = (uint8 *)(getIINCHIP_TxBASE(s));
wiz_write_buf((uint16)dst_ptr, (uint8*)src, size);
}
else
{
wiz_write_buf((uint16)dst_ptr, (uint8*)src, len);
}
}
/**
@brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
It calculate the actual physical address where one has to read
the data from Receive buffer. Here also take care of the condition while it exceed
the Rx memory uper-bound of socket.
*/
void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len)
{
uint16 size;
uint16 src_mask;
uint8 * src_ptr;
src_mask = (uint16)src & getIINCHIP_RxMASK(s);
src_ptr = (uint8 *)(getIINCHIP_RxBASE(s) + src_mask);
if( (src_mask + len) > getIINCHIP_RxMAX(s) )
{
size = getIINCHIP_RxMAX(s) - src_mask;
wiz_read_buf((uint16)src_ptr, (uint8*)dst,size);
dst += size;
size = len - size;
src_ptr = (uint8 *)(getIINCHIP_RxBASE(s));
wiz_read_buf((uint16)src_ptr, (uint8*) dst,size);
}
else
{
wiz_read_buf((uint16)src_ptr, (uint8*) dst,len);
}
}
#ifdef __DEF_IINCHIP_PPP__
#define PPP_OPTION_BUF_LEN 64
uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen);
/**
@brief make PPPoE connection
@return 1 => success to connect, 2 => Auth fail, 3 => timeout, 4 => Auth type not support
*/
uint8 pppinit(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
{
uint8 ret;
uint8 isr;
// PHASE0. W5100 PPPoE(ADSL) setup
// enable pppoe mode
printf("-- PHASE 0. W5100 PPPoE(ADSL) setup process --\r\n");
printf("\r\n");
IINCHIP_WRITE(MR,IINCHIP_READ(MR) | MR_PPPOE);
// open socket in pppoe mode
isr = IINCHIP_READ(Sn_IR(0));// first clear isr(0), W5100 at present time
IINCHIP_WRITE(Sn_IR(0),isr);
IINCHIP_WRITE(PTIMER,200); // 5sec timeout
IINCHIP_WRITE(PMAGIC,0x01); // magic number
IINCHIP_WRITE(Sn_MR(0),Sn_MR_PPPOE);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_OPEN);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
ret = pppinit_in(id, idlen, passwd, passwdlen);
// close ppp connection socket
/* +200801 (hwkim) */
close(0);
/* ------- */
return ret;
}
uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
{
uint8 loop_idx = 0;
uint8 isr = 0;
uint8 buf[PPP_OPTION_BUF_LEN];
uint16 len;
uint8 str[PPP_OPTION_BUF_LEN];
uint8 str_idx,dst_idx;
// PHASE1. PPPoE Discovery
// start to connect pppoe connection
printf("-- PHASE 1. PPPoE Discovery process --");
printf(" ok\r\n");
printf("\r\n");
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCON);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
loop_idx = 0;
//check whether PPPoE discovery end or not
while (!(IINCHIP_READ(Sn_IR(0)) & Sn_IR_PNEXT))
{
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout before LCP\r\n");
return 3;
}
wait_10ms(100);
}
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
// PHASE2. LCP process
printf("-- PHASE 2. LCP process --");
// send LCP Request
{
// Magic number option
// option format (type value + length value + data)
// write magic number value
buf[0] = 0x05; // type value
buf[1] = 0x06; // length value
buf[2] = 0x01; buf[3] = 0x01; buf[4] = 0x01; buf[5]= 0x01; // data
// for MRU option, 1492 0x05d4
// buf[6] = 0x01; buf[7] = 0x04; buf[8] = 0x05; buf[9] = 0xD4;
}
send_data_processing(0, buf, 0x06);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send request
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
while (!((isr = IINCHIP_READ(Sn_IR(0))) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PRECV) // Not support option
{
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), Sn_IR_PRECV);
/*---*/
len = getSn_RX_RSR(0);
if ( len > 0 )
{
recv_data_processing(0, str, len);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
// for debug
//printf("LCP proc\r\n"); for (i = 0; i < len; i++) printf ("%02x ", str[i]); printf("\r\n");
// get option length
len = str[4]; len = ((len & 0x00ff) << 8) + str[5];
len += 2;
str_idx = 6; dst_idx = 0; // ppp header is 6 byte, so starts at 6.
do
{
if ((str[str_idx] == 0x01) || (str[str_idx] == 0x02) || (str[str_idx] == 0x03) || (str[str_idx] == 0x05))
{
// skip as length of support option. str_idx+1 is option's length.
str_idx += str[str_idx+1];
}
else
{
// not support option , REJECT
memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
} while (str_idx != len);
// for debug
// printf("LCP dst proc\r\n"); for (i = 0; i < dst_idx; i++) printf ("%02x ", dst[i]); printf("\r\n");
// send LCP REJECT packet
send_data_processing(0, buf, dst_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCJ);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
}
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after LCP\r\n");
return 3;
}
wait_10ms(100);
}
printf(" ok\r\n");
printf("\r\n");
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
printf("-- PHASE 3. PPPoE(ADSL) Authentication mode --\r\n");
printf("Authentication protocol : %.2x %.2x, ", IINCHIP_READ(PATR0), IINCHIP_READ(PATR0+1));
loop_idx = 0;
if (IINCHIP_READ(PATR0) == 0xc0 && IINCHIP_READ(PATR0+1) == 0x23)
{
printf("PAP\r\n"); // in case of adsl normally supports PAP.
// send authentication data
// copy (idlen + id + passwdlen + passwd)
buf[loop_idx] = idlen; loop_idx++;
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen;
buf[loop_idx] = passwdlen; loop_idx++;
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen;
send_data_processing(0, buf, loop_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
}
else if (IINCHIP_READ(PATR0) == 0xc2 && IINCHIP_READ(PATR0+1) == 0x23)
{
uint8 chal_len;
md5_ctx context;
uint8 digest[16];
len = getSn_RX_RSR(0);
if ( len > 0 )
{
recv_data_processing(0, str, len);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
#ifdef __DEF_IINCHIP_DBG__
printf("recv CHAP\r\n");
{
int16 i;
for (i = 0; i < 32; i++)
printf ("%02x ", str[i]);
}
printf("\r\n");
#endif
// str is C2 23 xx CHAL_ID xx xx CHAP_LEN CHAP_DATA
// index 0 1 2 3 4 5 6 7 ...
memset(buf,0x00,64);
buf[loop_idx] = str[3]; loop_idx++; // chal_id
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen; //passwd
chal_len = str[6]; // chal_id
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(str+7), chal_len); loop_idx += chal_len; //challenge
buf[loop_idx] = 0x80;
#ifdef __DEF_IINCHIP_DBG__
printf("CHAP proc d1\r\n");
{
int16 i;
for (i = 0; i < 64; i++)
printf ("%02x ", buf[i]);
}
printf("\r\n");
#endif
md5_init(&context);
md5_update(&context, buf, loop_idx);
md5_final(digest, &context);
#ifdef __DEF_IINCHIP_DBG__
printf("CHAP proc d1\r\n");
{
int16 i;
for (i = 0; i < 16; i++)
printf ("%02x", digest[i]);
}
printf("\r\n");
#endif
loop_idx = 0;
buf[loop_idx] = 16; loop_idx++; // hash_len
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(digest), 16); loop_idx += 16; // hashed value
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen; // id
send_data_processing(0, buf, loop_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
}
}
else
{
printf("Not support\r\n");
#ifdef __DEF_IINCHIP_DBG__
printf("Not support PPP Auth type: %.2x%.2x\r\n",IINCHIP_READ(PATR0), IINCHIP_READ(PATR0+1));
#endif
return 4;
}
printf("\r\n");
printf("-- Waiting for PPPoE server's admission --");
loop_idx = 0;
while (!((isr = IINCHIP_READ(Sn_IR(0))) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PFAIL)
{
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
printf("failed\r\nReinput id, password..\r\n");
return 2;
}
printf(".");
if (loop_idx++ == 10) // timeout
{
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
printf("timeout after PAP\r\n");
return 3;
}
wait_10ms(100);
}
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
printf("ok\r\n");
printf("\r\n");
printf("-- PHASE 4. IPCP process --");
// IP Address
buf[0] = 0x03; buf[1] = 0x06; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00;
send_data_processing(0, buf, 6);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
loop_idx = 0;
while (1)
{
if (IINCHIP_READ(Sn_IR(0)) & Sn_IR_PRECV)
{
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
len = getSn_RX_RSR(0);
if ( len > 0 )
{
recv_data_processing(0, str, len);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_RECV);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
//for debug
//printf("IPCP proc\r\n"); for (i = 0; i < len; i++) printf ("%02x ", str[i]); printf("\r\n");
str_idx = 6; dst_idx = 0;
if (str[2] == 0x03) // in case of NAK
{
do
{
if (str[str_idx] == 0x03) // request only ip information
{
memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
else
{
// skip byte
str_idx += str[str_idx+1];
}
// for debug
//printf("s: %d, d: %d, l: %d", str_idx, dst_idx, len);
} while (str_idx != len);
send_data_processing(0, buf, dst_idx);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send ipcp request
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
break;
}
}
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP\r\n");
return 3;
}
wait_10ms(100);
send_data_processing(0, buf, 6);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); //ipcp re-request
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
}
loop_idx = 0;
while (!(IINCHIP_READ(Sn_IR(0)) & Sn_IR_PNEXT))
{
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP NAK\r\n");
return 3;
}
wait_10ms(100);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PCR); // send ipcp request
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
}
/* +200801[bj] clear interrupt value*/
IINCHIP_WRITE(Sn_IR(0), 0xff);
/*---*/
printf("ok\r\n");
printf("\r\n");
return 1;
// after this function, User must save the pppoe server's mac address and pppoe session id in current connection
}
/**
@brief terminate PPPoE connection
*/
uint8 pppterm(uint8 * mac, uint8 * sessionid)
{
uint16 i;
uint8 isr;
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm()\r\n");
#endif
/* Set PPPoE bit in MR(Common Mode Register) : enable socket0 pppoe */
IINCHIP_WRITE(MR,IINCHIP_READ(MR) | MR_PPPOE);
// write pppoe server's mac address and session id
// must be setted these value.
for (i = 0; i < 6; i++) IINCHIP_WRITE((Sn_DHAR0(0)+i),mac[i]);
for (i = 0; i < 2; i++) IINCHIP_WRITE((Sn_DPORT0(0)+i),sessionid[i]);
isr = IINCHIP_READ(Sn_IR(0));
IINCHIP_WRITE(Sn_IR(0),isr);
//open socket in pppoe mode
IINCHIP_WRITE(Sn_MR(0),Sn_MR_PPPOE);
IINCHIP_WRITE(Sn_CR(0),Sn_CR_OPEN);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_1us(1);
// close pppoe connection
IINCHIP_WRITE(Sn_CR(0),Sn_CR_PDISCON);
/* +20071122[chungs]:wait to process the command... */
while( IINCHIP_READ(Sn_CR(0)) )
;
/* ------- */
wait_10ms(100);
// close socket
/* +200801 (hwkim) */
close(0);
/* ------- */
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm() end ..\r\n");
#endif
return 1;
}
#endif

View File

@ -0,0 +1,174 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
#include "w5100.h"
// W5100 controller instance
W5100Class W5100;
#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)
#define TXBUF_BASE 0x4000
#define RXBUF_BASE 0x6000
void W5100Class::init(void)
{
writeMR(1<<RST);
writeTMSR(0x55);
writeRMSR(0x55);
for (int i=0; i<MAX_SOCK_NUM; i++) {
SBASE[i] = TXBUF_BASE + SSIZE * i;
RBASE[i] = RXBUF_BASE + RSIZE * i;
}
}
uint16_t W5100Class::getTXFreeSize(SOCKET s)
{
uint16_t val=0, val1=0;
do {
val1 = readSnTX_FSR(s);
if (val1 != 0)
val = readSnTX_FSR(s);
}
while (val != val1);
return val;
}
uint16_t W5100Class::getRXReceivedSize(SOCKET s)
{
uint16_t val=0,val1=0;
do {
val1 = readSnRX_RSR(s);
if (val1 != 0)
val = readSnRX_RSR(s);
}
while (val != val1);
return val;
}
void W5100Class::send_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
uint16_t ptr = readSnTX_WR(s);
uint16_t offset = ptr & SMASK;
uint16_t dstAddr = offset + SBASE[s];
if (offset + len > SSIZE)
{
// Wrap around circular buffer
uint16_t size = SSIZE - offset;
write(dstAddr, data, size);
write(SBASE[s], data + size, len - size);
}
else {
write(dstAddr, data, len);
}
ptr += len;
writeSnTX_WR(s, ptr);
}
void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
uint16_t ptr;
ptr = readSnRX_RD(s);
read_data(s, (uint8_t *)ptr, data, len);
ptr += len;
writeSnRX_RD(s, ptr);
}
void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
{
uint16_t size;
uint16_t src_mask;
uint16_t src_ptr;
src_mask = (uint16_t)src & RMASK;
src_ptr = RBASE[s] + src_mask;
if( (src_mask + len) > RSIZE )
{
size = RSIZE - src_mask;
read(src_ptr, (uint8_t *)dst, size);
dst += size;
read(RBASE[s], (uint8_t *) dst, len - size);
}
else
read(src_ptr, (uint8_t *) dst, len);
}
uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
{
setSS();
SPI.send(0xF0);
SPI.send(_addr >> 8);
SPI.send(_addr & 0xFF);
SPI.send(_data);
resetSS();
return 1;
}
uint16_t W5100Class::write(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
for (int i=0; i<_len; i++)
{
setSS();
SPI.send(0xF0);
SPI.send(_addr >> 8);
SPI.send(_addr & 0xFF);
_addr++;
SPI.send(_buf[i]);
resetSS();
}
return _len;
}
uint8_t W5100Class::read(uint16_t _addr)
{
setSS();
SPI.send(0x0F);
SPI.send(_addr >> 8);
SPI.send(_addr & 0xFF);
uint8_t _data = SPI.send(0);
resetSS();
return _data;
}
uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
for (int i=0; i<_len; i++)
{
setSS();
SPI.send(0x0F);
SPI.send(_addr >> 8);
SPI.send(_addr & 0xFF);
_addr++;
_buf[i] = SPI.send(0);
resetSS();
}
return _len;
}
void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
// Send command to socket
writeSnCR(s, _cmd);
// Wait for command to complete
while (readSnCR(s))
;
}

View File

@ -1,299 +1,381 @@
/*
@file w5100.h
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef _W5100_H_
#define _W5100_H_
#ifndef W5100_H_INCLUDED
#define W5100_H_INCLUDED
#include <avr/pgmspace.h>
#include <SPI.h>
#define MR __DEF_IINCHIP_MAP_BASE__
#define IDM_OR ((__DEF_IINCHIP_MAP_BASE__ + 0x00))
#define IDM_AR0 ((__DEF_IINCHIP_MAP_BASE__ + 0x01))
#define IDM_AR1 ((__DEF_IINCHIP_MAP_BASE__ + 0x02))
#define IDM_DR ((__DEF_IINCHIP_MAP_BASE__ + 0x03))
#define MAX_SOCK_NUM 4
typedef uint8_t SOCKET;
#define IDM_OR 0x8000
#define IDM_AR0 0x8001
#define IDM_AR1 0x8002
#define IDM_DR 0x8003
/*
class MR {
public:
static const uint8_t RST = 0x80;
static const uint8_t PB = 0x10;
static const uint8_t PPPOE = 0x08;
static const uint8_t LB = 0x04;
static const uint8_t AI = 0x02;
static const uint8_t IND = 0x01;
};
*/
/*
class IR {
public:
static const uint8_t CONFLICT = 0x80;
static const uint8_t UNREACH = 0x40;
static const uint8_t PPPoE = 0x20;
static const uint8_t SOCK0 = 0x01;
static const uint8_t SOCK1 = 0x02;
static const uint8_t SOCK2 = 0x04;
static const uint8_t SOCK3 = 0x08;
static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); };
};
*/
class SnMR {
public:
static const uint8_t CLOSE = 0x00;
static const uint8_t TCP = 0x01;
static const uint8_t UDP = 0x02;
static const uint8_t IPRAW = 0x03;
static const uint8_t MACRAW = 0x04;
static const uint8_t PPPOE = 0x05;
static const uint8_t ND = 0x20;
static const uint8_t MULTI = 0x80;
};
enum SockCMD {
Sock_OPEN = 0x01,
Sock_LISTEN = 0x02,
Sock_CONNECT = 0x04,
Sock_DISCON = 0x08,
Sock_CLOSE = 0x10,
Sock_SEND = 0x20,
Sock_SEND_MAC = 0x21,
Sock_SEND_KEEP = 0x22,
Sock_RECV = 0x40
};
/*class SnCmd {
public:
static const uint8_t OPEN = 0x01;
static const uint8_t LISTEN = 0x02;
static const uint8_t CONNECT = 0x04;
static const uint8_t DISCON = 0x08;
static const uint8_t CLOSE = 0x10;
static const uint8_t SEND = 0x20;
static const uint8_t SEND_MAC = 0x21;
static const uint8_t SEND_KEEP = 0x22;
static const uint8_t RECV = 0x40;
};
*/
class SnIR {
public:
static const uint8_t SEND_OK = 0x10;
static const uint8_t TIMEOUT = 0x08;
static const uint8_t RECV = 0x04;
static const uint8_t DISCON = 0x02;
static const uint8_t CON = 0x01;
};
class SnSR {
public:
static const uint8_t CLOSED = 0x00;
static const uint8_t INIT = 0x13;
static const uint8_t LISTEN = 0x14;
static const uint8_t SYNSENT = 0x15;
static const uint8_t SYNRECV = 0x16;
static const uint8_t ESTABLISHED = 0x17;
static const uint8_t FIN_WAIT = 0x18;
static const uint8_t CLOSING = 0x1A;
static const uint8_t TIME_WAIT = 0x1B;
static const uint8_t CLOSE_WAIT = 0x1C;
static const uint8_t LAST_ACK = 0x1D;
static const uint8_t UDP = 0x22;
static const uint8_t IPRAW = 0x32;
static const uint8_t MACRAW = 0x42;
static const uint8_t PPPOE = 0x5F;
};
class IPPROTO {
public:
static const uint8_t IP = 0;
static const uint8_t ICMP = 1;
static const uint8_t IGMP = 2;
static const uint8_t GGP = 3;
static const uint8_t TCP = 6;
static const uint8_t PUP = 12;
static const uint8_t UDP = 17;
static const uint8_t IDP = 22;
static const uint8_t ND = 77;
static const uint8_t RAW = 255;
};
class W5100Class {
public:
void init();
/**
@brief Gateway IP Register address
* @brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
*
* It calculate the actual physical address where one has to read
* the data from Receive buffer. Here also take care of the condition while it exceed
* the Rx memory uper-bound of socket.
*/
#define GAR0 (COMMON_BASE + 0x0001)
/**
@brief Subnet mask Register address
*/
#define SUBR0 (COMMON_BASE + 0x0005)
/**
@brief Source MAC Register address
*/
#define SHAR0 (COMMON_BASE + 0x0009)
/**
@brief Source IP Register address
*/
#define SIPR0 (COMMON_BASE + 0x000F)
/**
@brief Interrupt Register
*/
#define IR (COMMON_BASE + 0x0015)
/**
@brief Interrupt mask register
*/
#define IMR (COMMON_BASE + 0x0016)
/**
@brief Timeout register address( 1 is 100us )
*/
#define RTR0 (COMMON_BASE + 0x0017)
/**
@brief Retry count reigster
*/
#define RCR (COMMON_BASE + 0x0019)
/**
@brief Receive memory size reigster
*/
#define RMSR (COMMON_BASE + 0x001A)
/**
@brief Transmit memory size reigster
*/
#define TMSR (COMMON_BASE + 0x001B)
/**
@brief Authentication type register address in PPPoE mode
*/
#define PATR0 (COMMON_BASE + 0x001C)
//#define PPPALGO (COMMON_BASE + 0x001D)
#define PTIMER (COMMON_BASE + 0x0028)
#define PMAGIC (COMMON_BASE + 0x0029)
void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len);
/**
@brief Unreachable IP register address in UDP mode
* @brief This function is being called by send() and sendto() function also.
*
* This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
* register. User should read upper byte first and lower byte later to get proper value.
*/
#define UIPR0 (COMMON_BASE + 0x002A)
/**
@brief Unreachable Port register address in UDP mode
*/
#define UPORT0 (COMMON_BASE + 0x002E)
void send_data_processing(SOCKET s, uint8_t *data, uint16_t len);
/**
@brief socket register
* @brief This function is being called by recv() also.
*
* This function read the Rx read pointer register
* and after copy the data from receive buffer update the Rx write pointer register.
* User should read upper byte first and lower byte later to get proper value.
*/
#define CH_BASE (COMMON_BASE + 0x0400)
/**
@brief size of each channel register map
*/
#define CH_SIZE 0x0100
/**
@brief socket Mode register
*/
#define Sn_MR(ch) (CH_BASE + ch * CH_SIZE + 0x0000)
/**
@brief channel Sn_CR register
*/
#define Sn_CR(ch) (CH_BASE + ch * CH_SIZE + 0x0001)
/**
@brief channel interrupt register
*/
#define Sn_IR(ch) (CH_BASE + ch * CH_SIZE + 0x0002)
/**
@brief channel status register
*/
#define Sn_SR(ch) (CH_BASE + ch * CH_SIZE + 0x0003)
/**
@brief source port register
*/
#define Sn_PORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0004)
/**
@brief Peer MAC register address
*/
#define Sn_DHAR0(ch) (CH_BASE + ch * CH_SIZE + 0x0006)
/**
@brief Peer IP register address
*/
#define Sn_DIPR0(ch) (CH_BASE + ch * CH_SIZE + 0x000C)
/**
@brief Peer port register address
*/
#define Sn_DPORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0010)
/**
@brief Maximum Segment Size(Sn_MSSR0) register address
*/
#define Sn_MSSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0012)
/**
@brief Protocol of IP Header field register in IP raw mode
*/
#define Sn_PROTO(ch) (CH_BASE + ch * CH_SIZE + 0x0014)
void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len);
/**
@brief IP Type of Service(TOS) Register
*/
#define Sn_TOS(ch) (CH_BASE + ch * CH_SIZE + 0x0015)
/**
@brief IP Time to live(TTL) Register
*/
#define Sn_TTL(ch) (CH_BASE + ch * CH_SIZE + 0x0016)
inline void setGatewayIp(uint8_t *_addr);
inline void getGatewayIp(uint8_t *_addr);
/**
@brief Transmit free memory size register
*/
#define Sn_TX_FSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0020)
/**
@brief Transmit memory read pointer register address
*/
#define Sn_TX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0022)
/**
@brief Transmit memory write pointer register address
*/
#define Sn_TX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x0024)
/**
@brief Received data size register
*/
#define Sn_RX_RSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0026)
/**
@brief Read point of Receive memory
*/
#define Sn_RX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0028)
/**
@brief Write point of Receive memory
*/
#define Sn_RX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x002A)
inline void setSubnetMask(uint8_t *_addr);
inline void getSubnetMask(uint8_t *_addr);
inline void setMACAddress(uint8_t * addr);
inline void getMACAddress(uint8_t * addr);
inline void setIPAddress(uint8_t * addr);
inline void getIPAddress(uint8_t * addr);
inline void setRetransmissionTime(uint16_t timeout);
inline void setRetransmissionCount(uint8_t _retry);
void execCmdSn(SOCKET s, SockCMD _cmd);
uint16_t getTXFreeSize(SOCKET s);
uint16_t getRXReceivedSize(SOCKET s);
// W5100 Registers
// ---------------
private:
static uint8_t write(uint16_t _addr, uint8_t _data);
static uint16_t write(uint16_t addr, uint8_t *buf, uint16_t len);
static uint8_t read(uint16_t addr);
static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);
/* MODE register values */
#define MR_RST 0x80 /**< reset */
#define MR_PB 0x10 /**< ping block */
#define MR_PPPOE 0x08 /**< enable pppoe */
#define MR_LB 0x04 /**< little or big endian selector in indirect mode */
#define MR_AI 0x02 /**< auto-increment in indirect mode */
#define MR_IND 0x01 /**< enable indirect mode */
#define __GP_REGISTER8(name, address) \
static inline void write##name(uint8_t _data) { \
write(address, _data); \
} \
static inline uint8_t read##name() { \
return read(address); \
}
#define __GP_REGISTER16(name, address) \
static void write##name(uint16_t _data) { \
write(address, _data >> 8); \
write(address+1, _data & 0xFF); \
} \
static uint16_t read##name() { \
uint16_t res = read(address); \
res = (res << 8) + read(address + 1); \
return res; \
}
#define __GP_REGISTER_N(name, address, size) \
static uint16_t write##name(uint8_t *_buff) { \
return write(address, _buff, size); \
} \
static uint16_t read##name(uint8_t *_buff) { \
return read(address, _buff, size); \
}
/* IR register values */
#define IR_CONFLICT 0x80 /**< check ip confict */
#define IR_UNREACH 0x40 /**< get the destination unreachable message in UDP sending */
#define IR_PPPoE 0x20 /**< get the PPPoE close message */
#define IR_SOCK(ch) (0x01 << ch) /**< check socket interrupt */
public:
__GP_REGISTER8 (MR, 0x0000); // Mode
__GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address
__GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address
__GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address
__GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address
__GP_REGISTER8 (IR, 0x0015); // Interrupt
__GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask
__GP_REGISTER16(RTR, 0x0017); // Timeout address
__GP_REGISTER8 (RCR, 0x0019); // Retry count
__GP_REGISTER8 (RMSR, 0x001A); // Receive memory size
__GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size
__GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode
__GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer
__GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number
__GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode
__GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode
/* Sn_MR values */
#define Sn_MR_CLOSE 0x00 /**< unused socket */
#define Sn_MR_TCP 0x01 /**< TCP */
#define Sn_MR_UDP 0x02 /**< UDP */
#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
#define Sn_MR_MACRAW 0x04 /**< MAC LAYER RAW SOCK */
#define Sn_MR_PPPOE 0x05 /**< PPPoE */
#define Sn_MR_ND 0x20 /**< No Delayed Ack(TCP) flag */
#define Sn_MR_MULTI 0x80 /**< support multicating */
#undef __GP_REGISTER8
#undef __GP_REGISTER16
#undef __GP_REGISTER_N
// W5100 Socket registers
// ----------------------
private:
static inline uint8_t readSn(SOCKET _s, uint16_t _addr);
static inline uint8_t writeSn(SOCKET _s, uint16_t _addr, uint8_t _data);
static inline uint16_t readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
static inline uint16_t writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
static const uint16_t CH_BASE = 0x0400;
static const uint16_t CH_SIZE = 0x0100;
#define __SOCKET_REGISTER8(name, address) \
static inline void write##name(SOCKET _s, uint8_t _data) { \
writeSn(_s, address, _data); \
} \
static inline uint8_t read##name(SOCKET _s) { \
return readSn(_s, address); \
}
#define __SOCKET_REGISTER16(name, address) \
static void write##name(SOCKET _s, uint16_t _data) { \
writeSn(_s, address, _data >> 8); \
writeSn(_s, address+1, _data & 0xFF); \
} \
static uint16_t read##name(SOCKET _s) { \
uint16_t res = readSn(_s, address); \
res = (res << 8) + readSn(_s, address + 1); \
return res; \
}
#define __SOCKET_REGISTER_N(name, address, size) \
static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \
return writeSn(_s, address, _buff, size); \
} \
static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \
return readSn(_s, address, _buff, size); \
}
public:
__SOCKET_REGISTER8(SnMR, 0x0000) // Mode
__SOCKET_REGISTER8(SnCR, 0x0001) // Command
__SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt
__SOCKET_REGISTER8(SnSR, 0x0003) // Status
__SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port
__SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr
__SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr
__SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port
__SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size
__SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode
__SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS
__SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL
__SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size
__SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer
__SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer
__SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size
__SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer
__SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)
#undef __SOCKET_REGISTER8
#undef __SOCKET_REGISTER16
#undef __SOCKET_REGISTER_N
/* Sn_CR values */
#define Sn_CR_OPEN 0x01 /**< initialize or open socket */
#define Sn_CR_LISTEN 0x02 /**< wait connection request in tcp mode(Server mode) */
#define Sn_CR_CONNECT 0x04 /**< send connection request in tcp mode(Client mode) */
#define Sn_CR_DISCON 0x08 /**< send closing reqeuset in tcp mode */
#define Sn_CR_CLOSE 0x10 /**< close socket */
#define Sn_CR_SEND 0x20 /**< updata txbuf pointer, send data */
#define Sn_CR_SEND_MAC 0x21 /**< send data with MAC address, so without ARP process */
#define Sn_CR_SEND_KEEP 0x22 /**< send keep alive message */
#define Sn_CR_RECV 0x40 /**< update rxbuf pointer, recv data */
private:
static const uint8_t RST = 7; // Reset BIT
#ifdef __DEF_IINCHIP_PPP__
#define Sn_CR_PCON 0x23
#define Sn_CR_PDISCON 0x24
#define Sn_CR_PCR 0x25
#define Sn_CR_PCN 0x26
#define Sn_CR_PCJ 0x27
static const int SOCKETS = 4;
static const uint16_t SMASK = 0x07FF; // Tx buffer MASK
static const uint16_t RMASK = 0x07FF; // Rx buffer MASK
public:
static const uint16_t SSIZE = 2048; // Max Tx buffer size
private:
static const uint16_t RSIZE = 2048; // Max Rx buffer size
uint16_t SBASE[SOCKETS]; // Tx buffer base address
uint16_t RBASE[SOCKETS]; // Rx buffer base address
private:
#if defined(__AVR_ATmega1280__)
inline static void initSS() { DDRB |= _BV(4); };
inline static void setSS() { PORTB &= ~_BV(4); };
inline static void resetSS() { PORTB |= _BV(4); };
#else
inline static void initSS() { DDRB |= _BV(2); };
inline static void setSS() { PORTB &= ~_BV(2); };
inline static void resetSS() { PORTB |= _BV(2); };
#endif
/* Sn_IR values */
#ifdef __DEF_IINCHIP_PPP__
#define Sn_IR_PRECV 0x80
#define Sn_IR_PFAIL 0x40
#define Sn_IR_PNEXT 0x20
#endif
#define Sn_IR_SEND_OK 0x10 /**< complete sending */
#define Sn_IR_TIMEOUT 0x08 /**< assert timeout */
#define Sn_IR_RECV 0x04 /**< receiving data */
#define Sn_IR_DISCON 0x02 /**< closed socket */
#define Sn_IR_CON 0x01 /**< established connection */
};
/* Sn_SR values */
#define SOCK_CLOSED 0x00 /**< closed */
#define SOCK_INIT 0x13 /**< init state */
#define SOCK_LISTEN 0x14 /**< listen state */
#define SOCK_SYNSENT 0x15 /**< connection state */
#define SOCK_SYNRECV 0x16 /**< connection state */
#define SOCK_ESTABLISHED 0x17 /**< success to connect */
#define SOCK_FIN_WAIT 0x18 /**< closing state */
#define SOCK_CLOSING 0x1A /**< closing state */
#define SOCK_TIME_WAIT 0x1B /**< closing state */
#define SOCK_CLOSE_WAIT 0x1C /**< closing state */
#define SOCK_LAST_ACK 0x1D /**< closing state */
#define SOCK_UDP 0x22 /**< udp socket */
#define SOCK_IPRAW 0x32 /**< ip raw mode socket */
#define SOCK_MACRAW 0x42 /**< mac raw mode socket */
#define SOCK_PPPOE 0x5F /**< pppoe socket */
extern W5100Class W5100;
/* IP PROTOCOL */
#define IPPROTO_IP 0 /**< Dummy for IP */
#define IPPROTO_ICMP 1 /**< Control message protocol */
#define IPPROTO_IGMP 2 /**< Internet group management protocol */
#define IPPROTO_GGP 3 /**< Gateway^2 (deprecated) */
#define IPPROTO_TCP 6 /**< TCP */
#define IPPROTO_PUP 12 /**< PUP */
#define IPPROTO_UDP 17 /**< UDP */
#define IPPROTO_IDP 22 /**< XNS idp */
#define IPPROTO_ND 77 /**< UNOFFICIAL net disk protocol */
#define IPPROTO_RAW 255 /**< Raw IP packet */
uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) {
return read(CH_BASE + _s * CH_SIZE + _addr);
}
uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) {
return write(CH_BASE + _s * CH_SIZE + _addr, _data);
}
/*********************************************************
* iinchip access function
*********************************************************/
extern uint8 IINCHIP_READ(uint16 addr);
extern uint8 IINCHIP_WRITE(uint16 addr,uint8 data);
extern uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len);
extern uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len);
uint16_t W5100Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
return read(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
}
extern void iinchip_init(void); // reset iinchip
extern void sysinit(uint8 tx_size, uint8 rx_size); // setting tx/rx buf size
extern uint8 getISR(uint8 s);
extern void putISR(uint8 s, uint8 val);
extern uint16 getIINCHIP_RxMAX(uint8 s);
extern uint16 getIINCHIP_TxMAX(uint8 s);
extern uint16 getIINCHIP_RxMASK(uint8 s);
extern uint16 getIINCHIP_TxMASK(uint8 s);
extern uint16 getIINCHIP_RxBASE(uint8 s);
extern uint16 getIINCHIP_TxBASE(uint8 s);
extern void setGAR(uint8 * addr); // set gateway address
extern void setSUBR(uint8 * addr); // set subnet mask address
extern void setSHAR(uint8 * addr); // set local MAC address
extern void setSIPR(uint8 * addr); // set local IP address
extern void setRTR(uint16 timeout); // set retry duration for data transmission, connection, closing ...
extern void setRCR(uint8 retry); // set retry count (above the value, assert timeout interrupt)
extern void setIMR(uint8 mask); // set interrupt mask.
extern void getGAR(uint8 * addr);
extern void getSUBR(uint8 * addr);
extern void getSHAR(uint8 * addr);
extern void getSIPR(uint8 * addr);
extern uint8 getIR( void );
extern void setSn_MSS(SOCKET s, uint16 Sn_MSSR0); // set maximum segment size
extern void setSn_PROTO(SOCKET s, uint8 proto); // set IP Protocol value using IP-Raw mode
extern uint8 getSn_IR(SOCKET s); // get socket interrupt status
extern uint8 getSn_SR(SOCKET s); // get socket status
extern uint16 getSn_TX_FSR(SOCKET s); // get socket TX free buf size
extern uint16 getSn_RX_RSR(SOCKET s); // get socket RX recv buf size
extern void setSn_DHAR(SOCKET s, uint8 * addr);
extern void setSn_DIPR(SOCKET s, uint8 * addr);
extern void setSn_DPORT(SOCKET s, uint8 * addr);
extern void getSn_DHAR(SOCKET s, uint8 * addr);
extern void getSn_DIPR(SOCKET s, uint8 * addr);
extern void getSn_DPORT(SOCKET s, uint8 * addr);
extern void setSn_TTL(SOCKET s, uint8 ttl);
extern void setMR(uint8 val);
uint16_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
return write(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
}
#ifdef __DEF_IINCHIP_PPP__
extern uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen);
extern uint8 pppterm(uint8 *mac,uint8 *sessionid);
#endif
void W5100Class::getGatewayIp(uint8_t *_addr) {
readGAR(_addr);
}
extern void send_data_processing(SOCKET s, uint8 *data, uint16 len);
extern void recv_data_processing(SOCKET s, uint8 *data, uint16 len);
extern void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
extern void write_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
void W5100Class::setGatewayIp(uint8_t *_addr) {
writeGAR(_addr);
}
void W5100Class::getSubnetMask(uint8_t *_addr) {
readSUBR(_addr);
}
void W5100Class::setSubnetMask(uint8_t *_addr) {
writeSUBR(_addr);
}
void W5100Class::getMACAddress(uint8_t *_addr) {
readSHAR(_addr);
}
void W5100Class::setMACAddress(uint8_t *_addr) {
writeSHAR(_addr);
}
void W5100Class::getIPAddress(uint8_t *_addr) {
readSIPR(_addr);
}
void W5100Class::setIPAddress(uint8_t *_addr) {
writeSIPR(_addr);
}
void W5100Class::setRetransmissionTime(uint16_t _timeout) {
writeRTR(_timeout);
}
void W5100Class::setRetransmissionCount(uint8_t _retry) {
writeRCR(_retry);
}
#endif

94
libraries/SPI/SPI.cpp Normal file
View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "SPI.h"
SPIClass SPI;
SPIClass::SPIClass()
{
#if defined(__AVR_ATmega1280__)
// PBx
const static byte SS = 0;
const static byte MOSI = 2;
const static byte MISO = 3;
const static byte SCK = 1;
#else
// PBx
const static byte SS = 2;
const static byte MOSI = 3;
const static byte MISO = 4;
const static byte SCK = 5;
#endif
// Set direction register for SCK and MOSI pin.
// MISO pin automatically overrides to INPUT.
// When the SS pin is set as OUTPUT, it can be used as
// a general purpose output port (it doesn't influence
// SPI operations).
DDRB |= _BV(SCK) | _BV(MOSI) | _BV(SS);
PORTB &= ~(_BV(SCK) | _BV(MOSI) | _BV(SS));
SPCR = _BV(SPE) | _BV(MSTR);
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
// automatically switches to Slave, so the data direction of
// the SS pin MUST be kept as OUTPUT.
SPCR = _BV(SPE) | _BV(MSTR);
}
void SPIClass::setDataOrder(SPIDataOrder _d)
{
if (_d == SPI_DataOrder_LSB)
SPCR |= _BV(DORD); // LSB
else
SPCR &= ~_BV(DORD); // MSB
}
void SPIClass::setSPIMode(SPIMode _d)
{
switch (_d) {
case SPI_Mode_SampleRising:
SPCR &= ~(_BV(CPOL) | _BV(CPHA));
break;
case SPI_Mode_SetupRising:
SPCR &= ~_BV(CPOL);
SPCR |= _BV(CPHA);
break;
case SPI_Mode_SampleFalling:
SPCR &= ~_BV(CPHA);
SPCR |= _BV(CPOL);
break;
case SPI_Mode_SetupFalling:
SPCR |= _BV(CPOL) | _BV(CPHA);
break;
}
}
void SPIClass::setClockDivider(SPIClockDivider _d)
{
switch (_d) {
case SPI_ClkDiv_4:
SPCR &= ~(_BV(SPR1) | _BV(SPR0));
break;
case SPI_ClkDiv_16:
SPCR &= ~_BV(SPR1);
SPCR |= _BV(SPR0);
break;
case SPI_ClkDiv_64:
SPCR |= _BV(SPR1);
SPCR &= ~_BV(SPR0);
break;
case SPI_ClkDiv_128:
SPCR |= _BV(SPR1) | _BV(SPR0);
break;
}
}

93
libraries/SPI/SPI.h Normal file
View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
#include <stdio.h>
#include <WProgram.h>
#include <avr/pgmspace.h>
enum SPIClockDivider {
SPI_ClkDiv_4,
SPI_ClkDiv_16,
SPI_ClkDiv_64,
SPI_ClkDiv_128,
};
enum SPIDataOrder {
SPI_DataOrder_LSB,
SPI_DataOrder_MSB,
};
enum SPIMode {
SPI_Mode_SampleRising,
SPI_Mode_SetupRising,
SPI_Mode_SampleFalling,
SPI_Mode_SetupFalling,
};
class SPIClass {
public:
SPIClass();
inline static byte send(byte _data);
// SPI Configuration methods
inline static void attachInterrupt();
inline static void detachInterrupt(); // Default
inline static void begin(); // Default
inline static void end();
static void setDataOrder(SPIDataOrder);
static void setSPIMode(SPIMode);
static void setClockDivider(SPIClockDivider);
inline static void doubleSpeed();
inline static void noDoubleSpeed(); // Default
};
extern SPIClass SPI;
byte SPIClass::send(byte _data) {
SPDR = _data;
while (!(SPSR & _BV(SPIF)))
;
return SPDR;
}
void SPIClass::attachInterrupt() {
SPCR |= _BV(SPIE);
}
void SPIClass::detachInterrupt() {
SPCR &= ~_BV(SPIE);
}
void SPIClass::begin() {
SPCR |= _BV(SPE);
}
void SPIClass::end() {
SPCR &= ~_BV(SPE);
}
void SPIClass::doubleSpeed() {
SPSR |= _BV(SPI2X);
}
void SPIClass::noDoubleSpeed() {
SPSR &= ~_BV(SPI2X);
}
#endif

View File

@ -0,0 +1,51 @@
#######################################
# Syntax Coloring Map SPI
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SPI KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
send KEYWORD2
sendInt16 KEYWORD2
sendInt32 KEYWORD2
initSS KEYWORD2
setSS KEYWORD2
resetSS KEYWORD2
initSS2 KEYWORD2
setSS2 KEYWORD2
resetSS2 KEYWORD2
initSS3 KEYWORD2
setSS3 KEYWORD2
resetSS3 KEYWORD2
initSS4 KEYWORD2
setSS4 KEYWORD2
resetSS4 KEYWORD2
enableInterrupt KEYWORD2
disableInterrupt KEYWORD2
enable KEYWORD2
disable KEYWORD2
dataOrderLSB KEYWORD2
dataOrderMSB KEYWORD2
setSPIMode0 KEYWORD2
setSPIMode1 KEYWORD2
setSPIMode2 KEYWORD2
setSPIMode3 KEYWORD2
setClockDividerTo2 KEYWORD2
setClockDividerTo4 KEYWORD2
setClockDividerTo8 KEYWORD2
setClockDividerTo16 KEYWORD2
setClockDividerTo32 KEYWORD2
setClockDividerTo64 KEYWORD2
setClockDividerTo128 KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################