diff --git a/litex/build/sim/core/modules/serial2tcp/serial2tcp.c b/litex/build/sim/core/modules/serial2tcp/serial2tcp.c index 990228603..bd9d06107 100644 --- a/litex/build/sim/core/modules/serial2tcp/serial2tcp.c +++ b/litex/build/sim/core/modules/serial2tcp/serial2tcp.c @@ -35,6 +35,18 @@ int litex_sim_module_get_args( char *args, char *arg, char **val) char *value = NULL; int r; + if(!arg) { + fprintf(stderr, "litex_sim_module_get_args(): `arg` (requested .json key) is NULL!\n"); + ret=RC_JSERROR; + goto out; + } + + if(!args) { + fprintf(stderr, "missing key in .json file: %s\n", arg); + ret=RC_JSERROR; + goto out; + } + jsobj = json_tokener_parse(args); if(NULL==jsobj) { fprintf(stderr, "Error parsing json arg: %s \n", args); @@ -97,10 +109,19 @@ void read_handler(int fd, short event, void *arg) struct session_s *s = (struct session_s*)arg; char buffer[1024]; ssize_t read_len; - - int i; + int i, ret; read_len = read(fd, buffer, 1024); + if (read_len == 0) { + // Received EOF, remote has closed the connection + ret = event_del(s->ev); + if (ret != 0) { + eprintf("read_handler(): Error removing event %d!\n", event); + return; + } + event_free(s->ev); + s->ev = NULL; + } for(i = 0; i < read_len; i++) { s->databuf[(s->data_start + s->datalen ) % 2048] = buffer[i]; @@ -128,7 +149,7 @@ static void accept_error_cb(struct evconnlistener *listener, void *ctx) { struct event_base *base = evconnlistener_get_base(listener); - eprintf("ERRROR\n"); + eprintf("ERROR\n"); event_base_loopexit(base, NULL); } @@ -146,7 +167,6 @@ static int serial2tcp_new(void **sess, char *args) ret = RC_INVARG; goto out; } - ret = litex_sim_module_get_args(args, "port", &cport); if(RC_OK != ret) goto out; @@ -233,10 +253,13 @@ static int serial2tcp_tick(void *sess, uint64_t time_ps) *s->rx_valid=0; if(s->datalen) { - *s->rx=s->databuf[s->data_start]; - s->data_start = (s->data_start + 1) % 2048; - s->datalen--; + c = s->databuf[s->data_start]; + *s->rx = c; *s->rx_valid=1; + if (*s->rx_ready) { + s->data_start = (s->data_start + 1) % 2048; + s->datalen--; + } } out: diff --git a/litex/soc/cores/uart.py b/litex/soc/cores/uart.py index 7cf79cd22..0ab6c035d 100644 --- a/litex/soc/cores/uart.py +++ b/litex/soc/cores/uart.py @@ -259,7 +259,6 @@ class Stream2Wishbone(Module): self.sink = sink = stream.Endpoint([("data", 8)]) if phy is None else phy.source self.source = source = stream.Endpoint([("data", 8)]) if phy is None else phy.sink self.wishbone = wishbone.Interface() - self.comb += sink.ready.eq(1) # Always accept incoming stream. # # # @@ -280,6 +279,7 @@ class Stream2Wishbone(Module): self.submodules += fsm, timer self.comb += fsm.reset.eq(timer.done) fsm.act("RECEIVE-CMD", + sink.ready.eq(1), NextValue(bytes_count, 0), NextValue(words_count, 0), If(sink.valid, @@ -288,12 +288,14 @@ class Stream2Wishbone(Module): ) ) fsm.act("RECEIVE-LENGTH", + sink.ready.eq(1), If(sink.valid, NextValue(length, sink.data), NextState("RECEIVE-ADDRESS") ) ) fsm.act("RECEIVE-ADDRESS", + sink.ready.eq(1), If(sink.valid, NextValue(address, Cat(sink.data, address)), NextValue(bytes_count, bytes_count + 1), @@ -311,6 +313,7 @@ class Stream2Wishbone(Module): ) ) fsm.act("RECEIVE-DATA", + sink.ready.eq(1), If(sink.valid, NextValue(data, Cat(sink.data, data)), NextValue(bytes_count, bytes_count + 1), @@ -325,6 +328,7 @@ class Stream2Wishbone(Module): self.wishbone.sel.eq(2**(data_width//8) - 1) ] fsm.act("WRITE-DATA", + sink.ready.eq(0), self.wishbone.stb.eq(1), self.wishbone.we.eq(1), self.wishbone.cyc.eq(1), @@ -339,6 +343,7 @@ class Stream2Wishbone(Module): ) ) fsm.act("READ-DATA", + sink.ready.eq(0), self.wishbone.stb.eq(1), self.wishbone.we.eq(0), self.wishbone.cyc.eq(1), @@ -352,6 +357,7 @@ class Stream2Wishbone(Module): cases[i] = source.data.eq(data[8*n:]) self.comb += Case(bytes_count, cases) fsm.act("SEND-DATA", + sink.ready.eq(0), source.valid.eq(1), If(source.ready, NextValue(bytes_count, bytes_count + 1),