diff options
Diffstat (limited to 'code')
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"' $@ |