Enables fast realtime communication over Ethernet by using plain Ethernet frames (overhead of TCP/IP network layers is stripped away).
RawEthernet.h@0:ca476e0a1a28, 2018-08-20 (annotated)
- Committer:
- hudakz
- Date:
- Mon Aug 20 11:37:35 2018 +0000
- Revision:
- 0:ca476e0a1a28
Initial release.
Who changed what in which revision?
| 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 |