1
0
Fork 0

ADDED - Driver: function routines for using hardware checksum capabilities (enc28j60[conf].cpp/h, nic.h).

MODIF - ICMP: Switched to hardware checksum routines.
MODIF - Main: Better output of ip config when in debug mode.
ISSUE - Only the new checksum should be written back to the memory, not the whole packet.

git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/Ethduino@5 b05466c9-153a-0410-ad00-ea1d4d8a27b5
master
mlalondesvn 17 years ago
parent 27a2de3439
commit b004ac562d

@ -114,6 +114,15 @@ void nicReboot(void)
enc28j60Reboot();
}
uint16_t nicGetChecksum(uint8_t* packet, uint16_t len)
{
#ifdef ENC28J60_CHECKSUM_ENABLED
enc28j60getChecksum(packet, len);
#else
return 0x0000;
#endif
}
void enc28j60Reboot(void)
{
#ifndef ENC28J60_HARD_RESET_DISABLED
@ -215,6 +224,68 @@ void enc28j60ReadBuffer(uint16_t len, uint8_t* data)
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
}
uint16_t enc28j60getChecksum(uint8_t* packet, uint16_t len)
//void enc28j60PacketSend(uint16_t len, uint8_t* packet)
{
// Errata workaround #10 Transmit Logic
if (enc28j60Read(EIR) & EIR_TXERIF)
{
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF);
}
// Set the write pointer to start of transmit buffer area
enc28j60Write(EWRPTL, TXSTART_INIT);
enc28j60Write(EWRPTH, TXSTART_INIT>>8);
// Set the TXND pointer to correspond to the packet size given
enc28j60Write(ETXNDL, (TXSTART_INIT+len));
enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
// write per-packet control byte
enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
// copy the packet into the transmit buffer
enc28j60WriteBuffer(len, packet);
// return the calculated checksum
return enc28j60doHardwareChecksum(len);
}
uint16_t enc28j60doHardwareChecksum(uint16_t len)
{
// Set EDMASTL to the beggining of the used memory
enc28j60Write(EDMASTL, TXSTART_INIT);
enc28j60Write(EDMASTH, TXSTART_INIT>>8);
// Set EDMAND to the end of the memory used
enc28j60Write(EDMANDL, (TXSTART_INIT+len));
enc28j60Write(EDMANDH, (TXSTART_INIT+len)>>8);
// Set EDMADST to the beggining of the DMA buffer
enc28j60Write(EDMADSTL, TXSTART_INIT);
enc28j60Write(EDMADSTH, TXSTART_INIT>>8);
// Enable DMA copy mode
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_CSUMEN);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
// Wait for the DMA copy to complete
while(!(enc28j60Read(EIR) & EIR_DMAIF));
// Start the checksum calculation
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_CSUMEN);
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);
// Wait for the checksum calculation to complete
while(!(enc28j60Read(ECON1) & ~ECON1_DMAST && enc28j60Read(EIR) & EIR_DMAIF));
// Read back and return the calculated checksum
return (uint16_t)(enc28j60Read(EDMACSL) | (uint16_t)enc28j60Read(EDMACSH)<<8);
}
void enc28j60WriteBuffer(uint16_t len, uint8_t* data)
{
// assert CS

@ -301,6 +301,9 @@ uint16_t enc28j60PhyRead(uint8_t address);
//! write a PHY register
void enc28j60PhyWrite(uint8_t address, uint16_t data);
uint16_t enc28j60doHardwareChecksum(uint16_t len);
uint16_t enc28j60getChecksum(uint8_t* packet, uint16_t len);
//! initialize the ethernet interface for transmit/receive
/// \return -1 if there was a problem initializing the NIC, otherwise the value is undefined
char enc28j60Init(void);

@ -67,6 +67,9 @@
#define ENC28J60_PACKET_FILTER_ENABLED /* Unimplemented */
#define ENC28J60_LAMPS_MODE 0x3476 /* Default (with Errata #9 correction) applied if this is undefied */
#define ENC28J60_CHECKSUM_ENABLED
/**
* Lamps reference
* 0x3D56 # Default full duplex: LEDA: Display link status and transmit/receive activity LEDB: Display duplex status

@ -26,6 +26,10 @@
#include "HardwareSerial.h"
#endif
#ifdef NET_CHECKSUM_DEBUG
#include "enc28j60.h"
#endif
// functions
void icmpInit(void)
{
@ -48,36 +52,27 @@ void icmpIpIn(icmpip_hdr* packet)
void icmpEchoRequest(icmpip_hdr* packet)
{
uint32_t tempIp, tempId;
uint32_t tempIp;
uint16_t tempId;
// change type to reply
packet->icmp.type = ICMP_TYPE_ECHOREPLY;
// recalculate checksum
packet->icmp.icmpchksum = 0x0000;
packet->icmp.icmpchksum = ipChecksum((netIpHeader*)&packet->icmp, htons(packet->ip.len)-sizeof(netIpHeader));
packet->icmp.icmpchksum = nicGetChecksum((uint8_t*)&packet->icmp, htons(packet->ip.len)-IP_HEADER_LEN);
#ifdef NET_CHECKSUM_DEBUG
SPrintln(" ");
SPrint("ICMP Checksum: 0x");
Serial.print((uint16_t)htons(packet->icmp.icmpchksum), HEX);
SPrint(" 0x");
Serial.println((uint16_t)HTONS(packet->icmp.icmpchksum), HEX);
#endif
#ifdef NET_CHECKSUM_DEBUG
SPrintln(" ");
SPrint("Hardware Checksum: 0x");
Serial.println((uint16_t)HTONS(packet->icmp.icmpchksum), HEX);
#endif
// return to sender
tempIp = packet->ip.destipaddr;
packet->ip.destipaddr = packet->ip.srcipaddr;
packet->ip.srcipaddr = tempIp;
// Set the proper transaction id
tempId = packet->ip.ipid;
packet->ip.ipid = tempId;
tempId = packet->icmp.id;
packet->icmp.id = tempId;
// add ethernet routing
arpIpOut((struct netEthIpHeader*)(((u08*)packet)-ETH_HEADER_LEN), 0);
@ -88,7 +83,7 @@ void icmpEchoRequest(icmpip_hdr* packet)
#endif
// send it (packet->ip.len+ETH_HEADER_LEN
nicSend(htons(packet->ip.len)+ETH_HEADER_LEN, (((u08*)packet)-ETH_HEADER_LEN));
nicSend(htons(packet->ip.len)+ETH_HEADER_LEN, (((uint8_t*)packet)-ETH_HEADER_LEN));
}
#ifdef ICMP_DEBUG_PRINT

@ -31,7 +31,7 @@
#include "net.h"
#define ICMP_DEBUG_PRINT
// #define ICMP_DEBUG_PRINT
//! Initialize ICMP protocol library.
void icmpInit(void);

@ -5,7 +5,6 @@
**/
#include "main.h"
/**
* Network support
**/
@ -21,6 +20,8 @@
#include "ip.h"
#include "icmp.h"
#define PrintIP(ip) netPrintIPAddr(ip); SPrintln(" ")
struct netEthAddr myEthAddress;
// prototypes
@ -112,10 +113,12 @@ void serviceLocal(void)
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
break;
*/
#if defined(NET_DEBUG) || defined(NIC_DEBUG)
#if defined(ARP_DEBUG_PRINT)
case 'a' :
arpPrintTable();
break;
#endif
#if defined(NET_DEBUG) || defined(NIC_DEBUG)
case 'd':
nicRegDump();
break;
@ -144,11 +147,13 @@ void serviceLocal(void)
case 'c':
SPrintln("IP Configs");
SPrint("IP:");
Serial.println(ipGetConfig()->ip);
PrintIP(ipGetConfig()->ip);
SPrint("Gateway:");
Serial.println(ipGetConfig()->gateway);
PrintIP(ipGetConfig()->gateway);
SPrint("Netmask:");
Serial.println(ipGetConfig()->netmask);
PrintIP(ipGetConfig()->netmask);
//SPrint("MAC:");
//netPrintEthAddr(netEthAddr);
break;
/*
case 'x':

@ -30,12 +30,17 @@ uint32_t htonl(uint32_t val)
return (htons(val>>16) | (uint32_t)htons(val&0x0000FFFF)<<16);
}
static uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len)
uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len)
{
uint16_t t;
uint32_t *dataptr;
uint32_t *last_byte;
#ifdef NET_CHECKSUM_DEBUG
SPrint("Length for chksum func: ");
Serial.println((long int)len, HEX);
#endif
dataptr = (uint32_t *) data;
last_byte = (uint32_t *) data + len - 1;

@ -29,7 +29,7 @@
// #define NET_DEBUG 7
//#define NET_CHECKSUM_DEBUG
// #define NET_CHECKSUM_DEBUG
#include "avrlibdefs.h"
#include "avrlibtypes.h"
@ -198,7 +198,7 @@ uint16_t ipChecksum(netIpHeader *data, uint16_t len);
//! Calculate IP Header checksum from data.
uint16_t netChecksum(netIpHeader *data, uint16_t len);
static uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len);
uint16_t generateChecksum(uint16_t sum, netIpHeader *data, uint16_t len);
//! Print Ethernet address in XX:XX:XX:XX:XX:XX format.
void netPrintEthAddr(struct netEthAddr* ethaddr);

@ -44,7 +44,7 @@
#include "ip.h"
#include "nic.h"
// #define NETSTACK_DEBUG
//#define NETSTACK_DEBUG
/// NET_BUFFERSIZE is the common receive/process/transmit buffer.
/// - You may override the default NET_BUFFERSIZE by defining an alternate value in global.h.

@ -27,6 +27,7 @@
#ifndef NIC_H
#define NIC_H
#include "net.h"
// #define NIC_DEBUG
#include <inttypes.h>
@ -81,5 +82,8 @@ void nicSoftReset(void);
//! PHY Chip reboot
void nicReboot(void);
//! PHY Chip hardware checksum, if available
uint16_t nicGetChecksum(uint8_t* packet, uint16_t len);
#endif
//@}

Loading…
Cancel
Save