diff options
| -rw-r--r-- | code/fe310/eos/Makefile | 12 | ||||
| -rw-r--r-- | code/fe310/eos/ecp.c | 22 | ||||
| -rw-r--r-- | code/fe310/eos/eos.h | 1 | ||||
| -rw-r--r-- | code/fe310/eos/event.c | 82 | ||||
| -rw-r--r-- | code/fe310/eos/event.h | 16 | ||||
| -rw-r--r-- | code/fe310/eos/interrupt.c | 33 | ||||
| -rw-r--r-- | code/fe310/eos/interrupt.h | 6 | ||||
| -rw-r--r-- | code/fe310/eos/net.c | 240 | ||||
| -rw-r--r-- | code/fe310/eos/net.h | 4 | ||||
| -rw-r--r-- | code/fe310/eos/spi.h | 22 | ||||
| -rw-r--r-- | code/fe310/eos/timer.c | 21 | 
11 files changed, 269 insertions, 190 deletions
diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile index 573bca7..43313fd 100644 --- a/code/fe310/eos/Makefile +++ b/code/fe310/eos/Makefile @@ -1,11 +1,11 @@ -FE310_HOME=/opt/my/freedom-e-sdk +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 +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 +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 = eos.o msgq.o event.o interrupt.o timer.o net.o ecp.o  %.o: %.c %.h diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c index b50e0d7..9301555 100644 --- a/code/fe310/eos/ecp.c +++ b/code/fe310/eos/ecp.c @@ -12,20 +12,11 @@  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); +    ecp_cts_t next = ecp_timer_exe(_sock); +    if (next) { +        uint32_t tick = next * (uint64_t)RTC_FREQ / 1000; +        eos_timer_set(tick, 1);      }  } @@ -60,9 +51,8 @@ int ecp_init(ECPContext *ctx) {      rv = ecp_ctx_create_vconn(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); - +    eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler, EOS_EVT_FLAG_WRAP); +    eos_net_set_handler(EOS_NET_CMD_PKT, packet_handler, 0);      return ECP_OK;  } diff --git a/code/fe310/eos/eos.h b/code/fe310/eos/eos.h index 938030e..8ca73e5 100644 --- a/code/fe310/eos/eos.h +++ b/code/fe310/eos/eos.h @@ -1,5 +1,6 @@  #define EOS_OK                  0  #define EOS_ERR_Q_FULL          -10 +#define EOS_ERR_Q_EMPTY         -11  void eos_init(void);  void eos_start(void); diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c index 25f1fa1..a1cf591 100644 --- a/code/fe310/eos/event.c +++ b/code/fe310/eos/event.c @@ -1,56 +1,65 @@ +#include <stdint.h>  #include <stdio.h> +#include <unistd.h>  #include "encoding.h"  #include "platform.h" -#include "eos.h" -#include "msgq.h"  #include "net.h" -#include "timer.h" +#include "msgq.h"  #include "event.h" -static EOSMsgQ event_q; +EOSMsgQ _eos_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); -} +static eos_evt_fptr_t evt_handler[EOS_EVT_MAX_EVT]; +static uint16_t evt_handler_wrapper_acq = 0; +static uint16_t evt_handler_wrapper_en = 0;  void eos_evtq_init(void) {      int i; -    for (i=0; i<EOS_NET_MAX_CMD; i++) { -        evt_net_handler[i] = bad_handler; +    for (i=0; i<EOS_EVT_MAX_EVT; i++) { +        evt_handler[i] = eos_evtq_bad_handler;      } -    evt_timer_handler = bad_handler; -    evt_ui_handler = bad_handler; -    eos_msgq_init(&event_q, event_q_array, EOS_EVT_SIZE_Q); +    eos_msgq_init(&_eos_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); +    return eos_msgq_push(&_eos_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); +    eos_msgq_pop(&_eos_event_q, cmd, buffer, len); +} + +void eos_evtq_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    write(1, "error\n", 6); +} + +void eos_evtq_handler_wrapper(unsigned char cmd, unsigned char *buffer, uint16_t len, uint16_t *flags_acq, uint16_t flag, eos_evt_fptr_t f) { +    int ok = eos_net_acquire(*flags_acq & flag); +    if (ok) { +        f(cmd, buffer, len); +        eos_net_release(1); +        *flags_acq &= ~flag; +    } else { +        *flags_acq |= flag; +        eos_evtq_push(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); +    if (((cmd & EOS_EVT_MASK) >> 4) > EOS_EVT_MAX_EVT) { +        eos_evtq_bad_handler(cmd, buffer, len); +    } else { +        unsigned char idx = ((cmd & EOS_EVT_MASK) >> 4) - 1; +        uint16_t flag = (uint16_t)1 << idx; +        if (flag & evt_handler_wrapper_en) { +            eos_evtq_handler_wrapper(cmd, buffer, len, &evt_handler_wrapper_acq, flag, evt_handler[idx]);          } else { -            bad_handler(cmd, buffer, len); +            evt_handler[idx](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);      }  } @@ -58,7 +67,7 @@ void eos_evtq_loop(void) {      unsigned char cmd;      unsigned char *buffer;      uint16_t len; -    volatile int foo = 1; +    int foo = 1;      while(foo) {          clear_csr(mstatus, MSTATUS_MIE); @@ -68,18 +77,17 @@ void eos_evtq_loop(void) {              eos_evtq_handle(cmd, buffer, len);              clear_csr(mstatus, MSTATUS_MIE);          } else { -            // asm volatile ("wfi"); +            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; +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags) { +    if (flags & EOS_EVT_FLAG_WRAP) { +        uint16_t flag = (uint16_t)1 << (((cmd & EOS_EVT_MASK) >> 4) - 1); +        evt_handler_wrapper_en |= flag;      } -}
\ No newline at end of file +    evt_handler[((cmd & EOS_EVT_MASK) >> 4) - 1] = handler; +} + diff --git a/code/fe310/eos/event.h b/code/fe310/eos/event.h index 21079b4..ce71c0b 100644 --- a/code/fe310/eos/event.h +++ b/code/fe310/eos/event.h @@ -1,9 +1,15 @@  #include <stdint.h> -#define EOS_EVT_MASK_NET    0x80 -#define EOS_EVT_TIMER       0x01 -#define EOS_EVT_UI          0x02 +#define EOS_EVT_FLAG_WRAP   0x1 +#define EOS_EVT_NET         0x10 +#define EOS_EVT_TIMER       0x20 +#define EOS_EVT_AUDIO       0x30 +#define EOS_EVT_UI          0x40 + +#define EOS_EVT_MASK        0xF0 + +#define EOS_EVT_MAX_EVT     4  #define EOS_EVT_SIZE_Q      4  typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t); @@ -11,6 +17,8 @@ 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_bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len); +void eos_evtq_handler_wrapper(unsigned char cmd, unsigned char *buffer, uint16_t len, uint16_t *flags_acq, uint16_t flag, eos_evt_fptr_t f);  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 +void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags); diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c index def1a24..77ab6d5 100644 --- a/code/fe310/eos/interrupt.c +++ b/code/fe310/eos/interrupt.c @@ -1,6 +1,4 @@ -#include <stdio.h>  #include <stdlib.h> -#include <string.h>  #include <stdint.h>  #include <unistd.h> @@ -15,15 +13,16 @@ 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])) { +uintptr_t eos_intr_handle(uintptr_t int_num) { +    // 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); +        write(1, "error\n", 6); +        exit(int_num);      } -    PLIC_complete_interrupt(&plic, int_num); +    // PLIC_complete_interrupt(&plic, int_num); +    return int_num;  }  void eos_intr_init(void) { @@ -46,8 +45,24 @@ void eos_intr_init(void) {      set_csr(mstatus, MSTATUS_MIE);  } -void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) { +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) {      ext_interrupt_handler[int_num] = handler; +    PLIC_set_priority(&plic, int_num, priority);      PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_set_priority(uint8_t int_num, uint8_t priority) {      PLIC_set_priority(&plic, int_num, priority);  } + +void eos_intr_enable(uint8_t int_num) { +    PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_disable(uint8_t int_num) { +    PLIC_disable_interrupt(&plic, int_num); +} + +void eos_intr_mask(uint8_t priority) { +    PLIC_set_threshold(&plic, priority); +} diff --git a/code/fe310/eos/interrupt.h b/code/fe310/eos/interrupt.h index 7ef81b8..3ccfb21 100644 --- a/code/fe310/eos/interrupt.h +++ b/code/fe310/eos/interrupt.h @@ -5,4 +5,8 @@  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); +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler); +void eos_intr_set_priority(uint8_t int_num, uint8_t priority); +void eos_intr_enable(uint8_t int_num); +void eos_intr_disable(uint8_t int_num); +void eos_intr_mask(uint8_t priority);
\ No newline at end of file diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c index 080da72..4588485 100644 --- a/code/fe310/eos/net.c +++ b/code/fe310/eos/net.c @@ -10,7 +10,6 @@  #include "eos.h"  #include "msgq.h" -#include "event.h"  #include "interrupt.h"  #include "net.h"  #include "spi.h" @@ -19,18 +18,18 @@  #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 eos_evt_fptr_t evt_handler[EOS_NET_MAX_CMD]; +static uint16_t evt_handler_wrapper_acq = 0; +static uint16_t evt_handler_wrapper_en = 0;  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; +    return EOS_OK;  }  static unsigned char *spi_bufq_pop(void) { @@ -38,45 +37,43 @@ static unsigned char *spi_bufq_pop(void) {      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 SPIState spi_state;  static void spi_reset(void) {      int i; -    volatile uint32_t r; -    spi_cts = 0; +    spi_state.flags &= ~SPI_FLAG_CTS; +    spi_state.flags |= SPI_FLAG_RST;      // 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; +    SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(0); +    SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;  }  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) { +    spi_state.flags &= ~SPI_FLAG_CTS; +    spi_state.flags |= SPI_FLAG_INIT; +    if (spi_state.next_buf == NULL) {          if (cmd & EOS_NET_CMD_FLAG_ONEW) { -            spi_res_next = 1; -        } else if (spi_res) { +            spi_state.flags |= SPI_FLAG_ONEW; +        } else if (spi_state.next_cnt) {              cmd |= EOS_NET_CMD_FLAG_ONEW;          }      } else if (cmd & EOS_NET_CMD_FLAG_ONEW) {          cmd &= ~EOS_NET_CMD_FLAG_ONEW;      } +    spi_state.cmd = cmd; +    spi_state.buf = buffer; +    spi_state.len_tx = len; +    spi_state.len_rx = 0; +    spi_state.idx_tx = 0; +    spi_state.idx_rx = 0; +          // before starting a transaction, set SPI peripheral to desired mode      SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; @@ -86,30 +83,8 @@ static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) {      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; +    SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(1); +    SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;  }  static int spi_xchg_next(unsigned char *_buffer) { @@ -120,7 +95,7 @@ static int spi_xchg_next(unsigned char *_buffer) {      eos_msgq_pop(&spi_sndq, &cmd, &buffer, &len);      if (cmd) {          spi_xchg(cmd, buffer, len); -    } else if (spi_rts) { +    } else if (spi_state.flags & SPI_FLAG_RTS) {          if (_buffer == NULL) _buffer = spi_bufq_pop();          if (_buffer) {              spi_xchg(0, _buffer, 0); @@ -131,47 +106,82 @@ static int spi_xchg_next(unsigned char *_buffer) {  }  static void spi_xchg_handler(void) { +    volatile uint32_t r1, r2;      int i; +    if (spi_state.flags & SPI_FLAG_RST) { +        while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); +        SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; +        SPI1_REG(SPI_REG_IE) = 0x0; +        spi_state.flags &= ~SPI_FLAG_RST; + +        return; +    } else if (spi_state.flags & SPI_FLAG_INIT) { +        while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); +        while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); +     +        if (spi_state.cmd & EOS_NET_CMD_FLAG_ONEW) { +            r1 = 0; +            r2 = 0; +        } + +        spi_state.cmd = ((r1 & 0xFF) >> 3); +        spi_state.len_rx = ((r1 & 0x07) << 8); +        spi_state.len_rx |= (r2 & 0xFF); +        spi_state.len = MAX(spi_state.len_tx, spi_state.len_rx); + +        // Work around esp32 bug +        if (spi_state.len < 6) { +            spi_state.len = 6; +        } else if ((spi_state.len + 2) % 4 != 0) { +            spi_state.len = ((spi_state.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; +        spi_state.flags &= ~SPI_FLAG_INIT; +    } +      if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) { -        uint16_t sz_chunk = MIN(spi_buffer.len - spi_buffer.idx_tx, SPI_SIZE_CHUNK); +        uint16_t sz_chunk = MIN(spi_state.len - spi_state.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]; +            SPI1_REG(SPI_REG_TXFIFO) = spi_state.buf[spi_state.idx_tx+i];          } -        spi_buffer.idx_tx += i; +        spi_state.idx_tx += i;      } -    for (i=0; i<spi_buffer.idx_tx - spi_buffer.idx_rx; i++) { +    for (i=0; i<spi_state.idx_tx - spi_state.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_state.buf[spi_state.idx_rx+i] = x & 0xFF;      } -    spi_buffer.idx_rx += i; +    spi_state.idx_rx += i; -    if (spi_buffer.idx_rx == spi_buffer.len) { +    if (spi_state.idx_rx == spi_state.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; +        if (spi_state.cmd) { +            int r = eos_evtq_push(EOS_EVT_NET | spi_state.cmd, spi_state.buf, spi_state.len_rx); +            if (r) spi_bufq_push(spi_state.buf); +        } else if ((spi_state.next_cnt || (spi_state.flags & SPI_FLAG_ONEW)) && (spi_state.next_buf == NULL)) { +            spi_state.next_buf = spi_state.buf; +            spi_state.flags &= ~SPI_FLAG_ONEW;          } else { -            spi_bufq_push(spi_buffer.buffer); +            spi_bufq_push(spi_state.buf);          } -    } 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)); +    } else if (spi_state.idx_tx == spi_state.len) { +        SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_state.len - spi_state.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; +    spi_state.flags |= SPI_FLAG_CTS; -    if (spi_rdy) { +    if (spi_state.flags & SPI_FLAG_RDY) {          spi_xchg_next(NULL);      } else {          uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2); @@ -183,16 +193,31 @@ 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(); +        spi_state.flags |= SPI_FLAG_RTS; +        if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) spi_reset();      }      if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {          GPIO_REG(GPIO_FALL_IP) = rts_offset; -        spi_rts = 0; +        spi_state.flags &= ~SPI_FLAG_RTS; +    } +} + +static void net_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) { +    if ((cmd & ~EOS_EVT_MASK) > EOS_NET_MAX_CMD) { +        eos_evtq_bad_handler(cmd, buffer, len); +    } else { +        unsigned char idx = (cmd & ~EOS_EVT_MASK) - 1; +        uint16_t flag = (uint16_t)1 << idx; +        if (flag & evt_handler_wrapper_en) { +            eos_evtq_handler_wrapper(cmd, buffer, len, &evt_handler_wrapper_acq, flag, evt_handler[idx]); +        } else { +            evt_handler[idx](cmd, buffer, len); +        }      }  } +  void eos_net_init(void) {      int i; @@ -201,23 +226,30 @@ void eos_net_init(void) {      for (i=0; i<SPI_SIZE_BUFQ; i++) {          spi_bufq_push(spi_bufq_array[i]);      } +    memset(&spi_state, 0, sizeof(spi_state)); +      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); +    eos_intr_set(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); - +    eos_intr_set(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); +    eos_intr_set(INT_GPIO_BASE + SPI_GPIO_RTS_OFFSET, 5, spi_rts_hanler); + +    for (i=0; i<EOS_NET_MAX_CMD; i++) { +        evt_handler[i] = eos_evtq_bad_handler; +    } +    eos_evtq_set_handler(EOS_EVT_NET, net_handler, 0);  }  void eos_net_start(uint32_t sckdiv) { @@ -240,8 +272,8 @@ void eos_net_start(uint32_t sckdiv) {      // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF;      clear_csr(mstatus, MSTATUS_MIE); -    spi_rdy = 1; -    if (spi_cts) spi_xchg_next(NULL); +    spi_state.flags |= SPI_FLAG_RDY; +    if (spi_state.flags & SPI_FLAG_CTS) spi_xchg_next(NULL);      set_csr(mstatus, MSTATUS_MIE);  } @@ -249,8 +281,8 @@ void eos_net_stop(void) {      volatile uint8_t done = 0;      clear_csr(mstatus, MSTATUS_MIE); -    spi_rdy = 0; -    if (spi_cts) { +    spi_state.flags &= ~SPI_FLAG_RDY; +    if (spi_state.flags & SPI_FLAG_CTS) {          uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2);          GPIO_REG(GPIO_IOF_EN) &= ~iof_mask;          done = 1; @@ -259,19 +291,27 @@ void eos_net_stop(void) {      while (!done) {          clear_csr(mstatus, MSTATUS_MIE); -        done = spi_cts; +        done = spi_state.flags & SPI_FLAG_CTS;          if (!done) asm volatile ("wfi");          set_csr(mstatus, MSTATUS_MIE);      }  } +void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags) { +    if (flags & EOS_EVT_FLAG_WRAP) { +        uint16_t flag = (uint16_t)1 << ((cmd & ~EOS_EVT_MASK) - 1); +        evt_handler_wrapper_en |= flag; +    } +    evt_handler[(cmd & ~EOS_EVT_MASK) - 1] = handler; +} +  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; +    spi_state.next_cnt++; +    if (spi_state.next_buf == NULL) { +        spi_state.next_buf = buffer;      } else {          rv = spi_bufq_push(buffer);      } @@ -286,7 +326,7 @@ int eos_net_acquire(unsigned char reserved) {      if (reserved) {          while (!ret) {              clear_csr(mstatus, MSTATUS_MIE); -            if (spi_res_buf) { +            if (spi_state.next_buf) {                  ret = 1;              } else {                  asm volatile ("wfi"); @@ -295,9 +335,9 @@ int eos_net_acquire(unsigned char reserved) {          }      } else {          clear_csr(mstatus, MSTATUS_MIE); -        spi_res++; -        spi_res_buf = spi_bufq_pop(); -        ret = (spi_res_buf != NULL); +        spi_state.next_cnt++; +        spi_state.next_buf = spi_bufq_pop(); +        ret = (spi_state.next_buf != NULL);          set_csr(mstatus, MSTATUS_MIE);      }      return ret; @@ -307,10 +347,10 @@ 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; +    if (reserved) spi_state.next_cnt--; +    if (!spi_state.next_cnt && spi_state.next_buf) { +        rv = spi_bufq_push((unsigned char *)spi_state.next_buf); +        if (!rv) spi_state.next_buf = NULL;      }      set_csr(mstatus, MSTATUS_MIE); @@ -318,31 +358,31 @@ int eos_net_release(unsigned char reserved) {  }  unsigned char *eos_net_alloc(void) { -    volatile unsigned char *ret = NULL; +    unsigned char *ret = NULL;      while (ret == NULL) {          clear_csr(mstatus, MSTATUS_MIE); -        if (spi_res_buf) { -            ret = spi_res_buf; -            spi_res_buf = NULL; +        if (spi_state.next_buf) { +            ret = spi_state.next_buf; +            spi_state.next_buf = NULL;          } else {              asm volatile ("wfi");          }          set_csr(mstatus, MSTATUS_MIE);      } -    return (unsigned char *)ret; +    return ret;  } -int eos_net_free(unsigned char *buffer, unsigned char reserve_next) { +int eos_net_free(unsigned char *buffer, unsigned char reserve) {      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; +    if ((reserve || spi_state.next_cnt) && (spi_state.next_buf == NULL)) { +        spi_state.next_buf = buffer;      } else { -        if (spi_rdy && spi_cts) do_release = spi_xchg_next(buffer); +        if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) do_release = spi_xchg_next(buffer);          if (do_release) rv = spi_bufq_push(buffer);      }      set_csr(mstatus, MSTATUS_MIE); @@ -354,7 +394,7 @@ 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) { +    if ((spi_state.flags & SPI_FLAG_RDY) && (spi_state.flags & SPI_FLAG_CTS)) {          spi_xchg(cmd, buffer, len);      } else {          rv = eos_msgq_push(&spi_sndq, cmd, buffer, len); diff --git a/code/fe310/eos/net.h b/code/fe310/eos/net.h index 0091c3c..106a204 100644 --- a/code/fe310/eos/net.h +++ b/code/fe310/eos/net.h @@ -1,4 +1,5 @@  #include <stdint.h> +#include "event.h"  #define EOS_NET_CMD_FLAG_ONEW   0x10 @@ -7,11 +8,12 @@  #define EOS_NET_CMD_SCAN        3  #define EOS_NET_CMD_PKT         4 -#define EOS_NET_MAX_CMD         8 +#define EOS_NET_MAX_CMD         4  void eos_net_init(void);  void eos_net_start(uint32_t sckdiv);  void eos_net_stop(void); +void eos_net_set_handler(unsigned char cmd, eos_evt_fptr_t handler, uint8_t flags);  int eos_net_reserve(unsigned char *buffer);  int eos_net_acquire(unsigned char reserved);  int eos_net_release(unsigned char reserved); diff --git a/code/fe310/eos/spi.h b/code/fe310/eos/spi.h index 7e281b8..55ff846 100644 --- a/code/fe310/eos/spi.h +++ b/code/fe310/eos/spi.h @@ -10,19 +10,31 @@  #define SPI_SIZE_BUF            1500  #define SPI_SIZE_CHUNK          4 -#define SPI_SIZE_BUFQ           4 +#define SPI_SIZE_BUFQ           2  #define SPI_GPIO_RTS_OFFSET     PIN_8_OFFSET  #define SPI_GPIO_CTS_OFFSET     PIN_7_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; + +#define SPI_FLAG_RDY            0x01 +#define SPI_FLAG_RST            0x02 +#define SPI_FLAG_RTS            0x04 +#define SPI_FLAG_CTS            0x08 +#define SPI_FLAG_INIT           0x10 +#define SPI_FLAG_ONEW           0x20 + +typedef struct SPIState { +    uint8_t flags;      uint16_t len; +    uint16_t len_tx;      uint16_t len_rx;      uint16_t idx_tx;      uint16_t idx_rx; -} SPIBuffer; +    unsigned char cmd; +    unsigned char *buf; +    uint8_t next_cnt; +    unsigned char *next_buf; +} SPIState;  typedef struct SPIBufQ {      uint8_t idx_r; diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c index 0a07ed9..9e2ae9d 100644 --- a/code/fe310/eos/timer.c +++ b/code/fe310/eos/timer.c @@ -13,7 +13,7 @@ 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) { +void eos_timer_handle(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; @@ -44,10 +44,9 @@ 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); +    clear_csr(mie, MIP_MTIP);      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; @@ -56,16 +55,15 @@ void eos_timer_set(uint32_t tick, unsigned char is_evt) {          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); +    if ((*mtimecmp == 0) || (next < *mtimecmp)) *mtimecmp = next; -    set_csr(mstatus, MSTATUS_MIE); +    if (*mtimecmp != 0) set_csr(mie, MIP_MTIP);  }  void eos_timer_clear(unsigned char is_evt) {      volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); -    clear_csr(mstatus, MSTATUS_MIE); +    clear_csr(mie, MIP_MTIP);      if (is_evt) {          timer_next_evt = 0; @@ -74,13 +72,14 @@ void eos_timer_clear(unsigned char is_evt) {          timer_next = 0;          *mtimecmp = timer_next_evt;      } -    if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); -    set_csr(mstatus, MSTATUS_MIE); +    if (*mtimecmp != 0) set_csr(mie, MIP_MTIP);  }  void eos_timer_set_handler(eos_timer_fptr_t handler) { -    clear_csr(mstatus, MSTATUS_MIE); +    volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + +    clear_csr(mie, MIP_MTIP);      timer_ext_handler = handler; -    set_csr(mstatus, MSTATUS_MIE); +    if (*mtimecmp != 0) set_csr(mie, MIP_MTIP);  }  | 
