Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 10 commits
  • 4 files changed
  • 0 commit comments
  • 2 contributors
4 milkymist/dvisampler/chansync.py
View
@@ -31,8 +31,8 @@ def __init__(self, nchan=3, depth=8):
self.add_submodule(fifo, "pix")
self.comb += [
fifo.we.eq(self.valid_i),
- fifo.din.eq(Cat(*data_in.flatten())),
- Cat(*data_out.flatten()).eq(fifo.dout)
+ fifo.din.eq(data_in.raw_bits()),
+ data_out.raw_bits().eq(fifo.dout)
]
is_control = Signal()
is_control_r = Signal()
60 software/bios/microudp.c
View
@@ -128,39 +128,42 @@ static unsigned int cached_ip;
static void process_arp(void)
{
+ const struct arp_frame *rx_arp = &rxbuffer->frame.contents.arp;
+ struct arp_frame *tx_arp = &txbuffer->frame.contents.arp;
+
if(rxlen < 68) return;
- if(rxbuffer->frame.contents.arp.hwtype != ARP_HWTYPE_ETHERNET) return;
- if(rxbuffer->frame.contents.arp.proto != ARP_PROTO_IP) return;
- if(rxbuffer->frame.contents.arp.hwsize != 6) return;
- if(rxbuffer->frame.contents.arp.protosize != 4) return;
- if(rxbuffer->frame.contents.arp.opcode == ARP_OPCODE_REPLY) {
- if(rxbuffer->frame.contents.arp.sender_ip == cached_ip) {
+ if(rx_arp->hwtype != ARP_HWTYPE_ETHERNET) return;
+ if(rx_arp->proto != ARP_PROTO_IP) return;
+ if(rx_arp->hwsize != 6) return;
+ if(rx_arp->protosize != 4) return;
+ if(rx_arp->opcode == ARP_OPCODE_REPLY) {
+ if(rx_arp->sender_ip == cached_ip) {
int i;
for(i=0;i<6;i++)
- cached_mac[i] = rxbuffer->frame.contents.arp.sender_mac[i];
+ cached_mac[i] = rx_arp->sender_mac[i];
}
return;
}
- if(rxbuffer->frame.contents.arp.opcode == ARP_OPCODE_REQUEST) {
- if(rxbuffer->frame.contents.arp.target_ip == my_ip) {
+ if(rx_arp->opcode == ARP_OPCODE_REQUEST) {
+ if(rx_arp->target_ip == my_ip) {
int i;
fill_eth_header(&txbuffer->frame.eth_header,
- rxbuffer->frame.contents.arp.sender_mac,
+ rx_arp->sender_mac,
my_mac,
ETHERTYPE_ARP);
txlen = 68;
- txbuffer->frame.contents.arp.hwtype = ARP_HWTYPE_ETHERNET;
- txbuffer->frame.contents.arp.proto = ARP_PROTO_IP;
- txbuffer->frame.contents.arp.hwsize = 6;
- txbuffer->frame.contents.arp.protosize = 4;
- txbuffer->frame.contents.arp.opcode = ARP_OPCODE_REPLY;
- txbuffer->frame.contents.arp.sender_ip = my_ip;
+ tx_arp->hwtype = ARP_HWTYPE_ETHERNET;
+ tx_arp->proto = ARP_PROTO_IP;
+ tx_arp->hwsize = 6;
+ tx_arp->protosize = 4;
+ tx_arp->opcode = ARP_OPCODE_REPLY;
+ tx_arp->sender_ip = my_ip;
for(i=0;i<6;i++)
- txbuffer->frame.contents.arp.sender_mac[i] = my_mac[i];
- txbuffer->frame.contents.arp.target_ip = rxbuffer->frame.contents.arp.sender_ip;
+ tx_arp->sender_mac[i] = my_mac[i];
+ tx_arp->target_ip = rx_arp->sender_ip;
for(i=0;i<6;i++)
- txbuffer->frame.contents.arp.target_mac[i] = rxbuffer->frame.contents.arp.sender_mac[i];
+ tx_arp->target_mac[i] = rx_arp->sender_mac[i];
send_packet();
}
return;
@@ -171,6 +174,7 @@ static const unsigned char broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int microudp_arp_resolve(unsigned int ip)
{
+ struct arp_frame *arp = &txbuffer->frame.contents.arp;
int i;
int tries;
int timeout;
@@ -190,17 +194,17 @@ int microudp_arp_resolve(unsigned int ip)
my_mac,
ETHERTYPE_ARP);
txlen = 68;
- txbuffer->frame.contents.arp.hwtype = ARP_HWTYPE_ETHERNET;
- txbuffer->frame.contents.arp.proto = ARP_PROTO_IP;
- txbuffer->frame.contents.arp.hwsize = 6;
- txbuffer->frame.contents.arp.protosize = 4;
- txbuffer->frame.contents.arp.opcode = ARP_OPCODE_REQUEST;
- txbuffer->frame.contents.arp.sender_ip = my_ip;
+ arp->hwtype = ARP_HWTYPE_ETHERNET;
+ arp->proto = ARP_PROTO_IP;
+ arp->hwsize = 6;
+ arp->protosize = 4;
+ arp->opcode = ARP_OPCODE_REQUEST;
+ arp->sender_ip = my_ip;
for(i=0;i<6;i++)
- txbuffer->frame.contents.arp.sender_mac[i] = my_mac[i];
- txbuffer->frame.contents.arp.target_ip = ip;
+ arp->sender_mac[i] = my_mac[i];
+ arp->target_ip = ip;
for(i=0;i<6;i++)
- txbuffer->frame.contents.arp.target_mac[i] = 0;
+ arp->target_mac[i] = 0;
send_packet();
/* Do we get a reply ? */
139 software/bios/tftp.c
View
@@ -1,3 +1,4 @@
+#include <stdint.h>
#include <string.h>
#include "microudp.h"
@@ -6,12 +7,25 @@
#define PORT_OUT 69
#define PORT_IN 7642
-static int format_request(char *buf, const char *filename)
+enum {
+ TFTP_RRQ = 1, /* Read request */
+ TFTP_WRQ = 2, /* Write request */
+ TFTP_DATA = 3, /* Data */
+ TFTP_ACK = 4, /* Acknowledgment */
+ TFTP_ERROR = 5, /* Error */
+};
+
+#define BLOCK_SIZE 512 /* block size in bytes */
+
+
+static int format_request(uint8_t *buf, uint16_t op, const char *filename)
{
- *buf++ = 0x00; /* Opcode: Request */
- *buf++ = 0x01;
- strcpy(buf, filename);
- buf += strlen(filename);
+ int len = strlen(filename);
+
+ *buf++ = op >> 8; /* Opcode */
+ *buf++ = op;
+ memcpy(buf, filename, len);
+ buf += len;
*buf++ = 0x00;
*buf++ = 'o';
*buf++ = 'c';
@@ -22,52 +36,70 @@ static int format_request(char *buf, const char *filename)
return 9+strlen(filename);
}
-static int format_ack(char *buf, unsigned short block)
+static int format_ack(uint8_t *buf, uint16_t block)
{
*buf++ = 0x00; /* Opcode: Ack */
- *buf++ = 0x04;
+ *buf++ = TFTP_ACK;
*buf++ = (block & 0xff00) >> 8;
*buf++ = (block & 0x00ff);
return 4;
}
-static char *packet_data;
+static int format_data(uint8_t *buf, uint16_t block, const void *data, int len)
+{
+ *buf++ = 0x00; /* Opcode: Data*/
+ *buf++ = TFTP_DATA;
+ *buf++ = (block & 0xff00) >> 8;
+ *buf++ = (block & 0x00ff);
+ memcpy(buf, data, len);
+ return len+4;
+}
+
+static uint8_t *packet_data;
static int total_length;
static int transfer_finished;
-static char *dst_buffer;
+static uint8_t *dst_buffer;
+static int last_ack; /* signed, so we can use -1 */
+static uint16_t data_port;
-static void rx_callback(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *_data, unsigned int length)
+static void rx_callback(uint32_t src_ip, uint16_t src_port,
+ uint16_t dst_port, void *_data, unsigned int length)
{
- unsigned char *data = (unsigned char *)_data;
- unsigned short opcode;
- unsigned short block;
+ uint8_t *data = _data;
+ uint16_t opcode;
+ uint16_t block;
int i;
int offset;
if(length < 4) return;
if(dst_port != PORT_IN) return;
- opcode = ((unsigned short)(data[0]) << 8)|((unsigned short)(data[1]));
- block = ((unsigned short)(data[2]) << 8)|((unsigned short)(data[3]));
+ opcode = data[0] << 8 | data[1];
+ block = data[2] << 8 | data[3];
+ if(opcode == TFTP_ACK) { /* Acknowledgement */
+ data_port = src_port;
+ last_ack = block;
+ return;
+ }
if(block < 1) return;
- if(opcode == 3) { /* Data */
+ if(opcode == TFTP_DATA) { /* Data */
length -= 4;
- offset = (block-1)*512;
+ offset = (block-1)*BLOCK_SIZE;
for(i=0;i<length;i++)
dst_buffer[offset+i] = data[i+4];
total_length += length;
- if(length < 512)
+ if(length < BLOCK_SIZE)
transfer_finished = 1;
length = format_ack(packet_data, block);
microudp_send(PORT_IN, src_port, length);
}
- if(opcode == 5) { /* Error */
+ if(opcode == TFTP_ERROR) { /* Error */
total_length = -1;
transfer_finished = 1;
}
}
-int tftp_get(unsigned int ip, const char *filename, char *buffer)
+int tftp_get(uint32_t ip, const char *filename, void *buffer)
{
int len;
int tries;
@@ -86,7 +118,7 @@ int tftp_get(unsigned int ip, const char *filename, char *buffer)
transfer_finished = 0;
tries = 5;
while(1) {
- len = format_request(packet_data, filename);
+ len = format_request(packet_data, TFTP_RRQ, filename);
microudp_send(PORT_IN, PORT_OUT, len);
for(i=0;i<2000000;i++) {
microudp_service();
@@ -117,3 +149,68 @@ int tftp_get(unsigned int ip, const char *filename, char *buffer)
return total_length;
}
+
+int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size)
+{
+ int len, send;
+ int tries;
+ int i;
+ int block = 0, sent = 0;
+
+ if(!microudp_arp_resolve(ip))
+ return -1;
+
+ microudp_set_callback(rx_callback);
+
+ packet_data = microudp_get_tx_buffer();
+
+ total_length = 0;
+ transfer_finished = 0;
+ tries = 5;
+ while(1) {
+ len = format_request(packet_data, TFTP_WRQ, filename);
+ microudp_send(PORT_IN, PORT_OUT, len);
+ for(i=0;i<2000000;i++) {
+ last_ack = -1;
+ microudp_service();
+ if(last_ack == block)
+ goto send_data;
+ if(transfer_finished)
+ goto fail;
+ }
+ tries--;
+ if(tries == 0)
+ goto fail;
+ }
+
+send_data:
+ do {
+ block++;
+ send = sent+BLOCK_SIZE > size ? size-sent : BLOCK_SIZE;
+ tries = 5;
+ while(1) {
+ len = format_data(packet_data, block, buffer, send);
+ microudp_send(PORT_IN, data_port, len);
+ for(i=0;i<12000000;i++) {
+ microudp_service();
+ if(transfer_finished)
+ goto fail;
+ if(last_ack == block)
+ goto next;
+ }
+ if (!--tries)
+ goto fail;
+ }
+next:
+ sent += send;
+ buffer += send;
+ } while (send == BLOCK_SIZE);
+
+ microudp_set_callback(NULL);
+
+ return sent;
+
+fail:
+ microudp_set_callback(NULL);
+ return -1;
+}
5 software/bios/tftp.h
View
@@ -1,7 +1,10 @@
#ifndef __TFTP_H
#define __TFTP_H
-int tftp_get(unsigned int ip, const char *filename, char *buffer);
+#include <stdint.h>
+
+int tftp_get(uint32_t ip, const char *filename, void *buffer);
+int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size);
#endif /* __TFTP_H */

No commit comments for this range

Something went wrong with that request. Please try again.