diff options
59 files changed, 1602 insertions, 133 deletions
diff --git a/code/ecp/Makefile b/code/ecp/Makefile index 88d8c84..1b16f39 100644 --- a/code/ecp/Makefile +++ b/code/ecp/Makefile @@ -1,4 +1,4 @@ -include ../Makefile.platform +include Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I.  obj = core.o timer.o $(obj_rbuf) diff --git a/code/Makefile.fe310 b/code/ecp/Makefile.fe310 index aff2784..130566b 100644 --- a/code/Makefile.fe310 +++ b/code/ecp/Makefile.fe310 @@ -3,10 +3,10 @@ vconn=vconn  platform=fe310  rbuf_obj= -FE310_HOME=/Users/majstor/src/sifive/freedom-e-sdk -EOS_HOME=/Users/majstor/src/sifive/hello +FE310_HOME=/opt/my/freedom-e-sdk  CC=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc  AR=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar -CFLAGS_PL=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(EOS_HOME) -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1  + +CFLAGS_PL=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1   # LDFLAGS_PL=-lm -pthread
\ No newline at end of file diff --git a/code/Makefile.posix b/code/ecp/Makefile.posix index 2680875..2680875 100644 --- a/code/Makefile.posix +++ b/code/ecp/Makefile.posix diff --git a/code/config_fe310.h b/code/ecp/config_fe310.h index fc95c26..fc95c26 100644 --- a/code/config_fe310.h +++ b/code/ecp/config_fe310.h diff --git a/code/config_posix.h b/code/ecp/config_posix.h index ad67d8a..ad67d8a 100644 --- a/code/config_posix.h +++ b/code/ecp/config_posix.h diff --git a/code/ecp/core.c b/code/ecp/core.c index f81bbc6..3f77c6f 100644 --- a/code/ecp/core.c +++ b/code/ecp/core.c @@ -544,7 +544,7 @@ static ssize_t _conn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {      payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);      ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ); -    return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), ti); +    return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);  }  int ecp_conn_init(ECPConnection *conn, ECPNode *node) { @@ -687,7 +687,7 @@ static ssize_t _conn_send_open(ECPConnection *conn, ECPTimerItem *ti) {      ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REQ);      buf[0] = conn->type; -    return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1, ECP_MTYPE_OPEN_REQ), ti); +    return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1, ECP_MTYPE_OPEN_REQ), 0, ti);  }  ssize_t ecp_conn_send_open(ECPConnection *conn) { @@ -781,6 +781,7 @@ ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char m          unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn)];          unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn)];          unsigned char ctype = 0; +          packet.buffer = pkt_buf;          packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn);          payload.buffer = pld_buf; @@ -788,7 +789,7 @@ ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char m          ctype = msg[0];          ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REP); -        ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP)); +        ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP), 0);          return 1;      } @@ -820,8 +821,10 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m          int rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1);          if (!rv && !is_open) {              ecp_conn_open_t *conn_open = ctx->handler[conn->type] ? ctx->handler[conn->type]->conn_open : NULL; -            ssize_t _rv = conn_open(conn); -            if (_rv < 0) rv = _rv; +            if (conn_open) { +                ssize_t _rv = conn_open(conn); +                if (_rv < 0) rv = _rv; +            }          }          if (rv) return rv; @@ -844,7 +847,7 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m          ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REP);          int rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1);          if (rv) return rv; -        ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP)); +        ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);          return 0;      } @@ -875,7 +878,7 @@ ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char m          if (rv) return rv;          ecp_pld_set_type(pld_buf, ECP_MTYPE_KPUT_REP); -        ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP)); +        ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP), 0);          return ECP_ECDH_SIZE_KEY+1;      } @@ -886,6 +889,7 @@ ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char m  ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {      if (size < 0) return size;      if (b == NULL) return ECP_ERR; +    if (b->packet->buffer == NULL) return ECP_ERR;      memcpy(b->packet->buffer, msg, size);      return ecp_pkt_handle(conn->sock, NULL, conn, b, size); @@ -931,7 +935,7 @@ static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) {      rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1);      if (rv) return rv; -    return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), ti); +    return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), 0, ti);  }  int ecp_conn_dhkey_new(ECPConnection *conn) { @@ -1006,7 +1010,6 @@ int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned ch  ssize_t ecp_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, unsigned char *payload, size_t pld_size) {      ssize_t rv; -    if (payload == NULL) return ECP_ERR;      if (pkt_size < ECP_SIZE_PKT_HDR) return ECP_ERR;      // ECP_SIZE_PROTO @@ -1114,21 +1117,30 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz  }  ssize_t _ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) { +    if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; +    if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; +      return ecp_conn_pack(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, si, addr);  }  ssize_t _ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { +    if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; +    if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; +      return ecp_pack_raw(sock, parent, packet->buffer, packet->size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size, addr);  } -ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *payload, size_t pld_size, unsigned char *packet, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq) { +ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq) {      unsigned char s_idx;      unsigned char c_idx;      unsigned char l_idx = ECP_ECDH_IDX_INV; +    unsigned char *payload = bufs->payload->buffer; +    unsigned char *packet = bufs->packet->buffer;      ecp_aead_key_t shsec;      ecp_dh_public_t public;      ecp_dh_private_t private; +    ECPContext *ctx = sock->ctx;      ECPConnection *conn = NULL;      ECPDHKey *key = NULL;      int rv = ECP_OK; @@ -1198,7 +1210,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, uns          memset(&private, 0, sizeof(private));      } -    dec_size = sock->ctx->cr.aead_dec(payload, pld_size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY); +    dec_size = sock->ctx->cr.aead_dec(payload, bufs->payload->size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY);      if (dec_size < ECP_SIZE_PLD_HDR+1) rv = ECP_ERR_DECRYPT;      if (rv) goto ecp_unpack_err; @@ -1208,6 +1220,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, uns          (payload[2] << 8)  | \          (payload[3]); +    if (ctx->tr.buf_free && ((payload[ECP_SIZE_PLD_HDR] & ECP_MTYPE_MASK) < ECP_MAX_MTYPE_SYS)) ctx->tr.buf_free(bufs, ECP_SEND_FLAG_MORE);      if (conn == NULL) {          if (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_OPEN_REQ) {              is_new = 1; @@ -1229,7 +1242,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, uns              rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1);              if (!rv) { -                ssize_t _rv = ecp_pld_send_raw(sock, parent, addr, &_packet, s_idx, c_idx, &public, &shsec, packet+ECP_SIZE_PKT_HDR, seq_p, &_payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP)); +                ssize_t _rv = ecp_pld_send_raw(sock, parent, addr, &_packet, s_idx, c_idx, &public, &shsec, packet+ECP_SIZE_PKT_HDR, seq_p, &_payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);                  if (_rv < 0) rv = _rv;              }              if (rv) return rv; @@ -1327,13 +1340,13 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent,      ECPConnection *conn;      ecp_seq_t seq;      ssize_t rv = 0; -    ssize_t pld_size = ecp_unpack(sock, addr, parent, bufs->payload->buffer, bufs->payload->size, bufs->packet->buffer, pkt_size, &conn, &seq); +    ssize_t pld_size = ecp_unpack(sock, addr, parent, bufs, pkt_size, &conn, &seq);      if (pld_size < 0) return pld_size;      if (conn) {          rv = 0;  #ifdef ECP_WITH_RBUF -        if (conn->rbuf.recv) rv = ecp_rbuf_recv_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR); +        if (conn->rbuf.recv) rv = ecp_rbuf_recv_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs);  #endif          if (rv == 0) rv = ecp_msg_handle(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs); @@ -1352,11 +1365,15 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent,      return ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG+ECP_SIZE_PLD_HDR+rv;  } -ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size) { -    ssize_t rv = sock->ctx->tr.send(&sock->sock, packet, pkt_size, addr); +ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags) { +    ssize_t rv = sock->ctx->tr.send(&sock->sock, packet, pkt_size, addr, flags);      if (rv < 0) return rv;      if (rv < ECP_MIN_PKT) return ECP_ERR_SEND; +    if (flags & ECP_SEND_FLAG_REPLY) { +        packet->buffer = NULL; +        packet->size = 0; +    }      return rv;  } @@ -1536,7 +1553,7 @@ unsigned char *ecp_pld_get_buf(unsigned char *payload, unsigned char mtype) {      return payload + ECP_SIZE_PLD_HDR + 1 + ECP_SIZE_MT_FLAG(mtype);  } -static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti, ECPSeqItem *si) { +static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) {      ECPSocket *sock = conn->sock;      ECPContext *ctx = sock->ctx;      ECPNetAddr addr; @@ -1545,25 +1562,25 @@ static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_      if (rv < 0) return rv;  #ifdef ECP_WITH_RBUF -    if (conn->rbuf.send) return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet->buffer, rv, ti, si); +    if (conn->rbuf.send) return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet, rv, flags, ti, si);  #endif      if (ti) {          int _rv = ecp_timer_push(ti);          if (_rv) return _rv;      } -    return ecp_pkt_send(sock, &addr, packet->buffer, rv); +    return ecp_pkt_send(sock, &addr, packet, rv, flags);  } -ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size) { -    return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, NULL); +ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags) { +    return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, NULL);  } -ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti) { -    return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, ti); +ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { +    return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, ti);  } -ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti) { +ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {      ECPSeqItem *_seq_item = NULL;  #ifdef ECP_WITH_RBUF @@ -1576,10 +1593,10 @@ ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_      }  #endif -    return pld_send(conn, packet, s_idx, c_idx, payload, pld_size, ti, _seq_item); +    return pld_send(conn, packet, s_idx, c_idx, payload, pld_size, flags, ti, _seq_item);  } -ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size) { +ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, unsigned char flags) {      ECPContext *ctx = sock->ctx;      ECPNetAddr _addr;      ssize_t rv; @@ -1587,7 +1604,7 @@ ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *add      rv = ctx->pack_raw(sock, parent, packet, s_idx, c_idx, public, shsec, nonce, seq, payload, pld_size, &_addr);      if (rv < 0) return rv; -    return ecp_pkt_send(sock, parent ? &_addr : addr, packet->buffer, rv); +    return ecp_pkt_send(sock, parent ? &_addr : addr, packet, rv, flags);  }  ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size) { @@ -1641,7 +1658,7 @@ ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *conten              content += frag_size;              seq_item.seq = seq_start + i; -            ssize_t _rv = pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(frag_size, mtype), NULL, &seq_item); +            ssize_t _rv = pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(frag_size, mtype), 0, NULL, &seq_item);              if (_rv < 0) return _rv;              rv += _rv; @@ -1649,7 +1666,7 @@ ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *conten      } else {          ecp_pld_set_type(pld_buf, mtype);          memcpy(ecp_pld_get_buf(pld_buf, mtype), content, content_size); -        rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(content_size, mtype)); +        rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(content_size, mtype), 0);      }      return rv;  } @@ -1669,17 +1686,14 @@ ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg  #endif  } -static int recv_p(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pkt_buf, size_t size) { +static int recv_p(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t size) {      ECP2Buffer bufs; -    ECPBuffer packet;      ECPBuffer payload;      unsigned char pld_buf[ECP_MAX_PLD]; -    bufs.packet = &packet; +    bufs.packet = packet;      bufs.payload = &payload; -    packet.buffer = pkt_buf; -    packet.size = ECP_MAX_PKT;      payload.buffer = pld_buf;      payload.size = ECP_MAX_PLD; @@ -1691,16 +1705,20 @@ static int recv_p(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pkt_buf, siz  int ecp_receiver(ECPSocket *sock) {      ECPNetAddr addr; +    ECPBuffer packet;      unsigned char pkt_buf[ECP_MAX_PKT];      ecp_cts_t next = 0; - +    ssize_t rv = 0;      if (sock->ctx->tr.recv == NULL) return ECP_ERR;      sock->running = 1;      while(sock->running) { -        ssize_t rv = sock->ctx->tr.recv(&sock->sock, pkt_buf, ECP_MAX_PKT, &addr, next ? next : sock->poll_timeout); +        packet.buffer = pkt_buf; +        packet.size = ECP_MAX_PKT; + +        rv = sock->ctx->tr.recv(&sock->sock, &packet, &addr, next ? next : sock->poll_timeout);          if (rv > 0) { -            int _rv = recv_p(sock, &addr, pkt_buf, rv); +            int _rv = recv_p(sock, &addr, &packet, rv);              DPRINT(_rv, "ERR:recv_p - RV:%d\n", _rv);          }          next = ecp_timer_exe(sock); diff --git a/code/ecp/core.h b/code/ecp/core.h index ce81d9d..0248814 100644 --- a/code/ecp/core.h +++ b/code/ecp/core.h @@ -78,10 +78,13 @@  #define ECP_CONN_FLAG_REG           0x01  #define ECP_CONN_FLAG_OPEN          0x02 +#define ECP_SEND_FLAG_REPLY         0x01 +#define ECP_SEND_FLAG_MORE          0x02 +  #define ecp_conn_is_reg(conn)       ((conn->flags) & ECP_CONN_FLAG_REG)  #define ecp_conn_is_open(conn)      ((conn->flags) & ECP_CONN_FLAG_OPEN) -#include "../config.h" +#include "config.h"  #include <sys/types.h>  #include <stddef.h> @@ -184,16 +187,20 @@ typedef struct ECPTransportIface {      int init;      int (*open) (ECPNetSock *, void *addr);      void (*close) (ECPNetSock *); -    ssize_t (*send) (ECPNetSock *, void *, size_t, ECPNetAddr *); -    ssize_t (*recv) (ECPNetSock *, void *, size_t, ECPNetAddr *, int); +    ssize_t (*send) (ECPNetSock *, struct ECPBuffer *packet, size_t, ECPNetAddr *, unsigned char); +    ssize_t (*recv) (ECPNetSock *, struct ECPBuffer *packet, ECPNetAddr *, int);      int (*addr_eq) (ECPNetAddr *, ECPNetAddr *);      int (*addr_set) (ECPNetAddr *, void *addr); +    void (*buf_free) (struct ECP2Buffer *, unsigned char); +    void (*buf_flag_set) (struct ECP2Buffer *, unsigned char); +    void (*buf_flag_clear) (struct ECP2Buffer *, unsigned char);  } ECPTransportIface;  typedef struct ECPTimeIface {      int init;      ecp_cts_t (*abstime_ms) (ecp_cts_t);      void (*sleep_ms) (ecp_cts_t); +    void (*timer_set) (ecp_cts_t);  } ECPTimeIface;  #ifdef ECP_WITH_HTABLE @@ -392,10 +399,10 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz  ssize_t _ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr);  ssize_t _ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr); -ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *payload, size_t pld_size, unsigned char *packet, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq); +ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq);  ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size); -ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size); +ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags);  int ecp_seq_item_init(ECPSeqItem *seq_item);  int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size); @@ -413,10 +420,10 @@ int ecp_pld_set_pts(unsigned char *payload, unsigned char mtype, ecp_pts_t pts);  unsigned char *ecp_pld_get_buf(unsigned char *payload, unsigned char mtype);  unsigned char ecp_pld_get_type(unsigned char *payload); -ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size); -ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti); -ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti); -ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size); +ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags); +ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); +ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); +ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, unsigned char flags);  ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size);  ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout); diff --git a/code/ecp/crypto/Makefile b/code/ecp/crypto/Makefile index a7145c7..797cb16 100644 --- a/code/ecp/crypto/Makefile +++ b/code/ecp/crypto/Makefile @@ -1,4 +1,4 @@ -include ../../Makefile.platform +include ../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -Iinclude -I.. -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=  obj = e_chacha20poly1305.o crypto.o diff --git a/code/ecp/crypto/chacha/Makefile b/code/ecp/crypto/chacha/Makefile index 8a977ae..e64aac3 100644 --- a/code/ecp/crypto/chacha/Makefile +++ b/code/ecp/crypto/chacha/Makefile @@ -1,4 +1,4 @@ -include ../../../Makefile.platform +include ../../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=  obj = chacha.o diff --git a/code/ecp/crypto/compat/Makefile b/code/ecp/crypto/compat/Makefile index 1afe391..9e96d9e 100644 --- a/code/ecp/crypto/compat/Makefile +++ b/code/ecp/crypto/compat/Makefile @@ -1,4 +1,4 @@ -include ../../../Makefile.platform +include ../../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=  getentropy = getentropy_osx diff --git a/code/ecp/crypto/curve25519/Makefile b/code/ecp/crypto/curve25519/Makefile index c3f94f0..5799e0e 100644 --- a/code/ecp/crypto/curve25519/Makefile +++ b/code/ecp/crypto/curve25519/Makefile @@ -1,4 +1,4 @@ -include ../../../Makefile.platform +include ../../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= -DED25519  obj = curve25519.o curve25519-generic.o diff --git a/code/ecp/crypto/poly1305/Makefile b/code/ecp/crypto/poly1305/Makefile index 6bc384f..5751602 100644 --- a/code/ecp/crypto/poly1305/Makefile +++ b/code/ecp/crypto/poly1305/Makefile @@ -1,4 +1,4 @@ -include ../../../Makefile.platform +include ../../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=  obj = poly1305.o diff --git a/code/ecp/crypto/sha/Makefile b/code/ecp/crypto/sha/Makefile index 1eb727f..4dc3f39 100644 --- a/code/ecp/crypto/sha/Makefile +++ b/code/ecp/crypto/sha/Makefile @@ -1,4 +1,4 @@ -include ../../../Makefile.platform +include ../../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=  obj = sha1dgst.o sha1_one.o sha256.o sha512.o diff --git a/code/ecp/crypto/test/Makefile b/code/ecp/crypto/test/Makefile index 2a5fa3e..8ea463d 100644 --- a/code/ecp/crypto/test/Makefile +++ b/code/ecp/crypto/test/Makefile @@ -1,4 +1,4 @@ -include ../../../Makefile.platform +include ../../Makefile.platform  CFLAGS=$(CFLAGS_PL) -I.. -I../include  LDFLAGS=$(LDFLAGS_PL) diff --git a/code/ecp/fe310/Makefile b/code/ecp/fe310/Makefile index 6dd42e2..1ccf322 100644 --- a/code/ecp/fe310/Makefile +++ b/code/ecp/fe310/Makefile @@ -1,5 +1,5 @@ -include ../../Makefile.platform -CFLAGS=$(CFLAGS_PL) $(PIC) -I.. +include ../Makefile.platform +CFLAGS=$(CFLAGS_PL) $(PIC) -I.. -I../../fe310  obj_tr = transport.o  obj_tm = time.o diff --git a/code/ecp/fe310/time.c b/code/ecp/fe310/time.c index 2ff98cb..4b8b2a7 100644 --- a/code/ecp/fe310/time.c +++ b/code/ecp/fe310/time.c @@ -1,5 +1,7 @@  #include <core.h> +#include <eos/timer.h> +  #include "encoding.h"  #include "platform.h" @@ -10,9 +12,14 @@ static ecp_cts_t t_abstime_ms(ecp_cts_t msec) {      return now_ms + msec;  } +static void t_timer_set(ecp_cts_t next) { +    uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; +    eos_timer_set(tick, 1); +} +  int ecp_time_init(ECPTimeIface *t) {      t->init = 1;      t->abstime_ms = t_abstime_ms; -    t->sleep_ms = NULL; +    t->timer_set = t_timer_set;      return 0;  } diff --git a/code/ecp/fe310/transport.c b/code/ecp/fe310/transport.c index b833ee3..9ff04ca 100644 --- a/code/ecp/fe310/transport.c +++ b/code/ecp/fe310/transport.c @@ -1,10 +1,10 @@  #include <stddef.h>  #include <string.h> -#include <core.h> +#include <eos/eos.h> +#include <eos/net.h> -#include "eos.h" -#include "net.h" +#include <core.h>  static int t_addr_eq(ECPNetAddr *addr1, ECPNetAddr *addr2) {      if (addr1->port != addr2->port) return 0; @@ -20,27 +20,55 @@ static int t_open(int *sock, void *addr_s) {  static void t_close(int *sock) {  } -static ssize_t t_send(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr) { -    unsigned char *buf = msg; +static ssize_t t_send(int *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags) { +    unsigned char *buf = NULL;      size_t addr_len = sizeof(addr->host) + sizeof(addr->port);      uint16_t buf_size = msg_size + addr_len; +    unsigned char cmd = EOS_NET_CMD_PKT;      int rv; -    buf -= addr_len; +    if (flags & ECP_SEND_FLAG_MORE) { +        cmd |= EOS_NET_CMD_FLAG_ONEW; +    } +    if (flags & ECP_SEND_FLAG_REPLY) { +        if (packet && packet->buffer) buf = packet->buffer-addr_len; +    } else { +        buf = eos_net_alloc(); +    } +    if (buf == NULL) return ECP_ERR;      memcpy(buf, addr->host, sizeof(addr->host));      memcpy(buf+sizeof(addr->host), &addr->port, sizeof(addr->port)); -    rv = eos_net_send(EOS_NET_CMD_PKT, buf, buf_size); +    rv = eos_net_send(cmd, buf, buf_size);      if (rv) return ECP_ERR_SEND;      return msg_size;  } +static void t_buf_free(ECP2Buffer *b, unsigned char flags) { +    size_t addr_len = ECP_IPv4_ADDR_SIZE + sizeof(uint16_t); +    if (b && b->packet && b->packet->buffer) eos_net_free(b->packet->buffer-addr_len, flags & ECP_SEND_FLAG_MORE); +} + +static void t_buf_flag_set(ECP2Buffer *b, unsigned char flags) { +    size_t addr_len = ECP_IPv4_ADDR_SIZE + sizeof(uint16_t); +    if (flags & ECP_SEND_FLAG_MORE) { +        if (b && b->packet && b->packet->buffer) eos_net_reserve(b->packet->buffer-addr_len); +    } +} + +static void t_buf_flag_clear(ECP2Buffer *b, unsigned char flags) { +    if (flags & ECP_SEND_FLAG_MORE) { +        eos_net_release(1); +    } +} +  int ecp_transport_init(ECPTransportIface *t) {      t->init = 1;      t->open = t_open;      t->close = t_close;      t->send = t_send; -    t->recv = NULL;      t->addr_eq = t_addr_eq; -    t->addr_set = NULL; +    t->buf_free = t_buf_free; +    t->buf_flag_set = t_buf_flag_set; +    t->buf_flag_clear = t_buf_flag_clear;      return ECP_OK;  } diff --git a/code/ecp/htable/Makefile b/code/ecp/htable/Makefile index eb73403..6f5b888 100644 --- a/code/ecp/htable/Makefile +++ b/code/ecp/htable/Makefile @@ -1,4 +1,4 @@ -include ../../Makefile.platform +include ../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I.. -std=gnu89   obj = htable.o hashtable.o hashtable_itr.o diff --git a/code/ecp/posix/Makefile b/code/ecp/posix/Makefile index 6dd42e2..595b0b5 100644 --- a/code/ecp/posix/Makefile +++ b/code/ecp/posix/Makefile @@ -1,4 +1,4 @@ -include ../../Makefile.platform +include ../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I..  obj_tr = transport.o diff --git a/code/ecp/posix/transport.c b/code/ecp/posix/transport.c index df8e0f5..bdd166a 100644 --- a/code/ecp/posix/transport.c +++ b/code/ecp/posix/transport.c @@ -71,17 +71,17 @@ static void t_close(int *sock) {      close(*sock);  } -static ssize_t t_send(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr) { +static ssize_t t_send(int *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags) {      struct sockaddr_in servaddr;      memset((void *)&servaddr, 0, sizeof(servaddr));      servaddr.sin_family = AF_INET;      servaddr.sin_port = addr->port;      memcpy((void *)&servaddr.sin_addr, addr->host, sizeof(addr->host)); -    return sendto(*sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); +    return sendto(*sock, packet->buffer, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));  } -static ssize_t t_recv(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr, int timeout) { +static ssize_t t_recv(int *sock, ECPBuffer *packet, ECPNetAddr *addr, int timeout) {      struct sockaddr_in servaddr;      socklen_t addrlen = sizeof(servaddr);      struct pollfd fds[] = { @@ -91,7 +91,7 @@ static ssize_t t_recv(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr, i      int rv = poll(fds, 1, timeout);      memset((void *)&servaddr, 0, sizeof(servaddr));      if (rv == 1) { -        ssize_t recvlen = recvfrom(*sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, &addrlen); +        ssize_t recvlen = recvfrom(*sock, packet->buffer, packet->size, 0, (struct sockaddr *)&servaddr, &addrlen);          if (recvlen < 0) return recvlen;          if (recvlen < ECP_MIN_PKT) return ECP_ERR_RECV; diff --git a/code/ecp/rbuf.c b/code/ecp/rbuf.c index b5f66a9..d24ac23 100644 --- a/code/ecp/rbuf.c +++ b/code/ecp/rbuf.c @@ -44,7 +44,7 @@ ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned ch      return msg_size;  } -ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, ecp_seq_t seq) { +ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq) {      ECPSocket *sock = conn->sock;      ECPContext *ctx = sock->ctx;      ECPNetAddr addr; @@ -61,7 +61,7 @@ ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *pay      rv = ctx->pack(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, &seq_item, &addr);      if (rv < 0) return rv; -    rv = ecp_pkt_send(sock, &addr, packet->buffer, rv); +    rv = ecp_pkt_send(sock, &addr, packet, rv, flags);      if (rv < 0) return rv;      return rv; diff --git a/code/ecp/rbuf.h b/code/ecp/rbuf.h index 145234f..c4ea08e 100644 --- a/code/ecp/rbuf.h +++ b/code/ecp/rbuf.h @@ -51,8 +51,8 @@ typedef struct ECPRBTimer {  typedef struct ECPRBRecv {      unsigned char flags; -    unsigned char flush;      unsigned char timer_pts; +    unsigned char ack_do;      unsigned short hole_max;      unsigned short ack_rate;      ecp_pts_t deliver_delay; @@ -94,7 +94,7 @@ int ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq);  int ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq);  ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned char *msg, size_t msg_size, unsigned char test_flags, unsigned char set_flags); -ssize_t ecp_rbuf_pld_send(struct ECPConnection *conn, struct ECPBuffer *packet, struct ECPBuffer *payload, size_t pld_size, ecp_seq_t seq); +ssize_t ecp_rbuf_pld_send(struct ECPConnection *conn, struct ECPBuffer *packet, struct ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq);  int ecp_rbuf_create(struct ECPConnection *conn, ECPRBSend *buf_s, ECPRBMessage *msg_s, unsigned int msg_s_size, ECPRBRecv *buf_r, ECPRBMessage *msg_r, unsigned int msg_r_size);  void ecp_rbuf_destroy(struct ECPConnection *conn); @@ -104,13 +104,13 @@ void ecp_rbuf_recv_destroy(struct ECPConnection *conn);  int ecp_rbuf_recv_set_hole(struct ECPConnection *conn, unsigned short hole_max);  int ecp_rbuf_recv_set_delay(struct ECPConnection *conn, ecp_pts_t delay);  int ecp_rbuf_recv_start(struct ECPConnection *conn, ecp_seq_t seq); -ssize_t ecp_rbuf_recv_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size); +ssize_t ecp_rbuf_recv_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);  int ecp_rbuf_send_create(struct ECPConnection *conn, ECPRBSend *buf, ECPRBMessage *msg, unsigned int msg_size);  void ecp_rbuf_send_destroy(struct ECPConnection *conn);  int ecp_rbuf_send_start(struct ECPConnection *conn);  int ecp_rbuf_pkt_prep(ECPRBSend *buf, struct ECPSeqItem *si, unsigned char mtype); -ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, struct ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, ECPTimerItem *ti, struct ECPSeqItem *si); +ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, struct ECPSocket *sock, ECPNetAddr *addr, struct ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, struct ECPSeqItem *si);  ssize_t ecp_rbuf_handle_ack(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);  ssize_t ecp_rbuf_handle_flush(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b); diff --git a/code/ecp/rbuf_recv.c b/code/ecp/rbuf_recv.c index 44b5113..c262f1d 100644 --- a/code/ecp/rbuf_recv.c +++ b/code/ecp/rbuf_recv.c @@ -5,7 +5,7 @@  #define ACK_RATE            8  #define ACK_MASK_FIRST      ((ecp_ack_t)1 << (ECP_SIZE_ACKB - 1)) -static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size) { +static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {      ECPRBRecv *buf = conn->rbuf.recv;      unsigned char flags = ECP_RBUF_FLAG_IN_RBUF;      unsigned char mtype = ecp_msg_get_type(msg) & ECP_MTYPE_MASK; @@ -29,12 +29,12 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg,      if (rv < 0) return rv;      if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) buf->rbuf.seq_max = seq; -    if (flags & ECP_RBUF_FLAG_SYS) ecp_msg_handle(conn, seq, msg, msg_size, NULL); +    if (flags & ECP_RBUF_FLAG_SYS) ecp_msg_handle(conn, seq, msg, msg_size, b);      return rv;  } -static void msg_flush(ECPConnection *conn) { +static void msg_flush(ECPConnection *conn, ECP2Buffer *b) {      ECPRBRecv *buf = conn->rbuf.recv;  #ifdef ECP_WITH_MSGQ @@ -101,7 +101,7 @@ static void msg_flush(ECPConnection *conn) {                      buf->rbuf.msg[idx].flags |= ECP_RBUF_FLAG_IN_MSGQ;  #endif                  } else { -                    ecp_msg_handle(conn, seq, buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, NULL); +                    ecp_msg_handle(conn, seq, buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, b);                  }              }              buf->rbuf.msg[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF; @@ -148,10 +148,11 @@ static int ack_send(ECPConnection *conn) {      buf_[6] = (buf->ack_map & 0x0000FF00) >> 8;      buf_[7] = (buf->ack_map & 0x000000FF); -    rv = ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0); +    rv = ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0, 0);      if (rv < 0) return rv;      buf->ack_pkt = 0; +    buf->ack_do = 0;      return ECP_OK;  } @@ -170,7 +171,7 @@ static int ack_shift(ECPRBRecv *buf) {          if (in_rbuf && (buf->ack_map == ECP_ACK_FULL)) continue;          buf->ack_map = buf->ack_map << 1; -        if (in_rbuf & ECP_RBUF_FLAG_IN_RBUF) { +        if (in_rbuf) {              buf->ack_map |= 1;          } else if (!do_ack && ECP_SEQ_LTE(buf->seq_ack, buf->rbuf.seq_max - 2 * buf->hole_max)) {              do_ack = 1; @@ -197,10 +198,12 @@ static int ack_shift(ECPRBRecv *buf) {  ssize_t ecp_rbuf_handle_flush(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {      if (size < 0) return size; +    ECPContext *ctx = conn->sock->ctx;      ECPRBRecv *buf = conn->rbuf.recv;      if (buf == NULL) return ECP_ERR; -    buf->flush = 1; +    if (ctx->tr.buf_free) ctx->tr.buf_free(b, ECP_SEND_FLAG_MORE); +    ack_send(conn);      return 0;  } @@ -209,7 +212,7 @@ ssize_t ecp_rbuf_handle_flush_pts(ECPConnection *conn, ecp_seq_t seq, unsigned c      if (buf == NULL) return ECP_ERR;      buf->timer_pts = 0; -    msg_flush(conn); +    msg_flush(conn, b);      return 0;  } @@ -282,17 +285,20 @@ int ecp_rbuf_recv_start(ECPConnection *conn, ecp_seq_t seq) {      return ECP_OK;  } -ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size) { +ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {      ECPRBRecv *buf = conn->rbuf.recv;      ecp_seq_t ack_pkt = 0;      ssize_t rv; -    int do_ack = 0;       unsigned char mtype;      mtype = ecp_msg_get_type(msg) & ECP_MTYPE_MASK; -    if ((mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return ecp_msg_handle(conn, seq, msg, msg_size, NULL); +    if ((mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return ecp_msg_handle(conn, seq, msg, msg_size, b); -    if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) ack_pkt = seq - buf->rbuf.seq_max; +    if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) { +        ack_pkt = seq - buf->rbuf.seq_max; +        buf->ack_pkt += ack_pkt; +        if (buf->ack_pkt > buf->ack_rate) buf->ack_do = 1; +    }      if (ECP_SEQ_LTE(seq, buf->seq_ack)) {          ecp_seq_t seq_offset = buf->seq_ack - seq;          if (seq_offset < ECP_SIZE_ACKB) { @@ -301,9 +307,9 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m              if (ack_mask & buf->ack_map) return ECP_ERR_RBUF_DUP;              buf->ack_map |= ack_mask; -            do_ack = ack_shift(buf); +            buf->ack_do = buf->ack_do || ack_shift(buf); -            rv = msg_store(conn, seq, msg, msg_size); +            rv = msg_store(conn, seq, msg, msg_size, b);              if (rv < 0) return rv;          } else {              return ECP_ERR_RBUF_DUP; @@ -311,10 +317,10 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m      } else {          if ((buf->ack_map == ECP_ACK_FULL) && (seq == (ecp_seq_t)(buf->seq_ack + 1))) {              if ((buf->flags & ECP_RBUF_FLAG_MSGQ) || buf->deliver_delay) { -                rv = msg_store(conn, seq, msg, msg_size); +                rv = msg_store(conn, seq, msg, msg_size, b);                  if (rv < 0) return rv;              } else { -                ecp_msg_handle(conn, seq, msg, msg_size, NULL); +                ecp_msg_handle(conn, seq, msg, msg_size, b);                  rv = msg_size;                  buf->rbuf.seq_max++;                  buf->rbuf.seq_start++; @@ -322,23 +328,14 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m              }              buf->seq_ack++;          } else { -            rv = msg_store(conn, seq, msg, msg_size); +            rv = msg_store(conn, seq, msg, msg_size, b);              if (rv < 0) return rv; -            do_ack = ack_shift(buf); +            buf->ack_do = buf->ack_do || ack_shift(buf);          }      } -    msg_flush(conn); -    if (buf->flush) { -        buf->flush = 0; -        do_ack = 1; -    } -    if (ack_pkt && !do_ack) { -        buf->ack_pkt += ack_pkt; -        // should send acks more aggresively when reliable and ack_map is not full (rate ~ PPS * RTT) -        if (buf->ack_pkt > buf->ack_rate) do_ack = 1; -    } -    if (do_ack) { +    msg_flush(conn, b); +    if (!(mtype < ECP_MAX_MTYPE_SYS) && buf->ack_do) {          int _rv = ack_send(conn);          if (_rv) return _rv;      } diff --git a/code/ecp/rbuf_send.c b/code/ecp/rbuf_send.c index f913e7e..61b29af 100644 --- a/code/ecp/rbuf_send.c +++ b/code/ecp/rbuf_send.c @@ -25,7 +25,7 @@ static ssize_t flush_send(ECPConnection *conn, ECPTimerItem *ti) {          rv = ecp_timer_push(&_ti);          if (rv) return rv;      } -    return ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_RBFLUSH), 0); +    return ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_RBFLUSH), 0, 0);  }  static void cc_flush(ECPConnection *conn) { @@ -65,8 +65,12 @@ static void cc_flush(ECPConnection *conn) {  #endif          for (i=0; i<pkt_to_send; i++) { +            ECPBuffer packet; +              if (rbuf->msg[_idx].idx_t != -1) ecp_timer_push(&ti[rbuf->msg[_idx].idx_t]); -            ecp_pkt_send(conn->sock, &conn->node.addr, rbuf->msg[_idx].msg, rbuf->msg[_idx].size); +            packet.buffer = rbuf->msg[_idx].msg; +            packet.size = rbuf->msg[_idx].size; +            ecp_pkt_send(conn->sock, &conn->node.addr, &packet, rbuf->msg[_idx].size, 0);              _idx = ECP_RBUF_IDX_MASK(_idx + 1, rbuf->msg_size);          } @@ -82,6 +86,7 @@ static void cc_flush(ECPConnection *conn) {  ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {      ECPRBSend *buf; +    ECPContext *ctx = conn->sock->ctx;      ssize_t rsize = sizeof(ecp_seq_t)+sizeof(ecp_ack_t);      ecp_seq_t seq_ack = 0;      ecp_ack_t ack_map = 0; @@ -105,6 +110,8 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt          (msg[6] << 8)  | \          (msg[7]); +    if (ctx->tr.buf_flag_set) ctx->tr.buf_flag_set(b, ECP_SEND_FLAG_MORE); +  #ifdef ECP_WITH_PTHREAD      pthread_mutex_lock(&buf->mutex);  #endif @@ -146,9 +153,12 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt                              payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_NOP, conn);                              ecp_pld_set_type(pld_buf, ECP_MTYPE_NOP); -                            ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_NOP), seq_ack + i); +                            ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_NOP), 0, seq_ack + i);                          } else { -                            ecp_pkt_send(conn->sock, &conn->node.addr, rbuf->msg[_idx].msg, rbuf->msg[_idx].size); +                            ECPBuffer packet; +                            packet.buffer = rbuf->msg[_idx].msg; +                            packet.size = rbuf->msg[_idx].size; +                            ecp_pkt_send(conn->sock, &conn->node.addr, &packet, rbuf->msg[_idx].size, 0);                          }                          if (!nack_first) {                              nack_first = 1; @@ -188,12 +198,14 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt      pthread_mutex_unlock(&buf->mutex);  #endif -    if (rv) return rv; - -    if (do_flush) { +    if (!rv && do_flush) {          ssize_t _rv = flush_send(conn, NULL); -        if (_rv < 0) return _rv; +        if (_rv < 0) rv = _rv;      } + +    if (ctx->tr.buf_flag_clear) ctx->tr.buf_flag_clear(b, ECP_SEND_FLAG_MORE); + +    if (rv) return rv;      return rsize;  } @@ -308,7 +320,7 @@ int ecp_rbuf_pkt_prep(ECPRBSend *buf, ECPSeqItem *si, unsigned char mtype) {      return ECP_OK;   } -ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, ECPTimerItem *ti, ECPSeqItem *si) { +ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) {      int do_send = 1;      ssize_t rv = 0; @@ -320,7 +332,7 @@ ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, uns          if (mtype < ECP_MAX_MTYPE_SYS) flags |= ECP_RBUF_FLAG_SYS; -        rv = ecp_rbuf_msg_store(&buf->rbuf, seq, idx, packet, pkt_size, 0, flags); +        rv = ecp_rbuf_msg_store(&buf->rbuf, seq, idx, packet->buffer, pkt_size, 0, flags);          if (rv < 0) return rv;          if (buf->flags & ECP_RBUF_FLAG_CCONTROL) { @@ -369,7 +381,7 @@ ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, uns              int _rv = ecp_timer_push(ti);              if (_rv) return _rv;          } -        rv = ecp_pkt_send(sock, addr, packet, pkt_size); +        rv = ecp_pkt_send(sock, addr, packet, pkt_size, flags);      }      return rv;  } diff --git a/code/ecp/timer.c b/code/ecp/timer.c index 691f75c..16a6ad0 100644 --- a/code/ecp/timer.c +++ b/code/ecp/timer.c @@ -58,6 +58,7 @@ int ecp_timer_push(ECPTimerItem *ti) {      if (!rv && !is_reg) rv = ECP_ERR_CLOSED;      if (!rv) { +        if (ctx->tm.timer_set) ctx->tm.timer_set(ti->timeout);          for (i=timer->head; i>=0; i--) {              if (ECP_CTS_LTE(ti->abstime, timer->item[i].abstime)) {                  if (i != timer->head) memmove(timer->item+i+2, timer->item+i+1, sizeof(ECPTimerItem) * (timer->head-i)); diff --git a/code/ecp/vconn/Makefile b/code/ecp/vconn/Makefile index 613601c..d9d2e6f 100644 --- a/code/ecp/vconn/Makefile +++ b/code/ecp/vconn/Makefile @@ -1,4 +1,4 @@ -include ../../Makefile.platform +include ../Makefile.platform  CFLAGS=$(CFLAGS_PL) $(PIC) -I..  obj = vconn.o diff --git a/code/ecp/vconn/vconn.c b/code/ecp/vconn/vconn.c index dadff0f..4023aa9 100644 --- a/code/ecp/vconn/vconn.c +++ b/code/ecp/vconn/vconn.c @@ -81,7 +81,7 @@ static ssize_t _vconn_send_open(ECPConnection *conn, ECPTimerItem *ti) {      payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);      ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ); -    return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), ti); +    return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);  }  static ssize_t vconn_open(ECPConnection *conn) { @@ -198,7 +198,7 @@ static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c      payload.size = b->payload->size - (payload.buffer - b->payload->buffer);      ecp_pld_set_type(payload.buffer, ECP_MTYPE_EXEC); -    rv = ecp_pld_send(conn_out, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size); +    rv = ecp_pld_send(conn_out, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY);  #ifdef ECP_WITH_PTHREAD      pthread_mutex_lock(&conn_out->mutex); @@ -286,7 +286,7 @@ static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) {      buf[0] = conn->type;      memcpy(buf+1, ctx->cr.dh_pub_get_buf(&sock->key_perma.public), ECP_ECDH_SIZE_KEY); -    return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ), ti); +    return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ), 0, ti);  }  static ssize_t vlink_open(ECPConnection *conn) { @@ -372,7 +372,7 @@ static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c      payload.size = b->payload->size - (payload.buffer - b->payload->buffer);      ecp_pld_set_type(payload.buffer, ECP_MTYPE_EXEC); -    rv = ecp_pld_send(conn, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size); +    rv = ecp_pld_send(conn, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY);  #ifdef ECP_WITH_PTHREAD      pthread_mutex_lock(&conn->mutex); @@ -422,6 +422,9 @@ static ssize_t vconn_set_msg(ECPConnection *conn, ECPBuffer *payload, unsigned c  static ssize_t vconn_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) {      ECPContext *ctx = conn->sock->ctx; +    if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; +    if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; +      if (conn->parent) {          unsigned char mtype = ecp_pld_get_type(payload->buffer);          ssize_t rv, hdr_size = vconn_set_msg(conn->parent, packet, mtype); @@ -442,6 +445,9 @@ static ssize_t vconn_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char  static ssize_t vconn_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) {      ECPContext *ctx = sock->ctx; +    if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; +    if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; +      if (parent) {          unsigned char mtype = ecp_pld_get_type(payload->buffer);          ssize_t rv, hdr_size = vconn_set_msg(parent, packet, mtype); @@ -599,7 +605,7 @@ static ssize_t _vconn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {      payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);      ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ); -    return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), ti); +    return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);  }  int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn[], ECPNode vconn_node[], int size) { diff --git a/code/esp32/Makefile b/code/esp32/Makefile new file mode 100644 index 0000000..eb26385 --- /dev/null +++ b/code/esp32/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := eos-app + +include $(IDF_PATH)/make/project.mk + diff --git a/code/esp32/components/eos/component.mk b/code/esp32/components/eos/component.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/code/esp32/components/eos/component.mk diff --git a/code/esp32/components/eos/fe310.c b/code/esp32/components/eos/fe310.c new file mode 100644 index 0000000..6dceb51 --- /dev/null +++ b/code/esp32/components/eos/fe310.c @@ -0,0 +1,180 @@ +#include <stdio.h> +#include <stdint.h> +#include <stddef.h> +#include <string.h> + +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> +#include <freertos/semphr.h> +// #include <freertos/heap_regions.h> + +#include <esp_system.h> +#include <esp_event.h> +#include <esp_event_loop.h> +#include <esp_log.h> +#include <esp_err.h> +#include <esp_heap_caps.h> +#include <driver/spi_slave.h> + +#include "msgq.h" +#include "transport.h" +#include "fe310.h" + +static EOSMsgQ send_q; +static EOSMsgItem send_q_array[EOS_FE310_SIZE_Q]; + +#define SPI_GPIO_RTS        4 +#define SPI_GPIO_CTS        2 +#define SPI_GPIO_MOSI       23 +#define SPI_GPIO_MISO       19 +#define SPI_GPIO_SCLK       18 +#define SPI_GPIO_CS         5 + +static SemaphoreHandle_t mutex; + +static const char *TAG = "EOS"; + +static eos_fe310_fptr_t cmd_handler[EOS_FE310_MAX_CMD]; + +static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    ESP_LOGI(TAG, "FE310 RECV: bad handler: %d", cmd); +} + +static void worker(void *pvParameters) { +    int repeat = 0; +    esp_err_t ret; +    unsigned char cmd = 0; +    unsigned char *buffer; +    uint16_t len; +    unsigned char *buf_send = heap_caps_malloc(EOS_FE310_SIZE_BUF, MALLOC_CAP_DMA); +    unsigned char *buf_recv = heap_caps_malloc(EOS_FE310_SIZE_BUF, MALLOC_CAP_DMA); + +    spi_slave_transaction_t t; +    memset(&t, 0, sizeof(t)); +    t.length = EOS_FE310_SIZE_BUF*8; +    t.tx_buffer = buf_send; +    t.rx_buffer = buf_recv; +     +    xSemaphoreTake(mutex, portMAX_DELAY); +    for (;;) { +        if (!repeat) { +            eos_msgq_pop(&send_q, &cmd, &buffer, &len); +            if (cmd) { +                buf_send[0] = ((cmd << 3) | (len >> 8)) & 0xFF; +                buf_send[1] = len & 0xFF; +                if (buffer) memcpy(buf_send + 2, buffer, len); +            } else { +                WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_RTS)); +                buf_send[0] = 0; +                buf_send[1] = 0; +            } +        } +        memset(buf_recv, 0, EOS_FE310_SIZE_BUF); +        ret = spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY); + +        repeat = 0; +        if (buf_recv[0] != 0) { +            xSemaphoreGive(mutex); +             +            cmd = (buf_recv[0] >> 3); +            len = ((buf_recv[0] & 0x07) << 8); +            len |= buf_recv[1]; +            buffer = buf_recv + 2; +            if (cmd & EOS_FE310_CMD_FLAG_ONEW) { +                cmd &= ~EOS_FE310_CMD_FLAG_ONEW; +                if (buf_send[0]) repeat = 1; +            } +            if (cmd < EOS_FE310_MAX_CMD) { +                cmd_handler[cmd](cmd, buffer, len); +            } else { +                bad_handler(cmd, buffer, len); +            } + +            xSemaphoreTake(mutex, portMAX_DELAY); +        } else { +            ESP_LOGI(TAG, "FE310 RECV NULL"); +        } +        // vTaskDelay(5000 / portTICK_PERIOD_MS); +    } +    xSemaphoreGive(mutex); +} + +// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. +static void _post_setup_cb(spi_slave_transaction_t *trans) { +    xSemaphoreGive(mutex); +    WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1 << SPI_GPIO_CTS)); +} + +// Called after transaction is sent/received. We use this to set the handshake line low. +static void _post_trans_cb(spi_slave_transaction_t *trans) { +    xSemaphoreTake(mutex, portMAX_DELAY); +    WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_CTS)); +} + +void eos_fe310_init(void) { +    esp_err_t ret; +     +    // Configuration for the handshake lines +    gpio_config_t io_conf; +     +    io_conf.intr_type = GPIO_INTR_DISABLE; +    io_conf.mode = GPIO_MODE_OUTPUT; +    io_conf.pin_bit_mask = (1 << SPI_GPIO_CTS); +    gpio_config(&io_conf); +    WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_CTS)); + +    io_conf.intr_type = GPIO_INTR_DISABLE; +    io_conf.mode = GPIO_MODE_OUTPUT; +    io_conf.pin_bit_mask = (1 << SPI_GPIO_RTS); +    gpio_config(&io_conf); +    WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_RTS)); + +    //Configuration for the SPI bus +    spi_bus_config_t buscfg = { +        .mosi_io_num = SPI_GPIO_MOSI, +        .miso_io_num = SPI_GPIO_MISO, +        .sclk_io_num = SPI_GPIO_SCLK +    }; + +    //Configuration for the SPI slave interface +    spi_slave_interface_config_t slvcfg = { +        .mode = 0, +        .spics_io_num = SPI_GPIO_CS, +        .queue_size = 2, +        .flags = 0, +        .post_setup_cb = _post_setup_cb, +        .post_trans_cb = _post_trans_cb +    }; + +    //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected. +    gpio_set_pull_mode(SPI_GPIO_MOSI, GPIO_PULLUP_ONLY); +    gpio_set_pull_mode(SPI_GPIO_SCLK, GPIO_PULLUP_ONLY); +    gpio_set_pull_mode(SPI_GPIO_CS, GPIO_PULLUP_ONLY); + +    int i; +    for (i=0; i<EOS_FE310_MAX_CMD; i++) { +        cmd_handler[i] = bad_handler; +    } +     +    //Initialize SPI slave interface +    ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1); +    assert(ret==ESP_OK); + +    eos_msgq_init(&send_q, send_q_array, EOS_FE310_SIZE_Q); +    mutex = xSemaphoreCreateMutex(); +    xTaskCreate(&worker, "fe310_receiver", 4096, NULL, 5, NULL); +} + +int eos_fe310_send(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    xSemaphoreTake(mutex, portMAX_DELAY); +    WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1 << SPI_GPIO_RTS)); +    int rv = eos_msgq_push(&send_q, cmd, buffer, len); +    xSemaphoreGive(mutex); +     +    return rv; +} + +void eos_fe310_set_handler(unsigned char cmd, eos_fe310_fptr_t handler) { +    cmd_handler[cmd] = handler; +} + diff --git a/code/esp32/components/eos/include/eos.h b/code/esp32/components/eos/include/eos.h new file mode 100644 index 0000000..a272ac8 --- /dev/null +++ b/code/esp32/components/eos/include/eos.h @@ -0,0 +1,2 @@ +#define EOS_OK          0 +#define EOS_ERR_Q_FULL  -10
\ No newline at end of file diff --git a/code/esp32/components/eos/include/fe310.h b/code/esp32/components/eos/include/fe310.h new file mode 100644 index 0000000..f4bc787 --- /dev/null +++ b/code/esp32/components/eos/include/fe310.h @@ -0,0 +1,18 @@ +#include <stdint.h> + +#define EOS_FE310_CMD_FLAG_ONEW     0x10 + +#define EOS_FE310_CMD_CONNECT       1 +#define EOS_FE310_CMD_DISCONNECT    2 +#define EOS_FE310_CMD_SCAN          3 +#define EOS_FE310_CMD_PKT           4 + +#define EOS_FE310_MAX_CMD           8 +#define EOS_FE310_SIZE_Q            64 +#define EOS_FE310_SIZE_BUF          2048 + +typedef void (*eos_fe310_fptr_t) (unsigned char, unsigned char *, uint16_t); + +void eos_fe310_init(void); +int eos_fe310_send(unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_fe310_set_handler(unsigned char cmd, eos_fe310_fptr_t handler); diff --git a/code/esp32/components/eos/include/msgq.h b/code/esp32/components/eos/include/msgq.h new file mode 100644 index 0000000..ebf54ce --- /dev/null +++ b/code/esp32/components/eos/include/msgq.h @@ -0,0 +1,20 @@ +#include <stdint.h> + +#include "fe310.h" + +typedef struct EOSMsgItem { +    unsigned char cmd; +    unsigned char buffer[EOS_FE310_SIZE_BUF]; +    uint16_t len; +} EOSMsgItem; + +typedef struct EOSMsgQ { +    uint8_t idx_r; +    uint8_t idx_w; +    uint8_t size; +    EOSMsgItem *array; +} EOSMsgQ; + +void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); +int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len); diff --git a/code/esp32/components/eos/include/transport.h b/code/esp32/components/eos/include/transport.h new file mode 100644 index 0000000..9d76d1b --- /dev/null +++ b/code/esp32/components/eos/include/transport.h @@ -0,0 +1,13 @@ +#include <stdint.h> + +#define EOS_IPv4_ADDR_SIZE          4 + +typedef struct EOSNetAddr { +    unsigned char host[EOS_IPv4_ADDR_SIZE]; +    uint16_t port; +} EOSNetAddr; + +void eos_net_init(void); +void eos_net_connect(char *ssid, char *password); +void eos_net_disconnect(void); +ssize_t eos_net_send(void *msg, size_t msg_size, EOSNetAddr *addr); diff --git a/code/esp32/components/eos/msgq.c b/code/esp32/components/eos/msgq.c new file mode 100644 index 0000000..ec89efe --- /dev/null +++ b/code/esp32/components/eos/msgq.c @@ -0,0 +1,39 @@ +#include <stddef.h> +#include <string.h> + +#include "eos.h" +#include "msgq.h" + +#define EOS_MSGQ_IDX_MASK(IDX, SIZE)  ((IDX) & ((SIZE) - 1)) + +void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { +    msgq->idx_r = 0; +    msgq->idx_w = 0; +    msgq->array = array; +    msgq->size = size; +} + +int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len) { +    if (msgq->idx_w - msgq->idx_r == msgq->size) return EOS_ERR_Q_FULL; + +    uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_w, msgq->size); +    msgq->array[idx].cmd = cmd; +    memcpy(msgq->array[idx].buffer, buffer, len); +    msgq->array[idx].len = len; +    msgq->idx_w++; +    return EOS_OK; +} + +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len) { +    if (msgq->idx_r == msgq->idx_w) { +        *cmd = 0; +        *buffer = NULL; +    } else { +        uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size); +        *cmd = msgq->array[idx].cmd; +        *buffer = msgq->array[idx].buffer; +        *len = msgq->array[idx].len; +        msgq->idx_r++; +    } +} + diff --git a/code/esp32/components/eos/transport.c b/code/esp32/components/eos/transport.c new file mode 100755 index 0000000..162fe86 --- /dev/null +++ b/code/esp32/components/eos/transport.c @@ -0,0 +1,205 @@ +/* +MIT License + +Copyright (c) 2017 Olof Astrand (Ebiroll) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include <string.h> +#include <stdint.h> + +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> + +#include <esp_system.h> +#include <esp_event.h> +#include <esp_event_loop.h> +#include <esp_log.h> +#include <esp_err.h> +#include <esp_wifi.h> +#include <nvs_flash.h> + +#include <lwip/sockets.h> +#include <lwip/err.h> +#include <lwip/sockets.h> +#include <lwip/sys.h> +#include <lwip/netdb.h> +#include <lwip/dns.h> + +#include "eos.h" +#include "fe310.h" +#include "transport.h" + +static const char *TAG = "EOS"; +static int udp_sock = -1; +static TaskHandle_t receiver_task; + +static int t_open(void) { +    struct sockaddr_in _myaddr; + +    udp_sock = socket(PF_INET, SOCK_DGRAM, 0); +    if (udp_sock < 0) return udp_sock; +     +    memset((char *)&_myaddr, 0, sizeof(_myaddr)); +    _myaddr.sin_family = AF_INET; +    _myaddr.sin_addr.s_addr = htonl(INADDR_ANY); +    _myaddr.sin_port = htons(0); + +    int rv = bind(udp_sock, (struct sockaddr *)&_myaddr, sizeof(_myaddr)); +    if (rv < 0) { +        close(udp_sock); +        return rv; +    } +    return EOS_OK; +} + +static void t_close(void) { +    close(udp_sock); +} + +static ssize_t t_send(void *msg, size_t msg_size, EOSNetAddr *addr) { +    struct sockaddr_in servaddr; + +    memset((void *)&servaddr, 0, sizeof(servaddr)); +    servaddr.sin_family = AF_INET; +    servaddr.sin_port = addr->port; +    memcpy((void *)&servaddr.sin_addr, addr->host, sizeof(addr->host)); +    return sendto(udp_sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); +} + +static ssize_t t_recv(void *msg, size_t msg_size, EOSNetAddr *addr) { +    struct sockaddr_in servaddr; +    socklen_t addrlen = sizeof(servaddr); +    memset((void *)&servaddr, 0, sizeof(servaddr)); + +    ssize_t recvlen = recvfrom(udp_sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, &addrlen); +    if (recvlen < 0) return recvlen; + +    if (addr) { +        addr->port = servaddr.sin_port; +        memcpy(addr->host, (void *)&servaddr.sin_addr, sizeof(addr->host)); +    } +    return recvlen; +} + +static void receiver(void *pvParameters) { +    EOSNetAddr addr; +    size_t addr_len = sizeof(addr.host) + sizeof(addr.port); +    unsigned char buffer[2048]; +     +    for (;;) { +        ssize_t rv = t_recv(buffer+addr_len, sizeof(buffer)-addr_len, &addr); +        if (rv < 0) { +            ESP_LOGI(TAG, "UDP RECV ERR:%d", rv); +            continue; +        } +        memcpy(buffer, addr.host, sizeof(addr.host)); +        memcpy(buffer+sizeof(addr.host), &addr.port, sizeof(addr.port)); +        eos_fe310_send(EOS_FE310_CMD_PKT, buffer, rv+addr_len); +    } +} + +static void fe310_connect_cmd_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) { +    eos_net_connect((char *)buffer, (char *)(buffer+strlen((char *)buffer)+1)); +} + +static void fe310_packet_cmd_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) { +    EOSNetAddr addr; +    size_t addr_len = sizeof(addr.host) + sizeof(addr.port); +     +    memcpy(addr.host, buffer, sizeof(addr.host)); +    memcpy(&addr.port, buffer+sizeof(addr.host), sizeof(addr.port)); +    eos_net_send(buffer+addr_len, size-addr_len, &addr); +} + +static esp_err_t esp32_wifi_event_handler(void *ctx, system_event_t *event) { +    switch(event->event_id) { +        case SYSTEM_EVENT_WIFI_READY: +            break; + +        case SYSTEM_EVENT_AP_STACONNECTED: +            break; + +        case SYSTEM_EVENT_AP_START:  +            break; + +        case SYSTEM_EVENT_SCAN_DONE: +            break; + +        case SYSTEM_EVENT_STA_CONNECTED:  +            break; + +        case SYSTEM_EVENT_STA_DISCONNECTED: +            ESP_LOGI(TAG, "DISCONNECT"); +            vTaskDelete(receiver_task); +            t_close(); +            break; + +        case SYSTEM_EVENT_STA_GOT_IP: +            ESP_LOGI(TAG, "********************************************"); +            ESP_LOGI(TAG, "* We are now connected to AP") +            ESP_LOGI(TAG, "* - Our IP address is: " IPSTR, IP2STR(&event->event_info.got_ip.ip_info.ip)); +            ESP_LOGI(TAG, "********************************************"); +            t_open(); +            xTaskCreate(&receiver, "receiver", 4096, NULL, 5, &receiver_task); +            eos_fe310_send(EOS_FE310_CMD_CONNECT, NULL, 0); +            break; + +        default: // Ignore the other event types +            break; +    } + +    return ESP_OK; +} + +void eos_net_init(void) { +    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); +    wifi_config_t wifi_config; + +    memset(&wifi_config, 0, sizeof(wifi_config)); +    tcpip_adapter_init(); +    ESP_ERROR_CHECK( nvs_flash_init() ); +    ESP_ERROR_CHECK( esp_event_loop_init(esp32_wifi_event_handler, NULL) ); +    ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); +    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); +    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); +    ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); +    ESP_ERROR_CHECK( esp_wifi_start() ); +    eos_fe310_set_handler(EOS_FE310_CMD_CONNECT, fe310_connect_cmd_handler); +    eos_fe310_set_handler(EOS_FE310_CMD_PKT, fe310_packet_cmd_handler); +} + +void eos_net_connect(char *ssid, char *password) { +    wifi_config_t wifi_config; +     +    memset(&wifi_config, 0, sizeof(wifi_config)); +    strncpy((char *)wifi_config.sta.ssid, ssid, 31); +    strncpy((char *)wifi_config.sta.password, password, 63); +    ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); +    ESP_ERROR_CHECK( esp_wifi_connect() ); +} + +void eos_net_disconnect(void) { +    ESP_ERROR_CHECK( esp_wifi_disconnect() ); +} + +ssize_t eos_net_send(void *msg, size_t msg_size, EOSNetAddr *addr) { +    return t_send(msg, msg_size, addr); +} diff --git a/code/esp32/main/app_main.c b/code/esp32/main/app_main.c new file mode 100644 index 0000000..1d3fa34 --- /dev/null +++ b/code/esp32/main/app_main.c @@ -0,0 +1,26 @@ +#include <stdio.h> +#include <stdint.h> +#include <stddef.h> +#include <string.h> + +#include <freertos/FreeRTOS.h> +#include <freertos/task.h> +#include <freertos/semphr.h> + +#include <esp_system.h> +#include <esp_event.h> +#include <esp_event_loop.h> +#include <esp_log.h> +#include <esp_err.h> +#include <driver/spi_slave.h> + +#include "fe310.h" +#include "transport.h" + +// Main application +void app_main() { +    eos_fe310_init(); +    eos_net_init(); +} + + diff --git a/code/esp32/main/component.mk b/code/esp32/main/component.mk new file mode 100644 index 0000000..61f8990 --- /dev/null +++ b/code/esp32/main/component.mk @@ -0,0 +1,8 @@ +# +# Main component makefile. +# +# This Makefile can be left empty. By default, it will take the sources in the  +# src/ directory, compile them and link them into lib(subdirectory_name).a  +# in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile new file mode 100644 index 0000000..573bca7 --- /dev/null +++ b/code/fe310/eos/Makefile @@ -0,0 +1,18 @@ +FE310_HOME=/opt/my/freedom-e-sdk + +CC=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc +AR=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar + +CFLAGS=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../.. + +obj = msgq.o event.o interrupt.o timer.o net.o eos.o ecp.o + + +%.o: %.c %.h +	$(CC) $(CFLAGS) -c $< + +all: $(obj) +	$(AR) rcs libeos.a $(obj) + +clean: +	rm -f *.o *.a
\ No newline at end of file diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c new file mode 100644 index 0000000..433e693 --- /dev/null +++ b/code/fe310/eos/ecp.c @@ -0,0 +1,66 @@ +#include <stddef.h> +#include <string.h> + +#include "encoding.h" +#include "platform.h" + +#include "event.h" +#include "timer.h" +#include "net.h" + +#include "ecp.h" + +static ECPSocket *_sock = NULL; + +static unsigned char net_buf_reserved = 0; +static void timer_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    int ok = eos_net_acquire(net_buf_reserved); +    if (ok) { +        ecp_cts_t next = ecp_timer_exe(_sock); +        if (next) { +            uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; +            eos_timer_set(tick, 1); +        } +        eos_net_release(1); +        net_buf_reserved = 0; +    } else { +        net_buf_reserved = 1; +        eos_evtq_push(EOS_EVT_TIMER, NULL, 0); +    } +} + +static void packet_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    ECPNetAddr addr; +    size_t addr_len = sizeof(addr.host) + sizeof(addr.port); +     +    ECP2Buffer bufs; +    ECPBuffer packet; +    ECPBuffer payload; +    unsigned char pld_buf[ECP_MAX_PLD]; +     +    bufs.packet = &packet; +    bufs.payload = &payload; + +    packet.buffer = buffer+addr_len; +    packet.size = ECP_MAX_PKT; +    payload.buffer = pld_buf; +    payload.size = ECP_MAX_PLD; + +    memcpy(addr.host, buffer, sizeof(addr.host)); +    memcpy(&addr.port, buffer+sizeof(addr.host), sizeof(addr.port)); +    ssize_t rv = ecp_pkt_handle(_sock, &addr, NULL, &bufs, len-addr_len); +    if (bufs.packet->buffer) eos_net_free(buffer, 0); +    eos_net_release(0); +} + +int ecp_init(ECPContext *ctx) { +    int rv; +     +    rv = ecp_ctx_create(ctx); +    if (rv) return rv; +     +    eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler); +    eos_evtq_set_handler(EOS_EVT_MASK_NET | EOS_NET_CMD_PKT, packet_handler); + +    return ECP_OK; +}
\ No newline at end of file diff --git a/code/fe310/eos/ecp.h b/code/fe310/eos/ecp.h new file mode 100644 index 0000000..95aed31 --- /dev/null +++ b/code/fe310/eos/ecp.h @@ -0,0 +1,3 @@ +#include <ecp/core.h> + +int ecp_init(ECPContext *ctx);
\ No newline at end of file diff --git a/code/fe310/eos/eos.c b/code/fe310/eos/eos.c new file mode 100644 index 0000000..3ad3b68 --- /dev/null +++ b/code/fe310/eos/eos.c @@ -0,0 +1,17 @@ +#include "event.h" +#include "interrupt.h" +#include "timer.h" +#include "net.h" + +#include "eos.h" + +void eos_init(void) { +    eos_evtq_init(); +    eos_intr_init(); +    eos_timer_init(); +    eos_net_init(); +} + +void eos_start(void) { +    eos_net_start(15); +}
\ No newline at end of file diff --git a/code/fe310/eos/eos.h b/code/fe310/eos/eos.h new file mode 100644 index 0000000..938030e --- /dev/null +++ b/code/fe310/eos/eos.h @@ -0,0 +1,6 @@ +#define EOS_OK                  0 +#define EOS_ERR_Q_FULL          -10 + +void eos_init(void); +void eos_start(void); + diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c new file mode 100644 index 0000000..25f1fa1 --- /dev/null +++ b/code/fe310/eos/event.c @@ -0,0 +1,85 @@ +#include <stdio.h> + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "msgq.h" +#include "net.h" +#include "timer.h" +#include "event.h" + +static EOSMsgQ event_q; +static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q]; + +static eos_evt_fptr_t evt_net_handler[EOS_NET_MAX_CMD]; +static eos_evt_fptr_t evt_timer_handler = NULL; +static eos_evt_fptr_t evt_ui_handler = NULL; + +static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    printf("bad handler: %d\n", cmd); +} + +void eos_evtq_init(void) { +    int i; +     +    for (i=0; i<EOS_NET_MAX_CMD; i++) { +        evt_net_handler[i] = bad_handler; +    } +    evt_timer_handler = bad_handler; +    evt_ui_handler = bad_handler; +    eos_msgq_init(&event_q, event_q_array, EOS_EVT_SIZE_Q); +} + +int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    return eos_msgq_push(&event_q, cmd, buffer, len); +} + +void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len) { +    eos_msgq_pop(&event_q, cmd, buffer, len); +} + +void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    if (cmd & EOS_EVT_MASK_NET) { +        cmd &= ~EOS_EVT_MASK_NET; +        if (cmd < EOS_NET_MAX_CMD) { +            evt_net_handler[cmd](cmd, buffer, len); +        } else { +            bad_handler(cmd, buffer, len); +        } +    } else if (cmd == EOS_EVT_TIMER) { +        evt_timer_handler(cmd, buffer, len); +    } else if (cmd == EOS_EVT_UI) { +        evt_ui_handler(cmd, buffer, len); +    } +} + +void eos_evtq_loop(void) { +    unsigned char cmd; +    unsigned char *buffer; +    uint16_t len; +    volatile int foo = 1; + +    while(foo) { +        clear_csr(mstatus, MSTATUS_MIE); +        eos_evtq_pop(&cmd, &buffer, &len); +        if (cmd) { +            set_csr(mstatus, MSTATUS_MIE); +            eos_evtq_handle(cmd, buffer, len); +            clear_csr(mstatus, MSTATUS_MIE); +        } else { +            // asm volatile ("wfi"); +        } +        set_csr(mstatus, MSTATUS_MIE); +    } +} + +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler) { +    if (cmd & EOS_EVT_MASK_NET) { +        evt_net_handler[cmd & ~EOS_EVT_MASK_NET] = handler; +    } else if (cmd == EOS_EVT_TIMER) { +        evt_timer_handler = handler; +    } else if (cmd == EOS_EVT_UI) { +        evt_ui_handler = handler; +    } +}
\ No newline at end of file diff --git a/code/fe310/eos/event.h b/code/fe310/eos/event.h new file mode 100644 index 0000000..21079b4 --- /dev/null +++ b/code/fe310/eos/event.h @@ -0,0 +1,16 @@ +#include <stdint.h> + +#define EOS_EVT_MASK_NET    0x80 +#define EOS_EVT_TIMER       0x01 +#define EOS_EVT_UI          0x02 + +#define EOS_EVT_SIZE_Q      4 + +typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t); + +void eos_evtq_init(void); +int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len); +void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_evtq_loop(void); +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler);
\ No newline at end of file diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c new file mode 100644 index 0000000..def1a24 --- /dev/null +++ b/code/fe310/eos/interrupt.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> + +#include "encoding.h" +#include "platform.h" +#include "plic/plic_driver.h" +#include "interrupt.h" + +// Global Instance data for the PLIC +// for use by the PLIC Driver. +static plic_instance_t plic; + +static eos_intr_fptr_t ext_interrupt_handler[PLIC_NUM_INTERRUPTS]; + +void handle_m_ext_interrupt(void) { +    plic_source int_num  = PLIC_claim_interrupt(&plic); +    if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num])) { +        ext_interrupt_handler[int_num](); +    } else { +        printf("handle_m_ext_interrupt error\n\n"); +        exit(1 + (uintptr_t) int_num); +    } +    PLIC_complete_interrupt(&plic, int_num); +} + +void eos_intr_init(void) { +    for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){ +        ext_interrupt_handler[i] = NULL; +    } + +    /************************************************************************** +    * Set up the PLIC +    **************************************************************************/ +    PLIC_init(&plic, + 	    PLIC_CTRL_ADDR, + 	    PLIC_NUM_INTERRUPTS, + 	    PLIC_NUM_PRIORITIES); + +    // Enable Global (PLIC) interrupts. +    set_csr(mie, MIP_MEIP); + +    // Enable all interrupts +    set_csr(mstatus, MSTATUS_MIE); +} + +void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) { +    ext_interrupt_handler[int_num] = handler; +    PLIC_enable_interrupt(&plic, int_num); +    PLIC_set_priority(&plic, int_num, priority); +} diff --git a/code/fe310/eos/interrupt.h b/code/fe310/eos/interrupt.h new file mode 100644 index 0000000..7ef81b8 --- /dev/null +++ b/code/fe310/eos/interrupt.h @@ -0,0 +1,8 @@ +#include <stdint.h> + +// Structures for registering different interrupt handlers +// for different parts of the application. +typedef void (*eos_intr_fptr_t) (void); + +void eos_intr_init(void); +void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler); diff --git a/code/fe310/eos/msgq.c b/code/fe310/eos/msgq.c new file mode 100644 index 0000000..d242c69 --- /dev/null +++ b/code/fe310/eos/msgq.c @@ -0,0 +1,66 @@ +#include <stddef.h> + +#include "eos.h" +#include "msgq.h" + +#define EOS_MSGQ_IDX_MASK(IDX, SIZE)  ((IDX) & ((SIZE) - 1)) + +void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { +    msgq->idx_r = 0; +    msgq->idx_w = 0; +    msgq->array = array; +    msgq->size = size; +} + +int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len) { +    if (msgq->idx_w - msgq->idx_r == msgq->size) return EOS_ERR_Q_FULL; + +    uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_w, msgq->size); +    msgq->array[idx].cmd = cmd; +    msgq->array[idx].buffer = buffer; +    msgq->array[idx].len = len; +    msgq->idx_w++; +    return EOS_OK; +} + +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len) { +    if (msgq->idx_r == msgq->idx_w) { +        *cmd = 0; +        *buffer = NULL; +    } else { +        uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size); +        *cmd = msgq->array[idx].cmd; +        *buffer = msgq->array[idx].buffer; +        *len = msgq->array[idx].len; +        msgq->idx_r++; +    } +} + +void eos_msgq_get(EOSMsgQ *msgq, unsigned char cmd, unsigned char **buffer, uint16_t *len) { +    uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size); +    unsigned char _cmd = msgq->array[idx].cmd; +    EOSMsgItem *tmp_item = &msgq->array[idx]; +     +    *buffer = msgq->array[idx].buffer; +    *len = msgq->array[idx].len; +    if (_cmd == cmd) { +        msgq->idx_r++; +        return; +    } +    for (idx = msgq->idx_r + 1; idx < msgq->idx_w; idx++) { +        *tmp_item = msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)]; +        msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].cmd = _cmd; +        msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].buffer = *buffer; +        msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].len = *len; +        _cmd = tmp_item->cmd; +        *buffer = tmp_item->buffer; +        *len = tmp_item->len; +        if (_cmd == cmd) { +            msgq->idx_r++; +            return; +        } +    } +    *buffer = NULL; +    *len = 0; +} + diff --git a/code/fe310/eos/msgq.h b/code/fe310/eos/msgq.h new file mode 100644 index 0000000..05a5d80 --- /dev/null +++ b/code/fe310/eos/msgq.h @@ -0,0 +1,19 @@ +#include <stdint.h> + +typedef struct EOSMsgItem { +    unsigned char cmd; +    unsigned char *buffer; +    uint16_t len; +} EOSMsgItem; + +typedef struct EOSMsgQ { +    uint8_t idx_r; +    uint8_t idx_w; +    uint8_t size; +    EOSMsgItem *array; +} EOSMsgQ; + +void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); +int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len); +void eos_msgq_get(EOSMsgQ *msgq, unsigned char cmd, unsigned char **buffer, uint16_t *len);
\ No newline at end of file diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c new file mode 100644 index 0000000..080da72 --- /dev/null +++ b/code/fe310/eos/net.c @@ -0,0 +1,365 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> + +#include "encoding.h" +#include "platform.h" +#include "plic/plic_driver.h" + +#include "eos.h" +#include "msgq.h" +#include "event.h" +#include "interrupt.h" +#include "net.h" +#include "spi.h" + +#define MIN(X, Y)               (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y)               (((X) > (Y)) ? (X) : (Y)) +#define SPI_BUFQ_IDX_MASK(IDX)  ((IDX) & (SPI_SIZE_BUFQ - 1)) + +static volatile uint8_t spi_res = 0; +static volatile uint8_t spi_res_next = 0; +static volatile unsigned char *spi_res_buf = NULL; + +static EOSMsgQ spi_sndq; +static EOSMsgItem spi_sndq_array[SPI_SIZE_BUFQ]; + +static SPIBufQ spi_bufq; +static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF]; + +static int spi_bufq_push(unsigned char *buffer) { +    spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer; +} + +static unsigned char *spi_bufq_pop(void) { +    if (spi_bufq.idx_r == spi_bufq.idx_w) return NULL; +    return spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_r++)]; +} + +static volatile uint8_t spi_rdy = 0; +static volatile uint8_t spi_cts = 0; +static volatile uint8_t spi_rts = 0; +static SPIBuffer spi_buffer; + +static void spi_reset(void) { +    int i; +    volatile uint32_t r; + +    spi_cts = 0; +    // before starting a transaction, set SPI peripheral to desired mode +    SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; + +    while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); +    SPI1_REG(SPI_REG_TXFIFO) = 0; +    while ((r = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + +    SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; +} + +static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    volatile uint32_t r1, r2; + +    spi_cts = 0; +    spi_buffer.buffer = buffer; +    spi_buffer.len_rx = 0; +    spi_buffer.idx_tx = 0; +    spi_buffer.idx_rx = 0; +     +    if (spi_res_buf == NULL) { +        if (cmd & EOS_NET_CMD_FLAG_ONEW) { +            spi_res_next = 1; +        } else if (spi_res) { +            cmd |= EOS_NET_CMD_FLAG_ONEW; +        } +    } else if (cmd & EOS_NET_CMD_FLAG_ONEW) { +        cmd &= ~EOS_NET_CMD_FLAG_ONEW; +    } + +    // before starting a transaction, set SPI peripheral to desired mode +    SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; + +    while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); +    SPI1_REG(SPI_REG_TXFIFO) = ((cmd << 3) | (len >> 8)) & 0xFF; + +    while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); +    SPI1_REG(SPI_REG_TXFIFO) = len & 0xFF; + +    while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); +    while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); +     +    if (cmd & EOS_NET_CMD_FLAG_ONEW) { +        r1 = 0; +        r2 = 0; +    } + +    spi_buffer.cmd = ((r1 & 0xFF) >> 3); +    spi_buffer.len_rx = ((r1 & 0x07) << 8); + +    spi_buffer.len_rx |= (r2 & 0xFF); +    spi_buffer.len = MAX(len, spi_buffer.len_rx); + +    // Work around esp32 bug +    if (spi_buffer.len < 6) { +        spi_buffer.len = 6; +    } else if ((spi_buffer.len + 2) % 4 != 0) { +        spi_buffer.len = ((spi_buffer.len + 2)/4 + 1) * 4 - 2; +    } + +    SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_CHUNK/2); +    SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(SPI_SIZE_CHUNK - 1); +    SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM | SPI_IP_RXWM; +} + +static int spi_xchg_next(unsigned char *_buffer) { +    unsigned char cmd; +    unsigned char *buffer = NULL; +    uint16_t len; + +    eos_msgq_pop(&spi_sndq, &cmd, &buffer, &len); +    if (cmd) { +        spi_xchg(cmd, buffer, len); +    } else if (spi_rts) { +        if (_buffer == NULL) _buffer = spi_bufq_pop(); +        if (_buffer) { +            spi_xchg(0, _buffer, 0); +            return 0; +        } +    } +    return 1; +} + +static void spi_xchg_handler(void) { +    int i; +     +    if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) { +        uint16_t sz_chunk = MIN(spi_buffer.len - spi_buffer.idx_tx, SPI_SIZE_CHUNK); +        for (i=0; i<sz_chunk; i++) { +            if (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL) break; +            SPI1_REG(SPI_REG_TXFIFO) = spi_buffer.buffer[spi_buffer.idx_tx+i]; +        } +        spi_buffer.idx_tx += i; +    } +     +    for (i=0; i<spi_buffer.idx_tx - spi_buffer.idx_rx; i++) { +        volatile uint32_t x = SPI1_REG(SPI_REG_RXFIFO); +        if (x & SPI_RXFIFO_EMPTY) break; +        spi_buffer.buffer[spi_buffer.idx_rx+i] = x & 0xFF; +    } +    spi_buffer.idx_rx += i; + +    if (spi_buffer.idx_rx == spi_buffer.len) { +        SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; +        SPI1_REG(SPI_REG_IE) = 0x0; +        if (spi_buffer.cmd) { +            int r = eos_evtq_push(spi_buffer.cmd | EOS_EVT_MASK_NET, spi_buffer.buffer, spi_buffer.len_rx); +            if (r) spi_bufq_push(spi_buffer.buffer); +        } else if ((spi_res || spi_res_next) && (spi_res_buf == NULL)) { +            spi_res_buf = spi_buffer.buffer; +            spi_res_next = 0; +        } else { +            spi_bufq_push(spi_buffer.buffer); +        } +    } else if (spi_buffer.idx_tx == spi_buffer.len) { +        SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_buffer.len - spi_buffer.idx_rx - 1, SPI_SIZE_CHUNK - 1)); +        SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; +    } +} + +static void spi_cts_hanler(void) { +    GPIO_REG(GPIO_RISE_IP) = (0x1 << SPI_GPIO_CTS_OFFSET); +    spi_cts = 1; + +    if (spi_rdy) { +        spi_xchg_next(NULL); +    } else { +        uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2); +        GPIO_REG(GPIO_IOF_EN) &= ~iof_mask; +    } +} + +static void spi_rts_hanler(void) { +    uint32_t rts_offset = (0x1 << SPI_GPIO_RTS_OFFSET); +    if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { +        GPIO_REG(GPIO_RISE_IP) = rts_offset; +        spi_rts = 1; +        if (spi_rdy && spi_cts) spi_reset(); +    } +     +    if (GPIO_REG(GPIO_FALL_IP) & rts_offset) { +        GPIO_REG(GPIO_FALL_IP) = rts_offset; +        spi_rts = 0; +    } +} + +void eos_net_init(void) { +    int i; +     +    spi_bufq.idx_r = 0; +    spi_bufq.idx_w = 0; +    for (i=0; i<SPI_SIZE_BUFQ; i++) { +        spi_bufq_push(spi_bufq_array[i]); +    } +    eos_msgq_init(&spi_sndq, spi_sndq_array, SPI_SIZE_BUFQ); +    GPIO_REG(GPIO_IOF_SEL) &= ~SPI_IOF_MASK; +    GPIO_REG(GPIO_IOF_EN) |= SPI_IOF_MASK; +    eos_intr_set_handler(INT_SPI1_BASE, 5, spi_xchg_handler); + +    GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_GPIO_CTS_OFFSET); +    GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_GPIO_CTS_OFFSET); +    GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_GPIO_CTS_OFFSET); +    GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_GPIO_CTS_OFFSET); +    eos_intr_set_handler(INT_GPIO_BASE + SPI_GPIO_CTS_OFFSET, 5, spi_cts_hanler); + +    GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_GPIO_RTS_OFFSET); +    GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_GPIO_RTS_OFFSET); +    GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_GPIO_RTS_OFFSET); +    GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_GPIO_RTS_OFFSET); +    GPIO_REG(GPIO_FALL_IE) |= (0x1 << SPI_GPIO_RTS_OFFSET); +    eos_intr_set_handler(INT_GPIO_BASE + SPI_GPIO_RTS_OFFSET, 5, spi_rts_hanler); +} + +void eos_net_start(uint32_t sckdiv) { +    uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2); + +    GPIO_REG(GPIO_IOF_SEL) &= ~iof_mask; +    GPIO_REG(GPIO_IOF_EN) |= iof_mask; + +    SPI1_REG(SPI_REG_SCKDIV) = sckdiv; +    SPI1_REG(SPI_REG_SCKMODE) = SPI_MODE0; +    SPI1_REG(SPI_REG_FMT) = SPI_FMT_PROTO(SPI_PROTO_S) | +      SPI_FMT_ENDIAN(SPI_ENDIAN_MSB) | +      SPI_FMT_DIR(SPI_DIR_RX) | +      SPI_FMT_LEN(8); + +    // enable CS pin for selected channel/pin +    SPI1_REG(SPI_REG_CSID) = 2;  +     +    // There is no way here to change the CS polarity. +    // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF; +     +    clear_csr(mstatus, MSTATUS_MIE); +    spi_rdy = 1; +    if (spi_cts) spi_xchg_next(NULL); +    set_csr(mstatus, MSTATUS_MIE); +} + +void eos_net_stop(void) { +    volatile uint8_t done = 0; +     +    clear_csr(mstatus, MSTATUS_MIE); +    spi_rdy = 0; +    if (spi_cts) { +        uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2); +        GPIO_REG(GPIO_IOF_EN) &= ~iof_mask; +        done = 1; +    } +    set_csr(mstatus, MSTATUS_MIE); +     +    while (!done) { +        clear_csr(mstatus, MSTATUS_MIE); +        done = spi_cts; +        if (!done) asm volatile ("wfi"); +        set_csr(mstatus, MSTATUS_MIE); +    } +} + +int eos_net_reserve(unsigned char *buffer) { +    int rv = EOS_OK; + +    clear_csr(mstatus, MSTATUS_MIE); +    spi_res++; +    if (spi_res_buf == NULL) { +        spi_res_buf = buffer; +    } else { +        rv = spi_bufq_push(buffer); +    } +    set_csr(mstatus, MSTATUS_MIE); +     +    return rv; +} + +int eos_net_acquire(unsigned char reserved) { +    int ret = 0; +     +    if (reserved) { +        while (!ret) { +            clear_csr(mstatus, MSTATUS_MIE); +            if (spi_res_buf) { +                ret = 1; +            } else { +                asm volatile ("wfi"); +            } +            set_csr(mstatus, MSTATUS_MIE); +        } +    } else { +        clear_csr(mstatus, MSTATUS_MIE); +        spi_res++; +        spi_res_buf = spi_bufq_pop(); +        ret = (spi_res_buf != NULL); +        set_csr(mstatus, MSTATUS_MIE); +    } +    return ret; +} + +int eos_net_release(unsigned char reserved) { +    int rv = EOS_OK; + +    clear_csr(mstatus, MSTATUS_MIE); +    if (reserved) spi_res--; +    if (!spi_res && spi_res_buf) { +        rv = spi_bufq_push((unsigned char *)spi_res_buf); +        if (!rv) spi_res_buf = NULL; +    } +    set_csr(mstatus, MSTATUS_MIE); +     +    return rv; +} + +unsigned char *eos_net_alloc(void) { +    volatile unsigned char *ret = NULL; + +    while (ret == NULL) { +        clear_csr(mstatus, MSTATUS_MIE); +        if (spi_res_buf) { +            ret = spi_res_buf; +            spi_res_buf = NULL; +        } else { +            asm volatile ("wfi"); +        } +        set_csr(mstatus, MSTATUS_MIE); +    } +     +    return (unsigned char *)ret; +} + +int eos_net_free(unsigned char *buffer, unsigned char reserve_next) { +    int rv = EOS_OK; +    uint8_t do_release = 1; + +    clear_csr(mstatus, MSTATUS_MIE); +    if ((spi_res || reserve_next) && (spi_res_buf == NULL)) { +        spi_res_buf = buffer; +    } else { +        if (spi_rdy && spi_cts) do_release = spi_xchg_next(buffer); +        if (do_release) rv = spi_bufq_push(buffer); +    } +    set_csr(mstatus, MSTATUS_MIE); + +    return rv; +} + +int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    int rv = EOS_OK; + +    clear_csr(mstatus, MSTATUS_MIE); +    if (spi_rdy && spi_cts) { +        spi_xchg(cmd, buffer, len); +    } else { +        rv = eos_msgq_push(&spi_sndq, cmd, buffer, len); +    } +    set_csr(mstatus, MSTATUS_MIE); + +    return rv; +} diff --git a/code/fe310/eos/net.h b/code/fe310/eos/net.h new file mode 100644 index 0000000..0091c3c --- /dev/null +++ b/code/fe310/eos/net.h @@ -0,0 +1,20 @@ +#include <stdint.h> + +#define EOS_NET_CMD_FLAG_ONEW   0x10 + +#define EOS_NET_CMD_CONNECT     1 +#define EOS_NET_CMD_DISCONNECT  2 +#define EOS_NET_CMD_SCAN        3 +#define EOS_NET_CMD_PKT         4 + +#define EOS_NET_MAX_CMD         8 + +void eos_net_init(void); +void eos_net_start(uint32_t sckdiv); +void eos_net_stop(void); +int eos_net_reserve(unsigned char *buffer); +int eos_net_acquire(unsigned char reserved); +int eos_net_release(unsigned char reserved); +unsigned char *eos_net_alloc(void); +int eos_net_free(unsigned char *buffer, unsigned char reserve_next); +int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len); diff --git a/code/fe310/eos/spi.h b/code/fe310/eos/spi.h new file mode 100644 index 0000000..88e54bb --- /dev/null +++ b/code/fe310/eos/spi.h @@ -0,0 +1,32 @@ +#include <stdint.h> + +#include "encoding.h" +#include "platform.h" + +#define SPI_MODE0               0x00 +#define SPI_MODE1               0x01 +#define SPI_MODE2               0x02 +#define SPI_MODE3               0x03 + +#define SPI_SIZE_BUF            1500 +#define SPI_SIZE_CHUNK          4 +#define SPI_SIZE_BUFQ           4 +#define SPI_GPIO_CTS_OFFSET     PIN_2_OFFSET +#define SPI_GPIO_RTS_OFFSET     PIN_3_OFFSET +#define SPI_IOF_MASK            (((uint32_t)1 << IOF_SPI1_SCK) | ((uint32_t)1 << IOF_SPI1_MOSI) | ((uint32_t)1 << IOF_SPI1_MISO)) + +typedef struct SPIBuffer { +    unsigned char cmd; +    unsigned char *buffer; +    uint16_t len; +    uint16_t len_rx; +    uint16_t idx_tx; +    uint16_t idx_rx; +} SPIBuffer; + +typedef struct SPIBufQ { +    uint8_t idx_r; +    uint8_t idx_w; +    unsigned char *array[SPI_SIZE_BUFQ]; +} SPIBufQ; + diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c new file mode 100644 index 0000000..0a07ed9 --- /dev/null +++ b/code/fe310/eos/timer.c @@ -0,0 +1,86 @@ +#include <stddef.h> +#include <stdio.h> + +#include "encoding.h" +#include "platform.h" +#include "event.h" +#include "timer.h" + +#define MIN(X, Y)               (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y)               (((X) > (Y)) ? (X) : (Y)) + +static eos_timer_fptr_t timer_ext_handler = NULL; +volatile uint64_t timer_next = 0; +volatile uint64_t timer_next_evt = 0; + +void handle_m_time_interrupt(void) { +    volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); +    volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); +    uint64_t now = *mtime; + +    if (timer_next && (timer_next <= now)) { +        uint32_t next = timer_ext_handler(); +        if (next) { +            timer_next = now + next; +        } else { +            timer_next = 0; +        } +    } +    if (timer_next_evt && (timer_next_evt <= now)) { +        eos_evtq_push(EOS_EVT_TIMER, NULL, 0); +        timer_next_evt = 0; +    } +    *mtimecmp = (timer_next && timer_next_evt) ? MIN(timer_next, timer_next_evt) : (timer_next ? timer_next : timer_next_evt); +    if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); +} + +void eos_timer_init(void) { +    volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); +    *mtimecmp = 0; +    clear_csr(mie, MIP_MTIP); +} + +void eos_timer_set(uint32_t tick, unsigned char is_evt) { +    volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); +    volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + +    clear_csr(mstatus, MSTATUS_MIE); + +    uint64_t now = *mtime; +    uint64_t then = *mtimecmp; +    uint64_t next = now + tick; +    if (is_evt) { +        if ((timer_next_evt == 0) || (next < timer_next_evt)) timer_next_evt = next; +        next = timer_next ? MIN(timer_next, timer_next_evt) : timer_next_evt; +    } else if (timer_ext_handler) { +        if ((timer_next == 0) || (next < timer_next)) timer_next = next; +        next = timer_next_evt ? MIN(timer_next, timer_next_evt) : timer_next; +    } +    if ((then == 0) || (next < then)) *mtimecmp = next; +    if (then == 0) set_csr(mie, MIP_MTIP); + +    set_csr(mstatus, MSTATUS_MIE); +} + +void eos_timer_clear(unsigned char is_evt) { +    volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + +    clear_csr(mstatus, MSTATUS_MIE); + +    if (is_evt) { +        timer_next_evt = 0; +        *mtimecmp = timer_next; +    } else { +        timer_next = 0; +        *mtimecmp = timer_next_evt; +    } +    if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); + +    set_csr(mstatus, MSTATUS_MIE); +} + +void eos_timer_set_handler(eos_timer_fptr_t handler) { +    clear_csr(mstatus, MSTATUS_MIE); +    timer_ext_handler = handler; +    set_csr(mstatus, MSTATUS_MIE); +} diff --git a/code/fe310/eos/timer.h b/code/fe310/eos/timer.h new file mode 100644 index 0000000..929283b --- /dev/null +++ b/code/fe310/eos/timer.h @@ -0,0 +1,7 @@ +#include <stdint.h> + +typedef uint32_t (*eos_timer_fptr_t) (void); + +void eos_timer_init(void); +void eos_timer_set(uint32_t tick, unsigned char is_evt); +void eos_timer_set_handler(eos_timer_fptr_t handler); diff --git a/code/platform b/code/platform index 545b475..0781395 100755 --- a/code/platform +++ b/code/platform @@ -10,5 +10,5 @@ fi  PLATFORM=$1 -ln -sf $BASEDIR/Makefile.$PLATFORM $BASEDIR/Makefile.platform -ln -sf $BASEDIR/config_$PLATFORM.h $BASEDIR/config.h
\ No newline at end of file +ln -sf ./Makefile.$PLATFORM $BASEDIR/ecp/Makefile.platform +ln -sf ./config_$PLATFORM.h $BASEDIR/ecp/config.h
\ No newline at end of file diff --git a/code/test/Makefile b/code/test/Makefile index 4172420..13fa476 100644 --- a/code/test/Makefile +++ b/code/test/Makefile @@ -1,4 +1,4 @@ -include ../Makefile.platform +include ../ecp/Makefile.platform  CFLAGS=$(CFLAGS_PL) -I../ecp -I../util -Wno-int-to-void-pointer-cast  LDFLAGS=$(LDFLAGS_PL) diff --git a/code/test/stress.c b/code/test/stress.c index d6bc74a..6bc5a64 100644 --- a/code/test/stress.c +++ b/code/test/stress.c @@ -94,7 +94,9 @@ void *sender(ECPConnection *c) {          usleep(rnd % (2000000/msg_rate));          ecp_pld_set_type(pld_buf, MTYPE_MSG); -        ssize_t _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0)); +        ssize_t _rv = 0; +        // XXX refactor +        // _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0));          if (c_start && (_rv > 0)) {              pthread_mutex_lock(&t_mtx[idx]);              t_sent[idx]++; @@ -153,7 +155,8 @@ ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigne      payload.size = ECP_MAX_PLD;      ecp_pld_set_type(pld_buf, MTYPE_MSG); -    ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0)); +    // XXX refactor +    // ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0));      return s;  } diff --git a/code/util/Makefile b/code/util/Makefile index 0645ace..a896fc2 100644 --- a/code/util/Makefile +++ b/code/util/Makefile @@ -1,4 +1,4 @@ -include ../Makefile.platform +include ../ecp/Makefile.platform  CFLAGS=$(CFLAGS_PL) -I../ecp  LDFLAGS=$(LDFLAGS_PL) diff --git a/code/util/keydump b/code/util/keydump new file mode 100755 index 0000000..9a884dc --- /dev/null +++ b/code/util/keydump @@ -0,0 +1,3 @@ +#!/bin/sh + +hexdump -e '16/1 "0x%02X, " "\n"' $@  | 
