The Source Code
How look like an ethernet frame and how the protocol works ?
The purpose of this section is to describe the dialog/protocol using ethernet
frames, and more especially the one we will use. To make and understand the
underlying software, we musy
An ethernet frame is a series of bytes, gathered into serial packets sent over
the network. The packet length could be between 32 to 1518 bytes.
Every ethernet devices has a fixed 6 bytes MAC address like 00:50:23:89:FA:04,
this one is unique and provided by a consorsium to avoid same adresses.
In our case, since we don't plan to use our device over very large Local Networks
Area (LAN), we don't care giving any MAC address we want. When two ethernet
devices are connected in a LAN, to be able to communicate with the IP protocol
(or any other protocol), they must ask each other which MAC address correspond
to their IP address, for instance the ethernet device having the 00:50:23:89:FA:04
MAC address, has an IP address such as 134.171.12.124, the other ethernet
device (another PC for instance) has a MAC adress of 00:56:11:33:FC:07 with
an IP address of 134.171.12.127. One can see that the two sets of addresses
are completely decorelated.
The ARP protocol is used to resolve MAC addresses into IP adresses between
devices over the LAN. For that purpose, whenever a PC starts to speak to our
Embedded Ethernet Device (let's call it EED in the following text) having
this IP address 134.171.12.146 , it says : who is 134.171.12.146 ? and which
MAC address does it have ?
This means that our EED MUST respond to ARP request to be identified by a client PC.
This is how look like a ARP REQUEST ethernet frame, sent by the PC to the EED :
| Offset | Value | Type | Offset | Value | Type | Offset | Value | Type |
| 00 | 00 | LengthHigh | 10 | 00 | Hardware Type | 20 | 0C | senders IP address 4 |
| 01 | 3C | LengthLow | 11 | 01 | Hardware Type | 21 | 7F | senders IP address 3 |
| 02 | FF | Dest MAC 1 | 12 | 08 | Protocol Type | 22 | 00 | target hardware addr MAC1 |
| 03 | FF | Dest MAC 2 | 13 | 00 | ProtocolType | 23 | 00 | target hardware addr MAC2 |
| 04 | FF | Dest MAC 3 | 14 | 06 | hardware address length | 24 | 00 | target hardware addr MAC3 |
| 05 | FF | Dest MAC 4 | 15 | 04 | protocol address length | 25 | 00 | target hardware addr MAC4 |
| 06 | FF | Dest MAC 5 | 16 | 00 | ARP operation | 26 | 00 | target hardware addr MAC5 |
| 07 | FF | Dest MAC 6 | 17 | 01 | ARP operation | 27 | 00 | target hardware addr MAC6 |
| 08 | 00 | Src MAC1 | 18 | 00 | senders hardware addr MAC1 | 28 | 86 | target IP address 1 |
| 09 | 50 | Src MAC2 | 19 | 50 | senders hardware addr MAC2 | 29 | AB | target IP address 2 |
| 0A | DA | Src MAC3 | 1A | DA | senders hardware addr MAC3 | 2A | 0C | target IP address 3 |
| 0B | B0 | Src MAC4 | 1B | B0 | senders hardware addr MAC4 | 2B | 23 | target IP address 4 |
| 0C | 6C | Src MAC5 | 1C | 6C | senders hardware addr MAC5 | 2C | ||
| 0D | 57 | Src MAC6 | 1D | 57 | senders hardware addr MAC6 | 2D | ||
| 0E | 08 | TypeProtoHigh(1) | 1E | 86 | senders IP address 1 | 2E | ||
| 0F | 06 | TypeProtoLow(2) | 1F | AB | senders IP address 2 | 2F | ||
ARP operation (1=request, 2=reply)
Type Protocol = $0806 for ARP, $0800 for IP 8137 IPX 8035 RARP
If one use a sofware able to catch ethernet frames coming out form the PC (such
as SNIFFER PRO), this is, for example, a 60 byte frame sent by the PC to the
network to identify our EED :
- Top window indicate that the PC (Laptop called GtwCom548297) has sent a broadcast
ARP request to 134.171.12.146. Broadcast because the target MAC address is FF:FF:FF:FF:FF:FF.
- Middle window has decoded the frame to make it readable (that's very very
nice !!)
- Bottom window shows the raw data (serial bytes from the ethernet frame)

Our EED must respond to ARP request with this frame :

Once an ARP request has been recevied by our EED, we must send back a reply to the requestor (PC laptop or GtwCom548297). Destination and target addresses are swapped and the FF:FF:FF:FF:FF:FF Mac address of our EED is now provided and sent back to the requestor (The PC).
This ARP request process is done every N minutes by the PC to check out devices
over the LAN. So that, the PC maintains a translation table of IP and MAC adresses.
If one issue a ARP -A command in a DOS window, this is what he should get :
| Interface: 134.171.12.94 on Interface 0x2 Internet | ||
| Address (IP) | Physical Address (MAC) | Type |
| 134.171.13.18 | 00-a0-24-c5-82-a8 | dynamic |
| 134.171.13.185 | 00-10-4b-45-a0-d5 | dynamic |
| 134.171.13.199 | 00-00-0c-07-ac-00 | dynamic |
| 134.171.12.146 | 00-00-86-54-82-96 | dynamic |
Now, the PC knows that 134.171.12.146 is 00-00-86-54-82-96, our EED has replied
properly to the PC ARP request.
Our EED does not make any ARP requests over the network, since it behaves like
a server except here :
If our EED has to send packet thru Gateway machines, it must send a broadcast
ARP request to the Gateway (IP of the gateway and MAC dest equal to FF:FF:FF:FF)
otherwise, our EED will mess up completely the network. At ESO, such failure/forgotten
request end up to make crash the whole network (!!). This request to the Gateway
must be done every 5 minutes to allow the gateway to update his ARP table (otherwise
our EED will be forgotten by the Gateway).
Once this process is done, IP dialog can start between the two devices, if
ARP request is not completed, the PC and the EED WILL NOT COMMUNICATE.
STEP 2: PING Discussion
To check that everything is OK, we must PING our embedded ethernet device.
The ping command is well known, especially in the UNIX world ! It consists in
sending an IP frame toward a target and the target replies to sender telling
that everything is OK, I'm alive.
This command is used to debug an IP link between two devices over the network (can be also worldwide used form machine to machine). Our EED responds to PING request so as to check that the connection between the PC and the EED is OK. The Ping request obey to the IP/ICMP protocol. The PC sends a Ping request using this multi-layer protocol encapsulated frame :
Frame coding :| ARP LAYER | IP LAYER | ICMP LAYER |
Echoes request/reply message for PING requests, hereafter a request, IC code is 40 bytes, so 40+20(IP header)=60=0x3C
| Offset | Value | Type | Offset | Value | Type | Offset | Value | Type |
| 00 | 00 | LengthHigh | 10 | 45 | version and header length(in longs), beginning of IP header | 20 | 86 | IP address of target 1 |
| 01 | 4A | LengthLow | 11 | 00 | type of service | 21 | AB | IP address of target 2 |
| 02 | 11 | Dest MAC 1 | 12 | 00 | packet length (length+header_length) | 22 | 0C | IP address of target 3 |
| 03 | 22 | Dest MAC 2 | 13 | 3C | packet length (length+header_length) | 23 | 23 | IP address of target 4; end of IP header, 20 bytes |
| 04 | 33 | Dest MAC 3 | 14 | F0 | datagram id | 24 | 08 | IC Type ** |
| 05 | 44 | Dest MAC 4 | 15 | 0E | datagram id | 25 | 00 | IC code |
| 06 | 55 | Dest MAC 5 | 16 | 00 | fragment offset | 26 | 8D | IC Checksum (header+data ) |
| 07 | 66 | Dest MAC 6 | 17 | 00 | fragment offset | 27 | 5B | IC Checksum (header+data) |
| 08 | 00 | Src MAC1 | 18 | 20 | time to live (in gateway hops) | 28 | 01 | message id |
| 09 | 50 | Src MAC2 | 19 | 01 | protocol * | 29 | 00 | message id |
| 0A | DA | Src MAC3 | 1A | 84 | IP header checksum High | 2A | BF | sequence number |
| 0B | B0 | Src MAC4 | 1B | BA | IP header checksum Low | 2B | 00 | sequence number |
| 0C | 6C | Src MAC5 | 1C | 86 | IP address of source 1 | 2C | 61 | Data.... |
| 0D | 57 | Src MAC6 | 1D | AB | IP address of source 2 | 2D | 62 | Data.... |
| 0E | 08 | TypeProtoHigh | 1E | 0C | IP address of source 3 | 2E | 63 | Data.... |
| 0F | 00 | TypeProtoLow | 1F | 7F | IP address of source 4 | 2F | 64 | Data .... |
* protocol (ICMP=1, TCP=6, EGP=8, UDP=17)
** IC types : 0=reply, 8=request, others=who-cares
The IP checksum algorithm at offsets 1A and 1B: The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header. For purposes of computing the checksum, the value of the checksum field is zero. IP checksum concerns ONLY IP data field (nor ICMP, neither whatever).
For instance if the IP header data from above is used from offset 10 to 23 :
Const Data:Array [1..10] of Word=($4500,$003C,$F00E,$0000,$2001,$0000,$86AB,$0C7F,$86AB,$0C23); // $84BA
The result is $84BA as seen at offsets 1A and 1B.
This routine works is the number of data is even. if not the last data has to be turned into a 16 bit value.
In Pascal
Var i,Inter:Integer; //32 bits
Cksum:Word; //16 bits
begin
Inter:=0;
For i:=1 to 10 do Inter:=Inter+Data[i];
Cksum:=((Inter and $FFFF) + (Inter shr 16)) Xor $FFFF;
end;
in C :
u_short checksum(u_short * data,u_short length)
{
register long value;
u_short i;
for(i=0;i<(length>>1);i++) value+=data[i]; // add
if((length&1)==1) value+=(data[i]<<8); // compensate of odd amount of datas
value=(value&65535)+(value>>16); // complements one to one
return(~value); // XOR the result
}
ICMP cheksum :
The checksum is the 16-bit one's complement of the one's complement sum of the entire ICMPv6 message starting with the ICMPv6 message type field, prepended with a "pseudo-header" of IPv6 header fields. The Next Header value used in the pseudo-header is 58. (NOTE: the inclusion of a pseudo-header in the ICMPv6 checksum is a change from IPv4; see [IPv6] for the rationale for this change.) For computing the checksum, the checksum field is set to zero. The data range is offset 24 to the last data byte at the end of the ICMP frame.
Once the EED has received an ICMP frame, it decodes it so as to check that this frame is intended for him.
Our EED, then SWAP the target destination adresses and fill the offset 24 with a reply code. The IP/ICMP frame is sent to the requestor.
This DOS command window shows the results issued from a PING command send to
our EED (134.171.12.146), obviously it works, our EED responds in less than
10ms over the LAN.

The following windows show a captured data form the network board displaying Ping (ICMP) request form my PC (134.171.73.42) to the EED (134.171.73.45) and the reply.

STEP 3: The final IP/UDP discussion
The UDP protocol has been chosen to exchange datas between our EED and the PC. We have secured this UDP handshakes scheme to avoid any packets losses. Why didn't we use TCP/IP instead of UPD/IP ? If one looks to the TCP/IP protocol specification compared to the UDP, the TCP/IP is really less straightforward to implement to a 8 bit SX52 microcontroller. TCP/IP has a large header, which can end up to non-negligeable overheads. Since we use handshaked UDP protocol, packet losses has been completely overcome by the use of a 2K SRAM. It allows to store the all IP frame in the EED and to re-send the frame to the PC if necessary. First of all, let's have a look to the UDP protocol.
IP/UDP
Frame coding :
| ARP LAYER | IP LAYER | UDP LAYER |
| Offset | Value | Type | Offset | Value | Type | Offset | Value | Type | |
| SX52 Bank $20 | SX52 Bank $30 | SX52 Bank $40 | |||||||
| 00 | LengthHigh | 10 | 45 | version and header length(in longs) | 20 | 86 | IP address of target 1 % | ||
| 01 | LengthLow | 11 | 00 | type of service | 21 | AB | IP address of target 2 % | ||
| 02 | 00 | Dest MAC 1 | 12 | 00 | packet length (length+header_length) | 22 | 49 | IP address of target 3 % | |
| 03 | 11 | Dest MAC 2 | 13 | 1E | packet length (length+header_length) | 23 | 2D | IP address of target 4 % | |
| 04 | 86 | Dest MAC 3 | 14 | 18 | datagram id | 24 | 00 | UDP Source Port Number High | |
| 05 | 54 | Dest MAC 4 | 15 | 55 | datagram id | 25 | BF | UDP Source Port Number Low | |
| 06 | 80 | Dest MAC 5 | 16 | 00 | fragment offset | 26 | 00 | UDP Destination port Number High | |
| 07 | 96 | Dest MAC 6 | 17 | 00 | fragment offset | 27 | BF | UDP Destination port Number Low | |
| 08 | 00 | Src MAC1 | 18 | 80 | time to live TTL | 28 | 00 | Length of UDP (header+data) High % | |
| 09 | 00 | Src MAC2 | 19 | 11 | IP protocol % UDP | 29 | 0A | Length of UDP (header+data) Low % | |
| 0A | E8 | Src MAC3 | 1A | 82 | header checksum | 2A | DD | ** Checksum High, not critical can be eventually set to zero | |
| 0B | D7 | Src MAC4 | 1B | CC | header checksum | 2B | AD | ** Checksum Low, not critical can be eventually set to zero | |
| 0C | B5 | Src MAC5 | 1C | 86 | IP address of source 1 % | 2C | XX | Data1 (Data length must be EVEN) |
Here, we can use it as we want !!
|
| 0D | 9F | Src MAC6 | 1D | AB | IP address of source 2 % | 2D | XX | Data2 |
Here, we can use it as we want !!
|
| 0E | 08 | TypeProtoHigh | 1E | 49 | IP address of source 3 % | 2E | XX | Data3. |
Here, we can use it as we want !!
|
| 0F | 00 | TypeProtoLow | 1F | 2A | IP address of source 4 % | 2F | XX | .... |
........
|
** Note: UDP checksum is calculated by taking the 16 bit sums of :
- IP address of source : 2 x 16 bits words at offsets 1C to 1F
- IP address of target : 2 x 16 bits words at offsets 20 to 23
- IP protocol : 8 bits words at offset 19, padded with a zero high byte to make
a 16 bit word.
- Length of UDP frame (header+Data) : 2x 16 bits words at offsets 28-29
- Finally, the sum starting at UDP Source Port Number, offset 24
Yes, this means that Length of UDP word is taken twice! Cksum word is zero during
the calculation. The sum is then one's complemented, as all previous checksums.
% = means that the first UDP checksum is computed using those value !
The table shows a standard UDP frame, what's interest us is the part Data1, Data2 and so on... because we can write here whatever we want, up to 1500 bytes per frames. As a reply, we send this kind of frame with swapped addresses and UDP port, the checksum is left to $0000 for the reply.

How the handshake UDP protocol has been implemented ?
This is for instance a complete sequence for a single event : it consists in 4 frames.
Step 1 : PC send an UDP frame to the EED, the UDP data section contains
something like "Do something..." coded as $82,$01,$03, Herefter, this
is frame number 6.
Step 2 : EED sends back to the PC an UDP frame, the UDP data section
contains something like "Ok, I'm alive..." coded as $82,$01, Hereafter,
this is frame number 7.
Step 3 : EED sends to the PC an UDP frame, the UDP data section contains
something like "Ok, This is the DATA you requested from step 1..."
coded as series of datas, this is frame number 8, the one selected on the window.
Step 4 : PC acknowledge the frame from the EED, the UDP data section
contains something like "Ok, all data received..." Here after this
is frame number 9.
Step 2 is necessary to check that the request from the PC has not been lost somewhere, if step 2 is not fullfilled, the PC raises a timeout/connection error with the EED.
Just after step 2, the PC starts a timeout counter, excepting step 3 coming, if nothing comes from EED, it raises a timeout error.
Step 4 is necessary to check that the data from the EED has not been lost somewhere, if step 4 is not fullfilled, the EED sends the data again, up to N times (N can be defined as we want...) and gives up if N is reached. N can be indefinite.

How this can be applied ?
For instance, let's consider the opening of a shutter controlled by the EED :
Step 1 : PC send an UDP frame to the EED, the UDP data section contains
codes/bytes that will be interpreted like "Open the shutter" by the
EED.
Step 2 : EED sends back to the PC an UDP frame, the UDP data section
contains codes/bytes that will be interpreted by the PC like "EED is alive,
request properly received and will be processed" by the EED.
Step 3 : EED sends to the PC an UDP frame, the UDP data section contains
codes/bytes that will be interpreted by the PC like "EED has opened the
shutter".
Step 4 : PC acknowledge the frame from the EED, the UDP data section
contains codes/bytes that will be interpreted by the EED like "OK, done.."
This protocol is secure : It was used to read a CCD camera, the RJ45 wire was disconnected for a while and connected back, the reading out of the rest of the CCD data went fine and no pixel losses.
The embedded ethernet controller SX52 micro-controller source code
The scenix SX52 is the core of our EED, controlling the ethernet circuit cs8900, the 2 FIFOs and the SRAM. The Sx52 read/write frames to cs8900, decode incoming frames, build response frames, send/read data/commands to the 2 FIFOs. The following source code comes as it whithout any warranties.
The slave microcontroller source code
- PIC16c74 microcontroller
This is, for instance the code employed for the PIC16C74 small temperature board.
Another example, this is the code to control a CCD camera- Another SX52 microcontroller
Coming soon.... when ready....
Delphi source code
- Code used to debug CCD communication (Delphi), Oct 2000, this code communicates with the SX52 V5.00 release code. This delphi code is also mandatory to compile the previous code.