User | Revision | Line number | New contents of line |
hudakz |
0:ca476e0a1a28
|
1
|
#ifndef RAW_ETHERNET_H
|
hudakz |
0:ca476e0a1a28
|
2
|
#define RAW_ETHERNET_H
|
hudakz |
0:ca476e0a1a28
|
3
|
|
hudakz |
0:ca476e0a1a28
|
4
|
#include "mbed.h"
|
hudakz |
0:ca476e0a1a28
|
5
|
|
hudakz |
0:ca476e0a1a28
|
6
|
//------------------------------------------------------------------------------
|
hudakz |
0:ca476e0a1a28
|
7
|
// Functions for using an ENC28J60 ethernet controller, optimized for
|
hudakz |
0:ca476e0a1a28
|
8
|
// communication speed.
|
hudakz |
0:ca476e0a1a28
|
9
|
//
|
hudakz |
0:ca476e0a1a28
|
10
|
// Written by Rogier Schouten for AVR micro controllers http://www.rogiershikes.tk
|
hudakz |
0:ca476e0a1a28
|
11
|
// Based on code by Guido Socher http://www.tuxgraphics.org
|
hudakz |
0:ca476e0a1a28
|
12
|
// Idea modified and further updated by Guido Socher
|
hudakz |
0:ca476e0a1a28
|
13
|
// Ported to MBED by Zoltan Hudak hudakz@outlook.com
|
hudakz |
0:ca476e0a1a28
|
14
|
// License: GPL V2
|
hudakz |
0:ca476e0a1a28
|
15
|
//
|
hudakz |
0:ca476e0a1a28
|
16
|
// Enables to read sensor data or control IO-ports with less than a millisecond delay.
|
hudakz |
0:ca476e0a1a28
|
17
|
// The trick is in removing the TCP/IP overhead and use raw Ethernet frames.
|
hudakz |
0:ca476e0a1a28
|
18
|
// A Linux application using raw network sockets is controlling this slave device.
|
hudakz |
0:ca476e0a1a28
|
19
|
//
|
hudakz |
0:ca476e0a1a28
|
20
|
// Assumptions:
|
hudakz |
0:ca476e0a1a28
|
21
|
// - Max. payload data: 255 bytes per packet
|
hudakz |
0:ca476e0a1a28
|
22
|
// - The network consists of a master PC and one or more slave devices.
|
hudakz |
0:ca476e0a1a28
|
23
|
// Only plain hubs and switches are allowed between PC and ethernet device.
|
hudakz |
0:ca476e0a1a28
|
24
|
// Note that some wlan routers have internal switches which switch only
|
hudakz |
0:ca476e0a1a28
|
25
|
// IP packets. They will discard plain ethernet frames. A normal 100Mbit
|
hudakz |
0:ca476e0a1a28
|
26
|
// office/workgroup switch will however work.
|
hudakz |
0:ca476e0a1a28
|
27
|
//
|
hudakz |
0:ca476e0a1a28
|
28
|
// Based on these assumptions, we can optimize the protocol for faster communication:
|
hudakz |
0:ca476e0a1a28
|
29
|
// - Master and slave send unicast packets.
|
hudakz |
0:ca476e0a1a28
|
30
|
// - We use raw ethernet and no higher-level protocol such as UDP or TCP/IP
|
hudakz |
0:ca476e0a1a28
|
31
|
// - We use the EtherType field of a packet as a length field. Actually, we only
|
hudakz |
0:ca476e0a1a28
|
32
|
// use one byte of it since we have max 255 length packets.
|
hudakz |
0:ca476e0a1a28
|
33
|
//
|
hudakz |
0:ca476e0a1a28
|
34
|
// Furthermore, there are a few code optimizations:
|
hudakz |
0:ca476e0a1a28
|
35
|
// - Minimize communication between ENC and MCU.
|
hudakz |
0:ca476e0a1a28
|
36
|
// - No unnecessary memory bank checks
|
hudakz |
0:ca476e0a1a28
|
37
|
//
|
hudakz |
0:ca476e0a1a28
|
38
|
|
hudakz |
0:ca476e0a1a28
|
39
|
class RawEthernet
|
hudakz |
0:ca476e0a1a28
|
40
|
{
|
hudakz |
0:ca476e0a1a28
|
41
|
public:
|
hudakz |
0:ca476e0a1a28
|
42
|
/**
|
hudakz |
0:ca476e0a1a28
|
43
|
* Constructor
|
hudakz |
0:ca476e0a1a28
|
44
|
*
|
hudakz |
0:ca476e0a1a28
|
45
|
* \param mosi mbed pin to use SPI
|
hudakz |
0:ca476e0a1a28
|
46
|
* \param miso mbed pin to use SPI
|
hudakz |
0:ca476e0a1a28
|
47
|
* \param sclk mbed pin to use SPI
|
hudakz |
0:ca476e0a1a28
|
48
|
* \param cs pin to select the ENC28J60 chip
|
hudakz |
0:ca476e0a1a28
|
49
|
*/
|
hudakz |
0:ca476e0a1a28
|
50
|
RawEthernet(PinName mosi, PinName miso, PinName sclk, PinName cs, uint8_t myMac[6], uint8_t myIp[4]);
|
hudakz |
0:ca476e0a1a28
|
51
|
void linkTo(uint8_t remoteMac[6]);
|
hudakz |
0:ca476e0a1a28
|
52
|
void packetSend(uint16_t len, uint8_t* packet);
|
hudakz |
0:ca476e0a1a28
|
53
|
bool isLinkUp(void);
|
hudakz |
0:ca476e0a1a28
|
54
|
uint8_t receive(uint8_t* buf, uint8_t maxlen);
|
hudakz |
0:ca476e0a1a28
|
55
|
void gratuitousArp();
|
hudakz |
0:ca476e0a1a28
|
56
|
void send(uint8_t* buf, uint8_t len);
|
hudakz |
0:ca476e0a1a28
|
57
|
uint8_t getRev(void);
|
hudakz |
0:ca476e0a1a28
|
58
|
protected:
|
hudakz |
0:ca476e0a1a28
|
59
|
uint8_t readOp(uint8_t op, uint8_t address);
|
hudakz |
0:ca476e0a1a28
|
60
|
void writeOp(uint8_t op, uint8_t address, uint8_t data);
|
hudakz |
0:ca476e0a1a28
|
61
|
uint8_t readReg(uint8_t address);
|
hudakz |
0:ca476e0a1a28
|
62
|
void writeReg(uint8_t address, uint8_t data);
|
hudakz |
0:ca476e0a1a28
|
63
|
void setBank(uint8_t address);
|
hudakz |
0:ca476e0a1a28
|
64
|
void readBuffer(uint16_t len, uint8_t* data);
|
hudakz |
0:ca476e0a1a28
|
65
|
void writeBuffer(uint16_t len, uint8_t* data);
|
hudakz |
0:ca476e0a1a28
|
66
|
uint16_t phyReadH(uint8_t address);
|
hudakz |
0:ca476e0a1a28
|
67
|
void phyWrite(uint8_t address, uint16_t data);
|
hudakz |
0:ca476e0a1a28
|
68
|
private:
|
hudakz |
0:ca476e0a1a28
|
69
|
SPI _spi;
|
hudakz |
0:ca476e0a1a28
|
70
|
DigitalOut _cs;
|
hudakz |
0:ca476e0a1a28
|
71
|
uint8_t _bank;
|
hudakz |
0:ca476e0a1a28
|
72
|
int16_t _nextPacketPtr;
|
hudakz |
0:ca476e0a1a28
|
73
|
uint8_t _lastTransmitPayloadLen;
|
hudakz |
0:ca476e0a1a28
|
74
|
uint8_t _mac[6];
|
hudakz |
0:ca476e0a1a28
|
75
|
uint8_t _ip[4];
|
hudakz |
0:ca476e0a1a28
|
76
|
uint8_t _remoteMac[6];
|
hudakz |
0:ca476e0a1a28
|
77
|
static char _arpReqHdr[10];
|
hudakz |
0:ca476e0a1a28
|
78
|
};
|
hudakz |
0:ca476e0a1a28
|
79
|
#endif // RAW_ETHERNET_H
|