Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 10 commits
  • 4 files changed
  • 0 comments
  • 2 contributors
4  milkymist/dvisampler/chansync.py
@@ -31,8 +31,8 @@ def __init__(self, nchan=3, depth=8):
31 31
 			self.add_submodule(fifo, "pix")
32 32
 			self.comb += [
33 33
 				fifo.we.eq(self.valid_i),
34  
-				fifo.din.eq(Cat(*data_in.flatten())),
35  
-				Cat(*data_out.flatten()).eq(fifo.dout)
  34
+				fifo.din.eq(data_in.raw_bits()),
  35
+				data_out.raw_bits().eq(fifo.dout)
36 36
 			]
37 37
 			is_control = Signal()
38 38
 			is_control_r = Signal()
60  software/bios/microudp.c
@@ -128,39 +128,42 @@ static unsigned int cached_ip;
128 128
 
129 129
 static void process_arp(void)
130 130
 {
  131
+	const struct arp_frame *rx_arp = &rxbuffer->frame.contents.arp;
  132
+	struct arp_frame *tx_arp = &txbuffer->frame.contents.arp;
  133
+
131 134
 	if(rxlen < 68) return;
132  
-	if(rxbuffer->frame.contents.arp.hwtype != ARP_HWTYPE_ETHERNET) return;
133  
-	if(rxbuffer->frame.contents.arp.proto != ARP_PROTO_IP) return;
134  
-	if(rxbuffer->frame.contents.arp.hwsize != 6) return;
135  
-	if(rxbuffer->frame.contents.arp.protosize != 4) return;
136  
-	if(rxbuffer->frame.contents.arp.opcode == ARP_OPCODE_REPLY) {
137  
-		if(rxbuffer->frame.contents.arp.sender_ip == cached_ip) {
  135
+	if(rx_arp->hwtype != ARP_HWTYPE_ETHERNET) return;
  136
+	if(rx_arp->proto != ARP_PROTO_IP) return;
  137
+	if(rx_arp->hwsize != 6) return;
  138
+	if(rx_arp->protosize != 4) return;
  139
+	if(rx_arp->opcode == ARP_OPCODE_REPLY) {
  140
+		if(rx_arp->sender_ip == cached_ip) {
138 141
 			int i;
139 142
 			for(i=0;i<6;i++)
140  
-				cached_mac[i] = rxbuffer->frame.contents.arp.sender_mac[i];
  143
+				cached_mac[i] = rx_arp->sender_mac[i];
141 144
 		}
142 145
 		return;
143 146
 	}
144  
-	if(rxbuffer->frame.contents.arp.opcode == ARP_OPCODE_REQUEST) {
145  
-		if(rxbuffer->frame.contents.arp.target_ip == my_ip) {
  147
+	if(rx_arp->opcode == ARP_OPCODE_REQUEST) {
  148
+		if(rx_arp->target_ip == my_ip) {
146 149
 			int i;
147 150
 			
148 151
 			fill_eth_header(&txbuffer->frame.eth_header,
149  
-				rxbuffer->frame.contents.arp.sender_mac,
  152
+				rx_arp->sender_mac,
150 153
 				my_mac,
151 154
 				ETHERTYPE_ARP);
152 155
 			txlen = 68;
153  
-			txbuffer->frame.contents.arp.hwtype = ARP_HWTYPE_ETHERNET;
154  
-			txbuffer->frame.contents.arp.proto = ARP_PROTO_IP;
155  
-			txbuffer->frame.contents.arp.hwsize = 6;
156  
-			txbuffer->frame.contents.arp.protosize = 4;
157  
-			txbuffer->frame.contents.arp.opcode = ARP_OPCODE_REPLY;
158  
-			txbuffer->frame.contents.arp.sender_ip = my_ip;
  156
+			tx_arp->hwtype = ARP_HWTYPE_ETHERNET;
  157
+			tx_arp->proto = ARP_PROTO_IP;
  158
+			tx_arp->hwsize = 6;
  159
+			tx_arp->protosize = 4;
  160
+			tx_arp->opcode = ARP_OPCODE_REPLY;
  161
+			tx_arp->sender_ip = my_ip;
159 162
 			for(i=0;i<6;i++)
160  
-				txbuffer->frame.contents.arp.sender_mac[i] = my_mac[i];
161  
-			txbuffer->frame.contents.arp.target_ip = rxbuffer->frame.contents.arp.sender_ip;
  163
+				tx_arp->sender_mac[i] = my_mac[i];
  164
+			tx_arp->target_ip = rx_arp->sender_ip;
162 165
 			for(i=0;i<6;i++)
163  
-				txbuffer->frame.contents.arp.target_mac[i] = rxbuffer->frame.contents.arp.sender_mac[i];
  166
+				tx_arp->target_mac[i] = rx_arp->sender_mac[i];
164 167
 			send_packet();
165 168
 		}
166 169
 		return;
@@ -171,6 +174,7 @@ static const unsigned char broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
171 174
 
172 175
 int microudp_arp_resolve(unsigned int ip)
173 176
 {
  177
+	struct arp_frame *arp = &txbuffer->frame.contents.arp;
174 178
 	int i;
175 179
 	int tries;
176 180
 	int timeout;
@@ -190,17 +194,17 @@ int microudp_arp_resolve(unsigned int ip)
190 194
 				my_mac,
191 195
 				ETHERTYPE_ARP);
192 196
 		txlen = 68;
193  
-		txbuffer->frame.contents.arp.hwtype = ARP_HWTYPE_ETHERNET;
194  
-		txbuffer->frame.contents.arp.proto = ARP_PROTO_IP;
195  
-		txbuffer->frame.contents.arp.hwsize = 6;
196  
-		txbuffer->frame.contents.arp.protosize = 4;
197  
-		txbuffer->frame.contents.arp.opcode = ARP_OPCODE_REQUEST;
198  
-		txbuffer->frame.contents.arp.sender_ip = my_ip;
  197
+		arp->hwtype = ARP_HWTYPE_ETHERNET;
  198
+		arp->proto = ARP_PROTO_IP;
  199
+		arp->hwsize = 6;
  200
+		arp->protosize = 4;
  201
+		arp->opcode = ARP_OPCODE_REQUEST;
  202
+		arp->sender_ip = my_ip;
199 203
 		for(i=0;i<6;i++)
200  
-			txbuffer->frame.contents.arp.sender_mac[i] = my_mac[i];
201  
-		txbuffer->frame.contents.arp.target_ip = ip;
  204
+			arp->sender_mac[i] = my_mac[i];
  205
+		arp->target_ip = ip;
202 206
 		for(i=0;i<6;i++)
203  
-			txbuffer->frame.contents.arp.target_mac[i] = 0;
  207
+			arp->target_mac[i] = 0;
204 208
 		send_packet();
205 209
 
206 210
 		/* Do we get a reply ? */
139  software/bios/tftp.c
... ...
@@ -1,3 +1,4 @@
  1
+#include <stdint.h>
1 2
 #include <string.h>
2 3
 
3 4
 #include "microudp.h"
@@ -6,12 +7,25 @@
6 7
 #define PORT_OUT	69
7 8
 #define PORT_IN		7642
8 9
 
9  
-static int format_request(char *buf, const char *filename)
  10
+enum {
  11
+	TFTP_RRQ	= 1,	/* Read request */
  12
+	TFTP_WRQ	= 2, 	/* Write request */
  13
+	TFTP_DATA	= 3,	/* Data */
  14
+	TFTP_ACK	= 4,	/* Acknowledgment */
  15
+	TFTP_ERROR	= 5,	/* Error */
  16
+};
  17
+
  18
+#define	BLOCK_SIZE	512	/* block size in bytes */
  19
+
  20
+
  21
+static int format_request(uint8_t *buf, uint16_t op, const char *filename)
10 22
 {
11  
-	*buf++ = 0x00; /* Opcode: Request */
12  
-	*buf++ = 0x01;
13  
-	strcpy(buf, filename);
14  
-	buf += strlen(filename);
  23
+	int len = strlen(filename);
  24
+
  25
+	*buf++ = op >> 8; /* Opcode */
  26
+	*buf++ = op;
  27
+	memcpy(buf, filename, len);
  28
+	buf += len;
15 29
 	*buf++ = 0x00;
16 30
 	*buf++ = 'o';
17 31
 	*buf++ = 'c';
@@ -22,52 +36,70 @@ static int format_request(char *buf, const char *filename)
22 36
 	return 9+strlen(filename);
23 37
 }
24 38
 
25  
-static int format_ack(char *buf, unsigned short block)
  39
+static int format_ack(uint8_t *buf, uint16_t block)
26 40
 {
27 41
 	*buf++ = 0x00; /* Opcode: Ack */
28  
-	*buf++ = 0x04;
  42
+	*buf++ = TFTP_ACK;
29 43
 	*buf++ = (block & 0xff00) >> 8;
30 44
 	*buf++ = (block & 0x00ff);
31 45
 	return 4;
32 46
 }
33 47
 
34  
-static char *packet_data;
  48
+static int format_data(uint8_t *buf, uint16_t block, const void *data, int len)
  49
+{
  50
+	*buf++ = 0x00; /* Opcode: Data*/
  51
+	*buf++ = TFTP_DATA;
  52
+	*buf++ = (block & 0xff00) >> 8;
  53
+	*buf++ = (block & 0x00ff);
  54
+	memcpy(buf, data, len);
  55
+	return len+4;
  56
+}
  57
+
  58
+static uint8_t *packet_data;
35 59
 static int total_length;
36 60
 static int transfer_finished;
37  
-static char *dst_buffer;
  61
+static uint8_t *dst_buffer;
  62
+static int last_ack; /* signed, so we can use -1 */
  63
+static uint16_t data_port;
38 64
 
39  
-static void rx_callback(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *_data, unsigned int length)
  65
+static void rx_callback(uint32_t src_ip, uint16_t src_port,
  66
+    uint16_t dst_port, void *_data, unsigned int length)
40 67
 {
41  
-	unsigned char *data = (unsigned char *)_data;
42  
-	unsigned short opcode;
43  
-	unsigned short block;
  68
+	uint8_t *data = _data;
  69
+	uint16_t opcode;
  70
+	uint16_t block;
44 71
 	int i;
45 72
 	int offset;
46 73
 	
47 74
 	if(length < 4) return;
48 75
 	if(dst_port != PORT_IN) return;
49  
-	opcode = ((unsigned short)(data[0]) << 8)|((unsigned short)(data[1]));
50  
-	block = ((unsigned short)(data[2]) << 8)|((unsigned short)(data[3]));
  76
+	opcode = data[0] << 8 | data[1];
  77
+	block = data[2] << 8 | data[3];
  78
+	if(opcode == TFTP_ACK) { /* Acknowledgement */
  79
+		data_port = src_port;
  80
+		last_ack = block;
  81
+		return;
  82
+	}
51 83
 	if(block < 1) return;
52  
-	if(opcode == 3) { /* Data */
  84
+	if(opcode == TFTP_DATA) { /* Data */
53 85
 		length -= 4;
54  
-		offset = (block-1)*512;
  86
+		offset = (block-1)*BLOCK_SIZE;
55 87
 		for(i=0;i<length;i++)
56 88
 			dst_buffer[offset+i] = data[i+4];
57 89
 		total_length += length;
58  
-		if(length < 512)
  90
+		if(length < BLOCK_SIZE)
59 91
 			transfer_finished = 1;
60 92
 		
61 93
 		length = format_ack(packet_data, block);
62 94
 		microudp_send(PORT_IN, src_port, length);
63 95
 	}
64  
-	if(opcode == 5) { /* Error */
  96
+	if(opcode == TFTP_ERROR) { /* Error */
65 97
 		total_length = -1;
66 98
 		transfer_finished = 1;
67 99
 	}
68 100
 }
69 101
 
70  
-int tftp_get(unsigned int ip, const char *filename, char *buffer)
  102
+int tftp_get(uint32_t ip, const char *filename, void *buffer)
71 103
 {
72 104
 	int len;
73 105
 	int tries;
@@ -86,7 +118,7 @@ int tftp_get(unsigned int ip, const char *filename, char *buffer)
86 118
 	transfer_finished = 0;
87 119
 	tries = 5;
88 120
 	while(1) {
89  
-		len = format_request(packet_data, filename);
  121
+		len = format_request(packet_data, TFTP_RRQ, filename);
90 122
 		microudp_send(PORT_IN, PORT_OUT, len);
91 123
 		for(i=0;i<2000000;i++) {
92 124
 			microudp_service();
@@ -117,3 +149,68 @@ int tftp_get(unsigned int ip, const char *filename, char *buffer)
117 149
 
118 150
 	return total_length;
119 151
 }
  152
+
  153
+int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size)
  154
+{
  155
+	int len, send;
  156
+	int tries;
  157
+	int i;
  158
+	int block = 0, sent = 0;
  159
+	
  160
+	if(!microudp_arp_resolve(ip))
  161
+		return -1;
  162
+
  163
+	microudp_set_callback(rx_callback);
  164
+
  165
+	packet_data = microudp_get_tx_buffer();
  166
+
  167
+	total_length = 0;
  168
+	transfer_finished = 0;
  169
+	tries = 5;
  170
+	while(1) {
  171
+		len = format_request(packet_data, TFTP_WRQ, filename);
  172
+		microudp_send(PORT_IN, PORT_OUT, len);
  173
+		for(i=0;i<2000000;i++) {
  174
+			last_ack = -1;
  175
+			microudp_service();
  176
+			if(last_ack == block)
  177
+				goto send_data;
  178
+			if(transfer_finished)
  179
+				goto fail;
  180
+		}
  181
+		tries--;
  182
+		if(tries == 0)
  183
+			goto fail;
  184
+	}
  185
+
  186
+send_data:
  187
+	do {
  188
+		block++;
  189
+		send = sent+BLOCK_SIZE > size ? size-sent : BLOCK_SIZE;
  190
+		tries = 5;
  191
+		while(1) {
  192
+			len = format_data(packet_data, block, buffer, send);
  193
+			microudp_send(PORT_IN, data_port, len);
  194
+			for(i=0;i<12000000;i++) {
  195
+				microudp_service();
  196
+				if(transfer_finished)
  197
+					goto fail;
  198
+				if(last_ack == block)
  199
+					goto next;
  200
+			}
  201
+			if (!--tries)
  202
+				goto fail;
  203
+		}
  204
+next:
  205
+		sent += send;
  206
+		buffer += send;
  207
+	} while (send == BLOCK_SIZE);
  208
+
  209
+	microudp_set_callback(NULL);
  210
+
  211
+	return sent;
  212
+
  213
+fail:
  214
+	microudp_set_callback(NULL);
  215
+	return -1;
  216
+}
5  software/bios/tftp.h
... ...
@@ -1,7 +1,10 @@
1 1
 #ifndef __TFTP_H
2 2
 #define __TFTP_H
3 3
 
4  
-int tftp_get(unsigned int ip, const char *filename, char *buffer);
  4
+#include <stdint.h>
  5
+
  6
+int tftp_get(uint32_t ip, const char *filename, void *buffer);
  7
+int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size);
5 8
 
6 9
 #endif /* __TFTP_H */
7 10
 

No commit comments for this range

Something went wrong with that request. Please try again.