ShineLAN-X: Growatt-Präfix aus Ordnername entfernt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
retr0
2026-04-20 13:53:57 +02:00
parent e27a47791a
commit 9b61f9780d
41 changed files with 0 additions and 0 deletions
@@ -0,0 +1,391 @@
/*
Enc28J60NetworkClass.cpp — Bitbang-SPI version for non-hardware-SPI pins
Based on UIPEthernet by Norbert Truchsess, GPL V2
Modification: Hardware SPI replaced with bitbang SPI.
Target: STM32F103RBT6 with ENC28J60 on PC6(SCK)/PC7(MISO)/PC8(CS)/PC9(MOSI)
*/
#include "Enc28J60Network.h"
#include <Arduino.h>
#include "config.h" // ETH_SCK_PIN / ETH_MOSI_PIN / ETH_MISO_PIN
// Note: <SPI.h> intentionally NOT included — this version uses bitbang SPI
extern "C" {
#include "enc28j60.h"
#include "uip.h"
}
// ============================================================
// Bitbang SPI — SPI Mode 0 (CPOL=0, CPHA=0)
// Pin definitions come from project include/config.h via build system
// ============================================================
#ifndef ETH_SCK_PIN
#error "ETH_SCK_PIN not defined — check include/config.h"
#endif
static bool _spi_ready = false;
static void bitbang_init() {
if (_spi_ready) return;
pinMode(ETH_SCK_PIN, OUTPUT); digitalWrite(ETH_SCK_PIN, LOW);
pinMode(ETH_MOSI_PIN, OUTPUT); digitalWrite(ETH_MOSI_PIN, LOW);
pinMode(ETH_MISO_PIN, INPUT);
_spi_ready = true;
}
static inline uint8_t bitbang_transfer(uint8_t out) {
uint8_t in = 0;
for (int8_t i = 7; i >= 0; i--) {
digitalWrite(ETH_MOSI_PIN, (out >> i) & 1);
digitalWrite(ETH_SCK_PIN, HIGH);
in = (in << 1) | digitalRead(ETH_MISO_PIN);
digitalWrite(ETH_SCK_PIN, LOW);
}
return in;
}
// ============================================================
// set CS to 0 = active
#define CSACTIVE digitalWrite(csPin, LOW)
// set CS to 1 = passive
#define CSPASSIVE digitalWrite(csPin, HIGH)
bool Enc28J60Network::spiInitialized = false;
uint8_t Enc28J60Network::csPin = SS;
uint16_t Enc28J60Network::nextPacketPtr;
uint8_t Enc28J60Network::bank = 0xff;
struct memblock Enc28J60Network::receivePkt;
void Enc28J60Network::initSPI()
{
if (spiInitialized)
return;
bitbang_init();
pinMode(csPin, OUTPUT);
CSPASSIVE;
spiInitialized = true;
}
bool Enc28J60Network::init(uint8_t* macaddr)
{
MemoryPool::init();
initSPI();
// perform system reset
writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
delay(50);
nextPacketPtr = RXSTART_INIT;
writeRegPair(ERXSTL, RXSTART_INIT);
writeRegPair(ERXRDPTL, RXSTART_INIT);
writeRegPair(ERXNDL, RXSTOP_INIT);
writeReg(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
writeRegPair(EPMM0, 0x303f);
writeRegPair(EPMCSL, 0xf7f9);
writeRegPair(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
writeRegPair(MAIPGL, 0x0C12);
writeReg(MABBIPG, 0x12);
writeRegPair(MAMXFLL, MAX_FRAMELEN);
writeReg(MAADR5, macaddr[0]);
writeReg(MAADR4, macaddr[1]);
writeReg(MAADR3, macaddr[2]);
writeReg(MAADR2, macaddr[3]);
writeReg(MAADR1, macaddr[4]);
writeReg(MAADR0, macaddr[5]);
phyWrite(PHCON2, PHCON2_HDLDIS);
setBank(ECON1);
writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
phyWrite(PHLCON, 0x476);
return getrev();
}
memhandle Enc28J60Network::receivePacket()
{
uint8_t rxstat;
uint16_t len;
if (readReg(EPKTCNT) != 0)
{
uint16_t readPtr = nextPacketPtr+6 > RXSTOP_INIT ?
nextPacketPtr+6-((RXSTOP_INIT + 1)-RXSTART_INIT) : nextPacketPtr+6;
writeRegPair(ERDPTL, nextPacketPtr);
nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0);
nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
len = readOp(ENC28J60_READ_BUF_MEM, 0);
len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
len -= 4;
rxstat = readOp(ENC28J60_READ_BUF_MEM, 0);
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
if ((rxstat & 0x80) != 0)
{
receivePkt.begin = readPtr;
receivePkt.size = len;
return UIP_RECEIVEBUFFERHANDLE;
}
setERXRDPT();
}
return (NOBLOCK);
}
void Enc28J60Network::setERXRDPT()
{
writeRegPair(ERXRDPTL, nextPacketPtr == RXSTART_INIT ? RXSTOP_INIT : nextPacketPtr-1);
}
memaddress Enc28J60Network::blockSize(memhandle handle)
{
return handle == NOBLOCK ? 0 :
handle == UIP_RECEIVEBUFFERHANDLE ? receivePkt.size : blocks[handle].size;
}
bool Enc28J60Network::sendPacket(memhandle handle)
{
memblock *packet = &blocks[handle];
uint16_t start = packet->begin;
uint16_t end = start + packet->size - 1 - UIP_SENDBUFFER_PADDING;
writeByte(start, 0);
writeRegPair(ETXSTL, start);
writeRegPair(ETXNDL, end);
bool success = false;
for (uint8_t retry = 0; retry < TX_COLLISION_RETRY_COUNT; retry++)
{
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
writeOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF | EIR_TXIF);
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
uint8_t eir;
while (((eir = readReg(EIR)) & (EIR_TXIF | EIR_TXERIF)) == 0);
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
success = ((eir & EIR_TXERIF) == 0);
if (success) break;
uint8_t tsv4 = readByte(end + 4);
if (!(tsv4 & 0b00100000)) break;
}
return success;
}
uint16_t Enc28J60Network::setReadPtr(memhandle handle, memaddress position, uint16_t len)
{
memblock *packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle];
memaddress start = handle == UIP_RECEIVEBUFFERHANDLE &&
packet->begin + position > RXSTOP_INIT ?
packet->begin + position-((RXSTOP_INIT + 1)-RXSTART_INIT) :
packet->begin + position;
writeRegPair(ERDPTL, start);
if (len > packet->size - position) len = packet->size - position;
return len;
}
uint16_t Enc28J60Network::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len)
{
len = setReadPtr(handle, position, len);
readBuffer(len, buffer);
return len;
}
uint16_t Enc28J60Network::writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len)
{
memblock *packet = &blocks[handle];
uint16_t start = packet->begin + position;
if (len > packet->size - position) len = packet->size - position;
if (len == 0) return 0;
writeRegPair(EWRPTL, start);
writeBuffer(len, buffer);
return len;
}
uint8_t Enc28J60Network::readByte(uint16_t addr)
{
writeRegPair(ERDPTL, addr);
CSACTIVE;
bitbang_transfer(ENC28J60_READ_BUF_MEM);
uint8_t c = bitbang_transfer(0x00);
CSPASSIVE;
return c;
}
void Enc28J60Network::writeByte(uint16_t addr, uint8_t data)
{
writeRegPair(EWRPTL, addr);
CSACTIVE;
bitbang_transfer(ENC28J60_WRITE_BUF_MEM);
bitbang_transfer(data);
CSPASSIVE;
}
void Enc28J60Network::copyPacket(memhandle dest_pkt, memaddress dest_pos, memhandle src_pkt, memaddress src_pos, uint16_t len)
{
memblock *dest = &blocks[dest_pkt];
memblock *src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
memaddress start = src_pkt == UIP_RECEIVEBUFFERHANDLE && src->begin + src_pos > RXSTOP_INIT ?
src->begin + src_pos - ((RXSTOP_INIT + 1) - RXSTART_INIT) : src->begin + src_pos;
enc28J60_mempool_block_move_callback(dest->begin + dest_pos, start, len);
}
void enc28J60_mempool_block_move_callback(memaddress dest, memaddress src, memaddress len)
{
if (len == 1)
{
Enc28J60Network::writeByte(dest, Enc28J60Network::readByte(src));
}
else
{
len += src - 1;
Enc28J60Network::writeRegPair(EDMASTL, src);
Enc28J60Network::writeRegPair(EDMADSTL, dest);
if ((src <= RXSTOP_INIT) && (len > RXSTOP_INIT))
len -= ((RXSTOP_INIT + 1)-RXSTART_INIT);
Enc28J60Network::writeRegPair(EDMANDL, len);
Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
Enc28J60Network::writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
while (Enc28J60Network::readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);
}
}
void Enc28J60Network::freePacket()
{
setERXRDPT();
}
uint8_t Enc28J60Network::readOp(uint8_t op, uint8_t address)
{
CSACTIVE;
bitbang_transfer(op | (address & ADDR_MASK));
if (address & 0x80) bitbang_transfer(0x00); // dummy read for MAC/MII
uint8_t c = bitbang_transfer(0x00);
CSPASSIVE;
return c;
}
void Enc28J60Network::writeOp(uint8_t op, uint8_t address, uint8_t data)
{
CSACTIVE;
bitbang_transfer(op | (address & ADDR_MASK));
bitbang_transfer(data);
CSPASSIVE;
}
void Enc28J60Network::readBuffer(uint16_t len, uint8_t* data)
{
CSACTIVE;
bitbang_transfer(ENC28J60_READ_BUF_MEM);
while (len--) *data++ = bitbang_transfer(0x00);
CSPASSIVE;
}
void Enc28J60Network::writeBuffer(uint16_t len, uint8_t* data)
{
CSACTIVE;
bitbang_transfer(ENC28J60_WRITE_BUF_MEM);
while (len--) bitbang_transfer(*data++);
CSPASSIVE;
}
void Enc28J60Network::setBank(uint8_t address)
{
if ((address & BANK_MASK) != bank)
{
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
bank = (address & BANK_MASK);
}
}
uint8_t Enc28J60Network::readReg(uint8_t address)
{
setBank(address);
return readOp(ENC28J60_READ_CTRL_REG, address);
}
void Enc28J60Network::writeReg(uint8_t address, uint8_t data)
{
setBank(address);
writeOp(ENC28J60_WRITE_CTRL_REG, address, data);
}
void Enc28J60Network::writeRegPair(uint8_t address, uint16_t data)
{
setBank(address);
writeOp(ENC28J60_WRITE_CTRL_REG, address, (data & 0xFF));
writeOp(ENC28J60_WRITE_CTRL_REG, address+1, (data >> 8));
}
void Enc28J60Network::phyWrite(uint8_t address, uint16_t data)
{
writeReg(MIREGADR, address);
writeRegPair(MIWRL, data);
while (readReg(MISTAT) & MISTAT_BUSY) delayMicroseconds(15);
}
uint16_t Enc28J60Network::phyRead(uint8_t address)
{
writeReg(MIREGADR, address);
writeReg(MICMD, MICMD_MIIRD);
while (readReg(MISTAT) & MISTAT_BUSY) delayMicroseconds(15);
writeReg(MICMD, 0);
return (readReg(MIRDL) | readReg(MIRDH) << 8);
}
void Enc28J60Network::clkout(uint8_t clk)
{
writeReg(ECOCON, clk & 0x7);
}
uint8_t Enc28J60Network::getrev(void)
{
initSPI();
return readReg(EREVID);
}
uint16_t Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len)
{
uint16_t t;
len = setReadPtr(handle, pos, len) - 1;
CSACTIVE;
bitbang_transfer(ENC28J60_READ_BUF_MEM);
uint16_t i;
for (i = 0; i < len; i += 2)
{
t = bitbang_transfer(0x00) << 8;
t += bitbang_transfer(0x00);
sum += t;
if (sum < t) sum++;
}
if (i == len)
{
t = (bitbang_transfer(0x00) << 8) + 0;
sum += t;
if (sum < t) sum++;
}
CSPASSIVE;
return sum;
}
void Enc28J60Network::powerOff()
{
writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);
delay(50);
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS);
delay(50);
writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
}
void Enc28J60Network::powerOn()
{
writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
delay(50);
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
delay(50);
}
bool Enc28J60Network::linkStatus()
{
return (phyRead(PHSTAT2) & 0x0400) > 0;
}
@@ -0,0 +1,94 @@
/*
Enc28J60NetworkClass.h
UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface.
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
All rights reserved.
inspired by enc28j60.c file from the AVRlib library by Pascal Stang.
For AVRlib See http://www.procyonengineering.com/
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Enc28J60Network_H_
#define Enc28J60Network_H_
#include "mempool.h"
#define UIP_RECEIVEBUFFERHANDLE 0xff
#define UIP_SENDBUFFER_PADDING 7
#define UIP_SENDBUFFER_OFFSET 1
#define TX_COLLISION_RETRY_COUNT 3
//#define ENC28J60DEBUG
/*
* Empfangen von ip-header, arp etc...
* wenn tcp/udp -> tcp/udp-callback -> assign new packet to connection
*/
class Enc28J60Network : public MemoryPool
{
private:
static uint8_t csPin;
static bool spiInitialized;
static uint16_t nextPacketPtr;
static uint8_t bank;
static struct memblock receivePkt;
static uint8_t readOp(uint8_t op, uint8_t address);
static void writeOp(uint8_t op, uint8_t address, uint8_t data);
static uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len);
static void setERXRDPT();
static void readBuffer(uint16_t len, uint8_t* data);
static void writeBuffer(uint16_t len, uint8_t* data);
static uint8_t readByte(uint16_t addr);
static void writeByte(uint16_t addr, uint8_t data);
static void setBank(uint8_t address);
static uint8_t readReg(uint8_t address);
static void writeReg(uint8_t address, uint8_t data);
static void writeRegPair(uint8_t address, uint16_t data);
static void phyWrite(uint8_t address, uint16_t data);
static uint16_t phyRead(uint8_t address);
static void clkout(uint8_t clk);
friend void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress);
public:
static uint8_t getrev(void);
static void powerOn();
static void powerOff();
static bool linkStatus();
static void setCsPin(uint8_t _csPin) {csPin = _csPin;}
static void initSPI();
static bool init(uint8_t* macaddr);
static memhandle receivePacket();
static void freePacket();
static memaddress blockSize(memhandle handle);
static bool sendPacket(memhandle handle);
static uint16_t readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len);
static uint16_t writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len);
static void copyPacket(memhandle dest, memaddress dest_pos, memhandle src, memaddress src_pos, uint16_t len);
static uint16_t chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len);
};
#endif /* Enc28J60NetworkClass_H_ */
@@ -0,0 +1,257 @@
/*****************************************************************************
*
* Title : Microchip ENC28J60 Ethernet Interface Driver
* Author : Pascal Stang (c)2005
* Modified by Norbert Truchsess
* Copyright: GPL V2
*
*This driver provides initialization and transmit/receive
*functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY.
*This chip is novel in that it is a full MAC+PHY interface all in a 28-pin
*chip, using an SPI interface to the host processor.
*
*
*****************************************************************************/
#ifndef ENC28J60_H
#define ENC28J60_H
#include <inttypes.h>
// ENC28J60 Control Registers
// Control register definitions are a combination of address,
// bank number, and Ethernet/MAC/PHY indicator bits.
// - Register address (bits 0-4)
// - Bank number (bits 5-6)
// - MAC/PHY indicator (bit 7)
#define ADDR_MASK 0x1F
#define BANK_MASK 0x60
#define SPRD_MASK 0x80
// All-bank registers
#define EIE 0x1B
#define EIR 0x1C
#define ESTAT 0x1D
#define ECON2 0x1E
#define ECON1 0x1F
// Bank 0 registers
#define ERDPTL (0x00|0x00)
#define ERDPTH (0x01|0x00)
#define EWRPTL (0x02|0x00)
#define EWRPTH (0x03|0x00)
#define ETXSTL (0x04|0x00)
#define ETXSTH (0x05|0x00)
#define ETXNDL (0x06|0x00)
#define ETXNDH (0x07|0x00)
#define ERXSTL (0x08|0x00)
#define ERXSTH (0x09|0x00)
#define ERXNDL (0x0A|0x00)
#define ERXNDH (0x0B|0x00)
#define ERXRDPTL (0x0C|0x00)
#define ERXRDPTH (0x0D|0x00)
#define ERXWRPTL (0x0E|0x00)
#define ERXWRPTH (0x0F|0x00)
#define EDMASTL (0x10|0x00)
#define EDMASTH (0x11|0x00)
#define EDMANDL (0x12|0x00)
#define EDMANDH (0x13|0x00)
#define EDMADSTL (0x14|0x00)
#define EDMADSTH (0x15|0x00)
#define EDMACSL (0x16|0x00)
#define EDMACSH (0x17|0x00)
// Bank 1 registers
#define EHT0 (0x00|0x20)
#define EHT1 (0x01|0x20)
#define EHT2 (0x02|0x20)
#define EHT3 (0x03|0x20)
#define EHT4 (0x04|0x20)
#define EHT5 (0x05|0x20)
#define EHT6 (0x06|0x20)
#define EHT7 (0x07|0x20)
#define EPMM0 (0x08|0x20)
#define EPMM1 (0x09|0x20)
#define EPMM2 (0x0A|0x20)
#define EPMM3 (0x0B|0x20)
#define EPMM4 (0x0C|0x20)
#define EPMM5 (0x0D|0x20)
#define EPMM6 (0x0E|0x20)
#define EPMM7 (0x0F|0x20)
#define EPMCSL (0x10|0x20)
#define EPMCSH (0x11|0x20)
#define EPMOL (0x14|0x20)
#define EPMOH (0x15|0x20)
#define EWOLIE (0x16|0x20)
#define EWOLIR (0x17|0x20)
#define ERXFCON (0x18|0x20)
#define EPKTCNT (0x19|0x20)
// Bank 2 registers
#define MACON1 (0x00|0x40|0x80)
#define MACON2 (0x01|0x40|0x80)
#define MACON3 (0x02|0x40|0x80)
#define MACON4 (0x03|0x40|0x80)
#define MABBIPG (0x04|0x40|0x80)
#define MAIPGL (0x06|0x40|0x80)
#define MAIPGH (0x07|0x40|0x80)
#define MACLCON1 (0x08|0x40|0x80)
#define MACLCON2 (0x09|0x40|0x80)
#define MAMXFLL (0x0A|0x40|0x80)
#define MAMXFLH (0x0B|0x40|0x80)
#define MAPHSUP (0x0D|0x40|0x80)
#define MICON (0x11|0x40|0x80)
#define MICMD (0x12|0x40|0x80)
#define MIREGADR (0x14|0x40|0x80)
#define MIWRL (0x16|0x40|0x80)
#define MIWRH (0x17|0x40|0x80)
#define MIRDL (0x18|0x40|0x80)
#define MIRDH (0x19|0x40|0x80)
// Bank 3 registers
#define MAADR1 (0x00|0x60|0x80)
#define MAADR0 (0x01|0x60|0x80)
#define MAADR3 (0x02|0x60|0x80)
#define MAADR2 (0x03|0x60|0x80)
#define MAADR5 (0x04|0x60|0x80)
#define MAADR4 (0x05|0x60|0x80)
#define EBSTSD (0x06|0x60)
#define EBSTCON (0x07|0x60)
#define EBSTCSL (0x08|0x60)
#define EBSTCSH (0x09|0x60)
#define MISTAT (0x0A|0x60|0x80)
#define EREVID (0x12|0x60)
#define ECOCON (0x15|0x60)
#define EFLOCON (0x17|0x60)
#define EPAUSL (0x18|0x60)
#define EPAUSH (0x19|0x60)
// PHY registers
#define PHCON1 0x00
#define PHSTAT1 0x01
#define PHHID1 0x02
#define PHHID2 0x03
#define PHCON2 0x10
#define PHSTAT2 0x11
#define PHIE 0x12
#define PHIR 0x13
#define PHLCON 0x14
// ENC28J60 ERXFCON Register Bit Definitions
#define ERXFCON_UCEN 0x80
#define ERXFCON_ANDOR 0x40
#define ERXFCON_CRCEN 0x20
#define ERXFCON_PMEN 0x10
#define ERXFCON_MPEN 0x08
#define ERXFCON_HTEN 0x04
#define ERXFCON_MCEN 0x02
#define ERXFCON_BCEN 0x01
// ENC28J60 EIE Register Bit Definitions
#define EIE_INTIE 0x80
#define EIE_PKTIE 0x40
#define EIE_DMAIE 0x20
#define EIE_LINKIE 0x10
#define EIE_TXIE 0x08
#define EIE_WOLIE 0x04
#define EIE_TXERIE 0x02
#define EIE_RXERIE 0x01
// ENC28J60 EIR Register Bit Definitions
#define EIR_PKTIF 0x40
#define EIR_DMAIF 0x20
#define EIR_LINKIF 0x10
#define EIR_TXIF 0x08
#define EIR_WOLIF 0x04
#define EIR_TXERIF 0x02
#define EIR_RXERIF 0x01
// ENC28J60 ESTAT Register Bit Definitions
#define ESTAT_INT 0x80
#define ESTAT_LATECOL 0x10
#define ESTAT_RXBUSY 0x04
#define ESTAT_TXABRT 0x02
#define ESTAT_CLKRDY 0x01
// ENC28J60 ECON2 Register Bit Definitions
#define ECON2_AUTOINC 0x80
#define ECON2_PKTDEC 0x40
#define ECON2_PWRSV 0x20
#define ECON2_VRPS 0x08
// ENC28J60 ECON1 Register Bit Definitions
#define ECON1_TXRST 0x80
#define ECON1_RXRST 0x40
#define ECON1_DMAST 0x20
#define ECON1_CSUMEN 0x10
#define ECON1_TXRTS 0x08
#define ECON1_RXEN 0x04
#define ECON1_BSEL1 0x02
#define ECON1_BSEL0 0x01
// ENC28J60 MACON1 Register Bit Definitions
#define MACON1_LOOPBK 0x10
#define MACON1_TXPAUS 0x08
#define MACON1_RXPAUS 0x04
#define MACON1_PASSALL 0x02
#define MACON1_MARXEN 0x01
// ENC28J60 MACON2 Register Bit Definitions
#define MACON2_MARST 0x80
#define MACON2_RNDRST 0x40
#define MACON2_MARXRST 0x08
#define MACON2_RFUNRST 0x04
#define MACON2_MATXRST 0x02
#define MACON2_TFUNRST 0x01
// ENC28J60 MACON3 Register Bit Definitions
#define MACON3_PADCFG2 0x80
#define MACON3_PADCFG1 0x40
#define MACON3_PADCFG0 0x20
#define MACON3_TXCRCEN 0x10
#define MACON3_PHDRLEN 0x08
#define MACON3_HFRMLEN 0x04
#define MACON3_FRMLNEN 0x02
#define MACON3_FULDPX 0x01
// ENC28J60 MICMD Register Bit Definitions
#define MICMD_MIISCAN 0x02
#define MICMD_MIIRD 0x01
// ENC28J60 MISTAT Register Bit Definitions
#define MISTAT_NVALID 0x04
#define MISTAT_SCAN 0x02
#define MISTAT_BUSY 0x01
// ENC28J60 PHY PHCON1 Register Bit Definitions
#define PHCON1_PRST 0x8000
#define PHCON1_PLOOPBK 0x4000
#define PHCON1_PPWRSV 0x0800
#define PHCON1_PDPXMD 0x0100
// ENC28J60 PHY PHSTAT1 Register Bit Definitions
#define PHSTAT1_PFDPX 0x1000
#define PHSTAT1_PHDPX 0x0800
#define PHSTAT1_LLSTAT 0x0004
#define PHSTAT1_JBSTAT 0x0002
// ENC28J60 PHY PHCON2 Register Bit Definitions
#define PHCON2_FRCLINK 0x4000
#define PHCON2_TXDIS 0x2000
#define PHCON2_JABBER 0x0400
#define PHCON2_HDLDIS 0x0100
// ENC28J60 Packet Control Byte Bit Definitions
#define PKTCTRL_PHUGEEN 0x08
#define PKTCTRL_PPADEN 0x04
#define PKTCTRL_PCRCEN 0x02
#define PKTCTRL_POVERRIDE 0x01
// SPI operation codes
#define ENC28J60_READ_CTRL_REG 0x00
#define ENC28J60_READ_BUF_MEM 0x3A
#define ENC28J60_WRITE_CTRL_REG 0x40
#define ENC28J60_WRITE_BUF_MEM 0x7A
#define ENC28J60_BIT_FIELD_SET 0x80
#define ENC28J60_BIT_FIELD_CLR 0xA0
#define ENC28J60_SOFT_RESET 0xFF
// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
// buffer boundaries applied to internal 8K ram
// the entire available packet buffer space is allocated
//
// start with recbuf at 0/
#define RXSTART_INIT 0x0
// receive buffer end. make sure this is an odd value ( See Rev. B1,B4,B5,B7 Silicon Errata 'Memory (Ethernet Buffer)')
#define RXSTOP_INIT (0x1FFF-0x1800)
// start TX buffer RXSTOP_INIT+1
#define TXSTART_INIT (RXSTOP_INIT+1)
// stp TX buffer at end of mem
#define TXSTOP_INIT 0x1FFF
//
// max frame length which the conroller will accept:
#define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518)
//#define MAX_FRAMELEN 600
#endif
@@ -0,0 +1,168 @@
/*
mempool.cpp - sleek implementation of a memory pool
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mempool.h"
#include <string.h>
#define POOLOFFSET 1
struct memblock MemoryPool::blocks[MEMPOOL_NUM_MEMBLOCKS+1];
void
MemoryPool::init()
{
memset(&blocks[0], 0, sizeof(blocks));
blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS;
blocks[POOLSTART].size = 0;
blocks[POOLSTART].nextblock = NOBLOCK;
}
memhandle
MemoryPool::allocBlock(memaddress size)
{
memblock* best = NULL;
memhandle cur = POOLSTART;
memblock* block = &blocks[POOLSTART];
memaddress bestsize = MEMPOOL_SIZE + 1;
do
{
memhandle next = block->nextblock;
memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) - block->begin - block->size;
if (freesize == size)
{
best = &blocks[cur];
goto found;
}
if (freesize > size && freesize < bestsize)
{
bestsize = freesize;
best = &blocks[cur];
}
if (next == NOBLOCK)
{
if (best)
goto found;
else
goto collect;
}
block = &blocks[next];
cur = next;
}
while (true);
collect:
{
cur = POOLSTART;
block = &blocks[POOLSTART];
memhandle next;
while ((next = block->nextblock) != NOBLOCK)
{
memaddress dest = block->begin + block->size;
memblock* nextblock = &blocks[next];
memaddress* src = &nextblock->begin;
if (dest != *src)
{
#ifdef MEMPOOL_MEMBLOCK_MV
MEMPOOL_MEMBLOCK_MV(dest,*src,nextblock->size);
#endif
*src = dest;
}
block = nextblock;
}
if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size)
best = block;
else
goto notfound;
}
found:
{
block = &blocks[POOLOFFSET];
for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++)
{
if (block->size)
{
block++;
continue;
}
memaddress address = best->begin + best->size;
#ifdef MEMBLOCK_ALLOC
MEMBLOCK_ALLOC(address,size);
#endif
block->begin = address;
block->size = size;
block->nextblock = best->nextblock;
best->nextblock = cur;
return cur;
}
}
notfound: return NOBLOCK;
}
void
MemoryPool::freeBlock(memhandle handle)
{
if (handle == NOBLOCK)
return;
memblock *b = &blocks[POOLSTART];
do
{
memhandle next = b->nextblock;
if (next == handle)
{
memblock *f = &blocks[next];
#ifdef MEMBLOCK_FREE
MEMBLOCK_FREE(f->begin,f->size);
#endif
b->nextblock = f->nextblock;
f->size = 0;
f->nextblock = NOBLOCK;
return;
}
if (next == NOBLOCK)
return;
b = &blocks[next];
}
while (true);
}
void
MemoryPool::resizeBlock(memhandle handle, memaddress position)
{
memblock * block = &blocks[handle];
block->begin += position;
block->size -= position;
}
void
MemoryPool::resizeBlock(memhandle handle, memaddress position, memaddress size)
{
memblock * block = &blocks[handle];
block->begin += position;
block->size = size;
}
memaddress
MemoryPool::blockSize(memhandle handle)
{
return blocks[handle].size;
}
@@ -0,0 +1,54 @@
/*
mempool.h - sleek implementation of a memory pool
Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MEMPOOL_H
#define MEMPOOL_H
#include <inttypes.h>
#define POOLSTART 0
#define NOBLOCK 0
#include "mempool_conf.h"
struct memblock
{
memaddress begin;
memaddress size;
memhandle nextblock;
};
class MemoryPool
{
#ifdef MEMPOOLTEST_H
friend class MemoryPoolTest;
#endif
protected:
static struct memblock blocks[MEMPOOL_NUM_MEMBLOCKS+1];
public:
static void init();
static memhandle allocBlock(memaddress);
static void freeBlock(memhandle);
static void resizeBlock(memhandle handle, memaddress position);
static void resizeBlock(memhandle handle, memaddress position, memaddress size);
static memaddress blockSize(memhandle);
};
#endif
@@ -0,0 +1,34 @@
#ifndef MEMPOOLCONF_H
#define MEMPOOLCONF_H
#include "uipethernet-conf.h"
extern "C" {
#include "uipopt.h"
#include "enc28j60.h"
}
#include <inttypes.h>
typedef uint16_t memaddress;
typedef uint8_t memhandle;
#if UIP_SOCKET_NUMPACKETS and UIP_CONNS
#define NUM_TCP_MEMBLOCKS (UIP_SOCKET_NUMPACKETS*2)*UIP_CONNS
#else
#define NUM_TCP_MEMBLOCKS 0
#endif
#if UIP_UDP and UIP_UDP_CONNS
#define NUM_UDP_MEMBLOCKS ((2+UIP_UDP_BACKLOG)*UIP_UDP_CONNS)
#else
#define NUM_UDP_MEMBLOCKS 0
#endif
#define MEMPOOL_NUM_MEMBLOCKS (NUM_TCP_MEMBLOCKS+NUM_UDP_MEMBLOCKS)
#define MEMPOOL_STARTADDRESS TXSTART_INIT+1
#define MEMPOOL_SIZE TXSTOP_INIT-TXSTART_INIT
void enc28J60_mempool_block_move_callback(memaddress,memaddress,memaddress);
#define MEMPOOL_MEMBLOCK_MV(dest,src,size) enc28J60_mempool_block_move_callback(dest,src,size)
#endif
@@ -0,0 +1,185 @@
/**
* UIPEthernet Project-specific configuration options
* Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
* @{
*
* uIP has a number of configuration options that can be overridden
* for each project. These are kept in a project-specific uip-conf.h
* file and all configuration names have the prefix UIP_CONF.
*/
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack
*
*/
#ifndef __UIP_CONF_H__
#define __UIP_CONF_H__
#include <inttypes.h>
#include "uipethernet-conf.h"
/**
* 8 bit datatype
*
* This typedef defines the 8-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint8_t u8_t;
/**
* 16 bit datatype
*
* This typedef defines the 16-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint16_t u16_t;
/**
* Statistics datatype
*
* This typedef defines the dataype used for keeping statistics in
* uIP.
*
* \hideinitializer
*/
typedef unsigned short uip_stats_t;
/**
* Maximum number of TCP connections.
* (see uipethernet-conf.h)
* \hideinitializer
*
* #define UIP_CONF_MAX_CONNECTIONS 4
*/
/**
* Maximum number of listening TCP ports.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_LISTENPORTS 4
/**
* uIP buffer size.
*
* \hideinitializer
*/
#define UIP_CONF_BUFFER_SIZE 98
//#define UIP_CONF_BUFFER_SIZE 118
/**
* The TCP maximum segment size.
*
* This is should not be to set to more than
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
*/
#define UIP_CONF_TCP_MSS 512
/**
* The size of the advertised receiver's window.
*
* Should be set low (i.e., to the size of the uip_buf buffer) is the
* application is slow to process incoming data, or high (32768 bytes)
* if the application processes data quickly.
*
* \hideinitializer
*/
#define UIP_CONF_RECEIVE_WINDOW 512
/**
* CPU byte order.
*
* \hideinitializer
*/
#define UIP_CONF_BYTE_ORDER __BYTE_ORDER__
/**
* Logging on or off
*
* \hideinitializer
*/
#define UIP_CONF_LOGGING 0
/**
* UDP support on or off
* (see uipethernet-conf.h)
* \hideinitializer
*
* #define UIP_CONF_UDP 1
*
* #define UIP_CONF_UDP_CONNS 4
*/
/**
* UDP checksums on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP_CHECKSUMS 1
/**
* UDP Broadcast (receive) on or off
* (see uipethernet-conf.h)
* \hideinitializer
*/
#define UIP_CONF_BROADCAST 1
/**
* uIP statistics on or off
*
* \hideinitializer
*/
#define UIP_CONF_STATISTICS 0
// SLIP
//#define UIP_CONF_LLH_LEN 0
typedef void* uip_tcp_appstate_t;
void uipclient_appcall(void);
#define UIP_APPCALL uipclient_appcall
typedef void* uip_udp_appstate_t;
void uipudp_appcall(void);
#define UIP_UDP_APPCALL uipudp_appcall
#define CC_REGISTER_ARG register
#define UIP_ARCH_CHKSUM 1
#endif /* __UIP_CONF_H__ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,138 @@
/**
* \addtogroup uip
* {@
*/
/**
* \defgroup uiparch Architecture specific uIP functions
* @{
*
* The functions in the architecture specific module implement the IP
* check sum and 32-bit additions.
*
* The IP checksum calculation is the most computationally expensive
* operation in the TCP/IP stack and it therefore pays off to
* implement this in efficient assembler. The purpose of the uip-arch
* module is to let the checksum functions to be implemented in
* architecture specific assembler.
*
*/
/**
* \file
* Declarations of architecture specific functions.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2001, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $
*
*/
#ifndef __UIP_ARCH_H__
#define __UIP_ARCH_H__
#include "uip.h"
/**
* Carry out a 32-bit addition.
*
* Because not all architectures for which uIP is intended has native
* 32-bit arithmetic, uIP uses an external C function for doing the
* required 32-bit additions in the TCP protocol processing. This
* function should add the two arguments and place the result in the
* global variable uip_acc32.
*
* \note The 32-bit integer pointed to by the op32 parameter and the
* result in the uip_acc32 variable are in network byte order (big
* endian).
*
* \param op32 A pointer to a 4-byte array representing a 32-bit
* integer in network byte order (big endian).
*
* \param op16 A 16-bit integer in host byte order.
*/
void uip_add32(u8_t *op32, u16_t op16);
/**
* Calculate the Internet checksum over a buffer.
*
* The Internet checksum is the one's complement of the one's
* complement sum of all 16-bit words in the buffer.
*
* See RFC1071.
*
* \note This function is not called in the current version of uIP,
* but future versions might make use of it.
*
* \param buf A pointer to the buffer over which the checksum is to be
* computed.
*
* \param len The length of the buffer over which the checksum is to
* be computed.
*
* \return The Internet checksum of the buffer.
*/
u16_t uip_chksum(u16_t *buf, u16_t len);
/**
* Calculate the IP header checksum of the packet header in uip_buf.
*
* The IP header checksum is the Internet checksum of the 20 bytes of
* the IP header.
*
* \return The IP header checksum of the IP header in the uip_buf
* buffer.
*/
u16_t uip_ipchksum(void);
/**
* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
*
* The TCP checksum is the Internet checksum of data contents of the
* TCP segment, and a pseudo-header as defined in RFC793.
*
* \note The uip_appdata pointer that points to the packet data may
* point anywhere in memory, so it is not possible to simply calculate
* the Internet checksum of the contents of the uip_buf buffer.
*
* \return The TCP checksum of the TCP segment in uip_buf and pointed
* to by uip_appdata.
*/
u16_t uip_tcpchksum(void);
u16_t uip_udpchksum(void);
/** @} */
/** @} */
#endif /* __UIP_ARCH_H__ */
@@ -0,0 +1,422 @@
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uiparp uIP Address Resolution Protocol
* @{
*
* The Address Resolution Protocol ARP is used for mapping between IP
* addresses and link level addresses such as the Ethernet MAC
* addresses. ARP uses broadcast queries to ask for the link level
* address of a known IP address and the host which is configured with
* the IP address for which the query was meant, will respond with its
* link level address.
*
* \note This ARP implementation only supports Ethernet.
*/
/**
* \file
* Implementation of the ARP Address Resolution Protocol.
* \author Adam Dunkels <adam@dunkels.com>
*
*/
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
*
*/
#include "uip_arp.h"
#include <string.h>
struct arp_hdr {
struct uip_eth_hdr ethhdr;
u16_t hwtype;
u16_t protocol;
u8_t hwlen;
u8_t protolen;
u16_t opcode;
struct uip_eth_addr shwaddr;
u16_t sipaddr[2];
struct uip_eth_addr dhwaddr;
u16_t dipaddr[2];
};
struct ethip_hdr {
struct uip_eth_hdr ethhdr;
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
};
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_HWTYPE_ETH 1
struct arp_entry {
u16_t ipaddr[2];
struct uip_eth_addr ethaddr;
u8_t time;
};
static const struct uip_eth_addr broadcast_ethaddr =
{{0xff,0xff,0xff,0xff,0xff,0xff}};
static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
static u16_t ipaddr[2];
static u8_t i, c;
static u8_t arptime;
static u8_t tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
/**
* Initialize the ARP module.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_init(void)
{
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(arp_table[i].ipaddr, 0, 4);
}
}
/*-----------------------------------------------------------------------------------*/
/**
* Periodic ARP processing function.
*
* This function performs periodic timer processing in the ARP module
* and should be called at regular intervals. The recommended interval
* is 10 seconds between the calls.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_timer(void)
{
struct arp_entry *tabptr;
++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
memset(tabptr->ipaddr, 0, 4);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
{
register struct arp_entry *tabptr;
/* Walk through the ARP mapping table and try to find an entry to
update. If none is found, the IP -> MAC address mapping is
inserted in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
/* Only check those entries that are actually in use. */
if(tabptr->ipaddr[0] != 0 &&
tabptr->ipaddr[1] != 0) {
/* Check if the source IP address of the incoming packet matches
the IP address in this ARP table entry. */
if(memcmp(ipaddr, tabptr->ipaddr, 4) == 0) {
/* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
return;
}
}
}
/* If we get here, no existing ARP table entry was found, so we
create one. */
/* First, we try to find an unused entry in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(tabptr->ipaddr[0] == 0 &&
tabptr->ipaddr[1] == 0) {
break;
}
}
/* If no unused entry is found, we try to find the oldest entry and
throw it away. */
if(i == UIP_ARPTAB_SIZE) {
tmpage = 0;
c = 0;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(arptime - tabptr->time > tmpage) {
tmpage = arptime - tabptr->time;
c = i;
}
}
i = c;
tabptr = &arp_table[i];
}
/* Now, i is the ARP table entry which we will fill with the new
information. */
memcpy(tabptr->ipaddr, ipaddr, 4);
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
}
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming IP packets
*
* This function should be called by the device driver when an IP
* packet has been received. The function will check if the address is
* in the ARP cache, and if so the ARP cache entry will be
* refreshed. If no ARP cache entry was found, a new one is created.
*
* This function expects an IP packet with a prepended Ethernet header
* in the uip_buf[] buffer, and the length of the packet in the global
* variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
//#if 0
void
uip_arp_ipin(void)
{
uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
//#endif /* 0 */
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming ARP packets.
*
* This function should be called by the device driver when an ARP
* packet has been received. The function will act differently
* depending on the ARP packet type: if it is a reply for a request
* that we previously sent out, the ARP cache will be filled in with
* the values from the ARP reply. If the incoming ARP packet is an ARP
* request for our IP address, an ARP reply packet is created and put
* into the uip_buf[] buffer.
*
* When the function returns, the value of the global variable uip_len
* indicates whether the device driver should send out a packet or
* not. If uip_len is zero, no packet should be sent. If uip_len is
* non-zero, it contains the length of the outbound packet that is
* present in the uip_buf[] buffer.
*
* This function expects an ARP packet with a prepended Ethernet
* header in the uip_buf[] buffer, and the length of the packet in the
* global variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
if(uip_len < sizeof(struct arp_hdr)) {
uip_len = 0;
return;
}
uip_len = 0;
switch(BUF->opcode) {
case HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a
reply. */
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
/* First, we register the one who made the request in our ARP
table, since it is likely that we will do more communication
with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
/* The reply opcode is 2. */
BUF->opcode = HTONS(2);
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_len = sizeof(struct arp_hdr);
}
break;
case HTONS(ARP_REPLY):
/* ARP reply. We insert or update the ARP table if it was meant
for us. */
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
}
break;
}
return;
}
/*-----------------------------------------------------------------------------------*/
/**
* Prepend Ethernet header to an outbound IP packet and see if we need
* to send out an ARP request.
*
* This function should be called before sending out an IP packet. The
* function checks the destination IP address of the IP packet to see
* what Ethernet MAC address that should be used as a destination MAC
* address on the Ethernet.
*
* If the destination IP address is in the local network (determined
* by logical ANDing of netmask and our IP address), the function
* checks the ARP cache to see if an entry for the destination IP
* address is found. If so, an Ethernet header is prepended and the
* function returns. If no ARP cache entry is found for the
* destination IP address, the packet in the uip_buf[] is replaced by
* an ARP request packet for the IP address. The IP packet is dropped
* and it is assumed that they higher level protocols (e.g., TCP)
* eventually will retransmit the dropped packet.
*
* If the destination IP address is not on the local network, the IP
* address of the default router is used instead.
*
* When the function returns, a packet is present in the uip_buf[]
* buffer, and the length of the packet is in the global variable
* uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(void)
{
struct arp_entry *tabptr;
/* Find the destination IP address in the ARP table and construct
the Ethernet header. If the destination IP addres isn't on the
local network, we use the default router's IP address instead.
If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */
/* First check if destination is a local broadcast. */
if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else {
/* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
/* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination
address when determining the MAC address. */
uip_ipaddr_copy(ipaddr, uip_draddr);
} else {
/* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
break;
}
}
if(i == UIP_ARPTAB_SIZE) {
/* The destination address was not in our ARP table, so we
overwrite the IP packet with an ARP request. */
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
}
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr);
}
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */
@@ -0,0 +1,144 @@
/**
* \addtogroup uip
* @{
*/
/**
* \addtogroup uiparp
* @{
*/
/**
* \file
* Macros and definitions for the ARP module.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
*
*/
#ifndef __UIP_ARP_H__
#define __UIP_ARP_H__
#include "uip.h"
extern struct uip_eth_addr uip_ethaddr;
/**
* The Ethernet header.
*/
struct uip_eth_hdr {
struct uip_eth_addr dest;
struct uip_eth_addr src;
u16_t type;
};
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
#define UIP_ETHTYPE_IP6 0x86dd
/* The uip_arp_init() function must be called before any of the other
ARP functions. */
void uip_arp_init(void);
/* The uip_arp_ipin() function should be called whenever an IP packet
arrives from the Ethernet. This function refreshes the ARP table or
inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */
void uip_arp_ipin(void);
//#define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the
Ethernet frame is present in the uip_buf buffer. When the
uip_arp_arpin() function returns, the contents of the uip_buf
buffer should be sent out on the Ethernet if the uip_len variable
is > 0. */
void uip_arp_arpin(void);
/* The uip_arp_out() function should be called when an IP packet
should be sent out on the Ethernet. This function creates an
Ethernet header before the IP header in the uip_buf buffer. The
Ethernet header will have the correct Ethernet MAC destination
address filled in if an ARP table entry for the destination IP
address (or the IP address of the default router) is present. If no
such table entry is found, the IP packet is overwritten with an ARP
request and we rely on TCP to retransmit the packet that was
overwritten. In any case, the uip_len variable holds the length of
the Ethernet frame that should be transmitted. */
void uip_arp_out(void);
/* The uip_arp_timer() function should be called every ten seconds. It
is responsible for flushing old entries in the ARP table. */
void uip_arp_timer(void);
/** @} */
/**
* \addtogroup uipconffunc
* @{
*/
/**
* Specifiy the Ethernet MAC address.
*
* The ARP code needs to know the MAC address of the Ethernet card in
* order to be able to respond to ARP queries and to generate working
* Ethernet headers.
*
* \note This macro only specifies the Ethernet MAC address to the ARP
* code. It cannot be used to change the MAC address of the Ethernet
* card.
*
* \param eaddr A pointer to a struct uip_eth_addr containing the
* Ethernet MAC address of the Ethernet card.
*
* \hideinitializer
*/
#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
uip_ethaddr.addr[1] = eaddr.addr[1];\
uip_ethaddr.addr[2] = eaddr.addr[2];\
uip_ethaddr.addr[3] = eaddr.addr[3];\
uip_ethaddr.addr[4] = eaddr.addr[4];\
uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
/** @} */
/** @} */
#endif /* __UIP_ARP_H__ */
@@ -0,0 +1,48 @@
#ifndef UIPETHERNET_CONF_H
#define UIPETHERNET_CONF_H
// https://github.com/jandrassy/EthernetENC/wiki/Settings
/* for TCP */
#ifndef UIP_SOCKET_NUMPACKETS
#define UIP_SOCKET_NUMPACKETS 3
#endif
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONF_MAX_CONNECTIONS 4
#endif
/* for UDP
* set UIP_CONF_UDP to 0 to disable UDP (saves aprox. 4kB flash) */
#ifndef UIP_CONF_UDP
#define UIP_CONF_UDP 1
#endif
#ifndef UIP_CONF_UDP_CONNS
#define UIP_CONF_UDP_CONNS 2
#endif
/**
* size of received UDP messages backlog. it must be at least 1
*/
#ifndef UIP_UDP_BACKLOG
#define UIP_UDP_BACKLOG 2
#endif
/* timeout in ms for attempts to get a free memory block to write
* before returning number of bytes sent so far
* set to 0 to block until connection is closed by timeout */
#ifndef UIP_WRITE_TIMEOUT
#define UIP_WRITE_TIMEOUT 2000
#endif
/* timeout after which UIPClient::connect gives up. The timeout is specified in seconds.
* if set to a number <= 0 connect will timeout when uIP does (which might be longer than you expect...) */
#ifndef UIP_CONNECT_TIMEOUT
#define UIP_CONNECT_TIMEOUT 5
#endif
/* periodic timer for uip (in ms) */
#ifndef UIP_PERIODIC_TIMER
#define UIP_PERIODIC_TIMER 100
#endif
#endif
@@ -0,0 +1,555 @@
/**
* \defgroup uipopt Configuration options for uIP
* @{
*
* uIP is configured using the per-project configuration file
* uipopt.h. This file contains all compile-time options for uIP and
* should be tweaked to match each specific project. The uIP
* distribution contains a documented example "uipopt.h" that can be
* copied and modified for each project.
*
* \note Most of the configuration options in the uipopt.h should not
* be changed, but rather the per-project uip-conf.h file.
*/
/**
* \file
* Configuration options for uIP.
* \author Adam Dunkels <adam@dunkels.com>
*
* This file is used for tweaking various configuration options for
* uIP. You should make a copy of this file into one of your project's
* directories instead of editing this example "uipopt.h" file that
* comes with the uIP distribution.
*/
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $
*
*/
#ifndef __UIPOPT_H__
#define __UIPOPT_H__
#ifndef UIP_LITTLE_ENDIAN
#if defined(LITTLE_ENDIAN)
#define UIP_LITTLE_ENDIAN LITTLE_ENDIAN
#elif defined(__ORDER_LITTLE_ENDIAN__)
#define UIP_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#else
#define UIP_LITTLE_ENDIAN 1234
#endif
#endif /* UIP_LITTLE_ENDIAN */
#ifndef UIP_BIG_ENDIAN
#if defined(BIG_ENDIAN)
#define UIP_BIG_ENDIAN BIG_ENDIAN
#elif defined(__ORDER_BIG_ENDIAN__)
#define UIP_BIG_ENDIAN __ORDER_BIG_ENDIAN__
#else
#define UIP_BIG_ENDIAN 4321
#endif
#endif /* UIP_BIG_ENDIAN */
#include "uip-conf.h"
/*------------------------------------------------------------------------------*/
/**
* \name Static configuration options
* @{
*
* These configuration options can be used for setting the IP address
* settings statically, but only if UIP_FIXEDADDR is set to 1. The
* configuration options for a specific node includes IP address,
* netmask and default router as well as the Ethernet address. The
* netmask, default router and Ethernet address are appliciable only
* if uIP should be run over Ethernet.
*
* All of these should be changed to suit your project.
*/
/**
* Determines if uIP should use a fixed IP address or not.
*
* If uIP should use a fixed IP address, the settings are set in the
* uipopt.h file. If not, the macros uip_sethostaddr(),
* uip_setdraddr() and uip_setnetmask() should be used instead.
*
* \hideinitializer
*/
#define UIP_FIXEDADDR 0
/**
* Ping IP address asignment.
*
* uIP uses a "ping" packets for setting its own IP address if this
* option is set. If so, uIP will start with an empty IP address and
* the destination IP address of the first incoming "ping" (ICMP echo)
* packet will be used for setting the hosts IP address.
*
* \note This works only if UIP_FIXEDADDR is 0.
*
* \hideinitializer
*/
#ifdef UIP_CONF_PINGADDRCONF
#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
#else /* UIP_CONF_PINGADDRCONF */
#define UIP_PINGADDRCONF 0
#endif /* UIP_CONF_PINGADDRCONF */
/**
* Specifies if the uIP ARP module should be compiled with a fixed
* Ethernet MAC address or not.
*
* If this configuration option is 0, the macro uip_setethaddr() can
* be used to specify the Ethernet address at run-time.
*
* \hideinitializer
*/
#define UIP_FIXEDETHADDR 0
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name IP configuration options
* @{
*
*/
/**
* The IP TTL (time to live) of IP packets sent by uIP.
*
* This should normally not be changed.
*/
#define UIP_TTL 64
/**
* Turn on support for IP packet reassembly.
*
* uIP supports reassembly of fragmented IP packets. This features
* requires an additonal amount of RAM to hold the reassembly buffer
* and the reassembly code size is approximately 700 bytes. The
* reassembly buffer is of the same size as the uip_buf buffer
* (configured by UIP_BUFSIZE).
*
* \note IP packet reassembly is not heavily tested.
*
* \hideinitializer
*/
#define UIP_REASSEMBLY 0
/**
* The maximum time an IP fragment should wait in the reassembly
* buffer before it is dropped.
*
*/
#define UIP_REASS_MAXAGE 40
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name UDP configuration options
* @{
*/
/**
* Toggles wether UDP support should be compiled in or not.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP
#define UIP_UDP UIP_CONF_UDP
#else /* UIP_CONF_UDP */
#define UIP_UDP 0
#endif /* UIP_CONF_UDP */
/**
* Toggles if UDP checksums should be used or not.
*
* \note Support for UDP checksums is currently not included in uIP,
* so this option has no function.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CHECKSUMS
#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
#else
#define UIP_UDP_CHECKSUMS 0
#endif
/**
* The maximum amount of concurrent UDP connections.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CONNS
#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
#else /* UIP_CONF_UDP_CONNS */
#define UIP_UDP_CONNS 10
#endif /* UIP_CONF_UDP_CONNS */
/**
* The name of the function that should be called when UDP datagrams arrive.
*
* \hideinitializer
*/
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name TCP configuration options
* @{
*/
/**
* Determines if support for opening connections from uIP should be
* compiled in.
*
* If the applications that are running on top of uIP for this project
* do not need to open outgoing TCP connections, this configration
* option can be turned off to reduce the code size of uIP.
*
* \hideinitializer
*/
#define UIP_ACTIVE_OPEN 1
/**
* The maximum number of simultaneously open TCP connections.
*
* Since the TCP connections are statically allocated, turning this
* configuration knob down results in less RAM used. Each TCP
* connection requires approximatly 30 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONNS 10
#else /* UIP_CONF_MAX_CONNECTIONS */
#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
#endif /* UIP_CONF_MAX_CONNECTIONS */
/**
* The maximum number of simultaneously listening TCP ports.
*
* Each listening TCP port requires 2 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_LISTENPORTS
#define UIP_LISTENPORTS 20
#else /* UIP_CONF_MAX_LISTENPORTS */
#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
#endif /* UIP_CONF_MAX_LISTENPORTS */
/**
* Determines if support for TCP urgent data notification should be
* compiled in.
*
* Urgent data (out-of-band data) is a rarely used TCP feature that
* very seldom would be required.
*
* \hideinitializer
*/
#define UIP_URGDATA 0
/**
* The initial retransmission timeout counted in timer pulses.
*
* This should not be changed.
*/
#define UIP_RTO 3
/**
* The maximum number of times a segment should be retransmitted
* before the connection should be aborted.
*
* This should not be changed.
*/
#define UIP_MAXRTX 8
/**
* The maximum number of times a SYN segment should be retransmitted
* before a connection request should be deemed to have been
* unsuccessful.
*
* This should not need to be changed.
*/
#define UIP_MAXSYNRTX 5
/**
* The TCP maximum segment size.
*
* This is should not be to set to more than
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
*/
#ifndef UIP_CONF_TCP_MSS
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
#else
#define UIP_TCP_MSS UIP_CONF_TCP_MSS
#endif
/**
* The size of the advertised receiver's window.
*
* Should be set low (i.e., to the size of the uip_buf buffer) is the
* application is slow to process incoming data, or high (32768 bytes)
* if the application processes data quickly.
*
* \hideinitializer
*/
#ifndef UIP_CONF_RECEIVE_WINDOW
#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
#else
#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
#endif
/**
* How long a connection should stay in the TIME_WAIT state.
*
* This configiration option has no real implication, and it should be
* left untouched.
*/
#define UIP_TIME_WAIT_TIMEOUT 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name ARP configuration options
* @{
*/
/**
* The size of the ARP table.
*
* This option should be set to a larger value if this uIP node will
* have many connections from the local network.
*
* \hideinitializer
*/
#ifdef UIP_CONF_ARPTAB_SIZE
#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
#else
#define UIP_ARPTAB_SIZE 8
#endif
/**
* The maxium age of ARP table entries measured in 10ths of seconds.
*
* An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
* default).
*/
#define UIP_ARP_MAXAGE 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name General configuration options
* @{
*/
/**
* The size of the uIP packet buffer.
*
* The uIP packet buffer should not be smaller than 60 bytes, and does
* not need to be larger than 1500 bytes. Lower size results in lower
* TCP throughput, larger size results in higher TCP throughput.
*
* \hideinitializer
*/
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_BUFSIZE 400
#else /* UIP_CONF_BUFFER_SIZE */
#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
#endif /* UIP_CONF_BUFFER_SIZE */
/**
* Determines if statistics support should be compiled in.
*
* The statistics is useful for debugging and to show the user.
*
* \hideinitializer
*/
#ifndef UIP_CONF_STATISTICS
#define UIP_STATISTICS 0
#else /* UIP_CONF_STATISTICS */
#define UIP_STATISTICS UIP_CONF_STATISTICS
#endif /* UIP_CONF_STATISTICS */
/**
* Determines if logging of certain events should be compiled in.
*
* This is useful mostly for debugging. The function uip_log()
* must be implemented to suit the architecture of the project, if
* logging is turned on.
*
* \hideinitializer
*/
#ifndef UIP_CONF_LOGGING
#define UIP_LOGGING 0
#else /* UIP_CONF_LOGGING */
#define UIP_LOGGING UIP_CONF_LOGGING
#endif /* UIP_CONF_LOGGING */
/**
* Broadcast support.
*
* This flag configures IP broadcast support. This is useful only
* together with UDP.
*
* \hideinitializer
*
*/
#if UIP_UDP && UIP_CONF_BROADCAST
#define UIP_BROADCAST UIP_CONF_BROADCAST
#else /* UIP_CONF_BROADCAST */
#define UIP_BROADCAST 0
#endif /* UIP_CONF_BROADCAST */
/**
* Print out a uIP log message.
*
* This function must be implemented by the module that uses uIP, and
* is called by uIP whenever a log message is generated.
*/
void uip_log(char *msg);
/**
* The link level header length.
*
* This is the offset into the uip_buf where the IP header can be
* found. For Ethernet, this should be set to 14. For SLIP, this
* should be set to 0.
*
* \hideinitializer
*/
#ifdef UIP_CONF_LLH_LEN
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
#else /* UIP_CONF_LLH_LEN */
#define UIP_LLH_LEN 14
#endif /* UIP_CONF_LLH_LEN */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name CPU architecture configuration
* @{
*
* The CPU architecture configuration is where the endianess of the
* CPU on which uIP is to be run is specified. Most CPUs today are
* little endian, and the most notable exception are the Motorolas
* which are big endian. The BYTE_ORDER macro should be changed to
* reflect the CPU architecture on which uIP is to be run.
*/
/**
* The byte order of the CPU architecture on which uIP is to be run.
*
* This option can be either BIG_ENDIAN (Motorola byte order) or
* LITTLE_ENDIAN (Intel byte order).
*
* \hideinitializer
*/
#ifdef UIP_CONF_BYTE_ORDER
#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER
#else /* UIP_CONF_BYTE_ORDER */
#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN
#endif /* UIP_CONF_BYTE_ORDER */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name Appication specific configurations
* @{
*
* An uIP application is implemented using a single application
* function that is called by uIP whenever a TCP/IP event occurs. The
* name of this function must be registered with uIP at compile time
* using the UIP_APPCALL definition.
*
* uIP applications can store the application state within the
* uip_conn structure by specifying the type of the application
* structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
*
* The file containing the definitions must be included in the
* uipopt.h file.
*
* The following example illustrates how this can look.
\code
void httpd_appcall(void);
#define UIP_APPCALL httpd_appcall
struct httpd_state {
u8_t state;
u16_t count;
char *dataptr;
char *script;
};
typedef struct httpd_state uip_tcp_appstate_t
\endcode
*/
/**
* \var #define UIP_APPCALL
*
* The name of the application function that uIP should call in
* response to TCP/IP events.
*
*/
/**
* \var typedef uip_tcp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/**
* \var typedef uip_udp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/** @} */
/** @} */
#endif /* __UIPOPT_H__ */
@@ -0,0 +1,10 @@
#ifndef UTIL_H
#define UTIL_H
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
((x)<< 8 & 0x00FF0000UL) | \
((x)>> 8 & 0x0000FF00UL) | \
((x)>>24 & 0x000000FFUL) )
#define ntohl(x) htonl(x)
#endif