Stefan Schuermans commited on 2012-03-17 01:03:19
Showing 14 changed files, with 546 additions and 109 deletions.
... | ... |
@@ -15,7 +15,7 @@ |
15 | 15 |
</top_modules> |
16 | 16 |
</db_ref> |
17 | 17 |
</db_ref_list> |
18 |
- <WVObjectSize size="13" /> |
|
18 |
+ <WVObjectSize size="19" /> |
|
19 | 19 |
<wvobject fp_name="/e_testbed/s_clk" type="logic" db_ref_id="1"> |
20 | 20 |
<obj_property name="ElementShortName">s_clk</obj_property> |
21 | 21 |
<obj_property name="ObjectShortName">s_clk</obj_property> |
... | ... |
@@ -74,4 +74,34 @@ |
74 | 74 |
<obj_property name="ObjectShortName">i_instr_data[31:0]</obj_property> |
75 | 75 |
<obj_property name="Radix">HEXRADIX</obj_property> |
76 | 76 |
</wvobject> |
77 |
+ <wvobject fp_name="/e_testbed/system/eth/r_rx_start" type="array" db_ref_id="1"> |
|
78 |
+ <obj_property name="ElementShortName">r_rx_start[31:0]</obj_property> |
|
79 |
+ <obj_property name="ObjectShortName">r_rx_start[31:0]</obj_property> |
|
80 |
+ <obj_property name="Radix">HEXRADIX</obj_property> |
|
81 |
+ </wvobject> |
|
82 |
+ <wvobject fp_name="/e_testbed/system/eth/r_rx_cur" type="array" db_ref_id="1"> |
|
83 |
+ <obj_property name="ElementShortName">r_rx_cur[31:0]</obj_property> |
|
84 |
+ <obj_property name="ObjectShortName">r_rx_cur[31:0]</obj_property> |
|
85 |
+ <obj_property name="Radix">HEXRADIX</obj_property> |
|
86 |
+ </wvobject> |
|
87 |
+ <wvobject fp_name="/e_testbed/system/eth/r_rx_size" type="array" db_ref_id="1"> |
|
88 |
+ <obj_property name="ElementShortName">r_rx_size[31:0]</obj_property> |
|
89 |
+ <obj_property name="ObjectShortName">r_rx_size[31:0]</obj_property> |
|
90 |
+ <obj_property name="Radix">HEXRADIX</obj_property> |
|
91 |
+ </wvobject> |
|
92 |
+ <wvobject fp_name="/e_testbed/system/eth/r_rx_end" type="array" db_ref_id="1"> |
|
93 |
+ <obj_property name="ElementShortName">r_rx_end[31:0]</obj_property> |
|
94 |
+ <obj_property name="ObjectShortName">r_rx_end[31:0]</obj_property> |
|
95 |
+ <obj_property name="Radix">HEXRADIX</obj_property> |
|
96 |
+ </wvobject> |
|
97 |
+ <wvobject fp_name="/e_testbed/system/eth/r_rx_new_start" type="array" db_ref_id="1"> |
|
98 |
+ <obj_property name="ElementShortName">r_rx_new_start[31:0]</obj_property> |
|
99 |
+ <obj_property name="ObjectShortName">r_rx_new_start[31:0]</obj_property> |
|
100 |
+ <obj_property name="Radix">HEXRADIX</obj_property> |
|
101 |
+ </wvobject> |
|
102 |
+ <wvobject fp_name="/e_testbed/system/eth/r_rx_new_end" type="array" db_ref_id="1"> |
|
103 |
+ <obj_property name="ElementShortName">r_rx_new_end[31:0]</obj_property> |
|
104 |
+ <obj_property name="ObjectShortName">r_rx_new_end[31:0]</obj_property> |
|
105 |
+ <obj_property name="Radix">HEXRADIX</obj_property> |
|
106 |
+ </wvobject> |
|
77 | 107 |
</wave_config> |
... | ... |
@@ -0,0 +1,227 @@ |
1 |
+#include "arp.h" |
|
2 |
+#include "config.h" |
|
3 |
+#include "ethernet.h" |
|
4 |
+// TODO #include "ip.h" |
|
5 |
+#include "macros.h" |
|
6 |
+#include "nethelp.h" |
|
7 |
+ |
|
8 |
+// timing parameters |
|
9 |
+#define ARP_TICKS_MAX (150) /**< maximum age of ARP table entries |
|
10 |
+ (in 200ms steps) */ |
|
11 |
+#define ARP_NO_MAC_TICKS_MAX (50) /**< maximum age of ARP table entries |
|
12 |
+ without MAC (in 200ms steps) */ |
|
13 |
+#define ARP_RETRY_TICKS (8) /**< time after which to retry ARP query |
|
14 |
+ (must be power of 2, in 200ms steps) */ |
|
15 |
+ |
|
16 |
+/// ARP table |
|
17 |
+#define ARP_TAB_FLAG_IN_USE (1) |
|
18 |
+#define ARP_TAB_FLAG_MAC_OK (2) |
|
19 |
+struct arp_table |
|
20 |
+{ |
|
21 |
+ unsigned char flags; /// flags - see constants |
|
22 |
+ unsigned char ticks; /// age of entry in 200ms steps |
|
23 |
+ unsigned char mac[6]; |
|
24 |
+ unsigned char ip[4]; |
|
25 |
+} arp_tab[12]; |
|
26 |
+ |
|
27 |
+/** |
|
28 |
+ * @brief send an ARP request |
|
29 |
+ * @param[in] ip IP address to query MAC for |
|
30 |
+ */ |
|
31 |
+static void arp_send_request(unsigned char ip[4]) |
|
32 |
+{ |
|
33 |
+ struct arp_packet arp_request; |
|
34 |
+ |
|
35 |
+ // build ARP request |
|
36 |
+ arp_request.arp_hdr.hw_type = htons(0x0001); // ethernet |
|
37 |
+ arp_request.arp_hdr.proto_type = htons(0x0800); // IP |
|
38 |
+ arp_request.arp_hdr.hw_len = 0x06; // length of a MAC address |
|
39 |
+ arp_request.arp_hdr.proto_len = 0x04; // length of an IP address |
|
40 |
+ arp_request.arp_hdr.op = htons(0x0001); // ARP request |
|
41 |
+ mac_cpy(arp_request.arp_hdr.src_mac, config_mac.mac); // own MAC |
|
42 |
+ ip_cpy(arp_request.arp_hdr.src_ip, config_ip.ip); // own IP |
|
43 |
+ mac_cpy(arp_request.arp_hdr.dest_mac, |
|
44 |
+ "\xFF\xFF\xFF\xFF\xFF\xFF"); // broadcast MAC |
|
45 |
+ ip_cpy(arp_request.arp_hdr.dest_ip, ip); // requested IP |
|
46 |
+ |
|
47 |
+ // send ARP request |
|
48 |
+ mac_cpy(arp_request.eth_hdr.dest, arp_request.arp_hdr.dest_mac); |
|
49 |
+ arp_request.eth_hdr.type = htons(0x0806); // ethernet packet type: ARP |
|
50 |
+ ethernet_send(&arp_request, sizeof(arp_request)); |
|
51 |
+} |
|
52 |
+ |
|
53 |
+/// initialize |
|
54 |
+/* extern */ void arp_init(void) |
|
55 |
+{ |
|
56 |
+ unsigned int i; |
|
57 |
+ |
|
58 |
+ // empty ARP table |
|
59 |
+ for (i = 0; i < count(arp_tab); ++i) |
|
60 |
+ arp_tab[i].flags = 0; |
|
61 |
+} |
|
62 |
+ |
|
63 |
+/// tick procedure - call every 200ms |
|
64 |
+/* extern */ void arp_tick200(void) |
|
65 |
+{ |
|
66 |
+ unsigned int i; |
|
67 |
+ |
|
68 |
+ // increase age of ARP table entires and remove timed out ones |
|
69 |
+ for (i = 0; i < count(arp_tab); ++i) { |
|
70 |
+ // entry in use |
|
71 |
+ if (arp_tab[i].flags & ARP_TAB_FLAG_IN_USE) { |
|
72 |
+ arp_tab[i].ticks++; // increase age |
|
73 |
+ // entry has a MAC |
|
74 |
+ if (arp_tab[i].flags & ARP_TAB_FLAG_MAC_OK) { |
|
75 |
+ if (arp_tab[i].ticks > ARP_TICKS_MAX) // too old |
|
76 |
+ arp_tab[i].flags = 0; // remove entry |
|
77 |
+ } |
|
78 |
+ // entry does not have a MAC |
|
79 |
+ else { |
|
80 |
+ if (arp_tab[i].ticks > ARP_NO_MAC_TICKS_MAX) // too old |
|
81 |
+ arp_tab[i].flags = 0; // remove entry |
|
82 |
+ else if ((arp_tab[i].ticks & (ARP_RETRY_TICKS - 1)) == 0) // re-request |
|
83 |
+ arp_send_request(arp_tab[i].ip); |
|
84 |
+ } |
|
85 |
+ } |
|
86 |
+ } |
|
87 |
+} |
|
88 |
+ |
|
89 |
+/** |
|
90 |
+ * @brief process a received ARP packet |
|
91 |
+ * @param[in] ptr pointer to data of packet |
|
92 |
+ * @param[in] sz size of packet |
|
93 |
+ */ |
|
94 |
+/* extern */ void arp_recv(void *ptr, unsigned int sz) |
|
95 |
+{ |
|
96 |
+ struct arp_packet *arp_pack; |
|
97 |
+ |
|
98 |
+ // packet too short |
|
99 |
+ if (sz < sizeof(struct arp_packet)) |
|
100 |
+ return; |
|
101 |
+ |
|
102 |
+ arp_pack = (struct arp_packet *)ptr; |
|
103 |
+ |
|
104 |
+ // not IP over ethernet |
|
105 |
+ if (arp_pack->arp_hdr.hw_type != htons(0x0001) || // ethernet |
|
106 |
+ arp_pack->arp_hdr.proto_type != htons(0x0800) || // IP |
|
107 |
+ arp_pack->arp_hdr.hw_len != 0x06 || // length of a MAC address |
|
108 |
+ arp_pack->arp_hdr.proto_len != 0x04) // length of an IP address |
|
109 |
+ // we do not support other protocols than IP over ethernet |
|
110 |
+ return; |
|
111 |
+ |
|
112 |
+ // source MAC is broadcast MAC -> broken packet / attac -> get lost |
|
113 |
+ if (mac_eq(arp_pack->arp_hdr.src_mac, "\xFF\xFF\xFF\xFF\xFF\xFF")) |
|
114 |
+ return; |
|
115 |
+ |
|
116 |
+ // ARP request for own IP address |
|
117 |
+ if (arp_pack->arp_hdr.op == htons(0x0001) && // ARP request |
|
118 |
+ ip_eq(arp_pack->arp_hdr.dest_ip, config_ip.ip)) { // own IP address |
|
119 |
+ struct arp_packet arp_reply; |
|
120 |
+ |
|
121 |
+ // build ARP reply |
|
122 |
+ arp_reply.arp_hdr.hw_type = htons(0x0001); // ethernet |
|
123 |
+ arp_reply.arp_hdr.proto_type = htons(0x0800); // IP |
|
124 |
+ arp_reply.arp_hdr.hw_len = 0x06; // length of a MAC address |
|
125 |
+ arp_reply.arp_hdr.proto_len = 0x04; // length of an IP address |
|
126 |
+ arp_reply.arp_hdr.op = htons(0x0002); // ARP reply |
|
127 |
+ mac_cpy(arp_reply.arp_hdr.src_mac, config_mac.mac); // own MAC |
|
128 |
+ ip_cpy(arp_reply.arp_hdr.src_ip, config_ip.ip); // own IP |
|
129 |
+ mac_cpy(arp_reply.arp_hdr.dest_mac, |
|
130 |
+ arp_pack->arp_hdr.src_mac); // requestor's MAC |
|
131 |
+ ip_cpy(arp_reply.arp_hdr.dest_ip, |
|
132 |
+ arp_pack->arp_hdr.src_ip); // requestor's IP |
|
133 |
+ |
|
134 |
+ // send ARP reply |
|
135 |
+ mac_cpy(arp_reply.eth_hdr.dest, |
|
136 |
+ arp_reply.arp_hdr.dest_mac); // ethernet destination address |
|
137 |
+ arp_reply.eth_hdr.type = htons(0x0806); // ethernet packet type: ARP |
|
138 |
+ ethernet_send(&arp_reply, sizeof(arp_reply)); |
|
139 |
+ |
|
140 |
+ return; |
|
141 |
+ } |
|
142 |
+ |
|
143 |
+ // ARP reply to own MAC address and own IP address |
|
144 |
+ if (arp_pack->arp_hdr.op == htons(0x0002) && // ARP reply |
|
145 |
+ mac_eq(arp_pack->arp_hdr.dest_mac, config_mac.mac) && // own MAC address |
|
146 |
+ ip_eq(arp_pack->arp_hdr.dest_ip, config_ip.ip)) { // own IP address |
|
147 |
+ unsigned int i; |
|
148 |
+ |
|
149 |
+ // search IP in ARP tabale |
|
150 |
+ for (i = 0; i < count(arp_tab); ++i) |
|
151 |
+ if ((arp_tab[i].flags & ARP_TAB_FLAG_IN_USE) && |
|
152 |
+ ip_eq(arp_pack->arp_hdr.src_ip, arp_tab[i].ip)) |
|
153 |
+ break; |
|
154 |
+ // if found in ARP table |
|
155 |
+ // (we do not want to put an entry in the ARP table |
|
156 |
+ // if we have not asked for the MAC of this IP) |
|
157 |
+ if (i < count(arp_tab)) { |
|
158 |
+ // update ARP table entry |
|
159 |
+ arp_tab[i].flags = ARP_TAB_FLAG_IN_USE | ARP_TAB_FLAG_MAC_OK; |
|
160 |
+ arp_tab[i].ticks = 0; |
|
161 |
+ mac_cpy(arp_tab[i].mac, arp_pack->arp_hdr.src_mac); |
|
162 |
+ // notify IP |
|
163 |
+ // - IP might be waiting for the MAC to transmit a packet |
|
164 |
+ // TODO ip_got_mac(arp_tab[i].ip, arp_tab[i].mac); |
|
165 |
+ } |
|
166 |
+ return; |
|
167 |
+ } |
|
168 |
+ |
|
169 |
+} |
|
170 |
+ |
|
171 |
+/** |
|
172 |
+ * @brief look up the MAC for an IP address |
|
173 |
+ * @param[in] ip IP address to look up |
|
174 |
+ * @param[out] mac MAC address for this IP address |
|
175 |
+ * @return 0 in case of success, 1 if the MAC address is unknown |
|
176 |
+ */ |
|
177 |
+/* extern */ int arp_lookup(unsigned char ip[4], unsigned char mac[6]) |
|
178 |
+{ |
|
179 |
+ unsigned int i, j; |
|
180 |
+ |
|
181 |
+ // own IP |
|
182 |
+ if (ip_eq(ip, config_ip.ip)) |
|
183 |
+ // own IP may not be looked up via ARP |
|
184 |
+ return 1; |
|
185 |
+ |
|
186 |
+ // search IP in ARP tabale |
|
187 |
+ for (i = 0; i < count(arp_tab); ++i) |
|
188 |
+ if ((arp_tab[i].flags & ARP_TAB_FLAG_IN_USE) && |
|
189 |
+ ip_eq(ip, arp_tab[i].ip)) |
|
190 |
+ break; |
|
191 |
+ |
|
192 |
+ // not found |
|
193 |
+ if (i >= count(arp_tab)) { |
|
194 |
+ // find a free entry |
|
195 |
+ for (i = 0; i < count(arp_tab); ++i) |
|
196 |
+ if (!(arp_tab[i].flags & ARP_TAB_FLAG_IN_USE)) |
|
197 |
+ break; |
|
198 |
+ |
|
199 |
+ // no free entry |
|
200 |
+ if (i >= count(arp_tab)) { |
|
201 |
+ // find oldest entry |
|
202 |
+ i = 0; |
|
203 |
+ for (j = 1; j < count(arp_tab); ++j) |
|
204 |
+ if (arp_tab[j].ticks > arp_tab[i].ticks ) |
|
205 |
+ i = j; |
|
206 |
+ } |
|
207 |
+ |
|
208 |
+ // set up this entry |
|
209 |
+ arp_tab[i].flags = ARP_TAB_FLAG_IN_USE; |
|
210 |
+ arp_tab[i].ticks = 0; |
|
211 |
+ ip_cpy(arp_tab[i].ip, ip); |
|
212 |
+ } |
|
213 |
+ |
|
214 |
+ // MAC available |
|
215 |
+ if (arp_tab[i].flags & ARP_TAB_FLAG_MAC_OK) { |
|
216 |
+ // return MAC and success |
|
217 |
+ mac_cpy(mac, arp_tab[i].mac); |
|
218 |
+ return 0; |
|
219 |
+ } |
|
220 |
+ |
|
221 |
+ // send ARP request |
|
222 |
+ arp_send_request(ip); |
|
223 |
+ |
|
224 |
+ // no success yet |
|
225 |
+ return 1; |
|
226 |
+} |
|
227 |
+ |
... | ... |
@@ -0,0 +1,49 @@ |
1 |
+#ifndef ARP_H |
|
2 |
+#define ARP_H |
|
3 |
+ |
|
4 |
+#include "ethernet.h" |
|
5 |
+ |
|
6 |
+/// header of an ARP packet |
|
7 |
+struct arp_header |
|
8 |
+{ |
|
9 |
+ unsigned short hw_type; |
|
10 |
+ unsigned short proto_type; |
|
11 |
+ unsigned char hw_len; |
|
12 |
+ unsigned char proto_len; |
|
13 |
+ unsigned short op; |
|
14 |
+ unsigned char src_mac[6]; |
|
15 |
+ unsigned char src_ip[4]; |
|
16 |
+ unsigned char dest_mac[6]; |
|
17 |
+ unsigned char dest_ip[4]; |
|
18 |
+} __attribute__((packed)); |
|
19 |
+ |
|
20 |
+/// an ARP packet |
|
21 |
+struct arp_packet |
|
22 |
+{ |
|
23 |
+ struct ethernet_header eth_hdr; |
|
24 |
+ struct arp_header arp_hdr; |
|
25 |
+} __attribute__((packed)); |
|
26 |
+ |
|
27 |
+/// initialize |
|
28 |
+extern void arp_init(void); |
|
29 |
+ |
|
30 |
+/// tick procedure - call every 200ms |
|
31 |
+extern void arp_tick200(void); |
|
32 |
+ |
|
33 |
+/** |
|
34 |
+ * @brief process a received ARP packet |
|
35 |
+ * @param[in] ptr pointer to data of packet |
|
36 |
+ * @param[in] sz size of packet |
|
37 |
+ */ |
|
38 |
+extern void arp_recv(void *ptr, unsigned int sz); |
|
39 |
+ |
|
40 |
+/** |
|
41 |
+ * @brief look up the MAC for an IP address |
|
42 |
+ * @param[in] ip IP address to look up |
|
43 |
+ * @param[out] mac MAC address for this IP address |
|
44 |
+ * @return 0 in case of success, 1 if the MAC address is unknown |
|
45 |
+ */ |
|
46 |
+extern int arp_lookup(unsigned char ip[4], unsigned char mac[6]); |
|
47 |
+ |
|
48 |
+#endif // #ifdef ARP_H |
|
49 |
+ |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+#include "config.h" |
|
2 |
+#include "macros.h" |
|
3 |
+#include "nethelp.h" |
|
4 |
+ |
|
5 |
+// MAC address |
|
6 |
+/* extern */ struct config_mac config_mac = { |
|
7 |
+ .mac = { 0x02, 0x4D, 0x49, 0x50, 0x53, 0x01 } |
|
8 |
+}; |
|
9 |
+ |
|
10 |
+// IP configuration |
|
11 |
+/* extern */ struct config_ip config_ip = { |
|
12 |
+ .ip = { 192, 168, 0, 89 }, |
|
13 |
+ .mask = { 255, 255, 0, 0 }, |
|
14 |
+ .gw = { 192, 168, 0, 1 } |
|
15 |
+}; |
|
16 |
+ |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+#ifndef CONFIG_H |
|
2 |
+#define CONFIG_H |
|
3 |
+ |
|
4 |
+// MAC address |
|
5 |
+struct config_mac { |
|
6 |
+ unsigned char mac[6]; |
|
7 |
+}; |
|
8 |
+extern struct config_mac config_mac; |
|
9 |
+ |
|
10 |
+// IP configuration |
|
11 |
+struct config_ip { |
|
12 |
+ unsigned char ip[4]; ///< own IP address |
|
13 |
+ unsigned char mask[4]; //</ subnet mask |
|
14 |
+ unsigned char gw[4]; ///< dateway IP address |
|
15 |
+}; |
|
16 |
+extern struct config_ip config_ip; |
|
17 |
+ |
|
18 |
+#endif // #ifndef CONFIG_H |
|
19 |
+ |
... | ... |
@@ -1,10 +1,11 @@ |
1 |
+#include "config.h" |
|
1 | 2 |
#include "eth.h" |
2 | 3 |
|
3 | 4 |
static volatile unsigned int *const eth_ptr = |
4 | 5 |
(volatile unsigned int *)0x80000400; |
5 | 6 |
|
6 | 7 |
static unsigned int eth_idx_hw; |
7 |
-static unsigned int eth_rx_buf[2][256]; |
|
8 |
+static unsigned int eth_rx_buf[2][381]; // max frame len: 1522 byte = 380.5 int |
|
8 | 9 |
static unsigned int *eth_rx_pos; |
9 | 10 |
|
10 | 11 |
/** |
... | ... |
@@ -45,8 +46,7 @@ static void * eth_rx_get_pos(void) |
45 | 46 |
/** initialize MAC address */ |
46 | 47 |
void eth_mac_init(void) |
47 | 48 |
{ |
48 |
- static const unsigned char mac[6] = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; |
|
49 |
- eth_mac_set(mac); |
|
49 |
+ eth_mac_set(config_mac.mac); |
|
50 | 50 |
} |
51 | 51 |
|
52 | 52 |
/** initialize receiver */ |
... | ... |
@@ -0,0 +1,68 @@ |
1 |
+/* flpDistriR25S - flexipix distributor for pixels round 25mm with switch |
|
2 |
+ * version 1.0.0 date 2011-06-12 |
|
3 |
+ * created by Stefan Schuermans <stefan@schuermans.info> |
|
4 |
+ * Copyright (C) 2006-2011 flexipix GbR, Germany |
|
5 |
+ */ |
|
6 |
+ |
|
7 |
+#include "arp.h" |
|
8 |
+#include "config.h" |
|
9 |
+#include "eth.h" |
|
10 |
+#include "ethernet.h" |
|
11 |
+// TODO #include "ip.h" |
|
12 |
+#include "macros.h" |
|
13 |
+#include "nethelp.h" |
|
14 |
+ |
|
15 |
+/** |
|
16 |
+ * @brief process a received ethernet packet |
|
17 |
+ * @param[in] ptr pointer to data of packet |
|
18 |
+ * @param[in] sz size of packet |
|
19 |
+ */ |
|
20 |
+/* extern */ void ethernet_recv(void *ptr, unsigned int sz) |
|
21 |
+{ |
|
22 |
+ struct ethernet_packet *eth_pack; |
|
23 |
+ |
|
24 |
+ // packet too short |
|
25 |
+ if (sz < sizeof(struct ethernet_packet)) |
|
26 |
+ return; |
|
27 |
+ |
|
28 |
+ eth_pack = (struct ethernet_packet *)ptr; |
|
29 |
+ |
|
30 |
+ // branch according to packet type |
|
31 |
+ switch (eth_pack->eth_hdr.type) |
|
32 |
+ { |
|
33 |
+ // ARP |
|
34 |
+ case htons(0x0806): |
|
35 |
+ arp_recv(ptr, sz); |
|
36 |
+ break; |
|
37 |
+ // IP |
|
38 |
+ case htons(0x0800): |
|
39 |
+ // TODO ip_recv(ptr, sz); |
|
40 |
+ break; |
|
41 |
+ } |
|
42 |
+} |
|
43 |
+ |
|
44 |
+/** |
|
45 |
+ * @brief send an ethernet packet |
|
46 |
+ * @param[in] ptr pointer to data of packet |
|
47 |
+ * @param[in] sz size of packet |
|
48 |
+ * |
|
49 |
+ * ptr must point to a ethernet_packet with eth_hdr.dest and eth_hdr.type |
|
50 |
+ * already initialized |
|
51 |
+ */ |
|
52 |
+/* extern */ void ethernet_send(void *ptr, unsigned int sz) |
|
53 |
+{ |
|
54 |
+ struct ethernet_packet *eth_pack; |
|
55 |
+ |
|
56 |
+ // packet too short |
|
57 |
+ if (sz < sizeof(struct ethernet_packet)) |
|
58 |
+ return; |
|
59 |
+ |
|
60 |
+ eth_pack = (struct ethernet_packet *)ptr; |
|
61 |
+ |
|
62 |
+ // fill in source address |
|
63 |
+ mac_cpy(eth_pack->eth_hdr.src, config_mac.mac); |
|
64 |
+ |
|
65 |
+ // transmit packet |
|
66 |
+ eth_tx(ptr, sz); |
|
67 |
+} |
|
68 |
+ |
... | ... |
@@ -0,0 +1,36 @@ |
1 |
+#ifndef ETHERNET_H |
|
2 |
+#define ETHERNET_H |
|
3 |
+ |
|
4 |
+/// header of an ethernet packet |
|
5 |
+struct ethernet_header |
|
6 |
+{ |
|
7 |
+ unsigned char dest[6]; |
|
8 |
+ unsigned char src[6]; |
|
9 |
+ unsigned short type; |
|
10 |
+} __attribute__((packed)); |
|
11 |
+ |
|
12 |
+/// ethernet packet |
|
13 |
+struct ethernet_packet |
|
14 |
+{ |
|
15 |
+ struct ethernet_header eth_hdr; |
|
16 |
+} __attribute__((packed)); |
|
17 |
+ |
|
18 |
+/** |
|
19 |
+ * @brief process a received ethernet packet |
|
20 |
+ * @param[in] ptr pointer to data of packet |
|
21 |
+ * @param[in] sz size of packet |
|
22 |
+ */ |
|
23 |
+void ethernet_recv(void *ptr, unsigned int sz); |
|
24 |
+ |
|
25 |
+/** |
|
26 |
+ * @brief send an ethernet packet |
|
27 |
+ * @param[in] ptr pointer to data of packet |
|
28 |
+ * @param[in] sz size of packet |
|
29 |
+ * |
|
30 |
+ * ptr must point to a ethernet_packet with eth_hdr.dest and eth_hdr.type |
|
31 |
+ * already initialized |
|
32 |
+ */ |
|
33 |
+void ethernet_send(void *ptr, unsigned int sz); |
|
34 |
+ |
|
35 |
+#endif // #ifdef ETHERNET_H |
|
36 |
+ |
... | ... |
@@ -0,0 +1,12 @@ |
1 |
+#ifndef MACROS_H |
|
2 |
+#define MACROS_H |
|
3 |
+ |
|
4 |
+// minimum and maximum |
|
5 |
+#define min(a, b) ((a) < (b) ? (a) : (b)) |
|
6 |
+#define max(a, b) ((a) > (b) ? (a) : (b)) |
|
7 |
+ |
|
8 |
+// number of entries in an array |
|
9 |
+#define count(array) (sizeof((array)) / sizeof((array)[0])) |
|
10 |
+ |
|
11 |
+#endif // #ifndef INC_macros |
|
12 |
+ |
... | ... |
@@ -1,3 +1,4 @@ |
1 |
+#include "arp.h" |
|
1 | 2 |
#include "cyc_cnt.h" |
2 | 3 |
#include "eth.h" |
3 | 4 |
#include "lcd.h" |
... | ... |
@@ -5,46 +6,10 @@ |
5 | 6 |
#include "uart.h" |
6 | 7 |
#include "switches.h" |
7 | 8 |
|
8 |
-//#define CFG_SIMULATION |
|
9 |
- |
|
10 |
-#define CFG_ETH_RX |
|
11 |
-#define CFG_ETH_TX |
|
12 |
-#define CFG_UART |
|
13 |
-#ifdef CFG_SIMULATION |
|
14 |
-# define CFG_UART_CHK |
|
15 |
-#else |
|
16 |
-# define CFG_DELAY |
|
17 |
-# define CFG_LCD |
|
18 |
-# define CFG_SWITCHES |
|
19 |
-#endif |
|
20 |
- |
|
21 |
-const int myconst = 0x12345678; |
|
22 |
- |
|
23 |
-int myvar = 0x11223344; |
|
24 |
- |
|
25 |
-volatile int data[100]; |
|
26 |
- |
|
27 |
-#ifdef CFG_ETH_TX |
|
28 |
- static const unsigned char example_packet[] = { |
|
29 |
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* destination MAC */ |
|
30 |
- 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* source MAC */ |
|
31 |
- 0x08, 0x00, /* ethertype: IP */ |
|
32 |
- 0x45, 0x00, 0x00, 0x36, /* IP header: ..., len */ |
|
33 |
- 0x12, 0x34, 0x00, 0x00, /* IP header: ..., not fragmented */ |
|
34 |
- 0x40, 0x11, 0x00, 0x00, /* IP header: ..., UDP, ... */ |
|
35 |
- 0x7F, 0x00, 0x00, 0x01, /* source IP */ |
|
36 |
- 0xFF, 0xFF, 0xFF, 0xFF, /* destination IP */ |
|
37 |
- 0x00, 0x01, 0x00, 0x01, /* UDP: source port, destination port */ |
|
38 |
- 0x00, 0x22, 0x00, 0x00, /* UDP: len, ... */ |
|
39 |
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
|
40 |
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
|
41 |
- }; |
|
42 |
-#endif |
|
9 |
+unsigned char leds_val = 0x88; |
|
43 | 10 |
|
44 | 11 |
void switches(void) |
45 | 12 |
{ |
46 |
-#ifdef CFG_LCD |
|
47 |
-#ifdef CFG_SWITCHES |
|
48 | 13 |
lcd_chr(1, 0, switches_get_state(sw_0) ? '0' : ' '); |
49 | 14 |
lcd_chr(1, 1, switches_get_state(sw_1) ? '1' : ' '); |
50 | 15 |
lcd_chr(1, 2, switches_get_state(sw_2) ? '2' : ' '); |
... | ... |
@@ -56,75 +21,78 @@ void switches(void) |
56 | 21 |
lcd_chr(1, 8, switches_get_state(sw_center) ? 'C' : ' '); |
57 | 22 |
lcd_chr(1, 9, switches_get_state(sw_rot_a) ? 'a' : ' '); |
58 | 23 |
lcd_chr(1, 10, switches_get_state(sw_rot_b) ? 'b' : ' '); |
59 |
-#endif |
|
60 |
-#endif |
|
61 | 24 |
|
62 |
-#ifdef CFG_LCD |
|
63 |
-#ifdef CFG_SWITCHES |
|
64 | 25 |
unsigned int cnt = switches_get_rot_cnt(); |
65 | 26 |
lcd_chr(1, 12, '0' + (cnt >> 9 & 0x7)); |
66 | 27 |
lcd_chr(1, 13, '0' + (cnt >> 6 & 0x7)); |
67 | 28 |
lcd_chr(1, 14, '0' + (cnt >> 3 & 0x7)); |
68 | 29 |
lcd_chr(1, 15, '0' + (cnt & 0x7)); |
69 |
-#endif |
|
70 |
-#endif |
|
71 | 30 |
} |
72 | 31 |
|
73 |
-void delay(void) |
|
32 |
+void leds_uart(void) |
|
33 |
+{ |
|
34 |
+ unsigned short chr; |
|
35 |
+ |
|
36 |
+ while (uart_can_rx()) { |
|
37 |
+ chr = uart_rx(); |
|
38 |
+ if (uart_is_err(chr)) |
|
39 |
+ leds_val = 0; |
|
40 |
+ else |
|
41 |
+ leds_val = chr; |
|
42 |
+ leds_set_state(leds_val); |
|
43 |
+ } |
|
44 |
+} |
|
45 |
+ |
|
46 |
+void eth_task(void) |
|
74 | 47 |
{ |
75 |
- unsigned int i; |
|
76 |
-#ifdef CFG_ETH_RX |
|
77 | 48 |
void *vptr; |
49 |
+ unsigned int sz, i; |
|
78 | 50 |
unsigned char *ptr; |
79 |
- unsigned int sz; |
|
80 |
-#endif |
|
81 | 51 |
|
82 |
- for (i = 0; i < 10; ++i) { |
|
83 |
- switches(); |
|
84 |
-#ifdef CFG_ETH_RX |
|
85 | 52 |
while (eth_rx(&vptr, &sz)) { |
86 | 53 |
ptr = vptr; |
87 |
-#ifdef CFG_UART |
|
88 |
- for ( ; sz > 0; ptr++, sz--) |
|
89 |
- uart_tx(*ptr); |
|
90 |
-#endif |
|
54 |
+ for (i = 0; i < sz; ++i) |
|
55 |
+ uart_tx(ptr[i]); |
|
56 |
+ ethernet_recv(vptr, sz); |
|
57 |
+ } |
|
58 |
+} |
|
59 |
+ |
|
60 |
+void tasks(void) |
|
61 |
+{ |
|
62 |
+ switches(); |
|
63 |
+ leds_uart(); |
|
64 |
+ eth_task(); |
|
91 | 65 |
} |
92 |
-#endif |
|
93 |
-#ifdef CFG_DELAY |
|
94 |
- cyc_cnt_delay_ms(20); |
|
95 |
-#endif |
|
66 |
+ |
|
67 |
+void leds_tick200(void) |
|
68 |
+{ |
|
69 |
+ leds_val = leds_val << 1 | leds_val >> 7; |
|
70 |
+ leds_set_state(leds_val); |
|
96 | 71 |
} |
72 |
+ |
|
73 |
+void tick200(void) |
|
74 |
+{ |
|
75 |
+ leds_tick200(); |
|
76 |
+ arp_tick200(); |
|
97 | 77 |
} |
98 | 78 |
|
99 | 79 |
int main() |
100 | 80 |
{ |
101 | 81 |
unsigned int i; |
102 |
- unsigned short chr; |
|
103 |
- unsigned char leds; |
|
104 | 82 |
|
105 | 83 |
leds_set_state(0x01); |
106 | 84 |
|
107 |
- for (i = 0; i < sizeof(data) / sizeof(data[0]); ++i) |
|
108 |
- data[i] = i; |
|
109 |
- |
|
110 |
- leds_set_state(0x02); |
|
111 |
- |
|
112 |
-#ifdef CFG_ETH_RX |
|
113 | 85 |
eth_mac_init(); |
114 | 86 |
eth_rx_init(); |
115 |
-#endif |
|
116 | 87 |
|
117 |
- leds_set_state(0x04); |
|
88 |
+ leds_set_state(0x02); |
|
118 | 89 |
|
119 |
-#ifdef CFG_LCD |
|
120 | 90 |
lcd_init(); |
121 | 91 |
lcd_str(0, "MIPS I system"); |
122 | 92 |
lcd_str(1, ""); |
123 |
-#endif |
|
124 | 93 |
|
125 |
- leds_set_state(0x08); |
|
94 |
+ leds_set_state(0x04); |
|
126 | 95 |
|
127 |
-#ifdef CFG_UART |
|
128 | 96 |
uart_cfg_scale(62); /* 115200 */ |
129 | 97 |
uart_cfg_bits(8); |
130 | 98 |
uart_cfg_stop(1); |
... | ... |
@@ -136,40 +104,19 @@ int main() |
136 | 104 |
uart_tx('I'); |
137 | 105 |
uart_tx('\r'); |
138 | 106 |
uart_tx('\n'); |
139 |
-#ifdef CFG_UART_CHK |
|
140 |
- if (uart_rx() != 'M') while(1); |
|
141 |
- if (uart_rx() != 'I') while(1); |
|
142 |
- if (uart_rx() != 'P') while(1); |
|
143 |
- if (uart_rx() != 'S') while(1); |
|
144 |
- if (uart_rx() != ' ') while(1); |
|
145 |
- if (uart_rx() != 'I') while(1); |
|
146 |
- if (uart_rx() != '\r') while(1); |
|
147 |
- if (uart_rx() != '\n') while(1); |
|
148 |
-#endif |
|
149 |
-#endif |
|
107 |
+ |
|
108 |
+ leds_set_state(0x08); |
|
109 |
+ |
|
110 |
+ arp_init(); |
|
150 | 111 |
|
151 | 112 |
leds_set_state(0x10); |
152 | 113 |
|
153 |
- leds = 0x11; |
|
154 | 114 |
while (1) { |
155 |
-#ifdef CFG_UART |
|
156 |
- if (uart_can_rx()) { |
|
157 |
- chr = uart_rx(); |
|
158 |
- if (uart_is_err(chr)) |
|
159 |
- leds = 0; |
|
160 |
- else |
|
161 |
- leds = chr; |
|
115 |
+ for (i = 0; i < 20; ++i) { |
|
116 |
+ tasks(); |
|
117 |
+ cyc_cnt_delay_ms(10); |
|
162 | 118 |
} |
163 |
-#endif |
|
164 |
- leds_set_state(leds); |
|
165 |
- leds = leds << 1 | leds >> 7; |
|
166 |
- delay(); |
|
167 |
-#ifdef CFG_ETH_TX |
|
168 |
-#ifdef CFG_SWITCHES |
|
169 |
- if (switches_get_state(sw_center)) |
|
170 |
-#endif |
|
171 |
- eth_tx(example_packet, sizeof(example_packet)); |
|
172 |
-#endif |
|
119 |
+ tick200(); |
|
173 | 120 |
} |
174 | 121 |
|
175 | 122 |
return 0; |
... | ... |
@@ -0,0 +1,33 @@ |
1 |
+#ifndef NETHELP_H |
|
2 |
+#define NETHELP_H |
|
3 |
+ |
|
4 |
+// byte order |
|
5 |
+#define ntohs(n) (((unsigned short)(n) & 0xFF00) >> 8 | \ |
|
6 |
+ ((unsigned short)(n) & 0x00FF) << 8) |
|
7 |
+#define htons(h) (((unsigned short)(h) & 0xFF00) >> 8 | \ |
|
8 |
+ ((unsigned short)(h) & 0x00FF) << 8) |
|
9 |
+#define ntohl(n) (((unsigned int)(n) & 0xFF000000) >> 24 | \ |
|
10 |
+ ((unsigned int)(n) & 0x00FF0000) >> 8 | \ |
|
11 |
+ ((unsigned int)(n) & 0x0000FF00) << 8 | \ |
|
12 |
+ ((unsigned int)(n) & 0x000000FF) << 24) |
|
13 |
+#define htonl(h) (((unsigned int)(h) & 0xFF000000) >> 24 | \ |
|
14 |
+ ((unsigned int)(h) & 0x00FF0000) >> 8 | \ |
|
15 |
+ ((unsigned int)(h) & 0x0000FF00) << 8 | \ |
|
16 |
+ ((unsigned int)(h) & 0x000000FF) << 24) |
|
17 |
+ |
|
18 |
+// comparing MACs and IPs |
|
19 |
+#define mac_eq(a, b) ((a)[0] == (b)[0] && (a)[1] == (b)[1] && \ |
|
20 |
+ (a)[2] == (b)[2] && (a)[3] == (b)[3] && \ |
|
21 |
+ (a)[4] == (b)[4] && (a)[5] == (b)[5]) |
|
22 |
+#define ip_eq(a, b) ((a)[0] == (b)[0] && (a)[1] == (b)[1] && \ |
|
23 |
+ (a)[2] == (b)[2] && (a)[3] == (b)[3]) |
|
24 |
+ |
|
25 |
+// copying MACs and IPs |
|
26 |
+#define mac_cpy(dest, src) ((dest)[0] = (src)[0], (dest)[1] = (src)[1], \ |
|
27 |
+ (dest)[2] = (src)[2], (dest)[3] = (src)[3], \ |
|
28 |
+ (dest)[4] = (src)[4], (dest)[5] = (src)[5]) |
|
29 |
+#define ip_cpy(dest, src) ((dest)[0] = (src)[0], (dest)[1] = (src)[1], \ |
|
30 |
+ (dest)[2] = (src)[2], (dest)[3] = (src)[3]) |
|
31 |
+ |
|
32 |
+#endif // #ifndef NETHELP_H |
|
33 |
+ |
... | ... |
@@ -407,7 +407,7 @@ |
407 | 407 |
<property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/> |
408 | 408 |
<property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/> |
409 | 409 |
<property xil_pn:name="Simulation Model Target" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
410 |
- <property xil_pn:name="Simulation Run Time ISim" xil_pn:value="2 ms" xil_pn:valueState="non-default"/> |
|
410 |
+ <property xil_pn:name="Simulation Run Time ISim" xil_pn:value="30 ms" xil_pn:valueState="non-default"/> |
|
411 | 411 |
<property xil_pn:name="Simulation Run Time Map" xil_pn:value="1000 ns" xil_pn:valueState="default"/> |
412 | 412 |
<property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/> |
413 | 413 |
<property xil_pn:name="Simulation Run Time Translate" xil_pn:value="1000 ns" xil_pn:valueState="default"/> |