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"/> |