diff --git a/artiq/coredevice/comm_tcp.py b/artiq/coredevice/comm_tcp.py index d2c9367e2..bce17fea3 100644 --- a/artiq/coredevice/comm_tcp.py +++ b/artiq/coredevice/comm_tcp.py @@ -18,6 +18,7 @@ class Comm(CommGeneric, AutoDB): return self.socket = socket.create_connection((self.host, self.port)) logger.debug("connected to host %s on port %d", self.host, self.port) + self.write(b"ARTIQ coredev\n") def close(self): if not hasattr(self, "socket"): diff --git a/benchmarks/ddb.pyon b/benchmarks/ddb.pyon index 3842a5e18..813c9645d 100644 --- a/benchmarks/ddb.pyon +++ b/benchmarks/ddb.pyon @@ -1,9 +1,9 @@ { "comm": { "type": "local", - "module": "artiq.coredevice.comm_serial", + "module": "artiq.coredevice.comm_tcp", "class": "Comm", - "arguments": {"serial_dev": "/dev/ttyUSB1"} + "arguments": {"host": "192.168.0.42"} }, "core": { "type": "local", diff --git a/examples/master/ddb.pyon b/examples/master/ddb.pyon index b602d367a..8ca5e5764 100644 --- a/examples/master/ddb.pyon +++ b/examples/master/ddb.pyon @@ -1,9 +1,9 @@ { "comm": { "type": "local", - "module": "artiq.coredevice.comm_serial", + "module": "artiq.coredevice.comm_tcp", "class": "Comm", - "arguments": {"serial_dev": "/dev/ttyUSB1"} + "arguments": {"host": "192.168.0.42"} }, "core": { "type": "local", diff --git a/soc/runtime/liblwip/netif/liteethif.c b/soc/runtime/liblwip/netif/liteethif.c index b8cf06971..757918e25 100644 --- a/soc/runtime/liblwip/netif/liteethif.c +++ b/soc/runtime/liblwip/netif/liteethif.c @@ -93,7 +93,7 @@ static struct pbuf *liteeth_low_level_input(struct netif *netif) if(rxslot) rxbuffer = rxbuffer1; else - rxbuffer = rxbuffer0; + rxbuffer = rxbuffer0; p = pbuf_alloc(PBUF_RAW, rxlen, PBUF_POOL); q = p; diff --git a/soc/runtime/log.c b/soc/runtime/log.c index 931a50ecf..4f1750f2f 100644 --- a/soc/runtime/log.c +++ b/soc/runtime/log.c @@ -1,6 +1,8 @@ #include #include +#include + #include "log.h" static int buffer_index; @@ -18,6 +20,12 @@ void log_va(const char *fmt, va_list args) } buffer[buffer_index] = '\n'; buffer_index = (buffer_index + 1) % LOG_BUFFER_SIZE; + +#ifdef CSR_ETHMAC_BASE + /* Since main comms are over ethernet, the serial port + * is free for us to use. */ + puts(outbuf); +#endif } void log(const char *fmt, ...) diff --git a/soc/runtime/main.c b/soc/runtime/main.c index 49158d0e6..d496d4d77 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -29,22 +29,13 @@ unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00}; u32_t clock_ms; -static void clock_init(void) -{ - timer0_en_write(0); - timer0_load_write(0xffffffff); - timer0_reload_write(0xffffffff); - timer0_en_write(1); - clock_ms = 0; -} - u32_t sys_now(void) { unsigned int freq; unsigned int prescaler; freq = identifier_frequency_read(); - prescaler = freq/1000; /* sys_now expect time in ms */ + prescaler = freq/1000; /* sys_now expects time in ms */ timer0_update_value_write(1); clock_ms += (0xffffffff - timer0_value_read())/prescaler; /* Reset timer to avoid rollover, this will increase clock_ms @@ -64,47 +55,18 @@ static void lwip_service(void) ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); } } -#endif -void comm_service(void) +static void network_init(void) { - char *txdata; - int txlen; - static char rxdata; - static int rxpending; - int r, i; - -#ifdef CSR_ETHMAC_BASE - lwip_service(); -#endif - - if(!rxpending && uart_read_nonblock()) { - rxdata = uart_read(); - rxpending = 1; - } - if(rxpending) { - r = session_input(&rxdata, 1); - if(r > 0) - rxpending = 0; - } - - session_poll((void **)&txdata, &txlen); - if(txlen > 0) { - for(i=0;imagic_recognized = 0; + cs->rp = NULL; + cs->rp_offset = 0; + return cs; +} + +static void cs_free(struct kserver_connstate *cs) +{ + if(cs->rp) + pbuf_free(cs->rp); + mem_free(cs); +} + +static const char kserver_magic[] = "ARTIQ coredev\n"; + +static int magic_ok(struct kserver_connstate *cs) +{ + return cs->magic_recognized >= 14; +} + +static struct kserver_connstate *active_cs; +static struct tcp_pcb *active_pcb; + +static void kserver_close(struct kserver_connstate *cs, struct tcp_pcb *pcb) +{ + if(cs == active_cs) { + session_end(); + active_cs = NULL; + active_pcb = NULL; + } + + /* lwip loves to call back with broken pointers. Prevent that. */ + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_err(pcb, NULL); + + cs_free(cs); + tcp_close(pcb); +} + +static err_t kserver_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct kserver_connstate *cs; + + cs = (struct kserver_connstate *)arg; + if(p) { + if(cs->rp) + pbuf_cat(cs->rp, p); + else { + cs->rp = p; + cs->rp_offset = 0; + } + } else + kserver_close(cs, pcb); + return ERR_OK; +} + +static err_t kserver_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + session_ack_mem(len); + return ERR_OK; +} + +static void tcp_pcb_service(void *arg, struct tcp_pcb *pcb) +{ + struct kserver_connstate *cs; + int remaining_in_pbuf; + char *rpp; + struct pbuf *next; + int r; + + cs = (struct kserver_connstate *)arg; + + while(cs->rp) { + remaining_in_pbuf = cs->rp->len - cs->rp_offset; + rpp = (char *)cs->rp->payload; + while(remaining_in_pbuf > 0) { + if(cs == active_cs) { + r = session_input(&rpp[cs->rp_offset], remaining_in_pbuf); + if(r > 0) { + tcp_recved(pcb, r); + cs->rp_offset += r; + remaining_in_pbuf -= r; + } else if(r == 0) + return; + else + kserver_close(cs, pcb); + } else { + if(rpp[cs->rp_offset] == kserver_magic[cs->magic_recognized]) { + cs->magic_recognized++; + if(magic_ok(cs)) { + if(active_cs) + kserver_close(active_cs, active_pcb); + session_start(); + active_cs = cs; + active_pcb = pcb; + tcp_sent(pcb, kserver_sent); + } + } else { + kserver_close(cs, pcb); + return; + } + remaining_in_pbuf--; + cs->rp_offset++; + tcp_recved(pcb, 1); + } + } + next = cs->rp->next; + if(cs->rp->tot_len != cs->rp->len) { + pbuf_ref(next); + pbuf_free(cs->rp); + cs->rp = next; + cs->rp_offset = 0; + } else { + pbuf_free(cs->rp); + cs->rp = NULL; + } + } +} + +static void kserver_err(void *arg, err_t err) +{ + struct kserver_connstate *cs; + + cs = (struct kserver_connstate *)arg; + cs_free(cs); +} + +static struct tcp_pcb *listen_pcb; + +static err_t kserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + struct kserver_connstate *cs; + + cs = cs_new(); + if(!cs) + return ERR_MEM; + tcp_accepted(listen_pcb); + tcp_arg(newpcb, cs); + tcp_recv(newpcb, kserver_recv); + tcp_err(newpcb, kserver_err); + return ERR_OK; +} + +static void kserver_init(void) +{ + listen_pcb = tcp_new(); + tcp_bind(listen_pcb, IP_ADDR_ANY, 1381); + listen_pcb = tcp_listen(listen_pcb); + tcp_accept(listen_pcb, kserver_accept); +} + +extern struct tcp_pcb *tcp_active_pcbs; + +static void kserver_service(void) +{ + struct tcp_pcb *pcb; + void *data; + int len, sndbuf; + + /* Assume all active TCP PCBs with a non-NULL arg are our connections. */ + pcb = tcp_active_pcbs; + while(pcb) { + if(pcb->callback_arg) + tcp_pcb_service(pcb->callback_arg, pcb); + pcb = pcb->next; + } + + if(active_cs) { + session_poll(&data, &len); + if(len > 0) { + sndbuf = tcp_sndbuf(active_pcb); + if(len > sndbuf) + len = sndbuf; + tcp_write(active_pcb, data, len, 0); + session_ack_data(len); + } + } +} + +static void regular_main(void) +{ + network_init(); + kserver_init(); + + while(1) { + lwip_service(); + kserver_service(); + } +} + +#else /* CSR_ETHMAC_BASE */ + +static void serial_service(void) +{ + char *txdata; + int txlen; + static char rxdata; + static int rxpending; + int r, i; + + if(!rxpending && uart_read_nonblock()) { + rxdata = uart_read(); + rxpending = 1; + } + if(rxpending) { + r = session_input(&rxdata, 1); + if(r > 0) + rxpending = 0; + if(r < 0) { + session_end(); + session_start(); + } + } + + session_poll((void **)&txdata, &txlen); + if(txlen > 0) { + for(i=0;i= get_out_packet_len()) { + buffer_out_index_data += len; +} + +void session_ack_mem(int len) +{ + buffer_out_index_mem += len; + if(buffer_out_index_mem >= get_out_packet_len()) { memset(&buffer_out[4], 0, 4); - buffer_out_index = 0; + buffer_out_index_mem = 0; } } diff --git a/soc/runtime/session.h b/soc/runtime/session.h index 8aab42cbb..988d0f6b0 100644 --- a/soc/runtime/session.h +++ b/soc/runtime/session.h @@ -6,9 +6,9 @@ void session_end(void); int session_input(void *data, int len); void session_poll(void **data, int *len); -void session_ack(int len); +void session_ack_data(int len); +void session_ack_mem(int len); int rpc(int rpc_num, ...); -void comm_service(void); #endif /* __SESSION_H */